]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
propagate partial equivs in the cache.
authorAndrew MacLeod <amacleod@redhat.com>
Wed, 5 Oct 2022 14:42:07 +0000 (10:42 -0400)
committerAndrew MacLeod <amacleod@redhat.com>
Thu, 13 Oct 2022 15:28:47 +0000 (11:28 -0400)
Adjust on-entry cache propagation to look for and propagate both full
and partial equivalences.

gcc/
PR tree-optimization/102540
PR tree-optimization/102872
* gimple-range-cache.cc (ranger_cache::fill_block_cache):
Handle partial equivs.
(ranger_cache::range_from_dom): Cleanup dump output.

gcc/testsuite/
* gcc.dg/pr102540.c: New.
* gcc.dg/pr102872.c: New.

gcc/gimple-range-cache.cc
gcc/testsuite/gcc.dg/pr102540.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr102872.c [new file with mode: 0644]

index 8c80ba6cd1421a7b001c056ddfa0fb458f27879c..0b9aa3639c5d5ca0528fdf48f4465627bce80b3e 100644 (file)
@@ -1189,8 +1189,9 @@ ranger_cache::fill_block_cache (tree name, basic_block bb, basic_block def_bb)
 {
   edge_iterator ei;
   edge e;
-  Value_Range block_result (TREE_TYPE (name));
-  Value_Range undefined (TREE_TYPE (name));
+  tree type = TREE_TYPE (name);
+  Value_Range block_result (type);
+  Value_Range undefined (type);
 
   // At this point we shouldn't be looking at the def, entry or exit block.
   gcc_checking_assert (bb != def_bb && bb != ENTRY_BLOCK_PTR_FOR_FN (cfun) &&
@@ -1221,10 +1222,16 @@ ranger_cache::fill_block_cache (tree name, basic_block bb, basic_block def_bb)
       if (m_oracle)
        {
          tree equiv_name;
-         FOR_EACH_EQUIVALENCE (m_oracle, bb, name, equiv_name)
+         relation_kind rel;
+         int prec = TYPE_PRECISION (type);
+         FOR_EACH_PARTIAL_AND_FULL_EQUIV (m_oracle, bb, name, equiv_name, rel)
            {
              basic_block equiv_bb = gimple_bb (SSA_NAME_DEF_STMT (equiv_name));
 
+             // Ignore partial equivs that are smaller than this object.
+             if (rel != VREL_EQ && prec > pe_to_bits (rel))
+               continue;
+
              // Check if the equiv has any ranges calculated.
              if (!m_gori.has_edge_range_p (equiv_name))
                continue;
@@ -1234,16 +1241,32 @@ ranger_cache::fill_block_cache (tree name, basic_block bb, basic_block def_bb)
                  (equiv_bb && !dominated_by_p (CDI_DOMINATORS, bb, equiv_bb)))
                continue;
 
+             if (DEBUG_RANGE_CACHE)
+               {
+                 if (rel == VREL_EQ)
+                   fprintf (dump_file, "Checking Equivalence (");
+                 else
+                   fprintf (dump_file, "Checking Partial equiv (");
+                 print_relation (dump_file, rel);
+                 fprintf (dump_file, ") ");
+                 print_generic_expr (dump_file, equiv_name, TDF_SLIM);
+                 fprintf (dump_file, "\n");
+               }
              Value_Range equiv_range (TREE_TYPE (equiv_name));
              if (range_from_dom (equiv_range, equiv_name, bb, RFD_READ_ONLY))
                {
+                 if (rel != VREL_EQ)
+                   range_cast (equiv_range, type);
                  if (block_result.intersect (equiv_range))
                    {
                      if (DEBUG_RANGE_CACHE)
                        {
-                         fprintf (dump_file, "Equivalence update! :  ");
+                         if (rel == VREL_EQ)
+                           fprintf (dump_file, "Equivalence update! :  ");
+                         else
+                           fprintf (dump_file, "Partial equiv update! :  ");
                          print_generic_expr (dump_file, equiv_name, TDF_SLIM);
-                         fprintf (dump_file, "had range  :  ");
+                         fprintf (dump_file, " has range  :  ");
                          equiv_range.dump (dump_file);
                          fprintf (dump_file, " refining range to :");
                          block_result.dump (dump_file);
@@ -1458,7 +1481,9 @@ ranger_cache::range_from_dom (vrange &r, tree name, basic_block start_bb,
 
   if (DEBUG_RANGE_CACHE)
     {
-      fprintf (dump_file, "CACHE: BB %d DOM query, found ", start_bb->index);
+      fprintf (dump_file, "CACHE: BB %d DOM query for ", start_bb->index);
+      print_generic_expr (dump_file, name, TDF_SLIM);
+      fprintf (dump_file, ", found ");
       r.dump (dump_file);
       if (bb)
        fprintf (dump_file, " at BB%d\n", bb->index);
diff --git a/gcc/testsuite/gcc.dg/pr102540.c b/gcc/testsuite/gcc.dg/pr102540.c
new file mode 100644 (file)
index 0000000..c12f8fc
--- /dev/null
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-evrp" } */
+
+
+void kill();
+
+static long a;
+static unsigned b;
+int test1 () {
+    long c, e;
+    c = b = a;
+    e = c ? 2 / (c + 1) : 0;
+    if (e && !b)
+        kill ();
+    a = 0;
+}
+
+/* { dg-final { scan-tree-dump-not "kill" "evrp" } }  */
+
diff --git a/gcc/testsuite/gcc.dg/pr102872.c b/gcc/testsuite/gcc.dg/pr102872.c
new file mode 100644 (file)
index 0000000..971bb03
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+void foo(void);
+
+static int a, b;
+int main() {
+  for (; a; ++a) {
+    unsigned short d = a;
+    if (!(b | d) && d)
+      foo();
+  }
+}
+
+/* { dg-final { scan-tree-dump-not "foo" "evrp" } }  */
+