OSDN Git Service

* reorg.c (mostly_true_jump): Clean up code depending on
[pf3gnuchains/gcc-fork.git] / gcc / varray.c
1 /* Virtual array support.
2    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004
3    Free Software Foundation, Inc.
4    Contributed by Cygnus Solutions.
5
6    This file is part of GCC.
7
8    GCC is free software; you can redistribute it and/or modify it
9    under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2, or (at your option)
11    any later version.
12
13    GCC is distributed in the hope that it will be useful, but WITHOUT
14    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
16    License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with GCC; see the file COPYING.  If not, write to the Free
20    the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
21    MA 02110-1301, USA.  */
22
23 /* This file is compiled twice: once for the generator programs
24    once for the compiler.  */
25 #ifdef GENERATOR_FILE
26 #include "bconfig.h"
27 #else
28 #include "config.h"
29 #endif
30
31 #include "system.h"
32 #include "coretypes.h"
33 #include "tm.h"
34 #ifdef GENERATOR_FILE
35 # include "errors.h"
36 #else
37 # include "toplev.h"
38 #endif
39 #include "varray.h"
40 #include "ggc.h"
41 #include "hashtab.h"
42
43 #define VARRAY_HDR_SIZE (sizeof (struct varray_head_tag) - sizeof (varray_data))
44
45 #ifdef GATHER_STATISTICS
46
47 /* Store information about each particular varray.  */
48 struct varray_descriptor
49 {
50   const char *name;
51   int allocated;
52   int created;
53   int resized;
54   int copied;
55 };
56
57 /* Hashtable mapping varray names to descriptors.  */
58 static htab_t varray_hash;
59
60 /* Hashtable helpers.  */
61 static hashval_t
62 hash_descriptor (const void *p)
63 {
64   const struct varray_descriptor *d = p;
65   return htab_hash_pointer (d->name);
66 }
67 static int
68 eq_descriptor (const void *p1, const void *p2)
69 {
70   const struct varray_descriptor *d = p1;
71   return d->name == p2;
72 }
73
74 /* For given name, return descriptor, create new if needed.  */
75 static struct varray_descriptor *
76 varray_descriptor (const char *name)
77 {
78   struct varray_descriptor **slot;
79
80   if (!varray_hash)
81     varray_hash = htab_create (10, hash_descriptor, eq_descriptor, NULL);
82
83   slot = (struct varray_descriptor **)
84     htab_find_slot_with_hash (varray_hash, name,
85                               htab_hash_pointer (name),
86                               1);
87   if (*slot)
88     return *slot;
89   *slot = xcalloc (sizeof (**slot), 1);
90   (*slot)->name = name;
91   return *slot;
92 }
93 #endif
94
95 /* Do not add any more non-GC items here.  Please either remove or GC
96    those items that are not GCed.  */
97
98 static const struct {
99   unsigned char size;
100   bool uses_ggc;
101 } element[NUM_VARRAY_DATA] = {
102   { sizeof (char), 1 },
103   { sizeof (unsigned char), 1 },
104   { sizeof (short), 1 },
105   { sizeof (unsigned short), 1 },
106   { sizeof (int), 1 },
107   { sizeof (unsigned int), 1 },
108   { sizeof (long), 1 },
109   { sizeof (unsigned long), 1 },
110   { sizeof (HOST_WIDE_INT), 1 },
111   { sizeof (unsigned HOST_WIDE_INT), 1 },
112   { sizeof (void *), 1 },
113   { sizeof (void *), 0 },
114   { sizeof (char *), 1 },
115   { sizeof (struct rtx_def *), 1 },
116   { sizeof (struct rtvec_def *), 1 },
117   { sizeof (union tree_node *), 1 },
118   { sizeof (struct bitmap_head_def *), 1 },
119   { sizeof (struct reg_info_def *), 0 },
120   { sizeof (struct basic_block_def *), 1 },
121   { sizeof (struct elt_list *), 1 },
122   { sizeof (struct edge_def *), 1 },
123   { sizeof (tree *), 1 },
124 };
125
126 /* Allocate a virtual array with NUM_ELEMENT elements, each of which is
127    ELEMENT_SIZE bytes long, named NAME.  Array elements are zeroed.  */
128 varray_type
129 varray_init (size_t num_elements, enum varray_data_enum element_kind,
130              const char *name)
131 {
132   size_t data_size = num_elements * element[element_kind].size;
133   varray_type ptr;
134 #ifdef GATHER_STATISTICS
135   struct varray_descriptor *desc = varray_descriptor (name);
136
137   desc->created++;
138   desc->allocated += data_size + VARRAY_HDR_SIZE;
139 #endif
140   if (element[element_kind].uses_ggc)
141     ptr = ggc_alloc_cleared (VARRAY_HDR_SIZE + data_size);
142   else
143     ptr = xcalloc (VARRAY_HDR_SIZE + data_size, 1);
144
145   ptr->num_elements = num_elements;
146   ptr->elements_used = 0;
147   ptr->type = element_kind;
148   ptr->name = name;
149   return ptr;
150 }
151
152 /* Grow/shrink the virtual array VA to N elements.  Zero any new elements
153    allocated.  */
154 varray_type
155 varray_grow (varray_type va, size_t n)
156 {
157   size_t old_elements = va->num_elements;
158   if (n != old_elements)
159     {
160       size_t elem_size = element[va->type].size;
161       size_t old_data_size = old_elements * elem_size;
162       size_t data_size = n * elem_size;
163 #ifdef GATHER_STATISTICS
164       struct varray_descriptor *desc = varray_descriptor (va->name);
165       varray_type oldva = va;
166
167       if (data_size > old_data_size)
168         desc->allocated += data_size - old_data_size;
169       desc->resized ++;
170 #endif
171
172
173       if (element[va->type].uses_ggc)
174         va = ggc_realloc (va, VARRAY_HDR_SIZE + data_size);
175       else
176         va = xrealloc (va, VARRAY_HDR_SIZE + data_size);
177       va->num_elements = n;
178       if (n > old_elements)
179         memset (&va->data.vdt_c[old_data_size], 0, data_size - old_data_size);
180 #ifdef GATHER_STATISTICS
181       if (oldva != va)
182         desc->copied++;
183 #endif
184     }
185
186   return va;
187 }
188
189 /* Reset a varray to its original state.  */
190 void
191 varray_clear (varray_type va)
192 {
193   size_t data_size = element[va->type].size * va->num_elements;
194
195   memset (va->data.vdt_c, 0, data_size);
196   va->elements_used = 0;
197 }
198
199 /* Check the bounds of a varray access.  */
200
201 #if defined ENABLE_CHECKING && (GCC_VERSION >= 2007)
202
203 void
204 varray_check_failed (varray_type va, size_t n, const char *file, int line,
205                      const char *function)
206 {
207   internal_error ("virtual array %s[%lu]: element %lu out of bounds "
208                   "in %s, at %s:%d",
209                   va->name, (unsigned long) va->num_elements, (unsigned long) n,
210                   function, trim_filename (file), line);
211 }
212
213 void
214 varray_underflow (varray_type va, const char *file, int line,
215                   const char *function)
216 {
217   internal_error ("underflowed virtual array %s in %s, at %s:%d",
218                   va->name, function, trim_filename (file), line);
219 }
220
221 #endif
222
223
224 /* Output per-varray statistics.  */
225 #ifdef GATHER_STATISTICS
226
227 /* Used to accumulate statistics about varray sizes.  */
228 struct output_info
229 {
230   int count;
231   int size;
232 };
233
234 /* Called via htab_traverse.  Output varray descriptor pointed out by SLOT
235    and update statistics.  */
236 static int
237 print_statistics (void **slot, void *b)
238 {
239   struct varray_descriptor *d = (struct varray_descriptor *) *slot;
240   struct output_info *i = (struct output_info *) b;
241
242   if (d->allocated)
243     {
244       fprintf (stderr, "%-21s %6d %10d %7d %7d\n", d->name,
245                d->created, d->allocated, d->resized, d->copied);
246       i->size += d->allocated;
247       i->count += d->created;
248     }
249   return 1;
250 }
251 #endif
252
253 /* Output per-varray memory usage statistics.  */
254 void dump_varray_statistics (void)
255 {
256 #ifdef GATHER_STATISTICS
257   struct output_info info;
258
259   fprintf (stderr, "\nVARRAY Kind            Count      Bytes  Resized copied\n");
260   fprintf (stderr, "-------------------------------------------------------\n");
261   info.count = 0;
262   info.size = 0;
263   htab_traverse (varray_hash, print_statistics, &info);
264   fprintf (stderr, "-------------------------------------------------------\n");
265   fprintf (stderr, "%-20s %7d %10d\n",
266            "Total", info.count, info.size);
267   fprintf (stderr, "-------------------------------------------------------\n");
268 #endif
269 }