Added support for ignore nodes and ignor colors to:
authorDaniel Grund <grund@cs.uni-saarland.de>
Mon, 13 Feb 2006 10:11:11 +0000 (10:11 +0000)
committerDaniel Grund <grund@cs.uni-saarland.de>
Mon, 13 Feb 2006 10:11:11 +0000 (10:11 +0000)
 - belady spiller
 - copyopt general
 - copyopt heur

ir/be/becopyheur.c
ir/be/becopyopt.c
ir/be/becopyopt.h
ir/be/bespillbelady.c

index a76b904..bdab704 100644 (file)
@@ -462,7 +462,10 @@ static INLINE void ou_insert_qnode(unit_t *ou, qnode_t *qn) {
 static void ou_optimize(unit_t *ou) {
        int i;
        qnode_t *curr = NULL, *tmp;
-       bitset_t *pos_regs = bitset_alloca(ou->co->chordal_env->cls->n_regs);
+       arch_env_t *aenv = get_arch_env(ou->co);
+       const arch_register_class_t *cls = ou->co->chordal_env->cls;
+       bitset_t *pos_regs = bitset_alloca(cls->n_regs);
+       bitset_t *ign_regs = bitset_alloca(cls->n_regs);
 
        DBG((dbg, LEVEL_1, "\tOptimizing unit:\n"));
        for (i=0; i<ou->node_count; ++i)
@@ -470,7 +473,14 @@ static void ou_optimize(unit_t *ou) {
 
        /* init queue */
        INIT_LIST_HEAD(&ou->queue);
-       arch_get_allocatable_regs(get_arch_env(ou->co), ou->nodes[0], -1, pos_regs);
+
+       arch_get_allocatable_regs(aenv, ou->nodes[0], -1, pos_regs);
+
+       /* exclude ingore colors */
+       arch_put_non_ignore_regs(aenv, cls, ign_regs);
+       bitset_and(pos_regs, ign_regs);
+
+       /* create new qnode */
        bitset_foreach(pos_regs, i)
                ou_insert_qnode(ou, new_qnode(ou, i));
 
index d45ba4c..0a6cb0e 100644 (file)
@@ -124,6 +124,7 @@ static void co_collect_units(ir_node *irn, void *env) {
        copy_opt_t *co = env;
        unit_t *unit;
        arch_register_req_t req;
+       arch_env_t *aenv = co->chordal_env->main_env->arch_env;
 
        if (!is_curr_reg_class(irn))
                return;
@@ -268,20 +269,25 @@ void free_copy_opt(copy_opt_t *co) {
 }
 
 int is_optimizable_arg(const copy_opt_t *co, ir_node *irn) {
-       arch_env_t *aenv = co->chordal_env->main_env->arch_env;
+       arch_env_t *aenv = get_arch_env(co);
        const ir_edge_t *edge;
 
+       if (arch_irn_is_ignore(aenv, irn))
+               return 0;
+
        foreach_out_edge(irn, edge) {
                ir_node *n = edge->src;
-               arch_register_req_t req;
 
-               arch_get_register_req(aenv, &req, n, -1);
+               if (!nodes_interfere(co->chordal_env, irn, n) || irn == n) {
+                       arch_register_req_t req;
+                       arch_get_register_req(aenv, &req, n, -1);
 
-               if(     (       (req.type == arch_register_req_type_should_be_same && req.other == irn) ||
-                               is_Reg_Phi(n) ||
-                               is_Perm(get_arch_env(co), n)
-                       ) && (irn == n || !nodes_interfere(co->chordal_env, irn, n)))
+                       if(is_Reg_Phi(n) ||
+                          is_Perm(aenv, n) ||
+                          (arch_register_req_is(&req, should_be_same) && req.other == irn)
+                         )
                                return 1;
+               }
        }
 
        return 0;
index 38a0298..0e2f167 100644 (file)
@@ -96,7 +96,7 @@ void free_copy_opt(copy_opt_t *co);
  * @param irn  The irn to check
  * @param req  A register_requirement structure (used to check for 2-addr-code)
  */
-#define is_optimizable(arch, irn, req) (is_Reg_Phi(irn) || is_Perm_Proj(arch, irn) || is_2addr_code(arch, irn, req))
+#define is_optimizable(arch, irn, req) (!arch_irn_is_ignore(arch, irn) && (is_Reg_Phi(irn) || is_Perm_Proj(arch, irn) || is_2addr_code(arch, irn, req)))
 
 /**
  * Checks if the irn is a non-interfering argument of a node which 'is_optimizable'
index 04cf887..2663df6 100644 (file)
@@ -225,6 +225,14 @@ static int is_mem_phi(const ir_node *irn, void *data) {
        return !workset_contains(sws, irn);
 }
 
+/**
+ * @return The distance to the next use
+ *         Or 0 if irn is an ignore node
+ */
+#define get_distance(bel, from, from_step, def, skip_from_uses) \
+               ((arch_irn_is_ignore(bel->arch, def) ) ? 0 : be_get_next_use(bel->uses, from, from_step, def, skip_from_uses))
+
+
 /**
  * Collects all values live-in at block @p blk and all phi results in this block.
  * Then it adds the best values (at most n_regs) to the blocks start_workset.
@@ -251,7 +259,7 @@ static void compute_block_start_info(ir_node *blk, void *env) {
        sched_foreach(blk, irn)
                if (is_Phi(irn) && arch_get_irn_reg_class(bel->arch, irn, -1) == bel->cls) {
                        loc.irn = irn;
-                       loc.time = be_get_next_use(bel->uses, first, 0, irn, 0);
+                       loc.time = get_distance(bel, first, 0, irn, 0);
                        obstack_grow(&ob, &loc, sizeof(loc));
                        DBG((dbg, DBG_START, "    %+F:\n", irn));
                        count++;
@@ -261,7 +269,7 @@ static void compute_block_start_info(ir_node *blk, void *env) {
        live_foreach(blk, li)
                if (live_is_in(li) && arch_get_irn_reg_class(bel->arch, li->irn, -1) == bel->cls) {
                        loc.irn = (ir_node *)li->irn;
-                       loc.time = be_get_next_use(bel->uses, first, 0, li->irn, 0);
+                       loc.time = get_distance(bel, first, 0, li->irn, 0);
                        obstack_grow(&ob, &loc, sizeof(loc));
                        DBG((dbg, DBG_START, "    %+F:\n", irn));
                        count++;
@@ -348,7 +356,7 @@ static void displace(belady_env_t *bel, workset_t *new_vals, int is_usage) {
        if (len > max_allowed) {
                /* get current next-use distance */
                for (i=0; i<ws->len; ++i)
-                       workset_set_time(ws, i, be_get_next_use(bel->uses, bel->instr, bel->instr_nr, workset_get_val(ws, i), !is_usage));
+                       workset_set_time(ws, i, get_distance(bel, bel->instr, bel->instr_nr, workset_get_val(ws, i), !is_usage));
 
                /* sort entries by increasing nextuse-distance*/
                workset_sort(ws);