to updated gimple_call_flags. */
static void
-cleanup_call_ctrl_altering_flag (gimple *bb_end)
+cleanup_call_ctrl_altering_flag (basic_block bb, gimple *bb_end)
{
if (!is_gimple_call (bb_end)
|| !gimple_call_ctrl_altering_p (bb_end))
&& !(flags & ECF_LOOPING_CONST_OR_PURE))
|| (flags & ECF_LEAF))
gimple_call_set_ctrl_altering (bb_end, false);
+ else
+ {
+ edge_iterator ei;
+ edge e;
+ bool found = false;
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ if (e->flags & EDGE_FALLTHRU)
+ found = true;
+ else if (e->flags & EDGE_ABNORMAL)
+ {
+ found = false;
+ break;
+ }
+ /* If there's no abnormal edge and a fallthru edge the call
+ isn't control-altering anymore. */
+ if (found)
+ gimple_call_set_ctrl_altering (bb_end, false);
+ }
}
/* Try to remove superfluous control structures in basic block BB. Returns
stmt = gsi_stmt (gsi);
/* Try to cleanup ctrl altering flag for call which ends bb. */
- cleanup_call_ctrl_altering_flag (stmt);
+ cleanup_call_ctrl_altering_flag (bb, stmt);
if (gimple_code (stmt) == GIMPLE_COND
|| gimple_code (stmt) == GIMPLE_SWITCH)