fixed precedence constraint
[libfirm] / ir / be / bechordal.c
index 2c105fe..604ff67 100644 (file)
@@ -7,9 +7,8 @@
  * Copyright (C) Universitaet Karlsruhe
  * Released under the GPL
  */
-
 #ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
 #endif
 
 #ifdef HAVE_MALLOC_H
@@ -42,7 +41,6 @@
 
 #include "beutil.h"
 #include "besched.h"
-#include "benumb_t.h"
 #include "besched_t.h"
 #include "belive_t.h"
 #include "benode_t.h"
@@ -51,6 +49,7 @@
 #include "beifg.h"
 #include "beinsn_t.h"
 #include "bestatevent.h"
+#include "beirg_t.h"
 
 #include "bechordal_t.h"
 #include "bechordal_draw.h"
@@ -134,8 +133,8 @@ static INLINE border_t *border_add(be_chordal_env_t *env, struct list_head *head
                 */
                set_irn_link(irn, def);
 
-               b->magic = BORDER_FOURCC;
-               def->magic = BORDER_FOURCC;
+               DEBUG_ONLY(b->magic = BORDER_FOURCC);
+               DEBUG_ONLY(def->magic = BORDER_FOURCC);
        }
 
        /*
@@ -234,31 +233,36 @@ static ir_node *prepare_constr_insn(be_chordal_env_t *env, ir_node *irn)
 
        for (i = get_irn_arity(irn) - 1; i >= 0; --i) {
                ir_node *op = get_irn_n(irn, i);
-
+               ir_node *copy;
                const arch_register_t *reg;
                arch_register_req_t req;
 
-               if (arch_get_irn_reg_class(aenv, irn, i) == env->cls) {
-                       reg = arch_get_irn_register(aenv, op);
+               if (arch_get_irn_reg_class(aenv, irn, i) != env->cls)
+                       continue;
 
-                       if (reg && arch_register_type_is(reg, ignore)) {
-                               arch_get_register_req(aenv, &req, irn, i);
+               reg = arch_get_irn_register(aenv, op);
 
-                               if (arch_register_req_is(&req, limited)) {
-                                       bitset_clear_all(tmp);
-                                       req.limited(req.limited_env, tmp);
+               if (reg == NULL || !arch_register_type_is(reg, ignore))
+                       continue;
+               if(arch_register_type_is(reg, joker))
+                       continue;
 
-                                       if (! bitset_is_set(tmp, reg->index)) {
-                                               ir_node *copy = be_new_Copy(env->cls, env->irg, bl, op);
-                                               be_stat_ev("constr_copy", 1);
+               arch_get_register_req(aenv, &req, irn, i);
+               if (!arch_register_req_is(&req, limited))
+                       continue;
 
-                                               sched_add_before(irn, copy);
-                                               set_irn_n(irn, i, copy);
-                                               DBG((env->dbg, LEVEL_3, "inserting ignore arg copy %+F for %+F pos %d\n", copy, irn, i));
-                                       }
-                               }
-                       }
-               }
+               bitset_clear_all(tmp);
+               req.limited(req.limited_env, tmp);
+
+               if (bitset_is_set(tmp, reg->index))
+                       continue;
+
+               copy = be_new_Copy(env->cls, env->irg, bl, op);
+               be_stat_ev("constr_copy", 1);
+
+               sched_add_before(irn, copy);
+               set_irn_n(irn, i, copy);
+               DBG((env->dbg, LEVEL_3, "inserting ignore arg copy %+F for %+F pos %d\n", copy, irn, i));
        }
 
     insn = chordal_scan_insn(env, irn);
@@ -270,19 +274,22 @@ static ir_node *prepare_constr_insn(be_chordal_env_t *env, ir_node *irn)
        for(i = insn->use_start; i < insn->n_ops; ++i) {
                be_operand_t *op = &insn->ops[i];
 
-               if(op->has_constraints) {
-                       for(j = i + 1; j < insn->n_ops; ++j) {
-                               be_operand_t *a_op = &insn->ops[j];
+               if(!op->has_constraints)
+                       continue;
 
-                               if(a_op->carrier == op->carrier && a_op->has_constraints) {
-                                       ir_node *copy = be_new_Copy(env->cls, env->irg, bl, op->carrier);
-                                       be_stat_ev("constr_copy", 1);
+               for(j = i + 1; j < insn->n_ops; ++j) {
+                       ir_node *copy;
+                       be_operand_t *a_op = &insn->ops[j];
 
-                                       sched_add_before(insn->irn, copy);
-                                       set_irn_n(insn->irn, a_op->pos, copy);
-                                       DBG((env->dbg, LEVEL_3, "inserting multiple constr copy %+F for %+F pos %d\n", copy, insn->irn, a_op->pos));
-                               }
-                       }
+                       if(a_op->carrier != op->carrier || !a_op->has_constraints)
+                               continue;
+
+                       copy = be_new_Copy(env->cls, env->irg, bl, op->carrier);
+                       be_stat_ev("constr_copy", 1);
+
+                       sched_add_before(insn->irn, copy);
+                       set_irn_n(insn->irn, a_op->pos, copy);
+                       DBG((env->dbg, LEVEL_3, "inserting multiple constr copy %+F for %+F pos %d\n", copy, insn->irn, a_op->pos));
                }
        }
 
@@ -298,6 +305,7 @@ static ir_node *prepare_constr_insn(be_chordal_env_t *env, ir_node *irn)
                and being constrained to a register which also occurs in out constraints.
        */
        for(i = insn->use_start; i < insn->n_ops; ++i) {
+               ir_node *copy;
                be_operand_t *op = &insn->ops[i];
 
                bitset_copy(tmp, op->regs);
@@ -309,22 +317,26 @@ static ir_node *prepare_constr_insn(be_chordal_env_t *env, ir_node *irn)
                        2) lives through the node.
                        3) is constrained to a register occuring in out constraints.
                */
-               if(op->has_constraints && values_interfere(lv, insn->irn, op->carrier) && bitset_popcnt(tmp) > 0) {
-                       /*
-                               only create the copy if the operand is no copy.
-                               this is necessary since the assure constraints phase inserts
-                               Copies and Keeps for operands which must be different from the results.
-                               Additional copies here would destroy this.
-                       */
-                       if(!be_is_Copy(op->carrier)) {
-                               ir_node *copy = be_new_Copy(env->cls, env->irg, bl, op->carrier);
+               if(!op->has_constraints ||
+                               !values_interfere(lv, insn->irn, op->carrier) ||
+                               bitset_popcnt(tmp) == 0)
+                       continue;
 
-                               sched_add_before(insn->irn, copy);
-                               set_irn_n(insn->irn, op->pos, copy);
-                               DBG((env->dbg, LEVEL_3, "inserting constr copy %+F for %+F pos %d\n", copy, insn->irn, op->pos));
-                               be_liveness_update(lv, op->carrier);
-                       }
-               }
+               /*
+                  only create the copy if the operand is no copy.
+                  this is necessary since the assure constraints phase inserts
+                  Copies and Keeps for operands which must be different from the results.
+                  Additional copies here would destroy this.
+                */
+               if(be_is_Copy(op->carrier))
+                       continue;
+
+               copy = be_new_Copy(env->cls, env->irg, bl, op->carrier);
+
+               sched_add_before(insn->irn, copy);
+               set_irn_n(insn->irn, op->pos, copy);
+               DBG((env->dbg, LEVEL_3, "inserting constr copy %+F for %+F pos %d\n", copy, insn->irn, op->pos));
+               be_liveness_update(lv, op->carrier);
        }
 
 end:
@@ -856,8 +868,7 @@ static void assign(ir_node *block, void *env_ptr)
        }
 
        /*
-        * Mind that the sequence
-        * of defs from back to front defines a perfect
+        * Mind that the sequence of defs from back to front defines a perfect
         * elimination order. So, coloring the definitions from first to last
         * will work.
         */
@@ -953,8 +964,6 @@ void be_ra_chordal_color(be_chordal_env_t *chordal_env)
        /* Assign the colors */
        dom_tree_walk_irg(irg, assign, NULL, &env);
 
-       be_numbering_done(irg);
-
        if(chordal_env->opts->dump_flags & BE_CH_DUMP_TREE_INTV) {
                plotter_t *plotter;
                ir_snprintf(buf, sizeof(buf), "ifg_%s_%F.eps", chordal_env->cls->name, irg);