From 3a938d756bad13643f32468815db337d3e5c1821 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 12 Feb 2014 16:01:03 +0000 Subject: [PATCH] vec.c (vec_prefix::calculate_allocation): Move as inline variant to vec.h. 2014-02-12 Richard Biener * 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::embedded_init): Add argument to initialize m_using_auto_storage. (auto_vec): Change m_vecpfx member to a vec member and adjust. (vec::reserve): Remove redundant check. (vec::release): Avoid casting. (vec::using_auto_storage): Simplify. From-SVN: r207729 --- gcc/ChangeLog | 20 ++++++++++++++++++++ gcc/vec.c | 47 ++++++++++++++--------------------------------- gcc/vec.h | 49 ++++++++++++++++++++++++++++--------------------- 3 files changed, 62 insertions(+), 54 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c33da781718..cf015713b3f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,23 @@ +2014-02-12 Richard Biener + + * 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::embedded_init): Add argument to initialize + m_using_auto_storage. + (auto_vec): Change m_vecpfx member to a vec + member and adjust. + (vec::reserve): Remove redundant check. + (vec::release): Avoid casting. + (vec::using_auto_storage): Simplify. + 2014-02-12 Richard Biener * gcse.c (compute_transp): break from loop over canon_modify_mem_list diff --git a/gcc/vec.c b/gcc/vec.c index bd0af2dc4ed..c0cd3386b7a 100644 --- a/gcc/vec.c +++ b/gcc/vec.c @@ -171,46 +171,27 @@ vec_prefix::release_overhead (void) /* 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. */ + it is of at least DESIRED size by growing ALLOC exponentially. */ unsigned -vec_prefix::calculate_allocation (vec_prefix *pfx, unsigned reserve, - bool exact) +vec_prefix::calculate_allocation_1 (unsigned alloc, unsigned desired) { - 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. */ - gcc_assert (alloc - num < reserve); + gcc_assert (alloc < desired); - if (exact) - /* Exact size. */ - alloc = num + reserve; + /* Exponential growth. */ + if (!alloc) + alloc = 4; + else if (alloc < 16) + /* Double when small. */ + alloc = alloc * 2; else - { - /* Exponential growth. */ - if (!alloc) - alloc = 4; - else if (alloc < 16) - /* Double when small. */ - alloc = alloc * 2; - else - /* Grow slower when large. */ - alloc = (alloc * 3 / 2); + /* 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; - } + /* If this is still too small, set it to the right size. */ + if (alloc < desired) + alloc = desired; return alloc; } diff --git a/gcc/vec.h b/gcc/vec.h index cb4ba632869..587302344d5 100644 --- a/gcc/vec.h +++ b/gcc/vec.h @@ -218,6 +218,7 @@ struct vec_prefix void register_overhead (size_t, const char *, int, const char *); void release_overhead (void); 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 offsetof() on vector fields of tree structures (e.g., @@ -233,10 +234,25 @@ struct vec_prefix friend struct va_heap; unsigned m_alloc : 31; - unsigned m_has_auto_buf : 1; + unsigned m_using_auto_storage : 1; 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 struct vec; /* Valid vector layouts @@ -283,7 +299,7 @@ va_heap::reserve (vec *&v, unsigned reserve, bool exact { unsigned alloc = vec_prefix::calculate_allocation (v ? &v->m_vecpfx : 0, reserve, exact); - gcc_assert (alloc); + gcc_checking_assert (alloc); if (GATHER_STATISTICS && v) v->m_vecpfx.release_overhead (); @@ -479,7 +495,7 @@ public: T *bsearch (const void *key, int (*compar)(const void *, const void *)); unsigned lower_bound (T, bool (*)(const T &, const T &)) const; 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_cleared (unsigned len); @@ -1037,10 +1053,10 @@ vec::embedded_size (unsigned alloc) template inline void -vec::embedded_init (unsigned alloc, unsigned num) +vec::embedded_init (unsigned alloc, unsigned num, unsigned aut) { m_vecpfx.m_alloc = alloc; - m_vecpfx.m_has_auto_buf = 0; + m_vecpfx.m_using_auto_storage = aut; m_vecpfx.m_num = num; } @@ -1234,10 +1250,8 @@ class auto_vec : public vec public: auto_vec () { - m_header.m_alloc = N; - m_header.m_has_auto_buf = 1; - m_header.m_num = 0; - this->m_vec = reinterpret_cast *> (&m_header); + m_auto.embedded_init (MAX (N, 2), 0, 1); + this->m_vec = &m_auto; } ~auto_vec () @@ -1246,10 +1260,8 @@ public: } private: - friend class vec; - - vec_prefix m_header; - T m_data[N]; + vec m_auto; + T m_data[MAX (N - 1, 1)]; }; /* auto_vec is a sub class of vec whose storage is released when it is @@ -1396,7 +1408,7 @@ template inline bool vec::reserve (unsigned nelems, bool exact MEM_STAT_DECL) { - if (!nelems || space (nelems)) + if (space (nelems)) return false; /* For now play a game with va_heap::reserve to hide our auto storage if any, @@ -1462,7 +1474,7 @@ vec::release (void) if (using_auto_storage ()) { - static_cast *> (this)->m_header.m_num = 0; + m_vec->m_vecpfx.m_num = 0; return; } @@ -1705,12 +1717,7 @@ template inline bool vec::using_auto_storage () const { - if (!m_vec->m_vecpfx.m_has_auto_buf) - return false; - - const vec_prefix *auto_header - = &static_cast *> (this)->m_header; - return reinterpret_cast (m_vec) == auto_header; + return m_vec->m_vecpfx.m_using_auto_storage; } #if (GCC_VERSION >= 3000)