aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/tree-cfgcleanup.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.9/gcc/tree-cfgcleanup.c')
-rw-r--r--gcc-4.9/gcc/tree-cfgcleanup.c61
1 files changed, 38 insertions, 23 deletions
diff --git a/gcc-4.9/gcc/tree-cfgcleanup.c b/gcc-4.9/gcc/tree-cfgcleanup.c
index b7882cf67..51b764f81 100644
--- a/gcc-4.9/gcc/tree-cfgcleanup.c
+++ b/gcc-4.9/gcc/tree-cfgcleanup.c
@@ -162,6 +162,23 @@ cleanup_control_expr_graph (basic_block bb, gimple_stmt_iterator gsi)
return retval;
}
+/* Cleanup the GF_CALL_CTRL_ALTERING flag according to
+ to updated gimple_call_flags. */
+
+static void
+cleanup_call_ctrl_altering_flag (gimple bb_end)
+{
+ if (!is_gimple_call (bb_end)
+ || !gimple_call_ctrl_altering_p (bb_end))
+ return;
+
+ int flags = gimple_call_flags (bb_end);
+ if (((flags & (ECF_CONST | ECF_PURE))
+ && !(flags & ECF_LOOPING_CONST_OR_PURE))
+ || (flags & ECF_LEAF))
+ gimple_call_set_ctrl_altering (bb_end, false);
+}
+
/* Try to remove superfluous control structures in basic block BB. Returns
true if anything changes. */
@@ -182,6 +199,9 @@ cleanup_control_flow_bb (basic_block bb)
stmt = gsi_stmt (gsi);
+ /* Try to cleanup ctrl altering flag for call which ends bb. */
+ cleanup_call_ctrl_altering_flag (stmt);
+
if (gimple_code (stmt) == GIMPLE_COND
|| gimple_code (stmt) == GIMPLE_SWITCH)
retval |= cleanup_control_expr_graph (bb, gsi);
@@ -594,30 +614,24 @@ fixup_noreturn_call (gimple stmt)
known not to return, and remove the unreachable code. */
static bool
-split_bbs_on_noreturn_calls (void)
+split_bb_on_noreturn_calls (basic_block bb)
{
bool changed = false;
- gimple stmt;
- basic_block bb;
+ gimple_stmt_iterator gsi;
- /* Detect cases where a mid-block call is now known not to return. */
- if (cfun->gimple_df)
- while (vec_safe_length (MODIFIED_NORETURN_CALLS (cfun)))
- {
- stmt = MODIFIED_NORETURN_CALLS (cfun)->pop ();
- bb = gimple_bb (stmt);
- /* BB might be deleted at this point, so verify first
- BB is present in the cfg. */
- if (bb == NULL
- || bb->index < NUM_FIXED_BLOCKS
- || bb->index >= last_basic_block_for_fn (cfun)
- || BASIC_BLOCK_FOR_FN (cfun, bb->index) != bb
- || !gimple_call_noreturn_p (stmt))
- continue;
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+ if (!is_gimple_call (stmt))
+ continue;
+
+ if (gimple_call_noreturn_p (stmt))
changed |= fixup_noreturn_call (stmt);
- }
+ }
+ if (changed)
+ bitmap_set_bit (cfgcleanup_altered_bbs, bb->index);
return changed;
}
@@ -655,8 +669,6 @@ cleanup_tree_cfg_1 (void)
basic_block bb;
unsigned i, n;
- retval |= split_bbs_on_noreturn_calls ();
-
/* Prepare the worklists of altered blocks. */
cfgcleanup_altered_bbs = BITMAP_ALLOC (NULL);
@@ -672,7 +684,10 @@ cleanup_tree_cfg_1 (void)
{
bb = BASIC_BLOCK_FOR_FN (cfun, i);
if (bb)
- retval |= cleanup_tree_cfg_bb (bb);
+ {
+ retval |= cleanup_tree_cfg_bb (bb);
+ retval |= split_bb_on_noreturn_calls (bb);
+ }
}
/* Now process the altered blocks, as long as any are available. */
@@ -689,9 +704,9 @@ cleanup_tree_cfg_1 (void)
retval |= cleanup_tree_cfg_bb (bb);
- /* Rerun split_bbs_on_noreturn_calls, in case we have altered any noreturn
+ /* Rerun split_bb_on_noreturn_calls, in case we have altered any noreturn
calls. */
- retval |= split_bbs_on_noreturn_calls ();
+ retval |= split_bb_on_noreturn_calls (bb);
}
end_recording_case_labels ();