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 */