This moves the optimize_unreachable to forwprop from fab.
There is a slightly optimization here in that the first
statement is checked and outside of the main fold loop. And if
the statement is __builtin_unreachable, then call optimize_unreachable.

Changes since v1:
* v2: simplified the check for BUILT_IN_UNREACHABLE to just use 
gimple_call_builtin_p.
      Move the code after checking for not executable blocks.

Bootstrapped and tested on x86_64-linux-gnu.

        PR tree-optimization/121762
gcc/ChangeLog:

        * tree-ssa-ccp.cc (optimize_unreachable): Move to tree-ssa-forwprop.cc
        (pass_fold_builtins::execute): Remove handling of __builtin_unreachable.
        * tree-ssa-forwprop.cc (optimize_unreachable): New function from
        tree-ssa-ccp.cc. Change argument to bb. Remove check on first statement
        being the __builtin_unreachable since it is handled already.
        (pass_forwprop::execute): Handle first statement as being 
__builtin_unreachable
        by calling optimize_unreachable.

Signed-off-by: Andrew Pinski <[email protected]>
---
 gcc/tree-ssa-ccp.cc      | 58 ----------------------------------------
 gcc/tree-ssa-forwprop.cc | 58 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 58 insertions(+), 58 deletions(-)

diff --git a/gcc/tree-ssa-ccp.cc b/gcc/tree-ssa-ccp.cc
index 739d3be9129..b69a8b64a61 100644
--- a/gcc/tree-ssa-ccp.cc
+++ b/gcc/tree-ssa-ccp.cc
@@ -3202,58 +3202,6 @@ optimize_stdarg_builtin (gimple_stmt_iterator *gsi, 
gimple *call)
     }
 }
 
-/* Attemp to make the block of __builtin_unreachable I unreachable by changing
-   the incoming jumps.  Return true if at least one jump was changed.  */
-
-static bool
-optimize_unreachable (gimple_stmt_iterator i)
-{
-  basic_block bb = gsi_bb (i);
-  gimple_stmt_iterator gsi;
-  gimple *stmt;
-  edge_iterator ei;
-  edge e;
-  bool ret;
-
-  if (flag_sanitize & SANITIZE_UNREACHABLE)
-    return false;
-  gsi = gsi_start_nondebug_after_labels_bb (bb);
-  /* Only handle the case that __builtin_unreachable is the first
-     statement in the block.  We rely on DCE to remove stmts
-     without side-effects before __builtin_unreachable.  */
-  if (*gsi != *i)
-    return false;
-
-  ret = false;
-  FOR_EACH_EDGE (e, ei, bb->preds)
-    {
-      gsi = gsi_last_bb (e->src);
-      if (gsi_end_p (gsi))
-       continue;
-
-      stmt = gsi_stmt (gsi);
-      if (gcond *cond_stmt = dyn_cast <gcond *> (stmt))
-       {
-         if (e->flags & EDGE_TRUE_VALUE)
-           gimple_cond_make_false (cond_stmt);
-         else if (e->flags & EDGE_FALSE_VALUE)
-           gimple_cond_make_true (cond_stmt);
-         else
-           gcc_unreachable ();
-         update_stmt (cond_stmt);
-       }
-      else
-       {
-         /* Todo: handle other cases.  Note that unreachable switch case
-            statements have already been removed.  */
-         continue;
-       }
-
-      ret = true;
-    }
-
-  return ret;
-}
 
 /* Convert
    _1 = __atomic_fetch_or_* (ptr_6, 1, _3);
@@ -4235,12 +4183,6 @@ pass_fold_builtins::execute (function *fun)
              tree result = NULL_TREE;
              switch (DECL_FUNCTION_CODE (callee))
                {
-
-               case BUILT_IN_UNREACHABLE:
-                 if (optimize_unreachable (i))
-                   cfg_changed = true;
-                 break;
-
                case BUILT_IN_ATOMIC_ADD_FETCH_1:
                case BUILT_IN_ATOMIC_ADD_FETCH_2:
                case BUILT_IN_ATOMIC_ADD_FETCH_4:
diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc
index e0c93237b97..0a8828f1124 100644
--- a/gcc/tree-ssa-forwprop.cc
+++ b/gcc/tree-ssa-forwprop.cc
@@ -4905,6 +4905,49 @@ public:
   bool m_full_walk = false;
 }; // class pass_forwprop
 
+/* Attemp to make the BB block of __builtin_unreachable unreachable by changing
+   the incoming jumps.  Return true if at least one jump was changed.  */
+
+static bool
+optimize_unreachable (basic_block bb)
+{
+  gimple_stmt_iterator gsi;
+  gimple *stmt;
+  edge_iterator ei;
+  edge e;
+  bool ret;
+
+  ret = false;
+  FOR_EACH_EDGE (e, ei, bb->preds)
+    {
+      gsi = gsi_last_bb (e->src);
+      if (gsi_end_p (gsi))
+       continue;
+
+      stmt = gsi_stmt (gsi);
+      if (gcond *cond_stmt = dyn_cast <gcond *> (stmt))
+       {
+         if (e->flags & EDGE_TRUE_VALUE)
+           gimple_cond_make_false (cond_stmt);
+         else if (e->flags & EDGE_FALSE_VALUE)
+           gimple_cond_make_true (cond_stmt);
+         else
+           gcc_unreachable ();
+         update_stmt (cond_stmt);
+       }
+      else
+       {
+         /* Todo: handle other cases.  Note that unreachable switch case
+            statements have already been removed.  */
+         continue;
+       }
+
+      ret = true;
+    }
+
+  return ret;
+}
+
 unsigned int
 pass_forwprop::execute (function *fun)
 {
@@ -4972,6 +5015,21 @@ pass_forwprop::execute (function *fun)
       if (!any)
        continue;
 
+      /* Remove conditions that go directly to unreachable when this is the 
last forwprop.  */
+      if (last_p
+         && !(flag_sanitize & SANITIZE_UNREACHABLE))
+       {
+         gimple_stmt_iterator gsi;
+         gsi = gsi_start_nondebug_after_labels_bb (bb);
+         if (!gsi_end_p (gsi)
+             && gimple_call_builtin_p (*gsi, BUILT_IN_UNREACHABLE)
+             && optimize_unreachable (bb))
+           {
+             cfg_changed = true;
+             continue;
+           }
+       }
+
       /* Record degenerate PHIs in the lattice.  */
       for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si);
           gsi_next (&si))
-- 
2.43.0

Reply via email to