public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [COMMITTED] Flesh out unsupported_range.
@ 2022-06-03  7:32 Aldy Hernandez
  2022-06-03  7:32 ` [COMMITTED] Remove unneeded vrange_traits Aldy Hernandez
  2022-06-03  7:32 ` [COMMITTED] Misc range temporary fixes Aldy Hernandez
  0 siblings, 2 replies; 3+ messages in thread
From: Aldy Hernandez @ 2022-06-03  7:32 UTC (permalink / raw)
  To: GCC patches

It's cleaner to have the unsupported_range fully fleshed out, instead
of trapping on every operation.  It can also serve as the basis for
the default vrange methods that frange and prange will inherit.

This patch implements most methods, including union and intersect, to
handle an UNDEFINED and a VARYING range.

Since this can serve as the basis for other classes, I have moved
everything into the vrange class, making the unsupported_range
trivial.

Note that vrange is still an abstract class, as I have purposely left
the dump() method abstract.

Also, I have made the unsupported range in the temporary class
(Value_Range) a method field, instead of a static member.  This way
the temporary can set UNDEFINED and VARYING as needed.

Tested on x86-64 Linux.

gcc/ChangeLog:

	* value-range.cc (vrange::contains_p): Implement.
	(vrange::type): Return void.
	(vrange::supports_type_p): Implement.
	(irange::fits_p): Same.
	(vrange::set_undefined): Same.
	(irange::set_nonnegative): Same.
	(vrange::set_varying): Same.
	(vrange::union_): Same.
	(unsupported_range::set): Move to vrange.
	(unsupported_range::type): Move to vrange.
	(vrange::intersect): Implement for varying and undefined.
	(vrange::zero_p): Implement.
	(unsupported_range::supports_type_p): Move to vrange.
	(vrange::nonzero_p): Implement.
	(unsupported_range::set_undefined): Move to vrange.
	(unsupported_range::set_varying): Same.
	(unsupported_range::dump): Same.
	(unsupported_range::union_): Same.  Implement for varying and
	undefined.
	(unsupported_range::intersect): Move to vrange.
	(unsupported_range::zero_p): Same.
	(unsupported_range::nonzero_p): Same.
	(unsupported_range::set_nonzero): Same.
	(unsupported_range::set_zero): Same.
	(unsupported_range::set_nonnegative): Same.
	(unsupported_range::fits_p): Same.
	* value-range.h (class vrange): Remove abstract markers for most
	methods.
	(class unsupported_range): Remove most methods as they will now be
	inherited from vrange.
---
 gcc/value-range.cc | 175 +++++++++++++++++++++++----------------------
 gcc/value-range.h  |  44 ++++--------
 2 files changed, 106 insertions(+), 113 deletions(-)

diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index c4bcb970094..815cb783abc 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -66,176 +66,183 @@ debug (const Value_Range &r)
   fprintf (stderr, "\n");
 }
 
-// Default implementation when none has been defined.
+// Default vrange definitions.
 
 bool
 vrange::contains_p (tree) const
 {
-  return false;
+  return varying_p ();
 }
 
-// Default implementation when none has been defined.
-
 bool
 vrange::singleton_p (tree *) const
 {
   return false;
 }
 
-// Assignment operator for generic ranges.  Copying incompatible types
-// is not allowed.
-
-vrange &
-vrange::operator= (const vrange &src)
+void
+vrange::set (tree, tree, value_range_kind)
 {
-  if (is_a <irange> (src))
-    {
-      as_a <irange> (*this) = as_a <irange> (src);
-      return *this;
-    }
-  else
-    gcc_unreachable ();
 }
 
-// Equality operator for generic ranges.
-
-bool
-vrange::operator== (const vrange &src) const
+tree
+vrange::type () const
 {
-  if (is_a <irange> (src))
-    return as_a <irange> (*this) == as_a <irange> (src);
-  gcc_unreachable ();
+  return void_type_node;
 }
 
 bool
-irange::supports_type_p (tree type) const
+vrange::supports_type_p (tree) const
 {
-  return supports_p (type);
+  return false;
 }
 
-// Return TRUE if R fits in THIS.
-
-bool
-irange::fits_p (const vrange &r) const
+void
+vrange::set_undefined ()
 {
-  return m_max_ranges >= as_a <irange> (r).num_pairs ();
+  m_kind = VR_UNDEFINED;
 }
 
 void
-irange::set_nonnegative (tree type)
+vrange::set_varying (tree)
 {
-  set (build_int_cst (type, 0), TYPE_MAX_VALUE (type));
+  m_kind = VR_VARYING;
 }
 
-unsupported_range::unsupported_range ()
+bool
+vrange::union_ (const vrange &r)
 {
-  m_discriminator = VR_UNKNOWN;
-  set_undefined ();
+  if (r.undefined_p () || varying_p ())
+    return false;
+  if (undefined_p () || r.varying_p ())
+    {
+      operator= (r);
+      return true;
+    }
+  gcc_unreachable ();
+  return false;
 }
 
-void
-unsupported_range::set (tree, tree, value_range_kind)
+bool
+vrange::intersect (const vrange &r)
 {
+  if (undefined_p () || r.varying_p ())
+    return false;
+  if (r.undefined_p ())
+    {
+      set_undefined ();
+      return true;
+    }
+  if (varying_p ())
+    {
+      operator= (r);
+      return true;
+    }
   gcc_unreachable ();
+  return false;
 }
 
-tree
-unsupported_range::type () const
+bool
+vrange::zero_p () const
 {
-  gcc_unreachable ();
-  return nullptr;
+  return false;
 }
 
 bool
-unsupported_range::supports_type_p (tree) const
+vrange::nonzero_p () const
 {
   return false;
 }
 
 void
-unsupported_range::set_undefined ()
+vrange::set_nonzero (tree)
 {
-  m_kind = VR_UNDEFINED;
 }
 
 void
-unsupported_range::set_varying (tree)
+vrange::set_zero (tree)
 {
-  gcc_unreachable ();
 }
 
 void
-unsupported_range::dump (FILE *file) const
+vrange::set_nonnegative (tree)
 {
-  fprintf (file, "[unsupported_range] ");
-  if (undefined_p ())
-    {
-      fprintf (file, "UNDEFINED");
-      return;
-    }
-  if (varying_p ())
-    {
-      fprintf (file, "VARYING");
-      return;
-    }
-  gcc_unreachable ();
 }
 
 bool
-unsupported_range::union_ (const vrange &)
+vrange::fits_p (const vrange &) const
 {
-  gcc_unreachable ();
-  return false;
+  return true;
 }
 
-bool
-unsupported_range::intersect (const vrange &)
+// Assignment operator for generic ranges.  Copying incompatible types
+// is not allowed.
+
+vrange &
+vrange::operator= (const vrange &src)
 {
-  gcc_unreachable ();
-  return false;
+  if (is_a <irange> (src))
+    {
+      as_a <irange> (*this) = as_a <irange> (src);
+      return *this;
+    }
+  else
+    gcc_unreachable ();
 }
 
+// Equality operator for generic ranges.
+
 bool
-unsupported_range::zero_p () const
+vrange::operator== (const vrange &src) const
 {
+  if (is_a <irange> (src))
+    return as_a <irange> (*this) == as_a <irange> (src);
   gcc_unreachable ();
-  return false;
 }
 
 bool
-unsupported_range::nonzero_p () const
+irange::supports_type_p (tree type) const
 {
-  gcc_unreachable ();
-  return false;
+  return supports_p (type);
 }
 
-void
-unsupported_range::set_nonzero (tree)
+// Return TRUE if R fits in THIS.
+
+bool
+irange::fits_p (const vrange &r) const
 {
-  gcc_unreachable ();
+  return m_max_ranges >= as_a <irange> (r).num_pairs ();
 }
 
 void
-unsupported_range::set_zero (tree)
+irange::set_nonnegative (tree type)
 {
-  gcc_unreachable ();
+  set (build_int_cst (type, 0), TYPE_MAX_VALUE (type));
 }
 
-void
-unsupported_range::set_nonnegative (tree)
+unsupported_range::unsupported_range ()
 {
-  gcc_unreachable ();
+  m_discriminator = VR_UNKNOWN;
+  set_undefined ();
 }
 
-bool
-unsupported_range::fits_p (const vrange &) const
+void
+unsupported_range::dump (FILE *file) const
 {
+  fprintf (file, "[unsupported_range] ");
+  if (undefined_p ())
+    {
+      fprintf (file, "UNDEFINED");
+      return;
+    }
+  if (varying_p ())
+    {
+      fprintf (file, "VARYING");
+      return;
+    }
   gcc_unreachable ();
-  return false;
 }
 
-unsupported_range Value_Range::m_unsupported;
-
 // Here we copy between any two irange's.  The ranges can be legacy or
 // multi-ranges, and copying between any combination works correctly.
 
diff --git a/gcc/value-range.h b/gcc/value-range.h
index 69cf6c304d6..61e6a1887d5 100644
--- a/gcc/value-range.h
+++ b/gcc/value-range.h
@@ -73,22 +73,22 @@ class vrange
   template <typename T> friend bool is_a (vrange &);
   friend class Value_Range;
 public:
-  virtual void set (tree, tree, value_range_kind = VR_RANGE) = 0;
-  virtual tree type () const = 0;
-  virtual bool supports_type_p (tree type) const = 0;
-  virtual void set_varying (tree type) = 0;
-  virtual void set_undefined () = 0;
+  virtual void set (tree, tree, value_range_kind = VR_RANGE);
+  virtual tree type () const;
+  virtual bool supports_type_p (tree type) const;
+  virtual void set_varying (tree type);
+  virtual void set_undefined ();
   virtual void dump (FILE * = stderr) const = 0;
-  virtual bool union_ (const vrange &) = 0;
-  virtual bool intersect (const vrange &) = 0;
+  virtual bool union_ (const vrange &);
+  virtual bool intersect (const vrange &);
   virtual bool singleton_p (tree *result = NULL) const;
   virtual bool contains_p (tree cst) const;
-  virtual bool zero_p () const = 0;
-  virtual bool nonzero_p () const = 0;
-  virtual void set_nonzero (tree type) = 0;
-  virtual void set_zero (tree type) = 0;
-  virtual void set_nonnegative (tree type) = 0;
-  virtual bool fits_p (const vrange &r) const = 0;
+  virtual bool zero_p () const;
+  virtual bool nonzero_p () const;
+  virtual void set_nonzero (tree type);
+  virtual void set_zero (tree type);
+  virtual void set_nonnegative (tree type);
+  virtual bool fits_p (const vrange &r) const;
 
   bool varying_p () const;
   bool undefined_p () const;
@@ -236,27 +236,13 @@ private:
 };
 
 // Unsupported temporaries may be created by ranger before it's known
-// they're unsupported, or by vr_values::get_value_range.  All
-// operations except construction cause a trap.
+// they're unsupported, or by vr_values::get_value_range.
 
 class unsupported_range : public vrange
 {
 public:
   unsupported_range ();
-  virtual void set (tree, tree, value_range_kind) override;
-  virtual tree type () const override;
-  virtual bool supports_type_p (tree type) const override;
-  virtual void set_varying (tree type) override;
-  virtual void set_undefined () override;
   virtual void dump (FILE *) const override;
-  virtual bool union_ (const vrange &) override;
-  virtual bool intersect (const vrange &) override;
-  virtual bool zero_p () const override;
-  virtual bool nonzero_p () const override;
-  virtual void set_nonzero (tree) override;
-  virtual void set_zero (tree) override;
-  virtual void set_nonnegative (tree) override;
-  virtual bool fits_p (const vrange &) const override;
 };
 
 // Traits to implement vrange is_a<> and as_a<>.
@@ -369,7 +355,7 @@ public:
   wide_int upper_bound () const; // For irange/prange compatability.
 private:
   void init (tree type);
-  static unsupported_range m_unsupported;
+  unsupported_range m_unsupported;
   vrange *m_vrange;
   int_range_max m_irange;
   DISABLE_COPY_AND_ASSIGN (Value_Range);
-- 
2.36.1


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [COMMITTED] Remove unneeded vrange_traits.
  2022-06-03  7:32 [COMMITTED] Flesh out unsupported_range Aldy Hernandez
@ 2022-06-03  7:32 ` Aldy Hernandez
  2022-06-03  7:32 ` [COMMITTED] Misc range temporary fixes Aldy Hernandez
  1 sibling, 0 replies; 3+ messages in thread
From: Aldy Hernandez @ 2022-06-03  7:32 UTC (permalink / raw)
  To: GCC patches

The traits struct is no longer needed.

Tested on x86-64 Linux.

gcc/ChangeLog:

	* value-range.h (struct vrange_traits): Remove.
	(is_a): Rewrite without vrange_traits.
	(as_a): Same.
---
 gcc/value-range.h | 28 +++++++---------------------
 1 file changed, 7 insertions(+), 21 deletions(-)

diff --git a/gcc/value-range.h b/gcc/value-range.h
index 61e6a1887d5..26e41ed2982 100644
--- a/gcc/value-range.h
+++ b/gcc/value-range.h
@@ -245,24 +245,12 @@ public:
   virtual void dump (FILE *) const override;
 };
 
-// Traits to implement vrange is_a<> and as_a<>.
-
-template<typename T>
-struct vrange_traits
-{
-  // Default to something unusable.
-  typedef void range_type;
-};
-
-template<>
-struct vrange_traits<irange>
-{
-  typedef irange range_type;
-};
+// is_a<> and as_a<> implementation for vrange.
 
+// Anything we haven't specialized is a hard fail.
 template <typename T>
 inline bool
-is_a (vrange &v)
+is_a (vrange &)
 {
   gcc_unreachable ();
   return false;
@@ -281,18 +269,16 @@ template <typename T>
 inline T &
 as_a (vrange &v)
 {
-  typedef typename vrange_traits<T>::range_type range_type;
-  gcc_checking_assert (is_a <range_type> (v));
-  return static_cast <range_type &> (v);
+  gcc_checking_assert (is_a <T> (v));
+  return static_cast <T &> (v);
 }
 
 template <typename T>
 inline const T &
 as_a (const vrange &v)
 {
-  typedef typename vrange_traits<T>::range_type range_type;
-  gcc_checking_assert (is_a <range_type> (v));
-  return static_cast <const range_type &> (v);
+  gcc_checking_assert (is_a <T> (v));
+  return static_cast <const T &> (v);
 }
 
 // Specializations for the different range types.
-- 
2.36.1


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [COMMITTED] Misc range temporary fixes.
  2022-06-03  7:32 [COMMITTED] Flesh out unsupported_range Aldy Hernandez
  2022-06-03  7:32 ` [COMMITTED] Remove unneeded vrange_traits Aldy Hernandez
@ 2022-06-03  7:32 ` Aldy Hernandez
  1 sibling, 0 replies; 3+ messages in thread
From: Aldy Hernandez @ 2022-06-03  7:32 UTC (permalink / raw)
  To: GCC patches

This fixes a couples places that were using int_range_max, but needed
a generic temporary.  Found while merging the frange work.

Also, copying between range temporaries is actually useful :).

Tested on x86-64 Linux.

gcc/ChangeLog:

	* gimple-range-cache.cc (ranger_cache::range_from_dom): Use
	Value_Range.
	* gimple-range.cc (gimple_ranger::register_inferred_ranges): Same.
	* value-range.h (Value_Range::Value_Range): Implement copy
	constructor for Value_Range.
---
 gcc/gimple-range-cache.cc | 2 +-
 gcc/gimple-range.cc       | 9 ++++++---
 gcc/value-range.h         | 8 +++++++-
 3 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc
index 85eed4421f4..f3494363a10 100644
--- a/gcc/gimple-range-cache.cc
+++ b/gcc/gimple-range-cache.cc
@@ -1372,7 +1372,7 @@ ranger_cache::range_from_dom (vrange &r, tree name, basic_block start_bb,
 	      // each incoming edge now and accumulate the results.
 	      r.set_undefined ();
 	      edge_iterator ei;
-	      int_range_max er;
+	      Value_Range er (TREE_TYPE (name));
 	      FOR_EACH_EDGE (e, ei, prev_bb->preds)
 		{
 		  edge_range (er, e, name, RFD_READ_ONLY);
diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc
index 67dafb2a2c0..f3a46555f91 100644
--- a/gcc/gimple-range.cc
+++ b/gcc/gimple-range.cc
@@ -461,17 +461,20 @@ gimple_ranger::register_inferred_ranges (gimple *s)
   tree lhs = gimple_get_lhs (s);
   if (lhs)
     {
-      int_range_max tmp;
+      Value_Range tmp (TREE_TYPE (lhs));
       if (range_of_stmt (tmp, s, lhs) && !tmp.varying_p ()
 	  && update_global_range (tmp, lhs) && dump_file)
 	{
-	  value_range vr = tmp;
+	  // ?? 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 != tmp)
+	  if (same != as_a <irange> (tmp))
 	    {
 	      fprintf (dump_file, " ...  irange was : ");
 	      tmp.dump (dump_file);
diff --git a/gcc/value-range.h b/gcc/value-range.h
index 26e41ed2982..dc6f6b0f935 100644
--- a/gcc/value-range.h
+++ b/gcc/value-range.h
@@ -314,6 +314,7 @@ public:
   Value_Range ();
   Value_Range (const vrange &r);
   Value_Range (tree type);
+  Value_Range (const Value_Range &);
   void set_type (tree type);
   vrange& operator= (const vrange &);
   bool operator== (const Value_Range &r) const;
@@ -344,7 +345,6 @@ private:
   unsupported_range m_unsupported;
   vrange *m_vrange;
   int_range_max m_irange;
-  DISABLE_COPY_AND_ASSIGN (Value_Range);
 };
 
 inline
@@ -370,6 +370,12 @@ Value_Range::Value_Range (tree type)
   init (type);
 }
 
+inline
+Value_Range::Value_Range (const Value_Range &r)
+{
+  m_vrange = r.m_vrange;
+}
+
 // Initialize object so it is possible to store temporaries of TYPE
 // into it.
 
-- 
2.36.1


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2022-06-03  7:32 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-03  7:32 [COMMITTED] Flesh out unsupported_range Aldy Hernandez
2022-06-03  7:32 ` [COMMITTED] Remove unneeded vrange_traits Aldy Hernandez
2022-06-03  7:32 ` [COMMITTED] Misc range temporary fixes 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).