]> gcc.gnu.org Git - gcc.git/commitdiff
params.def (PARAM_DSE_MAX_ALIAS_QUERIES_PER_STORE): New param.
authorRichard Biener <rguenther@suse.de>
Wed, 16 May 2018 13:02:27 +0000 (13:02 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 16 May 2018 13:02:27 +0000 (13:02 +0000)
2018-05-16  Richard Biener  <rguenther@suse.de>

* params.def (PARAM_DSE_MAX_ALIAS_QUERIES_PER_STORE): New param.
* doc/invoke.texi (dse-max-alias-queries-per-store): Document.
* tree-ssa-dse.c: Include tree-ssa-loop.h.
(check_name): New callback.
(dse_classify_store): Track cycles via a visited bitmap of PHI
defs and simplify handling of in-loop and across loop dead stores
and properly fail for loop-variant refs.  Handle byte-tracking with
multiple defs.  Use PARAM_DSE_MAX_ALIAS_QUERIES_PER_STORE for
limiting the walk.

* gcc.dg/tree-ssa/ssa-dse-32.c: New testcase.
* gcc.dg/tree-ssa/ssa-dse-33.c: Likewise.
* gcc.dg/uninit-pr81897-2.c: Use -fno-tree-dse.

From-SVN: r260288

gcc/ChangeLog
gcc/doc/invoke.texi
gcc/params.def
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-32.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-33.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/uninit-pr81897-2.c
gcc/tree-ssa-dse.c

index 95e966a19360f7c07e8a1b0aed87907f0b43f40f..5d4298b02ee376aea16d07dde0cb997147861bfa 100644 (file)
@@ -1,3 +1,15 @@
+2018-05-16  Richard Biener  <rguenther@suse.de>
+
+       * params.def (PARAM_DSE_MAX_ALIAS_QUERIES_PER_STORE): New param.
+       * doc/invoke.texi (dse-max-alias-queries-per-store): Document.
+       * tree-ssa-dse.c: Include tree-ssa-loop.h.
+       (check_name): New callback.
+       (dse_classify_store): Track cycles via a visited bitmap of PHI
+       defs and simplify handling of in-loop and across loop dead stores
+       and properly fail for loop-variant refs.  Handle byte-tracking with
+       multiple defs.  Use PARAM_DSE_MAX_ALIAS_QUERIES_PER_STORE for
+       limiting the walk.
+
 2018-05-16  Richard Sandiford  <richard.sandiford@linaro.org>
 
        * tree-vectorizer.h (vect_get_vector_types_for_stmt): Declare.
index ca3772bbebfc92b55518846adbc1fc9906d91226..b78a2d67b0dfef91a4b5c2d5ebafa264701c5228 100644 (file)
@@ -10439,6 +10439,11 @@ Average number of iterations of a loop.
 Maximum size (in bytes) of objects tracked bytewise by dead store elimination.
 Larger values may result in larger compilation times.
 
+@item dse-max-alias-queries-per-store
+Maximum number of queries into the alias oracle per store.
+Larger values result in larger compilation times and may result in more
+removed dead stores.
+
 @item scev-max-expr-size
 Bound on size of expressions used in the scalar evolutions analyzer.
 Large expressions slow the analyzer.
index dad47ec2b000069d284c8af20a13a73dba02281b..5c4e2c9507267e9f607d820d933a95eba19116bb 100644 (file)
@@ -547,6 +547,11 @@ DEFPARAM(PARAM_DSE_MAX_OBJECT_SIZE,
         "Maximum size (in bytes) of objects tracked bytewise by dead store elimination.",
         256, 0, 0)
 
+DEFPARAM(PARAM_DSE_MAX_ALIAS_QUERIES_PER_STORE,
+        "dse-max-alias-queries-per-store",
+        "Maximum number of queries into the alias oracle per store.",
+        256, 0, 0)
+
 DEFPARAM(PARAM_SCEV_MAX_EXPR_SIZE,
         "scev-max-expr-size",
         "Bound on size of expressions used in the scalar evolutions analyzer.",
index 7e32f600729002bad380b0f585959fae694bc5da..b1785436a175ac84d75c733aaf662cb6fa4c6d8e 100644 (file)
@@ -1,3 +1,9 @@
+2018-05-16  Richard Biener  <rguenther@suse.de>
+
+       * gcc.dg/tree-ssa/ssa-dse-32.c: New testcase.
+       * gcc.dg/tree-ssa/ssa-dse-33.c: Likewise.
+       * gcc.dg/uninit-pr81897-2.c: Use -fno-tree-dse.
+
 2018-05-16  Richard Sandiford  <richard.sandiford@linaro.org>
 
        * gcc.target/aarch64/sve/vcond_10.c: New test.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-32.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-32.c
new file mode 100644 (file)
index 0000000..eea0d8d
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-dse1-details" } */
+
+void f(int n)
+{
+  char *p = __builtin_malloc (1);
+  int i;
+  do
+    *p = 0;
+  while (++i < n);
+}
+
+/* { dg-final { scan-tree-dump-times "Deleted dead store" 1 "dse1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-33.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-33.c
new file mode 100644 (file)
index 0000000..5bcc016
--- /dev/null
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-dse1-details" } */
+
+void f(char *p, int n)
+{
+  for (int i = 0; i < n; ++i)
+    *p = 0;  /* Removed by DSE.  */
+  *p = 1;
+}
+
+void g(char *p, int n)
+{
+  int i = 0;
+  do
+    *p = 0;  /* Not yet removed by DSE.  */
+  while (++i < n);
+  *p = 1;
+}
+
+
+/* { dg-final { scan-tree-dump-times "Deleted dead store" 2 "dse1" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "Deleted dead store" 1 "dse1" } } */
index 3960af454e55d877a52b83cf90c6be0f6790222b..644de655225d9d72acd6d58aff379eb4f1a5373e 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile }  */
-/* { dg-options "-O1 -fno-tree-ccp -Wmaybe-uninitialized" } */
+/* { dg-options "-O1 -fno-tree-ccp -fno-tree-dse -Wmaybe-uninitialized" } */
 
 int oo;
 
index 126592a1d13f96a9342c78a219137ec49a5211a3..32a25b9eb1ef3b54517276d9c1a2c8efdb37d8ac 100644 (file)
@@ -35,6 +35,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-cfgcleanup.h"
 #include "params.h"
 #include "alias.h"
+#include "tree-ssa-loop.h"
 
 /* This file implements dead store elimination.
 
@@ -515,6 +516,21 @@ live_bytes_read (ao_ref use_ref, ao_ref *ref, sbitmap live)
   return true;
 }
 
+/* Callback for dse_classify_store calling for_each_index.  Verify that
+   indices are invariant in the loop with backedge PHI in basic-block DATA.  */
+
+static bool
+check_name (tree, tree *idx, void *data)
+{
+  basic_block phi_bb = (basic_block) data;
+  if (TREE_CODE (*idx) == SSA_NAME
+      && !SSA_NAME_IS_DEFAULT_DEF (*idx)
+      && dominated_by_p (CDI_DOMINATORS, gimple_bb (SSA_NAME_DEF_STMT (*idx)),
+                        phi_bb))
+    return false;
+  return true;
+}
+
 /* A helper of dse_optimize_stmt.
    Given a GIMPLE_ASSIGN in STMT that writes to REF, classify it
    according to downstream uses and defs.  Sets *BY_CLOBBER_P to true
@@ -527,7 +543,8 @@ dse_classify_store (ao_ref *ref, gimple *stmt,
                    bool *by_clobber_p = NULL)
 {
   gimple *temp;
-  unsigned cnt = 0;
+  int cnt = 0;
+  auto_bitmap visited;
 
   if (by_clobber_p)
     *by_clobber_p = true;
@@ -539,58 +556,50 @@ dse_classify_store (ao_ref *ref, gimple *stmt,
   temp = stmt;
   do
     {
-      gimple *use_stmt, *defvar_def;
+      gimple *use_stmt;
       imm_use_iterator ui;
       bool fail = false;
       tree defvar;
 
-      /* Limit stmt walking to be linear in the number of possibly
-         dead stores.  */
-      if (++cnt > 256)
-       return DSE_STORE_LIVE;
-
       if (gimple_code (temp) == GIMPLE_PHI)
-       defvar = PHI_RESULT (temp);
+       {
+         /* If we visit this PHI by following a backedge then we have to
+            make sure ref->ref only refers to SSA names that are invariant
+            with respect to the loop represented by this PHI node.  */
+         if (dominated_by_p (CDI_DOMINATORS, gimple_bb (stmt),
+                             gimple_bb (temp))
+             && !for_each_index (ref->ref ? &ref->ref : &ref->base,
+                                 check_name, gimple_bb (temp)))
+           return DSE_STORE_LIVE;
+         defvar = PHI_RESULT (temp);
+         bitmap_set_bit (visited, SSA_NAME_VERSION (defvar));
+       }
       else
        defvar = gimple_vdef (temp);
-      defvar_def = temp;
       auto_vec<gimple *, 10> defs;
       FOR_EACH_IMM_USE_STMT (use_stmt, ui, defvar)
        {
-         cnt++;
-
-         /* If we ever reach our DSE candidate stmt again fail.  We
-            cannot handle dead stores in loops.  */
-         if (use_stmt == stmt)
+         /* Limit stmt walking.  */
+         if (++cnt > PARAM_VALUE (PARAM_DSE_MAX_ALIAS_QUERIES_PER_STORE))
            {
              fail = true;
              BREAK_FROM_IMM_USE_STMT (ui);
            }
+
+         /* We have visited ourselves already so ignore STMT for the
+            purpose of chaining.  */
+         if (use_stmt == stmt)
+           ;
          /* In simple cases we can look through PHI nodes, but we
             have to be careful with loops and with memory references
             containing operands that are also operands of PHI nodes.
             See gcc.c-torture/execute/20051110-*.c.  */
          else if (gimple_code (use_stmt) == GIMPLE_PHI)
            {
-             /* Make sure we are not in a loop latch block.  */
-             if (gimple_bb (stmt) == gimple_bb (use_stmt)
-                 || dominated_by_p (CDI_DOMINATORS,
-                                    gimple_bb (stmt), gimple_bb (use_stmt))
-                 /* We can look through PHIs to regions post-dominating
-                    the DSE candidate stmt.  */
-                 || !dominated_by_p (CDI_POST_DOMINATORS,
-                                     gimple_bb (stmt), gimple_bb (use_stmt)))
-               {
-                 fail = true;
-                 BREAK_FROM_IMM_USE_STMT (ui);
-               }
-             /* Do not consider the PHI as use if it dominates the
-                stmt defining the virtual operand we are processing,
-                we have processed it already in this case.  */
-             if (gimple_bb (defvar_def) != gimple_bb (use_stmt)
-                 && !dominated_by_p (CDI_DOMINATORS,
-                                     gimple_bb (defvar_def),
-                                     gimple_bb (use_stmt)))
+             /* If we already visited this PHI ignore it for further
+                processing.  */
+             if (!bitmap_bit_p (visited,
+                                SSA_NAME_VERSION (PHI_RESULT (use_stmt))))
                defs.safe_push (use_stmt);
            }
          /* If the statement is a use the store is not dead.  */
@@ -600,25 +609,20 @@ dse_classify_store (ao_ref *ref, gimple *stmt,
                 structure for USE_STMT and in doing so we find that the
                 references hit non-live bytes and thus can be ignored.  */
              if (byte_tracking_enabled
-                 && (!gimple_vdef (use_stmt) || defs.is_empty ()))
+                 && is_gimple_assign (use_stmt))
                {
-                 if (is_gimple_assign (use_stmt))
+                 ao_ref use_ref;
+                 ao_ref_init (&use_ref, gimple_assign_rhs1 (use_stmt));
+                 if (valid_ao_ref_for_dse (&use_ref)
+                     && use_ref.base == ref->base
+                     && known_eq (use_ref.size, use_ref.max_size)
+                     && !live_bytes_read (use_ref, ref, live_bytes))
                    {
-                     /* Other cases were noted as non-aliasing by
-                        the call to ref_maybe_used_by_stmt_p.  */
-                     ao_ref use_ref;
-                     ao_ref_init (&use_ref, gimple_assign_rhs1 (use_stmt));
-                     if (valid_ao_ref_for_dse (&use_ref)
-                         && use_ref.base == ref->base
-                         && known_eq (use_ref.size, use_ref.max_size)
-                         && !live_bytes_read (use_ref, ref, live_bytes))
-                       {
-                         /* If this statement has a VDEF, then it is the
-                            first store we have seen, so walk through it.  */
-                         if (gimple_vdef (use_stmt))
-                           defs.safe_push (use_stmt);
-                         continue;
-                       }
+                     /* If this is a store, remember it as we possibly
+                        need to walk the defs uses.  */
+                     if (gimple_vdef (use_stmt))
+                       defs.safe_push (use_stmt);
+                     continue;
                    }
                }
 
This page took 0.170335 seconds and 5 git commands to generate.