diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-06-10 16:21:03 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-06-10 16:21:03 +0000 |
commit | f7f05a07345b516fb8f855e8db9c30cf51a84f83 (patch) | |
tree | 146a14ca67c6acb094e53fa2571c06b76f178775 | |
parent | 7a63ab96cf48e6f2dd363e70aa92f47642428038 (diff) | |
download | gcc-f7f05a07345b516fb8f855e8db9c30cf51a84f83.tar.gz |
* vec.h (DEF_VEC_ALLOC_I): Use DEF_VEC_NONALLOC_FUNCS_I.
(DEF_VEC_ALLOC_P): Use DEF_VEC_NONALLOC_FUNCS_P.
(DEF_VEC_ALLOC_O): Use DEF_VEC_NONALLOC_FUNCS_O.
(DEF_VEC_ALLOC_FUNC_P): Only define VEC_OP (T,A,alloc).
(DEF_VEC_NONALLOC_FUNCS_P): New macro, broken out of old
DEF_VEC_ALLOC_FUNC_P.
(DEF_VEC_ALLOC_FUNC_O): Only define VEC_OP (T,A,alloc).
(DEF_VEC_NONALLOC_FUNCS_O): New macro, broken out of old
DEF_VEC_ALLOC_FUNC_O.
(DEF_VEC_ALLOC_FUNC_I): Only define VEC_OP (T,A,alloc).
(DEF_VEC_NONALLOC_FUNCS_I): New macro, broken out of old
DEF_VEC_ALLOC_FUNC_I.
(vec_stack_p_reserve, vec_stack_p_reserve_exact): Declare.
(vec_stack_p_reserve_exact_1): Declare.
(vec_stack_o_reserve, vec_stack_o_reserve_exact): Declare.
(vec_stack_free): Declare.
(VEC_stack_alloc): Define.
(DEF_VEC_ALLOC_P_STACK, DEF_VEC_ALLOC_FUNC_P_STACK): Define.
(DEF_VEC_ALLOC_O_STACK, DEF_VEC_ALLOC_FUNC_O_STACK): Define.
(DEF_VEC_ALLOC_I_STACK, DEF_VEC_ALLOC_FUNC_I_STACK): Define.
* vec.c (void_p): New type. Call DEF_VEC_P and DEF_VEC_ALLOC_P
for void_p.
(stack_vecs): New static variable.
(vec_stack_p_reserve_exact_1): New function.
(vec_stack_o_reserve_1): New static function.
(vec_stack_p_reserve, vec_stack_p_reserve_exact): New functions.
(vec_stack_o_reserve, vec_stack_o_reserve_exact): New functions.
(vec_stack_free): New function.
* df-scan.c (df_ref): Use DEF_VEC_P and DEF_VEC_ALLOC_P_STACK.
(VEC_df_ref_stack_alloc): Define.
(df_mw_hardreg_ptr): New type. Use DEF_VEC_P and
DEF_VEC_ALLOC_P_STACK.
(VEC_df_mw_hardreg_ptr_stack_alloc): Define.
(struct df_collection_rec): Change _vec fields to VEC. Remove
_use fields.
(df_free_collection_rec): Adjust for new fields.
(df_insn_rescan): Use new df_collection_rec fields.
(df_notes_rescan, df_canonize_collection_rec): Likewise.
(df_ref_create_structure, df_ref_record): Likewise.
(df_get_conditional_uses, df_get_call_refs): Likewise.
(df_insn_refs_collect, df_bb_refs_collect): Likewise.
(df_bb_refs_record, df_record_entry_block_defs): Likewise.
(df_record_exit_block_uses, df_bb_verify): Likewise.
(df_swap_refs): Change ref_vec parameter to VEC. Change all
callers.
(df_sort_and_compress_refs): Change ref_vec parameter to VEC.
Remove count parameter. Change return type to void. Change all
callers.
(df_sort_and_compress_mws): Change mw_vec parameter to VEC.
Remove count parameter. Change return type to void. Change all
callers.
(df_install_refs): Change old_vec parameter to VEC. Remove count
parameter. Change all callers.
(df_install_mws): Change old_vec parameter to VEC. Remove count
parameter. Change all callers.
(df_refs_verify): Change new_rec parameter to VEC. Change call
callers.
(df_mws_verify): Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@148347 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 61 | ||||
-rw-r--r-- | gcc/df-scan.c | 354 | ||||
-rw-r--r-- | gcc/vec.c | 141 | ||||
-rw-r--r-- | gcc/vec.h | 89 |
4 files changed, 485 insertions, 160 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2af6cb30ab8..6e4a25f1d15 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,64 @@ +2009-06-10 Ian Lance Taylor <iant@google.com> + + * vec.h (DEF_VEC_ALLOC_I): Use DEF_VEC_NONALLOC_FUNCS_I. + (DEF_VEC_ALLOC_P): Use DEF_VEC_NONALLOC_FUNCS_P. + (DEF_VEC_ALLOC_O): Use DEF_VEC_NONALLOC_FUNCS_O. + (DEF_VEC_ALLOC_FUNC_P): Only define VEC_OP (T,A,alloc). + (DEF_VEC_NONALLOC_FUNCS_P): New macro, broken out of old + DEF_VEC_ALLOC_FUNC_P. + (DEF_VEC_ALLOC_FUNC_O): Only define VEC_OP (T,A,alloc). + (DEF_VEC_NONALLOC_FUNCS_O): New macro, broken out of old + DEF_VEC_ALLOC_FUNC_O. + (DEF_VEC_ALLOC_FUNC_I): Only define VEC_OP (T,A,alloc). + (DEF_VEC_NONALLOC_FUNCS_I): New macro, broken out of old + DEF_VEC_ALLOC_FUNC_I. + (vec_stack_p_reserve, vec_stack_p_reserve_exact): Declare. + (vec_stack_p_reserve_exact_1): Declare. + (vec_stack_o_reserve, vec_stack_o_reserve_exact): Declare. + (vec_stack_free): Declare. + (VEC_stack_alloc): Define. + (DEF_VEC_ALLOC_P_STACK, DEF_VEC_ALLOC_FUNC_P_STACK): Define. + (DEF_VEC_ALLOC_O_STACK, DEF_VEC_ALLOC_FUNC_O_STACK): Define. + (DEF_VEC_ALLOC_I_STACK, DEF_VEC_ALLOC_FUNC_I_STACK): Define. + * vec.c (void_p): New type. Call DEF_VEC_P and DEF_VEC_ALLOC_P + for void_p. + (stack_vecs): New static variable. + (vec_stack_p_reserve_exact_1): New function. + (vec_stack_o_reserve_1): New static function. + (vec_stack_p_reserve, vec_stack_p_reserve_exact): New functions. + (vec_stack_o_reserve, vec_stack_o_reserve_exact): New functions. + (vec_stack_free): New function. + * df-scan.c (df_ref): Use DEF_VEC_P and DEF_VEC_ALLOC_P_STACK. + (VEC_df_ref_stack_alloc): Define. + (df_mw_hardreg_ptr): New type. Use DEF_VEC_P and + DEF_VEC_ALLOC_P_STACK. + (VEC_df_mw_hardreg_ptr_stack_alloc): Define. + (struct df_collection_rec): Change _vec fields to VEC. Remove + _use fields. + (df_free_collection_rec): Adjust for new fields. + (df_insn_rescan): Use new df_collection_rec fields. + (df_notes_rescan, df_canonize_collection_rec): Likewise. + (df_ref_create_structure, df_ref_record): Likewise. + (df_get_conditional_uses, df_get_call_refs): Likewise. + (df_insn_refs_collect, df_bb_refs_collect): Likewise. + (df_bb_refs_record, df_record_entry_block_defs): Likewise. + (df_record_exit_block_uses, df_bb_verify): Likewise. + (df_swap_refs): Change ref_vec parameter to VEC. Change all + callers. + (df_sort_and_compress_refs): Change ref_vec parameter to VEC. + Remove count parameter. Change return type to void. Change all + callers. + (df_sort_and_compress_mws): Change mw_vec parameter to VEC. + Remove count parameter. Change return type to void. Change all + callers. + (df_install_refs): Change old_vec parameter to VEC. Remove count + parameter. Change all callers. + (df_install_mws): Change old_vec parameter to VEC. Remove count + parameter. Change all callers. + (df_refs_verify): Change new_rec parameter to VEC. Change call + callers. + (df_mws_verify): Likewise. + 2009-06-10 Alexandre Oliva <aoliva@redhat.com> * gcc.c (compare_files): Cast munmap argumento to caddr_t. diff --git a/gcc/df-scan.c b/gcc/df-scan.c index 9337b6dbd8a..51903da7a98 100644 --- a/gcc/df-scan.c +++ b/gcc/df-scan.c @@ -46,6 +46,19 @@ along with GCC; see the file COPYING3. If not see #include "df.h" #include "tree-pass.h" +DEF_VEC_P(df_ref); +DEF_VEC_ALLOC_P_STACK(df_ref); + +#define VEC_df_ref_stack_alloc(alloc) VEC_stack_alloc (df_ref, alloc) + +typedef struct df_mw_hardreg *df_mw_hardreg_ptr; + +DEF_VEC_P(df_mw_hardreg_ptr); +DEF_VEC_ALLOC_P_STACK(df_mw_hardreg_ptr); + +#define VEC_df_mw_hardreg_ptr_stack_alloc(alloc) \ + VEC_stack_alloc (df_mw_hardreg_ptr, alloc) + #ifndef HAVE_epilogue #define HAVE_epilogue 0 #endif @@ -84,14 +97,10 @@ static HARD_REG_SET elim_reg_set; struct df_collection_rec { - df_ref * def_vec; - df_ref * use_vec; - unsigned int next_def; - unsigned int next_use; - df_ref * eq_use_vec; - struct df_mw_hardreg **mw_vec; - unsigned int next_eq_use; - unsigned int next_mw; + VEC(df_ref,stack) *def_vec; + VEC(df_ref,stack) *use_vec; + VEC(df_ref,stack) *eq_use_vec; + VEC(df_mw_hardreg_ptr,stack) *mw_vec; }; static df_ref df_null_ref_rec[1]; @@ -1180,26 +1189,29 @@ df_insn_delete (basic_block bb, unsigned int uid) static void df_free_collection_rec (struct df_collection_rec *collection_rec) { + unsigned int ix; struct df_scan_problem_data *problem_data = (struct df_scan_problem_data *) df_scan->problem_data; - df_ref *ref; - struct df_mw_hardreg **mw; - - if (collection_rec->def_vec) - for (ref = collection_rec->def_vec; *ref; ref++) - df_free_ref (*ref); - if (collection_rec->use_vec) - for (ref = collection_rec->use_vec; *ref; ref++) - df_free_ref (*ref); - if (collection_rec->eq_use_vec) - for (ref = collection_rec->eq_use_vec; *ref; ref++) - df_free_ref (*ref); - if (collection_rec->mw_vec) - for (mw = collection_rec->mw_vec; *mw; mw++) - pool_free (problem_data->mw_reg_pool, *mw); + df_ref ref; + struct df_mw_hardreg *mw; + + for (ix = 0; VEC_iterate (df_ref, collection_rec->def_vec, ix, ref); ++ix) + df_free_ref (ref); + for (ix = 0; VEC_iterate (df_ref, collection_rec->use_vec, ix, ref); ++ix) + df_free_ref (ref); + for (ix = 0; VEC_iterate (df_ref, collection_rec->eq_use_vec, ix, ref); ++ix) + df_free_ref (ref); + for (ix = 0; + VEC_iterate (df_mw_hardreg_ptr, collection_rec->mw_vec, ix, mw); + ++ix) + pool_free (problem_data->mw_reg_pool, mw); + + VEC_free (df_ref, stack, collection_rec->def_vec); + VEC_free (df_ref, stack, collection_rec->use_vec); + VEC_free (df_ref, stack, collection_rec->eq_use_vec); + VEC_free (df_mw_hardreg_ptr, stack, collection_rec->mw_vec); } - /* Rescan INSN. Return TRUE if the rescanning produced any changes. */ bool @@ -1209,10 +1221,6 @@ df_insn_rescan (rtx insn) struct df_insn_info *insn_info = NULL; basic_block bb = BLOCK_FOR_INSN (insn); struct df_collection_rec collection_rec; - collection_rec.def_vec = XALLOCAVEC (df_ref, 1000); - collection_rec.use_vec = XALLOCAVEC (df_ref, 1000); - collection_rec.eq_use_vec = XALLOCAVEC (df_ref, 1000); - collection_rec.mw_vec = XALLOCAVEC (struct df_mw_hardreg *, 100); if ((!df) || (!INSN_P (insn))) return false; @@ -1253,6 +1261,11 @@ df_insn_rescan (rtx insn) return false; } + collection_rec.def_vec = VEC_alloc (df_ref, stack, 128); + collection_rec.use_vec = VEC_alloc (df_ref, stack, 32); + collection_rec.eq_use_vec = VEC_alloc (df_ref, stack, 32); + collection_rec.mw_vec = VEC_alloc (df_mw_hardreg_ptr, stack, 32); + bitmap_clear_bit (df->insns_to_delete, uid); bitmap_clear_bit (df->insns_to_rescan, uid); bitmap_clear_bit (df->insns_to_notes_rescan, uid); @@ -1288,6 +1301,12 @@ df_insn_rescan (rtx insn) df_refs_add_to_chains (&collection_rec, bb, insn); df_set_bb_dirty (bb); + + VEC_free (df_ref, stack, collection_rec.def_vec); + VEC_free (df_ref, stack, collection_rec.use_vec); + VEC_free (df_ref, stack, collection_rec.eq_use_vec); + VEC_free (df_mw_hardreg_ptr, stack, collection_rec.mw_vec); + return true; } @@ -2131,10 +2150,11 @@ df_notes_rescan (rtx insn) rtx note; struct df_collection_rec collection_rec; unsigned int num_deleted; + unsigned int mw_len; memset (&collection_rec, 0, sizeof (struct df_collection_rec)); - collection_rec.eq_use_vec = XALLOCAVEC (df_ref, 1000); - collection_rec.mw_vec = XALLOCAVEC (struct df_mw_hardreg *, 1000); + collection_rec.eq_use_vec = VEC_alloc (df_ref, stack, 32); + collection_rec.mw_vec = VEC_alloc (df_mw_hardreg_ptr, stack, 32); num_deleted = df_mw_hardreg_chain_delete_eq_uses (insn_info); df_ref_chain_delete (insn_info->eq_uses); @@ -2158,7 +2178,8 @@ df_notes_rescan (rtx insn) /* Find some place to put any new mw_hardregs. */ df_canonize_collection_rec (&collection_rec); - if (collection_rec.next_mw) + mw_len = VEC_length (df_mw_hardreg_ptr, collection_rec.mw_vec); + if (mw_len) { unsigned int count = 0; struct df_mw_hardreg **mw_rec = insn_info->mw_hardregs; @@ -2172,33 +2193,36 @@ df_notes_rescan (rtx insn) { /* Append to the end of the existing record after expanding it if necessary. */ - if (collection_rec.next_mw > num_deleted) + if (mw_len > num_deleted) { insn_info->mw_hardregs = XRESIZEVEC (struct df_mw_hardreg *, - insn_info->mw_hardregs, - count + 1 + collection_rec.next_mw); + insn_info->mw_hardregs, + count + 1 + mw_len); } - memcpy (&insn_info->mw_hardregs[count], collection_rec.mw_vec, - (collection_rec.next_mw + 1) * sizeof (struct df_mw_hardreg *)); - qsort (insn_info->mw_hardregs, count + collection_rec.next_mw, + memcpy (&insn_info->mw_hardregs[count], + VEC_address (df_mw_hardreg_ptr, collection_rec.mw_vec), + mw_len * sizeof (struct df_mw_hardreg *)); + insn_info->mw_hardregs[count + mw_len] = NULL; + qsort (insn_info->mw_hardregs, count + mw_len, sizeof (struct df_mw_hardreg *), df_mw_compare); } else { /* No vector there. */ insn_info->mw_hardregs - = XNEWVEC (struct df_mw_hardreg*, - count + 1 + collection_rec.next_mw); - memcpy (insn_info->mw_hardregs, collection_rec.mw_vec, - (collection_rec.next_mw + 1) * sizeof (struct df_mw_hardreg *)); + = XNEWVEC (struct df_mw_hardreg*, 1 + mw_len); + memcpy (insn_info->mw_hardregs, + VEC_address (df_mw_hardreg_ptr, collection_rec.mw_vec), + mw_len * sizeof (struct df_mw_hardreg *)); + insn_info->mw_hardregs[mw_len] = NULL; } } /* Get rid of the mw_rec so that df_refs_add_to_chains will ignore it. */ - collection_rec.mw_vec = NULL; - collection_rec.next_mw = 0; + VEC_free (df_mw_hardreg_ptr, stack, collection_rec.mw_vec); df_refs_add_to_chains (&collection_rec, bb, insn); + VEC_free (df_ref, stack, collection_rec.eq_use_vec); } else df_insn_rescan (insn); @@ -2316,35 +2340,43 @@ df_ref_compare (const void *r1, const void *r2) } static void -df_swap_refs (df_ref *ref_vec, int i, int j) +df_swap_refs (VEC(df_ref,stack) **ref_vec, int i, int j) { - df_ref tmp = ref_vec[i]; - ref_vec[i] = ref_vec[j]; - ref_vec[j] = tmp; + df_ref tmp = VEC_index (df_ref, *ref_vec, i); + VEC_replace (df_ref, *ref_vec, i, VEC_index (df_ref, *ref_vec, j)); + VEC_replace (df_ref, *ref_vec, j, tmp); } /* Sort and compress a set of refs. */ -static unsigned int -df_sort_and_compress_refs (df_ref *ref_vec, unsigned int count) +static void +df_sort_and_compress_refs (VEC(df_ref,stack) **ref_vec) { + unsigned int count; unsigned int i; unsigned int dist = 0; - ref_vec[count] = NULL; + count = VEC_length (df_ref, *ref_vec); + /* If there are 1 or 0 elements, there is nothing to do. */ if (count < 2) - return count; + return; else if (count == 2) { - if (df_ref_compare (&ref_vec[0], &ref_vec[1]) > 0) + df_ref r0 = VEC_index (df_ref, *ref_vec, 0); + df_ref r1 = VEC_index (df_ref, *ref_vec, 1); + if (df_ref_compare (&r0, &r1) > 0) df_swap_refs (ref_vec, 0, 1); } else { for (i = 0; i < count - 1; i++) - if (df_ref_compare (&ref_vec[i], &ref_vec[i+1]) >= 0) - break; + { + df_ref r0 = VEC_index (df_ref, *ref_vec, i); + df_ref r1 = VEC_index (df_ref, *ref_vec, i + 1); + if (df_ref_compare (&r0, &r1) >= 0) + break; + } /* If the array is already strictly ordered, which is the most common case for large COUNT case (which happens for CALL INSNs), @@ -2353,26 +2385,29 @@ df_sort_and_compress_refs (df_ref *ref_vec, unsigned int count) Make sure DF_GET_ADD_REFS adds refs in the increasing order of DF_REF_COMPARE. */ if (i == count - 1) - return count; - qsort (ref_vec, count, sizeof (df_ref), df_ref_compare); + return; + qsort (VEC_address (df_ref, *ref_vec), count, sizeof (df_ref), + df_ref_compare); } for (i=0; i<count-dist; i++) { /* Find the next ref that is not equal to the current ref. */ - while (df_ref_equal_p (ref_vec[i], ref_vec[i + dist + 1])) + while (i + dist + 1 < count + && df_ref_equal_p (VEC_index (df_ref, *ref_vec, i), + VEC_index (df_ref, *ref_vec, i + dist + 1))) { - df_free_ref (ref_vec[i + dist + 1]); + df_free_ref (VEC_index (df_ref, *ref_vec, i + dist + 1)); dist++; } /* Copy it down to the next position. */ - if (dist) - ref_vec[i+1] = ref_vec[i + dist + 1]; + if (dist && i + dist + 1 < count) + VEC_replace (df_ref, *ref_vec, i + 1, + VEC_index (df_ref, *ref_vec, i + dist + 1)); } count -= dist; - ref_vec[count] = NULL; - return count; + VEC_truncate (df_ref, *ref_vec, count); } @@ -2425,45 +2460,55 @@ df_mw_compare (const void *m1, const void *m2) /* Sort and compress a set of refs. */ -static unsigned int -df_sort_and_compress_mws (struct df_mw_hardreg **mw_vec, unsigned int count) +static void +df_sort_and_compress_mws (VEC(df_mw_hardreg_ptr,stack) **mw_vec) { + unsigned int count; struct df_scan_problem_data *problem_data = (struct df_scan_problem_data *) df_scan->problem_data; unsigned int i; unsigned int dist = 0; - mw_vec[count] = NULL; + count = VEC_length (df_mw_hardreg_ptr, *mw_vec); if (count < 2) - return count; + return; else if (count == 2) { - if (df_mw_compare (&mw_vec[0], &mw_vec[1]) > 0) + struct df_mw_hardreg *m0 = VEC_index (df_mw_hardreg_ptr, *mw_vec, 0); + struct df_mw_hardreg *m1 = VEC_index (df_mw_hardreg_ptr, *mw_vec, 1); + if (df_mw_compare (&m0, &m1) > 0) { - struct df_mw_hardreg *tmp = mw_vec[0]; - mw_vec[0] = mw_vec[1]; - mw_vec[1] = tmp; + struct df_mw_hardreg *tmp = VEC_index (df_mw_hardreg_ptr, + *mw_vec, 0); + VEC_replace (df_mw_hardreg_ptr, *mw_vec, 0, + VEC_index (df_mw_hardreg_ptr, *mw_vec, 1)); + VEC_replace (df_mw_hardreg_ptr, *mw_vec, 1, tmp); } } else - qsort (mw_vec, count, sizeof (struct df_mw_hardreg *), df_mw_compare); + qsort (VEC_address (df_mw_hardreg_ptr, *mw_vec), count, + sizeof (struct df_mw_hardreg *), df_mw_compare); for (i=0; i<count-dist; i++) { /* Find the next ref that is not equal to the current ref. */ - while (df_mw_equal_p (mw_vec[i], mw_vec[i + dist + 1])) + while (i + dist + 1 < count + && df_mw_equal_p (VEC_index (df_mw_hardreg_ptr, *mw_vec, i), + VEC_index (df_mw_hardreg_ptr, *mw_vec, + i + dist + 1))) { - pool_free (problem_data->mw_reg_pool, mw_vec[i + dist + 1]); + pool_free (problem_data->mw_reg_pool, + VEC_index (df_mw_hardreg_ptr, *mw_vec, i + dist + 1)); dist++; } /* Copy it down to the next position. */ - if (dist) - mw_vec[i+1] = mw_vec[i + dist + 1]; + if (dist && i + dist + 1 < count) + VEC_replace (df_mw_hardreg_ptr, *mw_vec, i + 1, + VEC_index (df_mw_hardreg_ptr, *mw_vec, i + dist + 1)); } count -= dist; - mw_vec[count] = NULL; - return count; + VEC_truncate (df_mw_hardreg_ptr, *mw_vec, count); } @@ -2472,22 +2517,10 @@ df_sort_and_compress_mws (struct df_mw_hardreg **mw_vec, unsigned int count) static void df_canonize_collection_rec (struct df_collection_rec *collection_rec) { - if (collection_rec->def_vec) - collection_rec->next_def - = df_sort_and_compress_refs (collection_rec->def_vec, - collection_rec->next_def); - if (collection_rec->use_vec) - collection_rec->next_use - = df_sort_and_compress_refs (collection_rec->use_vec, - collection_rec->next_use); - if (collection_rec->eq_use_vec) - collection_rec->next_eq_use - = df_sort_and_compress_refs (collection_rec->eq_use_vec, - collection_rec->next_eq_use); - if (collection_rec->mw_vec) - collection_rec->next_mw - = df_sort_and_compress_mws (collection_rec->mw_vec, - collection_rec->next_mw); + df_sort_and_compress_refs (&collection_rec->def_vec); + df_sort_and_compress_refs (&collection_rec->use_vec); + df_sort_and_compress_refs (&collection_rec->eq_use_vec); + df_sort_and_compress_mws (&collection_rec->mw_vec); } @@ -2545,16 +2578,20 @@ df_install_ref (df_ref this_ref, static df_ref * df_install_refs (basic_block bb, - df_ref *old_vec, unsigned int count, + VEC(df_ref,stack)* old_vec, struct df_reg_info **reg_info, struct df_ref_info *ref_info, bool is_notes) { + unsigned int count; + + count = VEC_length (df_ref, old_vec); if (count) { - unsigned int i; df_ref *new_vec = XNEWVEC (df_ref, count + 1); bool add_to_table; + df_ref this_ref; + unsigned int ix; switch (ref_info->ref_order) { @@ -2579,10 +2616,9 @@ df_install_refs (basic_block bb, if (add_to_table && df->analyze_subset) add_to_table = bitmap_bit_p (df->blocks_to_analyze, bb->index); - for (i = 0; i < count; i++) + for (ix = 0; VEC_iterate (df_ref, old_vec, ix, this_ref); ++ix) { - df_ref this_ref = old_vec[i]; - new_vec[i] = this_ref; + new_vec[ix] = this_ref; df_install_ref (this_ref, reg_info[DF_REF_REGNO (this_ref)], ref_info, add_to_table); } @@ -2599,14 +2635,18 @@ df_install_refs (basic_block bb, insn. */ static struct df_mw_hardreg ** -df_install_mws (struct df_mw_hardreg **old_vec, unsigned int count) +df_install_mws (VEC(df_mw_hardreg_ptr,stack) *old_vec) { + unsigned int count; + + count = VEC_length (df_mw_hardreg_ptr, old_vec); if (count) { struct df_mw_hardreg **new_vec = XNEWVEC (struct df_mw_hardreg*, count + 1); - memcpy (new_vec, old_vec, - sizeof (struct df_mw_hardreg*) * (count + 1)); + memcpy (new_vec, VEC_address (df_mw_hardreg_ptr, old_vec), + sizeof (struct df_mw_hardreg*) * count); + new_vec[count] = NULL; return new_vec; } else @@ -2631,8 +2671,7 @@ df_refs_add_to_chains (struct df_collection_rec *collection_rec, { df_scan_free_ref_vec (insn_rec->defs); insn_rec->defs - = df_install_refs (bb, collection_rec->def_vec, - collection_rec->next_def, + = df_install_refs (bb, collection_rec->def_vec, df->def_regs, &df->def_info, false); } @@ -2641,7 +2680,6 @@ df_refs_add_to_chains (struct df_collection_rec *collection_rec, df_scan_free_ref_vec (insn_rec->uses); insn_rec->uses = df_install_refs (bb, collection_rec->use_vec, - collection_rec->next_use, df->use_regs, &df->use_info, false); } @@ -2650,7 +2688,6 @@ df_refs_add_to_chains (struct df_collection_rec *collection_rec, df_scan_free_ref_vec (insn_rec->eq_uses); insn_rec->eq_uses = df_install_refs (bb, collection_rec->eq_use_vec, - collection_rec->next_eq_use, df->eq_use_regs, &df->use_info, true); } @@ -2658,8 +2695,7 @@ df_refs_add_to_chains (struct df_collection_rec *collection_rec, { df_scan_free_mws_vec (insn_rec->mw_hardregs); insn_rec->mw_hardregs - = df_install_mws (collection_rec->mw_vec, - collection_rec->next_mw); + = df_install_mws (collection_rec->mw_vec); } } else @@ -2668,14 +2704,12 @@ df_refs_add_to_chains (struct df_collection_rec *collection_rec, df_scan_free_ref_vec (bb_info->artificial_defs); bb_info->artificial_defs - = df_install_refs (bb, collection_rec->def_vec, - collection_rec->next_def, + = df_install_refs (bb, collection_rec->def_vec, df->def_regs, &df->def_info, false); df_scan_free_ref_vec (bb_info->artificial_uses); bb_info->artificial_uses = df_install_refs (bb, collection_rec->use_vec, - collection_rec->next_use, df->use_regs, &df->use_info, false); } @@ -2767,11 +2801,11 @@ df_ref_create_structure (enum df_ref_class cl, if (collection_rec) { if (DF_REF_REG_DEF_P (this_ref)) - collection_rec->def_vec[collection_rec->next_def++] = this_ref; + VEC_safe_push (df_ref, stack, collection_rec->def_vec, this_ref); else if (DF_REF_FLAGS (this_ref) & DF_REF_IN_NOTE) - collection_rec->eq_use_vec[collection_rec->next_eq_use++] = this_ref; + VEC_safe_push (df_ref, stack, collection_rec->eq_use_vec, this_ref); else - collection_rec->use_vec[collection_rec->next_use++] = this_ref; + VEC_safe_push (df_ref, stack, collection_rec->use_vec, this_ref); } return this_ref; @@ -2837,7 +2871,8 @@ df_ref_record (enum df_ref_class cl, hardreg->start_regno = regno; hardreg->end_regno = endregno - 1; hardreg->mw_order = df->ref_order++; - collection_rec->mw_vec[collection_rec->next_mw++] = hardreg; + VEC_safe_push (df_mw_hardreg_ptr, stack, collection_rec->mw_vec, + hardreg); } for (i = regno; i < endregno; i++) @@ -3291,10 +3326,11 @@ df_uses_record (enum df_ref_class cl, struct df_collection_rec *collection_rec, static void df_get_conditional_uses (struct df_collection_rec *collection_rec) { - unsigned int i; - for (i = 0; i < collection_rec->next_def; i++) + unsigned int ix; + df_ref ref; + + for (ix = 0; VEC_iterate (df_ref, collection_rec->def_vec, ix, ref); ++ix) { - df_ref ref = collection_rec->def_vec[i]; if (DF_REF_FLAGS_IS_SET (ref, DF_REF_CONDITIONAL)) { int width = -1; @@ -3333,16 +3369,14 @@ df_get_call_refs (struct df_collection_rec * collection_rec, unsigned int ui; bool is_sibling_call; unsigned int i; + df_ref def; bitmap defs_generated = BITMAP_ALLOC (&df_bitmap_obstack); /* Do not generate clobbers for registers that are the result of the call. This causes ordering problems in the chain building code depending on which def is seen first. */ - for (i=0; i<collection_rec->next_def; i++) - { - df_ref def = collection_rec->def_vec[i]; - bitmap_set_bit (defs_generated, DF_REF_REGNO (def)); - } + for (i = 0; VEC_iterate (df_ref, collection_rec->def_vec, i, def); ++i) + bitmap_set_bit (defs_generated, DF_REF_REGNO (def)); /* Record the registers used to pass arguments, and explicitly noted as clobbered. */ @@ -3420,10 +3454,10 @@ df_insn_refs_collect (struct df_collection_rec* collection_rec, bool is_cond_exec = (GET_CODE (PATTERN (insn_info->insn)) == COND_EXEC); /* Clear out the collection record. */ - collection_rec->next_def = 0; - collection_rec->next_use = 0; - collection_rec->next_eq_use = 0; - collection_rec->next_mw = 0; + VEC_truncate (df_ref, collection_rec->def_vec, 0); + VEC_truncate (df_ref, collection_rec->use_vec, 0); + VEC_truncate (df_ref, collection_rec->eq_use_vec, 0); + VEC_truncate (df_mw_hardreg_ptr, collection_rec->mw_vec, 0); /* Record register defs. */ df_defs_record (collection_rec, PATTERN (insn_info->insn), bb, insn_info, 0); @@ -3521,10 +3555,10 @@ df_need_static_chain_reg (struct function *fun) static void df_bb_refs_collect (struct df_collection_rec *collection_rec, basic_block bb) { - collection_rec->next_def = 0; - collection_rec->next_use = 0; - collection_rec->next_eq_use = 0; - collection_rec->next_mw = 0; + VEC_truncate (df_ref, collection_rec->def_vec, 0); + VEC_truncate (df_ref, collection_rec->use_vec, 0); + VEC_truncate (df_ref, collection_rec->eq_use_vec, 0); + VEC_truncate (df_mw_hardreg_ptr, collection_rec->mw_vec, 0); if (bb->index == ENTRY_BLOCK) { @@ -3590,10 +3624,6 @@ df_bb_refs_record (int bb_index, bool scan_insns) int luid = 0; struct df_scan_bb_info *bb_info; struct df_collection_rec collection_rec; - collection_rec.def_vec = XALLOCAVEC (df_ref, 1000); - collection_rec.use_vec = XALLOCAVEC (df_ref, 1000); - collection_rec.eq_use_vec = XALLOCAVEC (df_ref, 1000); - collection_rec.mw_vec = XALLOCAVEC (struct df_mw_hardreg *, 100); if (!df) return; @@ -3609,6 +3639,11 @@ df_bb_refs_record (int bb_index, bool scan_insns) bb_info->artificial_uses = NULL; } + collection_rec.def_vec = VEC_alloc (df_ref, stack, 128); + collection_rec.use_vec = VEC_alloc (df_ref, stack, 32); + collection_rec.eq_use_vec = VEC_alloc (df_ref, stack, 32); + collection_rec.mw_vec = VEC_alloc (df_mw_hardreg_ptr, stack, 32); + if (scan_insns) /* Scan the block an insn at a time from beginning to end. */ FOR_BB_INSNS (bb, insn) @@ -3631,6 +3666,11 @@ df_bb_refs_record (int bb_index, bool scan_insns) df_bb_refs_collect (&collection_rec, bb); df_refs_add_to_chains (&collection_rec, bb, NULL); + VEC_free (df_ref, stack, collection_rec.def_vec); + VEC_free (df_ref, stack, collection_rec.use_vec); + VEC_free (df_ref, stack, collection_rec.eq_use_vec); + VEC_free (df_mw_hardreg_ptr, stack, collection_rec.mw_vec); + /* Now that the block has been processed, set the block as dirty so LR and LIVE will get it processed. */ df_set_bb_dirty (bb); @@ -3889,12 +3929,12 @@ df_record_entry_block_defs (bitmap entry_block_defs) { struct df_collection_rec collection_rec; memset (&collection_rec, 0, sizeof (struct df_collection_rec)); - collection_rec.def_vec = XALLOCAVEC (df_ref, FIRST_PSEUDO_REGISTER); - + collection_rec.def_vec = VEC_alloc (df_ref, stack, FIRST_PSEUDO_REGISTER); df_entry_block_defs_collect (&collection_rec, entry_block_defs); /* Process bb_refs chain */ df_refs_add_to_chains (&collection_rec, BASIC_BLOCK (ENTRY_BLOCK), NULL); + VEC_free (df_ref, stack, collection_rec.def_vec); } @@ -4060,12 +4100,13 @@ df_record_exit_block_uses (bitmap exit_block_uses) { struct df_collection_rec collection_rec; memset (&collection_rec, 0, sizeof (struct df_collection_rec)); - collection_rec.use_vec = XALLOCAVEC (df_ref, FIRST_PSEUDO_REGISTER); + collection_rec.use_vec = VEC_alloc (df_ref, stack, FIRST_PSEUDO_REGISTER); df_exit_block_uses_collect (&collection_rec, exit_block_uses); /* Process bb_refs chain */ df_refs_add_to_chains (&collection_rec, BASIC_BLOCK (EXIT_BLOCK), NULL); + VEC_free (df_ref, stack, collection_rec.use_vec); } @@ -4242,7 +4283,7 @@ df_compute_regs_ever_live (bool reset) df_reg_chain_mark (refs, regno, is_def, is_eq_use) df_reg_chain_verify_unmarked (refs) - df_refs_verify (ref*, ref*, bool) + df_refs_verify (VEC(stack,df_ref)*, ref*, bool) df_mws_verify (mw*, mw*, bool) df_insn_refs_verify (collection_rec, bb, insn, bool) df_bb_refs_verify (bb, refs, bool) @@ -4306,12 +4347,15 @@ df_reg_chain_verify_unmarked (df_ref refs) /* Verify that NEW_REC and OLD_REC have exactly the same members. */ static bool -df_refs_verify (df_ref *new_rec, df_ref *old_rec, +df_refs_verify (VEC(df_ref,stack) *new_rec, df_ref *old_rec, bool abort_if_fail) { - while ((*new_rec) && (*old_rec)) + unsigned int ix; + df_ref new_ref; + + for (ix = 0; VEC_iterate (df_ref, new_rec, ix, new_ref); ++ix) { - if (!df_ref_equal_p (*new_rec, *old_rec)) + if (*old_rec == NULL || !df_ref_equal_p (new_ref, *old_rec)) { if (abort_if_fail) gcc_assert (0); @@ -4327,14 +4371,13 @@ df_refs_verify (df_ref *new_rec, df_ref *old_rec, DF_REF_REG_UNMARK (*old_rec); } - new_rec++; old_rec++; } if (abort_if_fail) - gcc_assert ((*new_rec == NULL) && (*old_rec == NULL)); + gcc_assert (*old_rec == NULL); else - return ((*new_rec == NULL) && (*old_rec == NULL)); + return *old_rec == NULL; return false; } @@ -4342,26 +4385,29 @@ df_refs_verify (df_ref *new_rec, df_ref *old_rec, /* Verify that NEW_REC and OLD_REC have exactly the same members. */ static bool -df_mws_verify (struct df_mw_hardreg **new_rec, struct df_mw_hardreg **old_rec, +df_mws_verify (VEC(df_mw_hardreg_ptr,stack) *new_rec, + struct df_mw_hardreg **old_rec, bool abort_if_fail) { - while ((*new_rec) && (*old_rec)) + unsigned int ix; + struct df_mw_hardreg *new_reg; + + for (ix = 0; VEC_iterate (df_mw_hardreg_ptr, new_rec, ix, new_reg); ++ix) { - if (!df_mw_equal_p (*new_rec, *old_rec)) + if (*old_rec == NULL || !df_mw_equal_p (new_reg, *old_rec)) { if (abort_if_fail) gcc_assert (0); else return false; } - new_rec++; old_rec++; } if (abort_if_fail) - gcc_assert ((*new_rec == NULL) && (*old_rec == NULL)); + gcc_assert (*old_rec == NULL); else - return ((*new_rec == NULL) && (*old_rec == NULL)); + return *old_rec == NULL; return false; } @@ -4424,10 +4470,10 @@ df_bb_verify (basic_block bb) struct df_collection_rec collection_rec; memset (&collection_rec, 0, sizeof (struct df_collection_rec)); - collection_rec.def_vec = XALLOCAVEC (df_ref, 1000); - collection_rec.use_vec = XALLOCAVEC (df_ref, 1000); - collection_rec.eq_use_vec = XALLOCAVEC (df_ref, 1000); - collection_rec.mw_vec = XALLOCAVEC (struct df_mw_hardreg *, 100); + collection_rec.def_vec = VEC_alloc (df_ref, stack, 128); + collection_rec.use_vec = VEC_alloc (df_ref, stack, 32); + collection_rec.eq_use_vec = VEC_alloc (df_ref, stack, 32); + collection_rec.mw_vec = VEC_alloc (df_mw_hardreg_ptr, stack, 32); gcc_assert (bb_info); diff --git a/gcc/vec.c b/gcc/vec.c index 530cd1abc4b..6563fd372b7 100644 --- a/gcc/vec.c +++ b/gcc/vec.c @@ -372,6 +372,147 @@ vec_heap_o_reserve_exact (void *vec, int reserve, size_t vec_offset, PASS_MEM_STAT); } +/* Stack vectors are a little different. VEC_alloc turns into a call + to vec_stack_p_reserve_exact1 and passes in space allocated via a + call to alloca. We record that pointer so that we know that we + shouldn't free it. If the vector is resized, we resize it on the + heap. We record the pointers in a vector and search it in LIFO + order--i.e., we look for the newest stack vectors first. We don't + expect too many stack vectors at any one level, and searching from + the end should normally be efficient even if they are used in a + recursive function. */ + +typedef void *void_p; +DEF_VEC_P(void_p); +DEF_VEC_ALLOC_P(void_p,heap); + +static VEC(void_p,heap) *stack_vecs; + +/* Allocate a vector which uses alloca for the initial allocation. + SPACE is space allocated using alloca, ALLOC is the number of + entries allocated. */ + +void * +vec_stack_p_reserve_exact_1 (int alloc, void *space) +{ + struct vec_prefix *pfx = (struct vec_prefix *) space; + + VEC_safe_push (void_p, heap, stack_vecs, space); + + pfx->num = 0; + pfx->alloc = alloc; + + return space; +} + +/* Grow a vector allocated using alloca. When this happens, we switch + back to heap allocation. We remove the vector from stack_vecs, if + it is there, since we no longer need to avoid freeing it. */ + +static void * +vec_stack_o_reserve_1 (void *vec, int reserve, size_t vec_offset, + size_t elt_size, bool exact MEM_STAT_DECL) +{ + bool found; + unsigned int ix; + void *newvec; + + found = false; + for (ix = VEC_length (void_p, stack_vecs); ix > 0; --ix) + { + if (VEC_index (void_p, stack_vecs, ix - 1) == vec) + { + VEC_unordered_remove (void_p, stack_vecs, ix - 1); + found = true; + break; + } + } + + if (!found) + { + /* VEC is already on the heap. */ + return vec_heap_o_reserve_1 (vec, reserve, vec_offset, elt_size, + exact PASS_MEM_STAT); + } + + /* Move VEC to the heap. */ + reserve += ((struct vec_prefix *) vec)->num; + newvec = vec_heap_o_reserve_1 (NULL, reserve, vec_offset, elt_size, + exact PASS_MEM_STAT); + if (newvec && vec) + { + ((struct vec_prefix *) newvec)->num = ((struct vec_prefix *) vec)->num; + memcpy (((struct vec_prefix *) newvec)->vec, + ((struct vec_prefix *) vec)->vec, + ((struct vec_prefix *) vec)->num * elt_size); + } + return newvec; +} + +/* Grow a vector allocated on the stack. */ + +void * +vec_stack_p_reserve (void *vec, int reserve MEM_STAT_DECL) +{ + return vec_stack_o_reserve_1 (vec, reserve, + offsetof (struct vec_prefix, vec), + sizeof (void *), false + PASS_MEM_STAT); +} + +/* Exact version of vec_stack_p_reserve. */ + +void * +vec_stack_p_reserve_exact (void *vec, int reserve MEM_STAT_DECL) +{ + return vec_stack_o_reserve_1 (vec, reserve, + offsetof (struct vec_prefix, vec), + sizeof (void *), true + PASS_MEM_STAT); +} + +/* Like vec_stack_p_reserve, but for objects. */ + +void * +vec_stack_o_reserve (void *vec, int reserve, size_t vec_offset, + size_t elt_size MEM_STAT_DECL) +{ + return vec_stack_o_reserve_1 (vec, reserve, vec_offset, elt_size, false + PASS_MEM_STAT); +} + +/* Like vec_stack_p_reserve_exact, but for objects. */ + +void * +vec_stack_o_reserve_exact (void *vec, int reserve, size_t vec_offset, + size_t elt_size MEM_STAT_DECL) +{ + return vec_stack_o_reserve_1 (vec, reserve, vec_offset, elt_size, true + PASS_MEM_STAT); +} + +/* Free a vector allocated on the stack. Don't actually free it if we + find it in the hash table. */ + +void +vec_stack_free (void *vec) +{ + unsigned int ix; + + for (ix = VEC_length (void_p, stack_vecs); ix > 0; --ix) + { + if (VEC_index (void_p, stack_vecs, ix - 1) == vec) + { + VEC_unordered_remove (void_p, stack_vecs, ix - 1); + return; + } + } + + /* VEC was not on the list of vecs allocated on the stack, so it + must be allocated on the heap. */ + vec_heap_free (vec); +} + #if ENABLE_CHECKING /* Issue a vector domain error, and then fall over. */ diff --git a/gcc/vec.h b/gcc/vec.h index 6c79df00885..d408c6d1a1a 100644 --- a/gcc/vec.h +++ b/gcc/vec.h @@ -508,6 +508,7 @@ struct vec_swallow_trailing_semi #define DEF_VEC_ALLOC_I(T,A) \ VEC_TA(T,base,A); \ DEF_VEC_ALLOC_FUNC_I(T,A) \ +DEF_VEC_NONALLOC_FUNCS_I(T,A) \ struct vec_swallow_trailing_semi /* Vector of pointer to object. */ @@ -524,6 +525,7 @@ struct vec_swallow_trailing_semi #define DEF_VEC_ALLOC_P(T,A) \ VEC_TA(T,base,A); \ DEF_VEC_ALLOC_FUNC_P(T,A) \ +DEF_VEC_NONALLOC_FUNCS_P(T,A) \ struct vec_swallow_trailing_semi #define DEF_VEC_FUNC_P(T) \ @@ -716,8 +718,10 @@ static inline VEC(T,A) *VEC_OP (T,A,alloc) \ { \ return (VEC(T,A) *) vec_##A##_p_reserve_exact (NULL, alloc_ \ PASS_MEM_STAT); \ -} \ - \ +} + + +#define DEF_VEC_NONALLOC_FUNCS_P(T,A) \ static inline void VEC_OP (T,A,free) \ (VEC(T,A) **vec_) \ { \ @@ -814,6 +818,7 @@ struct vec_swallow_trailing_semi #define DEF_VEC_ALLOC_O(T,A) \ VEC_TA(T,base,A); \ DEF_VEC_ALLOC_FUNC_O(T,A) \ +DEF_VEC_NONALLOC_FUNCS_O(T,A) \ struct vec_swallow_trailing_semi #define DEF_VEC_FUNC_O(T) \ @@ -995,8 +1000,9 @@ static inline VEC(T,A) *VEC_OP (T,A,alloc) \ offsetof (VEC(T,A),base.vec), \ sizeof (T) \ PASS_MEM_STAT); \ -} \ - \ +} + +#define DEF_VEC_NONALLOC_FUNCS_O(T,A) \ static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \ { \ size_t len_ = vec_ ? vec_->num : 0; \ @@ -1099,8 +1105,9 @@ static inline VEC(T,A) *VEC_OP (T,A,alloc) \ return (VEC(T,A) *) vec_##A##_o_reserve_exact \ (NULL, alloc_, offsetof (VEC(T,A),base.vec), \ sizeof (T) PASS_MEM_STAT); \ -} \ - \ +} + +#define DEF_VEC_NONALLOC_FUNCS_I(T,A) \ static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \ { \ size_t len_ = vec_ ? vec_->num : 0; \ @@ -1195,4 +1202,74 @@ static inline T *VEC_OP (T,A,safe_insert) \ VEC_CHECK_PASS); \ } +/* We support a vector which starts out with space on the stack and + switches to heap space when forced to reallocate. This works a + little differently. Instead of DEF_VEC_ALLOC_P(TYPE, heap|gc), use + DEF_VEC_ALLOC_P_STACK(TYPE). This uses alloca to get the initial + space; because alloca can not be usefully called in an inline + function, and because a macro can not define a macro, you must then + write a #define for each type: + + #define VEC_{TYPE}_stack_alloc(alloc) \ + VEC_stack_alloc({TYPE}, alloc) + + This is really a hack and perhaps can be made better. Note that + this macro will wind up evaluating the ALLOC parameter twice. + + Only the initial allocation will be made using alloca, so pass a + reasonable estimate that doesn't use too much stack space; don't + pass zero. Don't return a VEC(TYPE,stack) vector from the function + which allocated it. */ + +extern void *vec_stack_p_reserve (void *, int MEM_STAT_DECL); +extern void *vec_stack_p_reserve_exact (void *, int MEM_STAT_DECL); +extern void *vec_stack_p_reserve_exact_1 (int, void *); +extern void *vec_stack_o_reserve (void *, int, size_t, size_t MEM_STAT_DECL); +extern void *vec_stack_o_reserve_exact (void *, int, size_t, size_t + MEM_STAT_DECL); +extern void vec_stack_free (void *); + +#define VEC_stack_alloc(T,alloc) \ + (VEC_OP (T,stack,alloc1) \ + (alloc, XALLOCAVAR (VEC(T,stack), VEC_embedded_size (T, alloc)))) + +#define DEF_VEC_ALLOC_P_STACK(T) \ +VEC_TA(T,base,stack); \ +DEF_VEC_ALLOC_FUNC_P_STACK(T) \ +DEF_VEC_NONALLOC_FUNCS_P(T,stack) \ +struct vec_swallow_trailing_semi + +#define DEF_VEC_ALLOC_FUNC_P_STACK(T) \ +static inline VEC(T,stack) *VEC_OP (T,stack,alloc1) \ + (int alloc_, VEC(T,stack)* space MEM_STAT_DECL) \ +{ \ + return (VEC(T,stack) *) vec_stack_p_reserve_exact_1 (alloc_, space); \ +} + +#define DEF_VEC_ALLOC_O_STACK(T) \ +VEC_TA(T,base,stack); \ +DEF_VEC_ALLOC_FUNC_O_STACK(T) \ +DEF_VEC_NONALLOC_FUNCS_O(T,stack) \ +struct vec_swallow_trailing_semi + +#define DEF_VEC_ALLOC_FUNC_O_STACK(T) \ +static inline VEC(T,stack) *VEC_OP (T,stack,alloc1) \ + (int alloc_, VEC(T,stack)* space MEM_STAT_DECL) \ +{ \ + return ((VEC(T,stack) *) vec_stack_p_reserve_exact_1 (alloc_, space); \ +} + +#define DEF_VEC_ALLOC_I_STACK(T) \ +VEC_TA(T,base,stack); \ +DEF_VEC_ALLOC_FUNC_I_STACK(T) \ +DEF_VEC_NONALLOC_FUNCS_I(T,stack) \ +struct vec_swallow_trailing_semi + +#define DEF_VEC_ALLOC_FUNC_I_STACK(T) \ +static inline VEC(T,stack) *VEC_OP (T,stack,alloc1) \ + (int alloc_, VEC(T,stack)* space MEM_STAT_DECL) \ +{ \ + return ((VEC(T,stack) *) vec_stack_p_reserve_exact_1 (alloc_, space); \ +} + #endif /* GCC_VEC_H */ |