OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [tree-streamer.c] - Blame information for rev 745

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 684 jeremybenn
/* Miscellaneous utilities for tree streaming.  Things that are used
2
   in both input and output are here.
3
 
4
   Copyright 2011 Free Software Foundation, Inc.
5
   Contributed by Diego Novillo <dnovillo@google.com>
6
 
7
This file is part of GCC.
8
 
9
GCC is free software; you can redistribute it and/or modify it under
10
the terms of the GNU General Public License as published by the Free
11
Software Foundation; either version 3, or (at your option) any later
12
version.
13
 
14
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15
WARRANTY; without even the implied warranty of MERCHANTABILITY or
16
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17
for more details.
18
 
19
You should have received a copy of the GNU General Public License
20
along with GCC; see the file COPYING3.  If not see
21
<http://www.gnu.org/licenses/>.  */
22
 
23
#include "config.h"
24
#include "system.h"
25
#include "coretypes.h"
26
#include "streamer-hooks.h"
27
#include "tree-streamer.h"
28
 
29
/* Check that all the TS_* structures handled by the streamer_write_* and
30
   streamer_read_* routines are exactly ALL the structures defined in
31
   treestruct.def.  */
32
 
33
void
34
streamer_check_handled_ts_structures (void)
35
{
36
  bool handled_p[LAST_TS_ENUM];
37
  unsigned i;
38
 
39
  memset (&handled_p, 0, sizeof (handled_p));
40
 
41
  /* These are the TS_* structures that are either handled or
42
     explicitly ignored by the streamer routines.  */
43
  handled_p[TS_BASE] = true;
44
  handled_p[TS_TYPED] = true;
45
  handled_p[TS_COMMON] = true;
46
  handled_p[TS_INT_CST] = true;
47
  handled_p[TS_REAL_CST] = true;
48
  handled_p[TS_FIXED_CST] = true;
49
  handled_p[TS_VECTOR] = true;
50
  handled_p[TS_STRING] = true;
51
  handled_p[TS_COMPLEX] = true;
52
  handled_p[TS_IDENTIFIER] = true;
53
  handled_p[TS_DECL_MINIMAL] = true;
54
  handled_p[TS_DECL_COMMON] = true;
55
  handled_p[TS_DECL_WRTL] = true;
56
  handled_p[TS_DECL_NON_COMMON] = true;
57
  handled_p[TS_DECL_WITH_VIS] = true;
58
  handled_p[TS_FIELD_DECL] = true;
59
  handled_p[TS_VAR_DECL] = true;
60
  handled_p[TS_PARM_DECL] = true;
61
  handled_p[TS_LABEL_DECL] = true;
62
  handled_p[TS_RESULT_DECL] = true;
63
  handled_p[TS_CONST_DECL] = true;
64
  handled_p[TS_TYPE_DECL] = true;
65
  handled_p[TS_FUNCTION_DECL] = true;
66
  handled_p[TS_TYPE_COMMON] = true;
67
  handled_p[TS_TYPE_WITH_LANG_SPECIFIC] = true;
68
  handled_p[TS_TYPE_NON_COMMON] = true;
69
  handled_p[TS_LIST] = true;
70
  handled_p[TS_VEC] = true;
71
  handled_p[TS_EXP] = true;
72
  handled_p[TS_SSA_NAME] = true;
73
  handled_p[TS_BLOCK] = true;
74
  handled_p[TS_BINFO] = true;
75
  handled_p[TS_STATEMENT_LIST] = true;
76
  handled_p[TS_CONSTRUCTOR] = true;
77
  handled_p[TS_OMP_CLAUSE] = true;
78
  handled_p[TS_OPTIMIZATION] = true;
79
  handled_p[TS_TARGET_OPTION] = true;
80
  handled_p[TS_TRANSLATION_UNIT_DECL] = true;
81
 
82
  /* Anything not marked above will trigger the following assertion.
83
     If this assertion triggers, it means that there is a new TS_*
84
     structure that should be handled by the streamer.  */
85
  for (i = 0; i < LAST_TS_ENUM; i++)
86
    gcc_assert (handled_p[i]);
87
}
88
 
89
 
90
/* Helper for streamer_tree_cache_insert_1.  Add T to CACHE->NODES at
91
   slot IX.  */
92
 
93
static void
94
streamer_tree_cache_add_to_node_array (struct streamer_tree_cache_d *cache,
95
                                       unsigned ix, tree t)
96
{
97
  /* Make sure we're either replacing an old element or
98
     appending consecutively.  */
99
  gcc_assert (ix <= VEC_length (tree, cache->nodes));
100
 
101
  if (ix == VEC_length (tree, cache->nodes))
102
    VEC_safe_push (tree, heap, cache->nodes, t);
103
  else
104
    VEC_replace (tree, cache->nodes, ix, t);
105
}
106
 
107
 
108
/* Helper for streamer_tree_cache_insert and streamer_tree_cache_insert_at.
109
   CACHE, T, and IX_P are as in streamer_tree_cache_insert.
110
 
111
   If INSERT_AT_NEXT_SLOT_P is true, T is inserted at the next available
112
   slot in the cache.  Otherwise, T is inserted at the position indicated
113
   in *IX_P.
114
 
115
   If T already existed in CACHE, return true.  Otherwise,
116
   return false.  */
117
 
118
static bool
119
streamer_tree_cache_insert_1 (struct streamer_tree_cache_d *cache,
120
                              tree t, unsigned *ix_p,
121
                              bool insert_at_next_slot_p)
122
{
123
  void **slot;
124
  unsigned ix;
125
  bool existed_p;
126
 
127
  gcc_assert (t);
128
 
129
  slot = pointer_map_insert (cache->node_map, t);
130
  if (!*slot)
131
    {
132
      /* Determine the next slot to use in the cache.  */
133
      if (insert_at_next_slot_p)
134
        ix = VEC_length (tree, cache->nodes);
135
      else
136
        ix = *ix_p;
137
       *slot = (void *)(size_t) (ix + 1);
138
 
139
      streamer_tree_cache_add_to_node_array (cache, ix, t);
140
 
141
      /* Indicate that the item was not present in the cache.  */
142
      existed_p = false;
143
    }
144
  else
145
    {
146
      ix = (size_t) *slot - 1;
147
 
148
      if (!insert_at_next_slot_p && ix != *ix_p)
149
        {
150
          /* If the caller wants to insert T at a specific slot
151
             location, and ENTRY->TO does not match *IX_P, add T to
152
             the requested location slot.  */
153
          ix = *ix_p;
154
          streamer_tree_cache_add_to_node_array (cache, ix, t);
155
        }
156
 
157
      /* Indicate that T was already in the cache.  */
158
      existed_p = true;
159
    }
160
 
161
  if (ix_p)
162
    *ix_p = ix;
163
 
164
  return existed_p;
165
}
166
 
167
 
168
/* Insert tree node T in CACHE.  If T already existed in the cache
169
   return true.  Otherwise, return false.
170
 
171
   If IX_P is non-null, update it with the index into the cache where
172
   T has been stored.  */
173
 
174
bool
175
streamer_tree_cache_insert (struct streamer_tree_cache_d *cache, tree t,
176
                            unsigned *ix_p)
177
{
178
  return streamer_tree_cache_insert_1 (cache, t, ix_p, true);
179
}
180
 
181
 
182
/* Insert tree node T in CACHE at slot IX.  If T already
183
   existed in the cache return true.  Otherwise, return false.  */
184
 
185
bool
186
streamer_tree_cache_insert_at (struct streamer_tree_cache_d *cache,
187
                               tree t, unsigned ix)
188
{
189
  return streamer_tree_cache_insert_1 (cache, t, &ix, false);
190
}
191
 
192
 
193
/* Appends tree node T to CACHE, even if T already existed in it.  */
194
 
195
void
196
streamer_tree_cache_append (struct streamer_tree_cache_d *cache, tree t)
197
{
198
  unsigned ix = VEC_length (tree, cache->nodes);
199
  streamer_tree_cache_insert_1 (cache, t, &ix, false);
200
}
201
 
202
/* Return true if tree node T exists in CACHE, otherwise false.  If IX_P is
203
   not NULL, write to *IX_P the index into the cache where T is stored
204
   ((unsigned)-1 if T is not found).  */
205
 
206
bool
207
streamer_tree_cache_lookup (struct streamer_tree_cache_d *cache, tree t,
208
                            unsigned *ix_p)
209
{
210
  void **slot;
211
  bool retval;
212
  unsigned ix;
213
 
214
  gcc_assert (t);
215
 
216
  slot = pointer_map_contains  (cache->node_map, t);
217
  if (slot == NULL)
218
    {
219
      retval = false;
220
      ix = -1;
221
    }
222
  else
223
    {
224
      retval = true;
225
      ix = (size_t) *slot - 1;
226
    }
227
 
228
  if (ix_p)
229
    *ix_p = ix;
230
 
231
  return retval;
232
}
233
 
234
 
235
/* Return the tree node at slot IX in CACHE.  */
236
 
237
tree
238
streamer_tree_cache_get (struct streamer_tree_cache_d *cache, unsigned ix)
239
{
240
  gcc_assert (cache);
241
 
242
  /* Make sure we're not requesting something we don't have.  */
243
  gcc_assert (ix < VEC_length (tree, cache->nodes));
244
 
245
  return VEC_index (tree, cache->nodes, ix);
246
}
247
 
248
 
249
/* Record NODE in CACHE.  */
250
 
251
static void
252
record_common_node (struct streamer_tree_cache_d *cache, tree node)
253
{
254
  /* We have to make sure to fill exactly the same number of
255
     elements for all frontends.  That can include NULL trees.
256
     As our hash table can't deal with zero entries we'll simply stream
257
     a random other tree.  A NULL tree never will be looked up so it
258
     doesn't matter which tree we replace it with, just to be sure
259
     use error_mark_node.  */
260
  if (!node)
261
    node = error_mark_node;
262
 
263
  streamer_tree_cache_append (cache, node);
264
 
265
  if (POINTER_TYPE_P (node)
266
      || TREE_CODE (node) == COMPLEX_TYPE
267
      || TREE_CODE (node) == ARRAY_TYPE)
268
    record_common_node (cache, TREE_TYPE (node));
269
  else if (TREE_CODE (node) == RECORD_TYPE)
270
    {
271
      /* The FIELD_DECLs of structures should be shared, so that every
272
         COMPONENT_REF uses the same tree node when referencing a field.
273
         Pointer equality between FIELD_DECLs is used by the alias
274
         machinery to compute overlapping memory references (See
275
         nonoverlapping_component_refs_p).  */
276
      tree f;
277
      for (f = TYPE_FIELDS (node); f; f = TREE_CHAIN (f))
278
        record_common_node (cache, f);
279
    }
280
}
281
 
282
 
283
/* Preload common nodes into CACHE and make sure they are merged
284
   properly according to the gimple type table.  */
285
 
286
static void
287
preload_common_nodes (struct streamer_tree_cache_d *cache)
288
{
289
  unsigned i;
290
 
291
  for (i = 0; i < itk_none; i++)
292
    /* Skip itk_char.  char_type_node is dependent on -f[un]signed-char.  */
293
    if (i != itk_char)
294
      record_common_node (cache, integer_types[i]);
295
 
296
  for (i = 0; i < TYPE_KIND_LAST; i++)
297
    record_common_node (cache, sizetype_tab[i]);
298
 
299
  for (i = 0; i < TI_MAX; i++)
300
    /* Skip boolean type and constants, they are frontend dependent.  */
301
    if (i != TI_BOOLEAN_TYPE
302
        && i != TI_BOOLEAN_FALSE
303
        && i != TI_BOOLEAN_TRUE)
304
      record_common_node (cache, global_trees[i]);
305
}
306
 
307
 
308
/* Create a cache of pickled nodes.  */
309
 
310
struct streamer_tree_cache_d *
311
streamer_tree_cache_create (void)
312
{
313
  struct streamer_tree_cache_d *cache;
314
 
315
  cache = XCNEW (struct streamer_tree_cache_d);
316
 
317
  cache->node_map = pointer_map_create ();
318
 
319
  /* Load all the well-known tree nodes that are always created by
320
     the compiler on startup.  This prevents writing them out
321
     unnecessarily.  */
322
  preload_common_nodes (cache);
323
 
324
  return cache;
325
}
326
 
327
 
328
/* Delete the streamer cache C.  */
329
 
330
void
331
streamer_tree_cache_delete (struct streamer_tree_cache_d *c)
332
{
333
  if (c == NULL)
334
    return;
335
 
336
  pointer_map_destroy (c->node_map);
337
  VEC_free (tree, heap, c->nodes);
338
  free (c);
339
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.