From: Sebastian Hack Date: Thu, 16 Jun 2005 16:08:39 +0000 (+0000) Subject: Some fixes X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=82bfe0eb17ee7d899987c8b54370c5b892a2333e;p=libfirm Some fixes --- diff --git a/ir/be/beirgmod.c b/ir/be/beirgmod.c index 03d760be6..4e10e9a92 100644 --- a/ir/be/beirgmod.c +++ b/ir/be/beirgmod.c @@ -17,6 +17,7 @@ #include "irmode_t.h" #include "irdom_t.h" #include "iredges_t.h" +#include "irgopt.h" #include "be_t.h" #include "bearch.h" @@ -148,18 +149,13 @@ static void place_phi_functions(ir_node *orig, pset *copies, * Allocate an array for all blocks where the copies and the original * value were defined. */ - int n_orig_blocks = pset_count(copy_blocks) + 1; + int n_orig_blocks = pset_count(copy_blocks); ir_node **orig_blocks = malloc(n_orig_blocks * sizeof(orig_blocks[0])); - /* - * Fill the array of definition blocks. - */ - orig_blocks[0] = get_nodes_block(orig); - /* * Fill the worklist queue and the rest of the orig blocks array. */ - for(it = pset_first(copies), i = 1; it; it = pset_next(copies)) { + for(it = pset_first(copies), i = 0; it; it = pset_next(copies)) { ir_node *copy_block = get_nodes_block(it); if(!block_dominates(orig_block, copy_block)) { @@ -167,18 +163,17 @@ static void place_phi_functions(ir_node *orig, pset *copies, && "The block of the copy must be dominated by the block of the value"); } - pdeq_putr(worklist, it); + pdeq_putr(worklist, copy_block); orig_blocks[i++] = copy_block; } while(!pdeq_empty(worklist)) { - ir_node *irn = pdeq_getl(worklist); - ir_node *bl = get_nodes_block(irn); + ir_node *bl = pdeq_getl(worklist); ir_node *y; - int n_preds = get_irn_arity(bl); pset *df = be_get_dominance_frontier(df_info, bl); for(y = pset_first(df); y; y = pset_next(df)) { + int n_preds = get_irn_arity(y); if(!pset_find_ptr(phi_blocks, y)) { ir_node *phi; @@ -190,11 +185,12 @@ static void place_phi_functions(ir_node *orig, pset *copies, */ ins = realloc(ins, n_preds * sizeof(ins[0])); for(i = 0; i < n_preds; ++i) - ins[0] = new_Unknown(mode); + ins[i] = orig; /* Insert phi node */ - phi = new_r_Phi(irg, bl, n_preds, ins, mode); - DBG((dbg, LEVEL_2, " inserting phi in block %+F\n", bl)); + phi = new_r_Phi(irg, y, n_preds, ins, mode); + DBG((dbg, LEVEL_2, " inserting phi %+F with %d args in block %+F\n", + phi, n_preds, bl)); /* * The phi node itself is also a copy of the original @@ -267,14 +263,19 @@ static ir_node *search_def(ir_node *usage, int pos, pset *copies, pset *copy_blo * If the usage is in a phi node, search the copy in the * predecessor denoted by pos. */ - if(is_Phi(usage)) + if(is_Phi(usage)) { curr_bl = get_nodes_block(get_irn_n(curr_bl, pos)); + start_irn = sched_last(curr_bl); + } + + else { + start_irn = sched_prev(usage); + } /* * Traverse the dominance tree upwards from the * predecessor block of the usage. */ - start_irn = usage; while(curr_bl != NULL) { /* @@ -328,7 +329,6 @@ static void fix_usages(ir_node *orig, pset *copies, pset *copy_blocks) foreach_out_edge(orig, edge) { outs[i].irn = get_edge_src_irn(edge); outs[i].pos = get_edge_src_pos(edge); - DBG((dbg, LEVEL_2, " %+F(%d)\n", outs[i].irn, outs[i].pos)); i += 1; } @@ -341,6 +341,8 @@ static void fix_usages(ir_node *orig, pset *copies, pset *copy_blocks) int pos = outs[i].pos; def = search_def(irn, pos, copies, copy_blocks); + DBG((dbg, LEVEL_2, " %+F(%d) -> %+F\n", irn, pos, def)); + if(def != NULL) set_irn_n(irn, pos, def); } @@ -353,12 +355,17 @@ void be_introduce_copies(dom_front_info_t *info, ir_node *orig, int n, ir_node * pset *copies = pset_new_ptr(2 * n); pset *copy_blocks = pset_new_ptr(2 * n); int save_optimize = get_optimize(); - int i; + int save_normalize = get_opt_normalize(); firm_dbg_module_t *dbg = DBG_MODULE; + int i; firm_dbg_set_mask(dbg, -1); DBG((dbg, LEVEL_1, "Introducing following copies of %+F\n", orig)); + /* Fill the sets. */ + pset_insert_ptr(copies, orig); + pset_insert_ptr(copy_blocks, get_nodes_block(orig)); + for(i = 0; i < n; ++i) { DBG((dbg, LEVEL_1, " %+F in block %+F\n", copy_nodes[i], get_nodes_block(copy_nodes[i]))); @@ -371,6 +378,7 @@ void be_introduce_copies(dom_front_info_t *info, ir_node *orig, int n, ir_node * * disappear. */ set_optimize(0); + set_opt_normalize(0); /* * Place the phi functions and reroute the usages. @@ -380,6 +388,7 @@ void be_introduce_copies(dom_front_info_t *info, ir_node *orig, int n, ir_node * /* reset the optimizations */ set_optimize(save_optimize); + set_opt_normalize(save_normalize); del_pset(copies); del_pset(copy_blocks); diff --git a/ir/be/bessadestr.c b/ir/be/bessadestr.c index 26e70f73d..c989af90e 100644 --- a/ir/be/bessadestr.c +++ b/ir/be/bessadestr.c @@ -16,6 +16,8 @@ #include "irnode.h" #include "iredges_t.h" #include "irdump.h" +#include "irprintf.h" + #include "be_t.h" #include "beutil.h" #include "bechordal_t.h" @@ -30,13 +32,13 @@ * Maps blocks to perm nodes inserted during phi destruction. */ typedef struct _block2perm_t { - ir_node *block, *perm; + ir_node *block, *perm; } block2perm_t; static int set_cmp_b2p(const void *x, const void *y, size_t size) { - const block2perm_t *b1 = x; - const block2perm_t *b2 = y; - return b1->block != b2->block; + const block2perm_t *b1 = x; + const block2perm_t *b2 = y; + return b1->block != b2->block; } #define is_Branch(irn) (arch_irn_classify(arch_env, irn) == arch_irn_class_branch) @@ -45,27 +47,27 @@ static int set_cmp_b2p(const void *x, const void *y, size_t size) { #define is_curr_reg_class(irn) (get_reg_cls(p) == chordal_env->cls) static ir_node *get_perm(be_main_session_env_t *session, be_chordal_env_t *chordal_env, ir_node *block) { - block2perm_t find, *found; - ir_node *p; - set *b2p = chordal_env->data; - const arch_env_t *arch_env = chordal_env->arch_env; - - /* iff needed insert perm node */ - - /* .if the perm is in the pset return it */ - find.block = block; - find.perm = NULL; - found = set_insert(b2p, &find, sizeof(find), HASH_PTR(find.block)); - if (found->perm) - return found->perm; - - /* .else look for a perm of right register class in the schedule */ - p = sched_last(find.block); - while (!is_Block(p) && (is_Branch(p) || (is_Perm(p) && !is_curr_reg_class(p)))) - p = sched_prev(p); - - /* if we haven't found a perm of the right register class create a new one */ - if (! (is_Perm(p) && is_curr_reg_class(p))) + block2perm_t find, *found; + ir_node *p; + set *b2p = chordal_env->data; + const arch_env_t *arch_env = chordal_env->arch_env; + + /* iff needed insert perm node */ + + /* .if the perm is in the pset return it */ + find.block = block; + find.perm = NULL; + found = set_insert(b2p, &find, sizeof(find), HASH_PTR(find.block)); + if (found->perm) + return found->perm; + + /* .else look for a perm of right register class in the schedule */ + p = sched_last(find.block); + while (!is_Block(p) && (is_Branch(p) || (is_Perm(p) && !is_curr_reg_class(p)))) + p = sched_prev(p); + + /* if we haven't found a perm of the right register class create a new one */ + if (! (is_Perm(p) && is_curr_reg_class(p))) p = insert_Perm_after(session, chordal_env->cls, p); /* insert perm into pset */ @@ -80,7 +82,7 @@ static ir_node *get_perm(be_main_session_env_t *session, be_chordal_env_t *chord */ static void adjust_arguments(be_main_session_env_t *session, be_chordal_env_t *chordal_env, const ir_node *phi) { int i, max; - ir_node *arg, *perm, *proj; + ir_node *arg; const arch_register_t *phi_reg, *arg_reg, *proj_reg; const ir_edge_t *edge; ir_node *phi_block = get_nodes_block(phi); @@ -94,44 +96,56 @@ static void adjust_arguments(be_main_session_env_t *session, be_chordal_env_t *c arg_reg = get_reg(arg); /* if registers don't match ...*/ if (phi_reg != arg_reg) { + ir_node *perm; + perm = get_perm(session, chordal_env, get_nodes_block(get_irn_n(phi_block, i))); - /* adjust assigned registers for the projs */ + + /* + * Look at the projs of the perm. + * Find the one which corresponds to the phi argument + * This is done via the proj number: If + * the i-th argument of the perm is the old Phi + * argument, then the Proj with number i is the + * one we want. + */ foreach_out_edge(perm, edge) { - proj = get_edge_src_irn(edge); - proj_reg = get_reg(proj); - if (proj_reg == arg_reg) - set_reg(proj, phi_reg); - else if (proj_reg == phi_reg) - set_reg(proj, arg_reg); + ir_node *proj = get_edge_src_irn(edge); + int proj_nr = get_Proj_proj(proj); + + if(get_irn_n(perm, proj_nr) == arg) { + assert(get_reg(proj) == NULL); + set_reg(proj, phi_reg); + } } } } } static void checker(be_chordal_env_t *chordal_env) { - pmap_entry *pme; - int i, max; - - /* iterate over all blocks */ - pmap_foreach(chordal_env->border_heads, pme) { - border_t *curr; - struct list_head *head = pme->value; - - /* iterate over the first ops in the block */ - list_for_each_entry_reverse(border_t, curr, head, list) - if (curr->is_def && curr->is_real && is_Phi(curr->irn)) { - const arch_register_t *phi_reg, *arg_reg; - if (!is_Phi(curr->irn)) - break; - - phi_reg = get_reg(curr->irn); - /* iterate over all args of phi */ - for(i=0, max=get_irn_arity(curr->irn); iirn, i)); - assert(phi_reg == arg_reg && "WTF? You can do it better!?"); - } - } - } + pmap_entry *pme; + int i, max; + + /* iterate over all blocks */ + pmap_foreach(chordal_env->border_heads, pme) { + border_t *curr; + struct list_head *head = pme->value; + + /* iterate over the first ops in the block */ + list_for_each_entry_reverse(border_t, curr, head, list) + if (curr->is_def && curr->is_real && is_Phi(curr->irn)) { + const arch_register_t *phi_reg, *arg_reg; + if (!is_Phi(curr->irn)) + break; + + phi_reg = get_reg(curr->irn); + /* iterate over all args of phi */ + for(i=0, max=get_irn_arity(curr->irn); iirn, i)); + if(phi_reg != arg_reg) + ir_printf("register differ: %s %s\n", phi_reg->name, arg_reg->name); + } + } + } } void be_ssa_destruction(be_main_session_env_t *session, be_chordal_env_t *chordal_env) {