summaryrefslogtreecommitdiff
path: root/gcc/tree-cfgcleanup.c
diff options
context:
space:
mode:
authorwmi <wmi@138bc75d-0d04-0410-961f-82ee72b054a4>2014-08-20 16:47:12 +0000
committerwmi <wmi@138bc75d-0d04-0410-961f-82ee72b054a4>2014-08-20 16:47:12 +0000
commitc1e02247a09ea2142ec772dce1edb9ca27fca546 (patch)
treefac128b3e612dcf536a8553f9c12e52dce5cc4cd /gcc/tree-cfgcleanup.c
parent64f3d828ae6402c43abae532540f69dfc2e1879c (diff)
downloadgcc-c1e02247a09ea2142ec772dce1edb9ca27fca546.tar.gz
2014-08-20 Martin Jambor <mjambor@suse.cz>
Wei Mi <wmi@google.com> PR ipa/60449 PR middle-end/61776 * tree-ssa-operands.c (update_stmt_operands): Remove MODIFIED_NORETURN_CALLS. * tree-cfgcleanup.c (cleanup_call_ctrl_altering_flag): New func. (cleanup_control_flow_bb): Use cleanup_call_ctrl_altering_flag. (split_bb_on_noreturn_calls): Renamed from split_bbs_on_noreturn_calls. (cleanup_tree_cfg_1): Use split_bb_on_noreturn_calls. * tree-ssanames.h: Remove MODIFIED_NORETURN_CALLS. * gimple.h (enum gf_mask): Add GF_CALL_CTRL_ALTERING. (gimple_call_set_ctrl_altering): New func. (gimple_call_ctrl_altering_p): Ditto. * tree-cfg.c (gimple_call_initialize_ctrl_altering): Ditto. (make_blocks): Use gimple_call_initialize_ctrl_altering. (is_ctrl_altering_stmt): Use gimple_call_ctrl_altering_p. (execute_fixup_cfg): Use gimple_call_ctrl_altering_p and remove MODIFIED_NORETURN_CALLS. 2014-08-20 Martin Jambor <mjambor@suse.cz> Wei Mi <wmi@google.com> PR ipa/60449 PR middle-end/61776 * testsuite/gcc.dg/lto/pr60449_1.c: New test. * testsuite/gcc.dg/lto/pr60449_0.c: New test. * testsuite/gcc.dg/pr61776.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@214233 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-cfgcleanup.c')
-rw-r--r--gcc/tree-cfgcleanup.c61
1 files changed, 38 insertions, 23 deletions
diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c
index 2b6927e0437..a66ec6e7537 100644
--- a/gcc/tree-cfgcleanup.c
+++ b/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 ();