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:
parent
b898878032
commit
fab7764484
2 changed files with 39 additions and 2 deletions
19
gcc/testsuite/gcc.dg/pr96931.c
Normal file
19
gcc/testsuite/gcc.dg/pr96931.c
Normal 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 ();
|
||||
}
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue