When VRP does its dominator walk, any relations which dominate other
statements are reflected when fold_range is called. If however the
on-demand engine has looked ahead and resolved back edges, it will
sometime spick up the already calculated value that did not have access
to a relation.
This patch provides a mechanism for relation registration to indicate
that the two operands are "newer" (by giving them a new temporal time
stamp), so if they are used in a future calculation is will cause
range_of_stmt() to recognize that the definition is now stale, and
recalculate the result... using the now available relation.
Bootstraps on x86_64-pc-linux-gnu with no regressions. pushed.
Andrew
From 71f41d9b3ac80f428de61486f2cec9604c4d729e Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <[email protected]>
Date: Fri, 14 Nov 2025 15:44:27 -0500
Subject: [PATCH 2/4] Force recalculation when relations are registered.
Whena relation is registered between 2 ssa-names, update their timestamps.
Any calculations using those names will be stale and forced to recalculate.
* gimple-range-cache.cc (ranger_cache::update_consumers): New.
* gimple-range-cache.h (update_consumers): New prototype.
* gimple-range-fold.cc (fur_depend::fur_depend): Add cache ptr.
(fur_depend::register_relation): call update_consumers.
* gimple-range-fold.h (fur_depend): Add a cache pointer.
* gimple-range.cc (gimple_ranger::fold_range_internal): Add cache ptr.
---
gcc/gimple-range-cache.cc | 9 +++++++++
gcc/gimple-range-cache.h | 1 +
gcc/gimple-range-fold.cc | 21 +++++++++++++++++----
gcc/gimple-range-fold.h | 4 +++-
gcc/gimple-range.cc | 2 +-
5 files changed, 31 insertions(+), 6 deletions(-)
diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc
index ecf03319cd4..08a953f5012 100644
--- a/gcc/gimple-range-cache.cc
+++ b/gcc/gimple-range-cache.cc
@@ -1108,6 +1108,15 @@ ranger_cache::get_global_range (vrange &r, tree name, bool ¤t_p)
return had_global;
}
+// Consumers of NAME that have already calculated values should recalculate.
+// Accomplished by updating the timestamp.
+
+void
+ranger_cache::update_consumers (tree name)
+{
+ m_temporal->set_timestamp (name);
+}
+
// Set the global range of NAME to R and give it a timestamp.
void
diff --git a/gcc/gimple-range-cache.h b/gcc/gimple-range-cache.h
index 58bf5c57d10..0a49c12edd0 100644
--- a/gcc/gimple-range-cache.h
+++ b/gcc/gimple-range-cache.h
@@ -111,6 +111,7 @@ public:
bool get_global_range (vrange &r, tree name) const;
bool get_global_range (vrange &r, tree name, bool ¤t_p);
void set_global_range (tree name, const vrange &r, bool changed = true);
+ void update_consumers (tree name);
range_query &const_query () { return m_globals; }
void propagate_updated_value (tree name, basic_block bb);
diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc
index 06c645f3d08..d4481770d76 100644
--- a/gcc/gimple-range-fold.cc
+++ b/gcc/gimple-range-fold.cc
@@ -162,11 +162,10 @@ fur_stmt::query_relation (tree op1, tree op2)
return m_query->relation ().query (m_stmt, op1, op2);
}
-// Instantiate a stmt based fur_source with a GORI object.
+// Instantiate a stmt based fur_source with a GORI object and a ranger cache.
-
-fur_depend::fur_depend (gimple *s, range_query *q)
- : fur_stmt (s, q)
+fur_depend::fur_depend (gimple *s, range_query *q, ranger_cache *c)
+ : fur_stmt (s, q), m_cache (c)
{
m_depend_p = true;
}
@@ -177,6 +176,13 @@ void
fur_depend::register_relation (gimple *s, relation_kind k, tree op1, tree op2)
{
m_query->relation ().record (s, k, op1, op2);
+ // This new relation could cause different calculations, so mark the operands
+ // with a new timestamp, forcing recalculations.
+ if (m_cache)
+ {
+ m_cache->update_consumers (op1);
+ m_cache->update_consumers (op2);
+ }
}
// Register a relation on an edge if there is an oracle.
@@ -185,6 +191,13 @@ void
fur_depend::register_relation (edge e, relation_kind k, tree op1, tree op2)
{
m_query->relation ().record (e, k, op1, op2);
+ // This new relation could cause different calculations, so mark the operands
+ // with a new timestamp, forcing recalculations.
+ if (m_cache)
+ {
+ m_cache->update_consumers (op1);
+ m_cache->update_consumers (op2);
+ }
}
// This version of fur_source will pick a range up from a list of ranges
diff --git a/gcc/gimple-range-fold.h b/gcc/gimple-range-fold.h
index 826a10fd9e8..760a107821a 100644
--- a/gcc/gimple-range-fold.h
+++ b/gcc/gimple-range-fold.h
@@ -143,11 +143,13 @@ private:
class fur_depend : public fur_stmt
{
public:
- fur_depend (gimple *s, range_query *q = NULL);
+ fur_depend (gimple *s, range_query *q = NULL, class ranger_cache *c = NULL);
virtual void register_relation (gimple *stmt, relation_kind k, tree op1,
tree op2) override;
virtual void register_relation (edge e, relation_kind k, tree op1,
tree op2) override;
+private:
+ ranger_cache *m_cache;
};
diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc
index c4093e61d61..f7e0936d391 100644
--- a/gcc/gimple-range.cc
+++ b/gcc/gimple-range.cc
@@ -278,7 +278,7 @@ bool
gimple_ranger::fold_range_internal (vrange &r, gimple *s, tree name)
{
fold_using_range f;
- fur_depend src (s, this);
+ fur_depend src (s, this, &m_cache);
return f.fold_stmt (r, s, src, name);
}
--
2.45.0