X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Freturn.c;h=ebfb2f3c3e5f6df3fc7e07dd662fdc3b6e549e0b;hb=ba4016c7aa0437c72ef7323ecea585828bdc038b;hp=ce580eeec8768c34b1613226ba5b948dde0c5e89;hpb=f3b8448f1f42a265342841e97df6f0212f5f898f;p=libfirm diff --git a/ir/opt/return.c b/ir/opt/return.c index ce580eeec..ebfb2f3c3 100644 --- a/ir/opt/return.c +++ b/ir/opt/return.c @@ -23,16 +23,13 @@ * @author Michael Beck * @version $Id$ */ -#ifdef HAVE_CONFIG_H #include "config.h" -#endif #include "iroptimize.h" #include "irgraph_t.h" #include "ircons_t.h" #include "irnode_t.h" #include "irgmod.h" -#include "xmalloc.h" #define set_bit(n) (returns[(n) >> 3] |= 1 << ((n) & 7)) #define get_bit(n) (returns[(n) >> 3] & (1 << ((n) & 7))) @@ -65,8 +62,9 @@ void normalize_one_return(ir_graph *irg) { int i, j, k, n, last_idx, n_rets, n_ret_vals = -1; unsigned char *returns; ir_node **in, **retvals, **endbl_in; - ir_node *block; + int filter_dbgi = 0; + dbg_info *combined_dbgi = NULL; /* look, if we have more than one return */ n = get_Block_n_cfgpreds(endbl); @@ -76,13 +74,23 @@ void normalize_one_return(ir_graph *irg) { return; } - returns = alloca((n + 7) >> 3); - memset(returns, 0, (n + 7) >> 3); + returns = ALLOCANZ(unsigned char, (n + 7) >> 3); for (n_rets = i = 0; i < n; ++i) { ir_node *node = get_Block_cfgpred(endbl, i); if (is_Return(node)) { + dbg_info *dbgi = get_irn_dbg_info(node); + + if (dbgi != NULL && dbgi != combined_dbgi) { + if (filter_dbgi) { + combined_dbgi = NULL; + } else { + combined_dbgi = dbgi; + filter_dbgi = 1; + } + } + ++n_rets; set_bit(i); @@ -96,9 +104,9 @@ void normalize_one_return(ir_graph *irg) { if (n_rets <= 1) return; - in = alloca(sizeof(*in) * IMAX(n_rets, n_ret_vals)); - retvals = alloca(sizeof(*retvals) * n_rets * n_ret_vals); - endbl_in = alloca(sizeof(*endbl_in) * n); + in = ALLOCAN(ir_node*, IMAX(n_rets, n_ret_vals)); + retvals = ALLOCAN(ir_node*, n_rets * n_ret_vals); + endbl_in = ALLOCAN(ir_node*, n); last_idx = 0; for (j = i = 0; i < n; ++i) { @@ -144,7 +152,7 @@ void normalize_one_return(ir_graph *irg) { in[i] = new_r_Phi(irg, block, n_rets, &retvals[j], get_irn_mode(retvals[j])); } - endbl_in[last_idx++] = new_r_Return(irg, block, in[0], n_ret_vals-1, &in[1]); + endbl_in[last_idx++] = new_rd_Return(combined_dbgi, irg, block, in[0], n_ret_vals-1, &in[1]); set_irn_in(endbl, last_idx, endbl_in); @@ -190,6 +198,9 @@ static int can_move_ret(ir_node *ret) { /* check, that predecessors are Jmps */ n = get_Block_n_cfgpreds(retbl); + /* we cannot move above a labeled block, as this might kill the block */ + if (n <= 1 || has_Block_label(retbl)) + return 0; for (i = 0; i < n; ++i) { ir_node *pred = get_Block_cfgpred(retbl, i); @@ -202,9 +213,7 @@ static int can_move_ret(ir_node *ret) { set_Block_cfgpred(retbl, i, jmp); } } - - /* if we have 0 control flow predecessors, we cannot move :-) */ - return n > 0; + return 1; } /* @@ -271,11 +280,12 @@ void normalize_n_returns(ir_graph *irg) { */ end = get_irg_end(irg); n_ret_vals = get_irn_arity(list); - in = alloca(sizeof(*in) * n_ret_vals); + in = ALLOCAN(ir_node*, n_ret_vals); while (list) { - ir_node *ret = list; - ir_node *block = get_nodes_block(ret); - ir_node *phiM; + ir_node *ret = list; + ir_node *block = get_nodes_block(ret); + dbg_info *dbgi = get_irn_dbg_info(ret); + ir_node *phiM; list = get_irn_link(ret); --n_rets; @@ -298,7 +308,7 @@ void normalize_n_returns(ir_graph *irg) { 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]); + new_ret = new_rd_Return(dbgi, irg, new_bl, in[0], n_ret_vals - 1, &in[1]); if (! is_Bad(new_ret)) { /* @@ -344,7 +354,7 @@ void normalize_n_returns(ir_graph *irg) { * Last step: Create a new endblock, with all nodes on the final * list as predecessors. */ - in = alloca(sizeof(*in) * n_finals); + in = ALLOCAN(ir_node*, n_finals); for (i = 0; final; ++i, final = get_irn_link(final)) in[i] = final;