make sparc+arm backend completely independent from beabi
authorMatthias Braun <matze@braunis.de>
Fri, 8 Oct 2010 14:02:22 +0000 (14:02 +0000)
committerMatthias Braun <matze@braunis.de>
Fri, 8 Oct 2010 14:02:22 +0000 (14:02 +0000)
[r28073]

ir/be/arm/arm_spec.pl
ir/be/bechordal.c
ir/be/becopyopt.c
ir/be/bedump_minir.c
ir/be/benode.c
ir/be/bespill.c
ir/be/bestack.c
ir/be/ia32/ia32_optimize.c
ir/be/scripts/generate_regalloc_if.pl
ir/be/sparc/sparc_spec.pl

index 18a3a05..f4746d4 100644 (file)
@@ -12,48 +12,40 @@ $mode_gp    = "mode_Iu";
 $mode_flags = "mode_Bu";
 $mode_fp    = "mode_E";
 
-# register types:
-$normal      =  0; # no special type
-$caller_save =  1; # caller save (register must be saved by the caller of a function)
-$callee_save =  2; # callee save (register must be saved by the called function)
-$ignore      =  4; # ignore (do not assign this register)
-$arbitrary   =  8; # emitter can choose an arbitrary register of this class
-$virtual     = 16; # the register is a virtual one
-$state       = 32; # register represents a state
 # NOTE: Last entry of each class is the largest Firm-Mode a register can hold
 %reg_classes = (
        gp => [
-               { name => "r0",  type => $caller_save },
-               { name => "r1",  type => $caller_save },
-               { name => "r2",  type => $caller_save },
-               { name => "r3",  type => $caller_save },
-               { name => "r4",  type => $callee_save },
-               { name => "r5",  type => $callee_save },
-               { name => "r6",  type => $callee_save },
-               { name => "r7",  type => $callee_save },
-               { name => "r8",  type => $callee_save },
-               { name => "r9",  type => $callee_save },
-               { name => "r10", type => $callee_save },
-               { name => "r11", type => $callee_save },
-               { name => "r12", type => $ignore }, # reserved for linker/immediate fixups
-               { name => "sp",  type => $ignore }, # this is our stack pointer
-               { name => "lr",  type => $callee_save | $caller_save }, # this is our return address
-               { name => "pc",  type => $ignore }, # this is our program counter
+               { name => "r0" },
+               { name => "r1" },
+               { name => "r2" },
+               { name => "r3" },
+               { name => "r4" },
+               { name => "r5" },
+               { name => "r6" },
+               { name => "r7" },
+               { name => "r8" },
+               { name => "r9" },
+               { name => "r10" },
+               { name => "r11" },
+               { name => "r12" },
+               { name => "sp" },
+               { name => "lr" },
+               { name => "pc" },
                { mode => $mode_gp }
        ],
        fpa => [
-               { name => "f0", type => $caller_save },
-               { name => "f1", type => $caller_save },
-               { name => "f2", type => $caller_save },
-               { name => "f3", type => $caller_save },
-               { name => "f4", type => $caller_save },
-               { name => "f5", type => $caller_save },
-               { name => "f6", type => $caller_save },
-               { name => "f7", type => $caller_save },
+               { name => "f0" },
+               { name => "f1" },
+               { name => "f2" },
+               { name => "f3" },
+               { name => "f4" },
+               { name => "f5" },
+               { name => "f6" },
+               { name => "f7" },
                { mode => $mode_fp }
        ],
        flags => [
-               { name => "fl", type => 0 },
+               { name => "fl" },
                { mode => $mode_flags, flags => "manual_ra" }
        ],
 );
@@ -426,7 +418,8 @@ SwitchJmp => {
        mode      => "mode_T",
        attr      => "int n_projs, long def_proj_num",
        init_attr => "\tset_arm_SwitchJmp_n_projs(res, n_projs);\n".
-                    "\tset_arm_SwitchJmp_default_proj_num(res, def_proj_num);",
+                    "\tset_arm_SwitchJmp_default_proj_num(res, def_proj_num);\n".
+                    "\tinfo->out_infos = NULL;",
        reg_req   => { in => [ "gp" ], out => [ "none" ] },
        attr_type => "arm_SwitchJmp_attr_t",
 },
index 26f76f1..e92f1d3 100644 (file)
@@ -342,7 +342,6 @@ static ir_node *handle_constraints(be_chordal_alloc_env_t *alloc_env,
 
                assert(assignment[i] >= 0 && "there must have been a register assigned (node not register pressure faithful?)");
                reg = arch_register_for_index(env->cls, assignment[i]);
-               assert(! (reg->type & arch_register_type_ignore));
 
                irn = alloc_nodes[i];
                if (irn != NULL) {
@@ -502,7 +501,6 @@ static void assign(ir_node *block, void *env_ptr)
                                col = get_next_free_reg(alloc_env, colors);
                                reg = arch_register_for_index(env->cls, col);
                                assert(arch_get_irn_register(irn) == NULL && "This node must not have been assigned a register yet");
-                               assert(!arch_register_type_is(reg, ignore) && "Must not assign ignore register");
                        }
 
                        bitset_set(colors, col);
@@ -520,11 +518,6 @@ static void assign(ir_node *block, void *env_ptr)
                        assert(reg && "Register must have been assigned");
 
                        col = arch_register_get_index(reg);
-#ifndef NDEBUG
-                       if (!arch_register_type_is(reg, ignore)) {
-                               assert(bitset_is_set(live, nr) && "Cannot have a non live use");
-                       }
-#endif
 
                        bitset_clear(colors, col);
                        bitset_clear(live, nr);
index cde32cd..4b9fcc7 100644 (file)
@@ -228,15 +228,10 @@ void free_copy_opt(copy_opt_t *co)
 static int co_is_optimizable_root(ir_node *irn)
 {
        const arch_register_req_t *req;
-       const arch_register_t     *reg;
 
        if (arch_irn_is_ignore(irn))
                return 0;
 
-       reg = arch_get_irn_register(irn);
-       if (arch_register_type_is(reg, ignore))
-               return 0;
-
        if (is_Reg_Phi(irn) || is_Perm_Proj(irn))
                return 1;
 
@@ -805,7 +800,6 @@ static void build_graph_walker(ir_node *irn, void *env)
        const arch_register_req_t *req;
        copy_opt_t                *co  = env;
        int pos, max;
-       const arch_register_t *reg;
 
        if (get_irn_mode(irn) == mode_T)
                return;
@@ -813,10 +807,6 @@ static void build_graph_walker(ir_node *irn, void *env)
        if (req->cls != co->cls || arch_irn_is_ignore(irn))
                return;
 
-       reg = arch_get_irn_register(irn);
-       if (arch_register_type_is(reg, ignore))
-               return;
-
        if (is_Reg_Phi(irn)) { /* Phis */
                for (pos=0, max=get_irn_arity(irn); pos<max; ++pos) {
                        ir_node *arg = get_irn_n(irn, pos);
@@ -898,6 +888,8 @@ void co_dump_appel_graph(const copy_opt_t *co, FILE *f)
        be_ifg_t *ifg       = co->cenv->ifg;
        int      *color_map = ALLOCAN(int, co->cls->n_regs);
        int      *node_map  = XMALLOCN(int, get_irg_last_idx(co->irg) + 1);
+       ir_graph *irg       = co->irg;
+       be_irg_t *birg      = be_birg_from_irg(irg);
 
        ir_node *irn;
        nodes_iter_t it;
@@ -908,7 +900,11 @@ void co_dump_appel_graph(const copy_opt_t *co, FILE *f)
        n_regs = 0;
        for (i = 0; i < co->cls->n_regs; ++i) {
                const arch_register_t *reg = &co->cls->regs[i];
-               color_map[i] = arch_register_type_is(reg, ignore) ? -1 : n_regs++;
+               if (rbitset_is_set(birg->allocatable_regs, reg->global_index)) {
+                       color_map[i] = n_regs++;
+               } else {
+                       color_map[i] = -1;
+               }
        }
 
        /*
index 906ea7c..0809a98 100644 (file)
@@ -243,6 +243,7 @@ static void print_regclasses(void)
                }
                end_list("registers");
 
+#if 0
                begin_block_mapping("flags");
                for (r = 0; r < n_regs; ++r) {
                        const arch_register_t *reg  = arch_register_for_index(cls, r);
@@ -255,6 +256,7 @@ static void print_regclasses(void)
                        }
                }
                end_block_mapping("flags");
+#endif
 
                end_block_mapping(NULL);
        }
index 87c0b84..b3bbb13 100644 (file)
@@ -874,10 +874,12 @@ void be_set_constr_single_reg_in(ir_node *node, int pos,
 void be_set_constr_single_reg_out(ir_node *node, int pos,
                const arch_register_t *reg, arch_register_req_type_t additional_types)
 {
+       ir_graph                  *irg  = get_irn_irg(node);
+       be_irg_t                  *birg = be_birg_from_irg(irg);
        const arch_register_req_t *req;
 
        /* if we have an ignore register, add ignore flag and just assign it */
-       if (reg->type & arch_register_type_ignore) {
+       if (!rbitset_is_set(birg->allocatable_regs, reg->global_index)) {
                additional_types |= arch_register_req_type_ignore;
        }
 
index de71ea8..2e54f4e 100644 (file)
@@ -59,6 +59,7 @@ static void prepare_constr_insn(be_pre_spill_env_t *env, ir_node *node)
        const arch_register_class_t *cls = env->cls;
        ir_node  *block      = get_nodes_block(node);
        const ir_graph *irg  = env->irg;
+       be_irg_t       *birg = be_birg_from_irg(irg);
        be_lv_t *lv          = be_get_irg_liveness(irg);
        unsigned *tmp        = NULL;
        unsigned *def_constr = NULL;
@@ -70,15 +71,14 @@ static void prepare_constr_insn(be_pre_spill_env_t *env, ir_node *node)
         * fullfil the constraint
         * (typical example: stack pointer as input to copyb)
         * TODO: This really just checks precolored registers at the moment and
-        *       ignore the general case of not matching in/out constraints
+        *       ignores the general case of not matching in/out constraints
         */
        for (i = 0; i < arity; ++i) {
-               ir_node *op = get_irn_n(node, i);
-               ir_node *copy;
-               const arch_register_t *reg;
-               const arch_register_req_t *req;
+               ir_node                   *op  = get_irn_n(node, i);
+               const arch_register_req_t *req = arch_get_register_req(node, i);
+               const arch_register_t     *reg;
+               ir_node                   *copy;
 
-               req = arch_get_register_req(node, i);
                if (req->cls != cls)
                        continue;
                reg = arch_get_irn_register(op);
@@ -88,7 +88,7 @@ static void prepare_constr_insn(be_pre_spill_env_t *env, ir_node *node)
                /* precolored with an ignore register (which is not a joker like
                   unknown/noreg) */
                if (arch_register_type_is(reg, joker)
-                               || !arch_register_type_is(reg, ignore))
+                               || rbitset_is_set(birg->allocatable_regs, reg->global_index))
                        continue;
 
                if (! (req->type & arch_register_req_type_limited))
@@ -100,7 +100,8 @@ static void prepare_constr_insn(be_pre_spill_env_t *env, ir_node *node)
                stat_ev_int("constr_copy", 1);
                sched_add_before(node, copy);
                set_irn_n(node, i, copy);
-               DBG((dbg, LEVEL_3, "inserting ignore arg copy %+F for %+F pos %d\n", copy, node, i));
+               DBG((dbg, LEVEL_3, "inserting ignore arg copy %+F for %+F pos %d\n",
+                    copy, node, i));
        }
 
        /* insert copies for nodes that occur constrained more than once. */
index d63e7dc..14fa990 100644 (file)
@@ -305,6 +305,7 @@ void be_abi_fix_stack_nodes(ir_graph *irg)
        const arch_env_t          *arch_env = be_get_irg_arch_env(irg);
        be_irg_t                  *birg     = be_birg_from_irg(irg);
        const arch_register_req_t *sp_req   = birg->sp_req;
+       const arch_register_t     *sp       = arch_env->sp;
        be_ssa_construction_env_t  senv;
        int i, len;
        ir_node **phis;
@@ -322,9 +323,10 @@ void be_abi_fix_stack_nodes(ir_graph *irg)
                new_sp_req->width = 1;
 
                limited_bitset = rbitset_obstack_alloc(obst, new_sp_req->cls->n_regs);
-               rbitset_set(limited_bitset, arch_register_get_index(arch_env->sp));
+               rbitset_set(limited_bitset, arch_register_get_index(sp));
                new_sp_req->limited = limited_bitset;
-               if (arch_env->sp->type & arch_register_type_ignore) {
+
+               if (!rbitset_is_set(birg->allocatable_regs, sp->global_index)) {
                        new_sp_req->type |= arch_register_req_type_ignore;
                }
 
index 0d5d573..d233e02 100644 (file)
@@ -819,13 +819,14 @@ static void peephole_Load_IncSP_to_pop(ir_node *irn)
 /**
  * Find a free GP register if possible, else return NULL.
  */
-static const arch_register_t *get_free_gp_reg(void)
+static const arch_register_t *get_free_gp_reg(ir_graph *irg)
 {
+       be_irg_t *birg = be_birg_from_irg(irg);
        int i;
 
        for (i = 0; i < N_ia32_gp_REGS; ++i) {
                const arch_register_t *reg = &ia32_reg_classes[CLASS_ia32_gp].regs[i];
-               if (arch_register_type_is(reg, ignore))
+               if (!rbitset_is_set(birg->allocatable_regs, reg->global_index))
                        continue;
 
                if (be_peephole_get_value(CLASS_ia32_gp, i) == NULL)
@@ -907,7 +908,7 @@ static void peephole_be_IncSP(ir_node *node)
 
        if (offset < 0) {
                /* we need a free register for pop */
-               reg = get_free_gp_reg();
+               reg = get_free_gp_reg(get_irn_irg(node));
                if (reg == NULL)
                        return;
 
@@ -1196,7 +1197,7 @@ static void peephole_ia32_Imul_split(ir_node *imul)
                return;
        }
        /* we need a free register */
-       reg = get_free_gp_reg();
+       reg = get_free_gp_reg(get_irn_irg(imul));
        if (reg == NULL)
                return;
 
index 87714c9..50ebc66 100755 (executable)
@@ -208,9 +208,10 @@ EOF
        $reginit .= "\t$arch\_reg_classes[CLASS_".$class_name."].mode = $class_mode;\n";
        my $lastreg;
        foreach (@class) {
-               my $name = $_->{"name"};
+               my $name   = $_->{"name"};
                my $ucname = uc($name);
-               my $type = translate_reg_type($_->{"type"});
+               my $type   = "arch_register_type_none";
+               $type = translate_reg_type($_->{"type"}) if (exists($_->{"type"}));
                # realname is name if not set by user
                $_->{"realname"} = $_->{"name"} if (! exists($_->{"realname"}));
                my $realname = $_->{realname};
index d7d78e7..41330e8 100644 (file)
@@ -10,103 +10,92 @@ $mode_fp      = "mode_F";
 $mode_fp2     = "mode_D";
 $mode_fp4     = "mode_E"; # not correct, we need to register a new mode
 
-$normal      =  0; # no special type
-$caller_save =  1; # caller save (register must be saved by the caller of a function)
-$callee_save =  2; # callee save (register must be saved by the called function)
-$ignore      =  4; # ignore (do not assign this register)
-$arbitrary   =  8; # emitter can choose an arbitrary register of this class
-$virtual     = 16; # the register is a virtual one
-$state       = 32; # register represents a state
-
 # available SPARC registers: 8 globals, 24 window regs (8 ins, 8 outs, 8 locals)
 %reg_classes = (
        gp => [
-               { name => "g0", type => $ignore }, # hardwired 0, behaves like /dev/null
-               { name => "g1", type => $caller_save }, # temp. value
-               { name => "g2", type => $caller_save },
-               { name => "g3", type => $caller_save },
-               { name => "g4", type => $caller_save },
-               { name => "g5", type => $ignore }, # reserved by SPARC ABI
-               { name => "g6", type => $ignore }, # reserved by SPARC ABI
-               { name => "g7", type => $ignore }, # reserved by SPARC ABI
-
-               # window's out registers
-               { name => "o0", type => $caller_save }, # param 1 / return value from callee
-               { name => "o1", type => $caller_save }, # param 2
-               { name => "o2", type => $caller_save }, # param 3
-               { name => "o3", type => $caller_save }, # param 4
-               { name => "o4", type => $caller_save }, # param 5
-               { name => "o5", type => $caller_save }, # param 6
-               { name => "sp", type => $ignore }, # our stackpointer
-               { name => "o7", type => $ignore }, # temp. value / address of CALL instr.
-
-               # window's local registers
-               { name => "l0", type => 0 },
-               { name => "l1", type => 0 },
-               { name => "l2", type => 0 },
-               { name => "l3", type => 0 },
-               { name => "l4", type => 0 },
-               { name => "l5", type => 0 },
-               { name => "l6", type => 0 },
-               { name => "l7", type => 0 },
-
-               # window's in registers
-               { name => "i0", type => 0 }, # incoming param1 / return value to caller
-               { name => "i1", type => 0 }, # param 2
-               { name => "i2", type => 0 }, # param 3
-               { name => "i3", type => 0 }, # param 4
-               { name => "i4", type => 0 }, # param 5
-               { name => "i5", type => 0 }, # param 6
-               { name => "frame_pointer", realname => "fp", type => $ignore }, # our framepointer
-               { name => "i7", type => $ignore }, # return address - 8
+               { name => "g0" },
+               { name => "g1" },
+               { name => "g2" },
+               { name => "g3" },
+               { name => "g4" },
+               { name => "g5" },
+               { name => "g6" },
+               { name => "g7" },
+
+               { name => "o0" },
+               { name => "o1" },
+               { name => "o2" },
+               { name => "o3" },
+               { name => "o4" },
+               { name => "o5" },
+               { name => "sp" },
+               { name => "o7" },
+
+               { name => "l0" },
+               { name => "l1" },
+               { name => "l2" },
+               { name => "l3" },
+               { name => "l4" },
+               { name => "l5" },
+               { name => "l6" },
+               { name => "l7" },
+
+               { name => "i0" },
+               { name => "i1" },
+               { name => "i2" },
+               { name => "i3" },
+               { name => "i4" },
+               { name => "i5" },
+               { name => "frame_pointer", realname => "fp" },
+               { name => "i7" },
                { mode => $mode_gp }
        ],
        fpflags_class => [
-               { name => "fpflags", type => $ignore },
+               { name => "fpflags" },
                { mode => $mode_fpflags, flags => "manual_ra" }
        ],
        flags_class => [
-               { name => "flags", type => $ignore },
+               { name => "flags" },
                { mode => $mode_flags, flags => "manual_ra" }
        ],
        mul_div_high_res => [
-               { name => "y", type => $ignore },
+               { name => "y" },
                { mode => $mode_gp, flags => "manual_ra" }
        ],
        # fp registers can be accessed any time
        fp => [
-               { name => "f0",  type => $caller_save },
-               { name => "f1",  type => $caller_save },
-               { name => "f2",  type => $caller_save },
-               { name => "f3",  type => $caller_save },
-               { name => "f4",  type => $caller_save },
-               { name => "f5",  type => $caller_save },
-               { name => "f6",  type => $caller_save },
-               { name => "f7",  type => $caller_save },
-               { name => "f8",  type => $caller_save },
-               { name => "f9",  type => $caller_save },
-               { name => "f10", type => $caller_save },
-               { name => "f11", type => $caller_save },
-               { name => "f12", type => $caller_save },
-               { name => "f13", type => $caller_save },
-               { name => "f14", type => $caller_save },
-               { name => "f15", type => $caller_save },
-               { name => "f16", type => $caller_save },
-               { name => "f17", type => $caller_save },
-               { name => "f18", type => $caller_save },
-               { name => "f19", type => $caller_save },
-               { name => "f20", type => $caller_save },
-               { name => "f21", type => $caller_save },
-               { name => "f22", type => $caller_save },
-               { name => "f23", type => $caller_save },
-               { name => "f24", type => $caller_save },
-               { name => "f25", type => $caller_save },
-               { name => "f26", type => $caller_save },
-               { name => "f27", type => $caller_save },
-               { name => "f28", type => $caller_save },
-               { name => "f29", type => $caller_save },
-               { name => "f30", type => $caller_save },
-               { name => "f31", type => $caller_save },
+               { name => "f0" },
+               { name => "f1" },
+               { name => "f2" },
+               { name => "f3" },
+               { name => "f4" },
+               { name => "f5" },
+               { name => "f6" },
+               { name => "f7" },
+               { name => "f8" },
+               { name => "f9" },
+               { name => "f10" },
+               { name => "f11" },
+               { name => "f12" },
+               { name => "f13" },
+               { name => "f14" },
+               { name => "f15" },
+               { name => "f16" },
+               { name => "f17" },
+               { name => "f18" },
+               { name => "f19" },
+               { name => "f20" },
+               { name => "f21" },
+               { name => "f22" },
+               { name => "f23" },
+               { name => "f24" },
+               { name => "f25" },
+               { name => "f26" },
+               { name => "f27" },
+               { name => "f28" },
+               { name => "f29" },
+               { name => "f30" },
+               { name => "f31" },
                { mode => $mode_fp }
        ]
 ); # %reg_classes