X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Freturn.c;h=c60b9c12ceec866f97f3b7f541b68515c037661b;hb=8c89e7f37d59bcdcc21d680e1430c712c344938d;hp=02390b3e8c84a29f2fa73295162463c42586e417;hpb=83fc80129c4af047d22c8fb7218aef777a4d8482;p=libfirm diff --git a/ir/opt/return.c b/ir/opt/return.c index 02390b3e8..c60b9c12c 100644 --- a/ir/opt/return.c +++ b/ir/opt/return.c @@ -33,7 +33,7 @@ /* * Normalize the Returns of a graph by creating a new End block * with One Return(Phi). - * This is the prefered input for the if-conversion. + * This is the preferred input for the if-conversion. * * In pseudocode, it means: * @@ -61,6 +61,7 @@ void normalize_one_return(ir_graph *irg) /* look, if we have more than one return */ n = get_Block_n_cfgpreds(endbl); + assert(n > 0); returns = alloca((n + 7) >> 3); memset(returns, 0, (n + 7) >> 3); @@ -120,7 +121,7 @@ void normalize_one_return(ir_graph *irg) * a new Block was added, so dominator, outs and loop are inconsistent, * trouts and callee-state should be still valid */ - set_irg_dom_inconsistent(irg); + set_irg_doms_inconsistent(irg); set_irg_outs_inconsistent(irg); set_irg_loopinfo_state(current_ir_graph, loopinfo_cf_inconsistent); } @@ -169,7 +170,7 @@ static int can_move_ret(ir_node *ret) /* * Normalize the Returns of a graph by moving * the Returns upwards as much as possible. - * This might be prefered for code generation. + * This might be preferred for code generation. * * In pseudocode, it means: * @@ -195,7 +196,12 @@ void normalize_n_returns(ir_graph *irg) ir_node *endbl = get_irg_end_block(irg); ir_node *end; - /* first, link all returns */ + /* + * First, link all returns: + * These must be predecessors of the endblock. + * Place Returns that can be moved on list, all others + * on final. + */ n = get_Block_n_cfgpreds(endbl); for (n_finals = n_rets = i = 0; i < n; ++i) { ir_node *ret = get_Block_cfgpred(endbl, i); @@ -238,15 +244,19 @@ void normalize_n_returns(ir_graph *irg) n = get_Block_n_cfgpreds(block); for (i = 0; i < n; ++i) { - ir_node *jmp = get_Block_cfgpred(block, i); - ir_node *new_bl = get_nodes_block(jmp); - ir_node *new_ret; + ir_node *jmp = get_Block_cfgpred(block, i); + ir_node *new_bl, *new_ret; + + if (get_irn_op(jmp) != op_Jmp) + continue; + + new_bl = get_nodes_block(jmp); /* create the in-array for the new Ret */ for (j = 0; j < n_ret_vals; ++j) { ir_node *pred = get_irn_n(ret, j); - in[j] = is_Phi(pred) ? get_Phi_pred(pred, i) : pred; + in[j] = (is_Phi(pred) && get_nodes_block(pred) == block) ? get_Phi_pred(pred, i) : pred; } new_ret = new_r_Return(irg, new_bl, in[0], n_ret_vals - 1, &in[1]); @@ -270,6 +280,9 @@ void normalize_n_returns(ir_graph *irg) ++n_finals; } } + + /* remove the Jmp, we have placed a Return here */ + exchange(jmp, new_r_Bad(irg)); } /* @@ -300,14 +313,14 @@ void normalize_n_returns(ir_graph *irg) exchange(endbl, new_r_Block(irg, n_finals, in)); - /* the end block is not automatically skiped, so do it here */ + /* the end block is not automatically skipped, so do it here */ set_irg_end_block(irg, skip_Id(get_irg_end_block(irg))); /* Invalidate analysis information: - * Blocks become dead and new Eeturns were deleted, so dominator, outs and loop are inconsistent, + * Blocks become dead and new Returns were deleted, so dominator, outs and loop are inconsistent, * trouts and callee-state should be still valid */ - set_irg_dom_inconsistent(irg); + set_irg_doms_inconsistent(irg); set_irg_outs_inconsistent(irg); set_irg_loopinfo_state(current_ir_graph, loopinfo_cf_inconsistent); }