Copied register assignments from in's to out's for all phi-perms.
authorDaniel Grund <grund@cs.uni-saarland.de>
Fri, 29 Jul 2005 16:59:36 +0000 (16:59 +0000)
committerDaniel Grund <grund@cs.uni-saarland.de>
Fri, 29 Jul 2005 16:59:36 +0000 (16:59 +0000)
This should have fixed a bug. arch_set_irn_regiseter not working?

ir/be/becopyilp.c
ir/be/becopyoptmain.c
ir/be/bemain.c
ir/be/bessadestr.c

index 4ff9f25..8853c8b 100644 (file)
@@ -445,7 +445,7 @@ static void M_constr_walker(ir_node *block, void *env) {
                        /* compute the minimal costs (rhs) */
                        int phi_nr, sum=0, max=-1, minimal_costs;
                        bitset_foreach(candidates, phi_nr) {
-                               costs[phi_nr] = get_costs(pi, phis[phi_nr], irn);
+                               costs[phi_nr] = get_costs(pi, phis[phi_nr], irn); //TODO this failes for nodes not in the ou. the interfering ones.
                                sum += costs[phi_nr];
                                max = MAX(max, costs[phi_nr]);
                        }
index 0e31367..e1be7a8 100644 (file)
@@ -19,7 +19,7 @@
 #include "becopyoptmain.h"
 
 #define DO_HEUR
-#define DO_ILP
+#undef DO_ILP
 
 #define DEBUG_LVL SET_LEVEL_1
 static firm_dbg_module_t *dbg = NULL;
@@ -37,13 +37,13 @@ void be_copy_opt(be_chordal_env_t *chordal_env) {
        compute_outs(chordal_env->session_env->irg);
 
        co = new_copy_opt(chordal_env, get_costs_loop_depth);
-       DBG((dbg, LEVEL_1, "===>  %s  <===\n", co->name));
+       DBG((dbg, LEVEL_1, "----> CO: %s\n", co->name));
 
 #ifdef DO_STAT
        lb = co_get_lower_bound(co);
        copy_costs = co_get_copy_costs(co);
        curr_vals[I_COPIES_INIT] += copy_costs;
-       DBG((dbg, LEVEL_1, "Init costs: %3d / %3d\n", lb, copy_costs));
+       DBG((dbg, LEVEL_1, "Init costs: %3d <= %3d\n", lb, copy_costs));
 #endif
 
 #ifdef DO_HEUR
@@ -51,7 +51,7 @@ void be_copy_opt(be_chordal_env_t *chordal_env) {
 #ifdef DO_STAT
        copy_costs = co_get_copy_costs(co);
        curr_vals[I_COPIES_HEUR] += copy_costs;
-       DBG((dbg, LEVEL_1, "Heur costs: %3d / %3d\n", lb, copy_costs));
+       DBG((dbg, LEVEL_1, "Heur costs: %3d <= %3d\n", lb, copy_costs));
 #endif
 #endif
 
@@ -67,7 +67,7 @@ void be_copy_opt(be_chordal_env_t *chordal_env) {
        copy_costs = co_get_copy_costs(co);
        assert(copy_costs>=lb && "At least one computation of these two is boooogy");
        curr_vals[I_COPIES_OPT] += copy_costs;
-       DBG((dbg, LEVEL_1, "Opt  costs: %3d / %3d\n", copy_costs));
+       DBG((dbg, LEVEL_1, "Opt  costs: %3d <= %3d\n", lb, copy_costs));
 #endif
 #endif
 
index 7e8163c..ef14f15 100644 (file)
@@ -36,7 +36,7 @@
 #include "bearch_firm.h"
 #include "benode_t.h"
 #include "beirgmod.h"
-#include "bespillilp.h"
+//#include "bespillilp.h"
 
 #include "beasm_dump_globals.h"
 #include "beasm_asm_gnu.h"
@@ -62,6 +62,7 @@ static be_main_env_t *be_init_env(be_main_env_t *env)
 
   obstack_init(&env->obst);
   env->dbg = firm_dbg_register("be.main");
+  firm_dbg_set_mask(env->dbg, SET_LEVEL_1);
 
   env->arch_env = obstack_alloc(&env->obst, sizeof(env->arch_env[0]));
   arch_env_init(env->arch_env, isa);
@@ -132,7 +133,7 @@ static void be_main_loop(void)
                ir_graph *irg = get_irp_irg(i);
                be_main_session_env_t session;
 
-    DBG((env.dbg, LEVEL_1, "be irg: %F\n", irg));
+               DBG((env.dbg, LEVEL_1, "====> IRG: %F\n", irg));
 
                /* Init the session. */
                be_init_session_env(&session, &env, irg);
@@ -147,28 +148,28 @@ static void be_main_loop(void)
                /* Verify the schedule */
                sched_verify_irg(irg);
 
-    /* Build liveness information */
-    be_liveness(irg);
+               /* Build liveness information */
+               be_liveness(irg);
 
                copystat_reset();
                copystat_collect_irg(irg, env.arch_env);
 
-    /*
-     * Verifying the schedule once again cannot hurt.
-     */
-    sched_verify_irg(irg);
+               /*
+                * Verifying the schedule once again cannot hurt.
+                */
+               sched_verify_irg(irg);
 
                /* Perform the following for each register class. */
                for(j = 0, m = isa->get_n_reg_class(); j < m; ++j) {
                        be_chordal_env_t *chordal_env;
                        const arch_register_class_t *cls = isa->get_reg_class(j);
 
-      DBG((env.dbg, LEVEL_1, "\treg class: %s\n", cls->name));
+                       DBG((env.dbg, LEVEL_1, "----> Reg class: %s\n", cls->name));
 
-      be_numbering(irg);
-      be_liveness(irg);
+                       be_numbering(irg);
+                       be_liveness(irg);
 
-      // be_spill_ilp(&session, cls);
+                       //be_spill_ilp(&session, cls);
 
                        chordal_env = be_ra_chordal(&session, cls);
 
@@ -181,10 +182,10 @@ static void be_main_loop(void)
 
                        be_ssa_destruction(chordal_env);
                        be_ssa_destruction_check(chordal_env);
-
                        be_ra_chordal_check(chordal_env);
-      be_ra_chordal_done(chordal_env);
-      be_numbering_done(irg);
+
+                       be_ra_chordal_done(chordal_env);
+                       be_numbering_done(irg);
                }
                dump_ir_block_graph(session.irg, "-post");
 
index 4e42ac1..17d5425 100644 (file)
 #include "besched_t.h"
 
 static firm_dbg_module_t *dbg = NULL;
-#define DEBUG_LVL SET_LEVEL_2
+#define DEBUG_LVL SET_LEVEL_3
 
 
 #define get_chordal_arch(ce) ((ce)->session_env->main_env->arch_env)
 #define get_reg(irn) arch_get_irn_register(get_chordal_arch(chordal_env), irn, 0)
 #define set_reg(irn, reg) arch_set_irn_register(get_chordal_arch(chordal_env), irn, 0, reg)
 
-#define is_Branch(irn)          (arch_irn_classify(arch_env, irn) == arch_irn_class_branch)
 #define is_Perm(irn)            (arch_irn_classify(arch_env, irn) == arch_irn_class_perm)
 #define get_reg_cls(irn)        (arch_get_irn_reg_class(arch_env, irn, arch_pos_make_out(0)))
 #define is_curr_reg_class(irn)  (get_reg_cls(p) == chordal_env->cls)
@@ -71,11 +70,84 @@ static INLINE void build_phi_rings(be_chordal_env_t *env)
 }
 
 static int skip_cf_predicator(const ir_node *irn, void *data) {
-  be_chordal_env_t *ce = data;
-  arch_env_t *ae = ce->session_env->main_env->arch_env;
+  be_chordal_env_t *chordal_env = data;
+  arch_env_t *ae = chordal_env->session_env->main_env->arch_env;
   return arch_irn_classify(ae, irn) == arch_irn_class_branch;
 }
 
+static void insert_all_perms_walker(ir_node *bl, void *data)
+{
+  be_chordal_env_t *chordal_env = data;
+  pmap *perm_map = chordal_env->data;
+  ir_graph *irg = chordal_env->session_env->irg;
+  const be_node_factory_t *fact = chordal_env->session_env->main_env->node_factory;
+
+  /* Dummy targets for the projs */
+  ir_node *dummy = new_rd_Unknown(irg, mode_T);
+
+  assert(is_Block(bl));
+
+  /* If the link flag is NULL, this block has no phis. */
+  if(get_irn_link(bl)) {
+    int i, n;
+
+    /* Look at all predecessors of the phi block */
+    for(i = 0, n = get_irn_arity(bl); i < n; ++i) {
+      ir_node *pred_bl = get_Block_cfgpred_block(bl, i);
+      ir_node *phi, *perm, *insert_after;
+      ir_node **in;
+      int j, n_projs = 0;
+      pmap_entry *ent;
+      pmap *arg_map = pmap_create();
+
+      assert(!pmap_contains(perm_map, pred_bl) && "Already permed that block");
+
+      /*
+       * Note that all phis in the list are in the same register class
+       * by construction.
+       */
+      for(phi = get_irn_link(bl); phi; phi = get_irn_link(phi)) {
+        ir_node *arg = get_irn_n(phi, i);
+        ir_node *proj = pmap_get(arg_map, arg);
+
+        if(!proj) {
+          proj = new_r_Proj(irg, pred_bl, dummy, get_irn_mode(arg), n_projs++);
+          pmap_insert(arg_map, arg, proj);
+        }
+
+        set_irn_n(phi, i, proj);
+      }
+
+      j = 0;
+      in = malloc(n_projs * sizeof(in[0]));
+      pmap_foreach(arg_map, ent) {
+        in[j++] = ent->key;
+        /* register allocation is copied form former arguments
+         * to the projs (new arguments)
+         */
+        DBG((dbg, LEVEL_2, "Copy register assignment %s from %+F to %+F\n", get_reg(ent->key)->name, ent->key, ent->value));
+        set_reg(ent->value, get_reg(ent->key));
+      }
+
+      perm = new_Perm(fact, chordal_env->cls, irg, pred_bl, n_projs, in);
+      insert_after = sched_skip(sched_last(pred_bl), 0, skip_cf_predicator, chordal_env);
+      sched_add_after(insert_after, perm);
+      exchange(dummy, perm);
+
+      free(in);
+      pmap_destroy(arg_map);
+
+      /* register in perm map */
+      pmap_insert(perm_map, pred_bl, perm);
+    }
+  }
+}
+
+static void insert_all_perms(be_chordal_env_t *chordal_env) {
+       DBG((dbg, LEVEL_1, "Placing perms...\n"));
+       irg_block_walk_graph(chordal_env->session_env->irg, insert_all_perms_walker, NULL, chordal_env);
+}
+
 #define is_pinned(irn) (get_irn_link(irn))
 #define get_pinning_block(irn) ((ir_node *)get_irn_link(irn))
 #define pin_irn(irn, lock) (set_irn_link(irn, lock))
@@ -88,8 +160,7 @@ static int skip_cf_predicator(const ir_node *irn, void *data) {
 static void adjust_phi_arguments(be_chordal_env_t *chordal_env, ir_node *phi) {
        int i, max;
        ir_node *arg, *phi_block, *arg_block;
-       arch_env_t *arch_env = get_chordal_arch(chordal_env);
-  const be_main_session_env_t *session = chordal_env->session_env;
+       const be_main_session_env_t *session = chordal_env->session_env;
        const arch_register_t *phi_reg, *arg_reg;
        const arch_register_class_t *cls;
 
@@ -105,27 +176,30 @@ static void adjust_phi_arguments(be_chordal_env_t *chordal_env, ir_node *phi) {
                ir_node *perm;
 
                arg = get_irn_n(phi, i);
+               assert(is_Proj(arg));
                arg_block = get_nodes_block(arg);
                arg_reg = get_reg(arg);
+               assert(arg_reg && "Register must be set while placing perms");
+               DBG((dbg, LEVEL_3, "%+F has register %s assigned\n", arg, arg_reg->name));
                perm = get_Proj_pred(arg);
-               // assert(is_Perm(perm));
+               //TODO reenable this if classify is implemented. assert(is_Perm(perm));
 
                DBG((dbg, LEVEL_1, "    arg %+F has perm %+F\n", arg, perm));
                /* if registers don't match ...*/
                if (phi_reg != arg_reg) {
-                       DBG((dbg, LEVEL_1, "      regs don't match %d %d\n", phi_reg, arg_reg));
+                       DBG((dbg, LEVEL_1, "      regs don't match %d %d\n", phi_reg->name, arg_reg->name));
 
                        /* First check if there is another phi in the same block
                         * having arg at the same pos in its arg-list and the same color as arg */
                        if (!is_pinned(arg)) {
-                               DBG((dbg, LEVEL_1, "      arg is not pinned\n"));
+                               DBG((dbg, LEVEL_1, "        arg is not pinned\n"));
                                ir_node *other_phi = phi;
-        for(other_phi = get_irn_link(phi_block); other_phi; other_phi = get_irn_link(other_phi)) {
-          if(other_phi == phi)
-            continue;
+                               for(other_phi = get_irn_link(phi_block); other_phi; other_phi = get_irn_link(other_phi)) {
+                                       if(other_phi == phi)
+                                               continue;
                                        assert(is_Phi(other_phi) && get_nodes_block(phi) == get_nodes_block(other_phi) && "link fields are screwed up");
                                        if (get_irn_n(other_phi, i) == arg && get_reg(other_phi) == arg_reg) {
-                                               DBG((dbg, LEVEL_1, "      other phi pinned the argument\n"));
+                                               DBG((dbg, LEVEL_1, "        but other phi (%+F) just pinned it\n", other_phi));
                                                pin_irn(arg, phi_block);
                                        }
                                }
@@ -143,7 +217,7 @@ static void adjust_phi_arguments(be_chordal_env_t *chordal_env, ir_node *phi) {
                                dupl = new_Copy(session->main_env->node_factory, cls, session->irg, arg_block, arg);
                                set_irn_n(phi, i, dupl);
                                set_reg(dupl, phi_reg);
-                               DBG((dbg, LEVEL_1, "      inserting dupl %+F\n", dupl));
+                               DBG((dbg, LEVEL_1, "      arg is pinned so insert dupl %+F\n", dupl));
 
                                /* Add dupl to schedule */
                                tmp = sched_next(perm);
@@ -151,13 +225,6 @@ static void adjust_phi_arguments(be_chordal_env_t *chordal_env, ir_node *phi) {
                                        tmp = sched_next(tmp);
                                sched_add_after(tmp, dupl);
 
-                               /* Add dupl to chained list of duplicates. Ptrs starting at the Perm */
-                               tmp = perm;
-                               while (get_irn_link(tmp))
-                                       tmp = get_irn_link(tmp);
-                               set_irn_link(tmp, dupl);
-                               set_irn_link(dupl, NULL);
-
                                /* now the arg is the dupl */
                                arg = dupl;
                        } else {
@@ -167,9 +234,11 @@ static void adjust_phi_arguments(be_chordal_env_t *chordal_env, ir_node *phi) {
                                 * livein(PhiBl) = liveout(ArgBl), if all phis are processed then
                                 * every color is used exactly once.
                                 */
-                               DBG((dbg, LEVEL_1, "      just set color\n"));
+                               DBG((dbg, LEVEL_1, "      arg is not pinned so just set register to %s\n", phi_reg->name));
                                set_reg(arg, phi_reg);
                        }
+               } else {
+                       DBG((dbg, LEVEL_1, "      regs match %d\n"));
                }
 
                /* Now the color of the arg (arg may be a dupl now) and the phi-result are equal.
@@ -180,92 +249,25 @@ static void adjust_phi_arguments(be_chordal_env_t *chordal_env, ir_node *phi) {
        }
 }
 
-static void insert_all_perms_walker(ir_node *bl, void *data)
-{
-  be_chordal_env_t *ce = data;
-  pmap *perm_map = ce->data;
-  ir_graph *irg = ce->session_env->irg;
-  const be_node_factory_t *fact = ce->session_env->main_env->node_factory;
-
-  /* Dummy targets for the projs */
-  ir_node *dummy = new_rd_Unknown(irg, mode_T);
-
-  assert(is_Block(bl));
-
-  /* If the link flag is NULL, this block has no phis. */
-  if(get_irn_link(bl)) {
-    int i, n;
-
-    /* Look at all predecessors of the phi block */
-    for(i = 0, n = get_irn_arity(bl); i < n; ++i) {
-      ir_node *pred_bl = get_Block_cfgpred_block(bl, i);
-      ir_node *phi, *perm, *insert_after;
-      ir_node **in;
-      int j, n_projs = 0;
-      pmap_entry *ent;
-      pmap *arg_map = pmap_create();
-
-      assert(!pmap_contains(perm_map, pred_bl) && "Already permed that block");
-
-      /*
-       * Note that all phis in the ring are in the same register class
-       * by construction.
-       */
-      for(phi = get_irn_link(bl); phi; phi = get_irn_link(phi)) {
-        ir_node *arg = get_irn_n(phi, i);
-        ir_node *proj = pmap_get(arg_map, arg);
-
-        if(!proj) {
-          proj = new_r_Proj(irg, pred_bl, dummy, get_irn_mode(arg), n_projs++);
-          pmap_insert(arg_map, arg, proj);
-        }
-
-        set_irn_n(phi, i, proj);
-      }
-
-      j = 0;
-      in = malloc(n_projs * sizeof(in[0]));
-      pmap_foreach(arg_map, ent)
-        in[j++] = ent->key;
-
-      perm = new_Perm(fact, ce->cls, irg, pred_bl, n_projs, in);
-      insert_after = sched_skip(sched_last(pred_bl), 0, skip_cf_predicator, ce);
-      sched_add_after(insert_after, perm);
-      exchange(dummy, perm);
-
-      free(in);
-      pmap_destroy(arg_map);
-
-      /* register in perm map */
-      pmap_insert(perm_map, pred_bl, perm);
-    }
-  }
-}
-
-static void insert_all_perms(be_chordal_env_t *chordal_env) {
-       DBG((dbg, LEVEL_1, "Placing perms...\n"));
-  irg_block_walk_graph(chordal_env->session_env->irg, insert_all_perms_walker, NULL, chordal_env);
-}
-
 static void    set_regs_or_place_dupls_walker(ir_node *bl, void *data) {
-  be_chordal_env_t *chordal_env = data;
-  ir_node *phi;
+       be_chordal_env_t *chordal_env = data;
+       ir_node *phi;
 
-       DBG((dbg, LEVEL_1, "Setting regs and placing dupls...\n"));
-  for(phi = get_irn_link(bl); phi; phi = get_irn_link(phi))
-    adjust_phi_arguments(chordal_env, phi);
+       for(phi = get_irn_link(bl); phi; phi = get_irn_link(phi))
+               adjust_phi_arguments(chordal_env, phi);
 }
 
 static void    set_regs_or_place_dupls(be_chordal_env_t *chordal_env)
 {
-  irg_block_walk_graph(chordal_env->session_env->irg,
-      set_regs_or_place_dupls_walker, NULL, chordal_env);
+       DBG((dbg, LEVEL_1, "Setting regs and placing dupls...\n"));
+       irg_block_walk_graph(chordal_env->session_env->irg,
+               set_regs_or_place_dupls_walker, NULL, chordal_env);
 }
 
 
 void be_ssa_destruction(be_chordal_env_t *chordal_env) {
        pmap *perm_map = pmap_create();
-  ir_graph *irg = chordal_env->session_env->irg;
+       ir_graph *irg = chordal_env->session_env->irg;
 
        dbg = firm_dbg_register("ir.be.ssadestr");
        firm_dbg_set_mask(dbg, DEBUG_LVL);
@@ -273,7 +275,7 @@ void be_ssa_destruction(be_chordal_env_t *chordal_env) {
        /* create a map for fast lookup of perms: block --> perm */
        chordal_env->data = perm_map;
 
-  build_phi_rings(chordal_env);
+       build_phi_rings(chordal_env);
        insert_all_perms(chordal_env);
        dump_ir_block_graph(irg, "-ssa_destr_perms_placed");
 
@@ -285,30 +287,30 @@ void be_ssa_destruction(be_chordal_env_t *chordal_env) {
 
 static void ssa_destruction_check_walker(ir_node *bl, void *data)
 {
-  be_chordal_env_t *chordal_env = data;
-  ir_node *phi;
+       be_chordal_env_t *chordal_env = data;
+       ir_node *phi;
        int i, max;
 
-  for(phi = get_irn_link(bl); phi; phi = get_irn_link(phi)) {
-    const arch_register_t *phi_reg, *arg_reg;
-
-    phi_reg = get_reg(phi);
-    /* iterate over all args of phi */
-    for(i=0, max=get_irn_arity(phi); i<max; ++i) {
-      ir_node *arg = get_irn_n(phi, i);
-      arg_reg = get_reg(arg);
-      if(phi_reg != arg_reg) {
-        ir_printf("Registers of %+F and %+F differ: %s %s\n",
-            phi, arg, phi_reg->name, arg_reg->name);
-        assert(0 && "Registers of phi and arg differ\n");
-      }
-      if(!is_pinned(arg))
-        ir_printf("Warning: Arg %+F not pinned\n", arg);
-    }
-  }
+       for(phi = get_irn_link(bl); phi; phi = get_irn_link(phi)) {
+               const arch_register_t *phi_reg, *arg_reg;
+
+               phi_reg = get_reg(phi);
+               /* iterate over all args of phi */
+               for(i=0, max=get_irn_arity(phi); i<max; ++i) {
+                       ir_node *arg = get_irn_n(phi, i);
+                       arg_reg = get_reg(arg);
+                       if(phi_reg != arg_reg) {
+                               DBG((dbg, 0, "Error: Registers of %+F and %+F differ: %s %s\n", phi, arg, phi_reg->name, arg_reg->name));
+                               assert(0);
+                       }
+                       if(!is_pinned(arg)) {
+                               DBG((dbg, 0, "Warning: Phi argument %+F is not pinned.\n", arg));
+                               assert(0);
+                       }
+               }
+       }
 }
 
 void be_ssa_destruction_check(be_chordal_env_t *chordal_env) {
-  irg_block_walk_graph(chordal_env->session_env->irg,
-      ssa_destruction_check_walker, NULL, chordal_env);
+       irg_block_walk_graph(chordal_env->session_env->irg, ssa_destruction_check_walker, NULL, chordal_env);
 }