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