diff mbox series

[COMMITTED,10/12] - Make GORI a range_query component.

Message ID a907e404-b927-4ed1-b4e7-a29e54bd8aff@redhat.com
State New
Headers show
Series [COMMITTED,01/12] - Move all relation queries into relation_oracle. | expand

Commit Message

Andrew MacLeod May 23, 2024, 8:53 p.m. UTC
This patch moves the GORI component into the range_query object, and 
makes it generally available.  This makes it much easier to share 
between ranger, other range_queries, and the passes using them.

Bootstrapped on x86_64-pc-linux-gnu with no regressions.  Pushed.
diff mbox series

Patch

From 59a3a0ad763bc03ad5ab630a62fbc78ae50b486f Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <amacleod@redhat.com>
Date: Fri, 17 May 2024 14:27:12 -0400
Subject: [PATCH 10/12] Make GORI a range_query component.

This patch moves the GORI component into the range_query object, and
makes it generally available.  This makes it much easier to share
between ranger and the passes.

	* gimple-range-cache.cc (ranger_cache::ranger_cache): Create
	GORi via the range_query instead of a local member.
	(ranger_cache::dump_bb): Use gori via from the range_query parent.
	(ranger_cache::get_global_range): Likewise.
	(ranger_cache::set_global_range): Likewise.
	(ranger_cache::edge_range): Likewise.
	(anger_cache::block_range): Likewise.
	(ranger_cache::fill_block_cache): Likewise.
	(ranger_cache::range_from_dom): Likewise.
	(ranger_cache::register_inferred_value): Likewise.
	* gimple-range-cache.h (ranger_cache::m_gori): Delete.
	* gimple-range-fold.cc (fur_source::fur_source): Set m_depend_p.
	(fur_depend::fur_depend): Remove gori parameter.
	* gimple-range-fold.h (fur_source::gori): Adjust.
	(fur_source::m_gori): Delete.
	(fur_source::m_depend): New.
	(fur_depend::fur_depend): Adjust prototype.
	* gimple-range-path.cc (path_range_query::path_range_query): Share
	ranger oracles.
	(path_range_query::range_defined_in_block): Use oracle directly.
	(path_range_query::compute_ranges_in_block): Use new gori() method.
	(path_range_query::adjust_for_non_null_uses): Use oracle directly.
	(path_range_query::compute_exit_dependencies): Likewise.
	(jt_fur_source::jt_fur_source): No gori in the parameters.
	(path_range_query::range_of_stmt): Likewise.
	(path_range_query::compute_outgoing_relations): Likewise.
	* gimple-range.cc (gimple_ranger::fold_range_internal): Likewise.
	(gimple_ranger::range_of_stmt): Access gori via gori () method.
	(assume_query::range_of_expr): Create a gori object.
	(assume_query::~assume_query): Destroy a gori object.
	(assume_query::calculate_op): Remove old gori() accessor.
	* gimple-range.h (gimple_ranger::gori): Delete.
	(assume_query::~assume_query): New.
	(assume_query::m_gori): Delete.
	* tree-ssa-dom.cc (set_global_ranges_from_unreachable_edges): use
	gori () method.
	* tree-ssa-threadedge.cc (compute_exit_dependencies): Likewise.
	* value-query.cc (default_gori): New.
	(range_query::create_gori): New.
	(range_query::destroy_gori): New.
	(range_query::share_oracles): Set m_gori.
	(range_query::range_query): Set m_gori to default.
	(range_query::~range_query): call destroy gori.
	* value-query.h (range_query): Adjust prototypes
	(range_query::m_gori): New.
---
 gcc/gimple-range-cache.cc  | 34 +++++++++++++++++-----------------
 gcc/gimple-range-cache.h   |  1 -
 gcc/gimple-range-fold.cc   |  7 +++----
 gcc/gimple-range-fold.h    |  7 ++++---
 gcc/gimple-range-path.cc   | 28 ++++++++++++++--------------
 gcc/gimple-range.cc        | 12 +++++++++---
 gcc/gimple-range.h         |  3 +--
 gcc/tree-ssa-dom.cc        |  3 +--
 gcc/tree-ssa-threadedge.cc |  4 +---
 gcc/value-query.cc         | 20 ++++++++++++++++++++
 gcc/value-query.h          |  5 +++++
 11 files changed, 75 insertions(+), 49 deletions(-)

diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc
index 40e4baa6289..e75cac66902 100644
--- a/gcc/gimple-range-cache.cc
+++ b/gcc/gimple-range-cache.cc
@@ -950,7 +950,6 @@  update_list::pop ()
 // --------------------------------------------------------------------------
 
 ranger_cache::ranger_cache (int not_executable_flag, bool use_imm_uses)
-  : m_gori (not_executable_flag, param_vrp_switch_limit)
 {
   m_workback.create (0);
   m_workback.safe_grow_cleared (last_basic_block_for_fn (cfun));
@@ -960,6 +959,7 @@  ranger_cache::ranger_cache (int not_executable_flag, bool use_imm_uses)
   // If DOM info is available, spawn an oracle as well.
   create_relation_oracle ();
   create_infer_oracle (use_imm_uses);
+  create_gori (not_executable_flag, param_vrp_switch_limit);
 
   unsigned x, lim = last_basic_block_for_fn (cfun);
   // Calculate outgoing range info upfront.  This will fully populate the
@@ -969,7 +969,7 @@  ranger_cache::ranger_cache (int not_executable_flag, bool use_imm_uses)
     {
       basic_block bb = BASIC_BLOCK_FOR_FN (cfun, x);
       if (bb)
-	m_gori.map ()->exports (bb);
+	gori ().map ()->exports (bb);
     }
   m_update = new update_list ();
 }
@@ -1000,7 +1000,7 @@  ranger_cache::dump (FILE *f)
 void
 ranger_cache::dump_bb (FILE *f, basic_block bb)
 {
-  m_gori.map ()->dump (f, bb, false);
+  gori ().map ()->dump (f, bb, false);
   m_on_entry.dump (f, bb);
   m_relation->dump (f, bb);
 }
@@ -1033,8 +1033,8 @@  ranger_cache::get_global_range (vrange &r, tree name, bool &current_p)
   current_p = false;
   if (had_global)
     current_p = r.singleton_p ()
-		|| m_temporal->current_p (name, m_gori.map ()->depend1 (name),
-					  m_gori.map ()->depend2 (name));
+		|| m_temporal->current_p (name, gori ().map ()->depend1 (name),
+					  gori ().map ()->depend2 (name));
   else
     {
       // If no global value has been set and value is VARYING, fold the stmt
@@ -1071,8 +1071,8 @@  ranger_cache::set_global_range (tree name, const vrange &r, bool changed)
   if (!changed)
     {
       // If there are dependencies, make sure this is not out of date.
-      if (!m_temporal->current_p (name, m_gori.map ()->depend1 (name),
-				 m_gori.map ()->depend2 (name)))
+      if (!m_temporal->current_p (name, gori ().map ()->depend1 (name),
+				 gori ().map ()->depend2 (name)))
 	m_temporal->set_timestamp (name);
       return;
     }
@@ -1097,7 +1097,7 @@  ranger_cache::set_global_range (tree name, const vrange &r, bool changed)
 
   if (r.singleton_p ()
       || (POINTER_TYPE_P (TREE_TYPE (name)) && r.nonzero_p ()))
-    m_gori.map ()->set_range_invariant (name);
+    gori ().map ()->set_range_invariant (name);
   m_temporal->set_timestamp (name);
 }
 
@@ -1178,7 +1178,7 @@  ranger_cache::edge_range (vrange &r, edge e, tree name, enum rfd_mode mode)
   if ((e->flags & (EDGE_EH | EDGE_ABNORMAL)) == 0)
     infer_oracle ().maybe_adjust_range (r, name, e->src);
   Value_Range er (TREE_TYPE (name));
-  if (m_gori.edge_range_p (er, e, name, *this))
+  if (gori ().edge_range_p (er, e, name, *this))
     r.intersect (er);
   return true;
 }
@@ -1230,7 +1230,7 @@  ranger_cache::block_range (vrange &r, basic_block bb, tree name, bool calc)
 
   // If there are no range calculations anywhere in the IL, global range
   // applies everywhere, so don't bother caching it.
-  if (!m_gori.has_edge_range_p (name))
+  if (!gori ().has_edge_range_p (name))
     return false;
 
   if (calc)
@@ -1449,7 +1449,7 @@  ranger_cache::fill_block_cache (tree name, basic_block bb, basic_block def_bb)
 	    continue;
 
 	  // Check if the equiv has any ranges calculated.
-	  if (!m_gori.has_edge_range_p (equiv_name))
+	  if (!gori ().has_edge_range_p (equiv_name))
 	    continue;
 
 	  // Check if the equiv definition dominates this block
@@ -1562,7 +1562,7 @@  ranger_cache::fill_block_cache (tree name, basic_block bb, basic_block def_bb)
 		  r.dump (dump_file);
 		  fprintf (dump_file, ", ");
 		}
-	      if (!r.undefined_p () || m_gori.has_edge_range_p (name, e))
+	      if (!r.undefined_p () || gori ().has_edge_range_p (name, e))
 		{
 		  m_update->add (node);
 		  if (DEBUG_RANGE_CACHE)
@@ -1671,7 +1671,7 @@  ranger_cache::range_from_dom (vrange &r, tree name, basic_block start_bb,
       infer_oracle ().maybe_adjust_range (infer, name, bb);
 
       // This block has an outgoing range.
-      if (m_gori.has_edge_range_p (name, bb))
+      if (gori ().has_edge_range_p (name, bb))
 	m_workback.quick_push (prev_bb);
       else
 	{
@@ -1683,7 +1683,7 @@  ranger_cache::range_from_dom (vrange &r, tree name, basic_block start_bb,
 	  // If the first pred does not generate a range, then we will be
 	  // using the dominator range anyway, so that's all the check needed.
 	  if (EDGE_COUNT (prev_bb->preds) > 1
-	      && m_gori.has_edge_range_p (name, EDGE_PRED (prev_bb, 0)->src))
+	      && gori ().has_edge_range_p (name, EDGE_PRED (prev_bb, 0)->src))
 	    {
 	      edge e;
 	      edge_iterator ei;
@@ -1738,7 +1738,7 @@  ranger_cache::range_from_dom (vrange &r, tree name, basic_block start_bb,
 
       edge e = single_pred_edge (prev_bb);
       bb = e->src;
-      if (m_gori.edge_range_p (er, e, name, *this))
+      if (gori ().edge_range_p (er, e, name, *this))
 	{
 	  r.intersect (er);
 	  // If this is a normal edge, apply any inferred ranges.
@@ -1782,8 +1782,8 @@  ranger_cache::register_inferred_value (const vrange &ir, tree name,
     {
       m_on_entry.set_bb_range (name, bb, r);
       // If this range was invariant before, remove invariant.
-      if (!m_gori.has_edge_range_p (name))
-	m_gori.map ()->set_range_invariant (name, false);
+      if (!gori ().has_edge_range_p (name))
+	gori ().map ()->set_range_invariant (name, false);
     }
 }
 
diff --git a/gcc/gimple-range-cache.h b/gcc/gimple-range-cache.h
index e3ab89de02e..c7499f928a9 100644
--- a/gcc/gimple-range-cache.h
+++ b/gcc/gimple-range-cache.h
@@ -114,7 +114,6 @@  public:
 
   void register_inferred_value (const vrange &r, tree name, basic_block bb);
   void apply_inferred_ranges (gimple *s);
-  gori_compute m_gori;
 
   void dump_bb (FILE *f, basic_block bb);
   virtual void dump (FILE *f) override;
diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc
index 37c16761ba6..e9e387c7d59 100644
--- a/gcc/gimple-range-fold.cc
+++ b/gcc/gimple-range-fold.cc
@@ -59,7 +59,7 @@  fur_source::fur_source (range_query *q)
     m_query = q;
   else
     m_query = get_range_query (cfun);
-  m_gori = NULL;
+  m_depend_p = false;
 }
 
 // Invoke range_of_expr on EXPR.
@@ -184,11 +184,10 @@  fur_stmt::query_relation (tree op1, tree op2)
 // Instantiate a stmt based fur_source with a GORI object.
 
 
-fur_depend::fur_depend (gimple *s, gori_compute *gori, range_query *q)
+fur_depend::fur_depend (gimple *s, range_query *q)
   : fur_stmt (s, q)
 {
-  gcc_checking_assert (gori);
-  m_gori = gori;
+  m_depend_p = true;
 }
 
 // Register a relation on a stmt if there is an oracle.
diff --git a/gcc/gimple-range-fold.h b/gcc/gimple-range-fold.h
index d974b0192c8..9ae6cf56d2a 100644
--- a/gcc/gimple-range-fold.h
+++ b/gcc/gimple-range-fold.h
@@ -106,7 +106,8 @@  class fur_source
 public:
   fur_source (range_query *q = NULL);
   inline range_query *query () { return m_query; }
-  inline class gori_compute *gori () { return m_gori; };
+  inline class gimple_outgoing_range *gori ()
+    { return m_depend_p ? &(m_query->gori ()) : NULL; }
   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);
@@ -117,7 +118,7 @@  public:
   void register_outgoing_edges (gcond *, irange &lhs_range, edge e0, edge e1);
 protected:
   range_query *m_query;
-  gori_compute *m_gori;
+  bool m_depend_p;
 };
 
 // fur_stmt is the specification for drawing an operand from range_query Q
@@ -140,7 +141,7 @@  private:
 class fur_depend : public fur_stmt
 {
 public:
-  fur_depend (gimple *s, gori_compute *gori, range_query *q = NULL);
+  fur_depend (gimple *s, range_query *q = 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,
diff --git a/gcc/gimple-range-path.cc b/gcc/gimple-range-path.cc
index 03f73218a57..707bd0ebd94 100644
--- a/gcc/gimple-range-path.cc
+++ b/gcc/gimple-range-path.cc
@@ -44,6 +44,8 @@  path_range_query::path_range_query (gimple_ranger &ranger,
     m_ranger (ranger),
     m_resolve (resolve)
 {
+  share_query (ranger);
+  // Override the relation oracle with a local path relation oracle.
   m_relation = new path_oracle (&(m_ranger.relation ()));
 
   reset_path (path, dependencies);
@@ -54,6 +56,8 @@  path_range_query::path_range_query (gimple_ranger &ranger, bool resolve)
     m_ranger (ranger),
     m_resolve (resolve)
 {
+  share_query (ranger);
+  // Override the relation oracle with a local path relation oracle.
   m_relation = new path_oracle (&(m_ranger.relation ()));
 }
 
@@ -303,7 +307,7 @@  path_range_query::range_defined_in_block (vrange &r, tree name, basic_block bb)
     }
 
   if (bb && POINTER_TYPE_P (TREE_TYPE (name)))
-    m_ranger.infer_oracle ().maybe_adjust_range (r, name, bb);
+    infer_oracle ().maybe_adjust_range (r, name, bb);
 
   if (DEBUG_SOLVER && (bb || !r.varying_p ()))
     {
@@ -409,13 +413,12 @@  path_range_query::compute_ranges_in_block (basic_block bb)
       p->reset_path ();
     }
 
-  gori_compute &g = m_ranger.gori ();
-  bitmap exports = g.map()->exports (bb);
+  bitmap exports = gori ().map ()->exports (bb);
   EXECUTE_IF_AND_IN_BITMAP (m_exit_dependencies, exports, 0, i, bi)
     {
       tree name = ssa_name (i);
       Value_Range r (TREE_TYPE (name));
-      if (g.edge_range_p (r, e, name, *this))
+      if (gori ().edge_range_p (r, e, name, *this))
 	{
 	  Value_Range cached_range (TREE_TYPE (name));
 	  if (get_cache (cached_range, name))
@@ -463,7 +466,7 @@  path_range_query::adjust_for_non_null_uses (basic_block bb)
       else
 	r.set_varying (TREE_TYPE (name));
 
-      if (m_ranger.infer_oracle ().maybe_adjust_range (r, name, bb))
+      if (infer_oracle ().maybe_adjust_range (r, name, bb))
 	m_cache.set_range (name, r);
     }
 }
@@ -487,8 +490,7 @@  path_range_query::compute_exit_dependencies (bitmap dependencies)
 {
   // Start with the imports from the exit block...
   basic_block exit = m_path[0];
-  gori_compute &gori = m_ranger.gori ();
-  bitmap_copy (dependencies, gori.map()->imports (exit));
+  bitmap_copy (dependencies, gori ().map()->imports (exit));
 
   auto_vec<tree> worklist (bitmap_count_bits (dependencies));
   bitmap_iterator bi;
@@ -536,7 +538,7 @@  path_range_query::compute_exit_dependencies (bitmap dependencies)
       {
 	basic_block bb = m_path[i];
 	tree name;
-	FOR_EACH_GORI_EXPORT_NAME (*(gori.map ()), bb, name)
+	FOR_EACH_GORI_EXPORT_NAME (*(gori ().map ()), bb, name)
 	  if (TREE_CODE (TREE_TYPE (name)) == BOOLEAN_TYPE)
 	    bitmap_set_bit (dependencies, SSA_NAME_VERSION (name));
       }
@@ -611,8 +613,7 @@  path_range_query::compute_ranges (const bitmap_head *dependencies)
 class jt_fur_source : public fur_depend
 {
 public:
-  jt_fur_source (gimple *s, path_range_query *, gori_compute *,
-		 const vec<basic_block> &);
+  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;
@@ -622,9 +623,8 @@  private:
 
 jt_fur_source::jt_fur_source (gimple *s,
 			      path_range_query *query,
-			      gori_compute *gori,
 			      const vec<basic_block> &path)
-  : fur_depend (s, gori, query)
+  : fur_depend (s, query)
 {
   gcc_checking_assert (!path.is_empty ());
 
@@ -671,7 +671,7 @@  path_range_query::range_of_stmt (vrange &r, gimple *stmt, tree)
   if (m_resolve)
     {
       fold_using_range f;
-      jt_fur_source src (stmt, this, &m_ranger.gori (), m_path);
+      jt_fur_source src (stmt, this, m_path);
       if (!f.fold_stmt (r, stmt, src))
 	r.set_varying (type);
     }
@@ -761,7 +761,7 @@  path_range_query::compute_outgoing_relations (basic_block bb, basic_block next)
       else
 	gcc_unreachable ();
 
-      jt_fur_source src (NULL, this, &m_ranger.gori (), m_path);
+      jt_fur_source src (NULL, this, m_path);
       src.register_outgoing_edges (cond, r, e0, e1);
     }
 }
diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc
index e7e6fd86581..20294612185 100644
--- a/gcc/gimple-range.cc
+++ b/gcc/gimple-range.cc
@@ -273,7 +273,7 @@  bool
 gimple_ranger::fold_range_internal (vrange &r, gimple *s, tree name)
 {
   fold_using_range f;
-  fur_depend src (s, &(gori ()), this);
+  fur_depend src (s, this);
   return f.fold_stmt (r, s, src, name);
 }
 
@@ -310,7 +310,7 @@  gimple_ranger::range_of_stmt (vrange &r, gimple *s, tree name)
 	  // Update any exports in the cache if this is a gimple cond statement.
 	  tree exp;
 	  basic_block bb = gimple_bb (s);
-	  FOR_EACH_GORI_EXPORT_NAME (*(m_cache.m_gori.map ()), bb, exp)
+	  FOR_EACH_GORI_EXPORT_NAME (*(gori ().map ()), bb, exp)
 	    m_cache.propagate_updated_value (exp, bb);
 	}
     }
@@ -755,6 +755,7 @@  assume_query::range_of_expr (vrange &r, tree expr, gimple *stmt)
 
 assume_query::assume_query ()
 {
+  create_gori (0, param_vrp_switch_limit);
   basic_block exit_bb = EXIT_BLOCK_PTR_FOR_FN (cfun);
   if (single_pred_p (exit_bb))
     {
@@ -785,6 +786,11 @@  assume_query::assume_query ()
     }
 }
 
+assume_query::~assume_query ()
+{
+  destroy_gori ();
+}
+
 // Evaluate operand OP on statement S, using the provided LHS range.
 // If successful, set the range in the global table, then visit OP's def stmt.
 
@@ -792,7 +798,7 @@  void
 assume_query::calculate_op (tree op, gimple *s, vrange &lhs, fur_source &src)
 {
   Value_Range op_range (TREE_TYPE (op));
-  if (m_gori.compute_operand_range (op_range, s, lhs, op, src)
+  if (gori ().compute_operand_range (op_range, s, lhs, op, src)
       && !op_range.varying_p ())
     {
       // Set the global range, merging if there is already a range.
diff --git a/gcc/gimple-range.h b/gcc/gimple-range.h
index 167b54b2a37..1532951a449 100644
--- a/gcc/gimple-range.h
+++ b/gcc/gimple-range.h
@@ -55,7 +55,6 @@  public:
   virtual bool range_on_entry (vrange &r, basic_block bb, tree name) override;
   virtual bool range_on_exit (vrange &r, basic_block bb, tree name) override;
   void export_global_ranges ();
-  inline gori_compute &gori ()  { return m_cache.m_gori; }
   virtual void dump (FILE *f) override;
   void debug ();
   void dump_bb (FILE *f, basic_block bb);
@@ -87,6 +86,7 @@  class assume_query : public range_query
 {
 public:
   assume_query ();
+  ~assume_query ();
   bool assume_range_p (vrange &r, tree name);
   virtual bool range_of_expr (vrange &r, tree expr, gimple * = NULL);
   void dump (FILE *f);
@@ -97,7 +97,6 @@  protected:
   void check_taken_edge (edge e, fur_source &src);
 
   ssa_lazy_cache global;
-  gori_compute m_gori;
 };
 
 // DOM based ranger for fast VRP.
diff --git a/gcc/tree-ssa-dom.cc b/gcc/tree-ssa-dom.cc
index 81c8b16fd12..67c87bbd19e 100644
--- a/gcc/tree-ssa-dom.cc
+++ b/gcc/tree-ssa-dom.cc
@@ -1430,8 +1430,7 @@  dom_opt_dom_walker::set_global_ranges_from_unreachable_edges (basic_block bb)
     return;
 
   tree name;
-  gori_compute &gori = m_ranger->gori ();
-  FOR_EACH_GORI_EXPORT_NAME (*(gori.map()), pred_e->src, name)
+  FOR_EACH_GORI_EXPORT_NAME (*(m_ranger->gori ().map()), pred_e->src, name)
     if (all_uses_feed_or_dominated_by_stmt (name, stmt)
 	// The condition must post-dominate the definition point.
 	&& (SSA_NAME_IS_DEFAULT_DEF (name)
diff --git a/gcc/tree-ssa-threadedge.cc b/gcc/tree-ssa-threadedge.cc
index f5268d45516..766b68a007b 100644
--- a/gcc/tree-ssa-threadedge.cc
+++ b/gcc/tree-ssa-threadedge.cc
@@ -1446,10 +1446,8 @@  hybrid_jt_simplifier::compute_exit_dependencies (bitmap dependencies,
 						 const vec<basic_block> &path,
 						 gimple *stmt)
 {
-  gori_compute &gori = m_ranger->gori ();
-
   // Start with the imports to the final conditional.
-  bitmap_copy (dependencies, gori.map ()->imports (path[0]));
+  bitmap_copy (dependencies, m_ranger->gori ().map ()->imports (path[0]));
 
   // Add any other interesting operands we may have missed.
   if (gimple_bb (stmt) != path[0])
diff --git a/gcc/value-query.cc b/gcc/value-query.cc
index 41b581b20be..db813ad3094 100644
--- a/gcc/value-query.cc
+++ b/gcc/value-query.cc
@@ -182,6 +182,23 @@  range_query::dump (FILE *)
 // can be used anywhere.
 relation_oracle default_relation_oracle;
 infer_range_oracle default_infer_oracle;
+gimple_outgoing_range default_gori;
+
+void
+range_query::create_gori (int not_executable_flag, int sw_max_edges)
+{
+  gcc_checking_assert (m_gori == &default_gori);
+  m_gori = new gori_compute (not_executable_flag, sw_max_edges);
+  gcc_checking_assert (m_gori);
+}
+
+void
+range_query::destroy_gori ()
+{
+  if (m_gori && m_gori != &default_gori)
+    delete m_gori;
+  m_gori= &default_gori;
+}
 
 void
 range_query::create_infer_oracle (bool do_search)
@@ -233,6 +250,7 @@  range_query::share_query (range_query &q)
 {
   m_relation = q.m_relation;
   m_infer = q.m_infer;
+  m_gori = q.m_gori;
   m_shared_copy_p = true;
 }
 
@@ -240,6 +258,7 @@  range_query::range_query ()
 {
   m_relation = &default_relation_oracle;
   m_infer = &default_infer_oracle;
+  m_gori = &default_gori;
   m_shared_copy_p = false;
 }
 
@@ -248,6 +267,7 @@  range_query::~range_query ()
   // Do not destroy anything if this is a shared copy.
   if (m_shared_copy_p)
     return;
+  destroy_gori ();
   destroy_infer_oracle ();
   destroy_relation_oracle ();
 }
diff --git a/gcc/value-query.h b/gcc/value-query.h
index 2f65d95bc9b..1481f532d60 100644
--- a/gcc/value-query.h
+++ b/gcc/value-query.h
@@ -83,6 +83,10 @@  public:
   void create_infer_oracle (bool do_search = TRUE);
   void destroy_infer_oracle ();
 
+  inline class gimple_outgoing_range &gori () const { return *m_gori; }
+  void create_gori (int not_executable_flag = 0, int sw_max_edges = INT_MAX);
+  void destroy_gori ();
+
   virtual void dump (FILE *);
 
 protected:
@@ -93,6 +97,7 @@  protected:
   bool get_arith_expr_range (vrange &r, tree expr, gimple *stmt);
   relation_oracle *m_relation;
   infer_range_oracle *m_infer;
+  gimple_outgoing_range *m_gori;
   // When multiple related range queries wish to share oracles.
   // This is an internal interface
   void share_query (range_query &q);
-- 
2.41.0