On Mon, Jan 23, 2006 at 03:46:10PM -0800, Richard Henderson wrote:
> Got it.
Looks good to me. (Argh, I thought I had caught all of the places where
I made that mistake.) Are you going to check it in?
And here's the fix for genautomata, which had two bugs. One was a
simple case of assuming that an array got entirely initialized when
it didn't. The other is actually a latent vec.h bug. DEF_VEC_ALLOC_I
reused the _p out-of-line allocation functions, which assume the element
size == sizeof(void *). For smaller integral types, that just wastes
memory; but if HOST_WIDE_INT is 64 bits, pointers are 32, and you ask
for a VEC of HOST_WIDE_INT, you get half as much memory as you need.
genautomata, of course, is very fond of its VECs of HOST_WIDE_INT
(aka vect_el_t).
Thanks to Andrew Pinski for helping me debug.
This is close to obvious and should fix bootstrap, but I am hesitant
to call anything about vec.h obvious. Nathan cc:ed.
zw
* genautomata.c (process_state_for_insn_equiv_partition):
Use xcalloc for insn_arcs_array.
* vec.h (DEF_VEC_ALLOC_FUNC_I): New set of templates.
(DEF_VEC_ALLOC_I): Use it, not DEF_VEC_ALLOC_FUNC_P.
==================================================================
--- genautomata.c (revision 110196)
+++ genautomata.c (local)
@@ -6162,7 +6162,7 @@ static void
process_state_for_insn_equiv_partition (state_t state)
{
arc_t arc;
- arc_t *insn_arcs_array = xmalloc (description->insns_num * sizeof(arc_t));
+ arc_t *insn_arcs_array = xcalloc (description->insns_num, sizeof(arc_t));
/* Process insns of the arcs. */
for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
==================================================================
--- vec.h (revision 110196)
+++ vec.h (local)
@@ -479,7 +479,7 @@ DEF_VEC_FUNC_P(T)
\
struct vec_swallow_trailing_semi
#define DEF_VEC_ALLOC_I(T,A) \
VEC_TA_GTY(T,base,A,); \
-DEF_VEC_ALLOC_FUNC_P(T,A) \
+DEF_VEC_ALLOC_FUNC_I(T,A) \
struct vec_swallow_trailing_semi
#endif
@@ -1032,4 +1032,89 @@ static inline T *VEC_OP (T,A,safe_insert
return VEC_OP (T,base,quick_insert) (VEC_BASE(*vec_), ix_, obj_ \
VEC_CHECK_PASS); \
}
+
+#define DEF_VEC_ALLOC_FUNC_I(T,A) \
+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); \
+} \
+ \
+static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \
+{ \
+ size_t len_ = vec_ ? vec_->num : 0; \
+ VEC (T,A) *new_vec_ = NULL; \
+ \
+ if (len_) \
+ { \
+ /* We must request exact size allocation, hence the negation. */ \
+ new_vec_ = (VEC (T,A) *)(vec_##A##_o_reserve \
+ (NULL, -len_, \
+ offsetof (VEC(T,A),base.vec), sizeof (T) \
+ PASS_MEM_STAT)); \
+ \
+ new_vec_->base.num = len_; \
+ memcpy (new_vec_->base.vec, vec_->vec, sizeof (T) * len_); \
+ } \
+ return new_vec_; \
+} \
+ \
+static inline void VEC_OP (T,A,free) \
+ (VEC(T,A) **vec_) \
+{ \
+ if (*vec_) \
+ vec_##A##_free (*vec_); \
+ *vec_ = NULL;
\
+} \
+ \
+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_ \
+ VEC_CHECK_PASS); \
+ \
+ if (extend) \
+ *vec_ = (VEC(T,A) *) vec_##A##_o_reserve (*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_BASE (*vec_)->num = size_; \
+ VEC_BASE (*vec_)->num = size_; \
+} \
+ \
+static inline T *VEC_OP (T,A,safe_push)
\
+ (VEC(T,A) **vec_, const T obj_ VEC_CHECK_DECL MEM_STAT_DECL) \
+{ \
+ VEC_OP (T,A,reserve) (vec_, 1 VEC_CHECK_PASS PASS_MEM_STAT); \
+ \
+ return VEC_OP (T,base,quick_push) (VEC_BASE(*vec_), obj_ VEC_CHECK_PASS); \
+} \
+ \
+static inline T *VEC_OP (T,A,safe_insert) \
+ (VEC(T,A) **vec_, unsigned ix_, const T obj_ \
+ VEC_CHECK_DECL MEM_STAT_DECL) \
+{ \
+ VEC_OP (T,A,reserve) (vec_, 1 VEC_CHECK_PASS PASS_MEM_STAT); \
+ \
+ return VEC_OP (T,base,quick_insert) (VEC_BASE(*vec_), ix_, obj_ \
+ VEC_CHECK_PASS); \
+}
+
#endif /* GCC_VEC_H */