- more irp_resource_reserved()
[libfirm] / ir / be / becopyopt.c
index cd33474..20f7f4b 100644 (file)
@@ -220,17 +220,20 @@ 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;
+       const arch_register_t     *reg;
 
-       if (arch_irn_is(irn, ignore))
+       if (arch_irn_is_ignore(irn))
                return 0;
 
        reg = arch_get_irn_register(irn);
        if (arch_register_type_is(reg, ignore))
                return 0;
 
-       req = arch_get_register_req(irn, -1);
-       if (is_Reg_Phi(irn) || is_Perm_Proj(irn) || is_2addr_code(req))
+       if (is_Reg_Phi(irn) || is_Perm_Proj(irn))
+               return 1;
+
+       req = arch_get_register_req_out(irn);
+       if (is_2addr_code(req))
                return 1;
 
        return 0;
@@ -304,11 +307,11 @@ static int ou_max_ind_set_costs(unit_t *ou) {
         * safe: node has no interference, hence it is in every max stable set.
         * unsafe: node has an interference
         */
-       safe = alloca((ou->node_count-1) * sizeof(*safe));
-       safe_costs = 0;
-       safe_count = 0;
-       unsafe = alloca((ou->node_count-1) * sizeof(*unsafe));
-       unsafe_costs = alloca((ou->node_count-1) * sizeof(*unsafe_costs));
+       safe         = ALLOCAN(ir_node*, ou->node_count - 1);
+       safe_costs   = 0;
+       safe_count   = 0;
+       unsafe       = ALLOCAN(ir_node*, ou->node_count - 1);
+       unsafe_costs = ALLOCAN(int,      ou->node_count - 1);
        unsafe_count = 0;
        for(i=1; i<ou->node_count; ++i) {
                int is_safe = 1;
@@ -376,11 +379,13 @@ static int ou_max_ind_set_costs(unit_t *ou) {
        return safe_costs+best_weight;
 }
 
-static void co_collect_units(ir_node *irn, void *env) {
-       copy_opt_t *co = env;
+static void co_collect_units(ir_node *irn, void *env)
+{
+       const arch_register_req_t *req = arch_get_register_req_out(irn);
+       copy_opt_t                *co  = env;
        unit_t *unit;
 
-       if (!is_curr_reg_class(co, irn))
+       if (req->cls != co->cls)
                return;
        if (!co_is_optimizable_root(irn))
                return;
@@ -406,7 +411,7 @@ static void co_collect_units(ir_node *irn, void *env) {
                        int o, arg_pos;
                        ir_node *arg = get_irn_n(irn, i);
 
-                       assert(is_curr_reg_class(co, arg) && "Argument not in same register class.");
+                       assert(arch_get_irn_reg_class_out(arg) == co->cls && "Argument not in same register class.");
                        if (arg == irn)
                                continue;
                        if (nodes_interfere(co->cenv, irn, arg)) {
@@ -417,26 +422,27 @@ static void co_collect_units(ir_node *irn, void *env) {
                        /* Else insert the argument of the phi to the members of this ou */
                        DBG((dbg, LEVEL_1, "\t   Member: %+F\n", arg));
 
-                       if (!arch_irn_is(arg, ignore)) {
-                               /* Check if arg has occurred at a prior position in the arg/list */
-                               arg_pos = 0;
-                               for (o=1; o<unit->node_count; ++o) {
-                                       if (unit->nodes[o] == arg) {
-                                               arg_pos = o;
-                                               break;
-                                       }
-                               }
+                       if (arch_irn_is_ignore(arg))
+                               continue;
 
-                               if (!arg_pos) { /* a new argument */
-                                       /* insert node, set costs */
-                                       unit->nodes[unit->node_count] = arg;
-                                       unit->costs[unit->node_count] = co->get_costs(co, irn, arg, i);
-                                       unit->node_count++;
-                               } else { /* arg has occurred before in same phi */
-                                       /* increase costs for existing arg */
-                                       unit->costs[arg_pos] += co->get_costs(co, irn, arg, i);
+                       /* Check if arg has occurred at a prior position in the arg/list */
+                       arg_pos = 0;
+                       for (o=1; o<unit->node_count; ++o) {
+                               if (unit->nodes[o] == arg) {
+                                       arg_pos = o;
+                                       break;
                                }
                        }
+
+                       if (!arg_pos) { /* a new argument */
+                               /* insert node, set costs */
+                               unit->nodes[unit->node_count] = arg;
+                               unit->costs[unit->node_count] = co->get_costs(co, irn, arg, i);
+                               unit->node_count++;
+                       } else { /* arg has occurred before in same phi */
+                               /* increase costs for existing arg */
+                               unit->costs[arg_pos] += co->get_costs(co, irn, arg, i);
+                       }
                }
                unit->nodes = XREALLOC(unit->nodes, ir_node*, unit->node_count);
                unit->costs = XREALLOC(unit->costs, int,      unit->node_count);
@@ -450,8 +456,6 @@ static void co_collect_units(ir_node *irn, void *env) {
                unit->nodes[1] = get_Perm_src(irn);
                unit->costs[1] = co->get_costs(co, irn, unit->nodes[1], -1);
        } else {
-               const arch_register_req_t *req = arch_get_register_req(irn, -1);
-
                /* Src == Tgt of a 2-addr-code instruction */
                if (is_2addr_code(req)) {
                        const unsigned other = req->other_same;
@@ -461,10 +465,11 @@ static void co_collect_units(ir_node *irn, void *env) {
                        for (i = 0; (1U << i) <= other; ++i) {
                                if (other & (1U << i)) {
                                        ir_node *o  = get_irn_n(skip_Proj(irn), i);
-                                       if (!arch_irn_is(o, ignore) &&
-                                                       !nodes_interfere(co->cenv, irn, o)) {
-                                               ++count;
-                                       }
+                                       if (arch_irn_is_ignore(o))
+                                               continue;
+                                       if (nodes_interfere(co->cenv, irn, o))
+                                               continue;
+                                       ++count;
                                }
                        }
 
@@ -479,7 +484,7 @@ static void co_collect_units(ir_node *irn, void *env) {
                                for (i = 0; 1U << i <= other; ++i) {
                                        if (other & (1U << i)) {
                                                ir_node *o  = get_irn_n(skip_Proj(irn), i);
-                                               if (!arch_irn_is(o, ignore) &&
+                                               if (!arch_irn_is_ignore(o) &&
                                                                !nodes_interfere(co->cenv, irn, o)) {
                                                        unit->nodes[k] = o;
                                                        unit->costs[k] = co->get_costs(co, irn, o, -1);
@@ -527,7 +532,7 @@ static int compare_ous(const void *k1, const void *k2) {
        /* Units with constraints come first */
        u1_has_constr = 0;
        for (i=0; i<u1->node_count; ++i) {
-               arch_get_register_req(&req, u1->nodes[i], -1);
+               arch_get_register_req_out(&req, u1->nodes[i]);
                if (arch_register_req_is(&req, limited)) {
                        u1_has_constr = 1;
                        break;
@@ -536,7 +541,7 @@ static int compare_ous(const void *k1, const void *k2) {
 
        u2_has_constr = 0;
        for (i=0; i<u2->node_count; ++i) {
-               arch_get_register_req(&req, u2->nodes[i], -1);
+               arch_get_register_req_out(&req, u2->nodes[i]);
                if (arch_register_req_is(&req, limited)) {
                        u2_has_constr = 1;
                        break;
@@ -569,7 +574,7 @@ static void co_sort_units(copy_opt_t *co) {
        /* get the number of ous, remove them form the list and fill the array */
        list_for_each_entry(unit_t, ou, &co->units, units)
                count++;
-       ous = alloca(count * sizeof(*ous));
+       ous = ALLOCAN(unit_t, count);
 
        costs = co_get_max_copy_costs(co);
 
@@ -761,7 +766,7 @@ static void add_edge(copy_opt_t *co, ir_node *n1, ir_node *n2, int costs) {
        nbr->costs += costs;
 }
 
-static INLINE void add_edges(copy_opt_t *co, ir_node *n1, ir_node *n2, int costs) {
+static inline void add_edges(copy_opt_t *co, ir_node *n1, ir_node *n2, int costs) {
        if (! be_ifg_connected(co->cenv->ifg, n1, n2)) {
                add_edge(co, n1, n2, costs);
                add_edge(co, n2, n1, costs);
@@ -769,11 +774,12 @@ static INLINE void add_edges(copy_opt_t *co, ir_node *n1, ir_node *n2, int costs
 }
 
 static void build_graph_walker(ir_node *irn, void *env) {
-       copy_opt_t *co = env;
+       const arch_register_req_t *req = arch_get_register_req_out(irn);
+       copy_opt_t                *co  = env;
        int pos, max;
        const arch_register_t *reg;
 
-       if (!is_curr_reg_class(co, irn) || arch_irn_is(irn, ignore))
+       if (req->cls != co->cls || arch_irn_is_ignore(irn))
                return;
 
        reg = arch_get_irn_register(irn);
@@ -788,9 +794,7 @@ static void build_graph_walker(ir_node *irn, void *env) {
        } else if (is_Perm_Proj(irn)) { /* Perms */
                ir_node *arg = get_Perm_src(irn);
                add_edges(co, irn, arg, co->get_costs(co, irn, arg, 0));
-       }
-       else { /* 2-address code */
-               const arch_register_req_t *req = arch_get_register_req(irn, -1);
+       } else { /* 2-address code */
                if (is_2addr_code(req)) {
                        const unsigned other = req->other_same;
                        int i;
@@ -798,7 +802,7 @@ static void build_graph_walker(ir_node *irn, void *env) {
                        for (i = 0; 1U << i <= other; ++i) {
                                if (other & (1U << i)) {
                                        ir_node *other = get_irn_n(skip_Proj(irn), i);
-                                       if (!arch_irn_is(other, ignore))
+                                       if (!arch_irn_is_ignore(other))
                                                add_edges(co, irn, other, co->get_costs(co, irn, other, 0));
                                }
                        }
@@ -840,14 +844,13 @@ static int co_dump_appel_disjoint_constraints(const copy_opt_t *co, ir_node *a,
 {
        ir_node *nodes[]  = { a, b };
        bitset_t *constr[] = { NULL, NULL };
-       const arch_register_req_t *req;
        int j;
 
        constr[0] = bitset_alloca(co->cls->n_regs);
        constr[1] = bitset_alloca(co->cls->n_regs);
 
        for (j = 0; j < 2; ++j) {
-               req = arch_get_register_req(nodes[j], BE_OUT_POS(0));
+               const arch_register_req_t *req = arch_get_register_req_out(nodes[j]);
                if(arch_register_req_is(req, limited))
                        rbitset_copy_to_bitset(req->limited, constr[j]);
                else
@@ -860,9 +863,9 @@ static int co_dump_appel_disjoint_constraints(const copy_opt_t *co, ir_node *a,
 
 void co_dump_appel_graph(const copy_opt_t *co, FILE *f)
 {
-       be_ifg_t *ifg  = co->cenv->ifg;
-       int *color_map = alloca(co->cls->n_regs * sizeof(color_map[0]));
-       int *node_map  = XMALLOCN(int, get_irg_last_idx(co->irg) + 1);
+       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_node *irn;
        void *it, *nit;
@@ -885,21 +888,20 @@ void co_dump_appel_graph(const copy_opt_t *co, FILE *f)
 
        n = n_regs;
        be_ifg_foreach_node(ifg, it, irn) {
-               if (!arch_irn_is(irn, ignore))
-                       node_map[get_irn_idx(irn)] = n++;
+               if (arch_irn_is_ignore(irn))
+                       continue;
+               node_map[get_irn_idx(irn)] = n++;
        }
 
        fprintf(f, "%d %d\n", n, n_regs);
 
        be_ifg_foreach_node(ifg, it, irn) {
-               if (!arch_irn_is(irn, ignore)) {
-                       int idx            = node_map[get_irn_idx(irn)];
-                       affinity_node_t *a = get_affinity_info(co, irn);
-
-                       const arch_register_req_t *req;
-                       ir_node *adj;
+               if (!arch_irn_is_ignore(irn)) {
+                       int idx                        = node_map[get_irn_idx(irn)];
+                       affinity_node_t           *a   = get_affinity_info(co, irn);
+                       const arch_register_req_t *req = arch_get_register_req_out(irn);
+                       ir_node                   *adj;
 
-                       req = arch_get_register_req(irn, BE_OUT_POS(0));
                        if(arch_register_req_is(req, limited)) {
                                for(i = 0; i < co->cls->n_regs; ++i) {
                                        if(!rbitset_is_set(req->limited, i) && color_map[i] >= 0)
@@ -908,7 +910,7 @@ void co_dump_appel_graph(const copy_opt_t *co, FILE *f)
                        }
 
                        be_ifg_foreach_neighbour(ifg, nit, irn, adj) {
-                               if (!arch_irn_is(adj, ignore) &&
+                               if (!arch_irn_is_ignore(adj) &&
                                                !co_dump_appel_disjoint_constraints(co, irn, adj)) {
                                        int adj_idx = node_map[get_irn_idx(adj)];
                                        if(idx < adj_idx)
@@ -920,7 +922,7 @@ void co_dump_appel_graph(const copy_opt_t *co, FILE *f)
                                neighb_t *n;
 
                                co_gs_foreach_neighb(a, n) {
-                                       if (!arch_irn_is(n->irn, ignore)) {
+                                       if (!arch_irn_is_ignore(n->irn)) {
                                                int n_idx = node_map[get_irn_idx(n->irn)];
                                                if(idx < n_idx)
                                                        fprintf(f, "%d %d %d\n", idx, n_idx, (int) n->costs);
@@ -995,18 +997,15 @@ static void ifg_dump_graph_attr(FILE *f, void *self)
 static int ifg_is_dump_node(void *self, ir_node *irn)
 {
        (void)self;
-       return !arch_irn_is(irn, ignore);
+       return !arch_irn_is_ignore(irn);
 }
 
 static void ifg_dump_node_attr(FILE *f, void *self, ir_node *irn)
 {
-       co_ifg_dump_t *env         = self;
-       const arch_register_t *reg = arch_get_irn_register(irn);
-       const arch_register_req_t *req;
-       int limited;
-
-       req = arch_get_register_req(irn, BE_OUT_POS(0));
-       limited = arch_register_req_is(req, limited);
+       co_ifg_dump_t             *env     = self;
+       const arch_register_t     *reg     = arch_get_irn_register(irn);
+       const arch_register_req_t *req     = arch_get_register_req_out(irn);
+       int                        limited = arch_register_req_is(req, limited);
 
        if(env->flags & CO_IFG_DUMP_LABELS) {
                ir_fprintf(f, "label=\"%+F", irn);