tree-loop-distribution.c (generate_loops_for_partition): Remove inner loop's exit stmt by making it always exit the loop...

* tree-loop-distribution.c (generate_loops_for_partition): Remove
	inner loop's exit stmt by making it always exit the loop, otherwise
	we would generate an infinite empty loop.

	gcc/testsuite
	* gcc.dg/tree-ssa/ldist-27.c: New test.

From-SVN: r253580
This commit is contained in:
Bin Cheng 2017-10-10 09:02:13 +00:00 committed by Bin Cheng
parent 166b87998a
commit efe040bf21
4 changed files with 61 additions and 3 deletions

View File

@ -1,3 +1,9 @@
2017-10-10 Bin Cheng <bin.cheng@arm.com>
* tree-loop-distribution.c (generate_loops_for_partition): Remove
inner loop's exit stmt by making it always exit the loop, otherwise
we would generate an infinite empty loop.
2017-10-10 Bin Cheng <bin.cheng@arm.com>
* tree-vect-loop-manip.c (slpeel_tree_duplicate_loop_to_edge_cfg): Skip

View File

@ -1,3 +1,7 @@
2017-10-10 Bin Cheng <bin.cheng@arm.com>
* gcc.dg/tree-ssa/ldist-27.c: New test.
2017-10-09 Michael Meissner <meissner@linux.vnet.ibm.com>
* gcc.target/powerpc/amo1.c: New test.

View File

@ -0,0 +1,38 @@
/* { dg-do run } */
/* { dg-options "-O3 -ftree-loop-distribute-patterns -fdump-tree-ldist-details" } */
#define M (300)
#define N (200)
struct st
{
double a[M];
double b[M];
double c[M][N];
};
int __attribute__ ((noinline)) foo (struct st *s)
{
int i, j;
for (i = 0; i != M;)
{
s->a[i] = 0.0;
s->b[i] = 1.0;
for (j = 0; 1; ++j)
{
if (j == N) goto L2;
s->c[i][j] = 0.0;
}
L2:
++i;
}
return 0;
}
int main (void)
{
struct st s;
return foo (&s);
}
/* { dg-final { scan-tree-dump "distributed: split to " "ldist" } } */

View File

@ -830,6 +830,10 @@ generate_loops_for_partition (struct loop *loop, partition *partition,
for (i = 0; i < loop->num_nodes; i++)
{
basic_block bb = bbs[i];
edge inner_exit = NULL;
if (loop != bb->loop_father)
inner_exit = single_exit (bb->loop_father);
for (gphi_iterator bsi = gsi_start_phis (bb); !gsi_end_p (bsi);)
{
@ -848,11 +852,17 @@ generate_loops_for_partition (struct loop *loop, partition *partition,
&& !is_gimple_debug (stmt)
&& !bitmap_bit_p (partition->stmts, gimple_uid (stmt)))
{
/* Choose an arbitrary path through the empty CFG part
that this unnecessary control stmt controls. */
/* In distribution of loop nest, if bb is inner loop's exit_bb,
we choose its exit edge/path in order to avoid generating
infinite loop. For all other cases, we choose an arbitrary
path through the empty CFG part that this unnecessary
control stmt controls. */
if (gcond *cond_stmt = dyn_cast <gcond *> (stmt))
{
gimple_cond_make_false (cond_stmt);
if (inner_exit && inner_exit->flags & EDGE_TRUE_VALUE)
gimple_cond_make_true (cond_stmt);
else
gimple_cond_make_false (cond_stmt);
update_stmt (stmt);
}
else if (gimple_code (stmt) == GIMPLE_SWITCH)