diff options
Diffstat (limited to 'gcc-4.2.1-5666.3/gcc/vec.c')
-rw-r--r-- | gcc-4.2.1-5666.3/gcc/vec.c | 250 |
1 files changed, 250 insertions, 0 deletions
diff --git a/gcc-4.2.1-5666.3/gcc/vec.c b/gcc-4.2.1-5666.3/gcc/vec.c new file mode 100644 index 000000000..d65f5bfee --- /dev/null +++ b/gcc-4.2.1-5666.3/gcc/vec.c @@ -0,0 +1,250 @@ +/* Vector API for GNU compiler. + Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. + Contributed by Nathan Sidwell <nathan@codesourcery.com> + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING. If not, write to the Free +Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301, USA. */ + +/* This file is compiled twice: once for the generator programs + once for the compiler. */ +#ifdef GENERATOR_FILE +#include "bconfig.h" +#else +#include "config.h" +#endif + +#include "system.h" +#include "ggc.h" +#include "vec.h" +#include "coretypes.h" +#include "tree.h" +#include "toplev.h" + +struct vec_prefix +{ + unsigned num; + unsigned alloc; + void *vec[1]; +}; + +/* Calculate the new ALLOC value, making sure that RESERVE slots are + free. If EXACT grow exactly, otherwise grow exponentially. */ + +static inline unsigned +calculate_allocation (const struct vec_prefix *pfx, int reserve, bool exact) +{ + unsigned alloc = 0; + unsigned num = 0; + + gcc_assert (reserve >= 0); + + if (pfx) + { + alloc = pfx->alloc; + num = pfx->num; + } + else if (!reserve) + /* If there's no prefix, and we've not requested anything, then we + will create a NULL vector. */ + return 0; + + /* We must have run out of room. */ + gcc_assert (alloc - num < (unsigned) reserve); + + if (exact) + /* Exact size. */ + alloc = num + reserve; + else + { + /* Exponential growth. */ + if (!alloc) + alloc = 4; + else if (alloc < 16) + /* Double when small. */ + alloc = alloc * 2; + else + /* Grow slower when large. */ + alloc = (alloc * 3 / 2); + + /* If this is still too small, set it to the right size. */ + if (alloc < num + reserve) + alloc = num + reserve; + } + return alloc; +} + +/* Ensure there are at least RESERVE free slots in VEC. If EXACT grow + exactly, else grow exponentially. As a special case, if VEC is + NULL and RESERVE is 0, no vector will be created. The vector's + trailing array is at VEC_OFFSET offset and consists of ELT_SIZE + sized elements. */ + +static void * +vec_gc_o_reserve_1 (void *vec, int reserve, size_t vec_offset, size_t elt_size, + bool exact MEM_STAT_DECL) +{ + struct vec_prefix *pfx = vec; + unsigned alloc = alloc = calculate_allocation (pfx, reserve, exact); + + if (!alloc) + return NULL; + + vec = ggc_realloc_stat (vec, vec_offset + alloc * elt_size PASS_MEM_STAT); + ((struct vec_prefix *)vec)->alloc = alloc; + if (!pfx) + ((struct vec_prefix *)vec)->num = 0; + + return vec; +} + +/* Ensure there are at least RESERVE free slots in VEC, growing + exponentially. If RESERVE < 0 grow exactly, else grow + exponentially. As a special case, if VEC is NULL, and RESERVE is + 0, no vector will be created. */ + +void * +vec_gc_p_reserve (void *vec, int reserve MEM_STAT_DECL) +{ + return vec_gc_o_reserve_1 (vec, reserve, + offsetof (struct vec_prefix, vec), + sizeof (void *), false + PASS_MEM_STAT); +} + +/* Ensure there are at least RESERVE free slots in VEC, growing + exactly. If RESERVE < 0 grow exactly, else grow exponentially. As + a special case, if VEC is NULL, and RESERVE is 0, no vector will be + created. */ + +void * +vec_gc_p_reserve_exact (void *vec, int reserve MEM_STAT_DECL) +{ + return vec_gc_o_reserve_1 (vec, reserve, + offsetof (struct vec_prefix, vec), + sizeof (void *), true + PASS_MEM_STAT); +} + +/* As for vec_gc_p_reserve, but for object vectors. The vector's + trailing array is at VEC_OFFSET offset and consists of ELT_SIZE + sized elements. */ + +void * +vec_gc_o_reserve (void *vec, int reserve, size_t vec_offset, size_t elt_size + MEM_STAT_DECL) +{ + return vec_gc_o_reserve_1 (vec, reserve, vec_offset, elt_size, false + PASS_MEM_STAT); +} + +/* As for vec_gc_p_reserve_exact, but for object vectors. The + vector's trailing array is at VEC_OFFSET offset and consists of + ELT_SIZE sized elements. */ + +void * +vec_gc_o_reserve_exact (void *vec, int reserve, size_t vec_offset, + size_t elt_size MEM_STAT_DECL) +{ + return vec_gc_o_reserve_1 (vec, reserve, vec_offset, elt_size, true + PASS_MEM_STAT); +} + +/* As for vec_gc_o_reserve_1, but for heap allocated vectors. */ + +static void * +vec_heap_o_reserve_1 (void *vec, int reserve, size_t vec_offset, + size_t elt_size, bool exact MEM_STAT_DECL) +{ + struct vec_prefix *pfx = vec; + unsigned alloc = calculate_allocation (pfx, reserve, exact); + + if (!alloc) + return NULL; + + vec = xrealloc (vec, vec_offset + alloc * elt_size); + ((struct vec_prefix *)vec)->alloc = alloc; + if (!pfx) + ((struct vec_prefix *)vec)->num = 0; + + return vec; +} + +/* As for vec_gc_p_reserve, but for heap allocated vectors. */ + +void * +vec_heap_p_reserve (void *vec, int reserve MEM_STAT_DECL) +{ + return vec_heap_o_reserve_1 (vec, reserve, + offsetof (struct vec_prefix, vec), + sizeof (void *), false + PASS_MEM_STAT); +} + +/* As for vec_gc_p_reserve_exact, but for heap allocated vectors. */ + +void * +vec_heap_p_reserve_exact (void *vec, int reserve MEM_STAT_DECL) +{ + return vec_heap_o_reserve_1 (vec, reserve, + offsetof (struct vec_prefix, vec), + sizeof (void *), true + PASS_MEM_STAT); +} + +/* As for vec_gc_o_reserve, but for heap allocated vectors. */ + +void * +vec_heap_o_reserve (void *vec, int reserve, size_t vec_offset, size_t elt_size + MEM_STAT_DECL) +{ + return vec_heap_o_reserve_1 (vec, reserve, vec_offset, elt_size, false + PASS_MEM_STAT); +} + +/* As for vec_gc_o_reserve_exact, but for heap allocated vectors. */ + +void * +vec_heap_o_reserve_exact (void *vec, int reserve, size_t vec_offset, + size_t elt_size MEM_STAT_DECL) +{ + return vec_heap_o_reserve_1 (vec, reserve, vec_offset, elt_size, true + PASS_MEM_STAT); +} + +/* APPLE LOCAL begin vec checking */ +/* necessary for apple fat builds as we use vec in genautomata and + genextract on the host, and these two use auto-build.h to enable + build checking because we configured it in build_gcc, but vec.c is + built without checking as we don't want to slowdown release-style + builds. */ +void vec_assert_fail (const char *, const char *, + const char *, unsigned int, const char *); +#undef ENABLE_CHECKING +#define ENABLE_CHECKING 1 +/* APPLE LOCAL end vec checking, necessary for apple fat builds */ + +#if ENABLE_CHECKING +/* Issue a vector domain error, and then fall over. */ + +void +vec_assert_fail (const char *op, const char *struct_name, + const char *file, unsigned int line, const char *function) +{ + internal_error ("vector %s %s domain error, in %s at %s:%u", + struct_name, op, function, trim_filename (file), line); +} +#endif |