https://gcc.gnu.org/g:83bb9ad465f0c92c24658702804ee003183a9028

commit r15-808-g83bb9ad465f0c92c24658702804ee003183a9028
Author: Andrew MacLeod <amacl...@redhat.com>
Date:   Tue May 21 12:41:49 2024 -0400

    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.
            * gimple-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.

Diff:
---
 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);

Reply via email to