From c0b91541ff00fc193b51a3ac3c3f89d7e312d8e7 Mon Sep 17 00:00:00 2001 From: Sebastian Hack Date: Thu, 28 Apr 2005 13:50:27 +0000 Subject: [PATCH] Some bug fixes --- ir/be/bearch.h | 27 +++++++----- ir/be/bearch_firm.c | 27 ++++++------ ir/be/bechordal.c | 103 +++++++++++++++++++++++++++++++++++++------- ir/be/bera_t.h | 4 ++ 4 files changed, 122 insertions(+), 39 deletions(-) diff --git a/ir/be/bearch.h b/ir/be/bearch.h index 90e56d0bc..857a17d18 100644 --- a/ir/be/bearch.h +++ b/ir/be/bearch.h @@ -189,6 +189,9 @@ struct _arch_insn_t { ir_op *op; /**< The firm opcode for this insn. */ }; +#define arch_insn_is_allocatable(insn,reg) \ + ((irn)->get_allocatable_regs(irn, cls, NULL) != 0) + /** * Architecture interface. */ @@ -212,15 +215,6 @@ struct _arch_isa_if_t { */ const arch_register_class_t *(*get_reg_class)(int i); - /** - * Check, if a register is suitable to carry the node's value. - * @param irn The node. - * @param reg The register to check for. - * @return 1, if the register can be allocated for that node, 0 if - * not. - */ - int (*is_reg_allocatable)(const ir_node *irn, const arch_register_t *reg); - /** * Put all registers of a given class which are allocatable to a * certain node into a bitset. @@ -228,8 +222,8 @@ struct _arch_isa_if_t { * the register class @p cls. * @param irn The node. * @param cls The register class. - * @param bs The bitset. - * @return The number of registers which were put into the bitset. + * @param bs The bitset. Can be NULL. + * @return The number of registers which are allocatable at this node. */ int (*get_allocatable_regs)(const ir_node *irn, const arch_register_class_t *cls, struct _bitset_t *bs); @@ -243,6 +237,8 @@ struct _arch_isa_if_t { */ const arch_register_class_t *(*get_irn_reg_class)(const ir_node *irn); + + /** * Get an op for a name. * @note This method may not be implemented. @@ -264,4 +260,13 @@ struct _arch_isa_if_t { #define arch_isa_irn_has_reg_class(isa, irn, cls) \ ((isa)->get_irn_reg_class(irn) == (cls)) +/** + * Check, if a register is allocatable for an irn. + * @param irn The node. + * @param reg The register. + * @return 1, if the register can be allocated to this node, 0 if not. + */ +#define arch_isa_reg_is_allocatable(irn, reg) \ + ((isa)->get_allocatable_regs(irn, (reg)->reg_class, NULL) != 0) + #endif /* _FIRM_BEARCH_H */ diff --git a/ir/be/bearch_firm.c b/ir/be/bearch_firm.c index c91975bbb..e260472c2 100644 --- a/ir/be/bearch_firm.c +++ b/ir/be/bearch_firm.c @@ -20,7 +20,7 @@ static arch_register_class_t reg_classes[] = { (sizeof(reg_classes) / sizeof(reg_classes[0])) #define CLS_GP 0 -#define CLS_FP 0 +#define CLS_FP 1 static void firm_init(void) { @@ -78,32 +78,33 @@ static const arch_register_class_t *firm_get_irn_reg_class(const ir_node *irn) return NULL; } -static int firm_is_reg_allocatable(const ir_node *irn, const arch_register_t *reg) -{ - return arch_register_get_class(reg) == firm_get_irn_reg_class(irn); -} - static int firm_get_allocatable_regs(const ir_node *irn, const arch_register_class_t *cls, bitset_t *bs) { - int i; + int res = 0; if(firm_get_irn_reg_class(irn) != cls) { - bitset_clear_all(bs); - return 0; + if(bs) + bitset_clear_all(bs); } - for(i = 0; i < cls->n_regs; ++i) - bitset_set_all(bs); + else { + int i; + + res = cls->n_regs; + if(bs) { + for(i = 0; i < cls->n_regs; ++i) + bitset_set(bs, i); + } + } - return cls->n_regs; + return res; } const arch_isa_if_t arch_isa_if_firm = { firm_init, firm_get_n_reg_class, firm_get_reg_class, - firm_is_reg_allocatable, firm_get_allocatable_regs, firm_get_irn_reg_class, NULL diff --git a/ir/be/bechordal.c b/ir/be/bechordal.c index 5fed50aa2..b9c4b94bc 100644 --- a/ir/be/bechordal.c +++ b/ir/be/bechordal.c @@ -32,9 +32,14 @@ #include "bechordal_t.h" #include "bearch.h" -#undef DUMP_INTERVALS +#undef BUILD_GRAPH +#define DUMP_INTERVALS #undef DUMP_PRESSURE -#undef DUMP_IFG +#define DUMP_IFG + +#if defined(DUMP_IFG) && !defined(BUILD_GRAPH) +#define BUILD_GRAPH +#endif #ifdef DEBUG_libfirm @@ -54,6 +59,7 @@ static firm_dbg_module_t *dbg; */ 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 *graph; /**< The interference graph. */ #endif @@ -64,6 +70,8 @@ typedef struct _env_t { int colors_n; /**< The number of colors. */ const arch_isa_if_t *isa; /**< The isa interface. */ const arch_register_class_t *cls; /**< The current register class. */ + void *data; /**< Some pointer, to which different + phases can attach data to. */ } env_t; @@ -74,26 +82,33 @@ typedef struct _be_chordal_dump_params_t { } be_chordal_dump_params_t; static const be_chordal_dump_params_t dump_params = { - 30, + 10, 10, 4 }; #ifdef DUMP_INTERVALS -static void draw_interval_graphs(ir_node *block, - struct list_head *border_head, - const be_chordal_dump_params_t *params) + +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 = get_irn_irg(block); + ir_graph *irg = env->irg; + struct list_head *border_head = get_block_border_head(block); FILE *f; char buf[1024]; - ir_snprintf(buf, sizeof(buf), "intv_%s_bl%N.eps", - get_entity_name(get_irg_entity(irg)), block); + intv_filename(buf, sizeof(buf), env, block); if((f = fopen(buf, "wt")) != NULL) { border_t *b; @@ -155,6 +170,63 @@ static void draw_interval_graphs(ir_node *block, 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 @@ -621,10 +693,6 @@ static void assign(ir_node *block, void *env_ptr) } } -#ifdef DUMP_INTERVALS - draw_interval_graphs(block, head, &dump_params); -#endif - #ifdef DUMP_PRESSURE { char buf[128]; @@ -659,7 +727,7 @@ static void assign(ir_node *block, void *env_ptr) void be_ra_chordal_init(void) { dbg = firm_dbg_register(DBG_BERA); - firm_dbg_set_mask(dbg, 0); + firm_dbg_set_mask(dbg, -1); } void be_ra_chordal(ir_graph *irg, @@ -685,6 +753,7 @@ void be_ra_chordal(ir_graph *irg, env->colors_n = colors_n; env->cls = cls; env->isa = isa; + env->irg = irg; /* First, determine the pressure */ dom_tree_walk_irg(irg, pressure, NULL, env); @@ -699,11 +768,15 @@ void be_ra_chordal(ir_graph *irg, { char buf[128]; - ir_snprintf(buf, sizeof(buf), "ifg_%s.dot", get_entity_name(get_irg_entity(irg))); + ir_snprintf(buf, sizeof(buf), "ifg_%F.dot", irg); dump_ifg(irg, env->graph, buf); } #endif +#ifdef DUMP_INTERVALS + dump_intv_cfg(env); +#endif + set_irg_ra_link(irg, env); } diff --git a/ir/be/bera_t.h b/ir/be/bera_t.h index 8a70f66bd..5b83b8a4b 100644 --- a/ir/be/bera_t.h +++ b/ir/be/bera_t.h @@ -16,6 +16,8 @@ #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; @@ -41,6 +43,8 @@ typedef struct _ra_info_t { #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; -- 2.20.1