This is the irange storage class. It is used to allocate the minimum amount of storage needed for a given irange. Storage is automatically freed at destruction.

It is meant for long term storage, as opposed to int_range_max which is meant for intermediate temporary results on the stack.

The general gist is:

        irange_pool pool;

        // Allocate an irange of 5 sub-ranges.
        irange *p = pool.allocate (5);

        // Allocate an irange of 3 sub-ranges.
        irange *q = pool.allocate (3);

        // Allocate an irange with as many sub-ranges as are currently
        // used in "some_other_range".
        irange *r = pool.allocate (some_other_range);

OK?
Aldy
---
 gcc/value-range.h | 63 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)

diff --git a/gcc/value-range.h b/gcc/value-range.h
index 8497791c7b3..88cb3075bf0 100644
--- a/gcc/value-range.h
+++ b/gcc/value-range.h
@@ -43,6 +43,7 @@ enum value_range_kind

 class irange
 {
+  friend class irange_pool;
 public:
   // In-place setters.
   void set (tree, tree, value_range_kind = VR_RANGE);
@@ -619,4 +620,66 @@ vrp_val_min (const_tree type)
   return NULL_TREE;
 }

+// This is the irange storage class.  It is used to allocate the
+// minimum amount of storage needed for a given irange.  Storage is
+// automatically freed at destruction.
+//
+// It is meant for long term storage, as opposed to int_range_max
+// which is meant for intermediate temporary results on the stack.
+
+class irange_pool
+{
+public:
+  irange_pool ();
+  ~irange_pool ();
+  // Return a new range with NUM_PAIRS.
+  irange *allocate (unsigned num_pairs);
+  // Return a copy of SRC with the minimum amount of sub-ranges needed
+  // to represent it.
+  irange *allocate (const irange &src);
+private:
+  struct obstack irange_obstack;
+};
+
+inline
+irange_pool::irange_pool ()
+{
+  obstack_init (&irange_obstack);
+}
+
+inline
+irange_pool::~irange_pool ()
+{
+  obstack_free (&irange_obstack, NULL);
+}
+
+// Return a new range with NUM_PAIRS.
+
+inline irange *
+irange_pool::allocate (unsigned num_pairs)
+{
+  // Never allocate 0 pairs.
+  // Don't allocate 1 either, or we get legacy value_range's.
+  if (num_pairs < 2)
+    num_pairs = 2;
+
+  struct newir {
+    irange range;
+    tree mem[1];
+  };
+  struct newir *r
+    = (struct newir *) obstack_alloc (&irange_obstack,
+                                     sizeof (struct newir)
+                                     + sizeof (tree) * 2 * (num_pairs - 1));
+  return new ((irange *) r) irange (&(r->mem[0]), num_pairs);
+}
+
+inline irange *
+irange_pool::allocate (const irange &src)
+{
+  irange *r = allocate (src.num_pairs ());
+  *r = src;
+  return r;
+}
+
 #endif // GCC_VALUE_RANGE_H
--
2.26.2

Reply via email to