public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] tree-optimization/79958 - make DSE track multiple paths
@ 2024-05-15 17:25 Richard Biener
  0 siblings, 0 replies; only message in thread
From: Richard Biener @ 2024-05-15 17:25 UTC (permalink / raw)
  To: gcc-patches

DSE currently gives up when the path we analyze forks.  This leads
to multiple missed dead store elimination PRs.  The following fixes
this by recursing for each path and maintaining the visited bitmap
to avoid visiting CFG re-merges multiple times.  The overall cost
is still limited by the same bound, it's just more likely we'll hit
the limit now.  The patch doesn't try to deal with byte tracking
once a path forks but drops info on the floor and only handling
fully dead stores in that case.

Bootstrapped on x86_64-unknown-linux-gnu for all languages, testing in 
progress.

Richard.

	PR tree-optimization/79958
	PR tree-optimization/109087
	PR tree-optimization/100314
	PR tree-optimization/114774
	* tree-ssa-dse.cc (dse_classify_store): New forwarder.
	(dse_classify_store): Add arguments cnt and visited, recurse
	to track multiple paths when we end up with multiple defs.

	* gcc.dg/tree-ssa/ssa-dse-48.c: New testcase.
	* gcc.dg/tree-ssa/ssa-dse-49.c: Likewise.
	* gcc.dg/tree-ssa/ssa-dse-50.c: Likewise.
	* gcc.dg/tree-ssa/ssa-dse-51.c: Likewise.
---
 gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-48.c | 17 ++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-49.c | 18 +++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-50.c | 25 +++++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-51.c | 24 +++++++++++++++++
 gcc/tree-ssa-dse.cc                        | 31 +++++++++++++++++++---
 5 files changed, 111 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-48.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-49.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-50.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-51.c

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-48.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-48.c
new file mode 100644
index 00000000000..edfc62c7e4a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-48.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-dse1-details" } */
+
+int a;
+int foo (void);
+int bar (void);
+
+void
+baz (void)
+{
+  int *b[6];
+  b[0] = &a;
+  if (foo ())
+    a |= bar ();
+}
+
+/* { dg-final { scan-tree-dump "Deleted dead store: b\\\[0\\\] = &a;" "dse1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-49.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-49.c
new file mode 100644
index 00000000000..1eec284a415
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-49.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fno-tree-dce -fdump-tree-dse1-details" } */
+
+struct X { int i; };
+void bar ();
+void foo (int b)
+{
+  struct X x;
+  x.i = 1;
+  if (b)
+    {
+      bar ();
+      __builtin_abort ();
+    }
+  bar ();
+}
+
+/* { dg-final { scan-tree-dump "Deleted dead store: x.i = 1;" "dse1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-50.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-50.c
new file mode 100644
index 00000000000..7c42ae6a67a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-50.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-dse1-details" } */
+
+extern void foo(void);
+static int a, *c, g, **j;
+int b;
+static void e() {
+  int k, *l[5] = {&k, &k, &k, &k, &k};
+  while (g) {
+    j = &l[0];
+    b++;
+  }
+}
+static void d(int m) {
+  int **h[30] = {&c}, ***i[1] = {&h[3]};
+  if (m)
+    foo();
+  e();
+}
+int main() {
+  d(a);
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "Deleted dead store" 8 "dse1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-51.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-51.c
new file mode 100644
index 00000000000..ac9d1bb1fc8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-51.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fstrict-aliasing -fdump-tree-dse1-details" } */
+
+int a;
+short *p;
+void
+test (int b)
+{
+  a=1;
+  if (b)
+    {
+      (*p)++;
+      a=2;
+      __builtin_printf ("1\n");
+    }
+  else
+    {
+      (*p)++;
+      a=3;
+      __builtin_printf ("2\n");
+    }
+}
+
+/* { dg-final { scan-tree-dump "Deleted dead store: a = 1;" "dse1" } } */
diff --git a/gcc/tree-ssa-dse.cc b/gcc/tree-ssa-dse.cc
index fce4fc76a56..9252ca34050 100644
--- a/gcc/tree-ssa-dse.cc
+++ b/gcc/tree-ssa-dse.cc
@@ -971,14 +971,13 @@ static hash_map<gimple *, data_reference_p> *dse_stmt_to_dr_map;
    if only clobber statements influenced the classification result.
    Returns the classification.  */
 
-dse_store_status
+static dse_store_status
 dse_classify_store (ao_ref *ref, gimple *stmt,
 		    bool byte_tracking_enabled, sbitmap live_bytes,
-		    bool *by_clobber_p, tree stop_at_vuse)
+		    bool *by_clobber_p, tree stop_at_vuse, int &cnt,
+		    bitmap visited)
 {
   gimple *temp;
-  int cnt = 0;
-  auto_bitmap visited;
   std::unique_ptr<data_reference, void(*)(data_reference_p)>
     dra (nullptr, free_data_ref);
 
@@ -1238,6 +1237,19 @@ dse_classify_store (ao_ref *ref, gimple *stmt,
       /* If all defs kill the ref we are done.  */
       if (defs.is_empty ())
 	return DSE_STORE_DEAD;
+      /* If more than one def survives we have to analyze multiple
+	 paths.  We can handle this by recursing, sharing 'visited'
+	 to avoid redundant work and limiting it by shared 'cnt'.
+	 For now do not bother with byte-tracking in this case.  */
+      while (defs.length () > 1)
+	{
+	  if (dse_classify_store (ref, defs.last (), false, NULL,
+				  by_clobber_p, stop_at_vuse, cnt,
+				  visited) != DSE_STORE_DEAD)
+	    break;
+	  byte_tracking_enabled = false;
+	  defs.pop ();
+	}
       /* If more than one def survives fail.  */
       if (defs.length () > 1)
 	{
@@ -1265,6 +1277,17 @@ dse_classify_store (ao_ref *ref, gimple *stmt,
   while (1);
 }
 
+dse_store_status
+dse_classify_store (ao_ref *ref, gimple *stmt,
+		    bool byte_tracking_enabled, sbitmap live_bytes,
+		    bool *by_clobber_p, tree stop_at_vuse)
+{
+  int cnt = 0;
+  auto_bitmap visited;
+  return dse_classify_store (ref, stmt, byte_tracking_enabled, live_bytes,
+			     by_clobber_p, stop_at_vuse, cnt, visited);
+}
+
 
 /* Delete a dead call at GSI, which is mem* call of some kind.  */
 static void
-- 
2.35.3

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2024-05-15 17:25 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-05-15 17:25 [PATCH] tree-optimization/79958 - make DSE track multiple paths Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).