/*
- * 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.
*
#include "config.h"
#endif
+#include "iroptimize.h"
#include "irgraph_t.h"
#include "ircons_t.h"
#include "irnode_t.h"
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
* 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);
/* 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;
}
/*
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;
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);
set_irn_link(new_ret, list);
list = new_ret;
++n_rets;
- }
- else {
+ } else {
set_irn_link(new_ret, final);
final = new_ret;
++n_finals;
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);
}