vec.h (VEC_reserve_exact): Define.

./:	* vec.h (VEC_reserve_exact): Define.
	(vec_gc_p_reserve_exact): Declare.
	(vec_gc_o_reserve_exact): Declare.
	(vec_heap_p_reserve_exact): Declare.
	(vec_heap_o_reserve_exact): Declare.
	(VEC_OP (T,A,reserve_exact)): New static inline function, three
	versions.
	(VEC_OP (T,A,reserve)) [all versions]: Remove handling of
	negative parameter.
	(VEC_OP (T,A,alloc)) [all versions]: Call ...reserve_exact.
	(VEC_OP (T,A,copy)) [all versions]: Likewise.
	(VEC_OP (T,a,safe_grow)) [all versions]: Likewise.
	* vec.c (calculate_allocation): Add exact parameter.  Change all
	callers.
	(vec_gc_o_reserve_1): New static function, from vec_gc_o_reserve.
	(vec_gc_p_reserve, vec_gc_o_reserve): Call vec_gc_o_reserve_1.
	(vec_gc_p_reserve_exact, vec_gc_o_reserve_exact): New functions.
	(vec_heap_o_reserve_1): New static function, from vec_heap_o_reserve.
	(vec_heap_p_reserve, vec_heap_o_reserve): Call vec_heap_o_reserve_1.
	(vec_heap_p_reserve_exact): New function.
	(vec_heap_o_reserve_exact): New function.
cp/:
	* class.c (add_method): Call VEC_reserve_exact rather than passing
	a negative size to VEC_reserve.

From-SVN: r120861
This commit is contained in:
Ian Lance Taylor 2007-01-17 17:42:10 +00:00 committed by Ian Lance Taylor
parent 9dd8004e91
commit efb7e1e026
5 changed files with 237 additions and 76 deletions

View File

@ -1,3 +1,27 @@
2007-01-17 Ian Lance Taylor <iant@google.com>
* vec.h (VEC_reserve_exact): Define.
(vec_gc_p_reserve_exact): Declare.
(vec_gc_o_reserve_exact): Declare.
(vec_heap_p_reserve_exact): Declare.
(vec_heap_o_reserve_exact): Declare.
(VEC_OP (T,A,reserve_exact)): New static inline function, three
versions.
(VEC_OP (T,A,reserve)) [all versions]: Remove handling of
negative parameter.
(VEC_OP (T,A,alloc)) [all versions]: Call ...reserve_exact.
(VEC_OP (T,A,copy)) [all versions]: Likewise.
(VEC_OP (T,a,safe_grow)) [all versions]: Likewise.
* vec.c (calculate_allocation): Add exact parameter. Change all
callers.
(vec_gc_o_reserve_1): New static function, from vec_gc_o_reserve.
(vec_gc_p_reserve, vec_gc_o_reserve): Call vec_gc_o_reserve_1.
(vec_gc_p_reserve_exact, vec_gc_o_reserve_exact): New functions.
(vec_heap_o_reserve_1): New static function, from vec_heap_o_reserve.
(vec_heap_p_reserve, vec_heap_o_reserve): Call vec_heap_o_reserve_1.
(vec_heap_p_reserve_exact): New function.
(vec_heap_o_reserve_exact): New function.
2007-01-17 Jan Hubicka <jh@suse.cz>
* ipa-type-escape.c (look_for_casts): Revamp using handled_component_p.

View File

@ -1,3 +1,8 @@
2007-01-17 Ian Lance Taylor <iant@google.com>
* class.c (add_method): Call VEC_reserve_exact rather than passing
a negative size to VEC_reserve.
2007-01-11 Simon Martin <simartin@users.sourceforge.net>
PR c++/29573

View File

@ -1071,9 +1071,15 @@ add_method (tree type, tree method, tree using_decl)
if (insert_p)
{
bool reallocated;
/* We only expect to add few methods in the COMPLETE_P case, so
just make room for one more method in that case. */
if (VEC_reserve (tree, gc, method_vec, complete_p ? -1 : 1))
if (complete_p)
reallocated = VEC_reserve_exact (tree, gc, method_vec, 1);
else
reallocated = VEC_reserve (tree, gc, method_vec, 1);
if (reallocated)
CLASSTYPE_METHOD_VEC (type) = method_vec;
if (slot == VEC_length (tree, method_vec))
VEC_quick_push (tree, method_vec, overload);

143
gcc/vec.c
View File

@ -40,16 +40,17 @@ struct vec_prefix
void *vec[1];
};
/* Calculate the new ALLOC value, making sure that abs(RESERVE) slots
are free. If RESERVE < 0 grow exactly, otherwise grow
exponentially. */
/* Calculate the new ALLOC value, making sure that RESERVE slots are
free. If EXACT grow exactly, otherwise grow exponentially. */
static inline unsigned
calculate_allocation (const struct vec_prefix *pfx, int reserve)
calculate_allocation (const struct vec_prefix *pfx, int reserve, bool exact)
{
unsigned alloc = 0;
unsigned num = 0;
gcc_assert (reserve >= 0);
if (pfx)
{
alloc = pfx->alloc;
@ -61,11 +62,11 @@ calculate_allocation (const struct vec_prefix *pfx, int reserve)
return 0;
/* We must have run out of room. */
gcc_assert (alloc - num < (unsigned)(reserve < 0 ? -reserve : reserve));
gcc_assert (alloc - num < (unsigned) reserve);
if (reserve < 0)
if (exact)
/* Exact size. */
alloc = num + -reserve;
alloc = num + reserve;
else
{
/* Exponential growth. */
@ -85,28 +86,18 @@ calculate_allocation (const struct vec_prefix *pfx, int reserve)
return alloc;
}
/* Ensure there are at least abs(RESERVE) free slots in VEC. If
RESERVE < 0 grow exactly, else grow exponentially. As a special
case, if VEC is NULL, and RESERVE is 0, no vector will be created. */
/* Ensure there are at least RESERVE free slots in VEC. If EXACT grow
exactly, else grow exponentially. As a special case, if VEC is
NULL and RESERVE is 0, no vector will be created. The vector's
trailing array is at VEC_OFFSET offset and consists of ELT_SIZE
sized elements. */
void *
vec_gc_p_reserve (void *vec, int reserve MEM_STAT_DECL)
{
return vec_gc_o_reserve (vec, reserve,
offsetof (struct vec_prefix, vec), sizeof (void *)
PASS_MEM_STAT);
}
/* As vec_gc_p_reserve, but for object vectors. The vector's trailing
array is at VEC_OFFSET offset and consists of ELT_SIZE sized
elements. */
void *
vec_gc_o_reserve (void *vec, int reserve, size_t vec_offset, size_t elt_size
MEM_STAT_DECL)
static void *
vec_gc_o_reserve_1 (void *vec, int reserve, size_t vec_offset, size_t elt_size,
bool exact MEM_STAT_DECL)
{
struct vec_prefix *pfx = vec;
unsigned alloc = alloc = calculate_allocation (pfx, reserve);
unsigned alloc = alloc = calculate_allocation (pfx, reserve, exact);
if (!alloc)
return NULL;
@ -119,24 +110,66 @@ vec_gc_o_reserve (void *vec, int reserve, size_t vec_offset, size_t elt_size
return vec;
}
/* As for vec_gc_p_reserve, but for heap allocated vectors. */
/* Ensure there are at least RESERVE free slots in VEC, growing
exponentially. If RESERVE < 0 grow exactly, else grow
exponentially. As a special case, if VEC is NULL, and RESERVE is
0, no vector will be created. */
void *
vec_heap_p_reserve (void *vec, int reserve MEM_STAT_DECL)
vec_gc_p_reserve (void *vec, int reserve MEM_STAT_DECL)
{
return vec_heap_o_reserve (vec, reserve,
offsetof (struct vec_prefix, vec), sizeof (void *)
return vec_gc_o_reserve_1 (vec, reserve,
offsetof (struct vec_prefix, vec),
sizeof (void *), false
PASS_MEM_STAT);
}
/* As for vec_gc_o_reserve, but for heap allocated vectors. */
/* Ensure there are at least RESERVE free slots in VEC, growing
exactly. If RESERVE < 0 grow exactly, else grow exponentially. As
a special case, if VEC is NULL, and RESERVE is 0, no vector will be
created. */
void *
vec_heap_o_reserve (void *vec, int reserve, size_t vec_offset, size_t elt_size
MEM_STAT_DECL)
vec_gc_p_reserve_exact (void *vec, int reserve MEM_STAT_DECL)
{
return vec_gc_o_reserve_1 (vec, reserve,
offsetof (struct vec_prefix, vec),
sizeof (void *), true
PASS_MEM_STAT);
}
/* As for vec_gc_p_reserve, but for object vectors. The vector's
trailing array is at VEC_OFFSET offset and consists of ELT_SIZE
sized elements. */
void *
vec_gc_o_reserve (void *vec, int reserve, size_t vec_offset, size_t elt_size
MEM_STAT_DECL)
{
return vec_gc_o_reserve_1 (vec, reserve, vec_offset, elt_size, false
PASS_MEM_STAT);
}
/* As for vec_gc_p_reserve_exact, but for object vectors. The
vector's trailing array is at VEC_OFFSET offset and consists of
ELT_SIZE sized elements. */
void *
vec_gc_o_reserve_exact (void *vec, int reserve, size_t vec_offset,
size_t elt_size MEM_STAT_DECL)
{
return vec_gc_o_reserve_1 (vec, reserve, vec_offset, elt_size, true
PASS_MEM_STAT);
}
/* As for vec_gc_o_reserve_1, but for heap allocated vectors. */
static void *
vec_heap_o_reserve_1 (void *vec, int reserve, size_t vec_offset,
size_t elt_size, bool exact MEM_STAT_DECL)
{
struct vec_prefix *pfx = vec;
unsigned alloc = calculate_allocation (pfx, reserve);
unsigned alloc = calculate_allocation (pfx, reserve, exact);
if (!alloc)
return NULL;
@ -149,6 +182,48 @@ vec_heap_o_reserve (void *vec, int reserve, size_t vec_offset, size_t elt_size
return vec;
}
/* As for vec_gc_p_reserve, but for heap allocated vectors. */
void *
vec_heap_p_reserve (void *vec, int reserve MEM_STAT_DECL)
{
return vec_heap_o_reserve_1 (vec, reserve,
offsetof (struct vec_prefix, vec),
sizeof (void *), false
PASS_MEM_STAT);
}
/* As for vec_gc_p_reserve_exact, but for heap allocated vectors. */
void *
vec_heap_p_reserve_exact (void *vec, int reserve MEM_STAT_DECL)
{
return vec_heap_o_reserve_1 (vec, reserve,
offsetof (struct vec_prefix, vec),
sizeof (void *), true
PASS_MEM_STAT);
}
/* As for vec_gc_o_reserve, but for heap allocated vectors. */
void *
vec_heap_o_reserve (void *vec, int reserve, size_t vec_offset, size_t elt_size
MEM_STAT_DECL)
{
return vec_heap_o_reserve_1 (vec, reserve, vec_offset, elt_size, false
PASS_MEM_STAT);
}
/* As for vec_gc_o_reserve_exact, but for heap allocated vectors. */
void *
vec_heap_o_reserve_exact (void *vec, int reserve, size_t vec_offset,
size_t elt_size MEM_STAT_DECL)
{
return vec_heap_o_reserve_1 (vec, reserve, vec_offset, elt_size, true
PASS_MEM_STAT);
}
#if ENABLE_CHECKING
/* Issue a vector domain error, and then fall over. */

133
gcc/vec.h
View File

@ -66,8 +66,8 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
least as many elements as you ask for, it will exponentially
increase if there are too few spare slots. If you want reserve a
specific number of slots, but do not want the exponential increase
(for instance, you know this is the last allocation), use a
negative number for reservation. You can also create a vector of a
(for instance, you know this is the last allocation), use the
reserve_exact operation. You can also create a vector of a
specific size from the get go.
You should prefer the push and pop operations, as they append and
@ -238,16 +238,25 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
/* Reserve space.
int VEC_T_A_reserve(VEC(T,A) *&v, int reserve);
Ensure that V has at least abs(RESERVE) slots available. The
signedness of RESERVE determines the reallocation behavior. A
negative value will not create additional headroom beyond that
requested. A positive value will create additional headroom. Note
this can cause V to be reallocated. Returns nonzero iff
reallocation actually occurred. */
Ensure that V has at least RESERVE slots available. This will
create additional headroom. Note this can cause V to be
reallocated. Returns nonzero iff reallocation actually
occurred. */
#define VEC_reserve(T,A,V,R) \
(VEC_OP(T,A,reserve)(&(V),R VEC_CHECK_INFO MEM_STAT_INFO))
/* Reserve space exactly.
int VEC_T_A_reserve_exact(VEC(T,A) *&v, int reserve);
Ensure that V has at least RESERVE slots available. This will not
create additional headroom. Note this can cause V to be
reallocated. Returns nonzero iff reallocation actually
occurred. */
#define VEC_reserve_exact(T,A,V,R) \
(VEC_OP(T,A,reserve_exact)(&(V),R VEC_CHECK_INFO MEM_STAT_INFO))
/* Push object with no reallocation
T *VEC_T_quick_push (VEC(T) *v, T obj); // Integer
T *VEC_T_quick_push (VEC(T) *v, T obj); // Pointer
@ -411,11 +420,17 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#if !IN_GENGTYPE
/* Reallocate an array of elements with prefix. */
extern void *vec_gc_p_reserve (void *, int MEM_STAT_DECL);
extern void *vec_gc_p_reserve_exact (void *, int MEM_STAT_DECL);
extern void *vec_gc_o_reserve (void *, int, size_t, size_t MEM_STAT_DECL);
extern void *vec_gc_o_reserve_exact (void *, int, size_t, size_t
MEM_STAT_DECL);
extern void ggc_free (void *);
#define vec_gc_free(V) ggc_free (V)
extern void *vec_heap_p_reserve (void *, int MEM_STAT_DECL);
extern void *vec_heap_p_reserve_exact (void *, int MEM_STAT_DECL);
extern void *vec_heap_o_reserve (void *, int, size_t, size_t MEM_STAT_DECL);
extern void *vec_heap_o_reserve_exact (void *, int, size_t, size_t
MEM_STAT_DECL);
#define vec_heap_free(V) free (V)
#if ENABLE_CHECKING
@ -702,8 +717,8 @@ static inline unsigned VEC_OP (T,base,lower_bound) \
static inline VEC(T,A) *VEC_OP (T,A,alloc) \
(int alloc_ MEM_STAT_DECL) \
{ \
/* We must request exact size allocation, hence the negation. */ \
return (VEC(T,A) *) vec_##A##_p_reserve (NULL, -alloc_ PASS_MEM_STAT); \
return (VEC(T,A) *) vec_##A##_p_reserve_exact (NULL, alloc_ \
PASS_MEM_STAT); \
} \
\
static inline void VEC_OP (T,A,free) \
@ -721,9 +736,8 @@ static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \
\
if (len_) \
{ \
/* We must request exact size allocation, hence the negation. */ \
new_vec_ = (VEC (T,A) *)(vec_##A##_p_reserve \
(NULL, -len_ PASS_MEM_STAT)); \
new_vec_ = (VEC (T,A) *)(vec_##A##_p_reserve_exact \
(NULL, len_ PASS_MEM_STAT)); \
\
new_vec_->base.num = len_; \
memcpy (new_vec_->base.vec, vec_->vec, sizeof (T) * len_); \
@ -734,8 +748,7 @@ static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \
static inline int VEC_OP (T,A,reserve) \
(VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL) \
{ \
int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), \
alloc_ < 0 ? -alloc_ : alloc_ \
int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_ \
VEC_CHECK_PASS); \
\
if (extend) \
@ -744,14 +757,28 @@ static inline int VEC_OP (T,A,reserve) \
return extend; \
} \
\
static inline int VEC_OP (T,A,reserve_exact) \
(VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL) \
{ \
int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_ \
VEC_CHECK_PASS); \
\
if (extend) \
*vec_ = (VEC(T,A) *) vec_##A##_p_reserve_exact (*vec_, alloc_ \
PASS_MEM_STAT); \
\
return extend; \
} \
\
static inline void VEC_OP (T,A,safe_grow) \
(VEC(T,A) **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL) \
{ \
VEC_ASSERT (size_ >= 0 \
&& VEC_OP(T,base,length) VEC_BASE(*vec_) <= (unsigned)size_, \
"grow", T, A); \
VEC_OP (T,A,reserve) (vec_, (int)(*vec_ ? VEC_BASE(*vec_)->num : 0) - size_ \
VEC_CHECK_PASS PASS_MEM_STAT); \
VEC_OP (T,A,reserve_exact) (vec_, \
size_ - (int)(*vec_ ? VEC_BASE(*vec_)->num : 0) \
VEC_CHECK_PASS PASS_MEM_STAT); \
VEC_BASE (*vec_)->num = size_; \
} \
\
@ -972,11 +999,10 @@ static inline unsigned VEC_OP (T,base,lower_bound) \
static inline VEC(T,A) *VEC_OP (T,A,alloc) \
(int alloc_ MEM_STAT_DECL) \
{ \
/* We must request exact size allocation, hence the negation. */ \
return (VEC(T,A) *) vec_##A##_o_reserve (NULL, -alloc_, \
offsetof (VEC(T,A),base.vec), \
sizeof (T) \
PASS_MEM_STAT); \
return (VEC(T,A) *) vec_##A##_o_reserve_exact (NULL, alloc_, \
offsetof (VEC(T,A),base.vec), \
sizeof (T) \
PASS_MEM_STAT); \
} \
\
static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \
@ -986,9 +1012,8 @@ static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \
\
if (len_) \
{ \
/* We must request exact size allocation, hence the negation. */ \
new_vec_ = (VEC (T,A) *)(vec_##A##_o_reserve \
(NULL, -len_, \
new_vec_ = (VEC (T,A) *)(vec_##A##_o_reserve_exact \
(NULL, len_, \
offsetof (VEC(T,A),base.vec), sizeof (T) \
PASS_MEM_STAT)); \
\
@ -1009,8 +1034,7 @@ static inline void VEC_OP (T,A,free) \
static inline int VEC_OP (T,A,reserve) \
(VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL) \
{ \
int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), \
alloc_ < 0 ? -alloc_ : alloc_ \
int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_ \
VEC_CHECK_PASS); \
\
if (extend) \
@ -1022,14 +1046,30 @@ static inline int VEC_OP (T,A,reserve) \
return extend; \
} \
\
static inline int VEC_OP (T,A,reserve_exact) \
(VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL) \
{ \
int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_ \
VEC_CHECK_PASS); \
\
if (extend) \
*vec_ = (VEC(T,A) *) vec_##A##_o_reserve_exact \
(*vec_, alloc_, \
offsetof (VEC(T,A),base.vec), \
sizeof (T) PASS_MEM_STAT); \
\
return extend; \
} \
\
static inline void VEC_OP (T,A,safe_grow) \
(VEC(T,A) **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL) \
{ \
VEC_ASSERT (size_ >= 0 \
&& VEC_OP(T,base,length) VEC_BASE(*vec_) <= (unsigned)size_, \
"grow", T, A); \
VEC_OP (T,A,reserve) (vec_, (int)(*vec_ ? VEC_BASE(*vec_)->num : 0) - size_ \
VEC_CHECK_PASS PASS_MEM_STAT); \
VEC_OP (T,A,reserve_exact) (vec_, \
size_ - (int)(*vec_ ? VEC_BASE(*vec_)->num : 0) \
VEC_CHECK_PASS PASS_MEM_STAT); \
VEC_BASE (*vec_)->num = size_; \
} \
\
@ -1064,11 +1104,9 @@ static inline T *VEC_OP (T,A,safe_insert) \
static inline VEC(T,A) *VEC_OP (T,A,alloc) \
(int alloc_ MEM_STAT_DECL) \
{ \
/* We must request exact size allocation, hence the negation. */ \
return (VEC(T,A) *) vec_##A##_o_reserve (NULL, -alloc_, \
offsetof (VEC(T,A),base.vec), \
sizeof (T) \
PASS_MEM_STAT); \
return (VEC(T,A) *) vec_##A##_o_reserve_exact \
(NULL, alloc_, offsetof (VEC(T,A),base.vec), \
sizeof (T) PASS_MEM_STAT); \
} \
\
static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \
@ -1078,9 +1116,8 @@ static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \
\
if (len_) \
{ \
/* We must request exact size allocation, hence the negation. */ \
new_vec_ = (VEC (T,A) *)(vec_##A##_o_reserve \
(NULL, -len_, \
new_vec_ = (VEC (T,A) *)(vec_##A##_o_reserve_exact \
(NULL, len_, \
offsetof (VEC(T,A),base.vec), sizeof (T) \
PASS_MEM_STAT)); \
\
@ -1101,8 +1138,7 @@ static inline void VEC_OP (T,A,free) \
static inline int VEC_OP (T,A,reserve) \
(VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL) \
{ \
int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), \
alloc_ < 0 ? -alloc_ : alloc_ \
int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_ \
VEC_CHECK_PASS); \
\
if (extend) \
@ -1114,14 +1150,29 @@ static inline int VEC_OP (T,A,reserve) \
return extend; \
} \
\
static inline int VEC_OP (T,A,reserve_exact) \
(VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL) \
{ \
int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_ \
VEC_CHECK_PASS); \
\
if (extend) \
*vec_ = (VEC(T,A) *) vec_##A##_o_reserve_exact \
(*vec_, alloc_, offsetof (VEC(T,A),base.vec), \
sizeof (T) PASS_MEM_STAT); \
\
return extend; \
} \
\
static inline void VEC_OP (T,A,safe_grow) \
(VEC(T,A) **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL) \
{ \
VEC_ASSERT (size_ >= 0 \
&& VEC_OP(T,base,length) VEC_BASE(*vec_) <= (unsigned)size_, \
"grow", T, A); \
VEC_OP (T,A,reserve) (vec_, (int)(*vec_ ? VEC_BASE(*vec_)->num : 0) - size_ \
VEC_CHECK_PASS PASS_MEM_STAT); \
VEC_OP (T,A,reserve_exact) (vec_, \
size_ - (int)(*vec_ ? VEC_BASE(*vec_)->num : 0) \
VEC_CHECK_PASS PASS_MEM_STAT); \
VEC_BASE (*vec_)->num = size_; \
} \
\