Implemented tree intrrval dumping for chordal graphs.
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
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)
{
} 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.
#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)
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;
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",
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;
}
+#endif /* DUMP_IFG */
+
#endif /* BUILD_GRAPH */
* @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)
{
#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;
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.
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.
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;
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);
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);
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;
}
#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);
}
#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
#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);
* 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.
--- /dev/null
+
+/**
+ * @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);
+}
--- /dev/null
+
+/**
+ * @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 */
#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.
*/
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;
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 */
#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)
{
}
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) {
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);
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)))
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);
* 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);
}
*/
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);
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);
/* 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 */
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);
#endif
#include "xmalloc.h"
+#include "bechordal_t.h"
#include "becopyopt.h"
#include "becopystat.h"
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);
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)
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;
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;
}
}
-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) {
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)
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)
*/
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)
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!");
}
#include "beutil.h"
#include "benumb_t.h"
#include "belive_t.h"
-#include "bera_t.h"
#include "bechordal_t.h"
#include "bearch.h"
* 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) */
/**
* 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...
/**
* 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
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);
#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
#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"
be_sched_init();
be_liveness_init();
be_numbering_init();
- be_ra_init();
be_ra_chordal_init();
be_copy_opt_init();
#ifdef DO_STAT
#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, "");
#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);
#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);
+++ /dev/null
-/**
- * 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 */
#include "beutil.h"
#include "besched_t.h"
-#include "bera_t.h"
#include "bearch.h"
struct dump_env {
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 = ", ";