tree-optimization/96931 - clear ctrl-altering flag more aggressively

The testcase shows that we fail to clear gimple_call_ctrl_altering_p
when the last abnormal edge goes away, causing an edge insert to
a loop header edge when we have preheaders to split the edge
unnecessarily.

The following addresses this by more aggressively clearing the
flag in cleanup_call_ctrl_altering_flag.

2020-09-04  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/96931
	* tree-cfgcleanup.c (cleanup_call_ctrl_altering_flag): If
	there's a fallthru edge and no abnormal edge the call is
	no longer control-altering.
	(cleanup_control_flow_bb): Pass down the BB to
	cleanup_call_ctrl_altering_flag.

	* gcc.dg/pr96931.c: New testcase.
This commit is contained in:
Richard Biener 2020-09-04 12:18:38 +02:00
parent b898878032
commit fab7764484
2 changed files with 39 additions and 2 deletions

View file

@ -0,0 +1,19 @@
/* { dg-do compile } */
/* { dg-options "-O1 -fpredictive-commoning -fno-tree-loop-im" } */
int bl;
void
p3 (void);
void __attribute__ ((returns_twice))
ie (void)
{
p3 ();
bl = 0;
for (;;)
++bl;
ie ();
}

View file

@ -209,7 +209,7 @@ cleanup_control_expr_graph (basic_block bb, gimple_stmt_iterator gsi)
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))
@ -220,6 +220,24 @@ cleanup_call_ctrl_altering_flag (gimple *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
@ -243,7 +261,7 @@ 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);
cleanup_call_ctrl_altering_flag (bb, stmt);
if (gimple_code (stmt) == GIMPLE_COND
|| gimple_code (stmt) == GIMPLE_SWITCH)