summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBin Cheng <bin.cheng@arm.com>2017-10-10 09:02:13 +0000
committerBin Cheng <amker@gcc.gnu.org>2017-10-10 09:02:13 +0000
commitefe040bf219da9f0aa2298c19909e392c784b3d3 (patch)
tree5c6a56e26a252305e9ecc5ca13b46e9a1ac73b42
parent166b87998a85c8c7d6db923bc7c8370af3665381 (diff)
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
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ldist-27.c38
-rw-r--r--gcc/tree-loop-distribution.c16
4 files changed, 61 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6ce0d73dc47..01482824f71 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,11 @@
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
renaming variables in new preheader if it's deleted.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index eb88b21c431..33a5cf55302 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ldist-27.c b/gcc/testsuite/gcc.dg/tree-ssa/ldist-27.c
new file mode 100644
index 00000000000..3580c65f09b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ldist-27.c
@@ -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" } } */
diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c
index 3db3d6ec21e..999b32ef06c 100644
--- a/gcc/tree-loop-distribution.c
+++ b/gcc/tree-loop-distribution.c
@@ -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)