mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-02 16:23:56 +08:00
Add storage support for prange.
gcc/ChangeLog: * value-range-storage.cc (vrange_allocator::clone_varying): Add prange support. (vrange_allocator::clone_undefined): Same. (vrange_storage::alloc): Same. (vrange_storage::set_vrange): Same. (vrange_storage::get_vrange): Same. (vrange_storage::fits_p): Same. (vrange_storage::equal_p): Same. (prange_storage::alloc): New. (prange_storage::prange_storage): New. (prange_storage::set_prange): New. (prange_storage::get_prange): New. (prange_storage::equal_p): New. (prange_storage::fits_p): New. * value-range-storage.h (class prange_storage): Add prange support.
This commit is contained in:
parent
a7f1285380
commit
f859996a97
@ -118,6 +118,8 @@ vrange_allocator::clone_varying (tree type)
|
||||
{
|
||||
if (irange::supports_p (type))
|
||||
return irange_storage::alloc (*m_alloc, int_range <1> (type));
|
||||
if (prange::supports_p (type))
|
||||
return prange_storage::alloc (*m_alloc, prange (type));
|
||||
if (frange::supports_p (type))
|
||||
return frange_storage::alloc (*m_alloc, frange (type));
|
||||
return NULL;
|
||||
@ -128,6 +130,8 @@ vrange_allocator::clone_undefined (tree type)
|
||||
{
|
||||
if (irange::supports_p (type))
|
||||
return irange_storage::alloc (*m_alloc, int_range<1> ());
|
||||
if (prange::supports_p (type))
|
||||
return prange_storage::alloc (*m_alloc, prange ());
|
||||
if (frange::supports_p (type))
|
||||
return frange_storage::alloc (*m_alloc, frange ());
|
||||
return NULL;
|
||||
@ -141,6 +145,8 @@ vrange_storage::alloc (vrange_internal_alloc &allocator, const vrange &r)
|
||||
{
|
||||
if (is_a <irange> (r))
|
||||
return irange_storage::alloc (allocator, as_a <irange> (r));
|
||||
if (is_a <prange> (r))
|
||||
return prange_storage::alloc (allocator, as_a <prange> (r));
|
||||
if (is_a <frange> (r))
|
||||
return frange_storage::alloc (allocator, as_a <frange> (r));
|
||||
return NULL;
|
||||
@ -157,6 +163,12 @@ vrange_storage::set_vrange (const vrange &r)
|
||||
gcc_checking_assert (s->fits_p (as_a <irange> (r)));
|
||||
s->set_irange (as_a <irange> (r));
|
||||
}
|
||||
else if (is_a <prange> (r))
|
||||
{
|
||||
prange_storage *s = static_cast <prange_storage *> (this);
|
||||
gcc_checking_assert (s->fits_p (as_a <prange> (r)));
|
||||
s->set_prange (as_a <prange> (r));
|
||||
}
|
||||
else if (is_a <frange> (r))
|
||||
{
|
||||
frange_storage *s = static_cast <frange_storage *> (this);
|
||||
@ -190,6 +202,11 @@ vrange_storage::get_vrange (vrange &r, tree type) const
|
||||
const irange_storage *s = static_cast <const irange_storage *> (this);
|
||||
s->get_irange (as_a <irange> (r), type);
|
||||
}
|
||||
else if (is_a <prange> (r))
|
||||
{
|
||||
const prange_storage *s = static_cast <const prange_storage *> (this);
|
||||
s->get_prange (as_a <prange> (r), type);
|
||||
}
|
||||
else if (is_a <frange> (r))
|
||||
{
|
||||
const frange_storage *s = static_cast <const frange_storage *> (this);
|
||||
@ -209,6 +226,11 @@ vrange_storage::fits_p (const vrange &r) const
|
||||
const irange_storage *s = static_cast <const irange_storage *> (this);
|
||||
return s->fits_p (as_a <irange> (r));
|
||||
}
|
||||
if (is_a <prange> (r))
|
||||
{
|
||||
const prange_storage *s = static_cast <const prange_storage *> (this);
|
||||
return s->fits_p (as_a <prange> (r));
|
||||
}
|
||||
if (is_a <frange> (r))
|
||||
{
|
||||
const frange_storage *s = static_cast <const frange_storage *> (this);
|
||||
@ -230,6 +252,11 @@ vrange_storage::equal_p (const vrange &r) const
|
||||
const irange_storage *s = static_cast <const irange_storage *> (this);
|
||||
return s->equal_p (as_a <irange> (r));
|
||||
}
|
||||
if (is_a <prange> (r))
|
||||
{
|
||||
const prange_storage *s = static_cast <const prange_storage *> (this);
|
||||
return s->equal_p (as_a <prange> (r));
|
||||
}
|
||||
if (is_a <frange> (r))
|
||||
{
|
||||
const frange_storage *s = static_cast <const frange_storage *> (this);
|
||||
@ -559,6 +586,96 @@ frange_storage::fits_p (const frange &) const
|
||||
return true;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
// prange_storage implementation
|
||||
//============================================================================
|
||||
|
||||
prange_storage *
|
||||
prange_storage::alloc (vrange_internal_alloc &allocator, const prange &r)
|
||||
{
|
||||
// Assume all pointers are the same size.
|
||||
unsigned prec = TYPE_PRECISION (TREE_TYPE (null_pointer_node));
|
||||
gcc_checking_assert (r.undefined_p () || TYPE_PRECISION (r.type ()) == prec);
|
||||
|
||||
typedef trailing_wide_ints<NINTS> twi;
|
||||
size_t size = sizeof (prange_storage) + twi::extra_size (prec);
|
||||
prange_storage *p = static_cast <prange_storage *> (allocator.alloc (size));
|
||||
new (p) prange_storage (r);
|
||||
return p;
|
||||
}
|
||||
|
||||
// Initialize the storage with R.
|
||||
|
||||
prange_storage::prange_storage (const prange &r)
|
||||
{
|
||||
// It is the caller's responsibility to allocate enough space such
|
||||
// that the precision fits.
|
||||
unsigned prec = TYPE_PRECISION (TREE_TYPE (null_pointer_node));
|
||||
m_trailing_ints.set_precision (prec);
|
||||
|
||||
set_prange (r);
|
||||
}
|
||||
|
||||
void
|
||||
prange_storage::set_prange (const prange &r)
|
||||
{
|
||||
if (r.undefined_p ())
|
||||
m_kind = VR_UNDEFINED;
|
||||
else if (r.varying_p ())
|
||||
m_kind = VR_VARYING;
|
||||
else
|
||||
{
|
||||
m_kind = VR_RANGE;
|
||||
set_low (r.lower_bound ());
|
||||
set_high (r.upper_bound ());
|
||||
irange_bitmask bm = r.m_bitmask;
|
||||
set_value (bm.value ());
|
||||
set_mask (bm.mask ());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
prange_storage::get_prange (prange &r, tree type) const
|
||||
{
|
||||
gcc_checking_assert (r.supports_type_p (type));
|
||||
|
||||
if (m_kind == VR_UNDEFINED)
|
||||
r.set_undefined ();
|
||||
else if (m_kind == VR_VARYING)
|
||||
r.set_varying (type);
|
||||
else
|
||||
{
|
||||
gcc_checking_assert (m_kind == VR_RANGE);
|
||||
gcc_checking_assert (TYPE_PRECISION (type) == m_trailing_ints.get_precision ());
|
||||
r.m_kind = VR_RANGE;
|
||||
r.m_type = type;
|
||||
r.m_min = get_low ();
|
||||
r.m_max = get_high ();
|
||||
r.m_bitmask = irange_bitmask (get_value (), get_mask ());
|
||||
if (flag_checking)
|
||||
r.verify_range ();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
prange_storage::equal_p (const prange &r) const
|
||||
{
|
||||
if (r.undefined_p ())
|
||||
return m_kind == VR_UNDEFINED;
|
||||
|
||||
prange tmp;
|
||||
get_prange (tmp, r.type ());
|
||||
return tmp == r;
|
||||
}
|
||||
|
||||
bool
|
||||
prange_storage::fits_p (const prange &) const
|
||||
{
|
||||
// All pointers are the same size.
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static vrange_allocator ggc_vrange_allocator (true);
|
||||
|
||||
vrange_storage *ggc_alloc_vrange_storage (tree type)
|
||||
|
@ -98,6 +98,39 @@ private:
|
||||
irange_storage (const irange &r);
|
||||
};
|
||||
|
||||
// Efficient memory storage for a prange.
|
||||
|
||||
class prange_storage : public vrange_storage
|
||||
{
|
||||
public:
|
||||
static prange_storage *alloc (vrange_internal_alloc &, const prange &);
|
||||
void set_prange (const prange &r);
|
||||
void get_prange (prange &r, tree type) const;
|
||||
bool equal_p (const prange &r) const;
|
||||
bool fits_p (const prange &r) const;
|
||||
void dump () const;
|
||||
private:
|
||||
DISABLE_COPY_AND_ASSIGN (prange_storage);
|
||||
prange_storage (const prange &r);
|
||||
|
||||
enum value_range_kind m_kind : 3;
|
||||
|
||||
// We don't use TRAILING_WIDE_INT_ACCESSOR because the getters here
|
||||
// must be const. Perhaps TRAILING_WIDE_INT_ACCESSOR could be made
|
||||
// const and return wide_int instead of trailing_wide_int.
|
||||
wide_int get_low () const { return m_trailing_ints[0]; }
|
||||
wide_int get_high () const { return m_trailing_ints[1]; }
|
||||
wide_int get_value () const { return m_trailing_ints[2]; }
|
||||
wide_int get_mask () const { return m_trailing_ints[3]; }
|
||||
template <typename T> void set_low (const T &x) { m_trailing_ints[0] = x; }
|
||||
template <typename T> void set_high (const T &x) { m_trailing_ints[1] = x; }
|
||||
template <typename T> void set_value (const T &x) { m_trailing_ints[2] = x; }
|
||||
template <typename T> void set_mask (const T &x) { m_trailing_ints[3] = x; }
|
||||
|
||||
static const unsigned int NINTS = 4;
|
||||
trailing_wide_ints<NINTS> m_trailing_ints;
|
||||
};
|
||||
|
||||
// Efficient memory storage for an frange.
|
||||
|
||||
class frange_storage : public vrange_storage
|
||||
|
Loading…
Reference in New Issue
Block a user