Cosmetic changes to the chordal register allocator
authorSebastian Hack <hack@ipd.info.uni-karlsruhe.de>
Tue, 17 May 2005 12:48:08 +0000 (12:48 +0000)
committerSebastian Hack <hack@ipd.info.uni-karlsruhe.de>
Tue, 17 May 2005 12:48:08 +0000 (12:48 +0000)
Implemented tree intrrval dumping for chordal graphs.

19 files changed:
ir/be/Makefile.in
ir/be/bearch.c
ir/be/bearch.h
ir/be/bechordal.c
ir/be/bechordal.h
ir/be/bechordal_draw.c [new file with mode: 0644]
ir/be/bechordal_draw.h [new file with mode: 0644]
ir/be/bechordal_t.h
ir/be/bechordalspill.c
ir/be/becopyheur.c
ir/be/becopyilp.c
ir/be/becopyopt.c
ir/be/becopyopt.h
ir/be/becopyoptmain.c
ir/be/becopyoptmain.h
ir/be/bemain.c
ir/be/bera.c
ir/be/bera_t.h [deleted file]
ir/be/beutil.c

index 708963d..41d2bef 100644 (file)
@@ -24,7 +24,8 @@ SOURCES +=    Makefile.in besched.h belistsched.h belistsched.c \
        benumb_t.h benumb.c bechordal.c bera.c beutil.c \
        bera.h bechordalspill.c beasm_dump_globals.c beasm_asm_gnu.c \
        sp_matrix.c becopyoptmain.c becopyopt.c becopyheur.c \
-       becopyilp.c becopystat.c bearch_firm.c bearch.c
+       becopyilp.c becopystat.c bearch_firm.c bearch.c bechordal_draw.c \
+       bechordal_draw.h
 
 include $(topdir)/MakeRules
 
index a5f8fac..d0a0737 100644 (file)
@@ -95,6 +95,14 @@ int arch_get_allocatable_regs(const arch_env_t *env, const ir_node *irn,
   return 0;
 }
 
+int arch_is_register_operand(const arch_env_t *env,
+    const ir_node *irn, int pos)
+{
+  const arch_irn_ops_t *ops = get_irn_ops(env, irn);
+  const arch_register_req_t *req = ops->get_irn_reg_req(irn, pos);
+  return req != NULL;
+}
+
 int arch_reg_is_allocatable(const arch_env_t *env, const ir_node *irn,
     int pos, const arch_register_t *reg)
 {
index e361308..4ffe248 100644 (file)
@@ -293,6 +293,17 @@ typedef struct _arch_irn_ops_t {
 
 } arch_irn_ops_t;
 
+/**
+ * Check if an operand is a register operand.
+ * @param env The environment.
+ * @param irn The node.
+ * @param pos The position of the operand.
+ * @return 1, if the operand is significant for register allocation, 0
+ * if not.
+ */
+extern int arch_is_register_operand(const arch_env_t *env,
+    const ir_node *irn, int pos);
+
 /**
  * Get the number of allocatable registers concerning
  * a register class for an operand of a node.
index cadaf20..eb07a71 100644 (file)
 
 #include "beutil.h"
 #include "besched.h"
-#include "bera_t.h"
 #include "benumb_t.h"
 #include "besched_t.h"
 #include "belive_t.h"
-#include "bechordal_t.h"
 #include "bearch.h"
 
-#define BUILD_GRAPH
-#undef DUMP_INTERVALS
+#include "bechordal_t.h"
+#include "bechordal_draw.h"
+
+#define NO_COLOR (-1)
+
+#define DUMP_INTERVALS
 #undef DUMP_PRESSURE
 #undef DUMP_IFG
 
 #if defined(DUMP_IFG) && !defined(BUILD_GRAPH)
-#define BUILD_GRAPH
+#error Must define BUILD_GRAPH to be able to dump it.
 #endif
 
 
 
 #endif /* DEBUG_libfirm */
 
-#define TEST_COLORS 2048
-
 static firm_dbg_module_t *dbg;
 
-/**
- * Environment for each of the chordal register allocator phases
- */
-typedef struct _env_t {
-       struct obstack obst;    /**< An obstack for temporary storage. */
-  ir_graph *irg;        /**< The graph the reg alloc is running on. */
-#ifdef BUILD_GRAPH
-       set *nodes;                                             /**< The interference graph nodes. */
-       set *edges;                                             /**< The interference graph edges. */
-#endif
-
-       bitset_t *live;                         /**< A liveness bitset. */
-       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. */
-} env_t;
-
-
-typedef struct _be_chordal_dump_params_t {
-       int x_dist;
-       int y_dist;
-       double font_scale;
-} be_chordal_dump_params_t;
-
-static const be_chordal_dump_params_t dump_params = {
-       10,
-       10,
-       4
-};
-
-#ifdef DUMP_INTERVALS
-
-static INLINE void intv_filename(char *s, size_t n,
-    const env_t *env, ir_node *block)
-{
-       ir_snprintf(s, n, "intv_%F_%s_bl%N.eps",
-      env->irg, env->cls->name, block);
-}
-
-static void draw_interval_graph(const env_t *env,
-    ir_node *block, const be_chordal_dump_params_t *params)
-{
-       int i;
-       int x_dist = params->x_dist;
-       int y_dist = params->y_dist;
-       ir_graph *irg = env->irg;
-  struct list_head *border_head = get_block_border_head(block);
-
-       FILE *f;
-       char buf[1024];
-
-  intv_filename(buf, sizeof(buf), env, block);
-
-       if((f = fopen(buf, "wt")) != NULL) {
-               border_t *b;
-               int *seen = xcalloc(get_graph_node_count(irg), sizeof(seen[0]));
-               int last_pos = list_empty(border_head) ? 0 : list_entry(border_head->prev, border_t, list)->step;
-               int max_col = 0;
-
-               list_for_each_entry_reverse(border_t, b, border_head, list) {
-                       const ir_node *irn = b->irn;
-                       int col = get_irn_color(irn);
-                       max_col = max_col > col ? max_col : col;
-               }
-
-               fprintf(f, "%%!PS-Adobe-2.0\n");
-               fprintf(f, "%%%%BoundingBox: -10 -10 %d %d\n",
-                               x_dist * last_pos + x_dist, y_dist * max_col + y_dist);
-               fprintf(f, "/mainfont /Courier findfont %f scalefont def\n", params->font_scale);
-               fprintf(f, "mainfont setfont\n");
-               fprintf(f, "0.2 setlinewidth\n");
-
-               for(i = 0; i <= last_pos; ++i) {
-                       fprintf(f, "0 0 0 setrgbcolor\n");
-                       fprintf(f, "%d %d moveto\n", i * x_dist, -2);
-                       fprintf(f, "%d %d lineto\n", i * x_dist, max_col * y_dist + 2);
-                       fprintf(f, "stroke\n");
-               }
-               fprintf(f, "0.5 setlinewidth\n");
-
-               list_for_each_entry_reverse(border_t, b, border_head, list) {
-                       const ir_node *irn = b->irn;
-                       int nr = get_irn_graph_nr(irn);
-
-                       if(b->is_def)
-                               seen[nr] = b->step;
-                       else {
-                               int col = get_irn_color(irn);
-
-                               int pos = last_pos - seen[nr];
-                               int end_pos = last_pos - b->step;
-                               int live_in = is_live_in(block, irn);
-                               int live_end = is_live_end(block, irn);
-                               int y_val = y_dist * col;
-
-                               int red = 0;
-                               int green = live_end;
-                               int blue = live_in;
-
-                               fprintf(f, "0 0 0 setrgbcolor\n");
-                               fprintf(f, "%d %d moveto\n", x_dist * pos + 2, y_val + 2);
-                               ir_fprintf(f, "(%n/%d%s) show\n", irn, nr, is_phi_operand(irn) ? "*" : "");
-                               fprintf(f, "%d %d %d setrgbcolor\n", red, green, blue);
-                               fprintf(f, "%d %d moveto\n", x_dist * pos, y_val);
-                               fprintf(f, "%d %d lineto\n", (x_dist * end_pos) - 5, y_val);
-                               fprintf(f, "stroke\n");
-                       }
-               }
-
-               free(seen);
-               fclose(f);
-       }
-}
-
-static void dump_block(ir_node *bl, void *data)
-{
-  const env_t *env = data;
-  FILE *f = env->data;
-  char buf[128];
-
-  draw_interval_graph(env, bl, &dump_params);
-
-  intv_filename(buf, sizeof(buf), env, bl);
-  ir_fprintf(f, "\tb%N [shape=\"epsf\" shapefile=\"%s\"];\n", bl, buf);
-}
-
-static void dump_edges(ir_node *bl, void *data)
-{
-  const env_t *env = data;
-  FILE *f = env->data;
-  int i, n;
-  ir_node *dom;
-
-#if 0
-  for(i = 0, n = get_irn_arity(bl); i < n; ++i) {
-    ir_node *pred = get_irn_n(bl, i);
-    ir_fprintf(f, "\tb%N -> b%N;\n", get_nodes_block(pred), bl);
-  }
-#endif
-
-  for(dom = get_Block_dominated_first(bl); dom;
-      dom = get_Block_dominated_next(dom)) {
-
-    ir_fprintf(f, "\tb%N -> b%N;\n", dom, bl);
-  }
-}
-
-static void dump_intv_cfg(env_t *env)
-{
-  FILE *f;
-  char buf[128];
-
-  ir_snprintf(buf, sizeof(buf), "intv_cfg_%s_%F.dot",
-      env->cls->name, env->irg);
-
-  if((f = fopen(buf, "wt")) != NULL) {
-    void *old_data = env->data;
-
-    env->data = f;
-    ir_fprintf(f, "digraph G {\n");
-    ir_fprintf(f, "\tgraph [rankdir=\"LR\", ordering=\"out\"];\n");
-    dom_tree_walk_irg(env->irg, dump_block, dump_edges, env);
-    // irg_block_walk_graph(env->irg, dump_block, dump_edges, env);
-    ir_fprintf(f, "}\n");
-    fclose(f);
-
-    env->data = old_data;
-  }
-}
-
-#endif
-
 #ifdef BUILD_GRAPH
 
 #define IF_EDGE_HASH(e) ((e)->src)
@@ -269,7 +93,7 @@ static INLINE if_edge_t *edge_init(if_edge_t *edge, int src, int tgt)
        return edge;
 }
 
-static INLINE void add_if(const env_t *env, int src, int tgt)
+static INLINE void add_if(const be_chordal_env_t *env, int src, int tgt)
 {
        if_edge_t edge;
        if_node_t node, *src_node, *tgt_node;
@@ -290,18 +114,20 @@ static INLINE void add_if(const env_t *env, int src, int tgt)
        pset_insert_ptr(tgt_node->neighb, src_node);
 }
 
-static INLINE int are_connected(const env_t *env, int src, int tgt)
+static INLINE int are_connected(const be_chordal_env_t *env, int src, int tgt)
 {
        if_edge_t edge;
        edge_init(&edge, src, tgt);
        return set_find(env->edges, &edge, sizeof(edge), IF_EDGE_HASH(&edge)) != NULL;
 }
 
-int ifg_has_edge(const ir_graph *irg, if_node_t *n1, if_node_t* n2) {
-       return are_connected(get_irg_ra_link(irg), n1->nnr, n2->nnr);
+int ifg_has_edge(const be_chordal_env_t *env, const if_node_t *n1, const if_node_t* n2) {
+       return are_connected(env, n1->nnr, n2->nnr);
 }
 
-static void dump_ifg(ir_graph *irg, set *edges, const char *filename)
+#ifdef DUMP_IFG
+
+static void dump_ifg(const be_chordal_env_t *env)
 {
        static const char *colors[] = {
                "coral",
@@ -386,6 +212,11 @@ static void dump_ifg(ir_graph *irg, set *edges, const char *filename)
        static const int n_colors = sizeof(colors) / sizeof(colors[0]);
 
        FILE *f;
+  set *edges = env->edges;
+  ir_graph *irg = env->irg;
+  char filename[128];
+
+  ir_snprintf(filename, sizeof(filename), "ifg_%s_%F.dot", env->cls->name, irg);
 
        if((f = fopen(filename, "wt")) != NULL) {
                bitset_pos_t pos;
@@ -425,6 +256,8 @@ static void dump_ifg(ir_graph *irg, set *edges, const char *filename)
 
 }
 
+#endif /* DUMP_IFG */
+
 #endif /* BUILD_GRAPH */
 
 
@@ -440,7 +273,7 @@ static void dump_ifg(ir_graph *irg, set *edges, const char *filename)
  * @param is_def Is the border a use or a def.
  * @return The created border.
  */
-static INLINE border_t *border_add(env_t *env, struct list_head *head,
+static INLINE border_t *border_add(be_chordal_env_t *env, struct list_head *head,
                        ir_node *irn, unsigned step, unsigned pressure,
                        unsigned is_def, unsigned is_real)
 {
@@ -510,7 +343,7 @@ static void pressure(ir_node *block, void *env_ptr)
 #define border_use(irn, step, real) \
        border_add(env, head, irn, step, ++pressure, 0, real)
 
-       env_t *env = env_ptr;
+       be_chordal_env_t *env = env_ptr;
        bitset_t *live = env->live;
        ir_node *irn;
 
@@ -526,8 +359,9 @@ static void pressure(ir_node *block, void *env_ptr)
        bitset_clear_all(live);
 
        /* Set up the border list in the block info */
-       head = &get_ra_block_info(block)->border_head;
+  head = obstack_alloc(&env->obst, sizeof(*head));
        INIT_LIST_HEAD(head);
+  pmap_insert(env->border_heads, block, head);
 
        /*
         * Make final uses of all values live out of the block.
@@ -550,9 +384,6 @@ static void pressure(ir_node *block, void *env_ptr)
                DBG((dbg, LEVEL_1, "\tinsn: %n, pressure: %d\n", irn, pressure));
                DBG((dbg, LEVEL_2, "\tlive: %b\n", live));
 
-               /* Erase the color of each node encountered. */
-               set_irn_color(irn, NO_COLOR);
-
     /*
      * If the node defines some value, which can put into a
      * register of the current class, make a border for it.
@@ -610,7 +441,7 @@ static void pressure(ir_node *block, void *env_ptr)
 
 static void assign(ir_node *block, void *env_ptr)
 {
-       env_t *env = env_ptr;
+       be_chordal_env_t *env = env_ptr;
        struct obstack *obst = &env->obst;
        bitset_t *live = env->live;
        bitset_t *colors = env->colors;
@@ -623,7 +454,7 @@ static void assign(ir_node *block, void *env_ptr)
 
        const ir_node *irn;
        border_t *b;
-       struct list_head *head = &get_ra_block_info(block)->border_head;
+       struct list_head *head = get_block_border_head(env, block);
        pset *live_in = get_live_in(block);
 
        bitset_clear_all(live);
@@ -714,17 +545,17 @@ static void assign(ir_node *block, void *env_ptr)
 
 void be_ra_chordal_init(void)
 {
-       dbg = firm_dbg_register(DBG_BERA);
+       dbg = firm_dbg_register(DBG_CHORDAL);
        firm_dbg_set_mask(dbg, 0);
 }
 
-void be_ra_chordal(ir_graph *irg,
+be_chordal_env_t *be_ra_chordal(ir_graph *irg,
     const arch_env_t *arch_env,
     const arch_register_class_t *cls)
 {
        int node_count = get_graph_node_count(irg);
   int colors_n = arch_register_class_n_regs(cls);
-       env_t *env = malloc(sizeof(*env));
+       be_chordal_env_t *env = malloc(sizeof(*env));
 
        if(get_irg_dom_state(irg) != dom_consistent)
                compute_doms(irg);
@@ -743,36 +574,39 @@ void be_ra_chordal(ir_graph *irg,
   env->cls = cls;
   env->arch_env = arch_env;
   env->irg = irg;
+  env->border_heads = pmap_create();
 
        /* First, determine the pressure */
        dom_tree_walk_irg(irg, pressure, NULL, env);
 
        /* Insert probable spills */
-       be_ra_chordal_spill(irg);
+       be_ra_chordal_spill(env);
 
        /* Assign the colors */
        dom_tree_walk_irg(irg, assign, NULL, env);
 
 #ifdef DUMP_IFG
+  dump_ifg(env);
+#endif
+
+#ifdef DUMP_INTERVALS
        {
                char buf[128];
+    plotter_t *plotter;
 
-               ir_snprintf(buf, sizeof(buf), "ifg_%F.dot", irg);
-               dump_ifg(irg, env->edges, buf);
-       }
-#endif
+               ir_snprintf(buf, sizeof(buf), "ifg_%s_%F.eps", cls->name, irg);
+    plotter = new_plotter_ps(buf);
 
-#ifdef DUMP_INTERVALS
-  dump_intv_cfg(env);
+    draw_interval_tree(&draw_chordal_def_opts, env, plotter, arch_env, cls);
+    plotter_free(plotter);
+       }
 #endif
 
-       set_irg_ra_link(irg, env);
+  return env;
 }
 
-void be_ra_chordal_done(ir_graph *irg)
+void be_ra_chordal_done(be_chordal_env_t *env)
 {
-       env_t *env = get_irg_ra_link(irg);
-
 #ifdef BUILD_GRAPH
        {
                if_node_t *ifn;
@@ -783,18 +617,14 @@ void be_ra_chordal_done(ir_graph *irg)
        }
 #endif
 
+  pmap_destroy(env->border_heads);
        obstack_free(&env->obst, NULL);
        free(env);
 }
 
-int phi_ops_interfere(const ir_node *a, const ir_node *b)
+int nodes_interfere(const be_chordal_env_t *env, const ir_node *a, const ir_node *b)
 {
 #ifdef BUILD_GRAPH
-       ir_graph *irg = get_irn_irg(a);
-       env_t *env = get_irg_ra_link(irg);
-
-       assert(irg == get_irn_irg(b) && "Both nodes must be in the same graph");
-
        return are_connected(env, get_irn_graph_nr(a), get_irn_graph_nr(b));
 #else
        return values_interfere(a, b);
@@ -802,19 +632,13 @@ int phi_ops_interfere(const ir_node *a, const ir_node *b)
 }
 
 #ifdef BUILD_GRAPH
-/** TODO remove this
- * Deprecated. Use be_ra_get_ifg_edges instead.
- */
-set *be_ra_get_ifg(ir_graph *irg) {
-       return ((env_t *)get_irg_ra_link(irg))->edges;
-}
 
-set *be_ra_get_ifg_edges(ir_graph *irg) {
-       return ((env_t *)get_irg_ra_link(irg))->edges;
+set *be_ra_get_ifg_edges(const be_chordal_env_t *env) {
+       return env->edges;
 }
 
-set *be_ra_get_ifg_nodes(ir_graph *irg) {
-       return ((env_t *)get_irg_ra_link(irg))->nodes;
+set *be_ra_get_ifg_nodes(const be_chordal_env_t *env) {
+       return env->nodes;
 }
 
 #endif
index ef97007..c946a74 100644 (file)
 
 #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().
  */
-void be_ra_chordal(ir_graph *irg,
+be_chordal_env_t *be_ra_chordal(ir_graph *irg,
     const arch_env_t *arch_env,
     const arch_register_class_t *cls);
 
@@ -26,7 +28,7 @@ void be_ra_chordal(ir_graph *irg,
  * Free data from the chordal register allocation.
  * @param irg The graph.
  */
-void be_ra_chordal_done(ir_graph *irg);
+void be_ra_chordal_done(be_chordal_env_t *info);
 
 /**
  * Init some things for the chordal register allocator.
diff --git a/ir/be/bechordal_draw.c b/ir/be/bechordal_draw.c
new file mode 100644 (file)
index 0000000..45e7758
--- /dev/null
@@ -0,0 +1,401 @@
+
+/**
+ * @file   bechordal_draw.c
+ * @date   12.05.2005
+ * @author Sebastian Hack
+ *
+ * Paint chordal graphs.
+ *
+ * Copyright (C) 2005 Universitaet Karlsruhe
+ * Released under the GPL
+ */
+
+#include <limits.h>
+
+#include "pmap.h"
+
+#include "irgwalk.h"
+#include "irprintf.h"
+#include "irouts.h"
+
+#include "belive_t.h"
+#include "bechordal_t.h"
+#include "besched_t.h"
+#include "bechordal_draw.h"
+
+typedef struct {
+  be_chordal_env_t *env;
+  plotter_t inh;
+  const color_t *color;
+  int width;
+} base_plotter_t;
+
+#define decl_self(type, from) \
+  type *self = (type *) from
+
+static void set_color(plotter_t *_self, const color_t *color)
+{
+  decl_self(base_plotter_t, _self);
+  self->color = color;
+}
+
+static const color_t *get_color(const plotter_t *_self)
+{
+  decl_self(const base_plotter_t, _self);
+  return self->color;
+}
+
+static void set_width(plotter_t *_self, int width)
+{
+  decl_self(base_plotter_t, _self);
+  self->width = width;
+}
+
+static int get_width(const plotter_t *_self)
+{
+  decl_self(const base_plotter_t, _self);
+  return self->width;
+}
+
+static void plotter_default_free(plotter_t *self)
+{
+}
+
+typedef struct {
+  base_plotter_t inh;
+  const char *filename;
+  FILE *f;
+} ps_plotter_t;
+
+static void ps_begin(plotter_t *_self, const rect_t *vis)
+{
+  FILE *f;
+  decl_self(ps_plotter_t, _self);
+
+  f = self->f = fopen(self->filename, "wt");
+  fprintf(f, "%%!PS-Adobe-2.0\n");
+  fprintf(f, "%%%%BoundingBox: %d %d %d %d\n", vis->x, vis->y, vis->w, vis->h);
+#if 0
+  fprintf(f, "/mainfont /Courier findfont %f scalefont def\n", 10.0);
+  fprintf(f, "mainfont setfont\n");
+#endif
+}
+
+static void ps_setcolor(plotter_t *_self, const color_t *color)
+{
+  decl_self(ps_plotter_t, _self);
+  set_color(_self, color);
+
+  fprintf(self->f, "%.2f %.2f %.2f setrgbcolor\n",
+      color->r, color->g, color->b);
+}
+
+static void ps_line(plotter_t *_self, int x1, int y1, int x2, int y2)
+{
+  decl_self(ps_plotter_t, _self);
+
+  fprintf(self->f, "%d %d moveto\n", x1, y1);
+  fprintf(self->f, "%d %d lineto\n", x2, y2);
+  fprintf(self->f, "stroke\n");
+}
+
+static void ps_box(plotter_t *_self, const rect_t *rect)
+{
+  decl_self(ps_plotter_t, _self);
+
+  fprintf(self->f, "%d %d %d %d rectstroke\n",
+      rect->x, rect->y, rect->w, rect->h);
+}
+
+void ps_text(plotter_t *_self, int x, int y, const char *str)
+{
+  decl_self(ps_plotter_t, _self);
+
+  fprintf(self->f, "%d %d moveto\n", x, y);
+  fprintf(self->f, "(%s) show\n", str);
+}
+
+static void ps_finish(plotter_t *_self)
+{
+  decl_self(ps_plotter_t, _self);
+  fclose(self->f);
+}
+
+const plotter_if_t ps_plotter_vtab = {
+  ps_begin,
+  ps_setcolor,
+  get_color,
+  set_width,
+  get_width,
+  ps_line,
+  ps_box,
+  ps_text,
+  ps_finish,
+  plotter_default_free
+};
+
+plotter_t *new_plotter_ps(const char *filename)
+{
+  ps_plotter_t *ps_plotter = malloc(sizeof(*ps_plotter));
+  plotter_t *p = (plotter_t *) ps_plotter;
+
+  ps_plotter->filename = filename;
+  p->vtab = &ps_plotter_vtab;
+  return p;
+}
+
+extern void plotter_free(plotter_t *self)
+{
+  self->vtab->free(self);
+  free(self);
+}
+
+const draw_chordal_opts_t draw_chordal_def_opts = {
+  10, 10, 30, 8
+};
+
+typedef struct _draw_chordal_env_t {
+  const be_chordal_env_t *chordal_env;
+  const arch_env_t *arch_env;
+  const arch_register_class_t *cls;
+  pmap *block_dims;
+  plotter_t *plotter;
+  const draw_chordal_opts_t *opts;
+
+  struct obstack obst;
+  int max_color;
+} draw_chordal_env_t;
+
+struct block_dims {
+  int max_step;
+  int min_step;
+  int max_color;
+  rect_t box;
+  rect_t subtree_box;
+};
+
+static INLINE int min(int a, int b)
+{
+  return a < b ? a : b;
+}
+
+static INLINE int max(int a, int b)
+{
+  return a > b ? a : b;
+}
+
+#define doz(a, b) max((a) - (b), 0)
+
+static void block_dims_walker(ir_node *block, void *data)
+{
+  draw_chordal_env_t *env = data;
+  border_t *b;
+       struct list_head *head = get_block_border_head(env->chordal_env, block);
+  const draw_chordal_opts_t *opts = env->opts;
+  struct block_dims *dims = obstack_alloc(&env->obst, sizeof(*dims));
+
+  memset(dims, 0, sizeof(*dims));
+  dims->min_step = INT_MAX;
+
+       list_for_each_entry_reverse(border_t, b, head, list) {
+    ir_node *irn = b->irn;
+    const arch_register_t *reg = arch_get_irn_register(env->arch_env, irn, 0);
+    int col = arch_register_get_index(reg);
+
+    dims->max_step = max(dims->max_step, b->step);
+    dims->max_color = max(dims->max_color, col);
+    env->max_color = max(env->max_color, col);
+  }
+
+  dims->min_step = 1;
+
+#if 1
+  dims->box.w = (dims->max_color + 2) * opts->h_inter_gap;
+  dims->box.h = dims->max_step * opts->v_inter_gap;
+#else
+  dims->box.w = dims->box.h = 10;
+#endif
+
+  pmap_insert(env->block_dims, block, dims);
+}
+
+static void layout(const draw_chordal_env_t *env, ir_node *bl, int x)
+{
+  const draw_chordal_opts_t *opts = env->opts;
+  struct block_dims *dims = pmap_get(env->block_dims, bl);
+  ir_node *sub;
+  rect_t *rect = &dims->subtree_box;
+  int h_space = 0;
+
+  memset(rect, 0, sizeof(*rect));
+  rect->x = x;
+
+  dominates_for_each(bl, sub) {
+    struct block_dims *bl_dim = pmap_get(env->block_dims, sub);
+
+    layout(env, sub, rect->x + rect->w);
+
+    rect->w += h_space + bl_dim->subtree_box.w;
+    rect->h = max(rect->h, bl_dim->subtree_box.h);
+
+    h_space = opts->h_gap;
+  }
+
+  rect->w = max(rect->w, dims->box.w + opts->h_gap);
+
+  dims->box.x = x + doz(rect->w, dims->box.w) / 2;
+  dims->box.y = rect->h + opts->v_gap;
+
+  rect->h += dims->box.h + opts->v_gap;
+}
+
+static void set_y(const draw_chordal_env_t *env, ir_node *bl, int up)
+{
+  const draw_chordal_opts_t *opts = env->opts;
+  struct block_dims *dims = pmap_get(env->block_dims, bl);
+  int max_height = dims->subtree_box.h - dims->box.h - opts->v_gap;
+  ir_node *sub;
+
+  dominates_for_each(bl, sub) {
+    struct block_dims *bl_dim = pmap_get(env->block_dims, sub);
+    int height_diff = max_height - bl_dim->subtree_box.h;
+
+    set_y(env, sub, up + height_diff);
+  }
+
+  dims->subtree_box.y += up;
+  dims->box.y += up;
+}
+
+static color_t *reg_to_color(const draw_chordal_env_t *env,
+    ir_node *irn, color_t *color)
+{
+  int i, n, phi_arg = 0;
+
+  for(i = 0, n = get_irn_n_outs(irn); i < n && !phi_arg; ++i)
+    phi_arg |= is_Phi(get_irn_out(irn, i));
+
+  color->r = is_Phi(irn) ? 0.5 : 0.0;
+  color->g = phi_arg ? 0.5 : 0.0;
+  color->b = 0.0;
+
+  return color;
+
+}
+
+static void draw_block(ir_node *bl, void *data)
+{
+  static const color_t black = { 0, 0, 0 };
+
+  const draw_chordal_env_t *env = data;
+  pset *live_in = get_live_in(bl);
+  ir_node *irn;
+  border_t *b;
+       struct list_head *head = get_block_border_head(env->chordal_env, bl);
+  ir_node *dom = get_Block_idom(bl);
+  const draw_chordal_opts_t *opts = env->opts;
+  struct block_dims *dims = pmap_get(env->block_dims, bl);
+  char buf[64];
+
+  ir_snprintf(buf, sizeof(buf), "%F", bl);
+
+  env->plotter->vtab->set_color(env->plotter, &black);
+  env->plotter->vtab->box(env->plotter, &dims->box);
+
+#if 0
+  env->plotter->vtab->text(env->plotter, dims->box.x, dims->box.y, buf);
+#endif
+
+       list_for_each_entry(border_t, b, head, list) {
+    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 x = (col + 1) * opts->h_inter_gap;
+      int ystart = (b->step + dims->min_step) * opts->v_inter_gap;
+      int ystop = (b->other_end->step - dims->min_step)
+        * opts->v_inter_gap + opts->v_inter_gap / 2;
+
+      color_t color;
+      reg_to_color(env, b->irn, &color);
+
+      x += dims->box.x;
+      ystart += dims->box.y;
+      ystop += dims->box.y;
+
+      env->plotter->vtab->set_color(env->plotter, &color);
+      env->plotter->vtab->line(env->plotter, x, ystart, x, ystop);
+    }
+  }
+
+  if(dom) {
+    struct block_dims *dom_dims = pmap_get(env->block_dims, dom);
+
+    for(irn = pset_first(live_in); irn; irn = pset_next(live_in)) {
+      if(arch_irn_has_reg_class(env->arch_env, irn, 0, env->cls)) {
+        const arch_register_t *reg = arch_get_irn_register(env->arch_env, irn, 0);
+        int col = arch_register_get_index(reg);
+        int x = (col + 1) * opts->h_inter_gap;
+
+        color_t color;
+        reg_to_color(env, irn, &color);
+
+        env->plotter->vtab->set_color(env->plotter, &color);
+        env->plotter->vtab->line(env->plotter,
+            dims->box.x + x, dims->box.y + dims->box.h,
+            dom_dims->box.x + x, dom_dims->box.y);
+      }
+    }
+  }
+
+#if 0
+  if(dom) {
+  struct block_dims *dom_dims = pmap_get(env->block_dims, dom);
+    rect_t line;
+
+    line.x = dims->box.x;
+    line.y = dims->box.y;
+    line.w = dom_dims->box.x;
+    line.h = dom_dims->box.y;
+
+    env->plotter->vtab->line(env->plotter, &line);
+  }
+#endif
+}
+
+static void draw(draw_chordal_env_t *env, const rect_t *bbox)
+{
+  plotter_t *p = env->plotter;
+
+  p->vtab->begin(p, bbox);
+  irg_block_walk_graph(env->chordal_env->irg, draw_block, NULL, env);
+  p->vtab->finish(p);
+}
+
+void draw_interval_tree(const draw_chordal_opts_t *opts,
+    const be_chordal_env_t *chordal_env,
+    plotter_t *plotter, const arch_env_t *arch_env,
+    const arch_register_class_t *cls)
+{
+  draw_chordal_env_t env;
+  struct block_dims *start_dims;
+  ir_node *start_block = get_irg_start_block(chordal_env->irg);
+
+  env.arch_env = arch_env;
+  env.opts = opts;
+  env.block_dims = pmap_create();
+  env.plotter = plotter;
+  env.chordal_env = chordal_env;
+  env.cls = cls;
+  env.max_color = 0;
+  env.chordal_env = chordal_env;
+  obstack_init(&env.obst);
+
+  irg_block_walk_graph(chordal_env->irg, block_dims_walker, NULL, &env);
+  layout(&env, start_block, 0);
+  set_y(&env, start_block, 0);
+  start_dims = pmap_get(env.block_dims, start_block);
+  draw(&env, &start_dims->subtree_box);
+
+  pmap_destroy(env.block_dims);
+  obstack_free(&env.obst, NULL);
+}
diff --git a/ir/be/bechordal_draw.h b/ir/be/bechordal_draw.h
new file mode 100644 (file)
index 0000000..af86711
--- /dev/null
@@ -0,0 +1,71 @@
+
+/**
+ * @file   bechordal_draw.h
+ * @date   13.05.2005
+ * @author Sebastian Hack
+ *
+ * Drawing chordal graphs.
+ *
+ * Copyright (C) 2005 Universitaet Karlsruhe
+ * Released under the GPL
+ */
+
+#ifndef _BECHORDAL_DRAW_H
+#define _BECHORDAL_DRAW_H
+
+#include "irgraph.h"
+#include "bearch.h"
+
+typedef struct _plotter_t plotter_t;
+typedef struct _plotter_if_t plotter_if_t;
+typedef struct _rect_t rect_t;
+typedef struct _draw_chordal_opts_t draw_chordal_opts_t;
+typedef struct _color_t color_t;
+
+struct _color_t {
+  double r, g, b;
+};
+
+struct _rect_t {
+  int x, y, w, h;
+};
+
+struct _plotter_if_t {
+  void (*begin)(plotter_t *self, const rect_t *visible_area);
+
+  void (*set_color)(plotter_t *self, const color_t * color);
+  const color_t * (*get_color)(const plotter_t *self);
+  void (*set_width)(plotter_t *self, int width);
+  int (*get_width)(const plotter_t *self);
+  void (*line)(plotter_t *self, int x1, int y1, int x2, int y2);
+  void (*box)(plotter_t *self, const rect_t *rect);
+  void (*text)(plotter_t *self, int x, int y, const char *str);
+
+  void (*finish)(plotter_t *self);
+  void (*free)(plotter_t *self);
+};
+
+extern void plotter_free(plotter_t *self);
+
+struct _plotter_t {
+  const plotter_if_t *vtab;
+};
+
+struct _draw_chordal_opts_t {
+  int h_gap;
+  int h_inter_gap;
+  int v_gap;
+  int v_inter_gap;
+};
+
+extern const draw_chordal_opts_t draw_chordal_def_opts;
+
+extern plotter_t *new_plotter_ps(const char *filename);
+
+extern void draw_interval_tree(
+    const draw_chordal_opts_t *opts,
+    const be_chordal_env_t *chordal_env,
+    plotter_t *plotter, const arch_env_t *env,
+    const arch_register_class_t *cls);
+
+#endif /* _BECHORDAL_DRAW_H */
index 7898bd0..d571c9c 100644 (file)
@@ -8,8 +8,25 @@
 #ifndef _BECHORDAL_T_H
 #define _BECHORDAL_T_H
 
+#include <stdlib.h>
+
+#include "bitset.h"
+#include "list.h"
+#include "pset.h"
+#include "pmap.h"
+#include "set.h"
+
+#include "irnode.h"
+#include "irgraph.h"
+#include "bechordal.h"
+
+/** Defines an invalid register index. */
+#define NO_COLOR (-1)
+
 #define BUILD_GRAPH
 
+#define DBG_CHORDAL "firm.be.ra.chordal"
+
 /**
  * A liveness interval border.
  */
@@ -29,6 +46,39 @@ typedef struct _border_t {
                                                                                                                                        a block, each value has one begin and one end. */
 } border_t;
 
+/**
+ * Environment for each of the chordal register allocator phases
+ */
+struct _be_chordal_env_t {
+       struct obstack obst;    /**< An obstack for temporary storage. */
+  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. */
+       set *edges;                                             /**< The interference graph edges. */
+#endif
+
+       bitset_t *live;                         /**< A liveness bitset. */
+       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. */
+};
+
+static INLINE struct list_head *
+_get_block_border_head(const be_chordal_env_t *inf, ir_node *bl)
+{
+  return pmap_get(inf->border_heads, bl);
+}
+
+#define get_block_border_head(info, bl)     _get_block_border_head(info, bl)
+
+int nodes_interfere(const be_chordal_env_t *env, const ir_node *a, const ir_node *b);
+
 #ifdef BUILD_GRAPH
 typedef struct _if_node_t {
        int nnr;
@@ -39,15 +89,15 @@ typedef struct _if_edge_t {
        int src, tgt;
 } if_edge_t;
 
-set *be_ra_get_ifg(ir_graph *irg); /**< Deprecated. Use be_ra_get_ifg_edges. */
-set *be_ra_get_ifg_edges(ir_graph *irg);
-set *be_ra_get_ifg_nodes(ir_graph *irg);
-int ifg_has_edge(const ir_graph *irg, if_node_t *n1, if_node_t* n2);
+set *be_ra_get_ifg_edges(const be_chordal_env_t *env);
+set *be_ra_get_ifg_nodes(const be_chordal_env_t *env);
+int ifg_has_edge(const be_chordal_env_t *env, const if_node_t *n1, const if_node_t* n2);
+
 #define ifn_get_degree(ifnode) pset_count(ifnode->neighb)
 #define foreach_neighb(ifnode, curr) \
                        for(curr=pset_first(ifnode->neighb); curr; curr=pset_next(ifnode->neighb))
 #endif
 
-extern void be_ra_chordal_spill(ir_graph *irg);
+extern void be_ra_chordal_spill(be_chordal_env_t *env);
 
 #endif /* _BECHORDAL_T_H */
index 2166676..10be67a 100644 (file)
 
 #include "beutil.h"
 #include "besched.h"
-#include "bera_t.h"
 #include "benumb_t.h"
 #include "besched_t.h"
 #include "belive_t.h"
 #include "bechordal_t.h"
 
-void be_ra_chordal_spill(ir_graph *irg)
+void be_ra_chordal_spill(be_chordal_env_t *env)
 {
 }
index 4a98c06..9365393 100644 (file)
@@ -99,7 +99,7 @@ static INLINE void qnode_add_conflict(const qnode_t *qn, const ir_node *n1, cons
 static INLINE int qnode_are_conflicting(const qnode_t *qn, const ir_node *n1, const ir_node *n2) {
        conflict_t c;
        /* search for live range interference */
-       if (n1!=n2 && values_interfere(n1, n2))
+       if (n1!=n2 && nodes_interfere(qn->ou->co->chordal_env, n1, n2))
                return 1;
        /* search for recoloring conflicts */
        if ((int)n1 < (int)n2) {
@@ -205,6 +205,8 @@ static ir_node *qnode_color_irn(const qnode_t *qn, ir_node *irn, int col, const
        struct obstack confl_ob;
        ir_node **confl, *cn;
        int i, irn_col;
+  const arch_env_t *arch_env = qn->ou->co->env;
+  const be_chordal_env_t *chordal_env = qn->ou->co->chordal_env;
 
        DBG((dbg, LEVEL_3, "\t      %n \tcaused col(%n) \t%2d --> %2d\n", trigger, irn, qnode_get_new_color(qn, irn), col));
        obstack_init(&confl_ob);
@@ -216,7 +218,7 @@ static ir_node *qnode_color_irn(const qnode_t *qn, ir_node *irn, int col, const
                res = irn;
                goto ret_confl;
        }
-       if (!arch_reg_is_allocatable(qn->ou->co->env,
+       if (!arch_reg_is_allocatable(arch_env,
                                                                 irn,
                                                                 arch_pos_make_out(0),
                                                                 arch_register_for_index(qn->ou->co->cls, col)))
@@ -235,7 +237,10 @@ static ir_node *qnode_color_irn(const qnode_t *qn, ir_node *irn, int col, const
                        ir_node *n;
                        pset *live_ins = get_live_in(irn_bl);
                        for (n = pset_first(live_ins); n; n = pset_next(live_ins))
-                               if (is_allocatable_irn(n) && n != trigger && qnode_get_new_color(qn, n) == col && values_interfere(irn, n)) {
+                               if (arch_irn_has_reg_class(arch_env, n, arch_pos_make_out(0), qn->ou->co->cls)
+            && n != trigger && qnode_get_new_color(qn, n) == col
+            && nodes_interfere(chordal_env, irn, n)) {
+
                                        DBG((dbg, LEVEL_4, "\t        %n\ttroubles\n", n));
                                        obstack_ptr_grow(&confl_ob, n);
                                        pset_break(live_ins);
@@ -262,7 +267,10 @@ static ir_node *qnode_color_irn(const qnode_t *qn, ir_node *irn, int col, const
                         * the target color and interfere with the irn */
                        for (i = 0, max = get_irn_n_outs(curr_bl); i < max; ++i) {
                                ir_node *n = get_irn_out(curr_bl, i);
-                               if (is_allocatable_irn(n) && n != trigger && qnode_get_new_color(qn, n) == col && values_interfere(irn, n)) {
+                               if (arch_irn_has_reg_class(arch_env, n, arch_pos_make_out(0), qn->ou->co->cls)
+            && n != trigger && qnode_get_new_color(qn, n) == col
+            && nodes_interfere(chordal_env, irn, n)) {
+
                                        DBG((dbg, LEVEL_4, "\t        %n\ttroubles\n", n));
                                        obstack_ptr_grow(&confl_ob, n);
                                }
index 3ba94e7..79f564b 100644 (file)
@@ -173,7 +173,7 @@ static INLINE int pi_get_pos(problem_instance_t *pi, int num, int col) {
  */
 static void pi_collect_x_names(ir_node *block, void *env) {
        problem_instance_t *pi = env;
-       struct list_head *head = &get_ra_block_info(block)->border_head;
+       struct list_head *head = get_block_border_head(pi->co->chordal_env, block);
        border_t *curr;
        bitset_t *pos_regs = bitset_alloca(pi->co->cls->n_regs);
 
@@ -218,7 +218,7 @@ static INLINE int all_live_in(ir_node *block, pset *living) {
 static void pi_clique_finder(ir_node *block, void *env) {
        problem_instance_t *pi = env;
        enum phase_t {growing, shrinking} phase = growing;
-       struct list_head *head = &get_ra_block_info(block)->border_head;
+       struct list_head *head = get_block_border_head(pi->co->chordal_env, block);
        border_t *b;
        pset *living = pset_new_ptr(SLOTS_LIVING);
 
@@ -267,7 +267,7 @@ static INLINE int pi_is_simplicial(problem_instance_t *pi, const if_node_t *ifn)
        /* check if these form a clique */
        for (i=0; i<size; ++i)
                for (o=i+1; o<size; ++o)
-                       if (!ifg_has_edge(pi->co->irg, all[i], all[o]))
+                       if (!ifg_has_edge(pi->co->chordal_env, all[i], all[o]))
                                return 0;
 
        /* all edges exist so this is a clique */
@@ -279,12 +279,13 @@ static void pi_find_simplicials(problem_instance_t *pi) {
        if_node_t *ifn;
        int redo = 1;
 
-       if_nodes = be_ra_get_ifg_nodes(pi->co->irg);
+       if_nodes = be_ra_get_ifg_nodes(pi->co->chordal_env);
        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->irg, ifn->nnr);
-                       if (!is_removed(irn) && !is_optimizable(irn) && !is_optimizable_arg(irn) && pi_is_simplicial(pi, ifn)) {
+                       if (!is_removed(irn) && !is_optimizable(irn) &&
+          !is_optimizable_arg(pi->co, irn) && pi_is_simplicial(pi, ifn)) {
                                simpl_t *s = xmalloc(sizeof(*s));
                                s->ifn = ifn;
                                list_add(&s->chain, &pi->simplicials);
index da72f99..33a59b4 100644 (file)
@@ -9,6 +9,7 @@
 #endif
 
 #include "xmalloc.h"
+#include "bechordal_t.h"
 #include "becopyopt.h"
 #include "becopystat.h"
 
@@ -50,7 +51,7 @@ static void co_append_unit(copy_opt_t *co, ir_node *root) {
                ir_node *arg = get_irn_n(root, i);
                assert(is_curr_reg_class(arg) && "Argument not in same register class.");
                if (arg != root) {
-                       if (!values_interfere(root, arg)) {
+                       if (!nodes_interfere(co->chordal_env, root, arg)) {
                                DBG((dbg, LEVEL_1, "\t  Member: %n\n", arg));
                                if (is_optimizable(arg))
                                        co_append_unit(co, arg);
@@ -72,7 +73,7 @@ static void co_append_unit(copy_opt_t *co, ir_node *root) {
 
 static void co_collect_in_block(ir_node *block, void *env) {
        copy_opt_t *co = env;
-       struct list_head *head = &get_ra_block_info(block)->border_head;
+       struct list_head *head = get_block_border_head(co->chordal_env, block);
        border_t *curr;
 
        list_for_each_entry_reverse(border_t, curr, head, list)
@@ -87,7 +88,8 @@ static void co_collect_units(copy_opt_t *co) {
        del_pset(co->roots);
 }
 
-copy_opt_t *new_copy_opt(ir_graph *irg, const arch_env_t *env, const arch_register_class_t *cls) {
+copy_opt_t *new_copy_opt(be_chordal_env_t *chordal_env,
+    const arch_env_t *env, const arch_register_class_t *cls) {
        const char *s1, *s2, *s3;
        int len;
         copy_opt_t *co;
@@ -96,7 +98,8 @@ copy_opt_t *new_copy_opt(ir_graph *irg, const arch_env_t *env, const arch_regist
        firm_dbg_set_mask(dbg, DEBUG_LVL);
 
        co = xcalloc(1, sizeof(*co));
-       co->irg = irg;
+  co->chordal_env = chordal_env;
+       co->irg = chordal_env->irg;
        co->env = env;
 //     co->isa = env->isa;
        co->cls = cls;
@@ -124,18 +127,18 @@ void free_copy_opt(copy_opt_t *co) {
        }
 }
 
-int is_optimizable_arg(ir_node *irn) {
+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_optimizable(n) && (irn == n || !values_interfere(irn, n)))
+               if (is_optimizable(n) && (irn == n || !nodes_interfere(co->chordal_env, irn, n)))
                        return 1;
        }
        return 0;
 }
 
 
-int co_get_copy_count(copy_opt_t *co) {
+int co_get_copy_count(const copy_opt_t *co) {
        int i, res = 0;
        unit_t *curr;
        list_for_each_entry(unit_t, curr, &co->units, units) {
@@ -148,7 +151,7 @@ int co_get_copy_count(copy_opt_t *co) {
        return res;
 }
 
-int co_get_lower_bound(copy_opt_t *co) {
+int co_get_lower_bound(const copy_opt_t *co) {
        int res = 0;
        unit_t *curr;
        list_for_each_entry(unit_t, curr, &co->units, units)
@@ -156,7 +159,7 @@ int co_get_lower_bound(copy_opt_t *co) {
        return res;
 }
 
-int co_get_interferer_count(copy_opt_t *co) {
+int co_get_interferer_count(const copy_opt_t *co) {
        int res = 0;
        unit_t *curr;
        list_for_each_entry(unit_t, curr, &co->units, units)
@@ -169,7 +172,7 @@ int co_get_interferer_count(copy_opt_t *co) {
  */
 static void co_collect_for_checker(ir_node *block, void *env) {
        copy_opt_t *co = env;
-       struct list_head *head = &get_ra_block_info(block)->border_head;
+       struct list_head *head = get_block_border_head(co->chordal_env, block);
        border_t *curr;
 
        list_for_each_entry_reverse(border_t, curr, head, list)
@@ -190,9 +193,10 @@ void co_check_allocation(copy_opt_t *co) {
 
        nodes = (ir_node **) obstack_finish(&co->ob);
        for (i = 0, n1 = nodes[i]; n1; n1 = nodes[++i]) {
-               assert(! (is_allocatable_irn(n1) && get_irn_col(co, n1) == NO_COLOR));
                for (o = i+1, n2 = nodes[o]; n2; n2 = nodes[++o])
-                       if (phi_ops_interfere(n1, n2) && get_irn_col(co, n1) == get_irn_col(co, n2)) {
+                       if (nodes_interfere(co->chordal_env, n1, n2)
+          && get_irn_col(co, n1) == get_irn_col(co, n2)) {
+
                                DBG((dbg, 0, "Error: %n in %n  and  %n in %n have the same color.\n", n1, get_nodes_block(n1), n2, get_nodes_block(n2)));
                                assert(0 && "Interfering values have the same color!");
                        }
index c2ee3aa..632c6b2 100644 (file)
@@ -27,7 +27,6 @@
 #include "beutil.h"
 #include "benumb_t.h"
 #include "belive_t.h"
-#include "bera_t.h"
 #include "bechordal_t.h"
 #include "bearch.h"
 
@@ -39,6 +38,7 @@
  * Data representing the problem of copy minimization.
  */
 typedef struct _copy_opt_t {
+  be_chordal_env_t *chordal_env;
        ir_graph *irg;                                          /**< the irg to process */
        char *name;                                                     /**< ProgName__IrgName__RegClass */
        const arch_env_t *env;                          /**< Environment (isa + handlers) */
@@ -74,7 +74,8 @@ typedef struct _unit_t {
 /**
  * Generate the problem. Collect all infos and optimizable nodes.
  */
-copy_opt_t *new_copy_opt(ir_graph *irg, const arch_env_t *env, const arch_register_class_t *cls);
+copy_opt_t *new_copy_opt(be_chordal_env_t *chordal_env,
+    const arch_env_t *env, const arch_register_class_t *cls);
 
 /**
  * Free the space...
@@ -86,25 +87,25 @@ void free_copy_opt(copy_opt_t *co);
 /**
  * Checks if the irn is a non-interfering argument of a node which 'is_optimizable'
  */
-int is_optimizable_arg(ir_node *irn);
+int is_optimizable_arg(const copy_opt_t *co, ir_node *irn);
 
 /**
  * Returns the current number of copies needed
  */
-int co_get_copy_count(copy_opt_t *co);
+int co_get_copy_count(const copy_opt_t *co);
 
 /**
  * IMPORTANT: Available only iff heuristic has run!
  * Returns a lower bound for the number of copies needed based on interfering
  * arguments and the size of a max indep. set (only ifg-edges) of the other args.
  */
-int co_get_lower_bound(copy_opt_t *co);
+int co_get_lower_bound(const copy_opt_t *co);
 
 /**
  * Returns the number of arguments interfering with their root node. This also
  * is a (worse) lower bound for the number of copies needed.
  */
-int co_get_interferer_count(copy_opt_t *co);
+int co_get_interferer_count(const copy_opt_t *co);
 
 /**
  * Solves the problem using a heuristic approach
index 07b0690..e00c888 100644 (file)
@@ -27,10 +27,12 @@ void be_copy_opt_init(void) {
        firm_dbg_set_mask(dbg, DEBUG_LVL);
 }
 
-void be_copy_opt(ir_graph* irg, const arch_env_t *env, const arch_register_class_t *cls) {
+void be_copy_opt(be_chordal_env_t *chordal_env,
+    const arch_env_t *env, const arch_register_class_t *cls) {
+
        copy_opt_t *co;
        int lb, copies;
-       co = new_copy_opt(irg, env, cls);
+       co = new_copy_opt(chordal_env, env, cls);
        DBG((dbg, LEVEL_1, "\n\n    ===>  %s  <===\n\n", co->name));
        co_check_allocation(co);
 
index eb95603..e26803b 100644 (file)
 #include "irgraph.h"
 #include "bearch.h"
 
+#include "bechordal.h"
+
 void be_copy_opt_init(void);
-void be_copy_opt(ir_graph* irg, const arch_env_t *env, const arch_register_class_t *cls);
+void be_copy_opt(be_chordal_env_t *chordal_env,
+    const arch_env_t *env, const arch_register_class_t *cls);
 
 #endif
index 25cffd7..2eb1c2c 100644 (file)
@@ -18,7 +18,7 @@
 #include "phiclass.h"
 
 #include "be_t.h"
-#include "bera_t.h"
+#include "bechordal_t.h"
 #include "benumb_t.h"
 #include "besched_t.h"
 #include "belistsched.h"
@@ -44,7 +44,6 @@ void be_init(void)
        be_sched_init();
        be_liveness_init();
        be_numbering_init();
-       be_ra_init();
        be_ra_chordal_init();
        be_copy_opt_init();
 #ifdef DO_STAT
@@ -92,9 +91,10 @@ static void be_main_loop(void)
 #endif
                /* 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);
 
-                       be_ra_chordal(irg, &env, cls);
+                       chordal_env = be_ra_chordal(irg, &env, cls);
 
 #ifdef DUMP_ALLOCATED
                        dump_allocated_irg(&env, irg, "");
@@ -102,8 +102,8 @@ static void be_main_loop(void)
 #ifdef DO_STAT
                        stat_collect_irg(irg);
 #endif
-                       be_copy_opt(irg, &env, cls);
-                       be_ra_chordal_done(irg);
+                       be_copy_opt(chordal_env, &env, cls);
+                       be_ra_chordal_done(chordal_env);
                }
 #ifdef DO_STAT
                stat_dump(irg);
index e7ebb3b..5ab11e9 100644 (file)
 #include "irmode.h"
 #include "irdom.h"
 
-#include "bera_t.h"
 #include "besched_t.h"
 #include "belive_t.h"
 
-FIRM_IMPL1(is_allocatable_irn, int, const ir_node *)
-
-size_t ra_irn_data_offset = 0;
-size_t ra_irg_data_offset = 0;
-
-void be_ra_init(void)
-{
-       ra_irn_data_offset = register_additional_node_data(sizeof(ra_info_t));
-       ra_irg_data_offset = register_additional_graph_data(sizeof(void *));
-}
-
 static INLINE int values_interfere_dom(const ir_node *a, const ir_node *b)
 {
        const ir_node *b1 = get_nodes_block(a);
diff --git a/ir/be/bera_t.h b/ir/be/bera_t.h
deleted file mode 100644 (file)
index 5b83b8a..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/**
- * Internal register allocation facility.
- * @author Sebastian Hack
- * @date 8.12.2004
- */
-
-#ifndef _BERA_T_H
-#define _BERA_T_H
-
-#include "firm_config.h"
-#include "bitset.h"
-#include "list.h"
-
-#include "bera.h"
-
-#define DBG_BERA "firm.be.ra"
-
-typedef struct _ra_node_info_t {
-       ir_node *spill_location;  /**< Spill location node of the node.
-                                                                                                                       If NULL, the node is not spilled. */
-       int pressure;                                                   /**< Register pressure at this node. */
-       int color;                                                              /**< The color assigned to this node. */
-} ra_node_info_t;
-
-typedef struct _ra_block_info_t {
-       bitset_t *used_colors;                                  /**< A bitmask containing all colors used in the block. */
-       struct list_head border_head;           /**< A list head to enqueue the borders. */
-} ra_block_info_t;
-
-/**
- * Register allocation data for a node.
- */
-typedef struct _ra_info_t {
-       union {
-               ra_node_info_t node;
-               ra_block_info_t block;
-       } v;
-} ra_info_t;
-
-#define get_ra_irn_info(irn) get_irn_data(irn, ra_info_t, ra_irn_data_offset)
-#define get_ra_info_irn(inf) get_irn_data_base(inf, ra_irn_data_offset)
-
-#define get_ra_node_info(the_node)             (&get_ra_irn_info(the_node)->v.node)
-#define get_ra_block_info(the_block)   (&get_ra_irn_info(the_block)->v.block)
-
-#define get_block_border_head(bl)     (&get_ra_block_info(bl)->border_head)
-
-extern size_t ra_irn_data_offset;
-
-extern size_t ra_irg_data_offset;
-
-#define get_irg_ra_link(irg) (*(get_irg_data(irg, void *, ra_irg_data_offset)))
-#define set_irg_ra_link(irg,ptr) (*(get_irg_data(irg, void *, ra_irg_data_offset)) = ptr)
-
-/**
- * Initialize the register allocation framework.
- */
-void be_ra_init(void);
-
-/**
- * The 'no color' color. The register allocator should use this value,
- * if a color cannot be assigned at some point.
- */
-#define NO_COLOR (-1)
-
-/**
- * Check, if a color is valid.
- * @param col The color.
- * @return 1, if the color is ok, 0 if the color is illegal.
- */
-#define is_color(col) ((col) != NO_COLOR)
-
-static INLINE int _get_irn_color(const ir_node *irn)
-{
-       assert(!is_Block(irn) && "No block allowed here");
-       return get_ra_node_info(irn)->color;
-}
-
-static INLINE void _set_irn_color(const ir_node *irn, int color)
-{
-       assert(!is_Block(irn) && "No block allowed here");
-       get_ra_node_info(irn)->color = color;
-}
-
-static INLINE int _is_allocatable_irn(const ir_node *irn)
-{
-       assert(!is_Block(irn) && "No block allowed here");
-       return mode_is_datab(get_irn_mode(irn));
-}
-
-#define get_irn_color(irn)                                                             _get_irn_color(irn)
-#define set_irn_color(irn,col)                                         _set_irn_color(irn, col)
-#define is_allocatable_irn(irn)                                                _is_allocatable_irn(irn)
-
-static INLINE struct list_head *_get_block_border_head(ir_node *block)
-{
-       return &get_ra_block_info(block)->border_head;
-}
-
-/**
- * Check, if two phi operands interfere.
- * @param a A node which is operand to a phi function.
- * @param b Another node which is operand to a phi function.
- * @return 1, if @p a and @p b interfere, 0 if not.
- */
-int phi_ops_interfere(const ir_node *a, const ir_node *b);
-
-#endif /* BERA_T_H */
index 09c88cb..4b75cdc 100644 (file)
@@ -13,7 +13,6 @@
 
 #include "beutil.h"
 #include "besched_t.h"
-#include "bera_t.h"
 #include "bearch.h"
 
 struct dump_env {
@@ -42,7 +41,7 @@ static void dump_allocated_block(ir_node *block, void *data)
                if(block != get_irg_start_block(get_irn_irg(block))) {
                        for(i = 0, n = get_irn_arity(irn); i < n; ++i) {
                                ir_node *op = get_irn_n(irn, i);
-                               if(is_allocatable_irn(op)) {
+        if(arch_is_register_operand(dump_env->env, op, arch_pos_make_out(0))) {
                                        ir_fprintf(f, "%s%s", prefix,
               arch_register_get_name(arch_get_irn_register(env, op, 0)));
                                        prefix = ", ";