X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Freturn.c;h=49088db2901bce02196e7c66e2c330d9ff4a3afa;hb=44faeb9742640d3498eb4482f98eb1255607c4d6;hp=9cffb1a1866de1b1b96e846bd552d492ecc2489e;hpb=fa9649a9766ace19d23acf80c0ef6791390b0dea;p=libfirm diff --git a/ir/opt/return.c b/ir/opt/return.c index 9cffb1a18..49088db29 100644 --- a/ir/opt/return.c +++ b/ir/opt/return.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1995-2007 University of Karlsruhe. All right reserved. + * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved. * * This file is part of libFirm. * @@ -27,6 +27,7 @@ #include "config.h" #endif +#include "iroptimize.h" #include "irgraph_t.h" #include "ircons_t.h" #include "irnode_t.h" @@ -154,11 +155,11 @@ void normalize_one_return(ir_graph *irg) { set_irg_doms_inconsistent(irg); set_irg_outs_inconsistent(irg); set_irg_extblk_inconsistent(irg); - set_irg_loopinfo_state(irg, loopinfo_cf_inconsistent); + set_irg_loopinfo_inconsistent(irg); } /** - * check, whether a Ret can be moved on block upwards. + * Check, whether a Return can be moved on block upwards. * * In a block with a Return, all live nodes must be linked * with the Return, otherwise they are dead (because the Return leaves @@ -171,7 +172,7 @@ void normalize_one_return(ir_graph *irg) { * block of the Return block as well. * * All predecessors of the Return block must be Jmp's of course, or we - * cannot move it up, so we check this either. + * cannot move it up, so we add blocks if needed. */ static int can_move_ret(ir_node *ret) { ir_node *retbl = get_nodes_block(ret); @@ -189,12 +190,21 @@ static int can_move_ret(ir_node *ret) { /* check, that predecessors are Jmps */ n = get_Block_n_cfgpreds(retbl); - for (i = 0; i < n; ++i) - if (get_irn_op(get_Block_cfgpred(retbl, i)) != op_Jmp) - return 0; - - /* if we have 0 control flow predecessors, we cannot move :-) */ - return n > 0; + if (n <= 1) + return 0; + for (i = 0; i < n; ++i) { + ir_node *pred = get_Block_cfgpred(retbl, i); + + pred = skip_Tuple(pred); + if (! is_Jmp(pred) && !is_Bad(pred)) { + /* 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); + set_Block_cfgpred(retbl, i, jmp); + } + } + return 1; } /* @@ -237,9 +247,9 @@ void normalize_n_returns(ir_graph *irg) { if (is_Return(ret) && can_move_ret(ret)) { /* - * Ok, all conditions met, we can move this Return, put it - * on our work list. - */ + * Ok, all conditions met, we can move this Return, put it + * on our work list. + */ set_irn_link(ret, list); list = ret; ++n_rets; @@ -275,12 +285,13 @@ void normalize_n_returns(ir_graph *irg) { ir_node *jmp = get_Block_cfgpred(block, i); ir_node *new_bl, *new_ret; - if (get_irn_op(jmp) != op_Jmp) + if (is_Bad(jmp)) continue; + assert(is_Jmp(jmp)); new_bl = get_nodes_block(jmp); - /* create the in-array for the new Ret */ + /* create the in-array for the new Return */ for (j = 0; j < n_ret_vals; ++j) { ir_node *pred = get_irn_n(ret, j); @@ -301,8 +312,7 @@ void normalize_n_returns(ir_graph *irg) { set_irn_link(new_ret, list); list = new_ret; ++n_rets; - } - else { + } else { set_irn_link(new_ret, final); final = new_ret; ++n_finals; @@ -351,5 +361,5 @@ void normalize_n_returns(ir_graph *irg) { set_irg_doms_inconsistent(irg); set_irg_extblk_inconsistent(irg); /* may not be needed */ set_irg_outs_inconsistent(irg); - set_irg_loopinfo_state(current_ir_graph, loopinfo_cf_inconsistent); + set_irg_loopinfo_inconsistent(current_ir_graph); }