From d3574fcc5c50023d68c5588e8a2a20378121e39e Mon Sep 17 00:00:00 2001 From: Sebastian Hack Date: Tue, 26 Jul 2005 17:54:45 +0000 Subject: [PATCH] Fixed several bug and introduced some others --- ir/be/bearch.h | 2 +- ir/be/bearch_firm.c | 2 +- ir/be/bechordal.c | 55 ++++++++++++++++++++++++++++++++------------- ir/be/bechordal_t.h | 2 -- ir/be/bedupl.c | 2 ++ ir/be/bemain.c | 15 +++++-------- ir/be/benode.c | 2 +- ir/be/bera.c | 5 +++-- ir/be/besched.c | 3 +++ ir/be/besched_t.h | 5 +++-- 10 files changed, 59 insertions(+), 34 deletions(-) diff --git a/ir/be/bearch.h b/ir/be/bearch.h index 0d32c18a3..09397c8ce 100644 --- a/ir/be/bearch.h +++ b/ir/be/bearch.h @@ -363,7 +363,7 @@ extern int arch_reg_is_allocatable(const arch_env_t *env, * Get the register class of an operand of a node. * @param env The architecture environment. * @param irn The node. - * @param idx The position of the operand. + * @param pos The position of the operand. * @return The register class of the operand or NULL, if * operand is a non-register operand. */ diff --git a/ir/be/bearch_firm.c b/ir/be/bearch_firm.c index 678806fcd..5ddab0567 100644 --- a/ir/be/bearch_firm.c +++ b/ir/be/bearch_firm.c @@ -13,7 +13,7 @@ #include "irreflect.h" -#define N_REGS 4 +#define N_REGS 512 static arch_register_t datab_regs[N_REGS]; diff --git a/ir/be/bechordal.c b/ir/be/bechordal.c index 3416e40b5..488fa9533 100644 --- a/ir/be/bechordal.c +++ b/ir/be/bechordal.c @@ -49,14 +49,11 @@ #endif -#ifdef DEBUG_libfirm #include "fourcc.h" /* Make a fourcc for border checking. */ #define BORDER_FOURCC FOURCC('B', 'O', 'R', 'D') -#endif /* DEBUG_libfirm */ - static firm_dbg_module_t *dbg; #ifdef BUILD_GRAPH @@ -177,6 +174,23 @@ static void dump_ifg(const be_chordal_env_t *env) #endif /* BUILD_GRAPH */ +static void check_border_list(struct list_head *head) +{ + border_t *x; + list_for_each_entry(border_t, x, head, list) { + assert(x->magic == BORDER_FOURCC); + } +} + +static void check_heads(be_chordal_env_t *env) +{ + pmap_entry *ent; + for(ent = pmap_first(env->border_heads); ent; ent = pmap_next(env->border_heads)) { + /* ir_printf("checking border list of block %+F\n", ent->key); */ + check_border_list(ent->value); + } +} + /** * Add an interval border to the list of a block's list @@ -203,6 +217,7 @@ static INLINE border_t *border_add(be_chordal_env_t *env, struct list_head *head /* also allocate the def and tie it to the use. */ def = obstack_alloc(&env->obst, sizeof(*def)); + memset(def, 0, sizeof(*def)); b->other_end = def; def->other_end = b; @@ -213,10 +228,8 @@ static INLINE border_t *border_add(be_chordal_env_t *env, struct list_head *head */ set_irn_link(irn, def); -#ifdef DEBUG_libfirm b->magic = BORDER_FOURCC; def->magic = BORDER_FOURCC; -#endif } /* @@ -227,9 +240,7 @@ static INLINE border_t *border_add(be_chordal_env_t *env, struct list_head *head else { b = get_irn_link(irn); -#ifdef DEBUG_libfirm assert(b && b->magic == BORDER_FOURCC && "Illegal border encountered"); -#endif } b->pressure = pressure; @@ -237,13 +248,21 @@ static INLINE border_t *border_add(be_chordal_env_t *env, struct list_head *head b->is_real = is_real; b->irn = irn; b->step = step; + check_heads(env); list_add_tail(&b->list, head); + check_heads(env); DBG((dbg, LEVEL_5, "\t\t%s adding %+F, step: %d\n", is_def ? "def" : "use", irn, step)); + return b; } +static INLINE int has_reg_class(const be_chordal_env_t *env, const ir_node *irn) +{ + return arch_irn_has_reg_class(env->arch_env, irn, arch_pos_make_out(0), env->cls); +} + /** * Annotate the register pressure to the nodes and compute * the liveness intervals. @@ -278,6 +297,7 @@ static void pressure(ir_node *block, void *env_ptr) /* Set up the border list in the block info */ head = obstack_alloc(&env->obst, sizeof(*head)); INIT_LIST_HEAD(head); + assert(pmap_get(env->border_heads, block) == NULL); pmap_insert(env->border_heads, block, head); /* @@ -287,7 +307,7 @@ static void pressure(ir_node *block, void *env_ptr) for(irn = pset_first(live_end); irn; irn = pset_next(live_end)) { DBG((dbg, LEVEL_3, "\tMaking live: %+F/%d\n", irn, get_irn_graph_nr(irn))); bitset_set(live, get_irn_graph_nr(irn)); - if(arch_irn_has_reg_class(env->arch_env, irn, 0, cls)) + if(has_reg_class(env, irn)) border_use(irn, step, 0); } ++step; @@ -304,7 +324,7 @@ static void pressure(ir_node *block, void *env_ptr) * If the node defines some value, which can put into a * register of the current class, make a border for it. */ - if(arch_irn_has_reg_class(env->arch_env, irn, 0, cls)) { + if(has_reg_class(env, irn)) { bitset_pos_t elm; int nr = get_irn_graph_nr(irn); @@ -324,7 +344,7 @@ static void pressure(ir_node *block, void *env_ptr) for(i = 0, n = get_irn_arity(irn); i < n; ++i) { ir_node *op = get_irn_n(irn, i); - if(arch_irn_has_reg_class(env->arch_env, op, 0, cls)) { + if(has_reg_class(env, op)) { int nr = get_irn_graph_nr(op); DBG((dbg, LEVEL_4, "\t\tpos: %d, use: %+F\n", i, op)); @@ -343,7 +363,7 @@ static void pressure(ir_node *block, void *env_ptr) * Add initial defs for all values live in. */ for(irn = pset_first(live_in); irn; irn = pset_next(live_in)) { - if(arch_irn_has_reg_class(env->arch_env, irn, 0, cls)) { + if(has_reg_class(env, irn)) { /* Mark the value live in. */ bitset_set(live, get_irn_graph_nr(irn)); @@ -353,8 +373,10 @@ static void pressure(ir_node *block, void *env_ptr) } } - del_pset(live_in); - del_pset(live_end); + check_heads(env); + + del_pset(live_in); + del_pset(live_end); } static void assign(ir_node *block, void *env_ptr) @@ -375,6 +397,9 @@ static void assign(ir_node *block, void *env_ptr) struct list_head *head = get_block_border_head(env, block); pset *live_in = put_live_in(block, pset_new_ptr_default()); + check_heads(env); + + bitset_clear_all(live); bitset_clear_all(colors); bitset_clear_all(in_colors); @@ -392,7 +417,7 @@ static void assign(ir_node *block, void *env_ptr) * allocated before), we have to mark their colors as used also. */ for(irn = pset_first(live_in); irn; irn = pset_next(live_in)) { - if(arch_irn_has_reg_class(env->arch_env, irn, 0, cls)) { + if(has_reg_class(env, irn)) { const arch_register_t *reg = arch_get_irn_register(env->arch_env, irn, 0); int col; @@ -466,7 +491,7 @@ static void assign(ir_node *block, void *env_ptr) void be_ra_chordal_init(void) { dbg = firm_dbg_register(DBG_CHORDAL); - firm_dbg_set_mask(dbg, 0); + firm_dbg_set_mask(dbg, -1); } be_chordal_env_t *be_ra_chordal(ir_graph *irg, diff --git a/ir/be/bechordal_t.h b/ir/be/bechordal_t.h index 45f27c80f..3ec3527ab 100644 --- a/ir/be/bechordal_t.h +++ b/ir/be/bechordal_t.h @@ -32,9 +32,7 @@ * A liveness interval border. */ typedef struct _border_t { -#ifdef DEBUG_libfirm unsigned magic; /**< A magic number for checking. */ -#endif struct list_head list; /**< list head for queuing. */ struct _border_t *other_end; /**< The other end of the border. */ ir_node *irn; /**< The node. */ diff --git a/ir/be/bedupl.c b/ir/be/bedupl.c index 2e8b969ff..8ed7d8dca 100644 --- a/ir/be/bedupl.c +++ b/ir/be/bedupl.c @@ -17,6 +17,7 @@ #include "bearch.h" #include "bera.h" #include "benode_t.h" +#include "besched_t.h" static void eliminate_phi_int_walker(ir_node *irn, void *data) { @@ -35,6 +36,7 @@ static void eliminate_phi_int_walker(ir_node *irn, void *data) if(values_interfere(irn, operand)) { ir_node *copy = new_Copy(env->main_env->node_factory, cls, env->irg, bl, operand); set_irn_n(irn, i, copy); + sched_add_after(sched_last(bl), copy); } } } diff --git a/ir/be/bemain.c b/ir/be/bemain.c index 05e8fae8b..297bce0a6 100644 --- a/ir/be/bemain.c +++ b/ir/be/bemain.c @@ -147,8 +147,6 @@ static void be_main_loop(void) be_eliminate_phi_interferences(&session); dump_ir_block_graph(session.irg, "-prephase"); - be_numbering(irg); - /* Liveness analysis */ be_liveness(irg); @@ -157,12 +155,6 @@ static void be_main_loop(void) copystat_reset(); copystat_collect_irg(irg, env.arch_env); - /* - * Spilling changed the liveness information. - * Recompute it now. - */ - be_liveness(irg); - /* * Verifying the schedule once again cannot hurt. */ @@ -173,6 +165,9 @@ static void be_main_loop(void) be_chordal_env_t *chordal_env; const arch_register_class_t *cls = isa->get_reg_class(j); + be_numbering(irg); + be_liveness(irg); + chordal_env = be_ra_chordal(irg, env.arch_env, cls); #ifdef DUMP_ALLOCATED @@ -186,11 +181,11 @@ static void be_main_loop(void) be_ssa_destruction_check(&session, chordal_env); be_ra_chordal_check(chordal_env); - be_ra_chordal_done(chordal_env); + be_ra_chordal_done(chordal_env); + be_numbering_done(irg); } copystat_dump_pretty(irg); - be_numbering_done(irg); } } diff --git a/ir/be/benode.c b/ir/be/benode.c index 85392494c..26cef9e3b 100644 --- a/ir/be/benode.c +++ b/ir/be/benode.c @@ -124,7 +124,7 @@ ir_node *new_Copy(const be_node_factory_t *factory, ir_graph *irg, ir_node *bl, ir_node *in) { ir_node *ins[1]; - ir_op *op = get_op(factory, cls, node_kind_perm)->op; + ir_op *op = get_op(factory, cls, node_kind_copy)->op; ins[0] = in; diff --git a/ir/be/bera.c b/ir/be/bera.c index ed075676c..ff3ae55b2 100644 --- a/ir/be/bera.c +++ b/ir/be/bera.c @@ -14,14 +14,15 @@ #include "irmode.h" #include "irdom.h" +#include "beutil.h" #include "besched_t.h" #include "belive_t.h" int value_dominates(const ir_node *a, const ir_node *b) { int res = 0; - const ir_node *ba = get_nodes_block(a); - const ir_node *bb = get_nodes_block(a); + const ir_node *ba = get_block(a); + const ir_node *bb = get_block(b); /* * a and b are not in the same block, diff --git a/ir/be/besched.c b/ir/be/besched.c index b3c40e719..63a49b8c3 100644 --- a/ir/be/besched.c +++ b/ir/be/besched.c @@ -99,6 +99,9 @@ int sched_verify(const ir_node *block) sched_foreach(block, irn) n++; + if(n <= 0) + return 1; + save_time_step = malloc(n * sizeof(save_time_step[0])); save_nodes = malloc(n * sizeof(save_nodes[0])); diff --git a/ir/be/besched_t.h b/ir/be/besched_t.h index b82fc55fb..681f0e3a1 100644 --- a/ir/be/besched_t.h +++ b/ir/be/besched_t.h @@ -117,7 +117,8 @@ static INLINE ir_node *_sched_prev(const ir_node *irn) /** * Get the first node in a block schedule. * @param block The block of which to get the schedule. - * @return The first node in the schedule or the block itself if there is node in the schedule. + * @return The first node in the schedule or the block itself + * if there is no node in the schedule. */ static INLINE ir_node *_sched_first(const ir_node *block) { @@ -129,7 +130,7 @@ static INLINE ir_node *_sched_first(const ir_node *block) * Get the last node in a schedule. * @param block The block to get the schedule for. * @return The last ir node in a schedule, or the block itself - * if there is node in the schedule. + * if there is no node in the schedule. */ static INLINE ir_node *_sched_last(const ir_node *block) { -- 2.20.1