Move range allocator code to value-range-storage.*
Now that vrange_storage is in its own file, I think it's prudent to move all the vrange allocator code there since it's all related. The users of value-range.h do not need to know the implementation details of the storage facilities. Tested and benchmarked on x86-64 Linux. gcc/ChangeLog: * gimple-range-cache.cc: Include value-range-storage.h. * gimple-range-cache.h (class block_range_cache): Add "class" to m_range_allocator. * gimple-range-edge.cc (gimple_outgoing_range::gimple_outgoing_range): Allocate allocator. (gimple_outgoing_range::~gimple_outgoing_range): Free allocator. (gimple_outgoing_range::calc_switch_ranges): Dereference allocator. * gimple-range-edge.h: Add "class" to m_range_allocator. * gimple-range-infer.cc (infer_range_manager::infer_range_manager): Allocate allocator. (infer_range_manager::~infer_range_manager): Free allocator. (infer_range_manager::get_nonzero): Dereference allocator. (infer_range_manager::add_range): Same. * gimple-range-infer.h (class vrange_allocator): Add "class" to m_range_allocator. * value-range-storage.h (class vrange_allocator): Move from value-range.h. (class obstack_vrange_allocator): Same. (class ggc_vrange_allocator): Same. (vrange_allocator::alloc_vrange): Same. (vrange_allocator::alloc_irange): Same. * value-range.h (class vrange_allocator): Move to value-range-storage.h. (class obstack_vrange_allocator): Same. (class ggc_vrange_allocator): Same.
This commit is contained in:
parent
17f2e2b77b
commit
3ae9def085
@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "ssa.h"
|
||||
#include "gimple-pretty-print.h"
|
||||
#include "gimple-range.h"
|
||||
#include "value-range-storage.h"
|
||||
#include "tree-cfg.h"
|
||||
#include "target.h"
|
||||
#include "attribs.h"
|
||||
|
@ -44,7 +44,7 @@ private:
|
||||
vec<class ssa_block_ranges *> m_ssa_ranges;
|
||||
ssa_block_ranges &get_block_ranges (tree name);
|
||||
ssa_block_ranges *query_block_ranges (tree name);
|
||||
vrange_allocator *m_range_allocator;
|
||||
class vrange_allocator *m_range_allocator;
|
||||
bitmap_obstack m_bitmaps;
|
||||
};
|
||||
|
||||
|
@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "gimple-iterator.h"
|
||||
#include "tree-cfg.h"
|
||||
#include "gimple-range.h"
|
||||
#include "value-range-storage.h"
|
||||
|
||||
// If there is a range control statment at the end of block BB, return it.
|
||||
// Otherwise return NULL.
|
||||
@ -68,6 +69,7 @@ gimple_outgoing_range::gimple_outgoing_range (int max_sw_edges)
|
||||
{
|
||||
m_edge_table = NULL;
|
||||
m_max_edges = max_sw_edges;
|
||||
m_range_allocator = new obstack_vrange_allocator;
|
||||
}
|
||||
|
||||
|
||||
@ -75,6 +77,7 @@ gimple_outgoing_range::~gimple_outgoing_range ()
|
||||
{
|
||||
if (m_edge_table)
|
||||
delete m_edge_table;
|
||||
delete m_range_allocator;
|
||||
}
|
||||
|
||||
|
||||
@ -162,13 +165,13 @@ gimple_outgoing_range::calc_switch_ranges (gswitch *sw)
|
||||
// If there was an existing range and it doesn't fit, we lose the memory.
|
||||
// It'll get reclaimed when the obstack is freed. This seems less
|
||||
// intrusive than allocating max ranges for each case.
|
||||
slot = m_range_allocator.clone <irange> (case_range);
|
||||
slot = m_range_allocator->clone <irange> (case_range);
|
||||
}
|
||||
|
||||
irange *&slot = m_edge_table->get_or_insert (default_edge, &existed);
|
||||
// This should be the first call into this switch.
|
||||
gcc_checking_assert (!existed);
|
||||
irange *dr = m_range_allocator.clone <irange> (default_range);
|
||||
irange *dr = m_range_allocator->clone <irange> (default_range);
|
||||
slot = dr;
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ private:
|
||||
|
||||
int m_max_edges;
|
||||
hash_map<edge, irange *> *m_edge_table;
|
||||
obstack_vrange_allocator m_range_allocator;
|
||||
class obstack_vrange_allocator *m_range_allocator;
|
||||
};
|
||||
|
||||
// If there is a range control statement at the end of block BB, return it.
|
||||
|
@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "ssa.h"
|
||||
#include "gimple-pretty-print.h"
|
||||
#include "gimple-range.h"
|
||||
#include "value-range-storage.h"
|
||||
#include "tree-cfg.h"
|
||||
#include "target.h"
|
||||
#include "attribs.h"
|
||||
@ -166,6 +167,7 @@ infer_range_manager::infer_range_manager (bool do_search)
|
||||
// Non-zero elements are very common, so cache them for each ssa-name.
|
||||
m_nonzero.create (0);
|
||||
m_nonzero.safe_grow_cleared (num_ssa_names + 1);
|
||||
m_range_allocator = new obstack_vrange_allocator;
|
||||
}
|
||||
|
||||
// Destruct a range infer manager.
|
||||
@ -176,6 +178,7 @@ infer_range_manager::~infer_range_manager ()
|
||||
obstack_free (&m_list_obstack, NULL);
|
||||
m_on_exit.release ();
|
||||
bitmap_obstack_release (&m_bitmaps);
|
||||
delete m_range_allocator;
|
||||
}
|
||||
|
||||
// Return a non-zero range value of the appropriate type for NAME from
|
||||
@ -189,7 +192,7 @@ infer_range_manager::get_nonzero (tree name)
|
||||
m_nonzero.safe_grow_cleared (num_ssa_names + 20);
|
||||
if (!m_nonzero[v])
|
||||
{
|
||||
m_nonzero[v] = m_range_allocator.alloc_vrange (TREE_TYPE (name));
|
||||
m_nonzero[v] = m_range_allocator->alloc_vrange (TREE_TYPE (name));
|
||||
m_nonzero[v]->set_nonzero (TREE_TYPE (name));
|
||||
}
|
||||
return *(m_nonzero[v]);
|
||||
@ -261,7 +264,7 @@ infer_range_manager::add_range (tree name, basic_block bb, const vrange &r)
|
||||
else
|
||||
{
|
||||
vrange &v = cur;
|
||||
ptr->range = m_range_allocator.clone (v);
|
||||
ptr->range = m_range_allocator->clone (v);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -269,7 +272,7 @@ infer_range_manager::add_range (tree name, basic_block bb, const vrange &r)
|
||||
// Otherwise create a record.
|
||||
bitmap_set_bit (m_on_exit[bb->index].m_names, SSA_NAME_VERSION (name));
|
||||
ptr = (exit_range *)obstack_alloc (&m_list_obstack, sizeof (exit_range));
|
||||
ptr->range = m_range_allocator.clone (r);
|
||||
ptr->range = m_range_allocator->clone (r);
|
||||
ptr->name = name;
|
||||
ptr->next = m_on_exit[bb->index].head;
|
||||
m_on_exit[bb->index].head = ptr;
|
||||
|
@ -78,7 +78,7 @@ private:
|
||||
bitmap m_seen;
|
||||
bitmap_obstack m_bitmaps;
|
||||
struct obstack m_list_obstack;
|
||||
obstack_vrange_allocator m_range_allocator;
|
||||
class obstack_vrange_allocator *m_range_allocator;
|
||||
};
|
||||
|
||||
#endif // GCC_GIMPLE_RANGE_SIDE_H
|
||||
|
@ -21,6 +21,27 @@ 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.
|
||||
|
||||
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);
|
||||
private:
|
||||
irange *alloc_irange (unsigned pairs);
|
||||
void operator= (const vrange_allocator &) = delete;
|
||||
};
|
||||
|
||||
// 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
|
||||
@ -40,10 +61,6 @@ private:
|
||||
vrange_allocator *m_alloc;
|
||||
};
|
||||
|
||||
|
||||
// INTERNAL USE ONLY. The remaining interfaces are only exposed for
|
||||
// the GTY machinery to play nice with tree_ssa_name.
|
||||
|
||||
// A chunk of memory pointing to an irange storage.
|
||||
|
||||
class GTY ((variable_size)) irange_storage_slot
|
||||
@ -82,4 +99,92 @@ private:
|
||||
trailing_wide_ints<MAX_INTS> m_ints;
|
||||
};
|
||||
|
||||
class obstack_vrange_allocator : 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 : 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);
|
||||
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
// Return a new range with NUM_PAIRS.
|
||||
|
||||
inline irange *
|
||||
vrange_allocator::alloc_irange (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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// 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 a vrange.
|
||||
|
||||
template <>
|
||||
inline vrange *
|
||||
vrange_allocator::clone <vrange> (const vrange &src)
|
||||
{
|
||||
if (is_a <irange> (src))
|
||||
return clone <irange> (as_a <irange> (src));
|
||||
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
#endif // GCC_VALUE_RANGE_STORAGE_H
|
||||
|
@ -896,113 +896,4 @@ vrp_val_min (const_tree type)
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
// This is the range storage class. It is used to allocate the
|
||||
// minimum amount of storage needed for a given range. Storage is
|
||||
// automatically freed at destruction of the class.
|
||||
|
||||
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);
|
||||
private:
|
||||
irange *alloc_irange (unsigned pairs);
|
||||
void operator= (const vrange_allocator &) = delete;
|
||||
};
|
||||
|
||||
class obstack_vrange_allocator : 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 : 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);
|
||||
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
// Return a new range with NUM_PAIRS.
|
||||
|
||||
inline irange *
|
||||
vrange_allocator::alloc_irange (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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// 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 a vrange.
|
||||
|
||||
template <>
|
||||
inline vrange *
|
||||
vrange_allocator::clone <vrange> (const vrange &src)
|
||||
{
|
||||
if (is_a <irange> (src))
|
||||
return clone <irange> (as_a <irange> (src));
|
||||
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
#endif // GCC_VALUE_RANGE_H
|
||||
|
Loading…
Reference in New Issue
Block a user