gdb - Local mods (compile)
[dragonfly.git] / contrib / gcc-5.0 / gcc / tree-streamer.c
1 /* Miscellaneous utilities for tree streaming.  Things that are used
2    in both input and output are here.
3
4    Copyright (C) 2011-2015 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 "hash-set.h"
27 #include "machmode.h"
28 #include "vec.h"
29 #include "double-int.h"
30 #include "input.h"
31 #include "alias.h"
32 #include "symtab.h"
33 #include "options.h"
34 #include "wide-int.h"
35 #include "inchash.h"
36 #include "tree.h"
37 #include "fold-const.h"
38 #include "predict.h"
39 #include "tm.h"
40 #include "hard-reg-set.h"
41 #include "input.h"
42 #include "function.h"
43 #include "basic-block.h"
44 #include "tree-ssa-alias.h"
45 #include "internal-fn.h"
46 #include "gimple-expr.h"
47 #include "hash-map.h"
48 #include "is-a.h"
49 #include "gimple.h"
50 #include "streamer-hooks.h"
51 #include "plugin-api.h"
52 #include "ipa-ref.h"
53 #include "cgraph.h"
54 #include "tree-streamer.h"
55
56 /* Table indexed by machine_mode, used for 2 different purposes.
57    During streaming out we record there non-zero value for all modes
58    that were streamed out.
59    During streaming in, we translate the on the disk mode using this
60    table.  For normal LTO it is set to identity, for ACCEL_COMPILER
61    depending on the mode_table content.  */
62 unsigned char streamer_mode_table[1 << 8];
63
64 /* Check that all the TS_* structures handled by the streamer_write_* and
65    streamer_read_* routines are exactly ALL the structures defined in
66    treestruct.def.  */
67
68 void
69 streamer_check_handled_ts_structures (void)
70 {
71   bool handled_p[LAST_TS_ENUM];
72   unsigned i;
73
74   memset (&handled_p, 0, sizeof (handled_p));
75
76   /* These are the TS_* structures that are either handled or
77      explicitly ignored by the streamer routines.  */
78   handled_p[TS_BASE] = true;
79   handled_p[TS_TYPED] = true;
80   handled_p[TS_COMMON] = true;
81   handled_p[TS_INT_CST] = true;
82   handled_p[TS_REAL_CST] = true;
83   handled_p[TS_FIXED_CST] = true;
84   handled_p[TS_VECTOR] = true;
85   handled_p[TS_STRING] = true;
86   handled_p[TS_COMPLEX] = true;
87   handled_p[TS_IDENTIFIER] = true;
88   handled_p[TS_DECL_MINIMAL] = true;
89   handled_p[TS_DECL_COMMON] = true;
90   handled_p[TS_DECL_WRTL] = true;
91   handled_p[TS_DECL_NON_COMMON] = true;
92   handled_p[TS_DECL_WITH_VIS] = true;
93   handled_p[TS_FIELD_DECL] = true;
94   handled_p[TS_VAR_DECL] = true;
95   handled_p[TS_PARM_DECL] = true;
96   handled_p[TS_LABEL_DECL] = true;
97   handled_p[TS_RESULT_DECL] = true;
98   handled_p[TS_CONST_DECL] = true;
99   handled_p[TS_TYPE_DECL] = true;
100   handled_p[TS_FUNCTION_DECL] = true;
101   handled_p[TS_TYPE_COMMON] = true;
102   handled_p[TS_TYPE_WITH_LANG_SPECIFIC] = true;
103   handled_p[TS_TYPE_NON_COMMON] = true;
104   handled_p[TS_LIST] = true;
105   handled_p[TS_VEC] = true;
106   handled_p[TS_EXP] = true;
107   handled_p[TS_SSA_NAME] = true;
108   handled_p[TS_BLOCK] = true;
109   handled_p[TS_BINFO] = true;
110   handled_p[TS_STATEMENT_LIST] = true;
111   handled_p[TS_CONSTRUCTOR] = true;
112   handled_p[TS_OMP_CLAUSE] = true;
113   handled_p[TS_OPTIMIZATION] = true;
114   handled_p[TS_TARGET_OPTION] = true;
115   handled_p[TS_TRANSLATION_UNIT_DECL] = true;
116
117   /* Anything not marked above will trigger the following assertion.
118      If this assertion triggers, it means that there is a new TS_*
119      structure that should be handled by the streamer.  */
120   for (i = 0; i < LAST_TS_ENUM; i++)
121     gcc_assert (handled_p[i]);
122 }
123
124
125 /* Helper for streamer_tree_cache_insert_1.  Add T to CACHE->NODES at
126    slot IX.  */
127
128 static void
129 streamer_tree_cache_add_to_node_array (struct streamer_tree_cache_d *cache,
130                                        unsigned ix, tree t, hashval_t hash)
131 {
132   /* We're either replacing an old element or appending consecutively.  */
133   if (cache->nodes.exists ())
134     {
135       if (cache->nodes.length () == ix)
136         cache->nodes.safe_push (t);
137       else
138         cache->nodes[ix] = t;
139     }
140   if (cache->hashes.exists ())
141     {
142       if (cache->hashes.length () == ix)
143         cache->hashes.safe_push (hash);
144       else
145         cache->hashes[ix] = hash;
146     }
147 }
148
149
150 /* Helper for streamer_tree_cache_insert and streamer_tree_cache_insert_at.
151    CACHE, T, and IX_P are as in streamer_tree_cache_insert.
152
153    If INSERT_AT_NEXT_SLOT_P is true, T is inserted at the next available
154    slot in the cache.  Otherwise, T is inserted at the position indicated
155    in *IX_P.
156
157    If T already existed in CACHE, return true.  Otherwise,
158    return false.  */
159
160 static bool
161 streamer_tree_cache_insert_1 (struct streamer_tree_cache_d *cache,
162                               tree t, hashval_t hash, unsigned *ix_p,
163                               bool insert_at_next_slot_p)
164 {
165   bool existed_p;
166
167   gcc_assert (t);
168
169   unsigned int &ix = cache->node_map->get_or_insert (t, &existed_p);
170   if (!existed_p)
171     {
172       /* Determine the next slot to use in the cache.  */
173       if (insert_at_next_slot_p)
174         ix = cache->next_idx++;
175       else
176         ix = *ix_p;
177
178       streamer_tree_cache_add_to_node_array (cache, ix, t, hash);
179     }
180   else
181     {
182       if (!insert_at_next_slot_p && ix != *ix_p)
183         {
184           /* If the caller wants to insert T at a specific slot
185              location, and ENTRY->TO does not match *IX_P, add T to
186              the requested location slot.  */
187           ix = *ix_p;
188           streamer_tree_cache_add_to_node_array (cache, ix, t, hash);
189         }
190     }
191
192   if (ix_p)
193     *ix_p = ix;
194
195   return existed_p;
196 }
197
198
199 /* Insert tree node T in CACHE.  If T already existed in the cache
200    return true.  Otherwise, return false.
201
202    If IX_P is non-null, update it with the index into the cache where
203    T has been stored.  */
204
205 bool
206 streamer_tree_cache_insert (struct streamer_tree_cache_d *cache, tree t,
207                             hashval_t hash, unsigned *ix_p)
208 {
209   return streamer_tree_cache_insert_1 (cache, t, hash, ix_p, true);
210 }
211
212
213 /* Replace the tree node with T in CACHE at slot IX.  */
214
215 void
216 streamer_tree_cache_replace_tree (struct streamer_tree_cache_d *cache,
217                                   tree t, unsigned ix)
218 {
219   hashval_t hash = 0;
220   if (cache->hashes.exists ())
221     hash = streamer_tree_cache_get_hash (cache, ix);
222   if (!cache->node_map)
223     streamer_tree_cache_add_to_node_array (cache, ix, t, hash);
224   else
225     streamer_tree_cache_insert_1 (cache, t, hash, &ix, false);
226 }
227
228
229 /* Appends tree node T to CACHE, even if T already existed in it.  */
230
231 void
232 streamer_tree_cache_append (struct streamer_tree_cache_d *cache,
233                             tree t, hashval_t hash)
234 {
235   unsigned ix = cache->next_idx++;
236   if (!cache->node_map)
237     streamer_tree_cache_add_to_node_array (cache, ix, t, hash);
238   else
239     streamer_tree_cache_insert_1 (cache, t, hash, &ix, false);
240 }
241
242 /* Return true if tree node T exists in CACHE, otherwise false.  If IX_P is
243    not NULL, write to *IX_P the index into the cache where T is stored
244    ((unsigned)-1 if T is not found).  */
245
246 bool
247 streamer_tree_cache_lookup (struct streamer_tree_cache_d *cache, tree t,
248                             unsigned *ix_p)
249 {
250   unsigned *slot;
251   bool retval;
252   unsigned ix;
253
254   gcc_assert (t);
255
256   slot = cache->node_map->get (t);
257   if (slot == NULL)
258     {
259       retval = false;
260       ix = -1;
261     }
262   else
263     {
264       retval = true;
265       ix = *slot;
266     }
267
268   if (ix_p)
269     *ix_p = ix;
270
271   return retval;
272 }
273
274
275 /* Record NODE in CACHE.  */
276
277 static void
278 record_common_node (struct streamer_tree_cache_d *cache, tree node)
279 {
280   /* If we recursively end up at nodes we do not want to preload simply don't.
281      ???  We'd want to verify that this doesn't happen, or alternatively
282      do not recurse at all.  */
283   if (node == char_type_node)
284     return;
285
286   gcc_checking_assert (node != boolean_type_node
287                        && node != boolean_true_node
288                        && node != boolean_false_node);
289
290   /* We have to make sure to fill exactly the same number of
291      elements for all frontends.  That can include NULL trees.
292      As our hash table can't deal with zero entries we'll simply stream
293      a random other tree.  A NULL tree never will be looked up so it
294      doesn't matter which tree we replace it with, just to be sure
295      use error_mark_node.  */
296   if (!node)
297     node = error_mark_node;
298
299   /* ???  FIXME, devise a better hash value.  But the hash needs to be equal
300      for all frontend and lto1 invocations.  So just use the position
301      in the cache as hash value.  */
302   streamer_tree_cache_append (cache, node, cache->nodes.length ());
303
304   if (POINTER_TYPE_P (node)
305       || TREE_CODE (node) == COMPLEX_TYPE
306       || TREE_CODE (node) == ARRAY_TYPE)
307     record_common_node (cache, TREE_TYPE (node));
308   else if (TREE_CODE (node) == RECORD_TYPE)
309     {
310       /* The FIELD_DECLs of structures should be shared, so that every
311          COMPONENT_REF uses the same tree node when referencing a field.
312          Pointer equality between FIELD_DECLs is used by the alias
313          machinery to compute overlapping component references (see
314          nonoverlapping_component_refs_p and
315          nonoverlapping_component_refs_of_decl_p).  */
316       for (tree f = TYPE_FIELDS (node); f; f = TREE_CHAIN (f))
317         record_common_node (cache, f);
318     }
319 }
320
321
322 /* Preload common nodes into CACHE and make sure they are merged
323    properly according to the gimple type table.  */
324
325 static void
326 preload_common_nodes (struct streamer_tree_cache_d *cache)
327 {
328   unsigned i;
329
330   for (i = 0; i < itk_none; i++)
331     /* Skip itk_char.  char_type_node is dependent on -f[un]signed-char.  */
332     if (i != itk_char)
333       record_common_node (cache, integer_types[i]);
334
335   for (i = 0; i < stk_type_kind_last; i++)
336     record_common_node (cache, sizetype_tab[i]);
337
338   for (i = 0; i < TI_MAX; i++)
339     /* Skip boolean type and constants, they are frontend dependent.  */
340     if (i != TI_BOOLEAN_TYPE
341         && i != TI_BOOLEAN_FALSE
342         && i != TI_BOOLEAN_TRUE
343         /* MAIN_IDENTIFIER is not always initialized by Fortran FE.  */
344         && i != TI_MAIN_IDENTIFIER
345         /* PID_TYPE is initialized only by C family front-ends.  */
346         && i != TI_PID_TYPE
347         /* Skip optimization and target option nodes; they depend on flags.  */
348         && i != TI_OPTIMIZATION_DEFAULT
349         && i != TI_OPTIMIZATION_CURRENT
350         && i != TI_TARGET_OPTION_DEFAULT
351         && i != TI_TARGET_OPTION_CURRENT
352         && i != TI_CURRENT_TARGET_PRAGMA
353         && i != TI_CURRENT_OPTIMIZE_PRAGMA
354         /* Skip va_list* related nodes if offloading.  For native LTO
355            we want them to be merged for the stdarg pass, for offloading
356            they might not be identical between host and offloading target.  */
357         && (!lto_stream_offload_p
358             || (i != TI_VA_LIST_TYPE
359                 && i != TI_VA_LIST_GPR_COUNTER_FIELD
360                 && i != TI_VA_LIST_FPR_COUNTER_FIELD)))
361       record_common_node (cache, global_trees[i]);
362 }
363
364
365 /* Create a cache of pickled nodes.  */
366
367 struct streamer_tree_cache_d *
368 streamer_tree_cache_create (bool with_hashes, bool with_map, bool with_vec)
369 {
370   struct streamer_tree_cache_d *cache;
371
372   cache = XCNEW (struct streamer_tree_cache_d);
373
374   if (with_map)
375     cache->node_map = new hash_map<tree, unsigned> (251);
376   cache->next_idx = 0;
377   if (with_vec)
378     cache->nodes.create (165);
379   if (with_hashes)
380     cache->hashes.create (165);
381
382   /* Load all the well-known tree nodes that are always created by
383      the compiler on startup.  This prevents writing them out
384      unnecessarily.  */
385   preload_common_nodes (cache);
386
387   return cache;
388 }
389
390
391 /* Delete the streamer cache C.  */
392
393 void
394 streamer_tree_cache_delete (struct streamer_tree_cache_d *c)
395 {
396   if (c == NULL)
397     return;
398
399   delete c->node_map;
400   c->node_map = NULL;
401   c->nodes.release ();
402   c->hashes.release ();
403   free (c);
404 }