aboutsummaryrefslogtreecommitdiff
path: root/gcc/value-range.h
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2020-09-11 10:15:12 +0200
committerAldy Hernandez <aldyh@redhat.com>2020-09-29 00:23:53 +0200
commit77a23a825c2fcdac2a832998c228fd9d4ef99dd1 (patch)
tree731874d5e64de27b803291879d0369a66280085f /gcc/value-range.h
parent69c56ce673d1e1d4508e82053a32011f807c6088 (diff)
downloadgcc-77a23a825c2fcdac2a832998c228fd9d4ef99dd1.zip
gcc-77a23a825c2fcdac2a832998c228fd9d4ef99dd1.tar.gz
gcc-77a23a825c2fcdac2a832998c228fd9d4ef99dd1.tar.bz2
irange_allocator class
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 of the storage class. 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_allocator alloc; // Allocate an irange of 5 sub-ranges. irange *p = alloc.allocate (5); // Allocate an irange of 3 sub-ranges. irange *q = alloc.allocate (3); // Allocate an irange with as many sub-ranges as are currently // used in "some_other_range". irange *r = alloc.allocate (some_other_range); gcc/ChangeLog: * value-range.h (class irange): Add irange_allocator friend. (class irange_allocator): New.
Diffstat (limited to 'gcc/value-range.h')
-rw-r--r--gcc/value-range.h65
1 files changed, 65 insertions, 0 deletions
diff --git a/gcc/value-range.h b/gcc/value-range.h
index 8497791..c875e71 100644
--- a/gcc/value-range.h
+++ b/gcc/value-range.h
@@ -43,6 +43,7 @@ enum value_range_kind
class irange
{
+ friend class irange_allocator;
public:
// In-place setters.
void set (tree, tree, value_range_kind = VR_RANGE);
@@ -619,4 +620,68 @@ 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 of the storage class.
+//
+// It is meant for long term storage, as opposed to int_range_max
+// which is meant for intermediate temporary results on the stack.
+//
+// The newly allocated irange is initialized to the empty set
+// (undefined_p() is true).
+
+class irange_allocator
+{
+public:
+ irange_allocator ();
+ ~irange_allocator ();
+ // 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:
+ DISABLE_COPY_AND_ASSIGN (irange_allocator);
+ struct obstack m_obstack;
+};
+
+inline
+irange_allocator::irange_allocator ()
+{
+ obstack_init (&m_obstack);
+}
+
+inline
+irange_allocator::~irange_allocator ()
+{
+ obstack_free (&m_obstack, NULL);
+}
+
+// Return a new range with NUM_PAIRS.
+
+inline irange *
+irange_allocator::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];
+ };
+ size_t nbytes = (sizeof (newir) + sizeof (tree) * 2 * (num_pairs - 1));
+ struct newir *r = (newir *) obstack_alloc (&m_obstack, nbytes);
+ return new (r) irange (r->mem, num_pairs);
+}
+
+inline irange *
+irange_allocator::allocate (const irange &src)
+{
+ irange *r = allocate (src.num_pairs ());
+ *r = src;
+ return r;
+}
+
#endif // GCC_VALUE_RANGE_H