diff options
Diffstat (limited to 'gcc/value-range-storage.h')
-rw-r--r-- | gcc/value-range-storage.h | 226 |
1 files changed, 62 insertions, 164 deletions
diff --git a/gcc/value-range-storage.h b/gcc/value-range-storage.h index 070b85c..4ec0da7 100644 --- a/gcc/value-range-storage.h +++ b/gcc/value-range-storage.h @@ -21,97 +21,101 @@ along with GCC; see the file COPYING3. If not see #ifndef GCC_VALUE_RANGE_STORAGE_H #define GCC_VALUE_RANGE_STORAGE_H -// This class is used to allocate the minimum amount of storage needed -// for a given range. Storage is automatically freed at destruction -// of the class. +// This class is used to allocate chunks of memory that can store +// ranges as memory efficiently as possible. class vrange_allocator { public: - vrange_allocator () { } - virtual ~vrange_allocator () { } - // Allocate a range of TYPE. - vrange *alloc_vrange (tree type); - // Allocate a memory block of BYTES. - virtual void *alloc (unsigned bytes) = 0; - virtual void free (void *p) = 0; - // Return a clone of SRC. - template <typename T> T *clone (const T &src); + // Use GC memory when GC is true, otherwise use obstacks. + vrange_allocator (bool gc = false); + ~vrange_allocator (); + class vrange_storage *clone (const vrange &r); + vrange_storage *clone_varying (tree type); + vrange_storage *clone_undefined (tree type); + void *alloc (size_t size); + void free (void *); private: - irange *alloc_irange (unsigned pairs); - frange *alloc_frange (); - void operator= (const vrange_allocator &) = delete; + DISABLE_COPY_AND_ASSIGN (vrange_allocator); + class vrange_internal_alloc *m_alloc; + bool m_gc; }; -// This class is used to allocate chunks of memory that can store -// ranges as memory efficiently as possible. It is meant to be used -// when long term storage of a range is needed. The class can be used -// with any vrange_allocator (i.e. alloca or GC). +// Efficient memory storage for a vrange. +// +// The GTY marker here does nothing but get gengtype to generate the +// ggc_test_and_set_mark calls. We ignore the derived classes, since +// they don't contain any pointers. -class vrange_storage +class GTY(()) vrange_storage { public: - vrange_storage (vrange_allocator *alloc) : m_alloc (alloc) { } - void *alloc_slot (const vrange &r); - void free (void *slot) { m_alloc->free (slot); } - void get_vrange (const void *slot, vrange &r, tree type); - void set_vrange (void *slot, const vrange &r); - static bool fits_p (const void *slot, const vrange &r); -private: - DISABLE_COPY_AND_ASSIGN (vrange_storage); - vrange_allocator *m_alloc; + static vrange_storage *alloc (vrange_internal_alloc &, const vrange &); + void get_vrange (vrange &r, tree type) const; + void set_vrange (const vrange &r); + bool fits_p (const vrange &r) const; + bool equal_p (const vrange &r, tree type) const; +protected: + // Stack initialization disallowed. + vrange_storage () { } }; -// A chunk of memory pointing to an irange storage. +// Efficient memory storage for an irange. -class GTY ((variable_size)) irange_storage_slot +class irange_storage : public vrange_storage { public: - static irange_storage_slot *alloc_slot (vrange_allocator &, const irange &r); + static irange_storage *alloc (vrange_internal_alloc &, const irange &); void set_irange (const irange &r); void get_irange (irange &r, tree type) const; - wide_int get_nonzero_bits () const { return m_ints[0]; } + bool equal_p (const irange &r, tree type) const; bool fits_p (const irange &r) const; - static size_t size (const irange &r); void dump () const; private: - DISABLE_COPY_AND_ASSIGN (irange_storage_slot); - friend void gt_ggc_mx_irange_storage_slot (void *); - friend void gt_pch_p_19irange_storage_slot (void *, void *, + DISABLE_COPY_AND_ASSIGN (irange_storage); + static size_t size (const irange &r); + const unsigned char *lengths_address () const; + unsigned char *write_lengths_address (); + friend void gt_ggc_mx_irange_storage (void *); + friend void gt_pch_p_14irange_storage (void *, void *, gt_pointer_operator, void *); - friend void gt_pch_nx_irange_storage_slot (void *); + friend void gt_pch_nx_irange_storage (void *); + + // The shared precision of each number. + unsigned short m_precision; - // This is the maximum number of wide_int's allowed in the trailing - // ints structure, without going over 16 bytes (128 bits) in the - // control word that precedes the HOST_WIDE_INTs in - // trailing_wide_ints::m_val[]. - static const unsigned MAX_INTS = 12; + // The max number of sub-ranges that fit in this storage. + const unsigned char m_max_ranges; - // Maximum number of range pairs we can handle, considering the - // nonzero bits take one wide_int. - static const unsigned MAX_PAIRS = (MAX_INTS - 1) / 2; + // The number of stored sub-ranges. + unsigned char m_num_ranges; - // Constructor is private to disallow stack initialization. Use - // alloc_slot() to create objects. - irange_storage_slot (const irange &r); + enum value_range_kind m_kind : 3; - static unsigned num_wide_ints_needed (const irange &r); + // The length of this is m_num_ranges * 2 + 1 to accomodate the nonzero bits. + HOST_WIDE_INT m_val[1]; - trailing_wide_ints<MAX_INTS> m_ints; + // Another variable-length part of the structure following the HWIs. + // This is the length of each wide_int in m_val. + // + // unsigned char m_len[]; + + irange_storage (const irange &r); }; -// A chunk of memory to store an frange to long term memory. +// Efficient memory storage for an frange. -class GTY (()) frange_storage_slot +class frange_storage : public vrange_storage { public: - static frange_storage_slot *alloc_slot (vrange_allocator &, const frange &r); + static frange_storage *alloc (vrange_internal_alloc &, const frange &r); void set_frange (const frange &r); void get_frange (frange &r, tree type) const; + bool equal_p (const frange &r, tree type) const; bool fits_p (const frange &) const; private: - frange_storage_slot (const frange &r) { set_frange (r); } - DISABLE_COPY_AND_ASSIGN (frange_storage_slot); + frange_storage (const frange &r) { set_frange (r); } + DISABLE_COPY_AND_ASSIGN (frange_storage); enum value_range_kind m_kind; REAL_VALUE_TYPE m_min; @@ -120,113 +124,7 @@ class GTY (()) frange_storage_slot bool m_neg_nan; }; -class obstack_vrange_allocator final: public vrange_allocator -{ -public: - obstack_vrange_allocator () - { - obstack_init (&m_obstack); - } - virtual ~obstack_vrange_allocator () final override - { - obstack_free (&m_obstack, NULL); - } - virtual void *alloc (unsigned bytes) final override - { - return obstack_alloc (&m_obstack, bytes); - } - virtual void free (void *) final override { } -private: - obstack m_obstack; -}; - -class ggc_vrange_allocator final: public vrange_allocator -{ -public: - ggc_vrange_allocator () { } - virtual ~ggc_vrange_allocator () final override { } - virtual void *alloc (unsigned bytes) final override - { - return ggc_internal_alloc (bytes); - } - virtual void free (void *p) final override - { - return ggc_free (p); - } -}; - -// Return a new range to hold ranges of TYPE. The newly allocated -// range is initialized to VR_UNDEFINED. - -inline vrange * -vrange_allocator::alloc_vrange (tree type) -{ - if (irange::supports_p (type)) - return alloc_irange (2); - if (frange::supports_p (type)) - return alloc_frange (); - return NULL; - gcc_unreachable (); -} - -// Return a new range with NUM_PAIRS. - -inline irange * -vrange_allocator::alloc_irange (unsigned num_pairs) -{ - // Never allocate 0 pairs. - if (num_pairs < 1) - num_pairs = 2; - - size_t nbytes = sizeof (tree) * 2 * num_pairs; - - // Allocate the irange and required memory for the vector. - void *r = alloc (sizeof (irange)); - tree *mem = static_cast <tree *> (alloc (nbytes)); - return new (r) irange (mem, num_pairs); -} - -inline frange * -vrange_allocator::alloc_frange () -{ - void *r = alloc (sizeof (frange)); - return new (r) frange (); -} - -// Return a clone of an irange. - -template <> -inline irange * -vrange_allocator::clone <irange> (const irange &src) -{ - irange *r = alloc_irange (src.num_pairs ()); - *r = src; - return r; -} - -// Return a clone of an frange. - -template <> -inline frange * -vrange_allocator::clone <frange> (const frange &src) -{ - frange *r = alloc_frange (); - *r = src; - return r; -} - -// Return a clone of a vrange. - -template <> -inline vrange * -vrange_allocator::clone <vrange> (const vrange &src) -{ - if (is_a <irange> (src)) - return clone <irange> (as_a <irange> (src)); - if (is_a <frange> (src)) - return clone <frange> (as_a <frange> (src)); - return NULL; - gcc_unreachable (); -} +extern vrange_storage *ggc_alloc_vrange_storage (tree type); +extern vrange_storage *ggc_alloc_vrange_storage (const vrange &); #endif // GCC_VALUE_RANGE_STORAGE_H |