aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>2015-11-18 17:33:27 -0700
committerJeff Law <law@gcc.gnu.org>2015-11-18 17:33:27 -0700
commit7d7e7aca3bcded9bccc3ebb4c020287ff21ef102 (patch)
treecdce52b09099f2ec47842495fd8697f9d46bc078 /gcc
parent3ebf5a30cf7ef66b150a6a217636744329fcfe2b (diff)
downloadgcc-7d7e7aca3bcded9bccc3ebb4c020287ff21ef102.zip
gcc-7d7e7aca3bcded9bccc3ebb4c020287ff21ef102.tar.gz
gcc-7d7e7aca3bcded9bccc3ebb4c020287ff21ef102.tar.bz2
[PATCH][PR tree-optimization/68198] Avoid CFG explosion due to threading
PR tree-optimization/68198 * tree-ssa-threadupdate.c (valid_jump_thread_path): Distinguish between threading a multi-way branch and a thread path that contains a multi-way branch. Disallow the case where a path contains a multi-way branch and does not thread a multi-way branch. (thread_through_all_blocks): Update comment. PR tree-optimization/68198 * gcc.dg/tree-ssa/pr66752-3.c: Update expected output for VRP1. * gcc.dg/tree-ssa/pr68198.c: New test. From-SVN: r230586
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr66752-3.c6
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr68198.c43
-rw-r--r--gcc/tree-ssa-threadupdate.c49
5 files changed, 101 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4b788d3..26ddccc 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2015-11-18 Jeff Law <law@redhat.com>
+
+ PR tree-optimization/68198
+ * tree-ssa-threadupdate.c (valid_jump_thread_path): Distinguish
+ between threading a multi-way branch and a thread path that contains
+ a multi-way branch. Disallow the case where a path contains a
+ multi-way branch and does not thread a multi-way branch.
+ (thread_through_all_blocks): Update comment.
+
2015-11-18 Joseph Myers <joseph@codesourcery.com>
PR c/65083
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8109c33..48f536f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2015-11-18 Jeff Law <law@redhat.com>
+
+ PR tree-optimization/68198
+ * gcc.dg/tree-ssa/pr66752-3.c: Update expected output for VRP1.
+ * gcc.dg/tree-ssa/pr68198.c: New test.
+
2015-11-18 Steven G. Kargl <kargl@gcc.gnu.org>
PR fortran/59910
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr66752-3.c b/gcc/testsuite/gcc.dg/tree-ssa/pr66752-3.c
index 577a489..1f27b1a 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr66752-3.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr66752-3.c
@@ -32,8 +32,10 @@ foo (int N, int c, int b, int *a)
pt--;
}
-/* There are 3 FSM jump threading opportunities. */
-/* { dg-final { scan-tree-dump-times "FSM" 3 "vrp1"} } */
+/* There are 3 FSM jump threading opportunities, one of which will
+ get cancelled. */
+/* { dg-final { scan-tree-dump-times "Registering FSM" 3 "vrp1"} } */
+/* { dg-final { scan-tree-dump-times "Cancelling FSM" 1 "vrp1"} } */
/* There should be no assignments or references to FLAG. */
/* { dg-final { scan-tree-dump-not "flag" "optimized"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr68198.c b/gcc/testsuite/gcc.dg/tree-ssa/pr68198.c
new file mode 100644
index 0000000..ddd3c76
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr68198.c
@@ -0,0 +1,43 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-vrp1-details" } */
+
+extern void abort (void);
+
+typedef union tree_node *tree;
+union tree_node
+{
+ int code;
+ tree chain;
+ int omp_code;
+}
+bitmap_head;
+
+extern int c_omp_predetermined_sharing (tree);
+
+tree
+c_finish_omp_clauses (tree clauses)
+{
+ tree c, t, *pc = &clauses;
+ for (pc = &clauses, c = clauses; c; c = *pc)
+ {
+ unsigned char remove = 0;
+ switch (((c->omp_code)))
+ {
+ case 1:
+ if (t->code != 42)
+ remove = 1;
+ switch (c_omp_predetermined_sharing (t))
+ {
+ case 2:
+ abort ();
+ }
+ }
+ if (remove)
+ *pc = c->chain;
+ }
+}
+
+/* There are 3 FSM jump threading opportunities, two of which will
+ get cancelled. */
+/* { dg-final { scan-tree-dump-times "Registering FSM" 3 "vrp1"} } */
+/* { dg-final { scan-tree-dump-times "Cancelling FSM" 2 "vrp1"} } */
diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c
index c527206..3dd0e4f 100644
--- a/gcc/tree-ssa-threadupdate.c
+++ b/gcc/tree-ssa-threadupdate.c
@@ -2370,11 +2370,13 @@ static bool
valid_jump_thread_path (vec<jump_thread_edge *> *path)
{
unsigned len = path->length ();
- bool multiway_branch = false;
+ bool threaded_multiway_branch = false;
+ bool multiway_branch_in_path = false;
bool threaded_through_latch = false;
/* Check that the path is connected and see if there's a multi-way
- branch on the path. */
+ branch on the path and whether or not a multi-way branch
+ is threaded. */
for (unsigned int j = 0; j < len - 1; j++)
{
edge e = (*path)[j]->e;
@@ -2394,7 +2396,12 @@ valid_jump_thread_path (vec<jump_thread_edge *> *path)
threaded_through_latch = true;
gimple *last = last_stmt (e->dest);
- multiway_branch |= (last && gimple_code (last) == GIMPLE_SWITCH);
+ if (j == len - 2)
+ threaded_multiway_branch
+ |= (last && gimple_code (last) == GIMPLE_SWITCH);
+ else
+ multiway_branch_in_path
+ |= (last && gimple_code (last) == GIMPLE_SWITCH);
}
/* If we are trying to thread through the loop latch to a block in the
@@ -2402,8 +2409,33 @@ valid_jump_thread_path (vec<jump_thread_edge *> *path)
irreducible loop. We avoid that unless the jump thread has a multi-way
branch, in which case we have deemed it worth losing other
loop optimizations later if we can eliminate the multi-way branch. */
- if (!multiway_branch && threaded_through_latch)
- return false;
+ if (!threaded_multiway_branch && threaded_through_latch)
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file,
+ "Thread through latch without threading a multiway "
+ "branch.\n");
+ dump_jump_thread_path (dump_file, *path, false);
+ }
+ return false;
+ }
+
+ /* When there is a multi-way branch on the path, then threading can
+ explode the CFG due to duplicating the edges for that multi-way
+ branch. So like above, only allow a multi-way branch on the path
+ if we actually thread a multi-way branch. */
+ if (!threaded_multiway_branch && multiway_branch_in_path)
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file,
+ "Thread through multiway branch without threading "
+ "a multiway branch.\n");
+ dump_jump_thread_path (dump_file, *path, false);
+ }
+ return false;
+ }
return true;
}
@@ -2494,11 +2526,8 @@ thread_through_all_blocks (bool may_peel_loop_headers)
/* Do not jump-thread twice from the same block. */
if (bitmap_bit_p (threaded_blocks, entry->src->index)
- /* Verify that the jump thread path is still valid: a
- previous jump-thread may have changed the CFG, and
- invalidated the current path or the requested jump
- thread might create irreducible loops which should
- generally be avoided. */
+ /* We may not want to realize this jump thread path
+ for various reasons. So check it first. */
|| !valid_jump_thread_path (path))
{
/* Remove invalid FSM jump-thread paths. */