From 82c704c69fab610afcf4a1947577ed97dd72c429 Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <amacleod@redhat.com>
Date: Mon, 17 Jun 2024 11:23:12 -0400
Subject: [PATCH 1/5] Add builtin_unreachable processing for fast_vrp.

Add a remove_unreachable object to fast vrp, and honor the final_p flag.

	* tree-vrp.cc (remove_unreachable::remove): Export global range
	if builtin_unreachable dominates all uses.
	(remove_unreachable::remove_and_update_globals): Do not reset SCEV.
	(execute_ranger_vrp): Reset SCEV here instead.
	(fvrp_folder::fvrp_folder): Take final pass flag
	and create a remove_unreachable object when specified.
	(fvrp_folder::pre_fold_stmt): Register GIMPLE_CONDs with
	the remove_unreachcable object.
	(fvrp_folder::m_unreachable): New.
	(execute_fast_vrp): Process remove_unreachable object.
	(pass_vrp::execute): Add final_p flag to execute_fast_vrp.
---
 gcc/tree-vrp.cc | 52 ++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 41 insertions(+), 11 deletions(-)

diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc
index 5f5eb9b57e9..a3b1a5cd337 100644
--- a/gcc/tree-vrp.cc
+++ b/gcc/tree-vrp.cc
@@ -280,6 +280,25 @@ remove_unreachable::remove ()
       gimple *s = gimple_outgoing_range_stmt_p (e->src);
       gcc_checking_assert (gimple_code (s) == GIMPLE_COND);
 
+      tree name = gimple_range_ssa_p (gimple_cond_lhs (s));
+      if (!name)
+	name = gimple_range_ssa_p (gimple_cond_rhs (s));
+      // Check if global value can be set for NAME.
+      if (name && fully_replaceable (name, src))
+	{
+	  value_range r (TREE_TYPE (name));
+	  if (gori_name_on_edge (r, name, e, &m_ranger)
+	      && set_range_info (name, r) &&(dump_file))
+	    {
+	      fprintf (dump_file, "Global Exported (via unreachable): ");
+	      print_generic_expr (dump_file, name, TDF_SLIM);
+	      fprintf (dump_file, " = ");
+	      gimple_range_global (r, name);
+	      r.dump (dump_file);
+	      fputc ('\n', dump_file);
+	    }
+	}
+
       change = true;
       // Rewrite the condition.
       if (e->flags & EDGE_TRUE_VALUE)
@@ -305,14 +324,10 @@ remove_unreachable::remove_and_update_globals ()
   if (m_list.length () == 0)
     return false;
 
-  // If there is no import/export info, just remove unreachables if necessary.
+  // If there is no import/export info, Do basic removal.
   if (!m_ranger.gori_ssa ())
     return remove ();
 
-  // Ensure the cache in SCEV has been cleared before processing
-  // globals to be removed.
-  scev_reset ();
-
   bool change = false;
   tree name;
   unsigned i;
@@ -1107,6 +1122,9 @@ execute_ranger_vrp (struct function *fun, bool final_p)
   rvrp_folder folder (ranger, final_p);
   phi_analysis_initialize (ranger->const_query ());
   folder.substitute_and_fold ();
+  // Ensure the cache in SCEV has been cleared before processing
+  // globals to be removed.
+  scev_reset ();
   // Remove tagged builtin-unreachable and maybe update globals.
   folder.m_unreachable.remove_and_update_globals ();
   if (dump_file && (dump_flags & TDF_DETAILS))
@@ -1168,9 +1186,15 @@ execute_ranger_vrp (struct function *fun, bool final_p)
 class fvrp_folder : public substitute_and_fold_engine
 {
 public:
-  fvrp_folder (dom_ranger *dr) : substitute_and_fold_engine (),
-				 m_simplifier (dr)
-  { m_dom_ranger = dr; }
+  fvrp_folder (dom_ranger *dr, bool final_p) : substitute_and_fold_engine (),
+					       m_simplifier (dr)
+  {
+    m_dom_ranger = dr;
+    if (final_p)
+      m_unreachable = new remove_unreachable (*dr, final_p);
+    else
+      m_unreachable = NULL;
+  }
 
   ~fvrp_folder () { }
 
@@ -1228,6 +1252,9 @@ public:
 	value_range vr(type);
 	m_dom_ranger->range_of_stmt (vr, s);
       }
+    if (m_unreachable && gimple_code (s) == GIMPLE_COND)
+      m_unreachable->maybe_register (s);
+
   }
 
   bool fold_stmt (gimple_stmt_iterator *gsi) override
@@ -1238,6 +1265,7 @@ public:
     return ret;
   }
 
+  remove_unreachable *m_unreachable;
 private:
   DISABLE_COPY_AND_ASSIGN (fvrp_folder);
   simplify_using_ranges m_simplifier;
@@ -1248,16 +1276,18 @@ private:
 // Main entry point for a FAST VRP pass using a dom ranger.
 
 unsigned int
-execute_fast_vrp (struct function *fun)
+execute_fast_vrp (struct function *fun, bool final_p)
 {
   calculate_dominance_info (CDI_DOMINATORS);
   dom_ranger dr;
-  fvrp_folder folder (&dr);
+  fvrp_folder folder (&dr, final_p);
 
   gcc_checking_assert (!fun->x_range_query);
   fun->x_range_query = &dr;
 
   folder.substitute_and_fold ();
+  if (folder.m_unreachable)
+    folder.m_unreachable->remove ();
 
   fun->x_range_query = NULL;
   return 0;
@@ -1325,7 +1355,7 @@ public:
     {
       // Check for fast vrp.
       if (&data == &pass_data_fast_vrp)
-	return execute_fast_vrp (fun);
+	return execute_fast_vrp (fun, final_p);
 
       return execute_ranger_vrp (fun, final_p);
     }
-- 
2.45.0

