On 12/3/25 01:38, Richard Biener wrote:

Am 03.12.2025 um 06:05 schrieb Andrew MacLeod <[email protected]>:


On 12/2/25 20:09, Andrew Pinski wrote:
On Tue, Dec 2, 2025 at 1:37 PM Andrew MacLeod <[email protected]> wrote:
The  record() and register_relation() routines in the relation oracle
and folding routines currently return void.  They are called when there
is a relation to register and there has not been a need for feedback on
whether one was registered or not.

The patch which caused this PR recognized that and on-demand calculation
of something in the middle of the IL may not have access to relations
which  are not yet registered.   When that relation is added later
during the DOM walk, and then the statement encountered again, the
original cached version is used and any benefit of the now known
relation is lost.

This was resolved by updating the timestamp of the 2 ssa-names in the
relation when it is registered.  When a statement using those names is
re-examined, the use timestamp will be newer than the definition and the
statement will be recalculated with the relation available.

The problem shown here is a cycle of PHIs feeding each other... and each
one adding a relation potentially consumed by the other. This forces the
other to be recalculated.  This was done whether a relation was actually
added or not.   If no new relation is added, we should not update the
timestamps as there is no need to recalculate.

This patch changes the record() and register_relation() methods in the
both the relation oracle and fold_using_range classes . These routines
now return TRUE if a new relation was added, and FALSE otherwise.   The
timestamps are only updated now if TRUE is returned.

In order for the debugging output to make sense, its been tweaked to
only print that a relation is registered, not that an attempt was being
made.

Bootstraps on x86_64-pc-linux-gnu with no regressions.  OK?
One minor suggestion. Mention in comments before register_relation's
that false means nothing changed.
Likewise for add_partial_equiv and equiv_oracle::record and the others.


Oh yeah, forgot to add a comment didn't I ??  doh!

   I will do that before committing
Ok with that.

Richard


Pushed final version

Andrew
From d597daf3a8316e3a6f39bed9cc444fe57b11e4cd Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <[email protected]>
Date: Tue, 2 Dec 2025 10:12:24 -0500
Subject: [PATCH] Return true when a value_relation is added.

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        |  45 ++++++---
 gcc/gimple-range-fold.h         |   8 +-
 gcc/gimple-range-path.cc        |  18 ++--
 gcc/testsuite/gcc.dg/pr122898.c |  56 +++++++++++
 gcc/value-relation.cc           | 164 +++++++++++++++-----------------
 gcc/value-relation.h            |  16 ++--
 6 files changed, 183 insertions(+), 124 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr122898.c

diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc
index bd5e53516b7..ad11074c14b 100644
--- a/gcc/gimple-range-fold.cc
+++ b/gcc/gimple-range-fold.cc
@@ -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.
diff --git a/gcc/gimple-range-fold.h b/gcc/gimple-range-fold.h
index 760a107821a..54c1d169b9b 100644
--- a/gcc/gimple-range-fold.h
+++ b/gcc/gimple-range-fold.h
@@ -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;
diff --git a/gcc/gimple-range-path.cc b/gcc/gimple-range-path.cc
index 625622d45aa..823130c35ec 100644
--- a/gcc/gimple-range-path.cc
+++ b/gcc/gimple-range-path.cc
@@ -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
index 00000000000..8b89c829d10
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr122898.c
@@ -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(); }
diff --git a/gcc/value-relation.cc b/gcc/value-relation.cc
index 2ac7650fe5b..c96d438caf4 100644
--- a/gcc/value-relation.cc
+++ b/gcc/value-relation.cc
@@ -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
diff --git a/gcc/value-relation.h b/gcc/value-relation.h
index 87f0d856fab..fface9436bb 100644
--- a/gcc/value-relation.h
+++ b/gcc/value-relation.h
@@ -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;
-- 
2.45.0

Reply via email to