at block BB. */
static bool
-cleanup_control_expr_graph (basic_block bb, gimple_stmt_iterator gsi,
- bool first_p)
+cleanup_control_expr_graph (basic_block bb, gimple_stmt_iterator gsi)
{
edge taken_edge;
bool retval = false;
switch (gimple_code (stmt))
{
case GIMPLE_COND:
- /* During a first iteration on the CFG only remove trivially
- dead edges but mark other conditions for re-evaluation. */
- if (first_p)
- {
- val = const_binop (gimple_cond_code (stmt), boolean_type_node,
- gimple_cond_lhs (stmt),
- gimple_cond_rhs (stmt));
- if (! val)
- bitmap_set_bit (cfgcleanup_altered_bbs, bb->index);
- }
- else
- {
- code_helper rcode;
- tree ops[3] = {};
- if (gimple_simplify (stmt, &rcode, ops, NULL, no_follow_ssa_edges,
- no_follow_ssa_edges)
- && rcode == INTEGER_CST)
- val = ops[0];
- }
+ {
+ code_helper rcode;
+ tree ops[3] = {};
+ if (gimple_simplify (stmt, &rcode, ops, NULL, no_follow_ssa_edges,
+ no_follow_ssa_edges)
+ && rcode == INTEGER_CST)
+ val = ops[0];
+ }
break;
case GIMPLE_SWITCH:
true if anything changes. */
static bool
-cleanup_control_flow_bb (basic_block bb, bool first_p)
+cleanup_control_flow_bb (basic_block bb)
{
gimple_stmt_iterator gsi;
bool retval = false;
|| gimple_code (stmt) == GIMPLE_SWITCH)
{
gcc_checking_assert (gsi_stmt (gsi_last_bb (bb)) == stmt);
- retval |= cleanup_control_expr_graph (bb, gsi, first_p);
+ retval |= cleanup_control_expr_graph (bb, gsi);
}
else if (gimple_code (stmt) == GIMPLE_GOTO
&& TREE_CODE (gimple_goto_dest (stmt)) == ADDR_EXPR
return false;
}
+/* Do cleanup_control_flow_bb in PRE order. */
+
+static bool
+cleanup_control_flow_pre ()
+{
+ bool retval = false;
+
+ auto_vec<edge_iterator, 20> stack (n_basic_blocks_for_fn (cfun) + 1);
+ auto_sbitmap visited (last_basic_block_for_fn (cfun));
+ bitmap_clear (visited);
+
+ stack.quick_push (ei_start (ENTRY_BLOCK_PTR_FOR_FN (cfun)->succs));
+
+ while (! stack.is_empty ())
+ {
+ /* Look at the edge on the top of the stack. */
+ edge_iterator ei = stack.last ();
+ basic_block dest = ei_edge (ei)->dest;
+
+ if (dest != EXIT_BLOCK_PTR_FOR_FN (cfun)
+ && ! bitmap_bit_p (visited, dest->index))
+ {
+ bitmap_set_bit (visited, dest->index);
+ retval |= cleanup_control_flow_bb (dest);
+ if (EDGE_COUNT (dest->succs) > 0)
+ stack.quick_push (ei_start (dest->succs));
+ }
+ else
+ {
+ if (!ei_one_before_end_p (ei))
+ ei_next (&stack.last ());
+ else
+ stack.pop ();
+ }
+ }
+
+ return retval;
+}
+
/* Iterate the cfg cleanups, while anything changes. */
static bool
/* We cannot use FOR_EACH_BB_FN for the BB iterations below
since the basic blocks may get removed. */
- /* Start by iterating over all basic blocks looking for edge removal
- opportunities. Do this first because incoming SSA form may be
- invalid and we want to avoid performing SSA related tasks such
+ /* Start by iterating over all basic blocks in PRE order looking for
+ edge removal opportunities. Do this first because incoming SSA form
+ may be invalid and we want to avoid performing SSA related tasks such
as propgating out a PHI node during BB merging in that state. */
- n = last_basic_block_for_fn (cfun);
- for (i = NUM_FIXED_BLOCKS; i < n; i++)
- {
- bb = BASIC_BLOCK_FOR_FN (cfun, i);
- if (bb)
- retval |= cleanup_control_flow_bb (bb, true);
- }
+ retval |= cleanup_control_flow_pre ();
/* After doing the above SSA form should be valid (or an update SSA
should be required). */
if (!bb)
continue;
- retval |= cleanup_control_flow_bb (bb, false);
+ retval |= cleanup_control_flow_bb (bb);
retval |= cleanup_tree_cfg_bb (bb);
}