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.
This commit is contained in:
Aldy Hernandez 2020-09-11 10:15:12 +02:00
parent 69c56ce673
commit 77a23a825c

View File

@ -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