https://gcc.gnu.org/g:3be530f6d77ec24c94589341b069b199cfe6c2eb

commit r15-798-g3be530f6d77ec24c94589341b069b199cfe6c2eb
Author: Andrew MacLeod <amacl...@redhat.com>
Date:   Tue Apr 30 09:35:23 2024 -0400

    Move to an always available relation oracle.
    
    This eliminates the need to check if the relation oracle pointer is NULL
    before every call by providing a default oracle which does nothing.
    REmove unused routines, and Unify register_relation method names.
    
            * gimple-range-cache.cc (ranger_cache::dump_bb): Remove check for
            NULL oracle pointer.
            (ranger_cache::fill_block_cache): Likewise.
            * gimple-range-fold.cc (fur_stmt::get_phi_operand): Likewise.
            (fur_depend::fur_depend): Likewise.
            (fur_depend::register_relation): Likewise, use qury_relation.
            (fold_using_range::range_of_phi): Likewise.
            (fold_using_range::relation_fold_and_or): Likewise.
            * gimple-range-fold.h (fur_source::m_oracle): Delete.  Oracle
            can be accessed dirctly via m_query now.
            * gimple-range-path.cc (path_range_query::path_range_query):
            Adjust for oracle reference pointer.
            (path_range_query::compute_ranges): Likewise.
            (jt_fur_source::jt_fur_source): Adjust for no m_oracle member.
            (jt_fur_source::register_relation): Do not check for NULL
            pointer.
            (jt_fur_source::query_relation): Likewise.
            * gimple-range.cc (gimple_ranger::gimple_ranger):  Adjust for
            reference pointer.
            * value-query.cc (default_relation_oracle): New.
            (range_query::create_relation_oracle): Relocate from header.
            Ensure not being added to global query.
            (range_query::destroy_relation_oracle): Relocate from header.
            (range_query::range_query): Initailize to default oracle.
            (ange_query::~range_query): Call destroy_relation_oracle.
            * value-query.h (class range_query): Adjust prototypes.
            (range_query::create_relation_oracle): Move to source file.
            (range_query::destroy_relation_oracle): Move to source file.
            * value-relation.cc (relation_oracle::validate_relation): Delete.
            (relation_oracle::register_stmt): Rename to register_relation.
            (relation_oracle::register_edge): Likewise.
            * value-relation.h (register_stmt): Rename to register_relation and
            provide default function in base class.
            (register_edge): Likewise.
            (relation_oracle::validate_relation): Delete.
            (relation_oracle::query_relation): Provide default in base class.
            (relation_oracle::dump): Likewise.
            (relation_oracle::equiv_set): Likewise.
            (default_relation_oracle): New extenal reference.
            (partial_equiv_set, add_partial_equiv): Move to protected.

Diff:
---
 gcc/gimple-range-cache.cc | 98 +++++++++++++++++++++++------------------------
 gcc/gimple-range-fold.cc  | 22 +++--------
 gcc/gimple-range-fold.h   |  2 -
 gcc/gimple-range-path.cc  | 22 +++--------
 gcc/gimple-range.cc       |  5 ++-
 gcc/value-query.cc        | 38 ++++++++++++++++--
 gcc/value-query.h         | 31 ++-------------
 gcc/value-relation.cc     | 66 ++-----------------------------
 gcc/value-relation.h      | 32 ++++++++--------
 9 files changed, 119 insertions(+), 197 deletions(-)

diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc
index cf17a6af9db..020069fd635 100644
--- a/gcc/gimple-range-cache.cc
+++ b/gcc/gimple-range-cache.cc
@@ -1001,8 +1001,7 @@ ranger_cache::dump_bb (FILE *f, basic_block bb)
 {
   m_gori.gori_map::dump (f, bb, false);
   m_on_entry.dump (f, bb);
-  if (m_oracle)
-    m_oracle->dump (f, bb);
+  m_oracle->dump (f, bb);
 }
 
 // Get the global range for NAME, and return in R.  Return false if the
@@ -1437,62 +1436,59 @@ ranger_cache::fill_block_cache (tree name, basic_block 
bb, basic_block def_bb)
       // See if any equivalences can refine it.
       // PR 109462, like 108139 below, a one way equivalence introduced
       // by a PHI node can also be through the definition side.  Disallow it.
-      if (m_oracle)
+      tree equiv_name;
+      relation_kind rel;
+      int prec = TYPE_PRECISION (type);
+      FOR_EACH_PARTIAL_AND_FULL_EQUIV (m_oracle, bb, name, equiv_name, rel)
        {
-         tree equiv_name;
-         relation_kind rel;
-         int prec = TYPE_PRECISION (type);
-         FOR_EACH_PARTIAL_AND_FULL_EQUIV (m_oracle, bb, name, equiv_name, rel)
-           {
-             basic_block equiv_bb = gimple_bb (SSA_NAME_DEF_STMT (equiv_name));
+         basic_block equiv_bb = gimple_bb (SSA_NAME_DEF_STMT (equiv_name));
 
-             // Ignore partial equivs that are smaller than this object.
-             if (rel != VREL_EQ && prec > pe_to_bits (rel))
-               continue;
+         // Ignore partial equivs that are smaller than this object.
+         if (rel != VREL_EQ && prec > pe_to_bits (rel))
+           continue;
 
-             // Check if the equiv has any ranges calculated.
-             if (!m_gori.has_edge_range_p (equiv_name))
-               continue;
+         // Check if the equiv has any ranges calculated.
+         if (!m_gori.has_edge_range_p (equiv_name))
+           continue;
 
-             // Check if the equiv definition dominates this block
-             if (equiv_bb == bb ||
-                 (equiv_bb && !dominated_by_p (CDI_DOMINATORS, bb, equiv_bb)))
-               continue;
+         // Check if the equiv definition dominates this block
+         if (equiv_bb == bb ||
+             (equiv_bb && !dominated_by_p (CDI_DOMINATORS, bb, equiv_bb)))
+           continue;
 
-             if (DEBUG_RANGE_CACHE)
-               {
-                 if (rel == VREL_EQ)
-                   fprintf (dump_file, "Checking Equivalence (");
-                 else
-                   fprintf (dump_file, "Checking Partial equiv (");
-                 print_relation (dump_file, rel);
-                 fprintf (dump_file, ") ");
-                 print_generic_expr (dump_file, equiv_name, TDF_SLIM);
-                 fprintf (dump_file, "\n");
-               }
-             Value_Range equiv_range (TREE_TYPE (equiv_name));
-             if (range_from_dom (equiv_range, equiv_name, bb, RFD_READ_ONLY))
-               {
-                 if (rel != VREL_EQ)
-                   range_cast (equiv_range, type);
-                 else
-                   adjust_equivalence_range (equiv_range);
+         if (DEBUG_RANGE_CACHE)
+           {
+             if (rel == VREL_EQ)
+               fprintf (dump_file, "Checking Equivalence (");
+             else
+               fprintf (dump_file, "Checking Partial equiv (");
+             print_relation (dump_file, rel);
+             fprintf (dump_file, ") ");
+             print_generic_expr (dump_file, equiv_name, TDF_SLIM);
+             fprintf (dump_file, "\n");
+           }
+         Value_Range equiv_range (TREE_TYPE (equiv_name));
+         if (range_from_dom (equiv_range, equiv_name, bb, RFD_READ_ONLY))
+           {
+             if (rel != VREL_EQ)
+               range_cast (equiv_range, type);
+             else
+               adjust_equivalence_range (equiv_range);
 
-                 if (block_result.intersect (equiv_range))
+             if (block_result.intersect (equiv_range))
+               {
+                 if (DEBUG_RANGE_CACHE)
                    {
-                     if (DEBUG_RANGE_CACHE)
-                       {
-                         if (rel == VREL_EQ)
-                           fprintf (dump_file, "Equivalence update! :  ");
-                         else
-                           fprintf (dump_file, "Partial equiv update! :  ");
-                         print_generic_expr (dump_file, equiv_name, TDF_SLIM);
-                         fprintf (dump_file, " has range  :  ");
-                         equiv_range.dump (dump_file);
-                         fprintf (dump_file, " refining range to :");
-                         block_result.dump (dump_file);
-                         fprintf (dump_file, "\n");
-                       }
+                     if (rel == VREL_EQ)
+                       fprintf (dump_file, "Equivalence update! :  ");
+                     else
+                       fprintf (dump_file, "Partial equiv update! :  ");
+                     print_generic_expr (dump_file, equiv_name, TDF_SLIM);
+                     fprintf (dump_file, " has range  :  ");
+                     equiv_range.dump (dump_file);
+                     fprintf (dump_file, " refining range to :");
+                     block_result.dump (dump_file);
+                     fprintf (dump_file, "\n");
                    }
                }
            }
diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc
index 41b6d350c40..eeffdce0b97 100644
--- a/gcc/gimple-range-fold.cc
+++ b/gcc/gimple-range-fold.cc
@@ -178,10 +178,7 @@ fur_stmt::get_phi_operand (vrange &r, tree expr, edge e)
 relation_kind
 fur_stmt::query_relation (tree op1, tree op2)
 {
-  relation_oracle *oracle = m_query->oracle ();
-  if (!oracle)
-    return VREL_VARYING;
-  return oracle->query_relation (m_stmt, op1, op2);
+  return m_query->oracle ().query_relation (m_stmt, op1, op2);
 }
 
 // Instantiate a stmt based fur_source with a GORI object.
@@ -192,10 +189,6 @@ fur_depend::fur_depend (gimple *s, gori_compute *gori, 
range_query *q)
 {
   gcc_checking_assert (gori);
   m_gori = gori;
-  // Set relations if there is an oracle in the range_query.
-  // This will enable registering of relationships as they are discovered.
-  m_oracle = q->oracle ();
-
 }
 
 // Register a relation on a stmt if there is an oracle.
@@ -203,8 +196,7 @@ fur_depend::fur_depend (gimple *s, gori_compute *gori, 
range_query *q)
 void
 fur_depend::register_relation (gimple *s, relation_kind k, tree op1, tree op2)
 {
-  if (m_oracle)
-    m_oracle->register_stmt (s, k, op1, op2);
+  m_query->oracle ().register_relation (s, k, op1, op2);
 }
 
 // Register a relation on an edge if there is an oracle.
@@ -212,8 +204,7 @@ fur_depend::register_relation (gimple *s, relation_kind k, 
tree op1, tree op2)
 void
 fur_depend::register_relation (edge e, relation_kind k, tree op1, tree op2)
 {
-  if (m_oracle)
-    m_oracle->register_edge (e, k, op1, op2);
+  m_query->oracle ().register_relation (e, k, op1, op2);
 }
 
 // This version of fur_source will pick a range up from a list of ranges
@@ -863,7 +854,7 @@ fold_using_range::range_of_phi (vrange &r, gphi *phi, 
fur_source &src)
   tree single_arg = NULL_TREE;
   bool seen_arg = false;
 
-  relation_oracle *oracle = src.query()->oracle ();
+  relation_oracle *oracle = &(src.query()->oracle ());
   // Start with an empty range, unioning in each argument's range.
   r.set_undefined ();
   for (x = 0; x < gimple_phi_num_args (phi); x++)
@@ -884,8 +875,7 @@ fold_using_range::range_of_phi (vrange &r, gphi *phi, 
fur_source &src)
          // Likewise, if the incoming PHI argument is equivalent to this
          // PHI definition, it provides no new info.  Accumulate these ranges
          // in case all arguments are equivalences.
-         if (oracle
-             && oracle->query_relation (e, arg, phi_def) == VREL_EQ)
+         if (oracle->query_relation (e, arg, phi_def) == VREL_EQ)
            equiv_range.union_(arg_range);
          else
            r.union_ (arg_range);
@@ -1135,7 +1125,7 @@ fold_using_range::relation_fold_and_or (irange& 
lhs_range, gimple *s,
                                        vrange &op2)
 {
   // No queries or already folded.
-  if (!src.gori () || !src.query ()->oracle () || lhs_range.singleton_p ())
+  if (!src.gori () || lhs_range.singleton_p ())
     return;
 
   // Only care about AND and OR expressions.
diff --git a/gcc/gimple-range-fold.h b/gcc/gimple-range-fold.h
index c7c599bfc93..1925fb899e3 100644
--- a/gcc/gimple-range-fold.h
+++ b/gcc/gimple-range-fold.h
@@ -138,8 +138,6 @@ public:
                                  tree op2) override;
   virtual void register_relation (edge e, relation_kind k, tree op1,
                                  tree op2) override;
-protected:
-  relation_oracle *m_oracle;
 };
 
 // This class uses ranges to fold a gimple statement producing a range for
diff --git a/gcc/gimple-range-path.cc b/gcc/gimple-range-path.cc
index ef3db10470e..cf7e0409098 100644
--- a/gcc/gimple-range-path.cc
+++ b/gcc/gimple-range-path.cc
@@ -44,7 +44,7 @@ path_range_query::path_range_query (gimple_ranger &ranger,
     m_ranger (ranger),
     m_resolve (resolve)
 {
-  m_oracle = new path_oracle (m_ranger.oracle ());
+  m_oracle = new path_oracle (&(m_ranger.oracle ()));
 
   reset_path (path, dependencies);
 }
@@ -54,7 +54,7 @@ path_range_query::path_range_query (gimple_ranger &ranger, 
bool resolve)
     m_ranger (ranger),
     m_resolve (resolve)
 {
-  m_oracle = new path_oracle (m_ranger.oracle ());
+  m_oracle = new path_oracle (&(m_ranger.oracle ()));
 }
 
 path_range_query::~path_range_query ()
@@ -563,7 +563,7 @@ path_range_query::compute_ranges (const bitmap_head 
*dependencies)
   if (m_resolve)
     {
       path_oracle *p = get_path_oracle ();
-      p->reset_path (m_ranger.oracle ());
+      p->reset_path (&(m_ranger.oracle ()));
     }
 
   if (DEBUG_SOLVER)
@@ -629,11 +629,6 @@ jt_fur_source::jt_fur_source (gimple *s,
   gcc_checking_assert (!path.is_empty ());
 
   m_entry = path[path.length () - 1];
-
-  if (dom_info_available_p (CDI_DOMINATORS))
-    m_oracle = query->oracle ();
-  else
-    m_oracle = NULL;
 }
 
 // Ignore statement and register relation on entry to path.
@@ -641,8 +636,7 @@ jt_fur_source::jt_fur_source (gimple *s,
 void
 jt_fur_source::register_relation (gimple *, relation_kind k, tree op1, tree 
op2)
 {
-  if (m_oracle)
-    m_oracle->register_relation (m_entry, k, op1, op2);
+  m_query->oracle ().register_relation (m_entry, k, op1, op2);
 }
 
 // Ignore edge and register relation on entry to path.
@@ -650,20 +644,16 @@ jt_fur_source::register_relation (gimple *, relation_kind 
k, tree op1, tree op2)
 void
 jt_fur_source::register_relation (edge, relation_kind k, tree op1, tree op2)
 {
-  if (m_oracle)
-    m_oracle->register_relation (m_entry, k, op1, op2);
+  m_query->oracle ().register_relation (m_entry, k, op1, op2);
 }
 
 relation_kind
 jt_fur_source::query_relation (tree op1, tree op2)
 {
-  if (!m_oracle)
-    return VREL_VARYING;
-
   if (TREE_CODE (op1) != SSA_NAME || TREE_CODE (op2) != SSA_NAME)
     return VREL_VARYING;
 
-  return m_oracle->query_relation (m_entry, op1, op2);
+  return m_query->oracle().query_relation (m_entry, op1, op2);
 }
 
 // Return the range of STMT at the end of the path being analyzed.
diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc
index 22e8add5de1..24ffd63c89b 100644
--- a/gcc/gimple-range.cc
+++ b/gcc/gimple-range.cc
@@ -43,8 +43,8 @@ gimple_ranger::gimple_ranger (bool use_imm_uses) :
        tracer (""),
        current_bb (NULL)
 {
-  // If the cache has a relation oracle, use it.
-  m_oracle = m_cache.oracle ();
+  // Share the oracle from the cache.
+  m_oracle = &m_cache.oracle ();
   if (dump_file && (param_ranger_debug & RANGER_DEBUG_TRACE))
     tracer.enable_trace ();
   m_stmt_list.create (0);
@@ -67,6 +67,7 @@ gimple_ranger::gimple_ranger (bool use_imm_uses) :
 
 gimple_ranger::~gimple_ranger ()
 {
+  // Restore the original oracle.
   m_oracle = NULL;
   m_stmt_list.release ();
 }
diff --git a/gcc/value-query.cc b/gcc/value-query.cc
index b275a43b679..03ce574bcb5 100644
--- a/gcc/value-query.cc
+++ b/gcc/value-query.cc
@@ -178,15 +178,47 @@ range_query::dump (FILE *)
 {
 }
 
+// Default oracle for all range queries.  This contains no storage and thus
+// can be used anywhere.
+relation_oracle default_relation_oracle;
+
+// Create dominance based range oracle for the current query if dom info is
+// available.
+
+void
+range_query::create_relation_oracle ()
+{
+  gcc_checking_assert (this != &global_ranges);
+  gcc_checking_assert (m_oracle == &default_relation_oracle);
+
+  if (!dom_info_available_p (CDI_DOMINATORS))
+    return;
+  m_oracle = new dom_oracle ();
+  gcc_checking_assert (m_oracle);
+}
+
+// Destroy any relation oracle that was created.
+
+void
+range_query::destroy_relation_oracle ()
+{
+  // m_oracle can be NULL if a derived range_query class took care of
+  // disposing its own oracle.
+  if (m_oracle && m_oracle != &default_relation_oracle)
+    {
+      delete m_oracle;
+      m_oracle = &default_relation_oracle;
+    }
+}
+
 range_query::range_query ()
 {
-  m_oracle = NULL;
+  m_oracle = &default_relation_oracle;
 }
 
 range_query::~range_query ()
 {
-  if (m_oracle)
-    destroy_relation_oracle ();
+  destroy_relation_oracle ();
 }
 
 // This routine will invoke the equivalent of range_of_expr on
diff --git a/gcc/value-query.h b/gcc/value-query.h
index 9df89905ace..ed355bedfa8 100644
--- a/gcc/value-query.h
+++ b/gcc/value-query.h
@@ -75,12 +75,12 @@ public:
   virtual bool range_on_entry (vrange &r, basic_block bb, tree expr);
   virtual bool range_on_exit (vrange &r, basic_block bb, tree expr);
 
-  inline relation_oracle *oracle () const  { return m_oracle; }
+  inline class relation_oracle &oracle () const  { return *m_oracle; }
+  void create_relation_oracle ();
+  void destroy_relation_oracle ();
 
   virtual void dump (FILE *);
 
-  void create_relation_oracle ();
-  void destroy_relation_oracle ();
 protected:
   bool get_tree_range (vrange &v, tree expr, gimple *stmt,
                       basic_block bbentry = NULL, basic_block bbexit = NULL);
@@ -118,29 +118,4 @@ get_range_query (const struct function *fun)
 // Query the global range of NAME in function F.  Default to cfun.
 extern void gimple_range_global (vrange &v, tree name,
                                 struct function *f = cfun);
-
-// Create dominance based range oracle for the current query if dom info is
-// available.
-
-inline void
-range_query::create_relation_oracle ()
-{
-  if (!dom_info_available_p (CDI_DOMINATORS))
-    return;
-  gcc_checking_assert (m_oracle == NULL);
-  m_oracle = new dom_oracle ();
-}
-
-// Destroy any relation oracle that was created.
-
-inline void
-range_query::destroy_relation_oracle ()
-{
-  if (m_oracle != NULL)
-    {
-      delete m_oracle;
-      m_oracle = NULL;
-    }
-}
-
 #endif // GCC_QUERY_H
diff --git a/gcc/value-relation.cc b/gcc/value-relation.cc
index d1081b3b3f5..fac15613945 100644
--- a/gcc/value-relation.cc
+++ b/gcc/value-relation.cc
@@ -208,66 +208,6 @@ static const tree_code relation_to_code [VREL_LAST] = {
   ERROR_MARK, ERROR_MARK, LT_EXPR, LE_EXPR, GT_EXPR, GE_EXPR, EQ_EXPR,
   NE_EXPR };
 
-// This routine validates that a relation can be applied to a specific set of
-// ranges.  In particular, floating point x == x may not be true if the NaN bit
-// is set in the range.  Symbolically the oracle will determine x == x,
-// but specific range instances may override this.
-// To verify, attempt to fold the relation using the supplied ranges.
-// One would expect [1,1] to be returned, anything else means there is 
something
-// in the range preventing the relation from applying.
-// If there is no mechanism to verify, assume the relation is acceptable.
-
-relation_kind
-relation_oracle::validate_relation (relation_kind rel, vrange &op1, vrange 
&op2)
-{
-  // If there is no mapping to a tree code, leave the relation as is.
-  tree_code code = relation_to_code [rel];
-  if (code == ERROR_MARK)
-    return rel;
-
-  // Undefined ranges cannot be checked either.
-  if (op1.undefined_p () || op2.undefined_p ())
-    return rel;
-
-  tree t1 = op1.type ();
-  tree t2 = op2.type ();
-
-  // If the range types are not compatible, no relation can exist.
-  if (!range_compatible_p (t1, t2))
-    return VREL_VARYING;
-
-  // If there is no handler, leave the relation as is.
-  range_op_handler handler (code);
-  if (!handler)
-    return rel;
-
-  // If the relation cannot be folded for any reason, leave as is.
-  Value_Range result (boolean_type_node);
-  if (!handler.fold_range (result, boolean_type_node, op1, op2,
-                          relation_trio::op1_op2 (rel)))
-    return rel;
-
-  // The expression op1 REL op2 using REL should fold to [1,1].
-  // Any other result means the relation is not verified to be true.
-  if (result.varying_p () || result.zero_p ())
-    return VREL_VARYING;
-
-  return rel;
-}
-
-// If no range is available, create a varying range for each SSA name and
-// verify.
-
-relation_kind
-relation_oracle::validate_relation (relation_kind rel, tree ssa1, tree ssa2)
-{
-  Value_Range op1, op2;
-  op1.set_varying (TREE_TYPE (ssa1));
-  op2.set_varying (TREE_TYPE (ssa2));
-
-  return validate_relation (rel, op1, op2);
-}
-
 // Given an equivalence set EQUIV, set all the bits in B that are still valid
 // members of EQUIV in basic block BB.
 
@@ -1058,8 +998,8 @@ dom_oracle::~dom_oracle ()
 // Register relation K between ssa_name OP1 and OP2 on STMT.
 
 void
-relation_oracle::register_stmt (gimple *stmt, relation_kind k, tree op1,
-                               tree op2)
+relation_oracle::register_relation (gimple *stmt, relation_kind k, tree op1,
+                                   tree op2)
 {
   gcc_checking_assert (TREE_CODE (op1) == SSA_NAME);
   gcc_checking_assert (TREE_CODE (op2) == SSA_NAME);
@@ -1106,7 +1046,7 @@ relation_oracle::register_stmt (gimple *stmt, 
relation_kind k, tree op1,
 // Register relation K between ssa_name OP1 and OP2 on edge E.
 
 void
-relation_oracle::register_edge (edge e, relation_kind k, tree op1, tree op2)
+relation_oracle::register_relation (edge e, relation_kind k, tree op1, tree 
op2)
 {
   gcc_checking_assert (TREE_CODE (op1) == SSA_NAME);
   gcc_checking_assert (TREE_CODE (op2) == SSA_NAME);
diff --git a/gcc/value-relation.h b/gcc/value-relation.h
index 5adf736cf41..528f00aecbb 100644
--- a/gcc/value-relation.h
+++ b/gcc/value-relation.h
@@ -98,37 +98,37 @@ class relation_oracle
 {
 public:
   virtual ~relation_oracle () { }
-  // register a relation between 2 ssa names at a stmt.
-  void register_stmt (gimple *, relation_kind, tree, tree);
-  // register a relation between 2 ssa names on an edge.
-  void register_edge (edge, relation_kind, tree, tree);
 
-  // register a relation between 2 ssa names in a basic block.
-  virtual void register_relation (basic_block, relation_kind, tree, tree) = 0;
+  // register a relation between 2 ssa names.
+  void register_relation (gimple *, relation_kind, tree, tree);
+  void register_relation (edge, relation_kind, tree, tree);
+  virtual void register_relation (basic_block, relation_kind, tree, tree) { }
+
   // Query if there is any relation between SSA1 and SSA2.
-  virtual relation_kind query_relation (basic_block, tree, tree) = 0;
   relation_kind query_relation (gimple *s, tree ssa1, tree ssa2);
   relation_kind query_relation (edge e, tree ssa1, tree ssa2);
+  virtual relation_kind query_relation (basic_block, tree, tree)
+    { return VREL_VARYING; }
 
-  relation_kind validate_relation (relation_kind, tree, tree);
-  relation_kind validate_relation (relation_kind, vrange &, vrange &);
-
-  virtual void dump (FILE *, basic_block) const = 0;
-  virtual void dump (FILE *) const = 0;
+  virtual void dump (FILE *, basic_block) const { }
+  virtual void dump (FILE *) const  { }
   void debug () const;
 protected:
   friend class equiv_relation_iterator;
   // Return equivalency set for an SSA name in a basic block.
-  virtual const_bitmap equiv_set (tree, basic_block) = 0;
+  virtual const_bitmap equiv_set (tree, basic_block) { return NULL; }
   // Return partial equivalency record for an SSA name.
   virtual const class pe_slice *partial_equiv_set (tree) { return NULL; }
   void valid_equivs (bitmap b, const_bitmap equivs, basic_block bb);
   // Query for a relation between two equivalency sets in a basic block.
   virtual relation_kind query_relation (basic_block, const_bitmap,
-                                       const_bitmap) = 0;
+                                       const_bitmap) { return VREL_VARYING; }
   friend class path_oracle;
 };
 
+// Instance with no storage used for default queries with no active oracle.
+extern relation_oracle default_relation_oracle;
+
 // This class represents an equivalency set, and contains a link to the next
 // one in the list to be searched.
 
@@ -162,11 +162,9 @@ public:
   ~equiv_oracle ();
 
   const_bitmap equiv_set (tree ssa, basic_block bb) final override;
-  const pe_slice *partial_equiv_set (tree name) final override;
   void register_relation (basic_block bb, relation_kind k, tree ssa1,
                          tree ssa2) override;
 
-  void add_partial_equiv (relation_kind, tree, tree);
   relation_kind partial_equiv (tree ssa1, tree ssa2, tree *base = NULL) const;
   relation_kind query_relation (basic_block, tree, tree) override;
   relation_kind query_relation (basic_block, const_bitmap, const_bitmap)
@@ -175,6 +173,8 @@ public:
   void dump (FILE *f) const override;
 
 protected:
+  void add_partial_equiv (relation_kind, tree, tree);
+  const pe_slice *partial_equiv_set (tree name) final override;
   inline bool has_equiv_p (unsigned v) { return bitmap_bit_p (m_equiv_set, v); 
}
   bitmap_obstack m_bitmaps;
   struct obstack m_chain_obstack;

Reply via email to