Modified everything
authorSebastian Hack <hack@ipd.info.uni-karlsruhe.de>
Fri, 29 Jul 2005 14:34:16 +0000 (14:34 +0000)
committerSebastian Hack <hack@ipd.info.uni-karlsruhe.de>
Fri, 29 Jul 2005 14:34:16 +0000 (14:34 +0000)
18 files changed:
ir/be/bechordal.c
ir/be/bechordal.h
ir/be/bechordal_draw.c
ir/be/bechordal_t.h
ir/be/becopyheur.c
ir/be/becopyilp.c
ir/be/becopyopt.c
ir/be/becopyopt.h
ir/be/becopyoptmain.c
ir/be/becopystat.c
ir/be/beirgmod.c
ir/be/bemain.c
ir/be/benode.c
ir/be/bera.c
ir/be/besched.c
ir/be/besched_t.h
ir/be/bessadestr.c
ir/be/bessadestr.h

index f7c7d4c..78b001a 100644 (file)
@@ -261,7 +261,7 @@ static INLINE border_t *border_add(be_chordal_env_t *env, struct list_head *head
 
 static INLINE int has_reg_class(const be_chordal_env_t *env, const ir_node *irn)
 {
-  return arch_irn_has_reg_class(env->arch_env, irn, arch_pos_make_out(0), env->cls);
+  return arch_irn_has_reg_class(env->session_env->main_env->arch_env, irn, arch_pos_make_out(0), env->cls);
 }
 
 /**
@@ -290,7 +290,6 @@ static void pressure(ir_node *block, void *env_ptr)
        struct list_head *head;
        pset *live_in = put_live_in(block, pset_new_ptr_default());
        pset *live_end = put_live_end(block, pset_new_ptr_default());
-       const arch_register_class_t *cls = env->cls;
 
        DBG((dbg, LEVEL_1, "Computing pressure in block %+F\n", block));
        bitset_clear_all(live);
@@ -383,15 +382,10 @@ static void pressure(ir_node *block, void *env_ptr)
 static void assign(ir_node *block, void *env_ptr)
 {
        be_chordal_env_t *env = env_ptr;
-       struct obstack *obst = &env->obst;
        bitset_t *live = env->live;
        bitset_t *colors = env->colors;
        bitset_t *in_colors = env->in_colors;
-       const arch_register_class_t *cls = env->cls;
-
-       /* Mark the obstack level and allocate the temporary tmp_colors */
-       void *obstack_level = obstack_base(obst);
-       /*bitset_t *tmp_colors = bitset_obstack_alloc(obst, env->colors_n);*/
+  const arch_env_t *arch_env = env->session_env->main_env->arch_env;
 
        const ir_node *irn;
        border_t *b;
@@ -419,7 +413,7 @@ static void assign(ir_node *block, void *env_ptr)
         */
        for(irn = pset_first(live_in); irn; irn = pset_next(live_in)) {
                if(has_reg_class(env, irn)) {
-      const arch_register_t *reg = arch_get_irn_register(env->arch_env, irn, 0);
+      const arch_register_t *reg = arch_get_irn_register(arch_env, irn, 0);
       int col;
 
       assert(reg && "Node must have been assigned a register");
@@ -456,21 +450,21 @@ static void assign(ir_node *block, void *env_ptr)
       col = bitset_next_clear(colors, 0);
       reg = arch_register_for_index(env->cls, col);
 
-      assert(arch_get_irn_register(env->arch_env, irn, 0) == NULL
+      assert(arch_get_irn_register(arch_env, irn, 0) == NULL
           && "This node must not have been assigned a register yet");
                        assert(!bitset_is_set(live, nr) && "Value's definition must not have been encountered");
 
                        bitset_set(colors, col);
                        bitset_set(live, nr);
 
-                       arch_set_irn_register(env->arch_env, irn, 0, reg);
+                       arch_set_irn_register(arch_env, irn, 0, reg);
                        DBG((dbg, LEVEL_1, "\tassigning register %s(%d) to %+F\n",
             arch_register_get_name(reg), col, irn));
                }
 
                /* Clear the color upon a use. */
                else if(!b->is_def) {
-      const arch_register_t *reg = arch_get_irn_register(env->arch_env, irn, 0);
+      const arch_register_t *reg = arch_get_irn_register(arch_env, irn, 0);
                        int col;
 
       assert(reg && "Register must have been assigned");
@@ -483,9 +477,6 @@ static void assign(ir_node *block, void *env_ptr)
                }
        }
 
-       /* Free the auxillary data on the obstack. */
-       //obstack_free(obst, obstack_level);
-
   del_pset(live_in);
 }
 
@@ -495,10 +486,11 @@ void be_ra_chordal_init(void)
        firm_dbg_set_mask(dbg, DBG_LEVEL);
 }
 
-be_chordal_env_t *be_ra_chordal(ir_graph *irg,
-    const arch_env_t *arch_env,
+be_chordal_env_t *be_ra_chordal(
+    const be_main_session_env_t *session,
     const arch_register_class_t *cls)
 {
+  ir_graph *irg = session->irg;
        int node_count = get_graph_node_count(irg);
        int colors_n = arch_register_class_n_regs(cls);
        be_chordal_env_t *env = malloc(sizeof(*env));
@@ -513,13 +505,12 @@ be_chordal_env_t *be_ra_chordal(ir_graph *irg,
        env->nodes = new_set(if_node_cmp, node_count);
 #endif
 
+  env->session_env = session;
        env->live = bitset_obstack_alloc(&env->obst, node_count);
        env->colors = bitset_obstack_alloc(&env->obst, colors_n);
        env->in_colors = bitset_obstack_alloc(&env->obst, colors_n);
        env->colors_n = colors_n;
        env->cls = cls;
-       env->arch_env = arch_env;
-       env->irg = irg;
        env->border_heads = pmap_create();
 
        /* First, determine the pressure */
@@ -551,14 +542,12 @@ be_chordal_env_t *be_ra_chordal(ir_graph *irg,
 }
 
 void be_ra_chordal_check(be_chordal_env_t *chordal_env) {
-       const arch_env_t *arch_env;
+       const arch_env_t *arch_env = chordal_env->session_env->main_env->arch_env;
        struct obstack ob;
        pmap_entry *pme;
        ir_node **nodes, *n1, *n2;
        int i, o;
 
-       arch_env = chordal_env->arch_env;
-
        /* Collect all irns */
        obstack_init(&ob);
        pmap_foreach(chordal_env->border_heads, pme) {
index 853d58d..e417035 100644 (file)
 #include "irnode.h"
 
 #include "bearch.h"
+#include "bearch.h"
 
-typedef struct _be_chordal_env_t be_chordal_env_t;
-
-/**
- * Allocate registers for an ir graph.
- * @param irg The graph.
- * @return Some internal data to be freed with be_ra_chordal_done().
- */
-be_chordal_env_t *be_ra_chordal(ir_graph *irg,
-    const arch_env_t *arch_env,
-    const arch_register_class_t *cls);
-
-/**
- * Check current register allocation for correctness.
- * Interfering nodes have different colors
- * Register constraints
- * O(n^2)
- */
-void be_ra_chordal_check(be_chordal_env_t *chordal_env);
-
-/**
- * Free data from the chordal register allocation.
- * @param irg The graph.
- */
-void be_ra_chordal_done(be_chordal_env_t *info);
-
-/**
- * Init some things for the chordal register allocator.
- * This must be called before Firm is inited.
- */
-void be_ra_chordal_init(void);
 
 #endif
index 1b31a56..4163273 100644 (file)
@@ -328,7 +328,6 @@ static void draw_block(ir_node *bl, void *data)
     if(b->is_def) {
       const arch_register_t *reg = arch_get_irn_register(env->arch_env, b->irn, 0);
       int col = arch_register_get_index(reg);
-      int live_in = is_live_in(bl, b->irn);
       int live_out = is_live_out(bl, b->irn);
       int x = (col + 1) * opts->h_inter_gap;
       int ystart = (b->step) * opts->v_inter_gap;
@@ -385,7 +384,7 @@ static void draw(draw_chordal_env_t *env, const rect_t *start_box)
   bbox.h = start_box->h + 2 * env->opts->y_margin;
 
   p->vtab->begin(p, &bbox);
-  irg_block_walk_graph(env->chordal_env->irg, draw_block, NULL, env);
+  irg_block_walk_graph(env->chordal_env->session_env->irg, draw_block, NULL, env);
   p->vtab->finish(p);
 }
 
@@ -396,7 +395,7 @@ void draw_interval_tree(const draw_chordal_opts_t *opts,
 {
   draw_chordal_env_t env;
   struct block_dims *start_dims;
-  ir_node *start_block = get_irg_start_block(chordal_env->irg);
+  ir_node *start_block = get_irg_start_block(chordal_env->session_env->irg);
 
   env.arch_env = arch_env;
   env.opts = opts;
@@ -408,7 +407,7 @@ void draw_interval_tree(const draw_chordal_opts_t *opts,
   env.chordal_env = chordal_env;
   obstack_init(&env.obst);
 
-  irg_block_walk_graph(chordal_env->irg, block_dims_walker, NULL, &env);
+  irg_block_walk_graph(chordal_env->session_env->irg, block_dims_walker, NULL, &env);
   layout(&env, start_block, opts->x_margin);
   set_y(&env, start_block, opts->y_margin);
   start_dims = pmap_get(env.block_dims, start_block);
index 3ec3527..684e60f 100644 (file)
@@ -19,7 +19,9 @@
 
 #include "irnode.h"
 #include "irgraph.h"
-#include "bechordal.h"
+
+#include "be_t.h"
+#include "bearch.h"
 
 /** Defines an invalid register index. */
 #define NO_COLOR (-1)
@@ -50,8 +52,8 @@ typedef struct _border_t {
  */
 struct _be_chordal_env_t {
        struct obstack obst;    /**< An obstack for temporary storage. */
+  const be_main_session_env_t *session_env; /**< The current session. */
   pmap *border_heads;   /**< Maps blocks to border heads. */
-  ir_graph *irg;        /**< The graph the reg alloc is running on. */
 
 #ifdef BUILD_GRAPH
        set *nodes;                                             /**< The interference graph nodes. */
@@ -62,12 +64,13 @@ struct _be_chordal_env_t {
        bitset_t *colors;                       /**< The color mask. */
        bitset_t *in_colors;    /**< Colors used by live in values. */
        int colors_n;                                   /**< The number of colors. */
-  const arch_env_t *arch_env;         /**< The arch interface environment. */
   const arch_register_class_t *cls;   /**< The current register class. */
   void *data;           /**< Some pointer, to which different
                           phases can attach data to. */
 };
 
+typedef struct _be_chordal_env_t be_chordal_env_t;
+
 static INLINE struct list_head *
 _get_block_border_head(const be_chordal_env_t *inf, ir_node *bl)
 {
@@ -99,4 +102,33 @@ int ifg_has_edge(const be_chordal_env_t *env, const if_node_t *n1, const if_node
 
 extern void be_ra_chordal_spill(be_chordal_env_t *env);
 
+/**
+ * Allocate registers for an ir graph.
+ * @param irg The graph.
+ * @return Some internal data to be freed with be_ra_chordal_done().
+ */
+be_chordal_env_t *be_ra_chordal(
+    const be_main_session_env_t *env,
+    const arch_register_class_t *cls);
+
+/**
+ * Check current register allocation for correctness.
+ * Interfering nodes have different colors
+ * Register constraints
+ * O(n^2)
+ */
+void be_ra_chordal_check(be_chordal_env_t *chordal_env);
+
+/**
+ * Free data from the chordal register allocation.
+ * @param irg The graph.
+ */
+void be_ra_chordal_done(be_chordal_env_t *info);
+
+/**
+ * Init some things for the chordal register allocator.
+ * This must be called before Firm is inited.
+ */
+void be_ra_chordal_init(void);
+
 #endif /* _BECHORDAL_T_H */
index 97969cc..1cde93a 100644 (file)
@@ -208,7 +208,7 @@ static ir_node *qnode_color_irn(const qnode_t *qn, ir_node *irn, int col, const
        ir_node **confl, *cn;
        int i, irn_col;
        const be_chordal_env_t *chordal_env = qn->ou->co->chordal_env;
-       const arch_env_t *arch_env = chordal_env->arch_env;
+       const arch_env_t *arch_env = get_arch_env(qn->ou->co);
        const arch_register_class_t *cls = chordal_env->cls;
 
        DBG((dbg, LEVEL_3, "\t      %+F \tcaused col(%+F) \t%2d --> %2d\n", trigger, irn, qnode_get_new_color(qn, irn), col));
@@ -501,7 +501,7 @@ static void ou_optimize(unit_t *ou) {
 
        /* init queue */
        INIT_LIST_HEAD(&ou->queue);
-       arch_get_allocatable_regs(ou->co->chordal_env->arch_env, ou->nodes[0], arch_pos_make_out(0), ou->co->chordal_env->cls, pos_regs);
+       arch_get_allocatable_regs(get_arch_env(ou->co), ou->nodes[0], arch_pos_make_out(0), ou->co->chordal_env->cls, pos_regs);
        bitset_foreach(pos_regs, i)
                ou_insert_qnode(ou, new_qnode(ou, i));
 
index 2e34e2f..4ff9f25 100644 (file)
@@ -55,7 +55,7 @@ typedef struct _problem_instance_t {
 
 #define is_removed(irn) pset_find_ptr(pi->removed, irn)
 
-#define is_color_possible(irn,color) arch_reg_is_allocatable(pi->co->chordal_env->arch_env, irn, arch_pos_make_out(0), arch_register_for_index(pi->co->chordal_env->cls, color))
+#define is_color_possible(irn,color) arch_reg_is_allocatable(get_arch_env(pi->co), irn, arch_pos_make_out(0), arch_register_for_index(pi->co->chordal_env->cls, color))
 
 /*
  * Some stuff for variable name handling.
@@ -112,8 +112,8 @@ static void pi_find_simplicials(problem_instance_t *pi) {
        while (redo) {
                redo = 0;
                for (ifn = set_first(if_nodes); ifn; ifn = set_next(if_nodes)) {
-                       ir_node *irn = get_irn_for_graph_nr(pi->co->chordal_env->irg, ifn->nnr);
-                       if (!is_removed(irn) && !is_optimizable(pi->co->chordal_env->arch_env, irn) &&
+                       ir_node *irn = get_irn_for_graph_nr(get_irg(pi->co), ifn->nnr);
+                       if (!is_removed(irn) && !is_optimizable(get_arch_env(pi->co), irn) &&
           !is_optimizable_arg(pi->co, irn) && pi_is_simplicial(pi, ifn)) {
                                simpl_t *s = xmalloc(sizeof(*s));
                                s->ifn = ifn;
@@ -152,7 +152,7 @@ static void pi_add_constr_A(problem_instance_t *pi) {
 
                                // iterate over all possible colors in order
                                bitset_clear_all(pos_regs);
-                               arch_get_allocatable_regs(pi->co->chordal_env->arch_env, curr->irn, arch_pos_make_out(0), pi->co->chordal_env->cls, pos_regs);
+                               arch_get_allocatable_regs(get_arch_env(pi->co), curr->irn, arch_pos_make_out(0), pi->co->chordal_env->cls, pos_regs);
                                bitset_foreach(pos_regs, col) {
                                        int var_idx;
                                        mangle_var(pi->buf, 'x', nnr, col);
@@ -258,14 +258,14 @@ static void pi_add_constr_E(problem_instance_t *pi) {
                root = curr->nodes[0];
                rootnr = get_irn_graph_nr(root);
                bitset_clear_all(root_regs);
-               arch_get_allocatable_regs(pi->co->chordal_env->arch_env, root, arch_pos_make_out(0), pi->co->chordal_env->cls, root_regs);
+               arch_get_allocatable_regs(get_arch_env(pi->co), root, arch_pos_make_out(0), pi->co->chordal_env->cls, root_regs);
 
                /* for all arguments of root */
                for (i = 1; i < curr->node_count; ++i) {
                        arg = curr->nodes[i];
                        argnr = get_irn_graph_nr(arg);
                        bitset_clear_all(arg_regs);
-                       arch_get_allocatable_regs(pi->co->chordal_env->arch_env, arg, arch_pos_make_out(0), pi->co->chordal_env->cls, arg_regs);
+                       arch_get_allocatable_regs(get_arch_env(pi->co), arg, arch_pos_make_out(0), pi->co->chordal_env->cls, arg_regs);
 
                        /* Introduce new variable and set factor in objective function */
                        mangle_var(buf, 'y', rootnr, argnr);
@@ -484,7 +484,7 @@ static void M_constr_walker(ir_node *block, void *env) {
  * Only one of the phis can get the arg.
  */
 static void pi_add_constr_M(problem_instance_t *pi) {
-       dom_tree_walk_irg(pi->co->chordal_env->irg, M_constr_walker, NULL, pi);
+       dom_tree_walk_irg(get_irg(pi->co), M_constr_walker, NULL, pi);
 }
 
 /**
@@ -549,8 +549,8 @@ static void pi_set_start_sol(problem_instance_t *pi) {
                lpp_get_var_name(pi->curr_lp, i, var_name, sizeof(var_name));
                /* split into components */
                if (split_var(var_name, &nnr, &col) == 2) {
-                       assert(get_irn_col(pi->co, get_irn_for_graph_nr(pi->co->chordal_env->irg, nnr)) != -1);
-                       val = (get_irn_col(pi->co, get_irn_for_graph_nr(pi->co->chordal_env->irg, nnr)) == col) ? 1 : 0;
+                       assert(get_irn_col(pi->co, get_irn_for_graph_nr(get_irg(pi->co), nnr)) != -1);
+                       val = (get_irn_col(pi->co, get_irn_for_graph_nr(get_irg(pi->co), nnr)) == col) ? 1 : 0;
                        lpp_set_start_value(pi->curr_lp, i, val);
                } else {
                        fprintf(stderr, "Variable name is: %s\n", var_name);
@@ -584,10 +584,10 @@ static void pi_set_simplicials(problem_instance_t *pi) {
 
                /* get free color by inspecting all neighbors */
                ifn = simpl->ifn;
-               irn = get_irn_for_graph_nr(pi->co->chordal_env->irg, ifn->nnr);
+               irn = get_irn_for_graph_nr(get_irg(pi->co), ifn->nnr);
                bitset_clear_all(used_cols);
                foreach_neighb(ifn, other) {
-                       other_irn = get_irn_for_graph_nr(pi->co->chordal_env->irg, other->nnr);
+                       other_irn = get_irn_for_graph_nr(get_irg(pi->co), other->nnr);
                        if (!is_removed(other_irn)) /* only inspect nodes which are in graph right now */
                                bitset_set(used_cols, get_irn_col(pi->co, other_irn));
                }
@@ -628,9 +628,9 @@ static void pi_apply_solution(problem_instance_t *pi) {
                if (sol[i] > 1-EPSILON) { /* split varibale name into components */
                        lpp_get_var_name(pi->curr_lp, 1+i, var_name, sizeof(var_name));
                        if (split_var(var_name, &nnr, &col) == 2) {
-                               DBG((dbg, LEVEL_2, "Irn %n  Idx %d  Var %s  Val %f\n", get_irn_for_graph_nr(pi->co->chordal_env->irg, nnr), i, var_name, sol[i]));
+                               DBG((dbg, LEVEL_2, "Irn %n  Idx %d  Var %s  Val %f\n", get_irn_for_graph_nr(get_irg(pi->co), nnr), i, var_name, sol[i]));
                                DBG((dbg, LEVEL_2, "x%d = %d\n", nnr, col));
-                               set_irn_col(pi->co, get_irn_for_graph_nr(pi->co->chordal_env->irg, nnr), col);
+                               set_irn_col(pi->co, get_irn_for_graph_nr(get_irg(pi->co), nnr), col);
                        } else
                                assert(0 && "This should be a x-var");
                }
index a85fd97..c4c2fe5 100644 (file)
@@ -24,7 +24,9 @@
 
 static firm_dbg_module_t *dbg = NULL;
 
-#define is_curr_reg_class(irn) (arch_get_irn_reg_class(co->chordal_env->arch_env, irn, arch_pos_make_out(0)) == co->chordal_env->cls)
+#define is_curr_reg_class(irn) \
+  (arch_get_irn_reg_class(get_arch_env(co), \
+                          irn, arch_pos_make_out(0)) == co->chordal_env->cls)
 
 #define MIN(a,b) ((a<b)?(a):(b))
 #define MAX(a,b) ((a<b)?(b):(a))
@@ -146,7 +148,7 @@ static void co_append_unit(copy_opt_t *co, ir_node *root) {
                }
                unit->nodes = xrealloc(unit->nodes, unit->node_count * sizeof(*unit->nodes));
                unit->costs = xrealloc(unit->costs, unit->node_count * sizeof(*unit->costs));
-       } else if (is_Copy(co->chordal_env->arch_env, root)) {
+       } else if (is_Copy(get_arch_env(co), root)) {
                assert(!nodes_interfere(co->chordal_env, root, get_Copy_src(root)));
                unit->nodes[1] = get_Copy_src(root);
                unit->costs[1] = co->get_costs(root, unit->nodes[1], -1);
@@ -180,14 +182,14 @@ static void co_collect_in_block(ir_node *block, void *env) {
        border_t *curr;
 
        list_for_each_entry_reverse(border_t, curr, head, list)
-               if (curr->is_def && curr->is_real && is_optimizable(co->chordal_env->arch_env, curr->irn))
+               if (curr->is_def && curr->is_real && is_optimizable(get_arch_env(co), curr->irn))
                        co_append_unit(co, curr->irn);
 }
 
 static void co_collect_units(copy_opt_t *co) {
        DBG((dbg, LEVEL_1, "\tCollecting optimization units\n"));
        co->roots = pset_new_ptr(64);
-       dom_tree_walk_irg(co->chordal_env->irg, co_collect_in_block, NULL, co);
+       dom_tree_walk_irg(get_irg(co), co_collect_in_block, NULL, co);
        del_pset(co->roots);
 }
 
@@ -204,7 +206,7 @@ copy_opt_t *new_copy_opt(be_chordal_env_t *chordal_env, int (*get_costs)(ir_node
        co->get_costs = get_costs;
 
        s1 = get_irp_prog_name();
-       s2 = get_entity_name(get_irg_entity(co->chordal_env->irg));
+       s2 = get_entity_name(get_irg_entity(get_irg(co)));
        s3 = chordal_env->cls->name;
        len = strlen(s1) + strlen(s2) + strlen(s3) + 5;
        co->name = xmalloc(len);
@@ -232,7 +234,7 @@ int is_optimizable_arg(const copy_opt_t *co, ir_node *irn) {
        int i, max;
        for(i=0, max=get_irn_n_outs(irn); i<max; ++i) {
                ir_node *n = get_irn_out(irn, i);
-               if ((is_Phi(n) || is_Perm(co->chordal_env->arch_env, n)) && (irn == n || !nodes_interfere(co->chordal_env, irn, n)))
+               if ((is_Phi(n) || is_Perm(get_arch_env(co), n)) && (irn == n || !nodes_interfere(co->chordal_env, irn, n)))
                        return 1;
        }
        return 0;
index 525d27c..3b56cf4 100644 (file)
@@ -70,11 +70,13 @@ typedef struct _unit_t {
 } unit_t;
 
 /* Helpers */
+#define get_arch_env(co) ((co)->chordal_env->session_env->main_env->arch_env)
+#define get_irg(co)      ((co)->chordal_env->session_env->irg)
+#define get_irn_col(co, irn) \
+       arch_register_get_index(arch_get_irn_register(get_arch_env(co), irn, 0))
 #define set_irn_col(co, irn, col) \
-       arch_set_irn_register(co->chordal_env->arch_env, irn, 0, arch_register_for_index(co->chordal_env->cls, col))
+       arch_set_irn_register(get_arch_env(co), irn, 0, arch_register_for_index(co->chordal_env->cls, col))
 
-#define get_irn_col(co, irn) \
-       arch_register_get_index(arch_get_irn_register(co->chordal_env->arch_env, irn, 0))
 
 #define list_entry_units(lh) list_entry(lh, unit_t, units)
 
index 502cd91..0e31367 100644 (file)
@@ -34,7 +34,7 @@ void be_copy_opt(be_chordal_env_t *chordal_env) {
        int lb, copy_costs;
 
        /* BETTER: You can remove this if you replace all `grep get_irn_out *.c`*/
-       compute_outs(chordal_env->irg);
+       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));
index a4c22cd..24a1c78 100644 (file)
@@ -96,7 +96,8 @@ static void stat_phi_node(be_chordal_env_t *chordal_env, ir_node *phi) {
                if (phi != arg) {
                        curr_vals[I_COPIES_MAX]++; /* if arg!=phi this is a possible copy */
                        if (nodes_interfere(chordal_env, phi, arg)) {
-                               DBG((dbg, LEVEL_1, "%e -- In Block %N: %n %N %n %N\n", get_irg_entity(chordal_env->irg), get_nodes_block(phi), phi, phi, arg, arg));
+                               DBG((dbg, LEVEL_1, "%e -- In Block %N: %n %N %n %N\n",
+              get_irg_entity(chordal_env->session_env->irg), get_nodes_block(phi), phi, phi, arg, arg));
                                curr_vals[I_COPIES_IF]++;
                        }
                }
@@ -183,7 +184,9 @@ static void stat_phi_class(be_chordal_env_t *chordal_env, pset *pc) {
        xfree(members);
 }
 
-#define is_curr_reg_class(irn) (arch_get_irn_reg_class(chordal_env->arch_env, irn, arch_pos_make_out(0)) == chordal_env->cls)
+#define is_curr_reg_class(irn) \
+  (arch_get_irn_reg_class(chordal_env->session_env->main_env->arch_env, irn, \
+                          arch_pos_make_out(0)) == chordal_env->cls)
 
 void copystat_collect_cls(be_chordal_env_t *chordal_env) {
        ir_node *n;
index cd54bde..07ff6c3 100644 (file)
@@ -14,6 +14,7 @@
 #include "irflag_t.h"
 #include "ircons_t.h"
 #include "irnode_t.h"
+#include "ircons_t.h"
 #include "irmode_t.h"
 #include "irdom_t.h"
 #include "iredges_t.h"
index 3690156..7e8163c 100644 (file)
@@ -36,6 +36,7 @@
 #include "bearch_firm.h"
 #include "benode_t.h"
 #include "beirgmod.h"
+#include "bespillilp.h"
 
 #include "beasm_dump_globals.h"
 #include "beasm_asm_gnu.h"
@@ -131,7 +132,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, "be irg: %F\n", irg));
 
                /* Init the session. */
                be_init_session_env(&session, &env, irg);
@@ -146,31 +147,30 @@ static void be_main_loop(void)
                /* Verify the schedule */
                sched_verify_irg(irg);
 
-               /* Build liveness information */
-               be_liveness(irg);
-
-               /* Liveness analysis */
-               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, "\treg class: %s\n", cls->name));
+
+      be_numbering(irg);
+      be_liveness(irg);
 
-                       be_numbering(irg);
-                       be_liveness(irg);
+      // be_spill_ilp(&session, cls);
 
-                       chordal_env = be_ra_chordal(irg, env.arch_env, cls);
+                       chordal_env = be_ra_chordal(&session, cls);
 
 #ifdef DUMP_ALLOCATED
                        dump_allocated_irg(env.arch_env, irg, "");
@@ -179,13 +179,14 @@ static void be_main_loop(void)
 
                        be_copy_opt(chordal_env);
 
-                       be_ssa_destruction(&session, chordal_env);
-                       be_ssa_destruction_check(&session, chordal_env);
-                       be_ra_chordal_check(chordal_env);
+                       be_ssa_destruction(chordal_env);
+                       be_ssa_destruction_check(chordal_env);
 
-                       be_ra_chordal_done(chordal_env);
-                       be_numbering_done(irg);
+                       be_ra_chordal_check(chordal_env);
+      be_ra_chordal_done(chordal_env);
+      be_numbering_done(irg);
                }
+               dump_ir_block_graph(session.irg, "-post");
 
                copystat_dump_pretty(irg);
        }
index b76c799..748a226 100644 (file)
@@ -244,6 +244,7 @@ arch_irn_class_t be_node_classify(const arch_irn_ops_t *_self, const ir_node *ir
   idx = redir_proj(&irn, 0);
   bo = pmap_get(factory->irn_op_map, get_irn_op(irn));
 
+  /* TODO Implement */
   return 0;
 }
 
@@ -406,6 +407,7 @@ ir_node *insert_Perm_after(const be_main_session_env_t *env,
   return perm;
 }
 
+#if 0
 typedef struct _phi_perm_info_t {
   const be_main_session_env_t *env;
   const arch_register_class_t *cls;
@@ -488,3 +490,4 @@ void be_insert_phi_perms(const be_main_session_env_t *env,
   irg_block_walk_graph(env->irg, insert_phi_perms, NULL, &pi);
   pmap_destroy(pi.perm_map);
 }
+#endif
index f3ae848..90ea5c9 100644 (file)
@@ -57,7 +57,6 @@ int values_interfere(const ir_node *a, const ir_node *b)
   /* If there is no dominance relation, they do not interfere. */
   if(a2b + b2a > 0) {
     const ir_edge_t *edge;
-    ir_node *ba = get_nodes_block(a);
     ir_node *bb = get_nodes_block(b);
 
     /*
index d23330b..fdb043b 100644 (file)
@@ -12,7 +12,7 @@
 #include "debug.h"
 
 #include "besched_t.h"
-#include "besched.h"
+#include "beutil.h"
 #include "belistsched.h"
 
 FIRM_IMPL1(sched_get_time_step, int, const ir_node *)
@@ -185,3 +185,14 @@ int sched_verify_irg(ir_graph *irg)
 
   return res;
 }
+
+extern ir_node *sched_skip(ir_node *from, int forward,
+    sched_predicator_t *predicator, void *data)
+{
+  const ir_node *bl = get_block(from);
+  ir_node *curr;
+
+  for(curr = from; curr != bl && predicator(curr, data);
+      curr = forward ? sched_next(curr) : sched_prev(curr));
+  return curr;
+}
index 9e6a27b..f5a2e18 100644 (file)
@@ -251,6 +251,25 @@ extern int sched_verify(const ir_node *block);
  */
 extern int sched_verify_irg(ir_graph *irg);
 
+/**
+ * A predicate for a node.
+ * @param irn The node.
+ * @param data The custom data.
+ * @return 1 or 0, depending on your criteria.
+ */
+typedef int (sched_predicator_t)(const ir_node *irn, void *data);
+
+/**
+ * Skip nodes in a schedule.
+ * @param from The node to start from.
+ * @param forward The direction (1 for forward, 0 for backward).
+ * @param predicator The one who decides what is skipped.
+ * @param data Food for the predicator.
+ * @return The first node rejected by the predicator or the block
+ * itself if none was rejected.
+ */
+extern ir_node *sched_skip(ir_node *from, int forward,
+    sched_predicator_t *predicator, void *data);
 
 #define sched_get_time_step(irn)           _sched_get_time_step(irn)
 #define sched_has_succ(irn)                              _sched_has_succ(irn)
index 8848acf..4e42ac1 100644 (file)
 #include "debug.h"
 #include "set.h"
 #include "pmap.h"
-#include "irnode.h"
+#include "irnode_t.h"
+#include "ircons_t.h"
 #include "iredges_t.h"
+#include "irgmod.h"
 #include "irdump.h"
 #include "irprintf.h"
 
@@ -29,60 +31,49 @@ static firm_dbg_module_t *dbg = NULL;
 #define DEBUG_LVL SET_LEVEL_2
 
 
-#define get_reg(irn) arch_get_irn_register(chordal_env->arch_env, irn, 0)
-#define set_reg(irn, reg) arch_set_irn_register(chordal_env->arch_env, irn, 0, reg)
-
-/**
- * Maps blocks to perm nodes inserted during phi destruction.
- */
-typedef struct _block2perm_t {
-  ir_node *block, *perm;
-} block2perm_t;
-
-static int set_cmp_b2p(const void *x, const void *y, size_t size) {
-  const block2perm_t *b1 = x;
-  const block2perm_t *b2 = y;
-  return b1->block != b2->block;
-}
+#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)
 
-static ir_node *get_or_insert_perm(be_main_session_env_t *session, be_chordal_env_t *chordal_env, ir_node *block) {
-       block2perm_t find, *found;
-       ir_node *p;
-       set *b2p = chordal_env->data;
-       const arch_env_t *arch_env = chordal_env->arch_env;
-
-
-       /* iff needed insert perm node */
-       DBG((dbg, LEVEL_1, "    Getting perm in %+F\n", block));
-
-       /* .if the perm is in the pset return it */
-       find.block = block;
-       find.perm = NULL;
-       found = set_insert(b2p, &find, sizeof(find), HASH_PTR(find.block));
-       if (found->perm) {
-               DBG((dbg, LEVEL_1, "      found it %+F in map\n", found->perm));
-               return found->perm;
-       }
+static void clear_link(ir_node *irn, void *data)
+{
+  set_irn_link(irn, NULL);
+}
 
-       /* .else look for a perm of right register class in the schedule */
-       p = sched_last(find.block);
-       while (!is_Block(p) && (is_Branch(p) || (is_Perm(p) && !is_curr_reg_class(p))))
-               p = sched_prev(p);
+/**
+ * Build a list of phis of a block.
+ */
+static void collect_phis(ir_node *irn, void *data)
+{
+  be_chordal_env_t *env = data;
+  if(is_Phi(irn) &&
+      arch_irn_has_reg_class(env->session_env->main_env->arch_env,
+        irn, arch_pos_make_out(0), env->cls)) {
+
+    ir_node *bl = get_nodes_block(irn);
+    set_irn_link(irn, get_irn_link(bl));
+    set_irn_link(bl, irn);
+  }
+}
 
-       /* if we haven't found a perm of the right register class create a new one */
-       if (! (is_Perm(p) && is_curr_reg_class(p))) {
-               DBG((dbg, LEVEL_1, "      insert it after %+F\n", p));
-               p = insert_Perm_after(session, chordal_env->cls, p);
-       }
+/**
+ * Build a ring of phis for each block in the link field.
+ * @param env The chordal env.
+ */
+static INLINE void build_phi_rings(be_chordal_env_t *env)
+{
+  irg_walk_graph(env->session_env->irg, clear_link, collect_phis, env);
+}
 
-       /* insert perm into pset and return it*/
-       found->perm = p;
-       return p;
+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;
+  return arch_irn_classify(ae, irn) == arch_irn_class_branch;
 }
 
 #define is_pinned(irn) (get_irn_link(irn))
@@ -94,17 +85,18 @@ static ir_node *get_or_insert_perm(be_main_session_env_t *session, be_chordal_en
  * by inserting perm nodes, if necessary.
  * @param phi The phi node to adjust operands for
  */
-static void adjust_phi_arguments(be_main_session_env_t *session, be_chordal_env_t *chordal_env, ir_node *phi) {
+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 = session->main_env->arch_env;
+       arch_env_t *arch_env = get_chordal_arch(chordal_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;
 
        assert(is_Phi(phi) && "Can only handle phi-destruction :)");
        DBG((dbg, LEVEL_1, "  for %+F\n", phi));
 
-       cls = arch_get_irn_reg_class(session->main_env->arch_env, phi, arch_pos_make_out(0));
+       cls = arch_get_irn_reg_class(get_chordal_arch(chordal_env), phi, arch_pos_make_out(0));
        phi_block = get_nodes_block(phi);
        phi_reg = get_reg(phi);
 
@@ -116,7 +108,7 @@ static void adjust_phi_arguments(be_main_session_env_t *session, be_chordal_env_
                arg_block = get_nodes_block(arg);
                arg_reg = get_reg(arg);
                perm = get_Proj_pred(arg);
-               assert(is_Perm(perm));
+               // assert(is_Perm(perm));
 
                DBG((dbg, LEVEL_1, "    arg %+F has perm %+F\n", arg, perm));
                /* if registers don't match ...*/
@@ -128,7 +120,9 @@ static void adjust_phi_arguments(be_main_session_env_t *session, be_chordal_env_
                        if (!is_pinned(arg)) {
                                DBG((dbg, LEVEL_1, "      arg is not pinned\n"));
                                ir_node *other_phi = phi;
-                               while ((other_phi = get_irn_link(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;
                                        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"));
@@ -186,112 +180,135 @@ static void adjust_phi_arguments(be_main_session_env_t *session, be_chordal_env_
        }
 }
 
+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_main_session_env_t *session, be_chordal_env_t *chordal_env) {
-       pmap_entry *pme;
-       int i, max;
-       ir_node *first_phi, *recent_phi;
-
+static void insert_all_perms(be_chordal_env_t *chordal_env) {
        DBG((dbg, LEVEL_1, "Placing perms...\n"));
-
-       /* place perms in cf-preds of phis */
-       pmap_foreach(chordal_env->border_heads, pme) {
-               border_t *curr;
-               struct list_head *head = pme->value;
-
-               first_phi = NULL;
-               /* iterate over the first ops in the block until a non-phi is reached */
-               list_for_each_entry(border_t, curr, head, list) {
-                       ir_node *phi = curr->irn;
-
-                       if (curr->is_def && curr->is_real && is_Phi(phi)) {
-                               set_irn_link(phi, NULL);
-                               /* chain of phis in a block */
-                               if (first_phi == NULL)
-                                       first_phi = phi;
-                               else
-                                       set_irn_link(recent_phi, phi);
-                               recent_phi = phi;
-
-                               /* insert perms */
-                               DBG((dbg, LEVEL_1, "  for %+F\n", phi));
-                               for(i=0, max=get_irn_arity(phi); i<max; ++i) {
-                                       ir_node *perm;
-
-                                       perm = get_or_insert_perm(session, chordal_env, get_Block_cfgpred_block(get_nodes_block(phi), i));
-                                       DBG((dbg, LEVEL_1, "    %+F in block %N\n", perm, get_Block_cfgpred_block(get_nodes_block(phi), i)));
-                                       set_irn_link(perm, NULL);
-                               }
-                       }
-               }
-               if (first_phi)
-                       set_irn_link(recent_phi, first_phi);
-       }
+  irg_block_walk_graph(chordal_env->session_env->irg, insert_all_perms_walker, NULL, chordal_env);
 }
 
-static void    set_regs_or_place_dupls(be_main_session_env_t *session, be_chordal_env_t *chordal_env) {
-       pmap_entry *pme;
+static void    set_regs_or_place_dupls_walker(ir_node *bl, void *data) {
+  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);
+}
 
-       /* iterate over all blocks and correct color of arguments*/
-       pmap_foreach(chordal_env->border_heads, pme) {
-               border_t *curr;
-               struct list_head *head = pme->value;
-
-               /* iterate over the first ops in the block until a non-phi is reached */
-               list_for_each_entry(border_t, curr, head, list)
-                       if (curr->is_def && curr->is_real && is_Phi(curr->irn))
-                               adjust_phi_arguments(session, chordal_env, curr->irn);
-       }
+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);
 }
 
-void be_ssa_destruction(be_main_session_env_t *session, be_chordal_env_t *chordal_env) {
-       set *b2p;
+
+void be_ssa_destruction(be_chordal_env_t *chordal_env) {
+       pmap *perm_map = pmap_create();
+  ir_graph *irg = chordal_env->session_env->irg;
 
        dbg = firm_dbg_register("ir.be.ssadestr");
        firm_dbg_set_mask(dbg, DEBUG_LVL);
 
        /* create a map for fast lookup of perms: block --> perm */
-       b2p = new_set(set_cmp_b2p, 32);
-       chordal_env->data = b2p;
+       chordal_env->data = perm_map;
 
-       insert_all_perms(session, chordal_env);
-       dump_ir_block_graph(session->irg, "-ssa_destr_perms_placed");
+  build_phi_rings(chordal_env);
+       insert_all_perms(chordal_env);
+       dump_ir_block_graph(irg, "-ssa_destr_perms_placed");
 
-       set_regs_or_place_dupls(session, chordal_env);
-       dump_ir_block_graph(session->irg, "-ssa_destr_regs_set");
+       set_regs_or_place_dupls(chordal_env);
+       dump_ir_block_graph(irg, "-ssa_destr_regs_set");
 
-       del_set(b2p);
+       pmap_destroy(perm_map);
 }
 
-void be_ssa_destruction_check(be_main_session_env_t *session, be_chordal_env_t *chordal_env) {
-       pmap_entry *pme;
+static void ssa_destruction_check_walker(ir_node *bl, void *data)
+{
+  be_chordal_env_t *chordal_env = data;
+  ir_node *phi;
        int i, max;
 
-       /* iterate over all blocks */
-       pmap_foreach(chordal_env->border_heads, pme) {
-               border_t *curr;
-               struct list_head *head = pme->value;
-
-               /* iterate over the first ops in the block */
-               list_for_each_entry(border_t, curr, head, list)
-                       if (curr->is_def && curr->is_real && is_Phi(curr->irn)) {
-                               const arch_register_t *phi_reg, *arg_reg;
-                               ir_node *phi = curr->irn;
-
-                               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) {
+        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);
+    }
+  }
+}
+
+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);
 }
index c55f78c..11edd31 100644 (file)
@@ -12,5 +12,5 @@
 /**
  * Performs SSA-Destruction. Arguments get adjusted, phi nodes just stay.
  */
-void be_ssa_destruction(be_main_session_env_t *session, be_chordal_env_t *chordal_env);
-void be_ssa_destruction_check(be_main_session_env_t *session, be_chordal_env_t *chordal_env);
+void be_ssa_destruction(be_chordal_env_t *chordal_env);
+void be_ssa_destruction_check(be_chordal_env_t *chordal_env);