We can now DSE calls in more cases which requires us to eventually
purge dead abnormal edges.  This implements this.

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

Richard.

2021-11-18  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/103277
        * tree-ssa-dse.c (need_ab_cleanup): New.
        (dse_optimize_redundant_stores): Adjust.
        (delete_dead_or_redundant_assignment): Get extra
        need_ab_cleanup argument and set when abnormal cleanup is
        needed.
        (dse_optimize_call): Adjust.
        (dse_optimize_stmt): Likewise.
        (pass_dse::execute): Allocate and deallocate need_ab_cleanup.
        Perform abnormal cleanup.
        * tree-ssa-dse.h (delete_dead_or_redundant_assignment): Adjust.

        * gcc.dg/pr103277.c: New testcase.
---
 gcc/testsuite/gcc.dg/pr103277.c | 14 ++++++++++++++
 gcc/tree-ssa-dse.c              | 25 ++++++++++++++++++++-----
 gcc/tree-ssa-dse.h              |  2 +-
 3 files changed, 35 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr103277.c

diff --git a/gcc/testsuite/gcc.dg/pr103277.c b/gcc/testsuite/gcc.dg/pr103277.c
new file mode 100644
index 00000000000..5c206f919cd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr103277.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fbranch-probabilities -fno-ipa-pure-const" } */
+
+__attribute__ ((returns_twice)) void
+bar (void)
+{
+}
+
+void
+foo (int cond)
+{
+  if (cond)
+    bar ();
+} /* { dg-message "profile count data" } */
diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c
index 231e827c525..9531d892f76 100644
--- a/gcc/tree-ssa-dse.c
+++ b/gcc/tree-ssa-dse.c
@@ -88,6 +88,7 @@ static void delete_dead_or_redundant_call 
(gimple_stmt_iterator *, const char *)
 /* Bitmap of blocks that have had EH statements cleaned.  We should
    remove their dead edges eventually.  */
 static bitmap need_eh_cleanup;
+static bitmap need_ab_cleanup;
 
 /* STMT is a statement that may write into memory.  Analyze it and
    initialize WRITE to describe how STMT affects memory.
@@ -758,7 +759,8 @@ dse_optimize_redundant_stores (gimple *stmt)
                               (ao_ref_base_alias_set (&lhs_ref),
                                                  earlier_base_set)))
                    delete_dead_or_redundant_assignment (&gsi, "redundant",
-                                                        need_eh_cleanup);
+                                                        need_eh_cleanup,
+                                                        need_ab_cleanup);
                }
              else if (is_gimple_call (use_stmt))
                {
@@ -1027,8 +1029,10 @@ delete_dead_or_redundant_call (gimple_stmt_iterator 
*gsi, const char *type)
 /* Delete a dead store at GSI, which is a gimple assignment. */
 
 void
-delete_dead_or_redundant_assignment (gimple_stmt_iterator *gsi, const char 
*type,
-                                    bitmap need_eh_cleanup)
+delete_dead_or_redundant_assignment (gimple_stmt_iterator *gsi,
+                                    const char *type,
+                                    bitmap need_eh_cleanup,
+                                    bitmap need_ab_cleanup)
 {
   gimple *stmt = gsi_stmt (*gsi);
   if (dump_file && (dump_flags & TDF_DETAILS))
@@ -1043,6 +1047,8 @@ delete_dead_or_redundant_assignment (gimple_stmt_iterator 
*gsi, const char *type
 
   /* Remove the dead store.  */
   basic_block bb = gimple_bb (stmt);
+  if (need_ab_cleanup && stmt_can_make_abnormal_goto (stmt))
+    bitmap_set_bit (need_ab_cleanup, bb->index);
   if (gsi_remove (gsi, true) && need_eh_cleanup)
     bitmap_set_bit (need_eh_cleanup, bb->index);
 
@@ -1132,7 +1138,8 @@ dse_optimize_call (gimple_stmt_iterator *gsi, sbitmap 
live_bytes)
          if (store_status != DSE_STORE_DEAD)
            return false;
        }
-  delete_dead_or_redundant_assignment (gsi, "dead", need_eh_cleanup);
+  delete_dead_or_redundant_assignment (gsi, "dead", need_eh_cleanup,
+                                      need_ab_cleanup);
   return true;
 }
 
@@ -1296,7 +1303,8 @@ dse_optimize_stmt (function *fun, gimple_stmt_iterator 
*gsi, sbitmap live_bytes)
       update_stmt (stmt);
     }
   else
-    delete_dead_or_redundant_assignment (gsi, "dead", need_eh_cleanup);
+    delete_dead_or_redundant_assignment (gsi, "dead", need_eh_cleanup,
+                                        need_ab_cleanup);
 }
 
 namespace {
@@ -1333,6 +1341,7 @@ pass_dse::execute (function *fun)
 {
   unsigned todo = 0;
   need_eh_cleanup = BITMAP_ALLOC (NULL);
+  need_ab_cleanup = BITMAP_ALLOC (NULL);
   auto_sbitmap live_bytes (param_dse_max_object_size);
 
   renumber_gimple_stmt_uids (fun);
@@ -1410,8 +1419,14 @@ pass_dse::execute (function *fun)
       gimple_purge_all_dead_eh_edges (need_eh_cleanup);
       todo |= TODO_cleanup_cfg;
     }
+  if (!bitmap_empty_p (need_ab_cleanup))
+    {
+      gimple_purge_all_dead_abnormal_call_edges (need_ab_cleanup);
+      todo |= TODO_cleanup_cfg;
+    }
 
   BITMAP_FREE (need_eh_cleanup);
+  BITMAP_FREE (need_ab_cleanup);
 
   return todo;
 }
diff --git a/gcc/tree-ssa-dse.h b/gcc/tree-ssa-dse.h
index 337579aec69..051620c0285 100644
--- a/gcc/tree-ssa-dse.h
+++ b/gcc/tree-ssa-dse.h
@@ -32,6 +32,6 @@ dse_store_status dse_classify_store (ao_ref *, gimple *, 
bool, sbitmap,
                                     bool * = NULL, tree = NULL);
 
 void delete_dead_or_redundant_assignment (gimple_stmt_iterator *, const char *,
-                                         bitmap = NULL);
+                                         bitmap = NULL, bitmap = NULL);
 
 #endif   /* GCC_TREE_SSA_DSE_H  */
-- 
2.31.1

Reply via email to