]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Try to resolve paths in threader without looking further back.
authorAldy Hernandez <aldyh@redhat.com>
Wed, 20 Oct 2021 05:29:25 +0000 (07:29 +0200)
committerAldy Hernandez <aldyh@redhat.com>
Tue, 26 Oct 2021 06:20:10 +0000 (08:20 +0200)
Sometimes we can solve a candidate path without having to recurse
further back.  This can mostly happen in fully resolving mode, because
we can ask the ranger what the range on entry to the path is, but
there's no reason this can't always apply.  This one-liner removes
the fully-resolving restriction.

I'm tickled pink to see how many things we now get quite early
in the compilation.  I actually had to disable jump threading entirely
for a few tests because the early threader was catching things
disturbingly early.  Also, as Richi predicted, I saw a lot of pre-VRP
cleanups happening.

I was going to commit this as obvious, but I think the test changes
merit discussion.

We've been playing games with gcc.dg/tree-ssa/ssa-thread-11.c for quite
some time.  Every time a threading pass gets smarter, we push the
check further down the pipeline.  We've officially run out of dumb
threading passes to disable ;-).  In the last year we've gone up from a
handful of threads, to 34 threads with the current combination of
options.  I doubt this is testing anything useful anymore, so I've
removed it.

Similarly for gcc.dg/tree-ssa/ssa-dom-thread-4.c.  We used to thread 3
jump threads, but they were disallowed because of loop rotation.  Then
we started catching more jump threads in VRP2 threading so we tested
there.  With this patch though, we triple the number of threads found
from 11 to 31.  I believe this test has outlived its usefulness, and
I've removed it.  Note that even though we have these outrageous
possibilities for this test, the block copier ultimately chops them
down (23 survive though).

Tested on x86-64 Linux.

gcc/ChangeLog:

* tree-ssa-threadbackward.c (back_threader::find_paths_to_names):
Always try to resolve path without looking back.
* tree-ssa-threadupdate.c (dump_jump_thread): Indidicate whether
edge is a back edge.

gcc/testsuite/ChangeLog:

* gcc.dg/graphite/scop-dsyr2k-2.c: Adjust for jump threading changes.
* gcc.dg/graphite/scop-dsyr2k.c: Same.
* gcc.dg/graphite/scop-dsyrk-2.c: Same.
* gcc.dg/graphite/scop-dsyrk.c: Same.
* gcc.dg/tree-ssa/pr20701.c: Same.
* gcc.dg/tree-ssa/pr20702.c: Same.
* gcc.dg/tree-ssa/pr21086.c: Same.
* gcc.dg/tree-ssa/pr25382.c: Same.
* gcc.dg/tree-ssa/pr58480.c: Same.
* gcc.dg/tree-ssa/ssa-vrp-thread-1.c: Same.
* gcc.dg/tree-ssa/vrp08.c: Same.
* gcc.dg/tree-ssa/vrp55.c: Same.
* gcc.dg/tree-ssa/ssa-dom-thread-7.c: Same.
* gcc.dg/tree-ssa/ssa-dom-thread-4.c: Removed.
* gcc.dg/tree-ssa/ssa-thread-11.c: Removed.
* gcc.dg/uninit-pr89230-1.c: xfail.

19 files changed:
gcc/testsuite/gcc.dg/graphite/scop-dsyr2k-2.c
gcc/testsuite/gcc.dg/graphite/scop-dsyr2k.c
gcc/testsuite/gcc.dg/graphite/scop-dsyrk-2.c
gcc/testsuite/gcc.dg/graphite/scop-dsyrk.c
gcc/testsuite/gcc.dg/tree-ssa/pr20701.c
gcc/testsuite/gcc.dg/tree-ssa/pr20702.c
gcc/testsuite/gcc.dg/tree-ssa/pr21086.c
gcc/testsuite/gcc.dg/tree-ssa/pr25382.c
gcc/testsuite/gcc.dg/tree-ssa/pr58480.c
gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-4.c [deleted file]
gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c
gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-11.c [deleted file]
gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-backedge.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/ssa-vrp-thread-1.c
gcc/testsuite/gcc.dg/tree-ssa/vrp08.c
gcc/testsuite/gcc.dg/tree-ssa/vrp55.c
gcc/testsuite/gcc.dg/uninit-pr89230-1.c
gcc/tree-ssa-threadbackward.c
gcc/tree-ssa-threadupdate.c

index 06aa19a85775b6838d9bc35d5d83d514f3b7d648..42e23fc157e594c9826309b10798b600a2a5d800 100644 (file)
@@ -1,4 +1,5 @@
 /* { dg-require-effective-target size32plus } */
+/* { dg-additional-options "-fno-thread-jumps" } */
 #define NMAX 3000
 
 static double a[NMAX][NMAX], b[NMAX][NMAX], c[NMAX][NMAX];
index 41c91b97b578da5153566ed2dbc9c47cbbd2fc0d..feb99358ac7fa1d422781d87fd0a6f47adee220d 100644 (file)
@@ -1,4 +1,5 @@
 /* { dg-require-effective-target size32plus } */
+/* { dg-additional-options "-fno-thread-jumps" } */
 #define NMAX 3000
 
 static double a[NMAX][NMAX], b[NMAX][NMAX], c[NMAX][NMAX];
index 5622dce47986c71b1d9d12bcf6c2778e3d207ffc..935ade3fb6ecc3578a4d8e67fddef66e5c8c9f75 100644 (file)
@@ -1,4 +1,5 @@
 /* { dg-require-effective-target size32plus } */
+/* { dg-additional-options "-fno-thread-jumps" } */
 #define NMAX 3000
 #define MEASURE_TIME 1
 
index e01a517be115ffc189614f2dbfdfacc28591c51d..5c65e406589093e3489449c431ad4e1677504647 100644 (file)
@@ -1,4 +1,5 @@
 /* { dg-require-effective-target size32plus } */
+/* { dg-additional-options "-fno-thread-jumps" } */
 #define NMAX 3000
 #define MEASURE_TIME 1
 
index 2f914589e32922650afa1adfcd9bffa563af529c..496c42567334b539d7127429dd741703ec9b90f4 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-vrp1 -fno-early-inlining -fdelete-null-pointer-checks" } */
+/* { dg-options "-O2 -fdump-tree-vrp1 -fno-early-inlining -fdelete-null-pointer-checks -fdisable-tree-thread1" } */
 
 typedef struct {
   int code;
index c896857748c5a2ff81849b5a75968f52e2ed9bb3..81129674d8af33bc16155ee13aa61633a5b67e73 100644 (file)
@@ -4,7 +4,7 @@
    immediate successors of the basic block.  */
 
 /* { dg-do compile } */
-/* { dg-options "-O2 -fno-tree-dominator-opts -fdisable-tree-evrp -fdump-tree-vrp1-details -fdelete-null-pointer-checks" } */
+/* { dg-options "-O2 -fno-thread-jumps -fdisable-tree-evrp -fdump-tree-vrp1-details -fdelete-null-pointer-checks" } */
 
 extern void bar (int);
 
index aadd53e2237bf1625a0b57b560babe3ba4bdef6a..9b93d39d4e440a6c46ebfd79ebb2c7c1bf74dd5e 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdisable-tree-evrp -fdump-tree-vrp1 -fdump-tree-dce2 -fdelete-null-pointer-checks" } */
+/* { dg-options "-O2 -fno-thread-jumps -fdisable-tree-evrp -fdump-tree-vrp1 -fdump-tree-dce2 -fdelete-null-pointer-checks" } */
 
 int
 foo (int *p)
index d74765551c2a137aeb4db7d3e009f2bff8d157f4..8634c0a78952812313fdababbb1c8169727151f7 100644 (file)
@@ -3,7 +3,7 @@
    Check that VRP now gets ranges from BIT_AND_EXPRs.  */
 
 /* { dg-do compile } */
-/* { dg-options "-O2 -fno-tree-ccp -fdisable-tree-evrp -fdump-tree-vrp1" } */
+/* { dg-options "-O2 -fno-thread-jumps -fno-tree-ccp -fdisable-tree-evrp -fdump-tree-vrp1" } */
 
 int
 foo (int a)
index 42898e72d4e129e86d0c9b0beb0be812354363b2..f11623b7c6b61c446d609f1c9e903b04c152c0ae 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile { target { ! keeps_null_pointer_checks } } } */
-/* { dg-options "-O2 -fdisable-tree-evrp -fdump-tree-vrp1 -fdelete-null-pointer-checks" } */
+/* { dg-options "-O2 -fno-thread-jumps -fdisable-tree-evrp -fdump-tree-vrp1 -fdelete-null-pointer-checks" } */
 
 extern void eliminate (void);
 extern void* f1 (void *a, void *b) __attribute__((nonnull));
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-4.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-4.c
deleted file mode 100644 (file)
index 9cd4635..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/* { dg-do compile } */ 
-/* { dg-options "-O2 -fdump-tree-vrp-thread2-details -fdump-tree-dom2-details -std=gnu89 --param logical-op-non-short-circuit=1" } */
-struct bitmap_head_def;
-typedef struct bitmap_head_def *bitmap;
-typedef const struct bitmap_head_def *const_bitmap;
-typedef unsigned long BITMAP_WORD;
-typedef struct bitmap_element_def
-{
-  struct bitmap_element_def *next;
-  unsigned int indx;
-} bitmap_element;
-
-
-
-
-
-
-
-
-
-unsigned char
-bitmap_ior_and_compl (bitmap dst, const_bitmap a, const_bitmap b,
-                     const_bitmap kill)
-{
-  unsigned char changed = 0;
-
-  bitmap_element *dst_elt;
-  const bitmap_element *a_elt, *b_elt, *kill_elt, *dst_prev;
-
-  while (a_elt || b_elt)
-    {
-      unsigned char new_element = 0;
-
-      if (b_elt)
-       while (kill_elt && kill_elt->indx < b_elt->indx)
-         kill_elt = kill_elt->next;
-
-      if (b_elt && kill_elt && kill_elt->indx == b_elt->indx
-         && (!a_elt || a_elt->indx >= b_elt->indx))
-       {
-         bitmap_element tmp_elt;
-         unsigned ix;
-
-         BITMAP_WORD ior = 0;
-
-             changed = bitmap_elt_ior (dst, dst_elt, dst_prev,
-                                       a_elt, &tmp_elt, changed);
-
-       }
-
-    }
-
-
-  return changed;
-}
-/* We used to catch 3 jump threads in vrp-thread1, but they all
-   rotated the loop, so they were disallowed.  This in turn created
-   other opportunities for the other threaders which result in the the
-   post-loop threader (vrp-thread2) catching more.  */
-/* { dg-final { scan-tree-dump-times "Registering jump thread" 5 "vrp-thread2" } } */
index 1da00a691c8e33a5419b54308c7657b77006a250..ed252b97b24c23270442ea304c9ff8b66c55358c 100644 (file)
@@ -1,7 +1,7 @@
 /* { dg-do compile } */
 /* { dg-options "-O2 -fdump-tree-thread1-stats -fdump-tree-thread2-stats -fdump-tree-dom2-stats -fdump-tree-thread3-stats -fdump-tree-dom3-stats -fdump-tree-vrp2-stats -fno-guess-branch-probability" } */
 
-/* { dg-final { scan-tree-dump "Jumps threaded: 12"  "thread3" } } */
+/* { dg-final { scan-tree-dump "Jumps threaded: 11" "thread3" } } */
 /* { dg-final { scan-tree-dump-not "Jumps threaded"  "dom2" } } */
 
 /* aarch64 has the highest CASE_VALUES_THRESHOLD in GCC.  It's high enough
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-11.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-11.c
deleted file mode 100644 (file)
index 672a54e..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-vrp2-details --param logical-op-non-short-circuit=1" } */
-/* { dg-additional-options "-fdisable-tree-ethread -fdisable-tree-thread1 -fdisable-tree-thread2" } */
-/* { dg-final { scan-tree-dump-not "IRREDUCIBLE_LOOP" "vrp2" } } */
-
-void abort (void);
-typedef struct bitmap_head_def *bitmap;
-typedef const struct bitmap_head_def *const_bitmap;
-typedef struct bitmap_obstack
-{
-  struct bitmap_obstack *next;
-  unsigned int indx;
-}
-bitmap_element;
-typedef struct bitmap_head_def
-{
-  bitmap_element *first;
-}
-bitmap_head;
-static __inline__ unsigned char
-bitmap_elt_ior (bitmap dst, bitmap_element * dst_elt,
-               bitmap_element * dst_prev, const bitmap_element * a_elt,
-               const bitmap_element * b_elt)
-{
-  ((void) (!(a_elt || b_elt) ? abort (), 0 : 0));
-}
-
-unsigned char
-bitmap_ior_and_compl (bitmap dst, const_bitmap a, const_bitmap b,
-                     const_bitmap kill)
-{
-  bitmap_element *dst_elt = dst->first;
-  const bitmap_element *a_elt = a->first;
-  const bitmap_element *b_elt = b->first;
-  const bitmap_element *kill_elt = kill->first;
-  bitmap_element *dst_prev = ((void *) 0);
-  while (a_elt || b_elt)
-    {
-      if (b_elt && kill_elt && kill_elt->indx == b_elt->indx
-         && (!a_elt || a_elt->indx >= b_elt->indx));
-      else
-       {
-         bitmap_elt_ior (dst, dst_elt, dst_prev, a_elt, b_elt);
-         if (a_elt && b_elt && a_elt->indx == b_elt->indx)
-           ;
-         else if (a_elt && (!b_elt || a_elt->indx <= b_elt->indx))
-           a_elt = a_elt->next;
-       }
-    }
-}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-backedge.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-backedge.c
new file mode 100644 (file)
index 0000000..890a0ee
--- /dev/null
@@ -0,0 +1,32 @@
+// { dg-do compile }
+// { dg-options "-O2 -fdisable-tree-ethread -fdisable-tree-thread1 -fdisable-tree-thread2 -fno-tree-dominator-opts -fdump-tree-thread3-details" }
+
+// Test that we can thread jumps across the backedge of a loop through
+// the switch statement to a particular case.
+//
+// Just in case, we disable all the jump threaders before loop
+// optimizations to make sure we get a clean stab at this.
+
+int foo (unsigned int x, int s)
+{
+  while (s != 999)
+    {
+      switch (s)
+       {
+       case 0:
+         if (x)
+           s = 1;
+         break;
+       case 1:
+         if (x)
+           s = 999;
+         break;
+       default:
+         break;
+       }
+      x++;
+    }
+  return s;
+}
+
+// { dg-final { scan-tree-dump "Registering jump thread:.*normal \\(back\\)" "thread3" } }
index 86d07ef9bdba8e775f5a2eadb64c72e087531283..f3ca140bd26eacdeb2e02c15c8f0ae42304392b4 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-vrp-thread1-details -fdelete-null-pointer-checks" } */
+/* { dg-options "-O2 -fdump-tree-thread1-details -fdelete-null-pointer-checks" } */
 /* { dg-skip-if "" keeps_null_pointer_checks } */
 
 void oof (void);
@@ -29,5 +29,5 @@ build_omp_regions_1 (basic_block bb, struct omp_region *parent,
 
 /* ARM Cortex-M defined LOGICAL_OP_NON_SHORT_CIRCUIT to false,
    so skip below test.  */
-/* { dg-final { scan-tree-dump-times "Threaded" 1 "vrp-thread1" { target { ! arm_cortex_m } } } } */
+/* { dg-final { scan-tree-dump-times "Registering jump thread" 1 "thread1" { target { ! arm_cortex_m } } } } */
 
index c2da30b4b68d1acc110af2d030a7539f4999c7ac..2c6742b76c76fcf446c8a41c0fadb265a94421ff 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fno-tree-fre -fdisable-tree-evrp -fdump-tree-vrp1-details -fdelete-null-pointer-checks" } */
+/* { dg-options "-O2 -fno-tree-fre -fdisable-tree-evrp -fdump-tree-vrp1-details -fdisable-tree-thread1 -fdelete-null-pointer-checks" } */
 
 /* Compile with -fno-tree-fre -O2 to prevent CSEing *p.  */
 int
index a478a6981ac0dd68a723e1d3732606b525de701d..0ef57d935e4a0f6dd8137abe7141a437b59d4e73 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-vrp-thread1-blocks-vops-details -fdelete-null-pointer-checks" } */
+/* { dg-options "-O2 -fdump-tree-ethread-details -fdelete-null-pointer-checks" } */
 
 void arf (void);
 
@@ -12,6 +12,6 @@ fu (char *p, int x)
     arf ();
 }
 
-/* { dg-final { scan-tree-dump-times "Threaded jump" 1 "vrp-thread1" { target { ! keeps_null_pointer_checks } } } } */
-/* { dg-final { scan-tree-dump-times "Threaded jump" 0 "vrp-thread1" { target {   keeps_null_pointer_checks } } } } */
+/* { dg-final { scan-tree-dump-times "Registering jump thread" 1 "ethread" { target { ! keeps_null_pointer_checks } } } } */
+/* { dg-final { scan-tree-dump-times "Registering jump thread" 0 "ethread" { target {   keeps_null_pointer_checks } } } } */
 
index 1c07c4f6d78b51db39b83ac89204722f29572787..dfc87a5b1a0b27e9ff9413d178bce7a8413426e0 100644 (file)
@@ -8,7 +8,8 @@ struct S { int i, j; };
 
 int g (void)
 {
-  struct S *p = f (), *q;
+  struct S *p = f ();
+  struct S *q; // { dg-bogus "may be used uninitialized" "uninitialized" { xfail *-*-* } }
 
   if (p->i || !(q = f ()) || p->j != q->i)
    {
index d94e3b962db415bb071b771c0331be5aa127aa5d..edb396b3d6fcabdb14a2b00e63d4fc5e99fb1670 100644 (file)
@@ -374,8 +374,8 @@ back_threader::find_paths_to_names (basic_block bb, bitmap interesting)
       return false;
     }
 
-  // Try to resolve the path with nothing but ranger knowledge.
-  if (m_resolve && m_path.length () > 1 && maybe_register_path ())
+  // Try to resolve the path without looking back.
+  if (m_path.length () > 1 && maybe_register_path ())
     {
       m_path.pop ();
       m_visited_bbs.remove (bb);
index 8e6f043bb44d4a34c42335445c20110d3da155b5..8aac733ac2515b874a33f0b4d27016380af09329 100644 (file)
@@ -253,6 +253,9 @@ dump_jump_thread_path (FILE *dump_file,
        default:
          gcc_unreachable ();
        }
+
+      if ((path[i]->e->flags & EDGE_DFS_BACK) != 0)
+       fprintf (dump_file, " (back)");
     }
   fprintf (dump_file, "; \n");
 }