diff options
author | Ian Lance Taylor <iant@google.com> | 2009-06-10 16:21:03 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2009-06-10 16:21:03 +0000 |
commit | c25696045a8422510cc2bdea80cd68eabc16d25f (patch) | |
tree | 146a14ca67c6acb094e53fa2571c06b76f178775 /gcc/vec.c | |
parent | e7aae3e8dfb1b09c77c86877ec1acfd19ce386ea (diff) | |
download | gcc-c25696045a8422510cc2bdea80cd68eabc16d25f.zip gcc-c25696045a8422510cc2bdea80cd68eabc16d25f.tar.gz gcc-c25696045a8422510cc2bdea80cd68eabc16d25f.tar.bz2 |
vec.h (DEF_VEC_ALLOC_I): Use DEF_VEC_NONALLOC_FUNCS_I.
* 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.
From-SVN: r148347
Diffstat (limited to 'gcc/vec.c')
-rw-r--r-- | gcc/vec.c | 141 |
1 files changed, 141 insertions, 0 deletions
@@ -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. */ |