xref: /dflybsd-src/contrib/gcc-8.0/gcc/lto-streamer-in.c (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
1*38fd1498Szrj /* Read the GIMPLE representation from a file stream.
2*38fd1498Szrj 
3*38fd1498Szrj    Copyright (C) 2009-2018 Free Software Foundation, Inc.
4*38fd1498Szrj    Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
5*38fd1498Szrj    Re-implemented by Diego Novillo <dnovillo@google.com>
6*38fd1498Szrj 
7*38fd1498Szrj This file is part of GCC.
8*38fd1498Szrj 
9*38fd1498Szrj GCC is free software; you can redistribute it and/or modify it under
10*38fd1498Szrj the terms of the GNU General Public License as published by the Free
11*38fd1498Szrj Software Foundation; either version 3, or (at your option) any later
12*38fd1498Szrj version.
13*38fd1498Szrj 
14*38fd1498Szrj GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15*38fd1498Szrj WARRANTY; without even the implied warranty of MERCHANTABILITY or
16*38fd1498Szrj FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17*38fd1498Szrj for more details.
18*38fd1498Szrj 
19*38fd1498Szrj You should have received a copy of the GNU General Public License
20*38fd1498Szrj along with GCC; see the file COPYING3.  If not see
21*38fd1498Szrj <http://www.gnu.org/licenses/>.  */
22*38fd1498Szrj 
23*38fd1498Szrj #include "config.h"
24*38fd1498Szrj #include "system.h"
25*38fd1498Szrj #include "coretypes.h"
26*38fd1498Szrj #include "backend.h"
27*38fd1498Szrj #include "target.h"
28*38fd1498Szrj #include "rtl.h"
29*38fd1498Szrj #include "tree.h"
30*38fd1498Szrj #include "gimple.h"
31*38fd1498Szrj #include "cfghooks.h"
32*38fd1498Szrj #include "tree-pass.h"
33*38fd1498Szrj #include "ssa.h"
34*38fd1498Szrj #include "gimple-streamer.h"
35*38fd1498Szrj #include "toplev.h"
36*38fd1498Szrj #include "gimple-iterator.h"
37*38fd1498Szrj #include "tree-cfg.h"
38*38fd1498Szrj #include "tree-into-ssa.h"
39*38fd1498Szrj #include "tree-dfa.h"
40*38fd1498Szrj #include "tree-ssa.h"
41*38fd1498Szrj #include "except.h"
42*38fd1498Szrj #include "cgraph.h"
43*38fd1498Szrj #include "cfgloop.h"
44*38fd1498Szrj #include "debug.h"
45*38fd1498Szrj 
46*38fd1498Szrj 
47*38fd1498Szrj struct freeing_string_slot_hasher : string_slot_hasher
48*38fd1498Szrj {
49*38fd1498Szrj   static inline void remove (value_type *);
50*38fd1498Szrj };
51*38fd1498Szrj 
52*38fd1498Szrj inline void
remove(value_type * v)53*38fd1498Szrj freeing_string_slot_hasher::remove (value_type *v)
54*38fd1498Szrj {
55*38fd1498Szrj   free (v);
56*38fd1498Szrj }
57*38fd1498Szrj 
58*38fd1498Szrj /* The table to hold the file names.  */
59*38fd1498Szrj static hash_table<freeing_string_slot_hasher> *file_name_hash_table;
60*38fd1498Szrj 
61*38fd1498Szrj 
62*38fd1498Szrj /* Check that tag ACTUAL has one of the given values.  NUM_TAGS is the
63*38fd1498Szrj    number of valid tag values to check.  */
64*38fd1498Szrj 
65*38fd1498Szrj void
lto_tag_check_set(enum LTO_tags actual,int ntags,...)66*38fd1498Szrj lto_tag_check_set (enum LTO_tags actual, int ntags, ...)
67*38fd1498Szrj {
68*38fd1498Szrj   va_list ap;
69*38fd1498Szrj   int i;
70*38fd1498Szrj 
71*38fd1498Szrj   va_start (ap, ntags);
72*38fd1498Szrj   for (i = 0; i < ntags; i++)
73*38fd1498Szrj     if ((unsigned) actual == va_arg (ap, unsigned))
74*38fd1498Szrj       {
75*38fd1498Szrj 	va_end (ap);
76*38fd1498Szrj 	return;
77*38fd1498Szrj       }
78*38fd1498Szrj 
79*38fd1498Szrj   va_end (ap);
80*38fd1498Szrj   internal_error ("bytecode stream: unexpected tag %s", lto_tag_name (actual));
81*38fd1498Szrj }
82*38fd1498Szrj 
83*38fd1498Szrj 
84*38fd1498Szrj /* Read LENGTH bytes from STREAM to ADDR.  */
85*38fd1498Szrj 
86*38fd1498Szrj void
lto_input_data_block(struct lto_input_block * ib,void * addr,size_t length)87*38fd1498Szrj lto_input_data_block (struct lto_input_block *ib, void *addr, size_t length)
88*38fd1498Szrj {
89*38fd1498Szrj   size_t i;
90*38fd1498Szrj   unsigned char *const buffer = (unsigned char *) addr;
91*38fd1498Szrj 
92*38fd1498Szrj   for (i = 0; i < length; i++)
93*38fd1498Szrj     buffer[i] = streamer_read_uchar (ib);
94*38fd1498Szrj }
95*38fd1498Szrj 
96*38fd1498Szrj 
97*38fd1498Szrj /* Lookup STRING in file_name_hash_table.  If found, return the existing
98*38fd1498Szrj    string, otherwise insert STRING as the canonical version.  */
99*38fd1498Szrj 
100*38fd1498Szrj static const char *
canon_file_name(const char * string)101*38fd1498Szrj canon_file_name (const char *string)
102*38fd1498Szrj {
103*38fd1498Szrj   string_slot **slot;
104*38fd1498Szrj   struct string_slot s_slot;
105*38fd1498Szrj   size_t len = strlen (string);
106*38fd1498Szrj 
107*38fd1498Szrj   s_slot.s = string;
108*38fd1498Szrj   s_slot.len = len;
109*38fd1498Szrj 
110*38fd1498Szrj   slot = file_name_hash_table->find_slot (&s_slot, INSERT);
111*38fd1498Szrj   if (*slot == NULL)
112*38fd1498Szrj     {
113*38fd1498Szrj       char *saved_string;
114*38fd1498Szrj       struct string_slot *new_slot;
115*38fd1498Szrj 
116*38fd1498Szrj       saved_string = (char *) xmalloc (len + 1);
117*38fd1498Szrj       new_slot = XCNEW (struct string_slot);
118*38fd1498Szrj       memcpy (saved_string, string, len + 1);
119*38fd1498Szrj       new_slot->s = saved_string;
120*38fd1498Szrj       new_slot->len = len;
121*38fd1498Szrj       *slot = new_slot;
122*38fd1498Szrj       return saved_string;
123*38fd1498Szrj     }
124*38fd1498Szrj   else
125*38fd1498Szrj     {
126*38fd1498Szrj       struct string_slot *old_slot = *slot;
127*38fd1498Szrj       return old_slot->s;
128*38fd1498Szrj     }
129*38fd1498Szrj }
130*38fd1498Szrj 
131*38fd1498Szrj /* Pointer to currently alive instance of lto_location_cache.  */
132*38fd1498Szrj 
133*38fd1498Szrj lto_location_cache *lto_location_cache::current_cache;
134*38fd1498Szrj 
135*38fd1498Szrj /* Sort locations in source order. Start with file from last application.  */
136*38fd1498Szrj 
137*38fd1498Szrj int
cmp_loc(const void * pa,const void * pb)138*38fd1498Szrj lto_location_cache::cmp_loc (const void *pa, const void *pb)
139*38fd1498Szrj {
140*38fd1498Szrj   const cached_location *a = ((const cached_location *)pa);
141*38fd1498Szrj   const cached_location *b = ((const cached_location *)pb);
142*38fd1498Szrj   const char *current_file = current_cache->current_file;
143*38fd1498Szrj   int current_line = current_cache->current_line;
144*38fd1498Szrj 
145*38fd1498Szrj   if (a->file == current_file && b->file != current_file)
146*38fd1498Szrj     return -1;
147*38fd1498Szrj   if (a->file != current_file && b->file == current_file)
148*38fd1498Szrj     return 1;
149*38fd1498Szrj   if (a->file == current_file && b->file == current_file)
150*38fd1498Szrj     {
151*38fd1498Szrj       if (a->line == current_line && b->line != current_line)
152*38fd1498Szrj 	return -1;
153*38fd1498Szrj       if (a->line != current_line && b->line == current_line)
154*38fd1498Szrj 	return 1;
155*38fd1498Szrj     }
156*38fd1498Szrj   if (a->file != b->file)
157*38fd1498Szrj     return strcmp (a->file, b->file);
158*38fd1498Szrj   if (a->sysp != b->sysp)
159*38fd1498Szrj     return a->sysp ? 1 : -1;
160*38fd1498Szrj   if (a->line != b->line)
161*38fd1498Szrj     return a->line - b->line;
162*38fd1498Szrj   return a->col - b->col;
163*38fd1498Szrj }
164*38fd1498Szrj 
165*38fd1498Szrj /* Apply all changes in location cache.  Add locations into linemap and patch
166*38fd1498Szrj    trees.  */
167*38fd1498Szrj 
168*38fd1498Szrj bool
apply_location_cache()169*38fd1498Szrj lto_location_cache::apply_location_cache ()
170*38fd1498Szrj {
171*38fd1498Szrj   static const char *prev_file;
172*38fd1498Szrj   if (!loc_cache.length ())
173*38fd1498Szrj     return false;
174*38fd1498Szrj   if (loc_cache.length () > 1)
175*38fd1498Szrj     loc_cache.qsort (cmp_loc);
176*38fd1498Szrj 
177*38fd1498Szrj   for (unsigned int i = 0; i < loc_cache.length (); i++)
178*38fd1498Szrj     {
179*38fd1498Szrj       struct cached_location loc = loc_cache[i];
180*38fd1498Szrj 
181*38fd1498Szrj       if (current_file != loc.file)
182*38fd1498Szrj 	linemap_add (line_table, prev_file ? LC_RENAME : LC_ENTER,
183*38fd1498Szrj 		     loc.sysp, loc.file, loc.line);
184*38fd1498Szrj       else if (current_line != loc.line)
185*38fd1498Szrj 	{
186*38fd1498Szrj 	  int max = loc.col;
187*38fd1498Szrj 
188*38fd1498Szrj 	  for (unsigned int j = i + 1; j < loc_cache.length (); j++)
189*38fd1498Szrj 	    if (loc.file != loc_cache[j].file
190*38fd1498Szrj 		|| loc.line != loc_cache[j].line)
191*38fd1498Szrj 	      break;
192*38fd1498Szrj 	    else if (max < loc_cache[j].col)
193*38fd1498Szrj 	      max = loc_cache[j].col;
194*38fd1498Szrj 	  linemap_line_start (line_table, loc.line, max + 1);
195*38fd1498Szrj 	}
196*38fd1498Szrj       gcc_assert (*loc.loc == BUILTINS_LOCATION + 1);
197*38fd1498Szrj       if (current_file == loc.file && current_line == loc.line
198*38fd1498Szrj 	  && current_col == loc.col)
199*38fd1498Szrj 	*loc.loc = current_loc;
200*38fd1498Szrj       else
201*38fd1498Szrj         current_loc = *loc.loc = linemap_position_for_column (line_table,
202*38fd1498Szrj 							      loc.col);
203*38fd1498Szrj       current_line = loc.line;
204*38fd1498Szrj       prev_file = current_file = loc.file;
205*38fd1498Szrj       current_col = loc.col;
206*38fd1498Szrj     }
207*38fd1498Szrj   loc_cache.truncate (0);
208*38fd1498Szrj   accepted_length = 0;
209*38fd1498Szrj   return true;
210*38fd1498Szrj }
211*38fd1498Szrj 
212*38fd1498Szrj /* Tree merging did not suceed; mark all changes in the cache as accepted.  */
213*38fd1498Szrj 
214*38fd1498Szrj void
accept_location_cache()215*38fd1498Szrj lto_location_cache::accept_location_cache ()
216*38fd1498Szrj {
217*38fd1498Szrj   gcc_assert (current_cache == this);
218*38fd1498Szrj   accepted_length = loc_cache.length ();
219*38fd1498Szrj }
220*38fd1498Szrj 
221*38fd1498Szrj /* Tree merging did suceed; throw away recent changes.  */
222*38fd1498Szrj 
223*38fd1498Szrj void
revert_location_cache()224*38fd1498Szrj lto_location_cache::revert_location_cache ()
225*38fd1498Szrj {
226*38fd1498Szrj   loc_cache.truncate (accepted_length);
227*38fd1498Szrj }
228*38fd1498Szrj 
229*38fd1498Szrj /* Read a location bitpack from input block IB and either update *LOC directly
230*38fd1498Szrj    or add it to the location cache.
231*38fd1498Szrj    It is neccesary to call apply_location_cache to get *LOC updated.  */
232*38fd1498Szrj 
233*38fd1498Szrj void
input_location(location_t * loc,struct bitpack_d * bp,struct data_in * data_in)234*38fd1498Szrj lto_location_cache::input_location (location_t *loc, struct bitpack_d *bp,
235*38fd1498Szrj 				    struct data_in *data_in)
236*38fd1498Szrj {
237*38fd1498Szrj   static const char *stream_file;
238*38fd1498Szrj   static int stream_line;
239*38fd1498Szrj   static int stream_col;
240*38fd1498Szrj   static bool stream_sysp;
241*38fd1498Szrj   bool file_change, line_change, column_change;
242*38fd1498Szrj 
243*38fd1498Szrj   gcc_assert (current_cache == this);
244*38fd1498Szrj 
245*38fd1498Szrj   *loc = bp_unpack_int_in_range (bp, "location", 0, RESERVED_LOCATION_COUNT);
246*38fd1498Szrj 
247*38fd1498Szrj   if (*loc < RESERVED_LOCATION_COUNT)
248*38fd1498Szrj     return;
249*38fd1498Szrj 
250*38fd1498Szrj   /* Keep value RESERVED_LOCATION_COUNT in *loc as linemap lookups will
251*38fd1498Szrj      ICE on it.  */
252*38fd1498Szrj 
253*38fd1498Szrj   file_change = bp_unpack_value (bp, 1);
254*38fd1498Szrj   line_change = bp_unpack_value (bp, 1);
255*38fd1498Szrj   column_change = bp_unpack_value (bp, 1);
256*38fd1498Szrj 
257*38fd1498Szrj   if (file_change)
258*38fd1498Szrj     {
259*38fd1498Szrj       stream_file = canon_file_name (bp_unpack_string (data_in, bp));
260*38fd1498Szrj       stream_sysp = bp_unpack_value (bp, 1);
261*38fd1498Szrj     }
262*38fd1498Szrj 
263*38fd1498Szrj   if (line_change)
264*38fd1498Szrj     stream_line = bp_unpack_var_len_unsigned (bp);
265*38fd1498Szrj 
266*38fd1498Szrj   if (column_change)
267*38fd1498Szrj     stream_col = bp_unpack_var_len_unsigned (bp);
268*38fd1498Szrj 
269*38fd1498Szrj   /* This optimization saves location cache operations druing gimple
270*38fd1498Szrj      streaming.  */
271*38fd1498Szrj 
272*38fd1498Szrj   if (current_file == stream_file && current_line == stream_line
273*38fd1498Szrj       && current_col == stream_col && current_sysp == stream_sysp)
274*38fd1498Szrj     {
275*38fd1498Szrj       *loc = current_loc;
276*38fd1498Szrj       return;
277*38fd1498Szrj     }
278*38fd1498Szrj 
279*38fd1498Szrj   struct cached_location entry
280*38fd1498Szrj     = {stream_file, loc, stream_line, stream_col, stream_sysp};
281*38fd1498Szrj   loc_cache.safe_push (entry);
282*38fd1498Szrj }
283*38fd1498Szrj 
284*38fd1498Szrj /* Read a location bitpack from input block IB and either update *LOC directly
285*38fd1498Szrj    or add it to the location cache.
286*38fd1498Szrj    It is neccesary to call apply_location_cache to get *LOC updated.  */
287*38fd1498Szrj 
288*38fd1498Szrj void
lto_input_location(location_t * loc,struct bitpack_d * bp,struct data_in * data_in)289*38fd1498Szrj lto_input_location (location_t *loc, struct bitpack_d *bp,
290*38fd1498Szrj 		    struct data_in *data_in)
291*38fd1498Szrj {
292*38fd1498Szrj   data_in->location_cache.input_location (loc, bp, data_in);
293*38fd1498Szrj }
294*38fd1498Szrj 
295*38fd1498Szrj /* Read location and return it instead of going through location caching.
296*38fd1498Szrj    This should be used only when the resulting location is not going to be
297*38fd1498Szrj    discarded.  */
298*38fd1498Szrj 
299*38fd1498Szrj location_t
stream_input_location_now(struct bitpack_d * bp,struct data_in * data_in)300*38fd1498Szrj stream_input_location_now (struct bitpack_d *bp, struct data_in *data_in)
301*38fd1498Szrj {
302*38fd1498Szrj   location_t loc;
303*38fd1498Szrj   stream_input_location (&loc, bp, data_in);
304*38fd1498Szrj   data_in->location_cache.apply_location_cache ();
305*38fd1498Szrj   return loc;
306*38fd1498Szrj }
307*38fd1498Szrj 
308*38fd1498Szrj /* Read a reference to a tree node from DATA_IN using input block IB.
309*38fd1498Szrj    TAG is the expected node that should be found in IB, if TAG belongs
310*38fd1498Szrj    to one of the indexable trees, expect to read a reference index to
311*38fd1498Szrj    be looked up in one of the symbol tables, otherwise read the pysical
312*38fd1498Szrj    representation of the tree using stream_read_tree.  FN is the
313*38fd1498Szrj    function scope for the read tree.  */
314*38fd1498Szrj 
315*38fd1498Szrj tree
lto_input_tree_ref(struct lto_input_block * ib,struct data_in * data_in,struct function * fn,enum LTO_tags tag)316*38fd1498Szrj lto_input_tree_ref (struct lto_input_block *ib, struct data_in *data_in,
317*38fd1498Szrj 		    struct function *fn, enum LTO_tags tag)
318*38fd1498Szrj {
319*38fd1498Szrj   unsigned HOST_WIDE_INT ix_u;
320*38fd1498Szrj   tree result = NULL_TREE;
321*38fd1498Szrj 
322*38fd1498Szrj   lto_tag_check_range (tag, LTO_field_decl_ref, LTO_namelist_decl_ref);
323*38fd1498Szrj 
324*38fd1498Szrj   switch (tag)
325*38fd1498Szrj     {
326*38fd1498Szrj     case LTO_type_ref:
327*38fd1498Szrj       ix_u = streamer_read_uhwi (ib);
328*38fd1498Szrj       result = lto_file_decl_data_get_type (data_in->file_data, ix_u);
329*38fd1498Szrj       break;
330*38fd1498Szrj 
331*38fd1498Szrj     case LTO_ssa_name_ref:
332*38fd1498Szrj       ix_u = streamer_read_uhwi (ib);
333*38fd1498Szrj       result = (*SSANAMES (fn))[ix_u];
334*38fd1498Szrj       break;
335*38fd1498Szrj 
336*38fd1498Szrj     case LTO_field_decl_ref:
337*38fd1498Szrj       ix_u = streamer_read_uhwi (ib);
338*38fd1498Szrj       result = lto_file_decl_data_get_field_decl (data_in->file_data, ix_u);
339*38fd1498Szrj       break;
340*38fd1498Szrj 
341*38fd1498Szrj     case LTO_function_decl_ref:
342*38fd1498Szrj       ix_u = streamer_read_uhwi (ib);
343*38fd1498Szrj       result = lto_file_decl_data_get_fn_decl (data_in->file_data, ix_u);
344*38fd1498Szrj       break;
345*38fd1498Szrj 
346*38fd1498Szrj     case LTO_type_decl_ref:
347*38fd1498Szrj       ix_u = streamer_read_uhwi (ib);
348*38fd1498Szrj       result = lto_file_decl_data_get_type_decl (data_in->file_data, ix_u);
349*38fd1498Szrj       break;
350*38fd1498Szrj 
351*38fd1498Szrj     case LTO_namespace_decl_ref:
352*38fd1498Szrj       ix_u = streamer_read_uhwi (ib);
353*38fd1498Szrj       result = lto_file_decl_data_get_namespace_decl (data_in->file_data, ix_u);
354*38fd1498Szrj       break;
355*38fd1498Szrj 
356*38fd1498Szrj     case LTO_global_decl_ref:
357*38fd1498Szrj     case LTO_result_decl_ref:
358*38fd1498Szrj     case LTO_const_decl_ref:
359*38fd1498Szrj     case LTO_imported_decl_ref:
360*38fd1498Szrj     case LTO_label_decl_ref:
361*38fd1498Szrj     case LTO_translation_unit_decl_ref:
362*38fd1498Szrj     case LTO_namelist_decl_ref:
363*38fd1498Szrj       ix_u = streamer_read_uhwi (ib);
364*38fd1498Szrj       result = lto_file_decl_data_get_var_decl (data_in->file_data, ix_u);
365*38fd1498Szrj       break;
366*38fd1498Szrj 
367*38fd1498Szrj     default:
368*38fd1498Szrj       gcc_unreachable ();
369*38fd1498Szrj     }
370*38fd1498Szrj 
371*38fd1498Szrj   gcc_assert (result);
372*38fd1498Szrj 
373*38fd1498Szrj   return result;
374*38fd1498Szrj }
375*38fd1498Szrj 
376*38fd1498Szrj 
377*38fd1498Szrj /* Read and return a double-linked list of catch handlers from input
378*38fd1498Szrj    block IB, using descriptors in DATA_IN.  */
379*38fd1498Szrj 
380*38fd1498Szrj static struct eh_catch_d *
lto_input_eh_catch_list(struct lto_input_block * ib,struct data_in * data_in,eh_catch * last_p)381*38fd1498Szrj lto_input_eh_catch_list (struct lto_input_block *ib, struct data_in *data_in,
382*38fd1498Szrj 			 eh_catch *last_p)
383*38fd1498Szrj {
384*38fd1498Szrj   eh_catch first;
385*38fd1498Szrj   enum LTO_tags tag;
386*38fd1498Szrj 
387*38fd1498Szrj   *last_p = first = NULL;
388*38fd1498Szrj   tag = streamer_read_record_start (ib);
389*38fd1498Szrj   while (tag)
390*38fd1498Szrj     {
391*38fd1498Szrj       tree list;
392*38fd1498Szrj       eh_catch n;
393*38fd1498Szrj 
394*38fd1498Szrj       lto_tag_check_range (tag, LTO_eh_catch, LTO_eh_catch);
395*38fd1498Szrj 
396*38fd1498Szrj       /* Read the catch node.  */
397*38fd1498Szrj       n = ggc_cleared_alloc<eh_catch_d> ();
398*38fd1498Szrj       n->type_list = stream_read_tree (ib, data_in);
399*38fd1498Szrj       n->filter_list = stream_read_tree (ib, data_in);
400*38fd1498Szrj       n->label = stream_read_tree (ib, data_in);
401*38fd1498Szrj 
402*38fd1498Szrj       /* Register all the types in N->FILTER_LIST.  */
403*38fd1498Szrj       for (list = n->filter_list; list; list = TREE_CHAIN (list))
404*38fd1498Szrj 	add_type_for_runtime (TREE_VALUE (list));
405*38fd1498Szrj 
406*38fd1498Szrj       /* Chain N to the end of the list.  */
407*38fd1498Szrj       if (*last_p)
408*38fd1498Szrj 	(*last_p)->next_catch = n;
409*38fd1498Szrj       n->prev_catch = *last_p;
410*38fd1498Szrj       *last_p = n;
411*38fd1498Szrj 
412*38fd1498Szrj       /* Set the head of the list the first time through the loop.  */
413*38fd1498Szrj       if (first == NULL)
414*38fd1498Szrj 	first = n;
415*38fd1498Szrj 
416*38fd1498Szrj       tag = streamer_read_record_start (ib);
417*38fd1498Szrj     }
418*38fd1498Szrj 
419*38fd1498Szrj   return first;
420*38fd1498Szrj }
421*38fd1498Szrj 
422*38fd1498Szrj 
423*38fd1498Szrj /* Read and return EH region IX from input block IB, using descriptors
424*38fd1498Szrj    in DATA_IN.  */
425*38fd1498Szrj 
426*38fd1498Szrj static eh_region
input_eh_region(struct lto_input_block * ib,struct data_in * data_in,int ix)427*38fd1498Szrj input_eh_region (struct lto_input_block *ib, struct data_in *data_in, int ix)
428*38fd1498Szrj {
429*38fd1498Szrj   enum LTO_tags tag;
430*38fd1498Szrj   eh_region r;
431*38fd1498Szrj 
432*38fd1498Szrj   /* Read the region header.  */
433*38fd1498Szrj   tag = streamer_read_record_start (ib);
434*38fd1498Szrj   if (tag == LTO_null)
435*38fd1498Szrj     return NULL;
436*38fd1498Szrj 
437*38fd1498Szrj   r = ggc_cleared_alloc<eh_region_d> ();
438*38fd1498Szrj   r->index = streamer_read_hwi (ib);
439*38fd1498Szrj 
440*38fd1498Szrj   gcc_assert (r->index == ix);
441*38fd1498Szrj 
442*38fd1498Szrj   /* Read all the region pointers as region numbers.  We'll fix up
443*38fd1498Szrj      the pointers once the whole array has been read.  */
444*38fd1498Szrj   r->outer = (eh_region) (intptr_t) streamer_read_hwi (ib);
445*38fd1498Szrj   r->inner = (eh_region) (intptr_t) streamer_read_hwi (ib);
446*38fd1498Szrj   r->next_peer = (eh_region) (intptr_t) streamer_read_hwi (ib);
447*38fd1498Szrj 
448*38fd1498Szrj   switch (tag)
449*38fd1498Szrj     {
450*38fd1498Szrj       case LTO_ert_cleanup:
451*38fd1498Szrj 	r->type = ERT_CLEANUP;
452*38fd1498Szrj 	break;
453*38fd1498Szrj 
454*38fd1498Szrj       case LTO_ert_try:
455*38fd1498Szrj 	{
456*38fd1498Szrj 	  struct eh_catch_d *last_catch;
457*38fd1498Szrj 	  r->type = ERT_TRY;
458*38fd1498Szrj 	  r->u.eh_try.first_catch = lto_input_eh_catch_list (ib, data_in,
459*38fd1498Szrj 							     &last_catch);
460*38fd1498Szrj 	  r->u.eh_try.last_catch = last_catch;
461*38fd1498Szrj 	  break;
462*38fd1498Szrj 	}
463*38fd1498Szrj 
464*38fd1498Szrj       case LTO_ert_allowed_exceptions:
465*38fd1498Szrj 	{
466*38fd1498Szrj 	  tree l;
467*38fd1498Szrj 
468*38fd1498Szrj 	  r->type = ERT_ALLOWED_EXCEPTIONS;
469*38fd1498Szrj 	  r->u.allowed.type_list = stream_read_tree (ib, data_in);
470*38fd1498Szrj 	  r->u.allowed.label = stream_read_tree (ib, data_in);
471*38fd1498Szrj 	  r->u.allowed.filter = streamer_read_uhwi (ib);
472*38fd1498Szrj 
473*38fd1498Szrj 	  for (l = r->u.allowed.type_list; l ; l = TREE_CHAIN (l))
474*38fd1498Szrj 	    add_type_for_runtime (TREE_VALUE (l));
475*38fd1498Szrj 	}
476*38fd1498Szrj 	break;
477*38fd1498Szrj 
478*38fd1498Szrj       case LTO_ert_must_not_throw:
479*38fd1498Szrj 	{
480*38fd1498Szrj 	  r->type = ERT_MUST_NOT_THROW;
481*38fd1498Szrj 	  r->u.must_not_throw.failure_decl = stream_read_tree (ib, data_in);
482*38fd1498Szrj 	  bitpack_d bp = streamer_read_bitpack (ib);
483*38fd1498Szrj 	  r->u.must_not_throw.failure_loc
484*38fd1498Szrj 	   = stream_input_location_now (&bp, data_in);
485*38fd1498Szrj 	}
486*38fd1498Szrj 	break;
487*38fd1498Szrj 
488*38fd1498Szrj       default:
489*38fd1498Szrj 	gcc_unreachable ();
490*38fd1498Szrj     }
491*38fd1498Szrj 
492*38fd1498Szrj   r->landing_pads = (eh_landing_pad) (intptr_t) streamer_read_hwi (ib);
493*38fd1498Szrj 
494*38fd1498Szrj   return r;
495*38fd1498Szrj }
496*38fd1498Szrj 
497*38fd1498Szrj 
498*38fd1498Szrj /* Read and return EH landing pad IX from input block IB, using descriptors
499*38fd1498Szrj    in DATA_IN.  */
500*38fd1498Szrj 
501*38fd1498Szrj static eh_landing_pad
input_eh_lp(struct lto_input_block * ib,struct data_in * data_in,int ix)502*38fd1498Szrj input_eh_lp (struct lto_input_block *ib, struct data_in *data_in, int ix)
503*38fd1498Szrj {
504*38fd1498Szrj   enum LTO_tags tag;
505*38fd1498Szrj   eh_landing_pad lp;
506*38fd1498Szrj 
507*38fd1498Szrj   /* Read the landing pad header.  */
508*38fd1498Szrj   tag = streamer_read_record_start (ib);
509*38fd1498Szrj   if (tag == LTO_null)
510*38fd1498Szrj     return NULL;
511*38fd1498Szrj 
512*38fd1498Szrj   lto_tag_check_range (tag, LTO_eh_landing_pad, LTO_eh_landing_pad);
513*38fd1498Szrj 
514*38fd1498Szrj   lp = ggc_cleared_alloc<eh_landing_pad_d> ();
515*38fd1498Szrj   lp->index = streamer_read_hwi (ib);
516*38fd1498Szrj   gcc_assert (lp->index == ix);
517*38fd1498Szrj   lp->next_lp = (eh_landing_pad) (intptr_t) streamer_read_hwi (ib);
518*38fd1498Szrj   lp->region = (eh_region) (intptr_t) streamer_read_hwi (ib);
519*38fd1498Szrj   lp->post_landing_pad = stream_read_tree (ib, data_in);
520*38fd1498Szrj 
521*38fd1498Szrj   return lp;
522*38fd1498Szrj }
523*38fd1498Szrj 
524*38fd1498Szrj 
525*38fd1498Szrj /* After reading the EH regions, pointers to peer and children regions
526*38fd1498Szrj    are region numbers.  This converts all these region numbers into
527*38fd1498Szrj    real pointers into the rematerialized regions for FN.  ROOT_REGION
528*38fd1498Szrj    is the region number for the root EH region in FN.  */
529*38fd1498Szrj 
530*38fd1498Szrj static void
fixup_eh_region_pointers(struct function * fn,HOST_WIDE_INT root_region)531*38fd1498Szrj fixup_eh_region_pointers (struct function *fn, HOST_WIDE_INT root_region)
532*38fd1498Szrj {
533*38fd1498Szrj   unsigned i;
534*38fd1498Szrj   vec<eh_region, va_gc> *eh_array = fn->eh->region_array;
535*38fd1498Szrj   vec<eh_landing_pad, va_gc> *lp_array = fn->eh->lp_array;
536*38fd1498Szrj   eh_region r;
537*38fd1498Szrj   eh_landing_pad lp;
538*38fd1498Szrj 
539*38fd1498Szrj   gcc_assert (eh_array && lp_array);
540*38fd1498Szrj 
541*38fd1498Szrj   gcc_assert (root_region >= 0);
542*38fd1498Szrj   fn->eh->region_tree = (*eh_array)[root_region];
543*38fd1498Szrj 
544*38fd1498Szrj #define FIXUP_EH_REGION(r) (r) = (*eh_array)[(HOST_WIDE_INT) (intptr_t) (r)]
545*38fd1498Szrj #define FIXUP_EH_LP(p) (p) = (*lp_array)[(HOST_WIDE_INT) (intptr_t) (p)]
546*38fd1498Szrj 
547*38fd1498Szrj   /* Convert all the index numbers stored in pointer fields into
548*38fd1498Szrj      pointers to the corresponding slots in the EH region array.  */
549*38fd1498Szrj   FOR_EACH_VEC_ELT (*eh_array, i, r)
550*38fd1498Szrj     {
551*38fd1498Szrj       /* The array may contain NULL regions.  */
552*38fd1498Szrj       if (r == NULL)
553*38fd1498Szrj 	continue;
554*38fd1498Szrj 
555*38fd1498Szrj       gcc_assert (i == (unsigned) r->index);
556*38fd1498Szrj       FIXUP_EH_REGION (r->outer);
557*38fd1498Szrj       FIXUP_EH_REGION (r->inner);
558*38fd1498Szrj       FIXUP_EH_REGION (r->next_peer);
559*38fd1498Szrj       FIXUP_EH_LP (r->landing_pads);
560*38fd1498Szrj     }
561*38fd1498Szrj 
562*38fd1498Szrj   /* Convert all the index numbers stored in pointer fields into
563*38fd1498Szrj      pointers to the corresponding slots in the EH landing pad array.  */
564*38fd1498Szrj   FOR_EACH_VEC_ELT (*lp_array, i, lp)
565*38fd1498Szrj     {
566*38fd1498Szrj       /* The array may contain NULL landing pads.  */
567*38fd1498Szrj       if (lp == NULL)
568*38fd1498Szrj 	continue;
569*38fd1498Szrj 
570*38fd1498Szrj       gcc_assert (i == (unsigned) lp->index);
571*38fd1498Szrj       FIXUP_EH_LP (lp->next_lp);
572*38fd1498Szrj       FIXUP_EH_REGION (lp->region);
573*38fd1498Szrj     }
574*38fd1498Szrj 
575*38fd1498Szrj #undef FIXUP_EH_REGION
576*38fd1498Szrj #undef FIXUP_EH_LP
577*38fd1498Szrj }
578*38fd1498Szrj 
579*38fd1498Szrj 
580*38fd1498Szrj /* Initialize EH support.  */
581*38fd1498Szrj 
582*38fd1498Szrj void
lto_init_eh(void)583*38fd1498Szrj lto_init_eh (void)
584*38fd1498Szrj {
585*38fd1498Szrj   static bool eh_initialized_p = false;
586*38fd1498Szrj 
587*38fd1498Szrj   if (eh_initialized_p)
588*38fd1498Szrj     return;
589*38fd1498Szrj 
590*38fd1498Szrj   /* Contrary to most other FEs, we only initialize EH support when at
591*38fd1498Szrj      least one of the files in the set contains exception regions in
592*38fd1498Szrj      it.  Since this happens much later than the call to init_eh in
593*38fd1498Szrj      lang_dependent_init, we have to set flag_exceptions and call
594*38fd1498Szrj      init_eh again to initialize the EH tables.  */
595*38fd1498Szrj   flag_exceptions = 1;
596*38fd1498Szrj   init_eh ();
597*38fd1498Szrj 
598*38fd1498Szrj   eh_initialized_p = true;
599*38fd1498Szrj }
600*38fd1498Szrj 
601*38fd1498Szrj 
602*38fd1498Szrj /* Read the exception table for FN from IB using the data descriptors
603*38fd1498Szrj    in DATA_IN.  */
604*38fd1498Szrj 
605*38fd1498Szrj static void
input_eh_regions(struct lto_input_block * ib,struct data_in * data_in,struct function * fn)606*38fd1498Szrj input_eh_regions (struct lto_input_block *ib, struct data_in *data_in,
607*38fd1498Szrj 		  struct function *fn)
608*38fd1498Szrj {
609*38fd1498Szrj   HOST_WIDE_INT i, root_region, len;
610*38fd1498Szrj   enum LTO_tags tag;
611*38fd1498Szrj 
612*38fd1498Szrj   tag = streamer_read_record_start (ib);
613*38fd1498Szrj   if (tag == LTO_null)
614*38fd1498Szrj     return;
615*38fd1498Szrj 
616*38fd1498Szrj   lto_tag_check_range (tag, LTO_eh_table, LTO_eh_table);
617*38fd1498Szrj 
618*38fd1498Szrj   /* If the file contains EH regions, then it was compiled with
619*38fd1498Szrj      -fexceptions.  In that case, initialize the backend EH
620*38fd1498Szrj      machinery.  */
621*38fd1498Szrj   lto_init_eh ();
622*38fd1498Szrj 
623*38fd1498Szrj   gcc_assert (fn->eh);
624*38fd1498Szrj 
625*38fd1498Szrj   root_region = streamer_read_hwi (ib);
626*38fd1498Szrj   gcc_assert (root_region == (int) root_region);
627*38fd1498Szrj 
628*38fd1498Szrj   /* Read the EH region array.  */
629*38fd1498Szrj   len = streamer_read_hwi (ib);
630*38fd1498Szrj   gcc_assert (len == (int) len);
631*38fd1498Szrj   if (len > 0)
632*38fd1498Szrj     {
633*38fd1498Szrj       vec_safe_grow_cleared (fn->eh->region_array, len);
634*38fd1498Szrj       for (i = 0; i < len; i++)
635*38fd1498Szrj 	{
636*38fd1498Szrj 	  eh_region r = input_eh_region (ib, data_in, i);
637*38fd1498Szrj 	  (*fn->eh->region_array)[i] = r;
638*38fd1498Szrj 	}
639*38fd1498Szrj     }
640*38fd1498Szrj 
641*38fd1498Szrj   /* Read the landing pads.  */
642*38fd1498Szrj   len = streamer_read_hwi (ib);
643*38fd1498Szrj   gcc_assert (len == (int) len);
644*38fd1498Szrj   if (len > 0)
645*38fd1498Szrj     {
646*38fd1498Szrj       vec_safe_grow_cleared (fn->eh->lp_array, len);
647*38fd1498Szrj       for (i = 0; i < len; i++)
648*38fd1498Szrj 	{
649*38fd1498Szrj 	  eh_landing_pad lp = input_eh_lp (ib, data_in, i);
650*38fd1498Szrj 	  (*fn->eh->lp_array)[i] = lp;
651*38fd1498Szrj 	}
652*38fd1498Szrj     }
653*38fd1498Szrj 
654*38fd1498Szrj   /* Read the runtime type data.  */
655*38fd1498Szrj   len = streamer_read_hwi (ib);
656*38fd1498Szrj   gcc_assert (len == (int) len);
657*38fd1498Szrj   if (len > 0)
658*38fd1498Szrj     {
659*38fd1498Szrj       vec_safe_grow_cleared (fn->eh->ttype_data, len);
660*38fd1498Szrj       for (i = 0; i < len; i++)
661*38fd1498Szrj 	{
662*38fd1498Szrj 	  tree ttype = stream_read_tree (ib, data_in);
663*38fd1498Szrj 	  (*fn->eh->ttype_data)[i] = ttype;
664*38fd1498Szrj 	}
665*38fd1498Szrj     }
666*38fd1498Szrj 
667*38fd1498Szrj   /* Read the table of action chains.  */
668*38fd1498Szrj   len = streamer_read_hwi (ib);
669*38fd1498Szrj   gcc_assert (len == (int) len);
670*38fd1498Szrj   if (len > 0)
671*38fd1498Szrj     {
672*38fd1498Szrj       if (targetm.arm_eabi_unwinder)
673*38fd1498Szrj 	{
674*38fd1498Szrj 	  vec_safe_grow_cleared (fn->eh->ehspec_data.arm_eabi, len);
675*38fd1498Szrj 	  for (i = 0; i < len; i++)
676*38fd1498Szrj 	    {
677*38fd1498Szrj 	      tree t = stream_read_tree (ib, data_in);
678*38fd1498Szrj 	      (*fn->eh->ehspec_data.arm_eabi)[i] = t;
679*38fd1498Szrj 	    }
680*38fd1498Szrj 	}
681*38fd1498Szrj       else
682*38fd1498Szrj 	{
683*38fd1498Szrj 	  vec_safe_grow_cleared (fn->eh->ehspec_data.other, len);
684*38fd1498Szrj 	  for (i = 0; i < len; i++)
685*38fd1498Szrj 	    {
686*38fd1498Szrj 	      uchar c = streamer_read_uchar (ib);
687*38fd1498Szrj 	      (*fn->eh->ehspec_data.other)[i] = c;
688*38fd1498Szrj 	    }
689*38fd1498Szrj 	}
690*38fd1498Szrj     }
691*38fd1498Szrj 
692*38fd1498Szrj   /* Reconstruct the EH region tree by fixing up the peer/children
693*38fd1498Szrj      pointers.  */
694*38fd1498Szrj   fixup_eh_region_pointers (fn, root_region);
695*38fd1498Szrj 
696*38fd1498Szrj   tag = streamer_read_record_start (ib);
697*38fd1498Szrj   lto_tag_check_range (tag, LTO_null, LTO_null);
698*38fd1498Szrj }
699*38fd1498Szrj 
700*38fd1498Szrj 
701*38fd1498Szrj /* Make a new basic block with index INDEX in function FN.  */
702*38fd1498Szrj 
703*38fd1498Szrj static basic_block
make_new_block(struct function * fn,unsigned int index)704*38fd1498Szrj make_new_block (struct function *fn, unsigned int index)
705*38fd1498Szrj {
706*38fd1498Szrj   basic_block bb = alloc_block ();
707*38fd1498Szrj   bb->index = index;
708*38fd1498Szrj   SET_BASIC_BLOCK_FOR_FN (fn, index, bb);
709*38fd1498Szrj   n_basic_blocks_for_fn (fn)++;
710*38fd1498Szrj   return bb;
711*38fd1498Szrj }
712*38fd1498Szrj 
713*38fd1498Szrj 
714*38fd1498Szrj /* Read the CFG for function FN from input block IB.  */
715*38fd1498Szrj 
716*38fd1498Szrj static void
input_cfg(struct lto_input_block * ib,struct data_in * data_in,struct function * fn)717*38fd1498Szrj input_cfg (struct lto_input_block *ib, struct data_in *data_in,
718*38fd1498Szrj 	   struct function *fn)
719*38fd1498Szrj {
720*38fd1498Szrj   unsigned int bb_count;
721*38fd1498Szrj   basic_block p_bb;
722*38fd1498Szrj   unsigned int i;
723*38fd1498Szrj   int index;
724*38fd1498Szrj 
725*38fd1498Szrj   init_empty_tree_cfg_for_function (fn);
726*38fd1498Szrj   init_ssa_operands (fn);
727*38fd1498Szrj 
728*38fd1498Szrj   profile_status_for_fn (fn) = streamer_read_enum (ib, profile_status_d,
729*38fd1498Szrj 						   PROFILE_LAST);
730*38fd1498Szrj 
731*38fd1498Szrj   bb_count = streamer_read_uhwi (ib);
732*38fd1498Szrj 
733*38fd1498Szrj   last_basic_block_for_fn (fn) = bb_count;
734*38fd1498Szrj   if (bb_count > basic_block_info_for_fn (fn)->length ())
735*38fd1498Szrj     vec_safe_grow_cleared (basic_block_info_for_fn (fn), bb_count);
736*38fd1498Szrj 
737*38fd1498Szrj   if (bb_count > label_to_block_map_for_fn (fn)->length ())
738*38fd1498Szrj     vec_safe_grow_cleared (label_to_block_map_for_fn (fn), bb_count);
739*38fd1498Szrj 
740*38fd1498Szrj   index = streamer_read_hwi (ib);
741*38fd1498Szrj   while (index != -1)
742*38fd1498Szrj     {
743*38fd1498Szrj       basic_block bb = BASIC_BLOCK_FOR_FN (fn, index);
744*38fd1498Szrj       unsigned int edge_count;
745*38fd1498Szrj 
746*38fd1498Szrj       if (bb == NULL)
747*38fd1498Szrj 	bb = make_new_block (fn, index);
748*38fd1498Szrj 
749*38fd1498Szrj       edge_count = streamer_read_uhwi (ib);
750*38fd1498Szrj 
751*38fd1498Szrj       /* Connect up the CFG.  */
752*38fd1498Szrj       for (i = 0; i < edge_count; i++)
753*38fd1498Szrj 	{
754*38fd1498Szrj 	  unsigned int dest_index;
755*38fd1498Szrj 	  unsigned int edge_flags;
756*38fd1498Szrj 	  basic_block dest;
757*38fd1498Szrj 	  profile_probability probability;
758*38fd1498Szrj 	  edge e;
759*38fd1498Szrj 
760*38fd1498Szrj 	  dest_index = streamer_read_uhwi (ib);
761*38fd1498Szrj 	  probability = profile_probability::stream_in (ib);
762*38fd1498Szrj 	  edge_flags = streamer_read_uhwi (ib);
763*38fd1498Szrj 
764*38fd1498Szrj 	  dest = BASIC_BLOCK_FOR_FN (fn, dest_index);
765*38fd1498Szrj 
766*38fd1498Szrj 	  if (dest == NULL)
767*38fd1498Szrj 	    dest = make_new_block (fn, dest_index);
768*38fd1498Szrj 
769*38fd1498Szrj 	  e = make_edge (bb, dest, edge_flags);
770*38fd1498Szrj 	  e->probability = probability;
771*38fd1498Szrj 	}
772*38fd1498Szrj 
773*38fd1498Szrj       index = streamer_read_hwi (ib);
774*38fd1498Szrj     }
775*38fd1498Szrj 
776*38fd1498Szrj   p_bb = ENTRY_BLOCK_PTR_FOR_FN (fn);
777*38fd1498Szrj   index = streamer_read_hwi (ib);
778*38fd1498Szrj   while (index != -1)
779*38fd1498Szrj     {
780*38fd1498Szrj       basic_block bb = BASIC_BLOCK_FOR_FN (fn, index);
781*38fd1498Szrj       bb->prev_bb = p_bb;
782*38fd1498Szrj       p_bb->next_bb = bb;
783*38fd1498Szrj       p_bb = bb;
784*38fd1498Szrj       index = streamer_read_hwi (ib);
785*38fd1498Szrj     }
786*38fd1498Szrj 
787*38fd1498Szrj   /* ???  The cfgloop interface is tied to cfun.  */
788*38fd1498Szrj   gcc_assert (cfun == fn);
789*38fd1498Szrj 
790*38fd1498Szrj   /* Input the loop tree.  */
791*38fd1498Szrj   unsigned n_loops = streamer_read_uhwi (ib);
792*38fd1498Szrj   if (n_loops == 0)
793*38fd1498Szrj     return;
794*38fd1498Szrj 
795*38fd1498Szrj   struct loops *loops = ggc_cleared_alloc<struct loops> ();
796*38fd1498Szrj   init_loops_structure (fn, loops, n_loops);
797*38fd1498Szrj   set_loops_for_fn (fn, loops);
798*38fd1498Szrj 
799*38fd1498Szrj   /* Input each loop and associate it with its loop header so
800*38fd1498Szrj      flow_loops_find can rebuild the loop tree.  */
801*38fd1498Szrj   for (unsigned i = 1; i < n_loops; ++i)
802*38fd1498Szrj     {
803*38fd1498Szrj       int header_index = streamer_read_hwi (ib);
804*38fd1498Szrj       if (header_index == -1)
805*38fd1498Szrj 	{
806*38fd1498Szrj 	  loops->larray->quick_push (NULL);
807*38fd1498Szrj 	  continue;
808*38fd1498Szrj 	}
809*38fd1498Szrj 
810*38fd1498Szrj       struct loop *loop = alloc_loop ();
811*38fd1498Szrj       loop->header = BASIC_BLOCK_FOR_FN (fn, header_index);
812*38fd1498Szrj       loop->header->loop_father = loop;
813*38fd1498Szrj 
814*38fd1498Szrj       /* Read everything copy_loop_info copies.  */
815*38fd1498Szrj       loop->estimate_state = streamer_read_enum (ib, loop_estimation, EST_LAST);
816*38fd1498Szrj       loop->any_upper_bound = streamer_read_hwi (ib);
817*38fd1498Szrj       if (loop->any_upper_bound)
818*38fd1498Szrj 	loop->nb_iterations_upper_bound = streamer_read_widest_int (ib);
819*38fd1498Szrj       loop->any_likely_upper_bound = streamer_read_hwi (ib);
820*38fd1498Szrj       if (loop->any_likely_upper_bound)
821*38fd1498Szrj 	loop->nb_iterations_likely_upper_bound = streamer_read_widest_int (ib);
822*38fd1498Szrj       loop->any_estimate = streamer_read_hwi (ib);
823*38fd1498Szrj       if (loop->any_estimate)
824*38fd1498Szrj 	loop->nb_iterations_estimate = streamer_read_widest_int (ib);
825*38fd1498Szrj 
826*38fd1498Szrj       /* Read OMP SIMD related info.  */
827*38fd1498Szrj       loop->safelen = streamer_read_hwi (ib);
828*38fd1498Szrj       loop->unroll = streamer_read_hwi (ib);
829*38fd1498Szrj       loop->dont_vectorize = streamer_read_hwi (ib);
830*38fd1498Szrj       loop->force_vectorize = streamer_read_hwi (ib);
831*38fd1498Szrj       loop->simduid = stream_read_tree (ib, data_in);
832*38fd1498Szrj 
833*38fd1498Szrj       place_new_loop (fn, loop);
834*38fd1498Szrj 
835*38fd1498Szrj       /* flow_loops_find doesn't like loops not in the tree, hook them
836*38fd1498Szrj          all as siblings of the tree root temporarily.  */
837*38fd1498Szrj       flow_loop_tree_node_add (loops->tree_root, loop);
838*38fd1498Szrj     }
839*38fd1498Szrj 
840*38fd1498Szrj   /* Rebuild the loop tree.  */
841*38fd1498Szrj   flow_loops_find (loops);
842*38fd1498Szrj }
843*38fd1498Szrj 
844*38fd1498Szrj 
845*38fd1498Szrj /* Read the SSA names array for function FN from DATA_IN using input
846*38fd1498Szrj    block IB.  */
847*38fd1498Szrj 
848*38fd1498Szrj static void
input_ssa_names(struct lto_input_block * ib,struct data_in * data_in,struct function * fn)849*38fd1498Szrj input_ssa_names (struct lto_input_block *ib, struct data_in *data_in,
850*38fd1498Szrj 		 struct function *fn)
851*38fd1498Szrj {
852*38fd1498Szrj   unsigned int i, size;
853*38fd1498Szrj 
854*38fd1498Szrj   size = streamer_read_uhwi (ib);
855*38fd1498Szrj   init_ssanames (fn, size);
856*38fd1498Szrj 
857*38fd1498Szrj   i = streamer_read_uhwi (ib);
858*38fd1498Szrj   while (i)
859*38fd1498Szrj     {
860*38fd1498Szrj       tree ssa_name, name;
861*38fd1498Szrj       bool is_default_def;
862*38fd1498Szrj 
863*38fd1498Szrj       /* Skip over the elements that had been freed.  */
864*38fd1498Szrj       while (SSANAMES (fn)->length () < i)
865*38fd1498Szrj 	SSANAMES (fn)->quick_push (NULL_TREE);
866*38fd1498Szrj 
867*38fd1498Szrj       is_default_def = (streamer_read_uchar (ib) != 0);
868*38fd1498Szrj       name = stream_read_tree (ib, data_in);
869*38fd1498Szrj       ssa_name = make_ssa_name_fn (fn, name, NULL);
870*38fd1498Szrj 
871*38fd1498Szrj       if (is_default_def)
872*38fd1498Szrj 	{
873*38fd1498Szrj 	  set_ssa_default_def (cfun, SSA_NAME_VAR (ssa_name), ssa_name);
874*38fd1498Szrj 	  SSA_NAME_DEF_STMT (ssa_name) = gimple_build_nop ();
875*38fd1498Szrj 	}
876*38fd1498Szrj 
877*38fd1498Szrj       i = streamer_read_uhwi (ib);
878*38fd1498Szrj     }
879*38fd1498Szrj }
880*38fd1498Szrj 
881*38fd1498Szrj 
882*38fd1498Szrj /* Go through all NODE edges and fixup call_stmt pointers
883*38fd1498Szrj    so they point to STMTS.  */
884*38fd1498Szrj 
885*38fd1498Szrj static void
fixup_call_stmt_edges_1(struct cgraph_node * node,gimple ** stmts,struct function * fn)886*38fd1498Szrj fixup_call_stmt_edges_1 (struct cgraph_node *node, gimple **stmts,
887*38fd1498Szrj 			 struct function *fn)
888*38fd1498Szrj {
889*38fd1498Szrj #define STMT_UID_NOT_IN_RANGE(uid) \
890*38fd1498Szrj   (gimple_stmt_max_uid (fn) < uid || uid == 0)
891*38fd1498Szrj 
892*38fd1498Szrj   struct cgraph_edge *cedge;
893*38fd1498Szrj   struct ipa_ref *ref = NULL;
894*38fd1498Szrj   unsigned int i;
895*38fd1498Szrj 
896*38fd1498Szrj   for (cedge = node->callees; cedge; cedge = cedge->next_callee)
897*38fd1498Szrj     {
898*38fd1498Szrj       if (STMT_UID_NOT_IN_RANGE (cedge->lto_stmt_uid))
899*38fd1498Szrj         fatal_error (input_location,
900*38fd1498Szrj 		     "Cgraph edge statement index out of range");
901*38fd1498Szrj       cedge->call_stmt = as_a <gcall *> (stmts[cedge->lto_stmt_uid - 1]);
902*38fd1498Szrj       if (!cedge->call_stmt)
903*38fd1498Szrj         fatal_error (input_location,
904*38fd1498Szrj 		     "Cgraph edge statement index not found");
905*38fd1498Szrj     }
906*38fd1498Szrj   for (cedge = node->indirect_calls; cedge; cedge = cedge->next_callee)
907*38fd1498Szrj     {
908*38fd1498Szrj       if (STMT_UID_NOT_IN_RANGE (cedge->lto_stmt_uid))
909*38fd1498Szrj         fatal_error (input_location,
910*38fd1498Szrj 		     "Cgraph edge statement index out of range");
911*38fd1498Szrj       cedge->call_stmt = as_a <gcall *> (stmts[cedge->lto_stmt_uid - 1]);
912*38fd1498Szrj       if (!cedge->call_stmt)
913*38fd1498Szrj         fatal_error (input_location, "Cgraph edge statement index not found");
914*38fd1498Szrj     }
915*38fd1498Szrj   for (i = 0; node->iterate_reference (i, ref); i++)
916*38fd1498Szrj     if (ref->lto_stmt_uid)
917*38fd1498Szrj       {
918*38fd1498Szrj 	if (STMT_UID_NOT_IN_RANGE (ref->lto_stmt_uid))
919*38fd1498Szrj 	  fatal_error (input_location,
920*38fd1498Szrj 		       "Reference statement index out of range");
921*38fd1498Szrj 	ref->stmt = stmts[ref->lto_stmt_uid - 1];
922*38fd1498Szrj 	if (!ref->stmt)
923*38fd1498Szrj 	  fatal_error (input_location, "Reference statement index not found");
924*38fd1498Szrj       }
925*38fd1498Szrj }
926*38fd1498Szrj 
927*38fd1498Szrj 
928*38fd1498Szrj /* Fixup call_stmt pointers in NODE and all clones.  */
929*38fd1498Szrj 
930*38fd1498Szrj static void
fixup_call_stmt_edges(struct cgraph_node * orig,gimple ** stmts)931*38fd1498Szrj fixup_call_stmt_edges (struct cgraph_node *orig, gimple **stmts)
932*38fd1498Szrj {
933*38fd1498Szrj   struct cgraph_node *node;
934*38fd1498Szrj   struct function *fn;
935*38fd1498Szrj 
936*38fd1498Szrj   while (orig->clone_of)
937*38fd1498Szrj     orig = orig->clone_of;
938*38fd1498Szrj   fn = DECL_STRUCT_FUNCTION (orig->decl);
939*38fd1498Szrj 
940*38fd1498Szrj   if (!orig->thunk.thunk_p)
941*38fd1498Szrj     fixup_call_stmt_edges_1 (orig, stmts, fn);
942*38fd1498Szrj   if (orig->clones)
943*38fd1498Szrj     for (node = orig->clones; node != orig;)
944*38fd1498Szrj       {
945*38fd1498Szrj 	if (!node->thunk.thunk_p)
946*38fd1498Szrj 	  fixup_call_stmt_edges_1 (node, stmts, fn);
947*38fd1498Szrj 	if (node->clones)
948*38fd1498Szrj 	  node = node->clones;
949*38fd1498Szrj 	else if (node->next_sibling_clone)
950*38fd1498Szrj 	  node = node->next_sibling_clone;
951*38fd1498Szrj 	else
952*38fd1498Szrj 	  {
953*38fd1498Szrj 	    while (node != orig && !node->next_sibling_clone)
954*38fd1498Szrj 	      node = node->clone_of;
955*38fd1498Szrj 	    if (node != orig)
956*38fd1498Szrj 	      node = node->next_sibling_clone;
957*38fd1498Szrj 	  }
958*38fd1498Szrj       }
959*38fd1498Szrj }
960*38fd1498Szrj 
961*38fd1498Szrj 
962*38fd1498Szrj /* Input the base body of struct function FN from DATA_IN
963*38fd1498Szrj    using input block IB.  */
964*38fd1498Szrj 
965*38fd1498Szrj static void
input_struct_function_base(struct function * fn,struct data_in * data_in,struct lto_input_block * ib)966*38fd1498Szrj input_struct_function_base (struct function *fn, struct data_in *data_in,
967*38fd1498Szrj                             struct lto_input_block *ib)
968*38fd1498Szrj {
969*38fd1498Szrj   struct bitpack_d bp;
970*38fd1498Szrj   int len;
971*38fd1498Szrj 
972*38fd1498Szrj   /* Read the static chain and non-local goto save area.  */
973*38fd1498Szrj   fn->static_chain_decl = stream_read_tree (ib, data_in);
974*38fd1498Szrj   fn->nonlocal_goto_save_area = stream_read_tree (ib, data_in);
975*38fd1498Szrj 
976*38fd1498Szrj   /* Read all the local symbols.  */
977*38fd1498Szrj   len = streamer_read_hwi (ib);
978*38fd1498Szrj   if (len > 0)
979*38fd1498Szrj     {
980*38fd1498Szrj       int i;
981*38fd1498Szrj       vec_safe_grow_cleared (fn->local_decls, len);
982*38fd1498Szrj       for (i = 0; i < len; i++)
983*38fd1498Szrj 	{
984*38fd1498Szrj 	  tree t = stream_read_tree (ib, data_in);
985*38fd1498Szrj 	  (*fn->local_decls)[i] = t;
986*38fd1498Szrj 	}
987*38fd1498Szrj     }
988*38fd1498Szrj 
989*38fd1498Szrj   /* Input the current IL state of the function.  */
990*38fd1498Szrj   fn->curr_properties = streamer_read_uhwi (ib);
991*38fd1498Szrj 
992*38fd1498Szrj   /* Read all the attributes for FN.  */
993*38fd1498Szrj   bp = streamer_read_bitpack (ib);
994*38fd1498Szrj   fn->is_thunk = bp_unpack_value (&bp, 1);
995*38fd1498Szrj   fn->has_local_explicit_reg_vars = bp_unpack_value (&bp, 1);
996*38fd1498Szrj   fn->returns_pcc_struct = bp_unpack_value (&bp, 1);
997*38fd1498Szrj   fn->returns_struct = bp_unpack_value (&bp, 1);
998*38fd1498Szrj   fn->can_throw_non_call_exceptions = bp_unpack_value (&bp, 1);
999*38fd1498Szrj   fn->can_delete_dead_exceptions = bp_unpack_value (&bp, 1);
1000*38fd1498Szrj   fn->always_inline_functions_inlined = bp_unpack_value (&bp, 1);
1001*38fd1498Szrj   fn->after_inlining = bp_unpack_value (&bp, 1);
1002*38fd1498Szrj   fn->stdarg = bp_unpack_value (&bp, 1);
1003*38fd1498Szrj   fn->has_nonlocal_label = bp_unpack_value (&bp, 1);
1004*38fd1498Szrj   fn->has_forced_label_in_static = bp_unpack_value (&bp, 1);
1005*38fd1498Szrj   fn->calls_alloca = bp_unpack_value (&bp, 1);
1006*38fd1498Szrj   fn->calls_setjmp = bp_unpack_value (&bp, 1);
1007*38fd1498Szrj   fn->has_force_vectorize_loops = bp_unpack_value (&bp, 1);
1008*38fd1498Szrj   fn->has_simduid_loops = bp_unpack_value (&bp, 1);
1009*38fd1498Szrj   fn->va_list_fpr_size = bp_unpack_value (&bp, 8);
1010*38fd1498Szrj   fn->va_list_gpr_size = bp_unpack_value (&bp, 8);
1011*38fd1498Szrj   fn->last_clique = bp_unpack_value (&bp, sizeof (short) * 8);
1012*38fd1498Szrj 
1013*38fd1498Szrj   /* Input the function start and end loci.  */
1014*38fd1498Szrj   fn->function_start_locus = stream_input_location_now (&bp, data_in);
1015*38fd1498Szrj   fn->function_end_locus = stream_input_location_now (&bp, data_in);
1016*38fd1498Szrj }
1017*38fd1498Szrj 
1018*38fd1498Szrj 
1019*38fd1498Szrj /* Read the body of function FN_DECL from DATA_IN using input block IB.  */
1020*38fd1498Szrj 
1021*38fd1498Szrj static void
input_function(tree fn_decl,struct data_in * data_in,struct lto_input_block * ib,struct lto_input_block * ib_cfg)1022*38fd1498Szrj input_function (tree fn_decl, struct data_in *data_in,
1023*38fd1498Szrj 		struct lto_input_block *ib, struct lto_input_block *ib_cfg)
1024*38fd1498Szrj {
1025*38fd1498Szrj   struct function *fn;
1026*38fd1498Szrj   enum LTO_tags tag;
1027*38fd1498Szrj   gimple **stmts;
1028*38fd1498Szrj   basic_block bb;
1029*38fd1498Szrj   struct cgraph_node *node;
1030*38fd1498Szrj 
1031*38fd1498Szrj   tag = streamer_read_record_start (ib);
1032*38fd1498Szrj   lto_tag_check (tag, LTO_function);
1033*38fd1498Szrj 
1034*38fd1498Szrj   /* Read decls for parameters and args.  */
1035*38fd1498Szrj   DECL_RESULT (fn_decl) = stream_read_tree (ib, data_in);
1036*38fd1498Szrj   DECL_ARGUMENTS (fn_decl) = streamer_read_chain (ib, data_in);
1037*38fd1498Szrj 
1038*38fd1498Szrj   /* Read debug args if available.  */
1039*38fd1498Szrj   unsigned n_debugargs = streamer_read_uhwi (ib);
1040*38fd1498Szrj   if (n_debugargs)
1041*38fd1498Szrj     {
1042*38fd1498Szrj       vec<tree, va_gc> **debugargs = decl_debug_args_insert (fn_decl);
1043*38fd1498Szrj       vec_safe_grow (*debugargs, n_debugargs);
1044*38fd1498Szrj       for (unsigned i = 0; i < n_debugargs; ++i)
1045*38fd1498Szrj 	(**debugargs)[i] = stream_read_tree (ib, data_in);
1046*38fd1498Szrj     }
1047*38fd1498Szrj 
1048*38fd1498Szrj   /* Read the tree of lexical scopes for the function.  */
1049*38fd1498Szrj   DECL_INITIAL (fn_decl) = stream_read_tree (ib, data_in);
1050*38fd1498Szrj   unsigned block_leaf_count = streamer_read_uhwi (ib);
1051*38fd1498Szrj   while (block_leaf_count--)
1052*38fd1498Szrj     stream_read_tree (ib, data_in);
1053*38fd1498Szrj 
1054*38fd1498Szrj   if (!streamer_read_uhwi (ib))
1055*38fd1498Szrj     return;
1056*38fd1498Szrj 
1057*38fd1498Szrj   push_struct_function (fn_decl);
1058*38fd1498Szrj   fn = DECL_STRUCT_FUNCTION (fn_decl);
1059*38fd1498Szrj   init_tree_ssa (fn);
1060*38fd1498Szrj   /* We input IL in SSA form.  */
1061*38fd1498Szrj   cfun->gimple_df->in_ssa_p = true;
1062*38fd1498Szrj 
1063*38fd1498Szrj   gimple_register_cfg_hooks ();
1064*38fd1498Szrj 
1065*38fd1498Szrj   node = cgraph_node::get (fn_decl);
1066*38fd1498Szrj   if (!node)
1067*38fd1498Szrj     node = cgraph_node::create (fn_decl);
1068*38fd1498Szrj   input_struct_function_base (fn, data_in, ib);
1069*38fd1498Szrj   input_cfg (ib_cfg, data_in, fn);
1070*38fd1498Szrj 
1071*38fd1498Szrj   /* Read all the SSA names.  */
1072*38fd1498Szrj   input_ssa_names (ib, data_in, fn);
1073*38fd1498Szrj 
1074*38fd1498Szrj   /* Read the exception handling regions in the function.  */
1075*38fd1498Szrj   input_eh_regions (ib, data_in, fn);
1076*38fd1498Szrj 
1077*38fd1498Szrj   gcc_assert (DECL_INITIAL (fn_decl));
1078*38fd1498Szrj   DECL_SAVED_TREE (fn_decl) = NULL_TREE;
1079*38fd1498Szrj 
1080*38fd1498Szrj   /* Read all the basic blocks.  */
1081*38fd1498Szrj   tag = streamer_read_record_start (ib);
1082*38fd1498Szrj   while (tag)
1083*38fd1498Szrj     {
1084*38fd1498Szrj       input_bb (ib, tag, data_in, fn,
1085*38fd1498Szrj 		node->count_materialization_scale);
1086*38fd1498Szrj       tag = streamer_read_record_start (ib);
1087*38fd1498Szrj     }
1088*38fd1498Szrj 
1089*38fd1498Szrj   /* Fix up the call statements that are mentioned in the callgraph
1090*38fd1498Szrj      edges.  */
1091*38fd1498Szrj   set_gimple_stmt_max_uid (cfun, 0);
1092*38fd1498Szrj   FOR_ALL_BB_FN (bb, cfun)
1093*38fd1498Szrj     {
1094*38fd1498Szrj       gimple_stmt_iterator gsi;
1095*38fd1498Szrj       for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1096*38fd1498Szrj 	{
1097*38fd1498Szrj 	  gimple *stmt = gsi_stmt (gsi);
1098*38fd1498Szrj 	  gimple_set_uid (stmt, inc_gimple_stmt_max_uid (cfun));
1099*38fd1498Szrj 	}
1100*38fd1498Szrj       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1101*38fd1498Szrj 	{
1102*38fd1498Szrj 	  gimple *stmt = gsi_stmt (gsi);
1103*38fd1498Szrj 	  gimple_set_uid (stmt, inc_gimple_stmt_max_uid (cfun));
1104*38fd1498Szrj 	}
1105*38fd1498Szrj     }
1106*38fd1498Szrj   stmts = (gimple **) xcalloc (gimple_stmt_max_uid (fn), sizeof (gimple *));
1107*38fd1498Szrj   FOR_ALL_BB_FN (bb, cfun)
1108*38fd1498Szrj     {
1109*38fd1498Szrj       gimple_stmt_iterator bsi = gsi_start_phis (bb);
1110*38fd1498Szrj       while (!gsi_end_p (bsi))
1111*38fd1498Szrj 	{
1112*38fd1498Szrj 	  gimple *stmt = gsi_stmt (bsi);
1113*38fd1498Szrj 	  gsi_next (&bsi);
1114*38fd1498Szrj 	  stmts[gimple_uid (stmt)] = stmt;
1115*38fd1498Szrj 	}
1116*38fd1498Szrj       bsi = gsi_start_bb (bb);
1117*38fd1498Szrj       while (!gsi_end_p (bsi))
1118*38fd1498Szrj 	{
1119*38fd1498Szrj 	  gimple *stmt = gsi_stmt (bsi);
1120*38fd1498Szrj 	  bool remove = false;
1121*38fd1498Szrj 	  /* If we're recompiling LTO objects with debug stmts but
1122*38fd1498Szrj 	     we're not supposed to have debug stmts, remove them now.
1123*38fd1498Szrj 	     We can't remove them earlier because this would cause uid
1124*38fd1498Szrj 	     mismatches in fixups, but we can do it at this point, as
1125*38fd1498Szrj 	     long as debug stmts don't require fixups.
1126*38fd1498Szrj 	     Similarly remove all IFN_*SAN_* internal calls   */
1127*38fd1498Szrj 	  if (!flag_wpa)
1128*38fd1498Szrj 	    {
1129*38fd1498Szrj 	      if (is_gimple_debug (stmt)
1130*38fd1498Szrj 		  && (gimple_debug_nonbind_marker_p (stmt)
1131*38fd1498Szrj 		      ? !MAY_HAVE_DEBUG_MARKER_STMTS
1132*38fd1498Szrj 		      : !MAY_HAVE_DEBUG_BIND_STMTS))
1133*38fd1498Szrj 		remove = true;
1134*38fd1498Szrj 	      if (is_gimple_call (stmt)
1135*38fd1498Szrj 		  && gimple_call_internal_p (stmt))
1136*38fd1498Szrj 		{
1137*38fd1498Szrj 		  bool replace = false;
1138*38fd1498Szrj 		  switch (gimple_call_internal_fn (stmt))
1139*38fd1498Szrj 		    {
1140*38fd1498Szrj 		    case IFN_UBSAN_NULL:
1141*38fd1498Szrj 		      if ((flag_sanitize
1142*38fd1498Szrj 			  & (SANITIZE_NULL | SANITIZE_ALIGNMENT)) == 0)
1143*38fd1498Szrj 			replace = true;
1144*38fd1498Szrj 		      break;
1145*38fd1498Szrj 		    case IFN_UBSAN_BOUNDS:
1146*38fd1498Szrj 		      if ((flag_sanitize & SANITIZE_BOUNDS) == 0)
1147*38fd1498Szrj 			replace = true;
1148*38fd1498Szrj 		      break;
1149*38fd1498Szrj 		    case IFN_UBSAN_VPTR:
1150*38fd1498Szrj 		      if ((flag_sanitize & SANITIZE_VPTR) == 0)
1151*38fd1498Szrj 			replace = true;
1152*38fd1498Szrj 		      break;
1153*38fd1498Szrj 		    case IFN_UBSAN_OBJECT_SIZE:
1154*38fd1498Szrj 		      if ((flag_sanitize & SANITIZE_OBJECT_SIZE) == 0)
1155*38fd1498Szrj 			replace = true;
1156*38fd1498Szrj 		      break;
1157*38fd1498Szrj 		    case IFN_UBSAN_PTR:
1158*38fd1498Szrj 		      if ((flag_sanitize & SANITIZE_POINTER_OVERFLOW) == 0)
1159*38fd1498Szrj 			replace = true;
1160*38fd1498Szrj 		      break;
1161*38fd1498Szrj 		    case IFN_ASAN_MARK:
1162*38fd1498Szrj 		      if ((flag_sanitize & SANITIZE_ADDRESS) == 0)
1163*38fd1498Szrj 			replace = true;
1164*38fd1498Szrj 		      break;
1165*38fd1498Szrj 		    case IFN_TSAN_FUNC_EXIT:
1166*38fd1498Szrj 		      if ((flag_sanitize & SANITIZE_THREAD) == 0)
1167*38fd1498Szrj 			replace = true;
1168*38fd1498Szrj 		      break;
1169*38fd1498Szrj 		    default:
1170*38fd1498Szrj 		      break;
1171*38fd1498Szrj 		    }
1172*38fd1498Szrj 		  if (replace)
1173*38fd1498Szrj 		    {
1174*38fd1498Szrj 		      gimple_call_set_internal_fn (as_a <gcall *> (stmt),
1175*38fd1498Szrj 						   IFN_NOP);
1176*38fd1498Szrj 		      update_stmt (stmt);
1177*38fd1498Szrj 		    }
1178*38fd1498Szrj 		}
1179*38fd1498Szrj 	    }
1180*38fd1498Szrj 	  if (remove)
1181*38fd1498Szrj 	    {
1182*38fd1498Szrj 	      gimple_stmt_iterator gsi = bsi;
1183*38fd1498Szrj 	      gsi_next (&bsi);
1184*38fd1498Szrj 	      unlink_stmt_vdef (stmt);
1185*38fd1498Szrj 	      release_defs (stmt);
1186*38fd1498Szrj 	      gsi_remove (&gsi, true);
1187*38fd1498Szrj 	    }
1188*38fd1498Szrj 	  else
1189*38fd1498Szrj 	    {
1190*38fd1498Szrj 	      gsi_next (&bsi);
1191*38fd1498Szrj 	      stmts[gimple_uid (stmt)] = stmt;
1192*38fd1498Szrj 
1193*38fd1498Szrj 	      /* Remember that the input function has begin stmt
1194*38fd1498Szrj 		 markers, so that we know to expect them when emitting
1195*38fd1498Szrj 		 debug info.  */
1196*38fd1498Szrj 	      if (!cfun->debug_nonbind_markers
1197*38fd1498Szrj 		  && gimple_debug_nonbind_marker_p (stmt))
1198*38fd1498Szrj 		cfun->debug_nonbind_markers = true;
1199*38fd1498Szrj 	    }
1200*38fd1498Szrj 	}
1201*38fd1498Szrj     }
1202*38fd1498Szrj 
1203*38fd1498Szrj   /* Set the gimple body to the statement sequence in the entry
1204*38fd1498Szrj      basic block.  FIXME lto, this is fairly hacky.  The existence
1205*38fd1498Szrj      of a gimple body is used by the cgraph routines, but we should
1206*38fd1498Szrj      really use the presence of the CFG.  */
1207*38fd1498Szrj   {
1208*38fd1498Szrj     edge_iterator ei = ei_start (ENTRY_BLOCK_PTR_FOR_FN (cfun)->succs);
1209*38fd1498Szrj     gimple_set_body (fn_decl, bb_seq (ei_edge (ei)->dest));
1210*38fd1498Szrj   }
1211*38fd1498Szrj 
1212*38fd1498Szrj   update_max_bb_count ();
1213*38fd1498Szrj   fixup_call_stmt_edges (node, stmts);
1214*38fd1498Szrj   execute_all_ipa_stmt_fixups (node, stmts);
1215*38fd1498Szrj 
1216*38fd1498Szrj   update_ssa (TODO_update_ssa_only_virtuals);
1217*38fd1498Szrj   free_dominance_info (CDI_DOMINATORS);
1218*38fd1498Szrj   free_dominance_info (CDI_POST_DOMINATORS);
1219*38fd1498Szrj   free (stmts);
1220*38fd1498Szrj   pop_cfun ();
1221*38fd1498Szrj }
1222*38fd1498Szrj 
1223*38fd1498Szrj /* Read the body of function FN_DECL from DATA_IN using input block IB.  */
1224*38fd1498Szrj 
1225*38fd1498Szrj static void
input_constructor(tree var,struct data_in * data_in,struct lto_input_block * ib)1226*38fd1498Szrj input_constructor (tree var, struct data_in *data_in,
1227*38fd1498Szrj 		   struct lto_input_block *ib)
1228*38fd1498Szrj {
1229*38fd1498Szrj   DECL_INITIAL (var) = stream_read_tree (ib, data_in);
1230*38fd1498Szrj }
1231*38fd1498Szrj 
1232*38fd1498Szrj 
1233*38fd1498Szrj /* Read the body from DATA for function NODE and fill it in.
1234*38fd1498Szrj    FILE_DATA are the global decls and types.  SECTION_TYPE is either
1235*38fd1498Szrj    LTO_section_function_body or LTO_section_static_initializer.  If
1236*38fd1498Szrj    section type is LTO_section_function_body, FN must be the decl for
1237*38fd1498Szrj    that function.  */
1238*38fd1498Szrj 
1239*38fd1498Szrj static void
lto_read_body_or_constructor(struct lto_file_decl_data * file_data,struct symtab_node * node,const char * data,enum lto_section_type section_type)1240*38fd1498Szrj lto_read_body_or_constructor (struct lto_file_decl_data *file_data, struct symtab_node *node,
1241*38fd1498Szrj 			      const char *data, enum lto_section_type section_type)
1242*38fd1498Szrj {
1243*38fd1498Szrj   const struct lto_function_header *header;
1244*38fd1498Szrj   struct data_in *data_in;
1245*38fd1498Szrj   int cfg_offset;
1246*38fd1498Szrj   int main_offset;
1247*38fd1498Szrj   int string_offset;
1248*38fd1498Szrj   tree fn_decl = node->decl;
1249*38fd1498Szrj 
1250*38fd1498Szrj   header = (const struct lto_function_header *) data;
1251*38fd1498Szrj   if (TREE_CODE (node->decl) == FUNCTION_DECL)
1252*38fd1498Szrj     {
1253*38fd1498Szrj       cfg_offset = sizeof (struct lto_function_header);
1254*38fd1498Szrj       main_offset = cfg_offset + header->cfg_size;
1255*38fd1498Szrj       string_offset = main_offset + header->main_size;
1256*38fd1498Szrj     }
1257*38fd1498Szrj   else
1258*38fd1498Szrj     {
1259*38fd1498Szrj       main_offset = sizeof (struct lto_function_header);
1260*38fd1498Szrj       string_offset = main_offset + header->main_size;
1261*38fd1498Szrj     }
1262*38fd1498Szrj 
1263*38fd1498Szrj   data_in = lto_data_in_create (file_data, data + string_offset,
1264*38fd1498Szrj 			      header->string_size, vNULL);
1265*38fd1498Szrj 
1266*38fd1498Szrj   if (section_type == LTO_section_function_body)
1267*38fd1498Szrj     {
1268*38fd1498Szrj       struct lto_in_decl_state *decl_state;
1269*38fd1498Szrj       unsigned from;
1270*38fd1498Szrj 
1271*38fd1498Szrj       gcc_checking_assert (node);
1272*38fd1498Szrj 
1273*38fd1498Szrj       /* Use the function's decl state. */
1274*38fd1498Szrj       decl_state = lto_get_function_in_decl_state (file_data, fn_decl);
1275*38fd1498Szrj       gcc_assert (decl_state);
1276*38fd1498Szrj       file_data->current_decl_state = decl_state;
1277*38fd1498Szrj 
1278*38fd1498Szrj 
1279*38fd1498Szrj       /* Set up the struct function.  */
1280*38fd1498Szrj       from = data_in->reader_cache->nodes.length ();
1281*38fd1498Szrj       lto_input_block ib_main (data + main_offset, header->main_size,
1282*38fd1498Szrj 			       file_data->mode_table);
1283*38fd1498Szrj       if (TREE_CODE (node->decl) == FUNCTION_DECL)
1284*38fd1498Szrj 	{
1285*38fd1498Szrj 	  lto_input_block ib_cfg (data + cfg_offset, header->cfg_size,
1286*38fd1498Szrj 				  file_data->mode_table);
1287*38fd1498Szrj 	  input_function (fn_decl, data_in, &ib_main, &ib_cfg);
1288*38fd1498Szrj 	}
1289*38fd1498Szrj       else
1290*38fd1498Szrj         input_constructor (fn_decl, data_in, &ib_main);
1291*38fd1498Szrj       data_in->location_cache.apply_location_cache ();
1292*38fd1498Szrj       /* And fixup types we streamed locally.  */
1293*38fd1498Szrj 	{
1294*38fd1498Szrj 	  struct streamer_tree_cache_d *cache = data_in->reader_cache;
1295*38fd1498Szrj 	  unsigned len = cache->nodes.length ();
1296*38fd1498Szrj 	  unsigned i;
1297*38fd1498Szrj 	  for (i = len; i-- > from;)
1298*38fd1498Szrj 	    {
1299*38fd1498Szrj 	      tree t = streamer_tree_cache_get_tree (cache, i);
1300*38fd1498Szrj 	      if (t == NULL_TREE)
1301*38fd1498Szrj 		continue;
1302*38fd1498Szrj 
1303*38fd1498Szrj 	      if (TYPE_P (t))
1304*38fd1498Szrj 		{
1305*38fd1498Szrj 		  gcc_assert (TYPE_CANONICAL (t) == NULL_TREE);
1306*38fd1498Szrj 		  if (type_with_alias_set_p (t)
1307*38fd1498Szrj 		      && canonical_type_used_p (t))
1308*38fd1498Szrj 		    TYPE_CANONICAL (t) = TYPE_MAIN_VARIANT (t);
1309*38fd1498Szrj 		  if (TYPE_MAIN_VARIANT (t) != t)
1310*38fd1498Szrj 		    {
1311*38fd1498Szrj 		      gcc_assert (TYPE_NEXT_VARIANT (t) == NULL_TREE);
1312*38fd1498Szrj 		      TYPE_NEXT_VARIANT (t)
1313*38fd1498Szrj 			= TYPE_NEXT_VARIANT (TYPE_MAIN_VARIANT (t));
1314*38fd1498Szrj 		      TYPE_NEXT_VARIANT (TYPE_MAIN_VARIANT (t)) = t;
1315*38fd1498Szrj 		    }
1316*38fd1498Szrj 		}
1317*38fd1498Szrj 	    }
1318*38fd1498Szrj 	}
1319*38fd1498Szrj 
1320*38fd1498Szrj       /* Restore decl state */
1321*38fd1498Szrj       file_data->current_decl_state = file_data->global_decl_state;
1322*38fd1498Szrj     }
1323*38fd1498Szrj 
1324*38fd1498Szrj   lto_data_in_delete (data_in);
1325*38fd1498Szrj }
1326*38fd1498Szrj 
1327*38fd1498Szrj 
1328*38fd1498Szrj /* Read the body of NODE using DATA.  FILE_DATA holds the global
1329*38fd1498Szrj    decls and types.  */
1330*38fd1498Szrj 
1331*38fd1498Szrj void
lto_input_function_body(struct lto_file_decl_data * file_data,struct cgraph_node * node,const char * data)1332*38fd1498Szrj lto_input_function_body (struct lto_file_decl_data *file_data,
1333*38fd1498Szrj 			 struct cgraph_node *node, const char *data)
1334*38fd1498Szrj {
1335*38fd1498Szrj   lto_read_body_or_constructor (file_data, node, data, LTO_section_function_body);
1336*38fd1498Szrj }
1337*38fd1498Szrj 
1338*38fd1498Szrj /* Read the body of NODE using DATA.  FILE_DATA holds the global
1339*38fd1498Szrj    decls and types.  */
1340*38fd1498Szrj 
1341*38fd1498Szrj void
lto_input_variable_constructor(struct lto_file_decl_data * file_data,struct varpool_node * node,const char * data)1342*38fd1498Szrj lto_input_variable_constructor (struct lto_file_decl_data *file_data,
1343*38fd1498Szrj 				struct varpool_node *node, const char *data)
1344*38fd1498Szrj {
1345*38fd1498Szrj   lto_read_body_or_constructor (file_data, node, data, LTO_section_function_body);
1346*38fd1498Szrj }
1347*38fd1498Szrj 
1348*38fd1498Szrj 
1349*38fd1498Szrj /* Queue of acummulated decl -> DIE mappings.  Similar to locations those
1350*38fd1498Szrj    are only applied to prevailing tree nodes during tree merging.  */
1351*38fd1498Szrj vec<dref_entry> dref_queue;
1352*38fd1498Szrj 
1353*38fd1498Szrj /* Read the physical representation of a tree node EXPR from
1354*38fd1498Szrj    input block IB using the per-file context in DATA_IN.  */
1355*38fd1498Szrj 
1356*38fd1498Szrj static void
lto_read_tree_1(struct lto_input_block * ib,struct data_in * data_in,tree expr)1357*38fd1498Szrj lto_read_tree_1 (struct lto_input_block *ib, struct data_in *data_in, tree expr)
1358*38fd1498Szrj {
1359*38fd1498Szrj   /* Read all the bitfield values in EXPR.  Note that for LTO, we
1360*38fd1498Szrj      only write language-independent bitfields, so no more unpacking is
1361*38fd1498Szrj      needed.  */
1362*38fd1498Szrj   streamer_read_tree_bitfields (ib, data_in, expr);
1363*38fd1498Szrj 
1364*38fd1498Szrj   /* Read all the pointer fields in EXPR.  */
1365*38fd1498Szrj   streamer_read_tree_body (ib, data_in, expr);
1366*38fd1498Szrj 
1367*38fd1498Szrj   /* Read any LTO-specific data not read by the tree streamer.  */
1368*38fd1498Szrj   if (DECL_P (expr)
1369*38fd1498Szrj       && TREE_CODE (expr) != FUNCTION_DECL
1370*38fd1498Szrj       && TREE_CODE (expr) != TRANSLATION_UNIT_DECL)
1371*38fd1498Szrj     DECL_INITIAL (expr) = stream_read_tree (ib, data_in);
1372*38fd1498Szrj 
1373*38fd1498Szrj   /* Stream references to early generated DIEs.  Keep in sync with the
1374*38fd1498Szrj      trees handled in dwarf2out_register_external_die.  */
1375*38fd1498Szrj   if ((DECL_P (expr)
1376*38fd1498Szrj        && TREE_CODE (expr) != FIELD_DECL
1377*38fd1498Szrj        && TREE_CODE (expr) != DEBUG_EXPR_DECL
1378*38fd1498Szrj        && TREE_CODE (expr) != TYPE_DECL)
1379*38fd1498Szrj       || TREE_CODE (expr) == BLOCK)
1380*38fd1498Szrj     {
1381*38fd1498Szrj       const char *str = streamer_read_string (data_in, ib);
1382*38fd1498Szrj       if (str)
1383*38fd1498Szrj 	{
1384*38fd1498Szrj 	  unsigned HOST_WIDE_INT off = streamer_read_uhwi (ib);
1385*38fd1498Szrj 	  dref_entry e = { expr, str, off };
1386*38fd1498Szrj 	  dref_queue.safe_push (e);
1387*38fd1498Szrj 	}
1388*38fd1498Szrj     }
1389*38fd1498Szrj }
1390*38fd1498Szrj 
1391*38fd1498Szrj /* Read the physical representation of a tree node with tag TAG from
1392*38fd1498Szrj    input block IB using the per-file context in DATA_IN.  */
1393*38fd1498Szrj 
1394*38fd1498Szrj static tree
lto_read_tree(struct lto_input_block * ib,struct data_in * data_in,enum LTO_tags tag,hashval_t hash)1395*38fd1498Szrj lto_read_tree (struct lto_input_block *ib, struct data_in *data_in,
1396*38fd1498Szrj 	       enum LTO_tags tag, hashval_t hash)
1397*38fd1498Szrj {
1398*38fd1498Szrj   /* Instantiate a new tree node.  */
1399*38fd1498Szrj   tree result = streamer_alloc_tree (ib, data_in, tag);
1400*38fd1498Szrj 
1401*38fd1498Szrj   /* Enter RESULT in the reader cache.  This will make RESULT
1402*38fd1498Szrj      available so that circular references in the rest of the tree
1403*38fd1498Szrj      structure can be resolved in subsequent calls to stream_read_tree.  */
1404*38fd1498Szrj   streamer_tree_cache_append (data_in->reader_cache, result, hash);
1405*38fd1498Szrj 
1406*38fd1498Szrj   lto_read_tree_1 (ib, data_in, result);
1407*38fd1498Szrj 
1408*38fd1498Szrj   /* end_marker = */ streamer_read_uchar (ib);
1409*38fd1498Szrj 
1410*38fd1498Szrj   return result;
1411*38fd1498Szrj }
1412*38fd1498Szrj 
1413*38fd1498Szrj 
1414*38fd1498Szrj /* Populate the reader cache with trees materialized from the SCC
1415*38fd1498Szrj    following in the IB, DATA_IN stream.  */
1416*38fd1498Szrj 
1417*38fd1498Szrj hashval_t
lto_input_scc(struct lto_input_block * ib,struct data_in * data_in,unsigned * len,unsigned * entry_len)1418*38fd1498Szrj lto_input_scc (struct lto_input_block *ib, struct data_in *data_in,
1419*38fd1498Szrj 	       unsigned *len, unsigned *entry_len)
1420*38fd1498Szrj {
1421*38fd1498Szrj   /* A blob of unnamed tree nodes, fill the cache from it and
1422*38fd1498Szrj      recurse.  */
1423*38fd1498Szrj   unsigned size = streamer_read_uhwi (ib);
1424*38fd1498Szrj   hashval_t scc_hash = streamer_read_uhwi (ib);
1425*38fd1498Szrj   unsigned scc_entry_len = 1;
1426*38fd1498Szrj 
1427*38fd1498Szrj   if (size == 1)
1428*38fd1498Szrj     {
1429*38fd1498Szrj       enum LTO_tags tag = streamer_read_record_start (ib);
1430*38fd1498Szrj       lto_input_tree_1 (ib, data_in, tag, scc_hash);
1431*38fd1498Szrj     }
1432*38fd1498Szrj   else
1433*38fd1498Szrj     {
1434*38fd1498Szrj       unsigned int first = data_in->reader_cache->nodes.length ();
1435*38fd1498Szrj       tree result;
1436*38fd1498Szrj 
1437*38fd1498Szrj       scc_entry_len = streamer_read_uhwi (ib);
1438*38fd1498Szrj 
1439*38fd1498Szrj       /* Materialize size trees by reading their headers.  */
1440*38fd1498Szrj       for (unsigned i = 0; i < size; ++i)
1441*38fd1498Szrj 	{
1442*38fd1498Szrj 	  enum LTO_tags tag = streamer_read_record_start (ib);
1443*38fd1498Szrj 	  if (tag == LTO_null
1444*38fd1498Szrj 	      || (tag >= LTO_field_decl_ref && tag <= LTO_global_decl_ref)
1445*38fd1498Szrj 	      || tag == LTO_tree_pickle_reference
1446*38fd1498Szrj 	      || tag == LTO_integer_cst
1447*38fd1498Szrj 	      || tag == LTO_tree_scc)
1448*38fd1498Szrj 	    gcc_unreachable ();
1449*38fd1498Szrj 
1450*38fd1498Szrj 	  result = streamer_alloc_tree (ib, data_in, tag);
1451*38fd1498Szrj 	  streamer_tree_cache_append (data_in->reader_cache, result, 0);
1452*38fd1498Szrj 	}
1453*38fd1498Szrj 
1454*38fd1498Szrj       /* Read the tree bitpacks and references.  */
1455*38fd1498Szrj       for (unsigned i = 0; i < size; ++i)
1456*38fd1498Szrj 	{
1457*38fd1498Szrj 	  result = streamer_tree_cache_get_tree (data_in->reader_cache,
1458*38fd1498Szrj 						 first + i);
1459*38fd1498Szrj 	  lto_read_tree_1 (ib, data_in, result);
1460*38fd1498Szrj 	  /* end_marker = */ streamer_read_uchar (ib);
1461*38fd1498Szrj 	}
1462*38fd1498Szrj     }
1463*38fd1498Szrj 
1464*38fd1498Szrj   *len = size;
1465*38fd1498Szrj   *entry_len = scc_entry_len;
1466*38fd1498Szrj   return scc_hash;
1467*38fd1498Szrj }
1468*38fd1498Szrj 
1469*38fd1498Szrj 
1470*38fd1498Szrj /* Read a tree from input block IB using the per-file context in
1471*38fd1498Szrj    DATA_IN.  This context is used, for example, to resolve references
1472*38fd1498Szrj    to previously read nodes.  */
1473*38fd1498Szrj 
1474*38fd1498Szrj tree
lto_input_tree_1(struct lto_input_block * ib,struct data_in * data_in,enum LTO_tags tag,hashval_t hash)1475*38fd1498Szrj lto_input_tree_1 (struct lto_input_block *ib, struct data_in *data_in,
1476*38fd1498Szrj 		  enum LTO_tags tag, hashval_t hash)
1477*38fd1498Szrj {
1478*38fd1498Szrj   tree result;
1479*38fd1498Szrj 
1480*38fd1498Szrj   gcc_assert ((unsigned) tag < (unsigned) LTO_NUM_TAGS);
1481*38fd1498Szrj 
1482*38fd1498Szrj   if (tag == LTO_null)
1483*38fd1498Szrj     result = NULL_TREE;
1484*38fd1498Szrj   else if (tag >= LTO_field_decl_ref && tag <= LTO_namelist_decl_ref)
1485*38fd1498Szrj     {
1486*38fd1498Szrj       /* If TAG is a reference to an indexable tree, the next value
1487*38fd1498Szrj 	 in IB is the index into the table where we expect to find
1488*38fd1498Szrj 	 that tree.  */
1489*38fd1498Szrj       result = lto_input_tree_ref (ib, data_in, cfun, tag);
1490*38fd1498Szrj     }
1491*38fd1498Szrj   else if (tag == LTO_tree_pickle_reference)
1492*38fd1498Szrj     {
1493*38fd1498Szrj       /* If TAG is a reference to a previously read tree, look it up in
1494*38fd1498Szrj 	 the reader cache.  */
1495*38fd1498Szrj       result = streamer_get_pickled_tree (ib, data_in);
1496*38fd1498Szrj     }
1497*38fd1498Szrj   else if (tag == LTO_integer_cst)
1498*38fd1498Szrj     {
1499*38fd1498Szrj       /* For shared integer constants in singletons we can use the
1500*38fd1498Szrj          existing tree integer constant merging code.  */
1501*38fd1498Szrj       tree type = stream_read_tree (ib, data_in);
1502*38fd1498Szrj       unsigned HOST_WIDE_INT len = streamer_read_uhwi (ib);
1503*38fd1498Szrj       unsigned HOST_WIDE_INT i;
1504*38fd1498Szrj       HOST_WIDE_INT a[WIDE_INT_MAX_ELTS];
1505*38fd1498Szrj 
1506*38fd1498Szrj       for (i = 0; i < len; i++)
1507*38fd1498Szrj 	a[i] = streamer_read_hwi (ib);
1508*38fd1498Szrj       gcc_assert (TYPE_PRECISION (type) <= MAX_BITSIZE_MODE_ANY_INT);
1509*38fd1498Szrj       result = wide_int_to_tree (type, wide_int::from_array
1510*38fd1498Szrj 				 (a, len, TYPE_PRECISION (type)));
1511*38fd1498Szrj       streamer_tree_cache_append (data_in->reader_cache, result, hash);
1512*38fd1498Szrj     }
1513*38fd1498Szrj   else if (tag == LTO_tree_scc)
1514*38fd1498Szrj     gcc_unreachable ();
1515*38fd1498Szrj   else
1516*38fd1498Szrj     {
1517*38fd1498Szrj       /* Otherwise, materialize a new node from IB.  */
1518*38fd1498Szrj       result = lto_read_tree (ib, data_in, tag, hash);
1519*38fd1498Szrj     }
1520*38fd1498Szrj 
1521*38fd1498Szrj   return result;
1522*38fd1498Szrj }
1523*38fd1498Szrj 
1524*38fd1498Szrj tree
lto_input_tree(struct lto_input_block * ib,struct data_in * data_in)1525*38fd1498Szrj lto_input_tree (struct lto_input_block *ib, struct data_in *data_in)
1526*38fd1498Szrj {
1527*38fd1498Szrj   enum LTO_tags tag;
1528*38fd1498Szrj 
1529*38fd1498Szrj   /* Input and skip SCCs.  */
1530*38fd1498Szrj   while ((tag = streamer_read_record_start (ib)) == LTO_tree_scc)
1531*38fd1498Szrj     {
1532*38fd1498Szrj       unsigned len, entry_len;
1533*38fd1498Szrj       lto_input_scc (ib, data_in, &len, &entry_len);
1534*38fd1498Szrj 
1535*38fd1498Szrj       /* Register DECLs with the debuginfo machinery.  */
1536*38fd1498Szrj       while (!dref_queue.is_empty ())
1537*38fd1498Szrj 	{
1538*38fd1498Szrj 	  dref_entry e = dref_queue.pop ();
1539*38fd1498Szrj 	  debug_hooks->register_external_die (e.decl, e.sym, e.off);
1540*38fd1498Szrj 	}
1541*38fd1498Szrj     }
1542*38fd1498Szrj   return lto_input_tree_1 (ib, data_in, tag, 0);
1543*38fd1498Szrj }
1544*38fd1498Szrj 
1545*38fd1498Szrj 
1546*38fd1498Szrj /* Input toplevel asms.  */
1547*38fd1498Szrj 
1548*38fd1498Szrj void
lto_input_toplevel_asms(struct lto_file_decl_data * file_data,int order_base)1549*38fd1498Szrj lto_input_toplevel_asms (struct lto_file_decl_data *file_data, int order_base)
1550*38fd1498Szrj {
1551*38fd1498Szrj   size_t len;
1552*38fd1498Szrj   const char *data = lto_get_section_data (file_data, LTO_section_asm,
1553*38fd1498Szrj 					   NULL, &len);
1554*38fd1498Szrj   const struct lto_simple_header_with_strings *header
1555*38fd1498Szrj     = (const struct lto_simple_header_with_strings *) data;
1556*38fd1498Szrj   int string_offset;
1557*38fd1498Szrj   struct data_in *data_in;
1558*38fd1498Szrj   tree str;
1559*38fd1498Szrj 
1560*38fd1498Szrj   if (! data)
1561*38fd1498Szrj     return;
1562*38fd1498Szrj 
1563*38fd1498Szrj   string_offset = sizeof (*header) + header->main_size;
1564*38fd1498Szrj 
1565*38fd1498Szrj   lto_input_block ib (data + sizeof (*header), header->main_size,
1566*38fd1498Szrj 		      file_data->mode_table);
1567*38fd1498Szrj 
1568*38fd1498Szrj   data_in = lto_data_in_create (file_data, data + string_offset,
1569*38fd1498Szrj 			      header->string_size, vNULL);
1570*38fd1498Szrj 
1571*38fd1498Szrj   while ((str = streamer_read_string_cst (data_in, &ib)))
1572*38fd1498Szrj     {
1573*38fd1498Szrj       asm_node *node = symtab->finalize_toplevel_asm (str);
1574*38fd1498Szrj       node->order = streamer_read_hwi (&ib) + order_base;
1575*38fd1498Szrj       if (node->order >= symtab->order)
1576*38fd1498Szrj 	symtab->order = node->order + 1;
1577*38fd1498Szrj     }
1578*38fd1498Szrj 
1579*38fd1498Szrj   lto_data_in_delete (data_in);
1580*38fd1498Szrj 
1581*38fd1498Szrj   lto_free_section_data (file_data, LTO_section_asm, NULL, data, len);
1582*38fd1498Szrj }
1583*38fd1498Szrj 
1584*38fd1498Szrj 
1585*38fd1498Szrj /* Input mode table.  */
1586*38fd1498Szrj 
1587*38fd1498Szrj void
lto_input_mode_table(struct lto_file_decl_data * file_data)1588*38fd1498Szrj lto_input_mode_table (struct lto_file_decl_data *file_data)
1589*38fd1498Szrj {
1590*38fd1498Szrj   size_t len;
1591*38fd1498Szrj   const char *data = lto_get_section_data (file_data, LTO_section_mode_table,
1592*38fd1498Szrj 					   NULL, &len);
1593*38fd1498Szrj   if (! data)
1594*38fd1498Szrj     {
1595*38fd1498Szrj       internal_error ("cannot read LTO mode table from %s",
1596*38fd1498Szrj 		      file_data->file_name);
1597*38fd1498Szrj       return;
1598*38fd1498Szrj     }
1599*38fd1498Szrj 
1600*38fd1498Szrj   unsigned char *table = ggc_cleared_vec_alloc<unsigned char> (1 << 8);
1601*38fd1498Szrj   file_data->mode_table = table;
1602*38fd1498Szrj   const struct lto_simple_header_with_strings *header
1603*38fd1498Szrj     = (const struct lto_simple_header_with_strings *) data;
1604*38fd1498Szrj   int string_offset;
1605*38fd1498Szrj   struct data_in *data_in;
1606*38fd1498Szrj   string_offset = sizeof (*header) + header->main_size;
1607*38fd1498Szrj 
1608*38fd1498Szrj   lto_input_block ib (data + sizeof (*header), header->main_size, NULL);
1609*38fd1498Szrj   data_in = lto_data_in_create (file_data, data + string_offset,
1610*38fd1498Szrj 				header->string_size, vNULL);
1611*38fd1498Szrj   bitpack_d bp = streamer_read_bitpack (&ib);
1612*38fd1498Szrj 
1613*38fd1498Szrj   table[VOIDmode] = VOIDmode;
1614*38fd1498Szrj   table[BLKmode] = BLKmode;
1615*38fd1498Szrj   unsigned int m;
1616*38fd1498Szrj   while ((m = bp_unpack_value (&bp, 8)) != VOIDmode)
1617*38fd1498Szrj     {
1618*38fd1498Szrj       enum mode_class mclass
1619*38fd1498Szrj 	= bp_unpack_enum (&bp, mode_class, MAX_MODE_CLASS);
1620*38fd1498Szrj       poly_uint16 size = bp_unpack_poly_value (&bp, 16);
1621*38fd1498Szrj       poly_uint16 prec = bp_unpack_poly_value (&bp, 16);
1622*38fd1498Szrj       machine_mode inner = (machine_mode) bp_unpack_value (&bp, 8);
1623*38fd1498Szrj       poly_uint16 nunits = bp_unpack_poly_value (&bp, 16);
1624*38fd1498Szrj       unsigned int ibit = 0, fbit = 0;
1625*38fd1498Szrj       unsigned int real_fmt_len = 0;
1626*38fd1498Szrj       const char *real_fmt_name = NULL;
1627*38fd1498Szrj       switch (mclass)
1628*38fd1498Szrj 	{
1629*38fd1498Szrj 	case MODE_FRACT:
1630*38fd1498Szrj 	case MODE_UFRACT:
1631*38fd1498Szrj 	case MODE_ACCUM:
1632*38fd1498Szrj 	case MODE_UACCUM:
1633*38fd1498Szrj 	  ibit = bp_unpack_value (&bp, 8);
1634*38fd1498Szrj 	  fbit = bp_unpack_value (&bp, 8);
1635*38fd1498Szrj 	  break;
1636*38fd1498Szrj 	case MODE_FLOAT:
1637*38fd1498Szrj 	case MODE_DECIMAL_FLOAT:
1638*38fd1498Szrj 	  real_fmt_name = bp_unpack_indexed_string (data_in, &bp,
1639*38fd1498Szrj 						    &real_fmt_len);
1640*38fd1498Szrj 	  break;
1641*38fd1498Szrj 	default:
1642*38fd1498Szrj 	  break;
1643*38fd1498Szrj 	}
1644*38fd1498Szrj       /* First search just the GET_CLASS_NARROWEST_MODE to wider modes,
1645*38fd1498Szrj 	 if not found, fallback to all modes.  */
1646*38fd1498Szrj       int pass;
1647*38fd1498Szrj       for (pass = 0; pass < 2; pass++)
1648*38fd1498Szrj 	for (machine_mode mr = pass ? VOIDmode
1649*38fd1498Szrj 				    : GET_CLASS_NARROWEST_MODE (mclass);
1650*38fd1498Szrj 	     pass ? mr < MAX_MACHINE_MODE : mr != VOIDmode;
1651*38fd1498Szrj 	     pass ? mr = (machine_mode) (mr + 1)
1652*38fd1498Szrj 		  : mr = GET_MODE_WIDER_MODE (mr).else_void ())
1653*38fd1498Szrj 	  if (GET_MODE_CLASS (mr) != mclass
1654*38fd1498Szrj 	      || maybe_ne (GET_MODE_SIZE (mr), size)
1655*38fd1498Szrj 	      || maybe_ne (GET_MODE_PRECISION (mr), prec)
1656*38fd1498Szrj 	      || (inner == m
1657*38fd1498Szrj 		  ? GET_MODE_INNER (mr) != mr
1658*38fd1498Szrj 		  : GET_MODE_INNER (mr) != table[(int) inner])
1659*38fd1498Szrj 	      || GET_MODE_IBIT (mr) != ibit
1660*38fd1498Szrj 	      || GET_MODE_FBIT (mr) != fbit
1661*38fd1498Szrj 	      || maybe_ne (GET_MODE_NUNITS (mr), nunits))
1662*38fd1498Szrj 	    continue;
1663*38fd1498Szrj 	  else if ((mclass == MODE_FLOAT || mclass == MODE_DECIMAL_FLOAT)
1664*38fd1498Szrj 		   && strcmp (REAL_MODE_FORMAT (mr)->name, real_fmt_name) != 0)
1665*38fd1498Szrj 	    continue;
1666*38fd1498Szrj 	  else
1667*38fd1498Szrj 	    {
1668*38fd1498Szrj 	      table[m] = mr;
1669*38fd1498Szrj 	      pass = 2;
1670*38fd1498Szrj 	      break;
1671*38fd1498Szrj 	    }
1672*38fd1498Szrj       unsigned int mname_len;
1673*38fd1498Szrj       const char *mname = bp_unpack_indexed_string (data_in, &bp, &mname_len);
1674*38fd1498Szrj       if (pass == 2)
1675*38fd1498Szrj 	{
1676*38fd1498Szrj 	  switch (mclass)
1677*38fd1498Szrj 	    {
1678*38fd1498Szrj 	    case MODE_VECTOR_BOOL:
1679*38fd1498Szrj 	    case MODE_VECTOR_INT:
1680*38fd1498Szrj 	    case MODE_VECTOR_FLOAT:
1681*38fd1498Szrj 	    case MODE_VECTOR_FRACT:
1682*38fd1498Szrj 	    case MODE_VECTOR_UFRACT:
1683*38fd1498Szrj 	    case MODE_VECTOR_ACCUM:
1684*38fd1498Szrj 	    case MODE_VECTOR_UACCUM:
1685*38fd1498Szrj 	      /* For unsupported vector modes just use BLKmode,
1686*38fd1498Szrj 		 if the scalar mode is supported.  */
1687*38fd1498Szrj 	      if (table[(int) inner] != VOIDmode)
1688*38fd1498Szrj 		{
1689*38fd1498Szrj 		  table[m] = BLKmode;
1690*38fd1498Szrj 		  break;
1691*38fd1498Szrj 		}
1692*38fd1498Szrj 	      /* FALLTHRU */
1693*38fd1498Szrj 	    default:
1694*38fd1498Szrj 	      fatal_error (UNKNOWN_LOCATION, "unsupported mode %s\n", mname);
1695*38fd1498Szrj 	      break;
1696*38fd1498Szrj 	    }
1697*38fd1498Szrj 	}
1698*38fd1498Szrj     }
1699*38fd1498Szrj   lto_data_in_delete (data_in);
1700*38fd1498Szrj 
1701*38fd1498Szrj   lto_free_section_data (file_data, LTO_section_mode_table, NULL, data, len);
1702*38fd1498Szrj }
1703*38fd1498Szrj 
1704*38fd1498Szrj 
1705*38fd1498Szrj /* Initialization for the LTO reader.  */
1706*38fd1498Szrj 
1707*38fd1498Szrj void
lto_reader_init(void)1708*38fd1498Szrj lto_reader_init (void)
1709*38fd1498Szrj {
1710*38fd1498Szrj   lto_streamer_init ();
1711*38fd1498Szrj   file_name_hash_table
1712*38fd1498Szrj     = new hash_table<freeing_string_slot_hasher> (37);
1713*38fd1498Szrj }
1714*38fd1498Szrj 
1715*38fd1498Szrj 
1716*38fd1498Szrj /* Create a new data_in object for FILE_DATA. STRINGS is the string
1717*38fd1498Szrj    table to use with LEN strings.  RESOLUTIONS is the vector of linker
1718*38fd1498Szrj    resolutions (NULL if not using a linker plugin).  */
1719*38fd1498Szrj 
1720*38fd1498Szrj struct data_in *
lto_data_in_create(struct lto_file_decl_data * file_data,const char * strings,unsigned len,vec<ld_plugin_symbol_resolution_t> resolutions)1721*38fd1498Szrj lto_data_in_create (struct lto_file_decl_data *file_data, const char *strings,
1722*38fd1498Szrj 		    unsigned len,
1723*38fd1498Szrj 		    vec<ld_plugin_symbol_resolution_t> resolutions)
1724*38fd1498Szrj {
1725*38fd1498Szrj   struct data_in *data_in = new (struct data_in);
1726*38fd1498Szrj   data_in->file_data = file_data;
1727*38fd1498Szrj   data_in->strings = strings;
1728*38fd1498Szrj   data_in->strings_len = len;
1729*38fd1498Szrj   data_in->globals_resolution = resolutions;
1730*38fd1498Szrj   data_in->reader_cache = streamer_tree_cache_create (false, false, true);
1731*38fd1498Szrj   return data_in;
1732*38fd1498Szrj }
1733*38fd1498Szrj 
1734*38fd1498Szrj 
1735*38fd1498Szrj /* Remove DATA_IN.  */
1736*38fd1498Szrj 
1737*38fd1498Szrj void
lto_data_in_delete(struct data_in * data_in)1738*38fd1498Szrj lto_data_in_delete (struct data_in *data_in)
1739*38fd1498Szrj {
1740*38fd1498Szrj   data_in->globals_resolution.release ();
1741*38fd1498Szrj   streamer_tree_cache_delete (data_in->reader_cache);
1742*38fd1498Szrj   delete data_in;
1743*38fd1498Szrj }
1744