diff options
author | Aldy Hernandez <aldyh@redhat.com> | 2021-10-04 09:47:02 +0200 |
---|---|---|
committer | Aldy Hernandez <aldyh@redhat.com> | 2021-10-20 07:07:35 +0200 |
commit | d8edfadfc7a9795b65177a50ce44fd348858e844 (patch) | |
tree | ee7768875b95baef113668261d2b54b00ecee722 /gcc/tree-ssa-threadupdate.c | |
parent | f36240f8c835d792f788b6724e272fc0a4a4f26f (diff) | |
download | gcc-d8edfadfc7a9795b65177a50ce44fd348858e844.zip gcc-d8edfadfc7a9795b65177a50ce44fd348858e844.tar.gz gcc-d8edfadfc7a9795b65177a50ce44fd348858e844.tar.bz2 |
Disallow loop rotation and loop header crossing in jump threaders.
There is a lot of fall-out from this patch, as there were many threading
tests that assumed the restrictions introduced by this patch were valid.
Some tests have merely shifted the threading to after loop
optimizations, but others ended up with no threading opportunities at
all. Surprisingly some tests ended up with more total threads. It was
a crapshoot all around.
On a postive note, there are 6 tests that no longer XFAIL, and one
guality test which now passes.
I felt a bit queasy about such a fundamental change wrt threading, so I
ran it through my callgrind test harness (.ii files from a bootstrap).
There was no change in overall compilation, DOM, or the VRP threaders.
However, there was a slight increase of 1.63% in the backward threader.
I'm pretty sure we could reduce this if we incorporated the restrictions
into their profitability code. This way we could stop the search when
we ran into one of these restrictions. Not sure it's worth it at this
point.
Tested on x86-64 Linux.
Co-authored-by: Richard Biener <rguenther@suse.de>
gcc/ChangeLog:
* tree-ssa-threadupdate.c (cancel_thread): Dump threading reason
on the same line as the threading cancellation.
(jt_path_registry::cancel_invalid_paths): Avoid rotating loops.
Avoid threading through loop headers where the path remains in the
loop.
libgomp/ChangeLog:
* testsuite/libgomp.graphite/force-parallel-5.c: Remove xfail.
gcc/testsuite/ChangeLog:
* gcc.dg/Warray-bounds-87.c: Remove xfail.
* gcc.dg/analyzer/pr94851-2.c: Remove xfail.
* gcc.dg/graphite/pr69728.c: Remove xfail.
* gcc.dg/graphite/scop-dsyr2k.c: Remove xfail.
* gcc.dg/graphite/scop-dsyrk.c: Remove xfail.
* gcc.dg/shrink-wrap-loop.c: Remove xfail.
* gcc.dg/loop-8.c: Adjust for new threading restrictions.
* gcc.dg/tree-ssa/ifc-20040816-1.c: Same.
* gcc.dg/tree-ssa/pr21559.c: Same.
* gcc.dg/tree-ssa/pr59597.c: Same.
* gcc.dg/tree-ssa/pr71437.c: Same.
* gcc.dg/tree-ssa/pr77445-2.c: Same.
* gcc.dg/tree-ssa/ssa-dom-thread-4.c: Same.
* gcc.dg/tree-ssa/ssa-dom-thread-7.c: Same.
* gcc.dg/vect/bb-slp-16.c: Same.
* gcc.dg/tree-ssa/ssa-dom-thread-6.c: Remove.
* gcc.dg/tree-ssa/ssa-dom-thread-18.c: Remove.
* gcc.dg/tree-ssa/ssa-dom-thread-2a.c: Remove.
* gcc.dg/tree-ssa/ssa-thread-invalid.c: New test.
Diffstat (limited to 'gcc/tree-ssa-threadupdate.c')
-rw-r--r-- | gcc/tree-ssa-threadupdate.c | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c index 32ce1e3..293836c 100644 --- a/gcc/tree-ssa-threadupdate.c +++ b/gcc/tree-ssa-threadupdate.c @@ -278,7 +278,7 @@ cancel_thread (vec<jump_thread_edge *> *path, const char *reason = NULL) if (dump_file && (dump_flags & TDF_DETAILS)) { if (reason) - fprintf (dump_file, "%s:\n", reason); + fprintf (dump_file, "%s: ", reason); dump_jump_thread_path (dump_file, *path, false); fprintf (dump_file, "\n"); @@ -2771,6 +2771,7 @@ jt_path_registry::cancel_invalid_paths (vec<jump_thread_edge *> &path) bool seen_latch = false; int loops_crossed = 0; bool crossed_latch = false; + bool crossed_loop_header = false; // Use ->dest here instead of ->src to ignore the first block. The // first block is allowed to be in a different loop, since it'll be // redirected. See similar comment in profitable_path_p: "we don't @@ -2804,6 +2805,14 @@ jt_path_registry::cancel_invalid_paths (vec<jump_thread_edge *> &path) ++loops_crossed; } + // ?? Avoid threading through loop headers that remain in the + // loop, as such threadings tend to create sub-loops which + // _might_ be OK ??. + if (e->dest->loop_father->header == e->dest + && !flow_loop_nested_p (exit->dest->loop_father, + e->dest->loop_father)) + crossed_loop_header = true; + if (flag_checking && !m_backedge_threads) gcc_assert ((path[i]->e->flags & EDGE_DFS_BACK) == 0); } @@ -2829,6 +2838,21 @@ jt_path_registry::cancel_invalid_paths (vec<jump_thread_edge *> &path) cancel_thread (&path, "Path crosses loops"); return true; } + // The path should either start and end in the same loop or exit the + // loop it starts in but never enter a loop. This also catches + // creating irreducible loops, not only rotation. + if (entry->src->loop_father != exit->dest->loop_father + && !flow_loop_nested_p (exit->src->loop_father, + entry->dest->loop_father)) + { + cancel_thread (&path, "Path rotates loop"); + return true; + } + if (crossed_loop_header) + { + cancel_thread (&path, "Path crosses loop header but does not exit it"); + return true; + } return false; } |