00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifdef GENERATOR_FILE
00026 #include "bconfig.h"
00027 #else
00028 #include "config.h"
00029 #endif
00030
00031 #include "system.h"
00032 #include "coretypes.h"
00033 #include "tm.h"
00034 #include "errors.h"
00035 #include "varray.h"
00036 #include "ggc.h"
00037 #include "hashtab.h"
00038
00039 #define VARRAY_HDR_SIZE (sizeof (struct varray_head_tag) - sizeof (varray_data))
00040
00041 #ifdef GATHER_STATISTICS
00042
00043
00044 struct varray_descriptor
00045 {
00046 const char *name;
00047 int allocated;
00048 int created;
00049 int resized;
00050 int copied;
00051 };
00052
00053
00054 static htab_t varray_hash;
00055
00056
00057 static hashval_t
00058 hash_descriptor (const void *p)
00059 {
00060 const struct varray_descriptor *d = p;
00061 return htab_hash_pointer (d->name);
00062 }
00063 static int
00064 eq_descriptor (const void *p1, const void *p2)
00065 {
00066 const struct varray_descriptor *d = p1;
00067 return d->name == p2;
00068 }
00069
00070
00071 static struct varray_descriptor *
00072 varray_descriptor (const char *name)
00073 {
00074 struct varray_descriptor **slot;
00075
00076 if (!varray_hash)
00077 varray_hash = htab_create (10, hash_descriptor, eq_descriptor, NULL);
00078
00079 slot = (struct varray_descriptor **)
00080 htab_find_slot_with_hash (varray_hash, name,
00081 htab_hash_pointer (name),
00082 1);
00083 if (*slot)
00084 return *slot;
00085 *slot = xcalloc (sizeof (**slot), 1);
00086 (*slot)->name = name;
00087 return *slot;
00088 }
00089 #endif
00090
00091
00092
00093
00094 static const struct {
00095 unsigned char size;
00096 bool uses_ggc;
00097 } element[NUM_VARRAY_DATA] = {
00098 { sizeof (char), 1 },
00099 { sizeof (unsigned char), 1 },
00100 { sizeof (short), 1 },
00101 { sizeof (unsigned short), 1 },
00102 { sizeof (int), 1 },
00103 { sizeof (unsigned int), 1 },
00104 { sizeof (long), 1 },
00105 { sizeof (unsigned long), 1 },
00106 { sizeof (HOST_WIDE_INT), 1 },
00107 { sizeof (unsigned HOST_WIDE_INT), 1 },
00108 { sizeof (void *), 1 },
00109 { sizeof (void *), 0 },
00110 { sizeof (char *), 1 },
00111 { sizeof (struct rtx_def *), 1 },
00112 { sizeof (struct rtvec_def *), 1 },
00113 { sizeof (union tree_node *), 1 },
00114 { sizeof (struct bitmap_head_def *), 1 },
00115 { sizeof (struct reg_info_def *), 0 },
00116 { sizeof (struct basic_block_def *), 1 },
00117 { sizeof (struct elt_list *), 1 },
00118 { sizeof (struct edge_def *), 1 },
00119 { sizeof (tree *), 1 },
00120 };
00121
00122
00123
00124 varray_type
00125 varray_init (size_t num_elements, enum varray_data_enum element_kind,
00126 const char *name)
00127 {
00128 size_t data_size = num_elements * element[element_kind].size;
00129 varray_type ptr;
00130 #ifdef GATHER_STATISTICS
00131 struct varray_descriptor *desc = varray_descriptor (name);
00132
00133 desc->created++;
00134 desc->allocated += data_size + VARRAY_HDR_SIZE;
00135 #endif
00136 if (element[element_kind].uses_ggc)
00137 ptr = ggc_alloc_cleared (VARRAY_HDR_SIZE + data_size);
00138 else
00139 ptr = xcalloc (VARRAY_HDR_SIZE + data_size, 1);
00140
00141 ptr->num_elements = num_elements;
00142 ptr->elements_used = 0;
00143 ptr->type = element_kind;
00144 ptr->name = name;
00145 return ptr;
00146 }
00147
00148
00149
00150 varray_type
00151 varray_grow (varray_type va, size_t n)
00152 {
00153 size_t old_elements = va->num_elements;
00154 if (n != old_elements)
00155 {
00156 size_t elem_size = element[va->type].size;
00157 size_t old_data_size = old_elements * elem_size;
00158 size_t data_size = n * elem_size;
00159 #ifdef GATHER_STATISTICS
00160 struct varray_descriptor *desc = varray_descriptor (va->name);
00161 varray_type oldva = va;
00162
00163 if (data_size > old_data_size)
00164 desc->allocated += data_size - old_data_size;
00165 desc->resized ++;
00166 #endif
00167
00168
00169 if (element[va->type].uses_ggc)
00170 va = ggc_realloc (va, VARRAY_HDR_SIZE + data_size);
00171 else
00172 va = xrealloc (va, VARRAY_HDR_SIZE + data_size);
00173 va->num_elements = n;
00174 if (n > old_elements)
00175 memset (&va->data.c[old_data_size], 0, data_size - old_data_size);
00176 #ifdef GATHER_STATISTICS
00177 if (oldva != va)
00178 desc->copied++;
00179 #endif
00180 }
00181
00182 return va;
00183 }
00184
00185
00186 void
00187 varray_clear (varray_type va)
00188 {
00189 size_t data_size = element[va->type].size * va->num_elements;
00190
00191 memset (va->data.c, 0, data_size);
00192 va->elements_used = 0;
00193 }
00194
00195
00196
00197 #if defined ENABLE_CHECKING && (GCC_VERSION >= 2007)
00198
00199 void
00200 varray_check_failed (varray_type va, size_t n, const char *file, int line,
00201 const char *function)
00202 {
00203 internal_error ("virtual array %s[%lu]: element %lu out of bounds "
00204 "in %s, at %s:%d",
00205 va->name, (unsigned long) va->num_elements, (unsigned long) n,
00206 function, trim_filename (file), line);
00207 }
00208
00209 void
00210 varray_underflow (varray_type va, const char *file, int line,
00211 const char *function)
00212 {
00213 internal_error ("underflowed virtual array %s in %s, at %s:%d",
00214 va->name, function, trim_filename (file), line);
00215 }
00216
00217 #endif
00218
00219
00220
00221 #ifdef GATHER_STATISTICS
00222
00223
00224 struct output_info
00225 {
00226 int count;
00227 int size;
00228 };
00229
00230
00231
00232 static int
00233 print_statistics (void **slot, void *b)
00234 {
00235 struct varray_descriptor *d = (struct varray_descriptor *) *slot;
00236 struct output_info *i = (struct output_info *) b;
00237
00238 if (d->allocated)
00239 {
00240 fprintf (stderr, "%-21s %6d %10d %7d %7d\n", d->name,
00241 d->created, d->allocated, d->resized, d->copied);
00242 i->size += d->allocated;
00243 i->count += d->created;
00244 }
00245 return 1;
00246 }
00247 #endif
00248
00249
00250 void dump_varray_statistics (void)
00251 {
00252 #ifdef GATHER_STATISTICS
00253 struct output_info info;
00254
00255 fprintf (stderr, "\nVARRAY Kind Count Bytes Resized copied\n");
00256 fprintf (stderr, "-------------------------------------------------------\n");
00257 info.count = 0;
00258 info.size = 0;
00259 htab_traverse (varray_hash, print_statistics, &info);
00260 fprintf (stderr, "-------------------------------------------------------\n");
00261 fprintf (stderr, "%-20s %7d %10d\n",
00262 "Total", info.count, info.size);
00263 fprintf (stderr, "-------------------------------------------------------\n");
00264 #endif
00265 }