X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Freturn.c;h=59530d9d29f6b1b8990aa1b855c1114a4395594d;hb=98c8808ee1d34300860bb78185558e1731a99368;hp=cc10e1d724b97b02b8b9efc0804823031b85b5a8;hpb=5180ebb8d84509469546f2528a59d26585652c6f;p=libfirm diff --git a/ir/opt/return.c b/ir/opt/return.c index cc10e1d72..59530d9d2 100644 --- a/ir/opt/return.c +++ b/ir/opt/return.c @@ -94,12 +94,12 @@ void normalize_one_return(ir_graph *irg) /* save the return values and shuffle them */ for (k = 0; k < n_ret_vals; ++k) - retvals[j + k*n_ret_vals] = get_irn_n(ret, k); - - ++j; + retvals[j + k*n_rets] = get_irn_n(ret, k); set_Block_cfgpred(endbl, i, new_r_Bad(irg)); last_idx = i; + + ++j; } } @@ -195,7 +195,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,29 +243,45 @@ 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]); - if (can_move_ret(new_ret)) { - set_irn_link(new_ret, list); - list = new_ret; - ++n_rets; - } - else { - set_irn_link(new_ret, final); - final = new_ret; - ++n_finals; + if (! is_Bad(new_ret)) { + /* + * The newly created node might be bad, if we + * create it in a block with only Bad predecessors. + * In that case ignore this block. + * + * We could even kill the jmp then ... + */ + if (can_move_ret(new_ret)) { + set_irn_link(new_ret, list); + list = new_ret; + ++n_rets; + } + else { + set_irn_link(new_ret, final); + final = new_ret; + ++n_finals; + } } + + /* remove the Jmp, we have placed a Return here */ + exchange(jmp, new_r_Bad(irg)); } /*