aboutsummaryrefslogtreecommitdiff
path: root/gcc/vec.c
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2009-06-10 16:21:03 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2009-06-10 16:21:03 +0000
commitc25696045a8422510cc2bdea80cd68eabc16d25f (patch)
tree146a14ca67c6acb094e53fa2571c06b76f178775 /gcc/vec.c
parente7aae3e8dfb1b09c77c86877ec1acfd19ce386ea (diff)
downloadgcc-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.c141
1 files changed, 141 insertions, 0 deletions
diff --git a/gcc/vec.c b/gcc/vec.c
index 530cd1a..6563fd3 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. */