X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbeirgmod.c;h=4806a580ff85f584c3b2c001adfbb89ecc7bb197;hb=48f0393daa5d5a14ed7e3e32ee2b090759c9371e;hp=071571689d96e35d6da76f172205c8a9735c2329;hpb=48f893878b07f6e334389ff52abda5cc2adbf179;p=libfirm diff --git a/ir/be/beirgmod.c b/ir/be/beirgmod.c index 071571689..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,15 +260,25 @@ 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)) { ir_node *phi = get_irn_link(curr_bl); - if(!phi) { + if(phi == NULL) { int i, n_preds = get_irn_arity(curr_bl); ir_graph *irg = get_irn_irg(curr_bl); - ir_node **ins = xmalloc(n_preds * sizeof(ins[0])); + ir_node **ins = alloca(n_preds * sizeof(ins[0])); for(i = 0; i < n_preds; ++i) ins[i] = new_r_Bad(irg); @@ -275,16 +287,26 @@ 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); - free(ins); + 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); } - if(phis) + if(phis != NULL) pset_insert_ptr(phis, phi); } @@ -347,13 +369,21 @@ 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); } +#if 0 /** * Remove phis which are not necessary. * During place_phi_functions() phi functions are put on the dominance @@ -366,26 +396,32 @@ static void fix_usages(pset *copies, pset *copy_blocks, pset *phi_blocks, pset * */ static void remove_odd_phis(pset *copies, pset *unused_copies) { - ir_node *irn; + ir_node *irn; - for(irn = pset_first(copies); irn; irn = pset_next(copies)) { - if(is_Phi(irn)) { - int i, n; - int illegal = 0; + for(irn = pset_first(copies); irn; irn = pset_next(copies)) { + if(is_Phi(irn)) { + int i, n; + int illegal = 0; - assert(sched_is_scheduled(irn) && "phi must be scheduled"); - for(i = 0, n = get_irn_arity(irn); i < n && !illegal; ++i) - illegal = get_irn_n(irn, i) == NULL; + assert(sched_is_scheduled(irn) && "phi must be scheduled"); + for(i = 0, n = get_irn_arity(irn); i < n && !illegal; ++i) + illegal = get_irn_n(irn, i) == NULL; - if(illegal) - sched_remove(irn); - } - } + 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(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); } } +#endif void be_ssa_constr_phis_ignore(dom_front_info_t *info, be_lv_t *lv, int n, ir_node *nodes[], pset *phis, pset *ignore_uses) { @@ -578,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); } @@ -595,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); +}