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