[gcc r17-3204] Provide a DCE no-delete option.

Andrew Macleod via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:e02ce3b8c4574c81a943eb1084b0e0bf6a9955d5

commit r17-3204-ge02ce3b8c4574c81a943eb1084b0e0bf6a9955d5
Author: Andrew MacLeod <[email protected]>
Date:   Tue Aug 4 12:13:15 2026 -0400

    Provide a DCE no-delete option.
    
    Add a flag which replaces statement with assignment to zero instead of
    removing them.
    
            PR tree-optimization/126329
            gcc/
            * tree-ssa-dce.cc (simple_dce_from_worklist): Add no-delete option.
            * tree-ssa-dce.h (simple_dce_from_worklist): Add no delete param.
            * tree-vrp.cc (remove_unreachable::handle_early): Use no delete option.
    
            gcc/testsuite/
            * gcc.dg/pr126329.c: New.

Diff:
---
 gcc/testsuite/gcc.dg/pr126329.c | 28 +++++++++++++++++++++
 gcc/tree-ssa-dce.cc             | 54 +++++++++++++++++++++++++++++++++--------
 gcc/tree-ssa-dce.h              |  2 +-
 gcc/tree-vrp.cc                 |  2 +-
 4 files changed, 74 insertions(+), 12 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/pr126329.c b/gcc/testsuite/gcc.dg/pr126329.c
new file mode 100644
index 000000000000..50165c574e5d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr126329.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+#include <stdint.h>
+int32_t g30;
+void f25(int32_t a1)
+{
+    int a2;
+    _Bool c6, c14;
+    int8_t v8;
+    int64_t v15;
+    int8_t v16;
+    if (a1 == 8098) goto lbl_sw11;
+    a2 = __builtin_ffs(a1);
+lbl_b8:
+    v8 = a2;
+    c6 = v8 >= v16;
+    goto lbl_br26;
+lbl_sw11:
+lbl_br17:
+    goto lbl_b8;
+lbl_br26:
+    g30 = v8;
+    if (c6) __builtin_unreachable();
+    c6 = c14 = a1;
+    a1 = v8;
+    if (v15) goto lbl_br26;
+    if (c14) goto lbl_br17;
+}
diff --git a/gcc/tree-ssa-dce.cc b/gcc/tree-ssa-dce.cc
index 548d5d4bd661..bf818ad2c919 100644
--- a/gcc/tree-ssa-dce.cc
+++ b/gcc/tree-ssa-dce.cc
@@ -2170,10 +2170,16 @@ make_pass_cd_dce (gcc::context *ctxt)
 /* A cheap DCE interface.  WORKLIST is a list of possibly dead stmts and
    is consumed by this function.  The function has linear complexity in
    the number of dead stmts with a constant factor like the average SSA
-   use operands number.  */
+   use operands number.
+   If no_delete is true (defaults to false) then rather than deleting the
+   statement, it is replaced with an assignment to 0.  This allows the
+   same elimination of statement dependencies, but delays the actual statement
+   removal from the IL until the next time DCE is run and they are detected
+   as dead statements with no uses. */
 
 void
-simple_dce_from_worklist (bitmap worklist, bitmap need_eh_cleanup)
+simple_dce_from_worklist (bitmap worklist, bitmap need_eh_cleanup,
+			  bool no_delete)
 {
   int phiremoved = 0;
   int stmtremoved = 0;
@@ -2217,11 +2223,20 @@ simple_dce_from_worklist (bitmap worklist, bitmap need_eh_cleanup)
       gimple *t = SSA_NAME_DEF_STMT (def);
       if (gimple_has_side_effects (t))
 	{
-	  if (gcall *call = dyn_cast <gcall *> (t))
+	  gcall *call = dyn_cast <gcall *> (t);
+	  if (call)
 	    {
 	      gimple_call_set_lhs (call, NULL_TREE);
 	      update_stmt (call);
-	      release_ssa_name (def);
+	      if (no_delete)
+		{
+		  tree zero = build_zero_cst (TREE_TYPE (def));
+		  gassign *new_stmt = gimple_build_assign (def, zero);
+		  gimple_stmt_iterator gsi = gsi_for_stmt (t);
+		  gsi_insert_after (&gsi, new_stmt, GSI_SAME_STMT);
+		}
+	      else
+		release_ssa_name (def);
 	    }
 	  continue;
 	}
@@ -2263,19 +2278,38 @@ simple_dce_from_worklist (bitmap worklist, bitmap need_eh_cleanup)
       gimple_stmt_iterator gsi = gsi_for_stmt (t);
       if (gimple_code (t) == GIMPLE_PHI)
 	{
-	  remove_phi_node (&gsi, true);
+	  if (no_delete)
+	    {
+	      gphi *phi = as_a<gphi *> (t);
+	      tree zero = build_zero_cst (TREE_TYPE (def));
+	      for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i)
+		SET_PHI_ARG_DEF (phi, i, zero);
+	      update_stmt (phi);
+	    }
+	  else
+	    remove_phi_node (&gsi, true);
+
 	  phiremoved++;
 	}
       else
 	{
 	  unlink_stmt_vdef (t);
-	  gsi_remove (&gsi, true);
-	  release_defs (t);
+	  if (no_delete)
+	    {
+	      tree zero = build_zero_cst (TREE_TYPE (def));
+	      gassign *new_stmt = gimple_build_assign (def, zero);
+	      gsi_replace (&gsi, new_stmt, true);
+	    }
+	  else
+	    {
+	      gsi_remove (&gsi, true);
+	      release_defs (t);
+	    }
 	  stmtremoved++;
 	}
     }
-  statistics_counter_event (cfun, "PHIs removed",
+  statistics_counter_event (cfun, no_delete ? "PHIs rewritten" : "PHIs removed",
 			    phiremoved);
-  statistics_counter_event (cfun, "Statements removed",
-			    stmtremoved);
+  statistics_counter_event (cfun, no_delete ? "Statements rewritten"
+					    : "Statements removed", stmtremoved);
 }
diff --git a/gcc/tree-ssa-dce.h b/gcc/tree-ssa-dce.h
index dd874479fb56..d97e5e7c3b1e 100644
--- a/gcc/tree-ssa-dce.h
+++ b/gcc/tree-ssa-dce.h
@@ -18,5 +18,5 @@ along with GCC; see the file COPYING3.  If not see
 
 #ifndef TREE_SSA_DCE_H
 #define TREE_SSA_DCE_H
-extern void simple_dce_from_worklist (bitmap, bitmap = nullptr);
+extern void simple_dce_from_worklist (bitmap, bitmap = nullptr, bool no_delete = false);
 #endif
diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc
index da65d67b4052..6f1e3eb90352 100644
--- a/gcc/tree-vrp.cc
+++ b/gcc/tree-vrp.cc
@@ -248,7 +248,7 @@ remove_unreachable::handle_early (gimple *s, edge e)
     {
       auto_bitmap dce;
       bitmap_set_bit (dce, SSA_NAME_VERSION (ssa));
-      simple_dce_from_worklist (dce);
+      simple_dce_from_worklist (dce, nullptr, true);
     }
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.