diff mbox series

[COMMITTED,12/12] - Move condexpr_adjust into gimple-range-fold

Message ID 4ec525b9-3d54-47a5-8fbc-b9538f2bbf09@redhat.com
State New
Headers show
Series [COMMITTED,01/12] - Move all relation queries into relation_oracle. | expand

Commit Message

Andrew MacLeod May 23, 2024, 8:53 p.m. UTC
Certain components of GORI were needed in order to process a COND_EXPR 
expression and calculate the 2 operands as if they were true and false edges
based on the condition.   With GORI available from the range_query 
object now, this can be moved into the fold_using_range code where it 
really belongs.

Bootstrapped on x86_64-pc-linux-gnu with no regressions.  Pushed.
diff mbox series

Patch

From eb66da78b896ad5e7f6a315413ed68273c83662f Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <amacleod@redhat.com>
Date: Tue, 21 May 2024 12:41:49 -0400
Subject: [PATCH 12/12] Move condexpr_adjust into gimple-range-fold

Certain components of GORI were needed in order to process a COND_EXPR
expression and calculate the 2 operands as if they were true and false edges
based on the condition.   With GORI available from the range_query
objcet now, this can be moved into the fold_using_range code where it
really belongs.

	* gimple-range-edge.h (range_query::condexpr_adjust): Delete.
	* gimpe-range-fold.cc (fold_using_range::range_of_range_op): Use
	gori_ssa routine.
	(fold_using_range::range_of_address): Likewise.
	(fold_using_range::range_of_phi): Likewise.
	(fold_using_range::condexpr_adjust): Relocated from gori_compute.
	(fold_using_range::range_of_cond_expr): Use local condexpr_adjust.
	(fur_source::register_outgoing_edges): Use gori_ssa routine.
	* gimple-range-fold.h (gori_ssa): Rename from gori_bb.
	(fold_using_range::condexpr_adjust): Add prototype.
	* gimple-range-gori.cc (gori_compute::condexpr_adjust): Relocate.
	* gimple-range-gori.h (gori_compute::condexpr_adjust): Delete.
---
 gcc/gimple-range-edge.h  |   4 +-
 gcc/gimple-range-fold.cc | 130 ++++++++++++++++++++++++++++++++-------
 gcc/gimple-range-fold.h  |   4 +-
 gcc/gimple-range-gori.cc | 103 -------------------------------
 gcc/gimple-range-gori.h  |   2 -
 5 files changed, 113 insertions(+), 130 deletions(-)

diff --git a/gcc/gimple-range-edge.h b/gcc/gimple-range-edge.h
index 0096c02faf4..0de1cca4294 100644
--- a/gcc/gimple-range-edge.h
+++ b/gcc/gimple-range-edge.h
@@ -54,13 +54,11 @@  public:
 
   virtual bool edge_range_p (vrange &, edge, tree, range_query &)
     { return false; }
-  virtual bool condexpr_adjust (vrange &, vrange &, gimple *, tree, tree, tree,
-				class fur_source &) { return false; }
   virtual bool has_edge_range_p (tree, basic_block = NULL) { return false; }
   virtual bool has_edge_range_p (tree, edge ) { return false; }
   virtual void dump (FILE *) { }
   virtual bool compute_operand_range (vrange &, gimple *, const vrange &, tree,
-				      fur_source &,
+				      class fur_source &,
 				      class value_relation * = NULL)
     { return false; }
 private:
diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc
index a0ff7f2b98b..b3965b5ee50 100644
--- a/gcc/gimple-range-fold.cc
+++ b/gcc/gimple-range-fold.cc
@@ -745,8 +745,8 @@  fold_using_range::range_of_range_op (vrange &r,
 	    r.set_varying (type);
 	  if (lhs && gimple_range_ssa_p (op1))
 	    {
-	      if (src.gori_bb ())
-		src.gori_bb ()->register_dependency (lhs, op1);
+	      if (src.gori_ssa ())
+		src.gori_ssa ()->register_dependency (lhs, op1);
 	      relation_kind rel;
 	      rel = handler.lhs_op1_relation (r, range1, range1);
 	      if (rel != VREL_VARYING)
@@ -772,10 +772,10 @@  fold_using_range::range_of_range_op (vrange &r,
 	    relation_fold_and_or (as_a <irange> (r), s, src, range1, range2);
 	  if (lhs)
 	    {
-	      if (src.gori_bb ())
+	      if (src.gori_ssa ())
 		{
-		  src.gori_bb ()->register_dependency (lhs, op1);
-		  src.gori_bb ()->register_dependency (lhs, op2);
+		  src.gori_ssa ()->register_dependency (lhs, op1);
+		  src.gori_ssa ()->register_dependency (lhs, op2);
 		}
 	      if (gimple_range_ssa_p (op1))
 		{
@@ -843,8 +843,8 @@  fold_using_range::range_of_address (prange &r, gimple *stmt, fur_source &src)
     {
       tree ssa = TREE_OPERAND (base, 0);
       tree lhs = gimple_get_lhs (stmt);
-      if (lhs && gimple_range_ssa_p (ssa) && src.gori_bb ())
-	src.gori_bb ()->register_dependency (lhs, ssa);
+      if (lhs && gimple_range_ssa_p (ssa) && src.gori_ssa ())
+	src.gori_ssa ()->register_dependency (lhs, ssa);
       src.get_operand (r, ssa);
       range_cast (r, TREE_TYPE (gimple_assign_rhs1 (stmt)));
 
@@ -950,8 +950,8 @@  fold_using_range::range_of_phi (vrange &r, gphi *phi, fur_source &src)
 	  else
 	    r.union_ (arg_range);
 
-	  if (gimple_range_ssa_p (arg) && src.gori_bb ())
-	    src.gori_bb ()->register_dependency (phi_def, arg);
+	  if (gimple_range_ssa_p (arg) && src.gori_ssa ())
+	    src.gori_ssa ()->register_dependency (phi_def, arg);
 	}
 
       // Track if all arguments are the same.
@@ -1114,6 +1114,95 @@  fold_using_range::range_of_call (vrange &r, gcall *call, fur_source &)
   return true;
 }
 
+// Given COND ? OP1 : OP2 with ranges R1 for OP1 and R2 for OP2, Use gori
+// to further resolve R1 and R2 if there are any dependencies between
+// OP1 and COND or OP2 and COND.  All values can are to be calculated using SRC
+// as the origination source location for operands..
+// Effectively, use COND an the edge condition and solve for OP1 on the true
+// edge and OP2 on the false edge.
+
+bool
+fold_using_range::condexpr_adjust (vrange &r1, vrange &r2, gimple *, tree cond,
+				   tree op1, tree op2, fur_source &src)
+{
+  if (!src.gori () || !src.gori_ssa ())
+    return false;
+
+  tree ssa1 = gimple_range_ssa_p (op1);
+  tree ssa2 = gimple_range_ssa_p (op2);
+  if (!ssa1 && !ssa2)
+    return false;
+  if (TREE_CODE (cond) != SSA_NAME)
+    return false;
+  gassign *cond_def = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (cond));
+  if (!cond_def
+      || TREE_CODE_CLASS (gimple_assign_rhs_code (cond_def)) != tcc_comparison)
+    return false;
+  tree type = TREE_TYPE (gimple_assign_rhs1 (cond_def));
+  if (!range_compatible_p (type, TREE_TYPE (gimple_assign_rhs2 (cond_def))))
+    return false;
+  range_op_handler hand (gimple_assign_rhs_code (cond_def));
+  if (!hand)
+    return false;
+
+  tree c1 = gimple_range_ssa_p (gimple_assign_rhs1 (cond_def));
+  tree c2 = gimple_range_ssa_p (gimple_assign_rhs2 (cond_def));
+
+  // Only solve if there is one SSA name in the condition.
+  if ((!c1 && !c2) || (c1 && c2))
+    return false;
+
+  // Pick up the current values of each part of the condition.
+  tree rhs1 = gimple_assign_rhs1 (cond_def);
+  tree rhs2 = gimple_assign_rhs2 (cond_def);
+  Value_Range cl (TREE_TYPE (rhs1));
+  Value_Range cr (TREE_TYPE (rhs2));
+  src.get_operand (cl, rhs1);
+  src.get_operand (cr, rhs2);
+
+  tree cond_name = c1 ? c1 : c2;
+  gimple *def_stmt = SSA_NAME_DEF_STMT (cond_name);
+
+  // Evaluate the value of COND_NAME on the true and false edges, using either
+  // the op1 or op2 routines based on its location.
+  Value_Range cond_true (type), cond_false (type);
+  if (c1)
+    {
+      if (!hand.op1_range (cond_false, type, range_false (), cr))
+	return false;
+      if (!hand.op1_range (cond_true, type, range_true (), cr))
+	return false;
+      cond_false.intersect (cl);
+      cond_true.intersect (cl);
+    }
+  else
+    {
+      if (!hand.op2_range (cond_false, type, range_false (), cl))
+	return false;
+      if (!hand.op2_range (cond_true, type, range_true (), cl))
+	return false;
+      cond_false.intersect (cr);
+      cond_true.intersect (cr);
+    }
+
+   // Now solve for SSA1 or SSA2 if they are in the dependency chain.
+   if (ssa1 && src.gori_ssa()->in_chain_p (ssa1, cond_name))
+    {
+      Value_Range tmp1 (TREE_TYPE (ssa1));
+      if (src.gori ()->compute_operand_range (tmp1, def_stmt, cond_true,
+	  ssa1, src))
+	r1.intersect (tmp1);
+    }
+  if (ssa2 && src.gori_ssa ()->in_chain_p (ssa2, cond_name))
+    {
+      Value_Range tmp2 (TREE_TYPE (ssa2));
+      if (src.gori ()->compute_operand_range (tmp2, def_stmt, cond_false,
+	  ssa2, src))
+	r2.intersect (tmp2);
+    }
+  return true;
+}
+
 // Calculate a range for COND_EXPR statement S and return it in R.
 // If a range cannot be calculated, return false.
 
@@ -1138,16 +1227,15 @@  fold_using_range::range_of_cond_expr  (vrange &r, gassign *s, fur_source &src)
   src.get_operand (range2, op2);
 
   // Try to see if there is a dependence between the COND and either operand
-  if (src.gori ())
-    if (src.gori ()->condexpr_adjust (range1, range2, s, cond, op1, op2, src))
-      if (dump_file && (dump_flags & TDF_DETAILS))
-	{
-	  fprintf (dump_file, "Possible COND_EXPR adjustment. Range op1 : ");
-	  range1.dump(dump_file);
-	  fprintf (dump_file, " and Range op2: ");
-	  range2.dump(dump_file);
-	  fprintf (dump_file, "\n");
-	}
+  if (condexpr_adjust (range1, range2, s, cond, op1, op2, src))
+    if (dump_file && (dump_flags & TDF_DETAILS))
+      {
+	fprintf (dump_file, "Possible COND_EXPR adjustment. Range op1 : ");
+	range1.dump(dump_file);
+	fprintf (dump_file, " and Range op2: ");
+	range2.dump(dump_file);
+	fprintf (dump_file, "\n");
+      }
 
   // If the condition is known, choose the appropriate expression.
   if (cond_range.singleton_p ())
@@ -1345,14 +1433,14 @@  fur_source::register_outgoing_edges (gcond *s, irange &lhs_range,
     }
 
   // Outgoing relations of GORI exports require a gori engine.
-  if (!gori_bb ())
+  if (!gori_ssa ())
     return;
 
   // Now look for other relations in the exports.  This will find stmts
   // leading to the condition such as:
   // c_2 = a_4 < b_7
   // if (c_2)
-  FOR_EACH_GORI_EXPORT_NAME (gori_bb (), bb, name)
+  FOR_EACH_GORI_EXPORT_NAME (gori_ssa (), bb, name)
     {
       if (TREE_CODE (TREE_TYPE (name)) != BOOLEAN_TYPE)
 	continue;
diff --git a/gcc/gimple-range-fold.h b/gcc/gimple-range-fold.h
index b240a6e4c61..491d57386f3 100644
--- a/gcc/gimple-range-fold.h
+++ b/gcc/gimple-range-fold.h
@@ -106,7 +106,7 @@  class fur_source
 public:
   fur_source (range_query *q = NULL);
   inline range_query *query () const { return m_query; }
-  inline gori_map *gori_bb () const
+  inline gori_map *gori_ssa () const
     { return (m_depend_p && m_query) ? m_query->gori_ssa () : NULL; }
   inline class gimple_outgoing_range *gori ()
     { return m_depend_p ? &(m_query->gori ()) : NULL; }
@@ -171,5 +171,7 @@  protected:
 					 fur_source &src);
   void relation_fold_and_or (irange& lhs_range, gimple *s, fur_source &src,
 			     vrange &op1, vrange &op2);
+  bool condexpr_adjust (vrange &r1, vrange &r2, gimple *, tree cond, tree op1,
+			tree op2, fur_source &src);
 };
 #endif // GCC_GIMPLE_RANGE_FOLD_H
diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc
index a3fe67ede4e..0d471b46903 100644
--- a/gcc/gimple-range-gori.cc
+++ b/gcc/gimple-range-gori.cc
@@ -1452,109 +1452,6 @@  gori_compute::edge_range_p (vrange &r, edge e, tree name, range_query &q)
   return false;
 }
 
-// Given COND ? OP1 : OP2 with ranges R1 for OP1 and R2 for OP2, Use gori
-// to further resolve R1 and R2 if there are any dependencies between
-// OP1 and COND or OP2 and COND.  All values can are to be calculated using SRC
-// as the origination source location for operands..
-// Effectively, use COND an the edge condition and solve for OP1 on the true
-// edge and OP2 on the false edge.
-
-bool
-gori_compute::condexpr_adjust (vrange &r1, vrange &r2, gimple *, tree cond,
-			       tree op1, tree op2, fur_source &src)
-{
-  tree ssa1 = gimple_range_ssa_p (op1);
-  tree ssa2 = gimple_range_ssa_p (op2);
-  if (!ssa1 && !ssa2)
-    return false;
-  if (TREE_CODE (cond) != SSA_NAME)
-    return false;
-  gassign *cond_def = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (cond));
-  if (!cond_def
-      || TREE_CODE_CLASS (gimple_assign_rhs_code (cond_def)) != tcc_comparison)
-    return false;
-  tree type = TREE_TYPE (gimple_assign_rhs1 (cond_def));
-  if (!range_compatible_p (type, TREE_TYPE (gimple_assign_rhs2 (cond_def))))
-    return false;
-  range_op_handler hand (gimple_assign_rhs_code (cond_def));
-  if (!hand)
-    return false;
-
-  tree c1 = gimple_range_ssa_p (gimple_assign_rhs1 (cond_def));
-  tree c2 = gimple_range_ssa_p (gimple_assign_rhs2 (cond_def));
-
-  // Only solve if there is one SSA name in the condition.
-  if ((!c1 && !c2) || (c1 && c2))
-    return false;
-
-  // Pick up the current values of each part of the condition.
-  tree rhs1 = gimple_assign_rhs1 (cond_def);
-  tree rhs2 = gimple_assign_rhs2 (cond_def);
-  Value_Range cl (TREE_TYPE (rhs1));
-  Value_Range cr (TREE_TYPE (rhs2));
-  src.get_operand (cl, rhs1);
-  src.get_operand (cr, rhs2);
-
-  tree cond_name = c1 ? c1 : c2;
-  gimple *def_stmt = SSA_NAME_DEF_STMT (cond_name);
-
-  // Evaluate the value of COND_NAME on the true and false edges, using either
-  // the op1 or op2 routines based on its location.
-  Value_Range cond_true (type), cond_false (type);
-  if (c1)
-    {
-      if (!hand.op1_range (cond_false, type, m_bool_zero, cr))
-	return false;
-      if (!hand.op1_range (cond_true, type, m_bool_one, cr))
-	return false;
-      cond_false.intersect (cl);
-      cond_true.intersect (cl);
-    }
-  else
-    {
-      if (!hand.op2_range (cond_false, type, m_bool_zero, cl))
-	return false;
-      if (!hand.op2_range (cond_true, type, m_bool_one, cl))
-	return false;
-      cond_false.intersect (cr);
-      cond_true.intersect (cr);
-    }
-
-  unsigned idx;
-  if ((idx = tracer.header ("cond_expr evaluation : ")))
-    {
-      fprintf (dump_file, " range1 = ");
-      r1.dump (dump_file);
-      fprintf (dump_file, ", range2 = ");
-      r1.dump (dump_file);
-      fprintf (dump_file, "\n");
-    }
-
-   // Now solve for SSA1 or SSA2 if they are in the dependency chain.
-   if (ssa1 && m_map.in_chain_p (ssa1, cond_name))
-    {
-      Value_Range tmp1 (TREE_TYPE (ssa1));
-      if (compute_operand_range (tmp1, def_stmt, cond_true, ssa1, src))
-	r1.intersect (tmp1);
-    }
-  if (ssa2 && m_map.in_chain_p (ssa2, cond_name))
-    {
-      Value_Range tmp2 (TREE_TYPE (ssa2));
-      if (compute_operand_range (tmp2, def_stmt, cond_false, ssa2, src))
-	r2.intersect (tmp2);
-    }
-  if (idx)
-    {
-      tracer.print (idx, "outgoing: range1 = ");
-      r1.dump (dump_file);
-      fprintf (dump_file, ", range2 = ");
-      r1.dump (dump_file);
-      fprintf (dump_file, "\n");
-      tracer.trailer (idx, "cond_expr", true, cond_name, cond_true);
-    }
-  return true;
-}
-
 // Dump what is known to GORI computes to listing file F.
 
 void
diff --git a/gcc/gimple-range-gori.h b/gcc/gimple-range-gori.h
index aa8369a6823..9b4bcd919f5 100644
--- a/gcc/gimple-range-gori.h
+++ b/gcc/gimple-range-gori.h
@@ -168,8 +168,6 @@  public:
 		int max_sw_edges = 0);
   virtual ~gori_compute ();
   bool edge_range_p (vrange &r, edge e, tree name, range_query &q);
-  bool condexpr_adjust (vrange &r1, vrange &r2, gimple *s, tree cond, tree op1,
-			tree op2, fur_source &src);
   bool has_edge_range_p (tree name, basic_block bb = NULL);
   bool has_edge_range_p (tree name, edge e);
   void dump (FILE *f);
-- 
2.41.0