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
7This file is part of GCC.
8
9GCC is free software; you can redistribute it and/or modify it under
10the terms of the GNU General Public License as published by the Free
11Software Foundation; either version 3, or (at your option) any later
12version.
13
14GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15WARRANTY; without even the implied warranty of MERCHANTABILITY or
16FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17for more details.
18
19You should have received a copy of the GNU General Public License
20along 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.  */
62unsigned 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
68void
69streamer_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
128static void
129streamer_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
160static bool
161streamer_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
205bool
206streamer_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
215void
216streamer_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
231void
232streamer_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
246bool
247streamer_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
277static void
278record_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
325static void
326preload_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
367struct streamer_tree_cache_d *
368streamer_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
393void
394streamer_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}
405