diff options
author | Aldy Hernandez <aldyh@redhat.com> | 2020-09-11 10:15:12 +0200 |
---|---|---|
committer | Aldy Hernandez <aldyh@redhat.com> | 2020-09-29 00:23:53 +0200 |
commit | 77a23a825c2fcdac2a832998c228fd9d4ef99dd1 (patch) | |
tree | 731874d5e64de27b803291879d0369a66280085f /gcc/value-range.h | |
parent | 69c56ce673d1e1d4508e82053a32011f807c6088 (diff) | |
download | gcc-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.h | 65 |
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 |