public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-1598] Implement global ranges for all vrange types (SSA_NAME_RANGE_INFO).
@ 2022-07-11  6:31 Aldy Hernandez
  0 siblings, 0 replies; only message in thread
From: Aldy Hernandez @ 2022-07-11  6:31 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:0a7e721a6499a42f04361caf24772547afdeed57

commit r13-1598-g0a7e721a6499a42f04361caf24772547afdeed57
Author: Aldy Hernandez <aldyh@redhat.com>
Date:   Fri Jun 10 15:11:06 2022 +0200

    Implement global ranges for all vrange types (SSA_NAME_RANGE_INFO).
    
    Currently SSA_NAME_RANGE_INFO only handles integer ranges, and loses
    half the precision in the process because its use of legacy
    value_range's.  This patch rewrites all the SSA_NAME_RANGE_INFO
    (nonzero bits included) to use the recently contributed
    vrange_storage.  With it, we'll be able to efficiently save any ranges
    supported by ranger in GC memory.  Presently this will only be
    irange's, but shortly we'll add floating ranges and others to the mix.
    
    As per the discussion with the trailing_wide_ints adjustments and
    vrange_storage, we'll be able to save integer ranges with a maximum of
    5 sub-ranges.  This could be adjusted later if more sub-ranges are
    needed (unlikely).
    
    Since this is a behavior changing patch, I would like to take a few
    days for discussion, and commit early next week if all goes well.
    
    A few notes.
    
    First, we get rid of the SSA_NAME_ANTI_RANGE_P bit in the SSA_NAME
    since we store full resolution ranges.  Perhaps it could be re-used
    for something else.
    
    The range_info_def struct is gone in favor of an opaque type handled
    by vrange_storage.  It currently supports irange, but will support
    frange, prange, etc, in due time.
    
    From the looks of it, set_range_info was an update operation despite
    its name, as we improved the nonzero bits with each call, even though
    we clobbered the ranges.  Presumably this was because doing a proper
    intersect of ranges lost information with the anti-range hack.  We no
    longer have this limitation so now we formalize both set_range_info
    and set_nonzero_bits to an update operation.  After all, we should
    never be losing information, but enhancing it whenever possible.  This
    means, that if folks' finger-memory is not offended, as a follow-up,
    I'd like to rename set_nonzero_bits and set_range_info to update_*.
    
    I have kept the same global API we had in tree-ssanames.h, with the
    caveat that all set operations are now update as discussed above.
    
    There is a 2% performance penalty for evrp and a 3% penalty for VRP
    that is coincidentally in line with a previous improvement of the same
    amount in the vrange abstraction patchset.  Interestingly, this
    penalty is mostly due to the wide int to tree dance we keep doing with
    irange and legacy.  In a first draft of this patch where I was
    streaming trees directly, there was actually a small improvement
    instead.  I hope to get some of the gain back when we move irange's to
    wide-ints, though I'm not in a hurry ;-).
    
    Tested and benchmarked on x86-64 Linux.  Tested on ppc64le Linux.
    
    Comments welcome.
    
    gcc/ChangeLog:
    
            * gimple-range.cc (gimple_ranger::export_global_ranges): Remove
            verification against legacy value_range.
            (gimple_ranger::register_inferred_ranges): Same.
            (gimple_ranger::export_global_ranges): Rename update_global_range
            to set_range_info.
            * tree-core.h (struct range_info_def): Remove.
            (struct irange_storage_slot): New.
            (struct tree_base): Remove SSA_NAME_ANTI_RANGE_P documentation.
            (struct tree_ssa_name): Add vrange_storage support.
            * tree-ssanames.cc (range_info_p): New.
            (range_info_fits_p): New.
            (range_info_alloc): New.
            (range_info_free): New.
            (range_info_get_range): New.
            (range_info_set_range): New.
            (set_range_info_raw): Remove.
            (set_range_info): Adjust to use vrange_storage.
            (set_nonzero_bits): Same.
            (get_nonzero_bits): Same.
            (duplicate_ssa_name_range_info): Remove overload taking
            value_range_kind.
            Rewrite tree overload to use vrange_storage.
            (duplicate_ssa_name_fn): Adjust to use vrange_storage.
            * tree-ssanames.h (struct range_info_def): Remove.
            (set_range_info): Adjust prototype to take vrange.
            * tree-vrp.cc (vrp_asserts::remove_range_assertions): Call
            duplicate_ssa_name_range_info.
            * tree.h (SSA_NAME_ANTI_RANGE_P): Remove.
            (SSA_NAME_RANGE_TYPE): Remove.
            * value-query.cc (get_ssa_name_range_info): Adjust to use
            vrange_storage.
            (update_global_range): Remove.
            (get_range_global): Remove as_a<irange>.
            * value-query.h (update_global_range): Remove.
            * tree-ssa-dom.cc (set_global_ranges_from_unreachable_edges):
            Rename update_global_range to set_range_info.
            * value-range-storage.cc (vrange_storage::alloc_slot): Remove
            gcc_unreachable.

Diff:
---
 gcc/gimple-range.cc        |  30 +-----
 gcc/tree-core.h            |  13 +--
 gcc/tree-ssa-dom.cc        |   2 +-
 gcc/tree-ssanames.cc       | 240 +++++++++++++++++++++------------------------
 gcc/tree-ssanames.h        |  12 +--
 gcc/tree-vrp.cc            |  22 +++--
 gcc/tree.h                 |   8 --
 gcc/value-query.cc         |  54 ++--------
 gcc/value-query.h          |   1 -
 gcc/value-range-storage.cc |   4 +-
 10 files changed, 149 insertions(+), 237 deletions(-)

diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc
index 3a9f0b07e79..7ac48303e4e 100644
--- a/gcc/gimple-range.cc
+++ b/gcc/gimple-range.cc
@@ -468,22 +468,12 @@ gimple_ranger::register_inferred_ranges (gimple *s)
     {
       Value_Range tmp (TREE_TYPE (lhs));
       if (range_of_stmt (tmp, s, lhs) && !tmp.varying_p ()
-	  && update_global_range (tmp, lhs) && dump_file)
+	  && set_range_info (lhs, tmp) && dump_file)
 	{
-	  // ?? This section should be adjusted when non-iranges can
-	  // be exported.  For now, the only way update_global_range
-	  // above can succeed is with an irange so this is safe.
-	  value_range vr = as_a <irange> (tmp);
 	  fprintf (dump_file, "Global Exported: ");
 	  print_generic_expr (dump_file, lhs, TDF_SLIM);
 	  fprintf (dump_file, " = ");
-	  vr.dump (dump_file);
-	  int_range_max same = vr;
-	  if (same != as_a <irange> (tmp))
-	    {
-	      fprintf (dump_file, " ...  irange was : ");
-	      tmp.dump (dump_file);
-	    }
+	  tmp.dump (dump_file);
 	  fputc ('\n', dump_file);
 	}
     }
@@ -509,7 +499,7 @@ gimple_ranger::export_global_ranges ()
 	  && m_cache.get_global_range (r, name)
 	  && !r.varying_p())
 	{
-	  bool updated = update_global_range (r, name);
+	  bool updated = set_range_info (name, r);
 	  if (!updated || !dump_file)
 	    continue;
 
@@ -522,22 +512,10 @@ gimple_ranger::export_global_ranges ()
 	      print_header = false;
 	    }
 
-	  if (!irange::supports_p (TREE_TYPE (name)))
-	    continue;
-
-	  vrange &v = r;
-	  value_range vr = as_a <irange> (v);
 	  print_generic_expr (dump_file, name , TDF_SLIM);
 	  fprintf (dump_file, "  : ");
-	  vr.dump (dump_file);
+	  r.dump (dump_file);
 	  fprintf (dump_file, "\n");
-	  int_range_max same = vr;
-	  if (same != as_a <irange> (v))
-	    {
-	      fprintf (dump_file, "         irange : ");
-	      r.dump (dump_file);
-	      fprintf (dump_file, "\n");
-	    }
 	}
     }
 }
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index ab5fa01e5cb..ea9f281f1cc 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -33,7 +33,7 @@ struct function;
 struct real_value;
 struct fixed_value;
 struct ptr_info_def;
-struct range_info_def;
+struct irange_storage_slot;
 struct die_struct;
 
 
@@ -1194,9 +1194,6 @@ struct GTY(()) tree_base {
        TRANSACTION_EXPR_OUTER in
 	   TRANSACTION_EXPR
 
-       SSA_NAME_ANTI_RANGE_P in
-	   SSA_NAME
-
        MUST_TAIL_CALL in
 	   CALL_EXPR
 
@@ -1594,8 +1591,12 @@ struct GTY(()) tree_ssa_name {
   union ssa_name_info_type {
     /* Pointer attributes used for alias analysis.  */
     struct GTY ((tag ("0"))) ptr_info_def *ptr_info;
-    /* Value range attributes used for zero/sign extension elimination.  */
-    struct GTY ((tag ("1"))) range_info_def *range_info;
+    /* This holds any range info supported by ranger (except ptr_info
+       above) and is managed by vrange_storage.  */
+    void * GTY ((skip)) range_info;
+    /* GTY tag when the range in the range_info slot above satisfies
+       irange::supports_type_p.  */
+    struct GTY ((tag ("1"))) irange_storage_slot *irange_info;
   } GTY ((desc ("%1.typed.type ?" \
 		"!POINTER_TYPE_P (TREE_TYPE ((tree)&%1)) : 2"))) info;
 
diff --git a/gcc/tree-ssa-dom.cc b/gcc/tree-ssa-dom.cc
index 2bc2c3db7d7..43acc756c96 100644
--- a/gcc/tree-ssa-dom.cc
+++ b/gcc/tree-ssa-dom.cc
@@ -1255,7 +1255,7 @@ dom_opt_dom_walker::set_global_ranges_from_unreachable_edges (basic_block bb)
       && !r.varying_p ()
       && !r.undefined_p ())
     {
-      update_global_range (r, name);
+      set_range_info (name, r);
       maybe_set_nonzero_bits (pred_e, name);
     }
 }
diff --git a/gcc/tree-ssanames.cc b/gcc/tree-ssanames.cc
index bc22ece636a..9389454a5a7 100644
--- a/gcc/tree-ssanames.cc
+++ b/gcc/tree-ssanames.cc
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "cfgloop.h"
 #include "tree-scalar-evolution.h"
 #include "value-query.h"
+#include "value-range-storage.h"
 
 /* Rewriting a function into SSA form can create a huge number of SSA_NAMEs,
    many of which may be thrown away shortly after their creation if jumps
@@ -71,6 +72,74 @@ unsigned int ssa_name_nodes_created;
 #define FREE_SSANAMES(fun) (fun)->gimple_df->free_ssanames
 #define FREE_SSANAMES_QUEUE(fun) (fun)->gimple_df->free_ssanames_queue
 
+static ggc_vrange_allocator ggc_allocator;
+static vrange_storage vstore (&ggc_allocator);
+
+/* Return TRUE if NAME has global range info.  */
+
+inline bool
+range_info_p (const_tree name)
+{
+  return SSA_NAME_RANGE_INFO (name);
+}
+
+/* Return TRUE if R fits in the global range of NAME.  */
+
+inline bool
+range_info_fits_p (tree name, const vrange &r)
+{
+  gcc_checking_assert (range_info_p (name));
+  void *mem = SSA_NAME_RANGE_INFO (name);
+  return vrange_storage::fits_p (mem, r);
+}
+
+/* Allocate a new global range for NAME and set it to R.  Return the
+   allocation slot.  */
+
+inline void *
+range_info_alloc (tree name, const vrange &r)
+{
+  void *mem = vstore.alloc_slot (r);
+  SSA_NAME_RANGE_INFO (name) = mem;
+  return mem;
+}
+
+/* Free storage allocated for the global range for NAME.  */
+
+inline void
+range_info_free (tree name)
+{
+  void *mem = SSA_NAME_RANGE_INFO (name);
+  vstore.free (mem);
+}
+
+/* Return the global range for NAME in R.  */
+
+inline void
+range_info_get_range (tree name, vrange &r)
+{
+  vstore.get_vrange (SSA_NAME_RANGE_INFO (name), r, TREE_TYPE (name));
+}
+
+/* Set the global range for NAME from R.  Return TRUE if successfull,
+   or FALSE if we can't set a range of NAME's type.  */
+
+inline bool
+range_info_set_range (tree name, const vrange &r)
+{
+  if (!range_info_p (name) || !range_info_fits_p (name, r))
+    {
+      if (range_info_p (name))
+	range_info_free (name);
+
+      return range_info_alloc (name, r);
+    }
+  else
+    {
+      vstore.set_vrange (SSA_NAME_RANGE_INFO (name), r);
+      return true;
+    }
+}
 
 /* Initialize management of SSA_NAMEs to default SIZE.  If SIZE is
    zero use default.  */
@@ -343,94 +412,38 @@ make_ssa_name_fn (struct function *fn, tree var, gimple *stmt,
   return t;
 }
 
-/* Helper function for set_range_info.
-
-   Store range information RANGE_TYPE, MIN, and MAX to tree ssa_name
-   NAME.  */
-
-void
-set_range_info_raw (tree name, enum value_range_kind range_type,
-		    const wide_int_ref &min, const wide_int_ref &max)
-{
-  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
-  gcc_assert (range_type == VR_RANGE || range_type == VR_ANTI_RANGE);
-  range_info_def *ri = SSA_NAME_RANGE_INFO (name);
-  unsigned int precision = TYPE_PRECISION (TREE_TYPE (name));
-
-  /* Allocate if not available.  */
-  if (ri == NULL)
-    {
-      size_t size = (sizeof (range_info_def)
-		     + trailing_wide_ints <3>::extra_size (precision));
-      ri = static_cast<range_info_def *> (ggc_internal_alloc (size));
-      ri->ints.set_precision (precision);
-      SSA_NAME_RANGE_INFO (name) = ri;
-      ri->set_nonzero_bits (wi::shwi (-1, precision));
-    }
-
-  /* Record the range type.  */
-  if (SSA_NAME_RANGE_TYPE (name) != range_type)
-    SSA_NAME_ANTI_RANGE_P (name) = (range_type == VR_ANTI_RANGE);
+/* Update the range information for NAME, intersecting into an existing
+   range if applicable.  Return TRUE if the range was updated.  */
 
-  /* Set the values.  */
-  ri->set_min (min);
-  ri->set_max (max);
-
-  /* If it is a range, try to improve nonzero_bits from the min/max.  */
-  if (range_type == VR_RANGE)
-    {
-      wide_int xorv = ri->get_min () ^ ri->get_max ();
-      if (xorv != 0)
-	xorv = wi::mask (precision - wi::clz (xorv), false, precision);
-      ri->set_nonzero_bits (ri->get_nonzero_bits () & (ri->get_min () | xorv));
-    }
-}
-
-/* Store range information RANGE_TYPE, MIN, and MAX to tree ssa_name
-   NAME while making sure we don't store useless range info.  */
-
-static void
-set_range_info (tree name, enum value_range_kind range_type,
-		const wide_int_ref &min, const wide_int_ref &max)
+bool
+set_range_info (tree name, const vrange &r)
 {
-  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
+  if (r.undefined_p () || r.varying_p ())
+    return false;
 
   tree type = TREE_TYPE (name);
-  if (range_type == VR_VARYING)
+  if (POINTER_TYPE_P (type))
     {
-      /* SSA_NAME_RANGE_TYPE can only hold a VR_RANGE or
-	 VR_ANTI_RANGE.  Denormalize VR_VARYING to VR_RANGE.  */
-      range_type = VR_RANGE;
-      gcc_checking_assert (min == wi::min_value (type));
-      gcc_checking_assert (max == wi::max_value (type));
-    }
-
-  /* A range of the entire domain is really no range at all.  */
-  if (min == wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type))
-      && max == wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type)))
-    {
-      range_info_def *ri = SSA_NAME_RANGE_INFO (name);
-      if (ri == NULL)
-	return;
-      if (ri->get_nonzero_bits () == -1)
+      if (r.nonzero_p ())
 	{
-	  ggc_free (ri);
-	  SSA_NAME_RANGE_INFO (name) = NULL;
-	  return;
+	  set_ptr_nonnull (name);
+	  return true;
 	}
+      return false;
     }
 
-  set_range_info_raw (name, range_type, min, max);
-}
-
-/* Store range information for NAME from a value_range.  */
+  /* If a global range already exists, incorporate it.  */
+  if (range_info_p (name))
+    {
+      Value_Range tmp (type);
+      range_info_get_range (name, tmp);
+      tmp.intersect (r);
+      if (tmp.undefined_p ())
+	return false;
 
-void
-set_range_info (tree name, const value_range &vr)
-{
-  wide_int min = wi::to_wide (vr.min ());
-  wide_int max = wi::to_wide (vr.max ());
-  set_range_info (name, vr.kind (), min, max);
+      return range_info_set_range (name, tmp);
+    }
+  return range_info_set_range (name, r);
 }
 
 /* Set nonnull attribute to pointer NAME.  */
@@ -443,22 +456,16 @@ set_ptr_nonnull (tree name)
   pi->pt.null = 0;
 }
 
-/* Change non-zero bits bitmask of NAME.  */
+/* Update the non-zero bits bitmask of NAME.  */
 
 void
 set_nonzero_bits (tree name, const wide_int_ref &mask)
 {
   gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
-  if (SSA_NAME_RANGE_INFO (name) == NULL)
-    {
-      if (mask == -1)
-	return;
-      set_range_info_raw (name, VR_RANGE,
-			  wi::to_wide (TYPE_MIN_VALUE (TREE_TYPE (name))),
-			  wi::to_wide (TYPE_MAX_VALUE (TREE_TYPE (name))));
-    }
-  range_info_def *ri = SSA_NAME_RANGE_INFO (name);
-  ri->set_nonzero_bits (mask);
+
+  int_range<2> r (TREE_TYPE (name));
+  r.set_nonzero_bits (mask);
+  set_range_info (name, r);
 }
 
 /* Return a widest_int with potentially non-zero bits in SSA_NAME
@@ -482,10 +489,15 @@ get_nonzero_bits (const_tree name)
       return wi::shwi (-1, precision);
     }
 
-  range_info_def *ri = SSA_NAME_RANGE_INFO (name);
-  if (!ri)
+  if (!range_info_p (name))
     return wi::shwi (-1, precision);
 
+  /* Optimization to get at the nonzero bits because we know the
+     storage type.  This saves us measurable time compared to going
+     through vrange_storage.  */
+  gcc_checking_assert (irange::supports_p (TREE_TYPE (name)));
+  irange_storage_slot *ri
+    = static_cast <irange_storage_slot *> (SSA_NAME_RANGE_INFO (name));
   return ri->get_nonzero_bits ();
 }
 
@@ -727,38 +739,18 @@ duplicate_ssa_name_ptr_info (tree name, struct ptr_info_def *ptr_info)
   SSA_NAME_PTR_INFO (name) = new_ptr_info;
 }
 
-/* Creates a duplicate of the range_info_def at RANGE_INFO of type
-   RANGE_TYPE for use by the SSA name NAME.  */
-static void
-duplicate_ssa_name_range_info (tree name, enum value_range_kind range_type,
-			       struct range_info_def *range_info)
-{
-  struct range_info_def *new_range_info;
-
-  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
-  gcc_assert (!SSA_NAME_RANGE_INFO (name));
-
-  if (!range_info)
-    return;
-
-  unsigned int precision = TYPE_PRECISION (TREE_TYPE (name));
-  size_t size = (sizeof (range_info_def)
-		 + trailing_wide_ints <3>::extra_size (precision));
-  new_range_info = static_cast<range_info_def *> (ggc_internal_alloc (size));
-  memcpy (new_range_info, range_info, size);
-
-  gcc_assert (range_type == VR_RANGE || range_type == VR_ANTI_RANGE);
-  SSA_NAME_ANTI_RANGE_P (name) = (range_type == VR_ANTI_RANGE);
-  SSA_NAME_RANGE_INFO (name) = new_range_info;
-}
-
 void
 duplicate_ssa_name_range_info (tree name, tree src)
 {
   gcc_checking_assert (!POINTER_TYPE_P (TREE_TYPE (src)));
-  duplicate_ssa_name_range_info (name,
-				 SSA_NAME_RANGE_TYPE (src),
-				 SSA_NAME_RANGE_INFO (src));
+  gcc_checking_assert (!range_info_p (name));
+
+  if (range_info_p (src))
+    {
+      Value_Range src_range (TREE_TYPE (src));
+      range_info_get_range (src, src_range);
+      range_info_set_range (name, src_range);
+    }
 }
 
 
@@ -776,14 +768,8 @@ duplicate_ssa_name_fn (struct function *fn, tree name, gimple *stmt)
       if (old_ptr_info)
 	duplicate_ssa_name_ptr_info (new_name, old_ptr_info);
     }
-  else
-    {
-      struct range_info_def *old_range_info = SSA_NAME_RANGE_INFO (name);
-
-      if (old_range_info)
-	duplicate_ssa_name_range_info (new_name, SSA_NAME_RANGE_TYPE (name),
-				       old_range_info);
-    }
+  else if (range_info_p (name))
+    duplicate_ssa_name_range_info (new_name, name);
 
   return new_name;
 }
diff --git a/gcc/tree-ssanames.h b/gcc/tree-ssanames.h
index 8c419b13e6a..ce10af9670a 100644
--- a/gcc/tree-ssanames.h
+++ b/gcc/tree-ssanames.h
@@ -45,16 +45,6 @@ struct GTY(()) ptr_info_def
   unsigned int misalign;
 };
 
-/* Value range information for SSA_NAMEs representing non-pointer variables.  */
-
-struct GTY ((variable_size)) range_info_def {
-  /* Minimum, maximum and nonzero bits.  */
-  TRAILING_WIDE_INT_ACCESSOR (min, ints, 0)
-  TRAILING_WIDE_INT_ACCESSOR (max, ints, 1)
-  TRAILING_WIDE_INT_ACCESSOR (nonzero_bits, ints, 2)
-  trailing_wide_ints <3> ints;
-};
-
 
 #define SSANAMES(fun) (fun)->gimple_df->ssa_names
 #define DEFAULT_DEFS(fun) (fun)->gimple_df->default_defs
@@ -67,7 +57,7 @@ struct GTY ((variable_size)) range_info_def {
     if (VAR)
 
 /* Sets the value range to SSA.  */
-extern void set_range_info (tree, const value_range &);
+extern bool set_range_info (tree, const vrange &);
 extern void set_nonzero_bits (tree, const wide_int_ref &);
 extern wide_int get_nonzero_bits (const_tree);
 extern bool ssa_name_has_boolean_range (tree);
diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc
index ed881be7e5f..c3030a1b130 100644
--- a/gcc/tree-vrp.cc
+++ b/gcc/tree-vrp.cc
@@ -3739,16 +3739,18 @@ vrp_asserts::remove_range_assertions ()
 		    && all_imm_uses_in_stmt_or_feed_cond (var, stmt,
 							  single_pred (bb)))
 		  {
-		    /* We could use duplicate_ssa_name_range_info here
-		       instead of peeking inside SSA_NAME_RANGE_INFO,
-		       but the aforementioned asserts that the
-		       destination has no global range.  This is
-		       slated for removal anyhow.  */
-		    value_range r (TREE_TYPE (lhs),
-				   SSA_NAME_RANGE_INFO (lhs)->get_min (),
-				   SSA_NAME_RANGE_INFO (lhs)->get_max (),
-				   SSA_NAME_RANGE_TYPE (lhs));
-		    set_range_info (var, r);
+		    if (SSA_NAME_RANGE_INFO (var))
+		      {
+			/* ?? This is a minor wart exposing the
+			   internals of SSA_NAME_RANGE_INFO in order
+			   to maintain existing behavior.  This is
+			   because duplicate_ssa_name_range_info below
+			   needs a NULL destination range.  This is
+			   all slated for removal...  */
+			ggc_free (SSA_NAME_RANGE_INFO (var));
+			SSA_NAME_RANGE_INFO (var) = NULL;
+		      }
+		    duplicate_ssa_name_range_info (var, lhs);
 		    maybe_set_nonzero_bits (single_pred_edge (bb), var);
 		  }
 	      }
diff --git a/gcc/tree.h b/gcc/tree.h
index 6f6ad5a3a5f..e6564aaccb7 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -2030,14 +2030,6 @@ class auto_suppress_location_wrappers
 #define SSA_NAME_PTR_INFO(N) \
    SSA_NAME_CHECK (N)->ssa_name.info.ptr_info
 
-/* True if SSA_NAME_RANGE_INFO describes an anti-range.  */
-#define SSA_NAME_ANTI_RANGE_P(N) \
-    SSA_NAME_CHECK (N)->base.static_flag
-
-/* The type of range described by SSA_NAME_RANGE_INFO.  */
-#define SSA_NAME_RANGE_TYPE(N) \
-    (SSA_NAME_ANTI_RANGE_P (N) ? VR_ANTI_RANGE : VR_RANGE)
-
 /* Value range info attributes for SSA_NAMEs of non pointer-type variables.  */
 #define SSA_NAME_RANGE_INFO(N) \
     SSA_NAME_CHECK (N)->ssa_name.info.range_info
diff --git a/gcc/value-query.cc b/gcc/value-query.cc
index 1d7541ce34f..51911bdd1d0 100644
--- a/gcc/value-query.cc
+++ b/gcc/value-query.cc
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "value-query.h"
 #include "alloc-pool.h"
 #include "gimple-range.h"
+#include "value-range-storage.h"
 
 // value_query default methods.
 
@@ -271,13 +272,13 @@ range_query::get_tree_range (vrange &r, tree expr, gimple *stmt)
 // Return the range for NAME from SSA_NAME_RANGE_INFO.
 
 static inline void
-get_ssa_name_range_info (irange &r, const_tree name)
+get_ssa_name_range_info (vrange &r, const_tree name)
 {
   tree type = TREE_TYPE (name);
   gcc_checking_assert (!POINTER_TYPE_P (type));
   gcc_checking_assert (TREE_CODE (name) == SSA_NAME);
 
-  range_info_def *ri = SSA_NAME_RANGE_INFO (name);
+  void *ri = SSA_NAME_RANGE_INFO (name);
 
   // Return VR_VARYING for SSA_NAMEs with NULL RANGE_INFO or SSA_NAMEs
   // with integral types width > 2 * HOST_BITS_PER_WIDE_INT precision.
@@ -285,9 +286,10 @@ get_ssa_name_range_info (irange &r, const_tree name)
 	      > 2 * HOST_BITS_PER_WIDE_INT))
     r.set_varying (type);
   else
-    r.set (wide_int_to_tree (type, ri->get_min ()),
-	   wide_int_to_tree (type, ri->get_max ()),
-	   SSA_NAME_RANGE_TYPE (name));
+    {
+      vrange_storage vstore (NULL);
+      vstore.get_vrange (ri, r, TREE_TYPE (name));
+    }
 }
 
 // Return nonnull attribute of pointer NAME from SSA_NAME_PTR_INFO.
@@ -311,43 +313,6 @@ get_ssa_name_ptr_info_nonnull (const_tree name)
 }
 
 // Update the global range for NAME into the SSA_RANGE_NAME_INFO and
-// SSA_NAME_PTR_INFO fields.  Return TRUE if the range for NAME was
-// updated.
-
-bool
-update_global_range (vrange &r, tree name)
-{
-  tree type = TREE_TYPE (name);
-
-  if (r.undefined_p () || r.varying_p ())
-    return false;
-
-  if (INTEGRAL_TYPE_P (type))
-    {
-      // If a global range already exists, incorporate it.
-      if (SSA_NAME_RANGE_INFO (name))
-	{
-	  value_range glob;
-	  get_ssa_name_range_info (glob, name);
-	  r.intersect (glob);
-	}
-      if (r.undefined_p ())
-	return false;
-
-      set_range_info (name, as_a <irange> (r));
-      return true;
-    }
-  else if (POINTER_TYPE_P (type))
-    {
-      if (r.nonzero_p ())
-	{
-	  set_ptr_nonnull (name);
-	  return true;
-	}
-    }
-  return false;
-}
-
 // Return the legacy global range for NAME if it has one, otherwise
 // return VARYING.
 
@@ -372,7 +337,7 @@ get_range_global (vrange &r, tree name)
 	    r.set_nonzero (type);
 	  else if (INTEGRAL_TYPE_P (type))
 	    {
-	      get_ssa_name_range_info (as_a <irange> (r), name);
+	      get_ssa_name_range_info (r, name);
 	      if (r.undefined_p ())
 		r.set_varying (type);
 	    }
@@ -387,8 +352,7 @@ get_range_global (vrange &r, tree name)
    }
   else if (!POINTER_TYPE_P (type) && SSA_NAME_RANGE_INFO (name))
     {
-      gcc_checking_assert (irange::supports_p (TREE_TYPE (name)));
-      get_ssa_name_range_info (as_a <irange> (r), name);
+      get_ssa_name_range_info (r, name);
       if (r.undefined_p ())
 	r.set_varying (type);
     }
diff --git a/gcc/value-query.h b/gcc/value-query.h
index 280e47e3f6b..fc638eb76b1 100644
--- a/gcc/value-query.h
+++ b/gcc/value-query.h
@@ -144,6 +144,5 @@ get_range_query (const struct function *fun)
 }
 
 extern void gimple_range_global (vrange &v, tree name);
-extern bool update_global_range (vrange &v, tree name);
 
 #endif // GCC_QUERY_H
diff --git a/gcc/value-range-storage.cc b/gcc/value-range-storage.cc
index ac62bfaa638..8b5ab544ce3 100644
--- a/gcc/value-range-storage.cc
+++ b/gcc/value-range-storage.cc
@@ -30,7 +30,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-range.h"
 #include "value-range-storage.h"
 
-// Return a newly allocated slot holding R.
+// Return a newly allocated slot holding R, or NULL if storing a range
+// of R's type is not supported.
 
 void *
 vrange_storage::alloc_slot (const vrange &r)
@@ -40,7 +41,6 @@ vrange_storage::alloc_slot (const vrange &r)
   if (is_a <irange> (r))
     return irange_storage_slot::alloc_slot (*m_alloc, as_a <irange> (r));
 
-  gcc_unreachable ();
   return NULL;
 }


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-07-11  6:31 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-11  6:31 [gcc r13-1598] Implement global ranges for all vrange types (SSA_NAME_RANGE_INFO) Aldy Hernandez

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).