X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Freturn.c;h=55bde8a9a774d27b6381fa261bfa91a6af52897f;hb=7ad745a95eae9330603cbac30f9dbe69c52a9536;hp=ad417aa46f72395d8ac044230567bc3a0c0a647f;hpb=429d687f06baeeb63d04750f846d39e55fb62343;p=libfirm diff --git a/ir/opt/return.c b/ir/opt/return.c index ad417aa46..55bde8a9a 100644 --- a/ir/opt/return.c +++ b/ir/opt/return.c @@ -30,6 +30,7 @@ #include "ircons_t.h" #include "irnode_t.h" #include "irgmod.h" +#include "irpass.h" #define set_bit(n) (returns[(n) >> 3] |= 1 << ((n) & 7)) #define get_bit(n) (returns[(n) >> 3] & (1 << ((n) & 7))) @@ -62,8 +63,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); @@ -79,6 +81,17 @@ void normalize_one_return(ir_graph *irg) { 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); @@ -104,7 +117,7 @@ void normalize_one_return(ir_graph *irg) { ir_node *block = get_nodes_block(ret); /* create a new Jmp for every Ret and place the in in */ - in[j] = new_r_Jmp(irg, block); + in[j] = new_r_Jmp(block); /* save the return values and shuffle them */ for (k = 0; k < n_ret_vals; ++k) @@ -137,10 +150,10 @@ void normalize_one_return(ir_graph *irg) { if (first) in[i] = first; else - in[i] = new_r_Phi(irg, block, n_rets, &retvals[j], get_irn_mode(retvals[j])); + in[i] = new_r_Phi(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, block, in[0], n_ret_vals-1, &in[1]); set_irn_in(endbl, last_idx, endbl_in); @@ -154,6 +167,12 @@ void normalize_one_return(ir_graph *irg) { set_irg_loopinfo_inconsistent(irg); } +/* Create a graph pass. */ +ir_graph_pass_t *normalize_one_return_pass(const char *name) +{ + return def_graph_pass(name ? name : "one_ret", normalize_one_return); +} + /** * Check, whether a Return can be moved on block upwards. * @@ -186,7 +205,8 @@ static int can_move_ret(ir_node *ret) { /* check, that predecessors are Jmps */ n = get_Block_n_cfgpreds(retbl); - if (n <= 1) + /* we cannot move above a labeled block, as this might kill the block */ + if (n <= 1 || has_Block_entity(retbl)) return 0; for (i = 0; i < n; ++i) { ir_node *pred = get_Block_cfgpred(retbl, i); @@ -196,7 +216,7 @@ static int can_move_ret(ir_node *ret) { /* simply place a new block here */ ir_graph *irg = get_irn_irg(retbl); ir_node *block = new_r_Block(irg, 1, &pred); - ir_node *jmp = new_r_Jmp(irg, block); + ir_node *jmp = new_r_Jmp(block); set_Block_cfgpred(retbl, i, jmp); } } @@ -269,9 +289,10 @@ void normalize_n_returns(ir_graph *irg) { n_ret_vals = get_irn_arity(list); 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; @@ -294,7 +315,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, new_bl, in[0], n_ret_vals - 1, &in[1]); if (! is_Bad(new_ret)) { /* @@ -359,3 +380,9 @@ void normalize_n_returns(ir_graph *irg) { set_irg_outs_inconsistent(irg); set_irg_loopinfo_inconsistent(current_ir_graph); } + +/* Create a graph pass. */ +ir_graph_pass_t *normalize_n_returns_pass(const char *name) +{ + return def_graph_pass(name ? name : "n_rets", normalize_n_returns); +}