aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-11.c1
-rw-r--r--gcc/tree-ssa-threadupdate.c33
4 files changed, 33 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3613a68..6a7d988 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2015-11-02 Jeff Law <jeff@redhat.com>
+
+ * tree-ssa-threadupdate.c (valid_jump_thread_path): Also detect
+ cases where the loop latch edge is in the middle of an FSM
+ path.
+
2015-11-03 Tom de Vries <tom@codesourcery.com>
* tree-ssa-structalias.c (make_restrict_var_constraints): Rename to ...
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index a86920a..3dc4edc 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2015-11-02 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/ssa-thread-11.c: Verify that we do not have
+ irreducible loops in the CFG.
+
2015-11-02 Alan Lawrence <alan.lawrence@arm.com>
Revert:
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-11.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-11.c
index 6a076e1..a729f56 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-11.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-11.c
@@ -1,5 +1,6 @@
/* { dg-do compile { target { ! { logical_op_short_circuit || { m68k*-*-* mep*-*-* bfin*-*-* v850*-*-* moxie*-*-* m32c*-*-* fr30*-*-* mcore*-*-* frv-*-* h8300-*-* m32r-*-* mn10300-*-* msp430-*-* pdp11-*-* rl78-*-* rx-*-* vax-*-*} } } } } */
/* { dg-options "-O2 -fdump-tree-vrp2-details" } */
+/* { dg-final { scan-tree-dump-not "IRREDUCIBLE_LOOP" "vrp2" } } */
/* { dg-final { scan-tree-dump "FSM" "vrp2" } } */
void abort (void);
diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c
index 511433a..68650e5 100644
--- a/gcc/tree-ssa-threadupdate.c
+++ b/gcc/tree-ssa-threadupdate.c
@@ -2547,29 +2547,38 @@ valid_jump_thread_path (vec<jump_thread_edge *> *path)
{
unsigned len = path->length ();
bool multiway_branch = false;
+ bool threaded_through_latch = false;
/* Check that the path is connected and see if there's a multi-way
branch on the path. */
for (unsigned int j = 0; j < len - 1; j++)
{
- if ((*path)[j]->e->dest != (*path)[j+1]->e->src)
+ edge e = (*path)[j]->e;
+ struct loop *loop = e->dest->loop_father;
+
+ if (e->dest != (*path)[j+1]->e->src)
return false;
- gimple *last = last_stmt ((*path)[j]->e->dest);
+
+ /* If we're threading through the loop latch back into the
+ same loop and the destination does not dominate the loop
+ latch, then this thread would create an irreducible loop. */
+ if (loop->latch
+ && loop_latch_edge (loop) == e
+ && loop == path->last()->e->dest->loop_father
+ && (determine_bb_domination_status (loop, path->last ()->e->dest)
+ == DOMST_NONDOMINATING))
+ threaded_through_latch = true;
+
+ gimple *last = last_stmt (e->dest);
multiway_branch |= (last && gimple_code (last) == GIMPLE_SWITCH);
}
- /* If we are trying to thread the loop latch to a block that does
- not dominate the loop latch, then that will create an irreducible
- loop. We avoid that unless the jump thread has a multi-way
+ /* If we are trying to thread through the loop latch to a block in the
+ loop that does not dominate the loop latch, then that will create an
+ 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. */
- edge e = (*path)[0]->e;
- struct loop *loop = e->dest->loop_father;
- if (!multiway_branch
- && loop->latch
- && loop_latch_edge (loop) == e
- && (determine_bb_domination_status (loop, path->last ()->e->dest)
- == DOMST_NONDOMINATING))
+ if (!multiway_branch && threaded_through_latch)
return false;
return true;