Commit 3a938d75 by Richard Biener Committed by Richard Biener

vec.c (vec_prefix::calculate_allocation): Move as inline variant to vec.h.

2014-02-12  Richard Biener  <rguenther@suse.de>

	* vec.c (vec_prefix::calculate_allocation): Move as
	inline variant to vec.h.
	(vec_prefix::calculate_allocation_1): New out-of-line version.
	* vec.h (vec_prefix::calculate_allocation_1): Declare.
	(vec_prefix::m_has_auto_buf): Rename to ...
	(vec_prefix::m_using_auto_storage): ... this.
	(vec_prefix::calculate_allocation): Inline the easy cases
	and dispatch to calculate_allocation_1 which doesn't need the
	prefix address.
	(va_heap::reserve): Use gcc_checking_assert.
	(vec<T, A, vl_embed>::embedded_init): Add argument to initialize
	m_using_auto_storage.
	(auto_vec): Change m_vecpfx member to a vec<T, va_heap, vl_embed>
	member and adjust.
	(vec<T, va_heap, vl_ptr>::reserve): Remove redundant check.
	(vec<T, va_heap, vl_ptr>::release): Avoid casting.
	(vec<T, va_heap, vl_ptr>::using_auto_storage): Simplify.

From-SVN: r207729
parent ad0188be
2014-02-12 Richard Biener <rguenther@suse.de> 2014-02-12 Richard Biener <rguenther@suse.de>
* vec.c (vec_prefix::calculate_allocation): Move as
inline variant to vec.h.
(vec_prefix::calculate_allocation_1): New out-of-line version.
* vec.h (vec_prefix::calculate_allocation_1): Declare.
(vec_prefix::m_has_auto_buf): Rename to ...
(vec_prefix::m_using_auto_storage): ... this.
(vec_prefix::calculate_allocation): Inline the easy cases
and dispatch to calculate_allocation_1 which doesn't need the
prefix address.
(va_heap::reserve): Use gcc_checking_assert.
(vec<T, A, vl_embed>::embedded_init): Add argument to initialize
m_using_auto_storage.
(auto_vec): Change m_vecpfx member to a vec<T, va_heap, vl_embed>
member and adjust.
(vec<T, va_heap, vl_ptr>::reserve): Remove redundant check.
(vec<T, va_heap, vl_ptr>::release): Avoid casting.
(vec<T, va_heap, vl_ptr>::using_auto_storage): Simplify.
2014-02-12 Richard Biener <rguenther@suse.de>
* gcse.c (compute_transp): break from loop over canon_modify_mem_list * gcse.c (compute_transp): break from loop over canon_modify_mem_list
when we found a dependence. when we found a dependence.
......
...@@ -171,46 +171,27 @@ vec_prefix::release_overhead (void) ...@@ -171,46 +171,27 @@ vec_prefix::release_overhead (void)
/* Calculate the number of slots to reserve a vector, making sure that /* Calculate the number of slots to reserve a vector, making sure that
RESERVE slots are free. If EXACT grow exactly, otherwise grow it is of at least DESIRED size by growing ALLOC exponentially. */
exponentially. PFX is the control data for the vector. */
unsigned unsigned
vec_prefix::calculate_allocation (vec_prefix *pfx, unsigned reserve, vec_prefix::calculate_allocation_1 (unsigned alloc, unsigned desired)
bool exact)
{ {
unsigned alloc = 0;
unsigned num = 0;
if (pfx)
{
alloc = pfx->m_alloc;
num = pfx->m_num;
}
else if (!reserve)
gcc_unreachable ();
/* We must have run out of room. */ /* We must have run out of room. */
gcc_assert (alloc - num < reserve); gcc_assert (alloc < desired);
if (exact) /* Exponential growth. */
/* Exact size. */ if (!alloc)
alloc = num + reserve; alloc = 4;
else if (alloc < 16)
/* Double when small. */
alloc = alloc * 2;
else else
{ /* Grow slower when large. */
/* Exponential growth. */ alloc = (alloc * 3 / 2);
if (!alloc)
alloc = 4; /* If this is still too small, set it to the right size. */
else if (alloc < 16) if (alloc < desired)
/* Double when small. */ alloc = desired;
alloc = alloc * 2;
else
/* Grow slower when large. */
alloc = (alloc * 3 / 2);
/* If this is still too small, set it to the right size. */
if (alloc < num + reserve)
alloc = num + reserve;
}
return alloc; return alloc;
} }
......
...@@ -218,6 +218,7 @@ struct vec_prefix ...@@ -218,6 +218,7 @@ struct vec_prefix
void register_overhead (size_t, const char *, int, const char *); void register_overhead (size_t, const char *, int, const char *);
void release_overhead (void); void release_overhead (void);
static unsigned calculate_allocation (vec_prefix *, unsigned, bool); static unsigned calculate_allocation (vec_prefix *, unsigned, bool);
static unsigned calculate_allocation_1 (unsigned, unsigned);
/* Note that vec_prefix should be a base class for vec, but we use /* Note that vec_prefix should be a base class for vec, but we use
offsetof() on vector fields of tree structures (e.g., offsetof() on vector fields of tree structures (e.g.,
...@@ -233,10 +234,25 @@ struct vec_prefix ...@@ -233,10 +234,25 @@ struct vec_prefix
friend struct va_heap; friend struct va_heap;
unsigned m_alloc : 31; unsigned m_alloc : 31;
unsigned m_has_auto_buf : 1; unsigned m_using_auto_storage : 1;
unsigned m_num; unsigned m_num;
}; };
/* Calculate the number of slots to reserve a vector, making sure that
RESERVE slots are free. If EXACT grow exactly, otherwise grow
exponentially. PFX is the control data for the vector. */
inline unsigned
vec_prefix::calculate_allocation (vec_prefix *pfx, unsigned reserve,
bool exact)
{
if (exact)
return (pfx ? pfx->m_num : 0) + reserve;
else if (!pfx)
return MAX (4, reserve);
return calculate_allocation_1 (pfx->m_alloc, pfx->m_num + reserve);
}
template<typename, typename, typename> struct vec; template<typename, typename, typename> struct vec;
/* Valid vector layouts /* Valid vector layouts
...@@ -283,7 +299,7 @@ va_heap::reserve (vec<T, va_heap, vl_embed> *&v, unsigned reserve, bool exact ...@@ -283,7 +299,7 @@ va_heap::reserve (vec<T, va_heap, vl_embed> *&v, unsigned reserve, bool exact
{ {
unsigned alloc unsigned alloc
= vec_prefix::calculate_allocation (v ? &v->m_vecpfx : 0, reserve, exact); = vec_prefix::calculate_allocation (v ? &v->m_vecpfx : 0, reserve, exact);
gcc_assert (alloc); gcc_checking_assert (alloc);
if (GATHER_STATISTICS && v) if (GATHER_STATISTICS && v)
v->m_vecpfx.release_overhead (); v->m_vecpfx.release_overhead ();
...@@ -479,7 +495,7 @@ public: ...@@ -479,7 +495,7 @@ public:
T *bsearch (const void *key, int (*compar)(const void *, const void *)); T *bsearch (const void *key, int (*compar)(const void *, const void *));
unsigned lower_bound (T, bool (*)(const T &, const T &)) const; unsigned lower_bound (T, bool (*)(const T &, const T &)) const;
static size_t embedded_size (unsigned); static size_t embedded_size (unsigned);
void embedded_init (unsigned, unsigned = 0); void embedded_init (unsigned, unsigned = 0, unsigned = 0);
void quick_grow (unsigned len); void quick_grow (unsigned len);
void quick_grow_cleared (unsigned len); void quick_grow_cleared (unsigned len);
...@@ -1037,10 +1053,10 @@ vec<T, A, vl_embed>::embedded_size (unsigned alloc) ...@@ -1037,10 +1053,10 @@ vec<T, A, vl_embed>::embedded_size (unsigned alloc)
template<typename T, typename A> template<typename T, typename A>
inline void inline void
vec<T, A, vl_embed>::embedded_init (unsigned alloc, unsigned num) vec<T, A, vl_embed>::embedded_init (unsigned alloc, unsigned num, unsigned aut)
{ {
m_vecpfx.m_alloc = alloc; m_vecpfx.m_alloc = alloc;
m_vecpfx.m_has_auto_buf = 0; m_vecpfx.m_using_auto_storage = aut;
m_vecpfx.m_num = num; m_vecpfx.m_num = num;
} }
...@@ -1234,10 +1250,8 @@ class auto_vec : public vec<T, va_heap> ...@@ -1234,10 +1250,8 @@ class auto_vec : public vec<T, va_heap>
public: public:
auto_vec () auto_vec ()
{ {
m_header.m_alloc = N; m_auto.embedded_init (MAX (N, 2), 0, 1);
m_header.m_has_auto_buf = 1; this->m_vec = &m_auto;
m_header.m_num = 0;
this->m_vec = reinterpret_cast<vec<T, va_heap, vl_embed> *> (&m_header);
} }
~auto_vec () ~auto_vec ()
...@@ -1246,10 +1260,8 @@ public: ...@@ -1246,10 +1260,8 @@ public:
} }
private: private:
friend class vec<T, va_heap, vl_ptr>; vec<T, va_heap, vl_embed> m_auto;
T m_data[MAX (N - 1, 1)];
vec_prefix m_header;
T m_data[N];
}; };
/* auto_vec is a sub class of vec whose storage is released when it is /* auto_vec is a sub class of vec whose storage is released when it is
...@@ -1396,7 +1408,7 @@ template<typename T> ...@@ -1396,7 +1408,7 @@ template<typename T>
inline bool inline bool
vec<T, va_heap, vl_ptr>::reserve (unsigned nelems, bool exact MEM_STAT_DECL) vec<T, va_heap, vl_ptr>::reserve (unsigned nelems, bool exact MEM_STAT_DECL)
{ {
if (!nelems || space (nelems)) if (space (nelems))
return false; return false;
/* For now play a game with va_heap::reserve to hide our auto storage if any, /* For now play a game with va_heap::reserve to hide our auto storage if any,
...@@ -1462,7 +1474,7 @@ vec<T, va_heap, vl_ptr>::release (void) ...@@ -1462,7 +1474,7 @@ vec<T, va_heap, vl_ptr>::release (void)
if (using_auto_storage ()) if (using_auto_storage ())
{ {
static_cast<auto_vec<T, 1> *> (this)->m_header.m_num = 0; m_vec->m_vecpfx.m_num = 0;
return; return;
} }
...@@ -1705,12 +1717,7 @@ template<typename T> ...@@ -1705,12 +1717,7 @@ template<typename T>
inline bool inline bool
vec<T, va_heap, vl_ptr>::using_auto_storage () const vec<T, va_heap, vl_ptr>::using_auto_storage () const
{ {
if (!m_vec->m_vecpfx.m_has_auto_buf) return m_vec->m_vecpfx.m_using_auto_storage;
return false;
const vec_prefix *auto_header
= &static_cast<const auto_vec<T, 1> *> (this)->m_header;
return reinterpret_cast<vec_prefix *> (m_vec) == auto_header;
} }
#if (GCC_VERSION >= 3000) #if (GCC_VERSION >= 3000)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment