X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbeirgmod.c;h=4806a580ff85f584c3b2c001adfbb89ecc7bb197;hb=48f0393daa5d5a14ed7e3e32ee2b090759c9371e;hp=a9981971d55834fc83d4d7b0d3318800991c5a01;hpb=fd1a2c6ca51ee2b6ff838581b79cf7a3c4553e36;p=libfirm diff --git a/ir/be/beirgmod.c b/ir/be/beirgmod.c index a9981971d..4806a580f 100644 --- a/ir/be/beirgmod.c +++ b/ir/be/beirgmod.c @@ -243,10 +243,12 @@ static ir_node *search_def(ir_node *usage, int pos, pset *copies, pset *copy_blo * predecessor block of the usage. */ while(curr_bl != NULL) { + ir_node *phim; /* * If this block contains a copy, search the block - * instruction by instruction. + * instruction by instruction. If nothing is found + * search for a not scheduled PhiM. */ if(pset_find_ptr(copy_blocks, curr_bl)) { ir_node *irn; @@ -258,6 +260,16 @@ static ir_node *search_def(ir_node *usage, int pos, pset *copies, pset *copy_blo if(pset_find_ptr(copies, irn)) return irn; } + + for(phim = pset_first(copies); phim; phim = pset_next(copies)) { + if(!is_Phi(phim) || !(get_irn_mode(phim) == mode_M)) + continue; + + if(get_nodes_block(phim) == curr_bl) { + pset_break(copies); + return phim; + } + } } if(pset_find_ptr(phi_blocks, curr_bl)) { @@ -275,10 +287,21 @@ static ir_node *search_def(ir_node *usage, int pos, pset *copies, pset *copy_blo DBG((dbg, LEVEL_2, "\tcreating phi %+F in %+F\n", phi, curr_bl)); set_irn_link(curr_bl, phi); - sched_add_after(curr_bl, phi); + if(mode != mode_M) + sched_add_after(curr_bl, phi); for(i = 0; i < n_preds; ++i) { ir_node *arg = search_def(phi, i, copies, copy_blocks, phis, phi_blocks, mode); + if(arg == NULL) { + ir_node *irn; + + ir_fprintf(stderr, "no definition found for %+F at position %d\nCopies: ", phi, i); + for(irn = pset_first(copies); irn; irn = pset_next(copies)) { + ir_fprintf(stderr, "%+F ", irn); + } + ir_fprintf(stderr, "\n\n"); + assert(arg && "no definition found"); + } DBG((dbg, LEVEL_2, "\t\t%+F(%d) -> %+F\n", phi, i, arg)); set_irn_n(phi, i, arg); } @@ -346,8 +369,15 @@ static void fix_usages(pset *copies, pset *copy_blocks, pset *phi_blocks, pset * def = search_def(irn, pos, copies, copy_blocks, phis, phi_blocks, mode); DBG((dbg, LEVEL_2, "\t%+F(%d) -> %+F\n", irn, pos, def)); - if(def != NULL) - set_irn_n(irn, pos, def); + if(def == NULL) { + ir_fprintf(stderr, "no definition found for %+F at position %d\nCopies: ", irn, pos); + for(irn = pset_first(copies); irn; irn = pset_next(copies)) { + ir_fprintf(stderr, "%+F ", irn); + } + ir_fprintf(stderr, "\n\n"); + assert(def && "no definition found"); + } + set_irn_n(irn, pos, def); } obstack_free(&obst, NULL); @@ -377,12 +407,17 @@ static void remove_odd_phis(pset *copies, pset *unused_copies) for(i = 0, n = get_irn_arity(irn); i < n && !illegal; ++i) illegal = get_irn_n(irn, i) == NULL; - if(illegal) + if(illegal) { + for(i = 0, n = get_irn_arity(irn); i < n; ++i) + set_irn_n(irn, i, new_Bad()); sched_remove(irn); + } } } for(irn = pset_first(unused_copies); irn; irn = pset_next(unused_copies)) { + for(i = 0, n = get_irn_arity(irn); i < n; ++i) + set_irn_n(irn, i, new_Bad()); sched_remove(irn); } } @@ -579,7 +614,6 @@ static void elr_split_walker(ir_node *bl, void *data) for(insn = be_scan_insn(&ie, sched_first(bl)); !is_Block(insn->irn); insn = be_scan_insn(&ie, insn->next_insn)) { ir_node *pred = sched_prev(insn->irn); - ir_printf("curr: %+F next: %+F, prev: %+F\n", insn->irn, insn->next_insn, pred); if(!is_Block(pred) && !is_Phi(insn->irn)) insert_Perm_after(aenv, cenv->lv, cenv->cls, cenv->dom_front, insn->irn); } @@ -596,3 +630,52 @@ void extreme_liverange_splitting(struct _be_chordal_env_t *cenv) be_liveness_recompute(cenv->lv); obstack_free(&c.obst, NULL); } + +static void remove_empty_block(ir_node *block, void *data) { + ir_graph *irg; + const ir_edge_t *edge, *next; + ir_node *node; + ir_node *jump = NULL; + + assert(is_Block(block)); + + if (get_Block_n_cfgpreds(block) != 1) + return; + + sched_foreach(block, node) { + if (! is_Jmp(node)) + return; + if (jump != NULL) { + /* we should never have 2 jumps in a block */ + assert(0 && "We should never have 2 jumps in a block"); + return; + } + jump = node; + } + + if (jump == NULL) + return; + + node = get_Block_cfgpred(block, 0); + foreach_out_edge_safe(jump, edge, next) { + ir_node *block = get_edge_src_irn(edge); + int pos = get_edge_src_pos(edge); + + set_irn_n(block, pos, node); + } + + set_Block_cfgpred(block, 0, new_Bad()); + sched_remove(jump); + + irg = get_irn_irg(block); + set_irg_doms_inconsistent(irg); + set_irg_extblk_inconsistent(irg); + set_irg_outs_inconsistent(irg); +} + +/** + * removes basic blocks that just contain a jump instruction + */ +void be_remove_empty_blocks(ir_graph *irg) { + irg_block_walk_graph(irg, remove_empty_block, NULL, NULL); +}