]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Return true when a value_relation is added.
authorAndrew MacLeod <amacleod@redhat.com>
Tue, 2 Dec 2025 15:12:24 +0000 (10:12 -0500)
committerAndrew MacLeod <amacleod@redhat.com>
Wed, 3 Dec 2025 14:59:49 +0000 (09:59 -0500)
relation_oracle::record does not indicate whether a relation was added.
Add a boolean return and only update timestamps when a relation is actually
added.

PR tree-optimization/122898
gcc/
* gimple-range-fold.cc (fur_source::register_relation): Return a bool;
(fur_depend::register_relation): Ditto.
(fur_relation::register_relation): Ditto.
* gimple-range-fold.h (fur_source::register_relation): Adjust prototype.
(fur_depend::register_relation): Ditto.
* gimple-range-path.cc (jt_fur_source::register_relation): Return bool.
* value-relation.cc (equiv_oracle::add_partial_equiv): Return a bool.
(equiv_oracle::record): Return a bool.
(relation_oracle::record): Return a bool.
(dom_oracle::record): Return a bool.
(dom_oracle::set_one_relation): Remove some debug output.
(path_oracle::equiv_set): Return a bool.
(path_oracle::register_equiv): Return a bool.
(path_oracle::record): Return a bool.
* value-relation.h (relation_oracle::record): Adjust prototype.
(equiv_oracle::add_partial_equiv): Ditto
(equiv_oracle::record): Ditto.
(dom_oracle::record): Ditto.
(path_oracle::equiv_set): Ditto.
(path_oracle::register_equiv): Ditto.
(path_oracle::record): Ditto.

gcc/testsuite
* gcc.dg/pr122898.c: New.

gcc/gimple-range-fold.cc
gcc/gimple-range-fold.h
gcc/gimple-range-path.cc
gcc/testsuite/gcc.dg/pr122898.c [new file with mode: 0644]
gcc/value-relation.cc
gcc/value-relation.h

index bd5e53516b79101659cb0c35eba5eb89210fa6ff..ad11074c14b73bc677a2083dcc6bd8e6ab3ed59d 100644 (file)
@@ -89,24 +89,26 @@ fur_source::query_relation (tree op1 ATTRIBUTE_UNUSED,
   return VREL_VARYING;
 }
 
-// Default registers nothing.
+// Default registers nothing and returns false meaning nothing changed.
 
-void
+bool
 fur_source::register_relation (gimple *s ATTRIBUTE_UNUSED,
                               relation_kind k ATTRIBUTE_UNUSED,
                               tree op1 ATTRIBUTE_UNUSED,
                               tree op2 ATTRIBUTE_UNUSED)
 {
+  return false;
 }
 
-// Default registers nothing.
+// Default registers nothing and returns false meaning nothing changed.
 
-void
+bool
 fur_source::register_relation (edge e ATTRIBUTE_UNUSED,
                               relation_kind k ATTRIBUTE_UNUSED,
                               tree op1 ATTRIBUTE_UNUSED,
                               tree op2 ATTRIBUTE_UNUSED)
 {
+  return false;
 }
 
 // Get the value of EXPR on edge m_edge.
@@ -170,12 +172,15 @@ fur_depend::fur_depend (gimple *s, range_query *q, ranger_cache *c)
   m_depend_p = true;
 }
 
-// Register a relation on a stmt if there is an oracle.
+// Register a relation on a stmt if there is an oracle.  Return false if
+// no new relation is registered.
 
-void
+bool
 fur_depend::register_relation (gimple *s, relation_kind k, tree op1, tree op2)
 {
-  m_query->relation ().record (s, k, op1, op2);
+  if (!m_query->relation ().record (s, k, op1, op2))
+    return false;
+
   // This new relation could cause different calculations, so mark the operands
   // with a new timestamp, forcing recalculations.
   if (m_cache)
@@ -183,14 +188,18 @@ fur_depend::register_relation (gimple *s, relation_kind k, tree op1, tree op2)
       m_cache->update_consumers (op1);
       m_cache->update_consumers (op2);
     }
+  return true;
 }
 
-// Register a relation on an edge if there is an oracle.
+// Register a relation on an edge if there is an oracle.  Return false if
+// no new relation is registered.
 
-void
+bool
 fur_depend::register_relation (edge e, relation_kind k, tree op1, tree op2)
 {
-  m_query->relation ().record (e, k, op1, op2);
+  if (!m_query->relation ().record (e, k, op1, op2))
+    return false;
+
   // This new relation could cause different calculations, so mark the operands
   // with a new timestamp, forcing recalculations.
   if (m_cache)
@@ -198,6 +207,7 @@ fur_depend::register_relation (edge e, relation_kind k, tree op1, tree op2)
       m_cache->update_consumers (op1);
       m_cache->update_consumers (op2);
     }
+  return true;
 }
 
 // This version of fur_source will pick a range up from a list of ranges
@@ -400,9 +410,9 @@ class fur_relation : public fur_stmt
 {
 public:
   fur_relation (gimple *s, range_query *q = NULL);
-  virtual void register_relation (gimple *stmt, relation_kind k, tree op1,
+  virtual bool register_relation (gimple *stmt, relation_kind k, tree op1,
                                  tree op2);
-  virtual void register_relation (edge e, relation_kind k, tree op1,
+  virtual bool register_relation (edge e, relation_kind k, tree op1,
                                  tree op2);
   relation_trio trio() const;
 private:
@@ -423,15 +433,18 @@ fur_relation::trio () const
 }
 
 // Don't support edges, but avoid a compiler warning by providing the routine.
+// Return false indicating nothing has changed.
 
-void
+bool
 fur_relation::register_relation (edge, relation_kind, tree, tree)
 {
+  return false;
 }
 
-// Register relation K between OP1 and OP2 on STMT.
+// Register relation K between OP1 and OP2 on STMT.  Return false if there
+// is no relation.
 
-void
+bool
 fur_relation::register_relation (gimple *stmt, relation_kind k, tree op1,
                                 tree op2)
 {
@@ -475,6 +488,8 @@ fur_relation::register_relation (gimple *stmt, relation_kind k, tree op1,
       else if (op2 == a1 && op1 == a2)
        op1_op2 = relation_swap (k);
     }
+  return def_op1 == VREL_VARYING && def_op2 == VREL_VARYING
+        && op1_op2 == VREL_VARYING;
 }
 
 // Return the relation trio for stmt S using query Q.
index 760a107821a9c39951975230ca5771103300bb72..54c1d169b9b45239daefbfe5e20b0c7f90e71289 100644 (file)
@@ -113,9 +113,9 @@ public:
   virtual bool get_operand (vrange &r, tree expr);
   virtual bool get_phi_operand (vrange &r, tree expr, edge e);
   virtual relation_kind query_relation (tree op1, tree op2);
-  virtual void register_relation (gimple *stmt, relation_kind k, tree op1,
+  virtual bool register_relation (gimple *stmt, relation_kind k, tree op1,
                                  tree op2);
-  virtual void register_relation (edge e, relation_kind k, tree op1,
+  virtual bool register_relation (edge e, relation_kind k, tree op1,
                                  tree op2);
   void register_outgoing_edges (gcond *, irange &lhs_range, edge e0, edge e1);
 protected:
@@ -144,9 +144,9 @@ class fur_depend : public fur_stmt
 {
 public:
   fur_depend (gimple *s, range_query *q = NULL, class ranger_cache *c = NULL);
-  virtual void register_relation (gimple *stmt, relation_kind k, tree op1,
+  virtual bool register_relation (gimple *stmt, relation_kind k, tree op1,
                                  tree op2) override;
-  virtual void register_relation (edge e, relation_kind k, tree op1,
+  virtual bool register_relation (edge e, relation_kind k, tree op1,
                                  tree op2) override;
 private:
   ranger_cache *m_cache;
index 625622d45aa5530ed508c9bf242c5d6c39ee0299..823130c35ec5b8a9b7a81ee386a91d8f4ed5b32b 100644 (file)
@@ -615,8 +615,8 @@ class jt_fur_source : public fur_depend
 public:
   jt_fur_source (gimple *s, path_range_query *, const vec<basic_block> &);
   relation_kind query_relation (tree op1, tree op2) override;
-  void register_relation (gimple *, relation_kind, tree op1, tree op2) override;
-  void register_relation (edge, relation_kind, tree op1, tree op2) override;
+  bool register_relation (gimple *, relation_kind, tree op1, tree op2) override;
+  bool register_relation (edge, relation_kind, tree op1, tree op2) override;
 private:
   basic_block m_entry;
 };
@@ -631,20 +631,22 @@ jt_fur_source::jt_fur_source (gimple *s,
   m_entry = path[path.length () - 1];
 }
 
-// Ignore statement and register relation on entry to path.
+// Ignore statement and register relation on entry to path.  Return false if
+// no new relation is registered.
 
-void
+bool
 jt_fur_source::register_relation (gimple *, relation_kind k, tree op1, tree op2)
 {
-  m_query->relation ().record (m_entry, k, op1, op2);
+  return m_query->relation ().record (m_entry, k, op1, op2);
 }
 
-// Ignore edge and register relation on entry to path.
+// Ignore edge and register relation on entry to path.  Return false if no
+// new relation is registered.
 
-void
+bool
 jt_fur_source::register_relation (edge, relation_kind k, tree op1, tree op2)
 {
-  m_query->relation ().record (m_entry, k, op1, op2);
+  return m_query->relation ().record (m_entry, k, op1, op2);
 }
 
 relation_kind
diff --git a/gcc/testsuite/gcc.dg/pr122898.c b/gcc/testsuite/gcc.dg/pr122898.c
new file mode 100644 (file)
index 0000000..8b89c82
--- /dev/null
@@ -0,0 +1,56 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fno-tree-forwprop -fno-tree-fre" } */
+extern void o();
+int a, b, c, d, e, f, g, h, i, k, l, m, n;
+volatile int j;
+static void p() {
+  if (d) {
+  q:
+    if (a) {
+      if (k) {
+        if (!(d && e))
+          goto r;
+        if (i)
+          goto q;
+        o();
+      }
+      h || j;
+    }
+  s:
+    d || j;
+    if (a)
+      goto q;
+  r:
+    if (b) {
+      if (c)
+        goto t;
+      if (b)
+        goto r;
+      if (m)
+        goto q;
+    }
+    while (j)
+      ;
+  u:
+    if (g) {
+      o();
+      goto s;
+    }
+    if (h) {
+    t:
+      if (n)
+        goto v;
+      o();
+      goto r;
+    }
+    int w = i & 1;
+  v:
+    if (w <= l)
+      if (f)
+        goto u;
+    goto q;
+  }
+  if (a)
+    goto v;
+}
+int main() { p(); }
index 2ac7650fe5b4d5daaacf146eca307dfb0a8d2153..c96d438caf4dafbdb37b1e5c1f012bdabe2e0ec2 100644 (file)
@@ -334,9 +334,10 @@ equiv_oracle::~equiv_oracle ()
   bitmap_obstack_release (&m_bitmaps);
 }
 
-// Add a partial equivalence R between OP1 and OP2.
+// Add a partial equivalence R between OP1 and OP2.  Return false if no
+// new relation is added.
 
-void
+bool
 equiv_oracle::add_partial_equiv (relation_kind r, tree op1, tree op2)
 {
   int v1 = SSA_NAME_VERSION (op1);
@@ -359,10 +360,10 @@ equiv_oracle::add_partial_equiv (relation_kind r, tree op1, tree op2)
       // being re-evaluated, or the def was used before being registered.
       // In either case, if PE2 has an entry, we simply do nothing.
       if (pe2.members)
-       return;
+       return false;
       // If there are no uses of op2, do not register.
       if (has_zero_uses (op2))
-       return;
+       return false;
       // PE1 is the LHS and already has members, so everything in the set
       // should be a slice of PE2 rather than PE1.
       pe2.code = pe_min (r, pe1.code);
@@ -376,13 +377,13 @@ equiv_oracle::add_partial_equiv (relation_kind r, tree op1, tree op2)
          m_partial[x].code = pe_min (m_partial[x].code, pe2.code);
        }
       bitmap_set_bit (pe1.members, v2);
-      return;
+      return true;
     }
   if (pe2.members)
     {
       // If there are no uses of op1, do not register.
       if (has_zero_uses (op1))
-       return;
+       return false;
       pe1.ssa_base = pe2.ssa_base;
       // If pe2 is a 16 bit value, but only an 8 bit copy, we can't be any
       // more than an 8 bit equivalence here, so choose MIN value.
@@ -394,11 +395,11 @@ equiv_oracle::add_partial_equiv (relation_kind r, tree op1, tree op2)
     {
       // If there are no uses of either operand, do not register.
       if (has_zero_uses (op1) || has_zero_uses (op2))
-       return;
+       return false;
       // Neither name has an entry, simply create op1 as slice of op2.
       pe2.code = bits_to_pe (TYPE_PRECISION (TREE_TYPE (op2)));
       if (pe2.code == VREL_VARYING)
-       return;
+       return false;
       pe2.ssa_base = op2;
       pe2.members = BITMAP_ALLOC (&m_bitmaps);
       bitmap_set_bit (pe2.members, v2);
@@ -407,6 +408,7 @@ equiv_oracle::add_partial_equiv (relation_kind r, tree op1, tree op2)
       pe1.members = pe2.members;
       bitmap_set_bit (pe1.members, v1);
     }
+  return true;
 }
 
 // Return the set of partial equivalences associated with NAME.  The bitmap
@@ -621,19 +623,18 @@ equiv_oracle::register_initial_def (tree ssa)
 // a query is made as to what equivalences both names have already, and
 // any preexisting equivalences are merged to create a single equivalence
 // containing all the ssa_names in this basic block.
+// Return false if no new relation is added.
 
-void
+bool
 equiv_oracle::record (basic_block bb, relation_kind k, tree ssa1, tree ssa2)
 {
   // Process partial equivalencies.
   if (relation_partial_equiv_p (k))
-    {
-      add_partial_equiv (k, ssa1, ssa2);
-      return;
-    }
+    return add_partial_equiv (k, ssa1, ssa2);
+
   // Only handle equality relations.
   if (k != VREL_EQ)
-    return;
+    return false;
 
   unsigned v1 = SSA_NAME_VERSION (ssa1);
   unsigned v2 = SSA_NAME_VERSION (ssa2);
@@ -650,7 +651,7 @@ equiv_oracle::record (basic_block bb, relation_kind k, tree ssa1, tree ssa2)
 
   // Check if they are the same set
   if (equiv_1 && equiv_1 == equiv_2)
-    return;
+    return false;
 
   bitmap equiv_set;
 
@@ -674,9 +675,10 @@ equiv_oracle::record (basic_block bb, relation_kind k, tree ssa1, tree ssa2)
   // A non-null return is a bitmap that is to be added to the current
   // block as a new equivalence.
   if (!equiv_set)
-    return;
+    return false;
 
   add_equiv_to_block (bb, equiv_set);
+  return true;
 }
 
 // Add an equivalency record in block BB containing bitmap EQUIV_SET.
@@ -1073,8 +1075,9 @@ dom_oracle::~dom_oracle ()
 }
 
 // Register relation K between ssa_name OP1 and OP2 on STMT.
+// Return false if no new relation is added.
 
-void
+bool
 relation_oracle::record (gimple *stmt, relation_kind k, tree op1, tree op2)
 {
   gcc_checking_assert (TREE_CODE (op1) == SSA_NAME);
@@ -1083,16 +1086,7 @@ relation_oracle::record (gimple *stmt, relation_kind k, tree op1, tree op2)
 
   // Don't register lack of a relation.
   if (k == VREL_VARYING)
-    return;
-
-  if (dump_file && (dump_flags & TDF_DETAILS))
-    {
-      value_relation vr (k, op1, op2);
-      fprintf (dump_file, " Registering value_relation ");
-      vr.dump (dump_file);
-      fprintf (dump_file, " (bb%d) at ", gimple_bb (stmt)->index);
-      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
-    }
+    return false;
 
   // If an equivalence is being added between a PHI and one of its arguments
   // make sure that that argument is not defined in the same block.
@@ -1106,22 +1100,26 @@ relation_oracle::record (gimple *stmt, relation_kind k, tree op1, tree op2)
       if (phi_def == op2)
        arg = op1;
       if (gimple_bb (stmt) == gimple_bb (SSA_NAME_DEF_STMT (arg)))
-       {
-         if (dump_file && (dump_flags & TDF_DETAILS))
-           {
-             fprintf (dump_file, "  Not registered due to ");
-             print_generic_expr (dump_file, arg, TDF_SLIM);
-             fprintf (dump_file, " being defined in the same block.\n");
-           }
-         return;
-       }
+       return false;
+    }
+
+  bool ret = record (gimple_bb (stmt), k, op1, op2);
+
+  if (ret && dump_file && (dump_flags & TDF_DETAILS))
+    {
+      value_relation vr (k, op1, op2);
+      fprintf (dump_file, " Registering value_relation ");
+      vr.dump (dump_file);
+      fprintf (dump_file, " (bb%d) at ", gimple_bb (stmt)->index);
+      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
     }
-  record (gimple_bb (stmt), k, op1, op2);
+  return ret;
 }
 
 // Register relation K between ssa_name OP1 and OP2 on edge E.
+// Return false if no new relation is added.
 
-void
+bool
 relation_oracle::record (edge e, relation_kind k, tree op1, tree op2)
 {
   gcc_checking_assert (TREE_CODE (op1) == SSA_NAME);
@@ -1130,34 +1128,35 @@ relation_oracle::record (edge e, relation_kind k, tree op1, tree op2)
   // Do not register lack of relation, or blocks which have more than
   // edge E for a predecessor.
   if (k == VREL_VARYING || !single_pred_p (e->dest))
-    return;
+    return false;
 
-  if (dump_file && (dump_flags & TDF_DETAILS))
+  bool ret = record (e->dest, k, op1, op2);
+
+  if (ret && dump_file && (dump_flags & TDF_DETAILS))
     {
       value_relation vr (k, op1, op2);
       fprintf (dump_file, " Registering value_relation ");
       vr.dump (dump_file);
       fprintf (dump_file, " on (%d->%d)\n", e->src->index, e->dest->index);
     }
-
-  record (e->dest, k, op1, op2);
+  return ret;
 }
 
 // Register relation K between OP! and OP2 in block BB.
 // This creates the record and searches for existing records in the dominator
-// tree to merge with.
+// tree to merge with.  Return false if no new relation is added.
 
-void
+bool
 dom_oracle::record (basic_block bb, relation_kind k, tree op1, tree op2)
 {
   // If the 2 ssa_names are the same, do nothing.  An equivalence is implied,
   // and no other relation makes sense.
   if (op1 == op2)
-    return;
+    return false;
 
   // Equivalencies are handled by the equivalence oracle.
   if (relation_equiv_p (k))
-    equiv_oracle::record (bb, k, op1, op2);
+    return equiv_oracle::record (bb, k, op1, op2);
   else
     {
       // if neither op1 nor op2 are in a relation before this is registered,
@@ -1169,6 +1168,7 @@ dom_oracle::record (basic_block bb, relation_kind k, tree op1, tree op2)
          && (m_relations[bb->index].m_num_relations
              < param_relation_block_limit))
        register_transitives (bb, *ptr);
+      return ptr != NULL;
     }
 }
 
@@ -1201,33 +1201,16 @@ dom_oracle::set_one_relation (basic_block bb, relation_kind k, tree op1,
   // There is an existing relation in this block, just intersect with it.
   if (curr != VREL_VARYING)
     {
-      if (dump_file && (dump_flags & TDF_DETAILS))
-       {
-         fprintf (dump_file, "    Intersecting with existing ");
-         ptr->dump (dump_file);
-       }
       // Check into whether we can simply replace the relation rather than
       // intersecting it.  This may help with some optimistic iterative
-      // updating algorithms.
-      bool new_rel = ptr->intersect (vr);
-      if (dump_file && (dump_flags & TDF_DETAILS))
-       {
-         fprintf (dump_file, " to produce ");
-         ptr->dump (dump_file);
-         fprintf (dump_file, " %s.\n", new_rel ? "Updated" : "No Change");
-       }
-      // If there was no change, return no record..
-      if (!new_rel)
+      // updating algorithms.  If there was no change, return no record..
+      if (!ptr->intersect (vr))
        return NULL;
     }
   else
     {
       if (m_relations[bbi].m_num_relations >= param_relation_block_limit)
-       {
-         if (dump_file && (dump_flags & TDF_DETAILS))
-           fprintf (dump_file, "  Not registered due to bb being full\n");
-         return NULL;
-       }
+       return NULL;
       m_relations[bbi].m_num_relations++;
       // Check for an existing relation further up the DOM chain.
       // By including dominating relations, The first one found in any search
@@ -1585,9 +1568,9 @@ path_oracle::equiv_set (tree ssa, basic_block bb)
 }
 
 // Register an equivalence between SSA1 and SSA2 resolving unknowns from
-// block BB.
+// block BB.  Return false if no new equivalence was added.
 
-void
+bool
 path_oracle::register_equiv (basic_block bb, tree ssa1, tree ssa2)
 {
   const_bitmap equiv_1 = equiv_set (ssa1, bb);
@@ -1595,7 +1578,7 @@ path_oracle::register_equiv (basic_block bb, tree ssa1, tree ssa2)
 
   // Check if they are the same set, if so, we're done.
   if (bitmap_equal_p (equiv_1, equiv_2))
-    return;
+    return false;
 
   // Don't mess around, simply create a new record and insert it first.
   bitmap b = BITMAP_ALLOC (&m_bitmaps);
@@ -1609,6 +1592,7 @@ path_oracle::register_equiv (basic_block bb, tree ssa1, tree ssa2)
   ptr->m_next = m_equiv.m_next;
   m_equiv.m_next = ptr;
   bitmap_ior_into (m_equiv.m_names, b);
+  return true;
 }
 
 // Register killing definition of an SSA_NAME.
@@ -1658,41 +1642,43 @@ path_oracle::killing_def (tree ssa)
 }
 
 // Register relation K between SSA1 and SSA2, resolving unknowns by
-// querying from BB.
+// querying from BB.  Return false if no new relation is registered.
 
-void
+bool
 path_oracle::record (basic_block bb, relation_kind k, tree ssa1, tree ssa2)
 {
   // If the 2 ssa_names are the same, do nothing.  An equivalence is implied,
   // and no other relation makes sense.
   if (ssa1 == ssa2)
-    return;
-
-  if (dump_file && (dump_flags & TDF_DETAILS))
-    {
-      value_relation vr (k, ssa1, ssa2);
-      fprintf (dump_file, " Registering value_relation (path_oracle) ");
-      vr.dump (dump_file);
-      fprintf (dump_file, " (root: bb%d)\n", bb->index);
-    }
+    return false;
 
   relation_kind curr = query (bb, ssa1, ssa2);
   if (curr != VREL_VARYING)
     k = relation_intersect (curr, k);
 
+  bool ret;
   if (k == VREL_EQ)
+    ret = register_equiv (bb, ssa1, ssa2);
+  else
     {
-      register_equiv (bb, ssa1, ssa2);
-      return;
+      bitmap_set_bit (m_relations.m_names, SSA_NAME_VERSION (ssa1));
+      bitmap_set_bit (m_relations.m_names, SSA_NAME_VERSION (ssa2));
+      relation_chain *ptr = (relation_chain *) obstack_alloc (&m_chain_obstack,
+                                                         sizeof (relation_chain));
+      ptr->set_relation (k, ssa1, ssa2);
+      ptr->m_next = m_relations.m_head;
+      m_relations.m_head = ptr;
+      ret = true;
     }
 
-  bitmap_set_bit (m_relations.m_names, SSA_NAME_VERSION (ssa1));
-  bitmap_set_bit (m_relations.m_names, SSA_NAME_VERSION (ssa2));
-  relation_chain *ptr = (relation_chain *) obstack_alloc (&m_chain_obstack,
-                                                     sizeof (relation_chain));
-  ptr->set_relation (k, ssa1, ssa2);
-  ptr->m_next = m_relations.m_head;
-  m_relations.m_head = ptr;
+  if (ret && dump_file && (dump_flags & TDF_DETAILS))
+    {
+      value_relation vr (k, ssa1, ssa2);
+      fprintf (dump_file, " Registering value_relation (path_oracle) ");
+      vr.dump (dump_file);
+      fprintf (dump_file, " (root: bb%d)\n", bb->index);
+    }
+  return ret;
 }
 
 // Query for a relationship between equiv set B1 and B2, resolving unknowns
index 87f0d856fabd3336f02ab72d1314cbe24787c15d..fface9436bb522b0862d0de4f9d9f7c094c1c1a4 100644 (file)
@@ -100,9 +100,9 @@ public:
   virtual ~relation_oracle () { }
 
   // register a relation between 2 ssa names.
-  void record (gimple *, relation_kind, tree, tree);
-  void record (edge, relation_kind, tree, tree);
-  virtual void record (basic_block, relation_kind, tree, tree) { }
+  bool record (gimple *, relation_kind, tree, tree);
+  bool record (edge, relation_kind, tree, tree);
+  virtual bool record (basic_block, relation_kind, tree, tree) { return false; }
 
   // Query if there is any relation between SSA1 and SSA2.
   relation_kind query (gimple *s, tree ssa1, tree ssa2);
@@ -166,7 +166,7 @@ public:
   ~equiv_oracle ();
 
   const_bitmap equiv_set (tree ssa, basic_block bb) final override;
-  void record (basic_block bb, relation_kind k, tree ssa1, tree ssa2) override;
+  bool record (basic_block bb, relation_kind k, tree ssa1, tree ssa2) override;
 
   relation_kind partial_equiv (tree ssa1, tree ssa2, tree *base = NULL) const;
   relation_kind query (basic_block, tree, tree) override;
@@ -175,7 +175,7 @@ public:
   void dump (FILE *f) const override;
 
 protected:
-  void add_partial_equiv (relation_kind, tree, tree);
+  bool 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;
@@ -224,7 +224,7 @@ public:
   dom_oracle (bool do_trans_p = true);
   ~dom_oracle ();
 
-  void record (basic_block bb, relation_kind k, tree op1, tree op2)
+  bool record (basic_block bb, relation_kind k, tree op1, tree op2)
     final override;
 
   relation_kind query (basic_block bb, tree ssa1, tree ssa2) final override;
@@ -273,7 +273,7 @@ public:
   path_oracle (relation_oracle *oracle = NULL);
   ~path_oracle ();
   const_bitmap equiv_set (tree, basic_block) final override;
-  void record (basic_block, relation_kind, tree, tree) final override;
+  bool record (basic_block, relation_kind, tree, tree) final override;
   void killing_def (tree);
   relation_kind query (basic_block, tree, tree) final override;
   relation_kind query (basic_block, const_bitmap, const_bitmap) final override;
@@ -282,7 +282,7 @@ public:
   void dump (FILE *, basic_block) const final override;
   void dump (FILE *) const final override;
 private:
-  void register_equiv (basic_block bb, tree ssa1, tree ssa2);
+  bool register_equiv (basic_block bb, tree ssa1, tree ssa2);
   equiv_chain m_equiv;
   relation_chain_head m_relations;
   relation_oracle *m_root;