1*e4b17023SJohn Marino /* Read the GIMPLE representation from a file stream.
2*e4b17023SJohn Marino
3*e4b17023SJohn Marino Copyright 2009, 2010 Free Software Foundation, Inc.
4*e4b17023SJohn Marino Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
5*e4b17023SJohn Marino Re-implemented by Diego Novillo <dnovillo@google.com>
6*e4b17023SJohn Marino
7*e4b17023SJohn Marino This file is part of GCC.
8*e4b17023SJohn Marino
9*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
10*e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
11*e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
12*e4b17023SJohn Marino version.
13*e4b17023SJohn Marino
14*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15*e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
16*e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17*e4b17023SJohn Marino for more details.
18*e4b17023SJohn Marino
19*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
20*e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see
21*e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */
22*e4b17023SJohn Marino
23*e4b17023SJohn Marino #include "config.h"
24*e4b17023SJohn Marino #include "system.h"
25*e4b17023SJohn Marino #include "coretypes.h"
26*e4b17023SJohn Marino #include "tm.h"
27*e4b17023SJohn Marino #include "toplev.h"
28*e4b17023SJohn Marino #include "tree.h"
29*e4b17023SJohn Marino #include "expr.h"
30*e4b17023SJohn Marino #include "flags.h"
31*e4b17023SJohn Marino #include "params.h"
32*e4b17023SJohn Marino #include "input.h"
33*e4b17023SJohn Marino #include "hashtab.h"
34*e4b17023SJohn Marino #include "basic-block.h"
35*e4b17023SJohn Marino #include "tree-flow.h"
36*e4b17023SJohn Marino #include "tree-pass.h"
37*e4b17023SJohn Marino #include "cgraph.h"
38*e4b17023SJohn Marino #include "function.h"
39*e4b17023SJohn Marino #include "ggc.h"
40*e4b17023SJohn Marino #include "diagnostic.h"
41*e4b17023SJohn Marino #include "libfuncs.h"
42*e4b17023SJohn Marino #include "except.h"
43*e4b17023SJohn Marino #include "debug.h"
44*e4b17023SJohn Marino #include "vec.h"
45*e4b17023SJohn Marino #include "timevar.h"
46*e4b17023SJohn Marino #include "output.h"
47*e4b17023SJohn Marino #include "ipa-utils.h"
48*e4b17023SJohn Marino #include "data-streamer.h"
49*e4b17023SJohn Marino #include "gimple-streamer.h"
50*e4b17023SJohn Marino #include "lto-streamer.h"
51*e4b17023SJohn Marino #include "tree-streamer.h"
52*e4b17023SJohn Marino #include "tree-pass.h"
53*e4b17023SJohn Marino #include "streamer-hooks.h"
54*e4b17023SJohn Marino
55*e4b17023SJohn Marino /* The table to hold the file names. */
56*e4b17023SJohn Marino static htab_t file_name_hash_table;
57*e4b17023SJohn Marino
58*e4b17023SJohn Marino
59*e4b17023SJohn Marino /* Check that tag ACTUAL has one of the given values. NUM_TAGS is the
60*e4b17023SJohn Marino number of valid tag values to check. */
61*e4b17023SJohn Marino
62*e4b17023SJohn Marino void
lto_tag_check_set(enum LTO_tags actual,int ntags,...)63*e4b17023SJohn Marino lto_tag_check_set (enum LTO_tags actual, int ntags, ...)
64*e4b17023SJohn Marino {
65*e4b17023SJohn Marino va_list ap;
66*e4b17023SJohn Marino int i;
67*e4b17023SJohn Marino
68*e4b17023SJohn Marino va_start (ap, ntags);
69*e4b17023SJohn Marino for (i = 0; i < ntags; i++)
70*e4b17023SJohn Marino if ((unsigned) actual == va_arg (ap, unsigned))
71*e4b17023SJohn Marino {
72*e4b17023SJohn Marino va_end (ap);
73*e4b17023SJohn Marino return;
74*e4b17023SJohn Marino }
75*e4b17023SJohn Marino
76*e4b17023SJohn Marino va_end (ap);
77*e4b17023SJohn Marino internal_error ("bytecode stream: unexpected tag %s", lto_tag_name (actual));
78*e4b17023SJohn Marino }
79*e4b17023SJohn Marino
80*e4b17023SJohn Marino
81*e4b17023SJohn Marino /* Read LENGTH bytes from STREAM to ADDR. */
82*e4b17023SJohn Marino
83*e4b17023SJohn Marino void
lto_input_data_block(struct lto_input_block * ib,void * addr,size_t length)84*e4b17023SJohn Marino lto_input_data_block (struct lto_input_block *ib, void *addr, size_t length)
85*e4b17023SJohn Marino {
86*e4b17023SJohn Marino size_t i;
87*e4b17023SJohn Marino unsigned char *const buffer = (unsigned char *const) addr;
88*e4b17023SJohn Marino
89*e4b17023SJohn Marino for (i = 0; i < length; i++)
90*e4b17023SJohn Marino buffer[i] = streamer_read_uchar (ib);
91*e4b17023SJohn Marino }
92*e4b17023SJohn Marino
93*e4b17023SJohn Marino
94*e4b17023SJohn Marino /* Lookup STRING in file_name_hash_table. If found, return the existing
95*e4b17023SJohn Marino string, otherwise insert STRING as the canonical version. */
96*e4b17023SJohn Marino
97*e4b17023SJohn Marino static const char *
canon_file_name(const char * string)98*e4b17023SJohn Marino canon_file_name (const char *string)
99*e4b17023SJohn Marino {
100*e4b17023SJohn Marino void **slot;
101*e4b17023SJohn Marino struct string_slot s_slot;
102*e4b17023SJohn Marino size_t len = strlen (string);
103*e4b17023SJohn Marino
104*e4b17023SJohn Marino s_slot.s = string;
105*e4b17023SJohn Marino s_slot.len = len;
106*e4b17023SJohn Marino
107*e4b17023SJohn Marino slot = htab_find_slot (file_name_hash_table, &s_slot, INSERT);
108*e4b17023SJohn Marino if (*slot == NULL)
109*e4b17023SJohn Marino {
110*e4b17023SJohn Marino char *saved_string;
111*e4b17023SJohn Marino struct string_slot *new_slot;
112*e4b17023SJohn Marino
113*e4b17023SJohn Marino saved_string = (char *) xmalloc (len + 1);
114*e4b17023SJohn Marino new_slot = XCNEW (struct string_slot);
115*e4b17023SJohn Marino memcpy (saved_string, string, len + 1);
116*e4b17023SJohn Marino new_slot->s = saved_string;
117*e4b17023SJohn Marino new_slot->len = len;
118*e4b17023SJohn Marino *slot = new_slot;
119*e4b17023SJohn Marino return saved_string;
120*e4b17023SJohn Marino }
121*e4b17023SJohn Marino else
122*e4b17023SJohn Marino {
123*e4b17023SJohn Marino struct string_slot *old_slot = (struct string_slot *) *slot;
124*e4b17023SJohn Marino return old_slot->s;
125*e4b17023SJohn Marino }
126*e4b17023SJohn Marino }
127*e4b17023SJohn Marino
128*e4b17023SJohn Marino
129*e4b17023SJohn Marino /* Clear the line info stored in DATA_IN. */
130*e4b17023SJohn Marino
131*e4b17023SJohn Marino static void
clear_line_info(struct data_in * data_in)132*e4b17023SJohn Marino clear_line_info (struct data_in *data_in)
133*e4b17023SJohn Marino {
134*e4b17023SJohn Marino if (data_in->current_file)
135*e4b17023SJohn Marino linemap_add (line_table, LC_LEAVE, false, NULL, 0);
136*e4b17023SJohn Marino data_in->current_file = NULL;
137*e4b17023SJohn Marino data_in->current_line = 0;
138*e4b17023SJohn Marino data_in->current_col = 0;
139*e4b17023SJohn Marino }
140*e4b17023SJohn Marino
141*e4b17023SJohn Marino
142*e4b17023SJohn Marino /* Read a location bitpack from input block IB. */
143*e4b17023SJohn Marino
144*e4b17023SJohn Marino static location_t
lto_input_location_bitpack(struct data_in * data_in,struct bitpack_d * bp)145*e4b17023SJohn Marino lto_input_location_bitpack (struct data_in *data_in, struct bitpack_d *bp)
146*e4b17023SJohn Marino {
147*e4b17023SJohn Marino bool file_change, line_change, column_change;
148*e4b17023SJohn Marino unsigned len;
149*e4b17023SJohn Marino bool prev_file = data_in->current_file != NULL;
150*e4b17023SJohn Marino
151*e4b17023SJohn Marino if (bp_unpack_value (bp, 1))
152*e4b17023SJohn Marino return UNKNOWN_LOCATION;
153*e4b17023SJohn Marino
154*e4b17023SJohn Marino file_change = bp_unpack_value (bp, 1);
155*e4b17023SJohn Marino if (file_change)
156*e4b17023SJohn Marino data_in->current_file = canon_file_name
157*e4b17023SJohn Marino (string_for_index (data_in,
158*e4b17023SJohn Marino bp_unpack_var_len_unsigned (bp),
159*e4b17023SJohn Marino &len));
160*e4b17023SJohn Marino
161*e4b17023SJohn Marino line_change = bp_unpack_value (bp, 1);
162*e4b17023SJohn Marino if (line_change)
163*e4b17023SJohn Marino data_in->current_line = bp_unpack_var_len_unsigned (bp);
164*e4b17023SJohn Marino
165*e4b17023SJohn Marino column_change = bp_unpack_value (bp, 1);
166*e4b17023SJohn Marino if (column_change)
167*e4b17023SJohn Marino data_in->current_col = bp_unpack_var_len_unsigned (bp);
168*e4b17023SJohn Marino
169*e4b17023SJohn Marino if (file_change)
170*e4b17023SJohn Marino {
171*e4b17023SJohn Marino if (prev_file)
172*e4b17023SJohn Marino linemap_add (line_table, LC_LEAVE, false, NULL, 0);
173*e4b17023SJohn Marino
174*e4b17023SJohn Marino linemap_add (line_table, LC_ENTER, false, data_in->current_file,
175*e4b17023SJohn Marino data_in->current_line);
176*e4b17023SJohn Marino }
177*e4b17023SJohn Marino else if (line_change)
178*e4b17023SJohn Marino linemap_line_start (line_table, data_in->current_line, data_in->current_col);
179*e4b17023SJohn Marino
180*e4b17023SJohn Marino return linemap_position_for_column (line_table, data_in->current_col);
181*e4b17023SJohn Marino }
182*e4b17023SJohn Marino
183*e4b17023SJohn Marino
184*e4b17023SJohn Marino /* Read a location from input block IB.
185*e4b17023SJohn Marino If the input_location streamer hook exists, call it.
186*e4b17023SJohn Marino Otherwise, proceed with reading the location from the
187*e4b17023SJohn Marino expanded location bitpack. */
188*e4b17023SJohn Marino
189*e4b17023SJohn Marino location_t
lto_input_location(struct lto_input_block * ib,struct data_in * data_in)190*e4b17023SJohn Marino lto_input_location (struct lto_input_block *ib, struct data_in *data_in)
191*e4b17023SJohn Marino {
192*e4b17023SJohn Marino if (streamer_hooks.input_location)
193*e4b17023SJohn Marino return streamer_hooks.input_location (ib, data_in);
194*e4b17023SJohn Marino else
195*e4b17023SJohn Marino {
196*e4b17023SJohn Marino struct bitpack_d bp;
197*e4b17023SJohn Marino
198*e4b17023SJohn Marino bp = streamer_read_bitpack (ib);
199*e4b17023SJohn Marino return lto_input_location_bitpack (data_in, &bp);
200*e4b17023SJohn Marino }
201*e4b17023SJohn Marino }
202*e4b17023SJohn Marino
203*e4b17023SJohn Marino
204*e4b17023SJohn Marino /* Read a reference to a tree node from DATA_IN using input block IB.
205*e4b17023SJohn Marino TAG is the expected node that should be found in IB, if TAG belongs
206*e4b17023SJohn Marino to one of the indexable trees, expect to read a reference index to
207*e4b17023SJohn Marino be looked up in one of the symbol tables, otherwise read the pysical
208*e4b17023SJohn Marino representation of the tree using stream_read_tree. FN is the
209*e4b17023SJohn Marino function scope for the read tree. */
210*e4b17023SJohn Marino
211*e4b17023SJohn Marino tree
lto_input_tree_ref(struct lto_input_block * ib,struct data_in * data_in,struct function * fn,enum LTO_tags tag)212*e4b17023SJohn Marino lto_input_tree_ref (struct lto_input_block *ib, struct data_in *data_in,
213*e4b17023SJohn Marino struct function *fn, enum LTO_tags tag)
214*e4b17023SJohn Marino {
215*e4b17023SJohn Marino unsigned HOST_WIDE_INT ix_u;
216*e4b17023SJohn Marino tree result = NULL_TREE;
217*e4b17023SJohn Marino
218*e4b17023SJohn Marino lto_tag_check_range (tag, LTO_field_decl_ref, LTO_global_decl_ref);
219*e4b17023SJohn Marino
220*e4b17023SJohn Marino switch (tag)
221*e4b17023SJohn Marino {
222*e4b17023SJohn Marino case LTO_type_ref:
223*e4b17023SJohn Marino ix_u = streamer_read_uhwi (ib);
224*e4b17023SJohn Marino result = lto_file_decl_data_get_type (data_in->file_data, ix_u);
225*e4b17023SJohn Marino break;
226*e4b17023SJohn Marino
227*e4b17023SJohn Marino case LTO_ssa_name_ref:
228*e4b17023SJohn Marino ix_u = streamer_read_uhwi (ib);
229*e4b17023SJohn Marino result = VEC_index (tree, SSANAMES (fn), ix_u);
230*e4b17023SJohn Marino break;
231*e4b17023SJohn Marino
232*e4b17023SJohn Marino case LTO_field_decl_ref:
233*e4b17023SJohn Marino ix_u = streamer_read_uhwi (ib);
234*e4b17023SJohn Marino result = lto_file_decl_data_get_field_decl (data_in->file_data, ix_u);
235*e4b17023SJohn Marino break;
236*e4b17023SJohn Marino
237*e4b17023SJohn Marino case LTO_function_decl_ref:
238*e4b17023SJohn Marino ix_u = streamer_read_uhwi (ib);
239*e4b17023SJohn Marino result = lto_file_decl_data_get_fn_decl (data_in->file_data, ix_u);
240*e4b17023SJohn Marino break;
241*e4b17023SJohn Marino
242*e4b17023SJohn Marino case LTO_type_decl_ref:
243*e4b17023SJohn Marino ix_u = streamer_read_uhwi (ib);
244*e4b17023SJohn Marino result = lto_file_decl_data_get_type_decl (data_in->file_data, ix_u);
245*e4b17023SJohn Marino break;
246*e4b17023SJohn Marino
247*e4b17023SJohn Marino case LTO_namespace_decl_ref:
248*e4b17023SJohn Marino ix_u = streamer_read_uhwi (ib);
249*e4b17023SJohn Marino result = lto_file_decl_data_get_namespace_decl (data_in->file_data, ix_u);
250*e4b17023SJohn Marino break;
251*e4b17023SJohn Marino
252*e4b17023SJohn Marino case LTO_global_decl_ref:
253*e4b17023SJohn Marino case LTO_result_decl_ref:
254*e4b17023SJohn Marino case LTO_const_decl_ref:
255*e4b17023SJohn Marino case LTO_imported_decl_ref:
256*e4b17023SJohn Marino case LTO_label_decl_ref:
257*e4b17023SJohn Marino case LTO_translation_unit_decl_ref:
258*e4b17023SJohn Marino ix_u = streamer_read_uhwi (ib);
259*e4b17023SJohn Marino result = lto_file_decl_data_get_var_decl (data_in->file_data, ix_u);
260*e4b17023SJohn Marino break;
261*e4b17023SJohn Marino
262*e4b17023SJohn Marino default:
263*e4b17023SJohn Marino gcc_unreachable ();
264*e4b17023SJohn Marino }
265*e4b17023SJohn Marino
266*e4b17023SJohn Marino gcc_assert (result);
267*e4b17023SJohn Marino
268*e4b17023SJohn Marino return result;
269*e4b17023SJohn Marino }
270*e4b17023SJohn Marino
271*e4b17023SJohn Marino
272*e4b17023SJohn Marino /* Read and return a double-linked list of catch handlers from input
273*e4b17023SJohn Marino block IB, using descriptors in DATA_IN. */
274*e4b17023SJohn Marino
275*e4b17023SJohn Marino static struct eh_catch_d *
lto_input_eh_catch_list(struct lto_input_block * ib,struct data_in * data_in,eh_catch * last_p)276*e4b17023SJohn Marino lto_input_eh_catch_list (struct lto_input_block *ib, struct data_in *data_in,
277*e4b17023SJohn Marino eh_catch *last_p)
278*e4b17023SJohn Marino {
279*e4b17023SJohn Marino eh_catch first;
280*e4b17023SJohn Marino enum LTO_tags tag;
281*e4b17023SJohn Marino
282*e4b17023SJohn Marino *last_p = first = NULL;
283*e4b17023SJohn Marino tag = streamer_read_record_start (ib);
284*e4b17023SJohn Marino while (tag)
285*e4b17023SJohn Marino {
286*e4b17023SJohn Marino tree list;
287*e4b17023SJohn Marino eh_catch n;
288*e4b17023SJohn Marino
289*e4b17023SJohn Marino lto_tag_check_range (tag, LTO_eh_catch, LTO_eh_catch);
290*e4b17023SJohn Marino
291*e4b17023SJohn Marino /* Read the catch node. */
292*e4b17023SJohn Marino n = ggc_alloc_cleared_eh_catch_d ();
293*e4b17023SJohn Marino n->type_list = stream_read_tree (ib, data_in);
294*e4b17023SJohn Marino n->filter_list = stream_read_tree (ib, data_in);
295*e4b17023SJohn Marino n->label = stream_read_tree (ib, data_in);
296*e4b17023SJohn Marino
297*e4b17023SJohn Marino /* Register all the types in N->FILTER_LIST. */
298*e4b17023SJohn Marino for (list = n->filter_list; list; list = TREE_CHAIN (list))
299*e4b17023SJohn Marino add_type_for_runtime (TREE_VALUE (list));
300*e4b17023SJohn Marino
301*e4b17023SJohn Marino /* Chain N to the end of the list. */
302*e4b17023SJohn Marino if (*last_p)
303*e4b17023SJohn Marino (*last_p)->next_catch = n;
304*e4b17023SJohn Marino n->prev_catch = *last_p;
305*e4b17023SJohn Marino *last_p = n;
306*e4b17023SJohn Marino
307*e4b17023SJohn Marino /* Set the head of the list the first time through the loop. */
308*e4b17023SJohn Marino if (first == NULL)
309*e4b17023SJohn Marino first = n;
310*e4b17023SJohn Marino
311*e4b17023SJohn Marino tag = streamer_read_record_start (ib);
312*e4b17023SJohn Marino }
313*e4b17023SJohn Marino
314*e4b17023SJohn Marino return first;
315*e4b17023SJohn Marino }
316*e4b17023SJohn Marino
317*e4b17023SJohn Marino
318*e4b17023SJohn Marino /* Read and return EH region IX from input block IB, using descriptors
319*e4b17023SJohn Marino in DATA_IN. */
320*e4b17023SJohn Marino
321*e4b17023SJohn Marino static eh_region
input_eh_region(struct lto_input_block * ib,struct data_in * data_in,int ix)322*e4b17023SJohn Marino input_eh_region (struct lto_input_block *ib, struct data_in *data_in, int ix)
323*e4b17023SJohn Marino {
324*e4b17023SJohn Marino enum LTO_tags tag;
325*e4b17023SJohn Marino eh_region r;
326*e4b17023SJohn Marino
327*e4b17023SJohn Marino /* Read the region header. */
328*e4b17023SJohn Marino tag = streamer_read_record_start (ib);
329*e4b17023SJohn Marino if (tag == LTO_null)
330*e4b17023SJohn Marino return NULL;
331*e4b17023SJohn Marino
332*e4b17023SJohn Marino r = ggc_alloc_cleared_eh_region_d ();
333*e4b17023SJohn Marino r->index = streamer_read_hwi (ib);
334*e4b17023SJohn Marino
335*e4b17023SJohn Marino gcc_assert (r->index == ix);
336*e4b17023SJohn Marino
337*e4b17023SJohn Marino /* Read all the region pointers as region numbers. We'll fix up
338*e4b17023SJohn Marino the pointers once the whole array has been read. */
339*e4b17023SJohn Marino r->outer = (eh_region) (intptr_t) streamer_read_hwi (ib);
340*e4b17023SJohn Marino r->inner = (eh_region) (intptr_t) streamer_read_hwi (ib);
341*e4b17023SJohn Marino r->next_peer = (eh_region) (intptr_t) streamer_read_hwi (ib);
342*e4b17023SJohn Marino
343*e4b17023SJohn Marino switch (tag)
344*e4b17023SJohn Marino {
345*e4b17023SJohn Marino case LTO_ert_cleanup:
346*e4b17023SJohn Marino r->type = ERT_CLEANUP;
347*e4b17023SJohn Marino break;
348*e4b17023SJohn Marino
349*e4b17023SJohn Marino case LTO_ert_try:
350*e4b17023SJohn Marino {
351*e4b17023SJohn Marino struct eh_catch_d *last_catch;
352*e4b17023SJohn Marino r->type = ERT_TRY;
353*e4b17023SJohn Marino r->u.eh_try.first_catch = lto_input_eh_catch_list (ib, data_in,
354*e4b17023SJohn Marino &last_catch);
355*e4b17023SJohn Marino r->u.eh_try.last_catch = last_catch;
356*e4b17023SJohn Marino break;
357*e4b17023SJohn Marino }
358*e4b17023SJohn Marino
359*e4b17023SJohn Marino case LTO_ert_allowed_exceptions:
360*e4b17023SJohn Marino {
361*e4b17023SJohn Marino tree l;
362*e4b17023SJohn Marino
363*e4b17023SJohn Marino r->type = ERT_ALLOWED_EXCEPTIONS;
364*e4b17023SJohn Marino r->u.allowed.type_list = stream_read_tree (ib, data_in);
365*e4b17023SJohn Marino r->u.allowed.label = stream_read_tree (ib, data_in);
366*e4b17023SJohn Marino r->u.allowed.filter = streamer_read_uhwi (ib);
367*e4b17023SJohn Marino
368*e4b17023SJohn Marino for (l = r->u.allowed.type_list; l ; l = TREE_CHAIN (l))
369*e4b17023SJohn Marino add_type_for_runtime (TREE_VALUE (l));
370*e4b17023SJohn Marino }
371*e4b17023SJohn Marino break;
372*e4b17023SJohn Marino
373*e4b17023SJohn Marino case LTO_ert_must_not_throw:
374*e4b17023SJohn Marino r->type = ERT_MUST_NOT_THROW;
375*e4b17023SJohn Marino r->u.must_not_throw.failure_decl = stream_read_tree (ib, data_in);
376*e4b17023SJohn Marino r->u.must_not_throw.failure_loc = lto_input_location (ib, data_in);
377*e4b17023SJohn Marino break;
378*e4b17023SJohn Marino
379*e4b17023SJohn Marino default:
380*e4b17023SJohn Marino gcc_unreachable ();
381*e4b17023SJohn Marino }
382*e4b17023SJohn Marino
383*e4b17023SJohn Marino r->landing_pads = (eh_landing_pad) (intptr_t) streamer_read_hwi (ib);
384*e4b17023SJohn Marino
385*e4b17023SJohn Marino return r;
386*e4b17023SJohn Marino }
387*e4b17023SJohn Marino
388*e4b17023SJohn Marino
389*e4b17023SJohn Marino /* Read and return EH landing pad IX from input block IB, using descriptors
390*e4b17023SJohn Marino in DATA_IN. */
391*e4b17023SJohn Marino
392*e4b17023SJohn Marino static eh_landing_pad
input_eh_lp(struct lto_input_block * ib,struct data_in * data_in,int ix)393*e4b17023SJohn Marino input_eh_lp (struct lto_input_block *ib, struct data_in *data_in, int ix)
394*e4b17023SJohn Marino {
395*e4b17023SJohn Marino enum LTO_tags tag;
396*e4b17023SJohn Marino eh_landing_pad lp;
397*e4b17023SJohn Marino
398*e4b17023SJohn Marino /* Read the landing pad header. */
399*e4b17023SJohn Marino tag = streamer_read_record_start (ib);
400*e4b17023SJohn Marino if (tag == LTO_null)
401*e4b17023SJohn Marino return NULL;
402*e4b17023SJohn Marino
403*e4b17023SJohn Marino lto_tag_check_range (tag, LTO_eh_landing_pad, LTO_eh_landing_pad);
404*e4b17023SJohn Marino
405*e4b17023SJohn Marino lp = ggc_alloc_cleared_eh_landing_pad_d ();
406*e4b17023SJohn Marino lp->index = streamer_read_hwi (ib);
407*e4b17023SJohn Marino gcc_assert (lp->index == ix);
408*e4b17023SJohn Marino lp->next_lp = (eh_landing_pad) (intptr_t) streamer_read_hwi (ib);
409*e4b17023SJohn Marino lp->region = (eh_region) (intptr_t) streamer_read_hwi (ib);
410*e4b17023SJohn Marino lp->post_landing_pad = stream_read_tree (ib, data_in);
411*e4b17023SJohn Marino
412*e4b17023SJohn Marino return lp;
413*e4b17023SJohn Marino }
414*e4b17023SJohn Marino
415*e4b17023SJohn Marino
416*e4b17023SJohn Marino /* After reading the EH regions, pointers to peer and children regions
417*e4b17023SJohn Marino are region numbers. This converts all these region numbers into
418*e4b17023SJohn Marino real pointers into the rematerialized regions for FN. ROOT_REGION
419*e4b17023SJohn Marino is the region number for the root EH region in FN. */
420*e4b17023SJohn Marino
421*e4b17023SJohn Marino static void
fixup_eh_region_pointers(struct function * fn,HOST_WIDE_INT root_region)422*e4b17023SJohn Marino fixup_eh_region_pointers (struct function *fn, HOST_WIDE_INT root_region)
423*e4b17023SJohn Marino {
424*e4b17023SJohn Marino unsigned i;
425*e4b17023SJohn Marino VEC(eh_region,gc) *eh_array = fn->eh->region_array;
426*e4b17023SJohn Marino VEC(eh_landing_pad,gc) *lp_array = fn->eh->lp_array;
427*e4b17023SJohn Marino eh_region r;
428*e4b17023SJohn Marino eh_landing_pad lp;
429*e4b17023SJohn Marino
430*e4b17023SJohn Marino gcc_assert (eh_array && lp_array);
431*e4b17023SJohn Marino
432*e4b17023SJohn Marino gcc_assert (root_region >= 0);
433*e4b17023SJohn Marino fn->eh->region_tree = VEC_index (eh_region, eh_array, root_region);
434*e4b17023SJohn Marino
435*e4b17023SJohn Marino #define FIXUP_EH_REGION(r) (r) = VEC_index (eh_region, eh_array, \
436*e4b17023SJohn Marino (HOST_WIDE_INT) (intptr_t) (r))
437*e4b17023SJohn Marino #define FIXUP_EH_LP(p) (p) = VEC_index (eh_landing_pad, lp_array, \
438*e4b17023SJohn Marino (HOST_WIDE_INT) (intptr_t) (p))
439*e4b17023SJohn Marino
440*e4b17023SJohn Marino /* Convert all the index numbers stored in pointer fields into
441*e4b17023SJohn Marino pointers to the corresponding slots in the EH region array. */
442*e4b17023SJohn Marino FOR_EACH_VEC_ELT (eh_region, eh_array, i, r)
443*e4b17023SJohn Marino {
444*e4b17023SJohn Marino /* The array may contain NULL regions. */
445*e4b17023SJohn Marino if (r == NULL)
446*e4b17023SJohn Marino continue;
447*e4b17023SJohn Marino
448*e4b17023SJohn Marino gcc_assert (i == (unsigned) r->index);
449*e4b17023SJohn Marino FIXUP_EH_REGION (r->outer);
450*e4b17023SJohn Marino FIXUP_EH_REGION (r->inner);
451*e4b17023SJohn Marino FIXUP_EH_REGION (r->next_peer);
452*e4b17023SJohn Marino FIXUP_EH_LP (r->landing_pads);
453*e4b17023SJohn Marino }
454*e4b17023SJohn Marino
455*e4b17023SJohn Marino /* Convert all the index numbers stored in pointer fields into
456*e4b17023SJohn Marino pointers to the corresponding slots in the EH landing pad array. */
457*e4b17023SJohn Marino FOR_EACH_VEC_ELT (eh_landing_pad, lp_array, i, lp)
458*e4b17023SJohn Marino {
459*e4b17023SJohn Marino /* The array may contain NULL landing pads. */
460*e4b17023SJohn Marino if (lp == NULL)
461*e4b17023SJohn Marino continue;
462*e4b17023SJohn Marino
463*e4b17023SJohn Marino gcc_assert (i == (unsigned) lp->index);
464*e4b17023SJohn Marino FIXUP_EH_LP (lp->next_lp);
465*e4b17023SJohn Marino FIXUP_EH_REGION (lp->region);
466*e4b17023SJohn Marino }
467*e4b17023SJohn Marino
468*e4b17023SJohn Marino #undef FIXUP_EH_REGION
469*e4b17023SJohn Marino #undef FIXUP_EH_LP
470*e4b17023SJohn Marino }
471*e4b17023SJohn Marino
472*e4b17023SJohn Marino
473*e4b17023SJohn Marino /* Initialize EH support. */
474*e4b17023SJohn Marino
475*e4b17023SJohn Marino void
lto_init_eh(void)476*e4b17023SJohn Marino lto_init_eh (void)
477*e4b17023SJohn Marino {
478*e4b17023SJohn Marino static bool eh_initialized_p = false;
479*e4b17023SJohn Marino
480*e4b17023SJohn Marino if (eh_initialized_p)
481*e4b17023SJohn Marino return;
482*e4b17023SJohn Marino
483*e4b17023SJohn Marino /* Contrary to most other FEs, we only initialize EH support when at
484*e4b17023SJohn Marino least one of the files in the set contains exception regions in
485*e4b17023SJohn Marino it. Since this happens much later than the call to init_eh in
486*e4b17023SJohn Marino lang_dependent_init, we have to set flag_exceptions and call
487*e4b17023SJohn Marino init_eh again to initialize the EH tables. */
488*e4b17023SJohn Marino flag_exceptions = 1;
489*e4b17023SJohn Marino init_eh ();
490*e4b17023SJohn Marino
491*e4b17023SJohn Marino eh_initialized_p = true;
492*e4b17023SJohn Marino }
493*e4b17023SJohn Marino
494*e4b17023SJohn Marino
495*e4b17023SJohn Marino /* Read the exception table for FN from IB using the data descriptors
496*e4b17023SJohn Marino in DATA_IN. */
497*e4b17023SJohn Marino
498*e4b17023SJohn Marino static void
input_eh_regions(struct lto_input_block * ib,struct data_in * data_in,struct function * fn)499*e4b17023SJohn Marino input_eh_regions (struct lto_input_block *ib, struct data_in *data_in,
500*e4b17023SJohn Marino struct function *fn)
501*e4b17023SJohn Marino {
502*e4b17023SJohn Marino HOST_WIDE_INT i, root_region, len;
503*e4b17023SJohn Marino enum LTO_tags tag;
504*e4b17023SJohn Marino
505*e4b17023SJohn Marino tag = streamer_read_record_start (ib);
506*e4b17023SJohn Marino if (tag == LTO_null)
507*e4b17023SJohn Marino return;
508*e4b17023SJohn Marino
509*e4b17023SJohn Marino lto_tag_check_range (tag, LTO_eh_table, LTO_eh_table);
510*e4b17023SJohn Marino
511*e4b17023SJohn Marino /* If the file contains EH regions, then it was compiled with
512*e4b17023SJohn Marino -fexceptions. In that case, initialize the backend EH
513*e4b17023SJohn Marino machinery. */
514*e4b17023SJohn Marino lto_init_eh ();
515*e4b17023SJohn Marino
516*e4b17023SJohn Marino gcc_assert (fn->eh);
517*e4b17023SJohn Marino
518*e4b17023SJohn Marino root_region = streamer_read_hwi (ib);
519*e4b17023SJohn Marino gcc_assert (root_region == (int) root_region);
520*e4b17023SJohn Marino
521*e4b17023SJohn Marino /* Read the EH region array. */
522*e4b17023SJohn Marino len = streamer_read_hwi (ib);
523*e4b17023SJohn Marino gcc_assert (len == (int) len);
524*e4b17023SJohn Marino if (len > 0)
525*e4b17023SJohn Marino {
526*e4b17023SJohn Marino VEC_safe_grow (eh_region, gc, fn->eh->region_array, len);
527*e4b17023SJohn Marino for (i = 0; i < len; i++)
528*e4b17023SJohn Marino {
529*e4b17023SJohn Marino eh_region r = input_eh_region (ib, data_in, i);
530*e4b17023SJohn Marino VEC_replace (eh_region, fn->eh->region_array, i, r);
531*e4b17023SJohn Marino }
532*e4b17023SJohn Marino }
533*e4b17023SJohn Marino
534*e4b17023SJohn Marino /* Read the landing pads. */
535*e4b17023SJohn Marino len = streamer_read_hwi (ib);
536*e4b17023SJohn Marino gcc_assert (len == (int) len);
537*e4b17023SJohn Marino if (len > 0)
538*e4b17023SJohn Marino {
539*e4b17023SJohn Marino VEC_safe_grow (eh_landing_pad, gc, fn->eh->lp_array, len);
540*e4b17023SJohn Marino for (i = 0; i < len; i++)
541*e4b17023SJohn Marino {
542*e4b17023SJohn Marino eh_landing_pad lp = input_eh_lp (ib, data_in, i);
543*e4b17023SJohn Marino VEC_replace (eh_landing_pad, fn->eh->lp_array, i, lp);
544*e4b17023SJohn Marino }
545*e4b17023SJohn Marino }
546*e4b17023SJohn Marino
547*e4b17023SJohn Marino /* Read the runtime type data. */
548*e4b17023SJohn Marino len = streamer_read_hwi (ib);
549*e4b17023SJohn Marino gcc_assert (len == (int) len);
550*e4b17023SJohn Marino if (len > 0)
551*e4b17023SJohn Marino {
552*e4b17023SJohn Marino VEC_safe_grow (tree, gc, fn->eh->ttype_data, len);
553*e4b17023SJohn Marino for (i = 0; i < len; i++)
554*e4b17023SJohn Marino {
555*e4b17023SJohn Marino tree ttype = stream_read_tree (ib, data_in);
556*e4b17023SJohn Marino VEC_replace (tree, fn->eh->ttype_data, i, ttype);
557*e4b17023SJohn Marino }
558*e4b17023SJohn Marino }
559*e4b17023SJohn Marino
560*e4b17023SJohn Marino /* Read the table of action chains. */
561*e4b17023SJohn Marino len = streamer_read_hwi (ib);
562*e4b17023SJohn Marino gcc_assert (len == (int) len);
563*e4b17023SJohn Marino if (len > 0)
564*e4b17023SJohn Marino {
565*e4b17023SJohn Marino if (targetm.arm_eabi_unwinder)
566*e4b17023SJohn Marino {
567*e4b17023SJohn Marino VEC_safe_grow (tree, gc, fn->eh->ehspec_data.arm_eabi, len);
568*e4b17023SJohn Marino for (i = 0; i < len; i++)
569*e4b17023SJohn Marino {
570*e4b17023SJohn Marino tree t = stream_read_tree (ib, data_in);
571*e4b17023SJohn Marino VEC_replace (tree, fn->eh->ehspec_data.arm_eabi, i, t);
572*e4b17023SJohn Marino }
573*e4b17023SJohn Marino }
574*e4b17023SJohn Marino else
575*e4b17023SJohn Marino {
576*e4b17023SJohn Marino VEC_safe_grow (uchar, gc, fn->eh->ehspec_data.other, len);
577*e4b17023SJohn Marino for (i = 0; i < len; i++)
578*e4b17023SJohn Marino {
579*e4b17023SJohn Marino uchar c = streamer_read_uchar (ib);
580*e4b17023SJohn Marino VEC_replace (uchar, fn->eh->ehspec_data.other, i, c);
581*e4b17023SJohn Marino }
582*e4b17023SJohn Marino }
583*e4b17023SJohn Marino }
584*e4b17023SJohn Marino
585*e4b17023SJohn Marino /* Reconstruct the EH region tree by fixing up the peer/children
586*e4b17023SJohn Marino pointers. */
587*e4b17023SJohn Marino fixup_eh_region_pointers (fn, root_region);
588*e4b17023SJohn Marino
589*e4b17023SJohn Marino tag = streamer_read_record_start (ib);
590*e4b17023SJohn Marino lto_tag_check_range (tag, LTO_null, LTO_null);
591*e4b17023SJohn Marino }
592*e4b17023SJohn Marino
593*e4b17023SJohn Marino
594*e4b17023SJohn Marino /* Make a new basic block with index INDEX in function FN. */
595*e4b17023SJohn Marino
596*e4b17023SJohn Marino static basic_block
make_new_block(struct function * fn,unsigned int index)597*e4b17023SJohn Marino make_new_block (struct function *fn, unsigned int index)
598*e4b17023SJohn Marino {
599*e4b17023SJohn Marino basic_block bb = alloc_block ();
600*e4b17023SJohn Marino bb->index = index;
601*e4b17023SJohn Marino SET_BASIC_BLOCK_FOR_FUNCTION (fn, index, bb);
602*e4b17023SJohn Marino bb->il.gimple = ggc_alloc_cleared_gimple_bb_info ();
603*e4b17023SJohn Marino n_basic_blocks_for_function (fn)++;
604*e4b17023SJohn Marino bb->flags = 0;
605*e4b17023SJohn Marino set_bb_seq (bb, gimple_seq_alloc ());
606*e4b17023SJohn Marino return bb;
607*e4b17023SJohn Marino }
608*e4b17023SJohn Marino
609*e4b17023SJohn Marino
610*e4b17023SJohn Marino /* Read the CFG for function FN from input block IB. */
611*e4b17023SJohn Marino
612*e4b17023SJohn Marino static void
input_cfg(struct lto_input_block * ib,struct function * fn,int count_materialization_scale)613*e4b17023SJohn Marino input_cfg (struct lto_input_block *ib, struct function *fn,
614*e4b17023SJohn Marino int count_materialization_scale)
615*e4b17023SJohn Marino {
616*e4b17023SJohn Marino unsigned int bb_count;
617*e4b17023SJohn Marino basic_block p_bb;
618*e4b17023SJohn Marino unsigned int i;
619*e4b17023SJohn Marino int index;
620*e4b17023SJohn Marino
621*e4b17023SJohn Marino init_empty_tree_cfg_for_function (fn);
622*e4b17023SJohn Marino init_ssa_operands ();
623*e4b17023SJohn Marino
624*e4b17023SJohn Marino profile_status_for_function (fn) = streamer_read_enum (ib, profile_status_d,
625*e4b17023SJohn Marino PROFILE_LAST);
626*e4b17023SJohn Marino
627*e4b17023SJohn Marino bb_count = streamer_read_uhwi (ib);
628*e4b17023SJohn Marino
629*e4b17023SJohn Marino last_basic_block_for_function (fn) = bb_count;
630*e4b17023SJohn Marino if (bb_count > VEC_length (basic_block, basic_block_info_for_function (fn)))
631*e4b17023SJohn Marino VEC_safe_grow_cleared (basic_block, gc,
632*e4b17023SJohn Marino basic_block_info_for_function (fn), bb_count);
633*e4b17023SJohn Marino
634*e4b17023SJohn Marino if (bb_count > VEC_length (basic_block, label_to_block_map_for_function (fn)))
635*e4b17023SJohn Marino VEC_safe_grow_cleared (basic_block, gc,
636*e4b17023SJohn Marino label_to_block_map_for_function (fn), bb_count);
637*e4b17023SJohn Marino
638*e4b17023SJohn Marino index = streamer_read_hwi (ib);
639*e4b17023SJohn Marino while (index != -1)
640*e4b17023SJohn Marino {
641*e4b17023SJohn Marino basic_block bb = BASIC_BLOCK_FOR_FUNCTION (fn, index);
642*e4b17023SJohn Marino unsigned int edge_count;
643*e4b17023SJohn Marino
644*e4b17023SJohn Marino if (bb == NULL)
645*e4b17023SJohn Marino bb = make_new_block (fn, index);
646*e4b17023SJohn Marino
647*e4b17023SJohn Marino edge_count = streamer_read_uhwi (ib);
648*e4b17023SJohn Marino
649*e4b17023SJohn Marino /* Connect up the CFG. */
650*e4b17023SJohn Marino for (i = 0; i < edge_count; i++)
651*e4b17023SJohn Marino {
652*e4b17023SJohn Marino unsigned int dest_index;
653*e4b17023SJohn Marino unsigned int edge_flags;
654*e4b17023SJohn Marino basic_block dest;
655*e4b17023SJohn Marino int probability;
656*e4b17023SJohn Marino gcov_type count;
657*e4b17023SJohn Marino edge e;
658*e4b17023SJohn Marino
659*e4b17023SJohn Marino dest_index = streamer_read_uhwi (ib);
660*e4b17023SJohn Marino probability = (int) streamer_read_hwi (ib);
661*e4b17023SJohn Marino count = ((gcov_type) streamer_read_hwi (ib) * count_materialization_scale
662*e4b17023SJohn Marino + REG_BR_PROB_BASE / 2) / REG_BR_PROB_BASE;
663*e4b17023SJohn Marino edge_flags = streamer_read_uhwi (ib);
664*e4b17023SJohn Marino
665*e4b17023SJohn Marino dest = BASIC_BLOCK_FOR_FUNCTION (fn, dest_index);
666*e4b17023SJohn Marino
667*e4b17023SJohn Marino if (dest == NULL)
668*e4b17023SJohn Marino dest = make_new_block (fn, dest_index);
669*e4b17023SJohn Marino
670*e4b17023SJohn Marino e = make_edge (bb, dest, edge_flags);
671*e4b17023SJohn Marino e->probability = probability;
672*e4b17023SJohn Marino e->count = count;
673*e4b17023SJohn Marino }
674*e4b17023SJohn Marino
675*e4b17023SJohn Marino index = streamer_read_hwi (ib);
676*e4b17023SJohn Marino }
677*e4b17023SJohn Marino
678*e4b17023SJohn Marino p_bb = ENTRY_BLOCK_PTR_FOR_FUNCTION(fn);
679*e4b17023SJohn Marino index = streamer_read_hwi (ib);
680*e4b17023SJohn Marino while (index != -1)
681*e4b17023SJohn Marino {
682*e4b17023SJohn Marino basic_block bb = BASIC_BLOCK_FOR_FUNCTION (fn, index);
683*e4b17023SJohn Marino bb->prev_bb = p_bb;
684*e4b17023SJohn Marino p_bb->next_bb = bb;
685*e4b17023SJohn Marino p_bb = bb;
686*e4b17023SJohn Marino index = streamer_read_hwi (ib);
687*e4b17023SJohn Marino }
688*e4b17023SJohn Marino }
689*e4b17023SJohn Marino
690*e4b17023SJohn Marino
691*e4b17023SJohn Marino /* Read the SSA names array for function FN from DATA_IN using input
692*e4b17023SJohn Marino block IB. */
693*e4b17023SJohn Marino
694*e4b17023SJohn Marino static void
input_ssa_names(struct lto_input_block * ib,struct data_in * data_in,struct function * fn)695*e4b17023SJohn Marino input_ssa_names (struct lto_input_block *ib, struct data_in *data_in,
696*e4b17023SJohn Marino struct function *fn)
697*e4b17023SJohn Marino {
698*e4b17023SJohn Marino unsigned int i, size;
699*e4b17023SJohn Marino
700*e4b17023SJohn Marino size = streamer_read_uhwi (ib);
701*e4b17023SJohn Marino init_ssanames (fn, size);
702*e4b17023SJohn Marino
703*e4b17023SJohn Marino i = streamer_read_uhwi (ib);
704*e4b17023SJohn Marino while (i)
705*e4b17023SJohn Marino {
706*e4b17023SJohn Marino tree ssa_name, name;
707*e4b17023SJohn Marino bool is_default_def;
708*e4b17023SJohn Marino
709*e4b17023SJohn Marino /* Skip over the elements that had been freed. */
710*e4b17023SJohn Marino while (VEC_length (tree, SSANAMES (fn)) < i)
711*e4b17023SJohn Marino VEC_quick_push (tree, SSANAMES (fn), NULL_TREE);
712*e4b17023SJohn Marino
713*e4b17023SJohn Marino is_default_def = (streamer_read_uchar (ib) != 0);
714*e4b17023SJohn Marino name = stream_read_tree (ib, data_in);
715*e4b17023SJohn Marino ssa_name = make_ssa_name_fn (fn, name, gimple_build_nop ());
716*e4b17023SJohn Marino
717*e4b17023SJohn Marino if (is_default_def)
718*e4b17023SJohn Marino set_default_def (SSA_NAME_VAR (ssa_name), ssa_name);
719*e4b17023SJohn Marino
720*e4b17023SJohn Marino i = streamer_read_uhwi (ib);
721*e4b17023SJohn Marino }
722*e4b17023SJohn Marino }
723*e4b17023SJohn Marino
724*e4b17023SJohn Marino
725*e4b17023SJohn Marino /* Go through all NODE edges and fixup call_stmt pointers
726*e4b17023SJohn Marino so they point to STMTS. */
727*e4b17023SJohn Marino
728*e4b17023SJohn Marino static void
fixup_call_stmt_edges_1(struct cgraph_node * node,gimple * stmts)729*e4b17023SJohn Marino fixup_call_stmt_edges_1 (struct cgraph_node *node, gimple *stmts)
730*e4b17023SJohn Marino {
731*e4b17023SJohn Marino struct cgraph_edge *cedge;
732*e4b17023SJohn Marino for (cedge = node->callees; cedge; cedge = cedge->next_callee)
733*e4b17023SJohn Marino cedge->call_stmt = stmts[cedge->lto_stmt_uid];
734*e4b17023SJohn Marino for (cedge = node->indirect_calls; cedge; cedge = cedge->next_callee)
735*e4b17023SJohn Marino cedge->call_stmt = stmts[cedge->lto_stmt_uid];
736*e4b17023SJohn Marino }
737*e4b17023SJohn Marino
738*e4b17023SJohn Marino /* Fixup call_stmt pointers in NODE and all clones. */
739*e4b17023SJohn Marino
740*e4b17023SJohn Marino static void
fixup_call_stmt_edges(struct cgraph_node * orig,gimple * stmts)741*e4b17023SJohn Marino fixup_call_stmt_edges (struct cgraph_node *orig, gimple *stmts)
742*e4b17023SJohn Marino {
743*e4b17023SJohn Marino struct cgraph_node *node;
744*e4b17023SJohn Marino
745*e4b17023SJohn Marino while (orig->clone_of)
746*e4b17023SJohn Marino orig = orig->clone_of;
747*e4b17023SJohn Marino
748*e4b17023SJohn Marino fixup_call_stmt_edges_1 (orig, stmts);
749*e4b17023SJohn Marino if (orig->clones)
750*e4b17023SJohn Marino for (node = orig->clones; node != orig;)
751*e4b17023SJohn Marino {
752*e4b17023SJohn Marino fixup_call_stmt_edges_1 (node, stmts);
753*e4b17023SJohn Marino if (node->clones)
754*e4b17023SJohn Marino node = node->clones;
755*e4b17023SJohn Marino else if (node->next_sibling_clone)
756*e4b17023SJohn Marino node = node->next_sibling_clone;
757*e4b17023SJohn Marino else
758*e4b17023SJohn Marino {
759*e4b17023SJohn Marino while (node != orig && !node->next_sibling_clone)
760*e4b17023SJohn Marino node = node->clone_of;
761*e4b17023SJohn Marino if (node != orig)
762*e4b17023SJohn Marino node = node->next_sibling_clone;
763*e4b17023SJohn Marino }
764*e4b17023SJohn Marino }
765*e4b17023SJohn Marino }
766*e4b17023SJohn Marino
767*e4b17023SJohn Marino
768*e4b17023SJohn Marino /* Input the base body of struct function FN from DATA_IN
769*e4b17023SJohn Marino using input block IB. */
770*e4b17023SJohn Marino
771*e4b17023SJohn Marino static void
input_struct_function_base(struct function * fn,struct data_in * data_in,struct lto_input_block * ib)772*e4b17023SJohn Marino input_struct_function_base (struct function *fn, struct data_in *data_in,
773*e4b17023SJohn Marino struct lto_input_block *ib)
774*e4b17023SJohn Marino {
775*e4b17023SJohn Marino struct bitpack_d bp;
776*e4b17023SJohn Marino int len;
777*e4b17023SJohn Marino
778*e4b17023SJohn Marino /* Read the static chain and non-local goto save area. */
779*e4b17023SJohn Marino fn->static_chain_decl = stream_read_tree (ib, data_in);
780*e4b17023SJohn Marino fn->nonlocal_goto_save_area = stream_read_tree (ib, data_in);
781*e4b17023SJohn Marino
782*e4b17023SJohn Marino /* Read all the local symbols. */
783*e4b17023SJohn Marino len = streamer_read_hwi (ib);
784*e4b17023SJohn Marino if (len > 0)
785*e4b17023SJohn Marino {
786*e4b17023SJohn Marino int i;
787*e4b17023SJohn Marino VEC_safe_grow (tree, gc, fn->local_decls, len);
788*e4b17023SJohn Marino for (i = 0; i < len; i++)
789*e4b17023SJohn Marino {
790*e4b17023SJohn Marino tree t = stream_read_tree (ib, data_in);
791*e4b17023SJohn Marino VEC_replace (tree, fn->local_decls, i, t);
792*e4b17023SJohn Marino }
793*e4b17023SJohn Marino }
794*e4b17023SJohn Marino
795*e4b17023SJohn Marino /* Input the function start and end loci. */
796*e4b17023SJohn Marino fn->function_start_locus = lto_input_location (ib, data_in);
797*e4b17023SJohn Marino fn->function_end_locus = lto_input_location (ib, data_in);
798*e4b17023SJohn Marino
799*e4b17023SJohn Marino /* Input the current IL state of the function. */
800*e4b17023SJohn Marino fn->curr_properties = streamer_read_uhwi (ib);
801*e4b17023SJohn Marino
802*e4b17023SJohn Marino /* Read all the attributes for FN. */
803*e4b17023SJohn Marino bp = streamer_read_bitpack (ib);
804*e4b17023SJohn Marino fn->is_thunk = bp_unpack_value (&bp, 1);
805*e4b17023SJohn Marino fn->has_local_explicit_reg_vars = bp_unpack_value (&bp, 1);
806*e4b17023SJohn Marino fn->after_tree_profile = bp_unpack_value (&bp, 1);
807*e4b17023SJohn Marino fn->returns_pcc_struct = bp_unpack_value (&bp, 1);
808*e4b17023SJohn Marino fn->returns_struct = bp_unpack_value (&bp, 1);
809*e4b17023SJohn Marino fn->can_throw_non_call_exceptions = bp_unpack_value (&bp, 1);
810*e4b17023SJohn Marino fn->always_inline_functions_inlined = bp_unpack_value (&bp, 1);
811*e4b17023SJohn Marino fn->after_inlining = bp_unpack_value (&bp, 1);
812*e4b17023SJohn Marino fn->stdarg = bp_unpack_value (&bp, 1);
813*e4b17023SJohn Marino fn->has_nonlocal_label = bp_unpack_value (&bp, 1);
814*e4b17023SJohn Marino fn->calls_alloca = bp_unpack_value (&bp, 1);
815*e4b17023SJohn Marino fn->calls_setjmp = bp_unpack_value (&bp, 1);
816*e4b17023SJohn Marino fn->va_list_fpr_size = bp_unpack_value (&bp, 8);
817*e4b17023SJohn Marino fn->va_list_gpr_size = bp_unpack_value (&bp, 8);
818*e4b17023SJohn Marino }
819*e4b17023SJohn Marino
820*e4b17023SJohn Marino
821*e4b17023SJohn Marino /* Read the body of function FN_DECL from DATA_IN using input block IB. */
822*e4b17023SJohn Marino
823*e4b17023SJohn Marino static void
input_function(tree fn_decl,struct data_in * data_in,struct lto_input_block * ib)824*e4b17023SJohn Marino input_function (tree fn_decl, struct data_in *data_in,
825*e4b17023SJohn Marino struct lto_input_block *ib)
826*e4b17023SJohn Marino {
827*e4b17023SJohn Marino struct function *fn;
828*e4b17023SJohn Marino enum LTO_tags tag;
829*e4b17023SJohn Marino gimple *stmts;
830*e4b17023SJohn Marino basic_block bb;
831*e4b17023SJohn Marino struct cgraph_node *node;
832*e4b17023SJohn Marino tree args, narg, oarg;
833*e4b17023SJohn Marino
834*e4b17023SJohn Marino fn = DECL_STRUCT_FUNCTION (fn_decl);
835*e4b17023SJohn Marino tag = streamer_read_record_start (ib);
836*e4b17023SJohn Marino clear_line_info (data_in);
837*e4b17023SJohn Marino
838*e4b17023SJohn Marino gimple_register_cfg_hooks ();
839*e4b17023SJohn Marino lto_tag_check (tag, LTO_function);
840*e4b17023SJohn Marino
841*e4b17023SJohn Marino input_struct_function_base (fn, data_in, ib);
842*e4b17023SJohn Marino
843*e4b17023SJohn Marino /* Read all function arguments. We need to re-map them here to the
844*e4b17023SJohn Marino arguments of the merged function declaration. */
845*e4b17023SJohn Marino args = stream_read_tree (ib, data_in);
846*e4b17023SJohn Marino for (oarg = args, narg = DECL_ARGUMENTS (fn_decl);
847*e4b17023SJohn Marino oarg && narg;
848*e4b17023SJohn Marino oarg = TREE_CHAIN (oarg), narg = TREE_CHAIN (narg))
849*e4b17023SJohn Marino {
850*e4b17023SJohn Marino unsigned ix;
851*e4b17023SJohn Marino bool res;
852*e4b17023SJohn Marino res = streamer_tree_cache_lookup (data_in->reader_cache, oarg, &ix);
853*e4b17023SJohn Marino gcc_assert (res);
854*e4b17023SJohn Marino /* Replace the argument in the streamer cache. */
855*e4b17023SJohn Marino streamer_tree_cache_insert_at (data_in->reader_cache, narg, ix);
856*e4b17023SJohn Marino }
857*e4b17023SJohn Marino gcc_assert (!oarg && !narg);
858*e4b17023SJohn Marino
859*e4b17023SJohn Marino /* Read all the SSA names. */
860*e4b17023SJohn Marino input_ssa_names (ib, data_in, fn);
861*e4b17023SJohn Marino
862*e4b17023SJohn Marino /* Read the exception handling regions in the function. */
863*e4b17023SJohn Marino input_eh_regions (ib, data_in, fn);
864*e4b17023SJohn Marino
865*e4b17023SJohn Marino /* Read the tree of lexical scopes for the function. */
866*e4b17023SJohn Marino DECL_INITIAL (fn_decl) = stream_read_tree (ib, data_in);
867*e4b17023SJohn Marino gcc_assert (DECL_INITIAL (fn_decl));
868*e4b17023SJohn Marino DECL_SAVED_TREE (fn_decl) = NULL_TREE;
869*e4b17023SJohn Marino node = cgraph_get_create_node (fn_decl);
870*e4b17023SJohn Marino
871*e4b17023SJohn Marino /* Read all the basic blocks. */
872*e4b17023SJohn Marino tag = streamer_read_record_start (ib);
873*e4b17023SJohn Marino while (tag)
874*e4b17023SJohn Marino {
875*e4b17023SJohn Marino input_bb (ib, tag, data_in, fn,
876*e4b17023SJohn Marino node->count_materialization_scale);
877*e4b17023SJohn Marino tag = streamer_read_record_start (ib);
878*e4b17023SJohn Marino }
879*e4b17023SJohn Marino
880*e4b17023SJohn Marino /* Fix up the call statements that are mentioned in the callgraph
881*e4b17023SJohn Marino edges. */
882*e4b17023SJohn Marino set_gimple_stmt_max_uid (cfun, 0);
883*e4b17023SJohn Marino FOR_ALL_BB (bb)
884*e4b17023SJohn Marino {
885*e4b17023SJohn Marino gimple_stmt_iterator gsi;
886*e4b17023SJohn Marino for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
887*e4b17023SJohn Marino {
888*e4b17023SJohn Marino gimple stmt = gsi_stmt (gsi);
889*e4b17023SJohn Marino gimple_set_uid (stmt, inc_gimple_stmt_max_uid (cfun));
890*e4b17023SJohn Marino }
891*e4b17023SJohn Marino }
892*e4b17023SJohn Marino stmts = (gimple *) xcalloc (gimple_stmt_max_uid (fn), sizeof (gimple));
893*e4b17023SJohn Marino FOR_ALL_BB (bb)
894*e4b17023SJohn Marino {
895*e4b17023SJohn Marino gimple_stmt_iterator bsi = gsi_start_bb (bb);
896*e4b17023SJohn Marino while (!gsi_end_p (bsi))
897*e4b17023SJohn Marino {
898*e4b17023SJohn Marino gimple stmt = gsi_stmt (bsi);
899*e4b17023SJohn Marino /* If we're recompiling LTO objects with debug stmts but
900*e4b17023SJohn Marino we're not supposed to have debug stmts, remove them now.
901*e4b17023SJohn Marino We can't remove them earlier because this would cause uid
902*e4b17023SJohn Marino mismatches in fixups, but we can do it at this point, as
903*e4b17023SJohn Marino long as debug stmts don't require fixups. */
904*e4b17023SJohn Marino if (!MAY_HAVE_DEBUG_STMTS && is_gimple_debug (stmt))
905*e4b17023SJohn Marino {
906*e4b17023SJohn Marino gimple_stmt_iterator gsi = bsi;
907*e4b17023SJohn Marino gsi_next (&bsi);
908*e4b17023SJohn Marino gsi_remove (&gsi, true);
909*e4b17023SJohn Marino }
910*e4b17023SJohn Marino else
911*e4b17023SJohn Marino {
912*e4b17023SJohn Marino gsi_next (&bsi);
913*e4b17023SJohn Marino stmts[gimple_uid (stmt)] = stmt;
914*e4b17023SJohn Marino }
915*e4b17023SJohn Marino }
916*e4b17023SJohn Marino }
917*e4b17023SJohn Marino
918*e4b17023SJohn Marino /* Set the gimple body to the statement sequence in the entry
919*e4b17023SJohn Marino basic block. FIXME lto, this is fairly hacky. The existence
920*e4b17023SJohn Marino of a gimple body is used by the cgraph routines, but we should
921*e4b17023SJohn Marino really use the presence of the CFG. */
922*e4b17023SJohn Marino {
923*e4b17023SJohn Marino edge_iterator ei = ei_start (ENTRY_BLOCK_PTR->succs);
924*e4b17023SJohn Marino gimple_set_body (fn_decl, bb_seq (ei_edge (ei)->dest));
925*e4b17023SJohn Marino }
926*e4b17023SJohn Marino
927*e4b17023SJohn Marino fixup_call_stmt_edges (node, stmts);
928*e4b17023SJohn Marino execute_all_ipa_stmt_fixups (node, stmts);
929*e4b17023SJohn Marino
930*e4b17023SJohn Marino update_ssa (TODO_update_ssa_only_virtuals);
931*e4b17023SJohn Marino free_dominance_info (CDI_DOMINATORS);
932*e4b17023SJohn Marino free_dominance_info (CDI_POST_DOMINATORS);
933*e4b17023SJohn Marino free (stmts);
934*e4b17023SJohn Marino }
935*e4b17023SJohn Marino
936*e4b17023SJohn Marino
937*e4b17023SJohn Marino /* Read initializer expressions for public statics. DATA_IN is the
938*e4b17023SJohn Marino file being read. IB is the input block used for reading. */
939*e4b17023SJohn Marino
940*e4b17023SJohn Marino static void
input_alias_pairs(struct lto_input_block * ib,struct data_in * data_in)941*e4b17023SJohn Marino input_alias_pairs (struct lto_input_block *ib, struct data_in *data_in)
942*e4b17023SJohn Marino {
943*e4b17023SJohn Marino tree var;
944*e4b17023SJohn Marino
945*e4b17023SJohn Marino clear_line_info (data_in);
946*e4b17023SJohn Marino
947*e4b17023SJohn Marino var = stream_read_tree (ib, data_in);
948*e4b17023SJohn Marino while (var)
949*e4b17023SJohn Marino {
950*e4b17023SJohn Marino const char *orig_name, *new_name;
951*e4b17023SJohn Marino alias_pair *p;
952*e4b17023SJohn Marino
953*e4b17023SJohn Marino p = VEC_safe_push (alias_pair, gc, alias_pairs, NULL);
954*e4b17023SJohn Marino p->decl = var;
955*e4b17023SJohn Marino p->target = stream_read_tree (ib, data_in);
956*e4b17023SJohn Marino
957*e4b17023SJohn Marino /* If the target is a static object, we may have registered a
958*e4b17023SJohn Marino new name for it to avoid clashes between statics coming from
959*e4b17023SJohn Marino different files. In that case, use the new name. */
960*e4b17023SJohn Marino orig_name = IDENTIFIER_POINTER (p->target);
961*e4b17023SJohn Marino new_name = lto_get_decl_name_mapping (data_in->file_data, orig_name);
962*e4b17023SJohn Marino if (strcmp (orig_name, new_name) != 0)
963*e4b17023SJohn Marino p->target = get_identifier (new_name);
964*e4b17023SJohn Marino
965*e4b17023SJohn Marino var = stream_read_tree (ib, data_in);
966*e4b17023SJohn Marino }
967*e4b17023SJohn Marino }
968*e4b17023SJohn Marino
969*e4b17023SJohn Marino
970*e4b17023SJohn Marino /* Read the body from DATA for function FN_DECL and fill it in.
971*e4b17023SJohn Marino FILE_DATA are the global decls and types. SECTION_TYPE is either
972*e4b17023SJohn Marino LTO_section_function_body or LTO_section_static_initializer. If
973*e4b17023SJohn Marino section type is LTO_section_function_body, FN must be the decl for
974*e4b17023SJohn Marino that function. */
975*e4b17023SJohn Marino
976*e4b17023SJohn Marino static void
lto_read_body(struct lto_file_decl_data * file_data,tree fn_decl,const char * data,enum lto_section_type section_type)977*e4b17023SJohn Marino lto_read_body (struct lto_file_decl_data *file_data, tree fn_decl,
978*e4b17023SJohn Marino const char *data, enum lto_section_type section_type)
979*e4b17023SJohn Marino {
980*e4b17023SJohn Marino const struct lto_function_header *header;
981*e4b17023SJohn Marino struct data_in *data_in;
982*e4b17023SJohn Marino int cfg_offset;
983*e4b17023SJohn Marino int main_offset;
984*e4b17023SJohn Marino int string_offset;
985*e4b17023SJohn Marino struct lto_input_block ib_cfg;
986*e4b17023SJohn Marino struct lto_input_block ib_main;
987*e4b17023SJohn Marino
988*e4b17023SJohn Marino header = (const struct lto_function_header *) data;
989*e4b17023SJohn Marino cfg_offset = sizeof (struct lto_function_header);
990*e4b17023SJohn Marino main_offset = cfg_offset + header->cfg_size;
991*e4b17023SJohn Marino string_offset = main_offset + header->main_size;
992*e4b17023SJohn Marino
993*e4b17023SJohn Marino LTO_INIT_INPUT_BLOCK (ib_cfg,
994*e4b17023SJohn Marino data + cfg_offset,
995*e4b17023SJohn Marino 0,
996*e4b17023SJohn Marino header->cfg_size);
997*e4b17023SJohn Marino
998*e4b17023SJohn Marino LTO_INIT_INPUT_BLOCK (ib_main,
999*e4b17023SJohn Marino data + main_offset,
1000*e4b17023SJohn Marino 0,
1001*e4b17023SJohn Marino header->main_size);
1002*e4b17023SJohn Marino
1003*e4b17023SJohn Marino data_in = lto_data_in_create (file_data, data + string_offset,
1004*e4b17023SJohn Marino header->string_size, NULL);
1005*e4b17023SJohn Marino
1006*e4b17023SJohn Marino /* Make sure the file was generated by the exact same compiler. */
1007*e4b17023SJohn Marino lto_check_version (header->lto_header.major_version,
1008*e4b17023SJohn Marino header->lto_header.minor_version);
1009*e4b17023SJohn Marino
1010*e4b17023SJohn Marino if (section_type == LTO_section_function_body)
1011*e4b17023SJohn Marino {
1012*e4b17023SJohn Marino struct function *fn = DECL_STRUCT_FUNCTION (fn_decl);
1013*e4b17023SJohn Marino struct lto_in_decl_state *decl_state;
1014*e4b17023SJohn Marino struct cgraph_node *node = cgraph_get_node (fn_decl);
1015*e4b17023SJohn Marino unsigned from;
1016*e4b17023SJohn Marino
1017*e4b17023SJohn Marino gcc_checking_assert (node);
1018*e4b17023SJohn Marino push_cfun (fn);
1019*e4b17023SJohn Marino init_tree_ssa (fn);
1020*e4b17023SJohn Marino
1021*e4b17023SJohn Marino /* Use the function's decl state. */
1022*e4b17023SJohn Marino decl_state = lto_get_function_in_decl_state (file_data, fn_decl);
1023*e4b17023SJohn Marino gcc_assert (decl_state);
1024*e4b17023SJohn Marino file_data->current_decl_state = decl_state;
1025*e4b17023SJohn Marino
1026*e4b17023SJohn Marino input_cfg (&ib_cfg, fn, node->count_materialization_scale);
1027*e4b17023SJohn Marino
1028*e4b17023SJohn Marino /* Set up the struct function. */
1029*e4b17023SJohn Marino from = VEC_length (tree, data_in->reader_cache->nodes);
1030*e4b17023SJohn Marino input_function (fn_decl, data_in, &ib_main);
1031*e4b17023SJohn Marino /* And fixup types we streamed locally. */
1032*e4b17023SJohn Marino {
1033*e4b17023SJohn Marino struct streamer_tree_cache_d *cache = data_in->reader_cache;
1034*e4b17023SJohn Marino unsigned len = VEC_length (tree, cache->nodes);
1035*e4b17023SJohn Marino unsigned i;
1036*e4b17023SJohn Marino for (i = len; i-- > from;)
1037*e4b17023SJohn Marino {
1038*e4b17023SJohn Marino tree t = VEC_index (tree, cache->nodes, i);
1039*e4b17023SJohn Marino if (t == NULL_TREE)
1040*e4b17023SJohn Marino continue;
1041*e4b17023SJohn Marino
1042*e4b17023SJohn Marino if (TYPE_P (t))
1043*e4b17023SJohn Marino {
1044*e4b17023SJohn Marino gcc_assert (TYPE_CANONICAL (t) == NULL_TREE);
1045*e4b17023SJohn Marino TYPE_CANONICAL (t) = TYPE_MAIN_VARIANT (t);
1046*e4b17023SJohn Marino if (TYPE_MAIN_VARIANT (t) != t)
1047*e4b17023SJohn Marino {
1048*e4b17023SJohn Marino gcc_assert (TYPE_NEXT_VARIANT (t) == NULL_TREE);
1049*e4b17023SJohn Marino TYPE_NEXT_VARIANT (t)
1050*e4b17023SJohn Marino = TYPE_NEXT_VARIANT (TYPE_MAIN_VARIANT (t));
1051*e4b17023SJohn Marino TYPE_NEXT_VARIANT (TYPE_MAIN_VARIANT (t)) = t;
1052*e4b17023SJohn Marino }
1053*e4b17023SJohn Marino }
1054*e4b17023SJohn Marino }
1055*e4b17023SJohn Marino }
1056*e4b17023SJohn Marino
1057*e4b17023SJohn Marino /* We should now be in SSA. */
1058*e4b17023SJohn Marino cfun->gimple_df->in_ssa_p = true;
1059*e4b17023SJohn Marino
1060*e4b17023SJohn Marino /* Restore decl state */
1061*e4b17023SJohn Marino file_data->current_decl_state = file_data->global_decl_state;
1062*e4b17023SJohn Marino
1063*e4b17023SJohn Marino pop_cfun ();
1064*e4b17023SJohn Marino }
1065*e4b17023SJohn Marino else
1066*e4b17023SJohn Marino {
1067*e4b17023SJohn Marino input_alias_pairs (&ib_main, data_in);
1068*e4b17023SJohn Marino }
1069*e4b17023SJohn Marino
1070*e4b17023SJohn Marino clear_line_info (data_in);
1071*e4b17023SJohn Marino lto_data_in_delete (data_in);
1072*e4b17023SJohn Marino }
1073*e4b17023SJohn Marino
1074*e4b17023SJohn Marino
1075*e4b17023SJohn Marino /* Read the body of FN_DECL using DATA. FILE_DATA holds the global
1076*e4b17023SJohn Marino decls and types. */
1077*e4b17023SJohn Marino
1078*e4b17023SJohn Marino void
lto_input_function_body(struct lto_file_decl_data * file_data,tree fn_decl,const char * data)1079*e4b17023SJohn Marino lto_input_function_body (struct lto_file_decl_data *file_data,
1080*e4b17023SJohn Marino tree fn_decl, const char *data)
1081*e4b17023SJohn Marino {
1082*e4b17023SJohn Marino current_function_decl = fn_decl;
1083*e4b17023SJohn Marino lto_read_body (file_data, fn_decl, data, LTO_section_function_body);
1084*e4b17023SJohn Marino }
1085*e4b17023SJohn Marino
1086*e4b17023SJohn Marino
1087*e4b17023SJohn Marino /* Read in VAR_DECL using DATA. FILE_DATA holds the global decls and
1088*e4b17023SJohn Marino types. */
1089*e4b17023SJohn Marino
1090*e4b17023SJohn Marino void
lto_input_constructors_and_inits(struct lto_file_decl_data * file_data,const char * data)1091*e4b17023SJohn Marino lto_input_constructors_and_inits (struct lto_file_decl_data *file_data,
1092*e4b17023SJohn Marino const char *data)
1093*e4b17023SJohn Marino {
1094*e4b17023SJohn Marino lto_read_body (file_data, NULL, data, LTO_section_static_initializer);
1095*e4b17023SJohn Marino }
1096*e4b17023SJohn Marino
1097*e4b17023SJohn Marino
1098*e4b17023SJohn Marino /* Read the physical representation of a tree node with tag TAG from
1099*e4b17023SJohn Marino input block IB using the per-file context in DATA_IN. */
1100*e4b17023SJohn Marino
1101*e4b17023SJohn Marino static tree
lto_read_tree(struct lto_input_block * ib,struct data_in * data_in,enum LTO_tags tag)1102*e4b17023SJohn Marino lto_read_tree (struct lto_input_block *ib, struct data_in *data_in,
1103*e4b17023SJohn Marino enum LTO_tags tag)
1104*e4b17023SJohn Marino {
1105*e4b17023SJohn Marino /* Instantiate a new tree node. */
1106*e4b17023SJohn Marino tree result = streamer_alloc_tree (ib, data_in, tag);
1107*e4b17023SJohn Marino
1108*e4b17023SJohn Marino /* Enter RESULT in the reader cache. This will make RESULT
1109*e4b17023SJohn Marino available so that circular references in the rest of the tree
1110*e4b17023SJohn Marino structure can be resolved in subsequent calls to stream_read_tree. */
1111*e4b17023SJohn Marino streamer_tree_cache_append (data_in->reader_cache, result);
1112*e4b17023SJohn Marino
1113*e4b17023SJohn Marino /* Read all the bitfield values in RESULT. Note that for LTO, we
1114*e4b17023SJohn Marino only write language-independent bitfields, so no more unpacking is
1115*e4b17023SJohn Marino needed. */
1116*e4b17023SJohn Marino streamer_read_tree_bitfields (ib, result);
1117*e4b17023SJohn Marino
1118*e4b17023SJohn Marino /* Read all the pointer fields in RESULT. */
1119*e4b17023SJohn Marino streamer_read_tree_body (ib, data_in, result);
1120*e4b17023SJohn Marino
1121*e4b17023SJohn Marino /* Read any LTO-specific data not read by the tree streamer. */
1122*e4b17023SJohn Marino if (DECL_P (result)
1123*e4b17023SJohn Marino && TREE_CODE (result) != FUNCTION_DECL
1124*e4b17023SJohn Marino && TREE_CODE (result) != TRANSLATION_UNIT_DECL)
1125*e4b17023SJohn Marino DECL_INITIAL (result) = stream_read_tree (ib, data_in);
1126*e4b17023SJohn Marino
1127*e4b17023SJohn Marino /* We should never try to instantiate an MD or NORMAL builtin here. */
1128*e4b17023SJohn Marino if (TREE_CODE (result) == FUNCTION_DECL)
1129*e4b17023SJohn Marino gcc_assert (!streamer_handle_as_builtin_p (result));
1130*e4b17023SJohn Marino
1131*e4b17023SJohn Marino /* end_marker = */ streamer_read_uchar (ib);
1132*e4b17023SJohn Marino
1133*e4b17023SJohn Marino #ifdef LTO_STREAMER_DEBUG
1134*e4b17023SJohn Marino /* Remove the mapping to RESULT's original address set by
1135*e4b17023SJohn Marino streamer_alloc_tree. */
1136*e4b17023SJohn Marino lto_orig_address_remove (result);
1137*e4b17023SJohn Marino #endif
1138*e4b17023SJohn Marino
1139*e4b17023SJohn Marino return result;
1140*e4b17023SJohn Marino }
1141*e4b17023SJohn Marino
1142*e4b17023SJohn Marino
1143*e4b17023SJohn Marino /* Read a tree from input block IB using the per-file context in
1144*e4b17023SJohn Marino DATA_IN. This context is used, for example, to resolve references
1145*e4b17023SJohn Marino to previously read nodes. */
1146*e4b17023SJohn Marino
1147*e4b17023SJohn Marino tree
lto_input_tree(struct lto_input_block * ib,struct data_in * data_in)1148*e4b17023SJohn Marino lto_input_tree (struct lto_input_block *ib, struct data_in *data_in)
1149*e4b17023SJohn Marino {
1150*e4b17023SJohn Marino enum LTO_tags tag;
1151*e4b17023SJohn Marino tree result;
1152*e4b17023SJohn Marino
1153*e4b17023SJohn Marino tag = streamer_read_record_start (ib);
1154*e4b17023SJohn Marino gcc_assert ((unsigned) tag < (unsigned) LTO_NUM_TAGS);
1155*e4b17023SJohn Marino
1156*e4b17023SJohn Marino if (tag == LTO_null)
1157*e4b17023SJohn Marino result = NULL_TREE;
1158*e4b17023SJohn Marino else if (tag >= LTO_field_decl_ref && tag <= LTO_global_decl_ref)
1159*e4b17023SJohn Marino {
1160*e4b17023SJohn Marino /* If TAG is a reference to an indexable tree, the next value
1161*e4b17023SJohn Marino in IB is the index into the table where we expect to find
1162*e4b17023SJohn Marino that tree. */
1163*e4b17023SJohn Marino result = lto_input_tree_ref (ib, data_in, cfun, tag);
1164*e4b17023SJohn Marino }
1165*e4b17023SJohn Marino else if (tag == LTO_tree_pickle_reference)
1166*e4b17023SJohn Marino {
1167*e4b17023SJohn Marino /* If TAG is a reference to a previously read tree, look it up in
1168*e4b17023SJohn Marino the reader cache. */
1169*e4b17023SJohn Marino result = streamer_get_pickled_tree (ib, data_in);
1170*e4b17023SJohn Marino }
1171*e4b17023SJohn Marino else if (tag == LTO_builtin_decl)
1172*e4b17023SJohn Marino {
1173*e4b17023SJohn Marino /* If we are going to read a built-in function, all we need is
1174*e4b17023SJohn Marino the code and class. */
1175*e4b17023SJohn Marino result = streamer_get_builtin_tree (ib, data_in);
1176*e4b17023SJohn Marino }
1177*e4b17023SJohn Marino else if (tag == lto_tree_code_to_tag (INTEGER_CST))
1178*e4b17023SJohn Marino {
1179*e4b17023SJohn Marino /* For integer constants we only need the type and its hi/low
1180*e4b17023SJohn Marino words. */
1181*e4b17023SJohn Marino result = streamer_read_integer_cst (ib, data_in);
1182*e4b17023SJohn Marino }
1183*e4b17023SJohn Marino else
1184*e4b17023SJohn Marino {
1185*e4b17023SJohn Marino /* Otherwise, materialize a new node from IB. */
1186*e4b17023SJohn Marino result = lto_read_tree (ib, data_in, tag);
1187*e4b17023SJohn Marino }
1188*e4b17023SJohn Marino
1189*e4b17023SJohn Marino return result;
1190*e4b17023SJohn Marino }
1191*e4b17023SJohn Marino
1192*e4b17023SJohn Marino
1193*e4b17023SJohn Marino /* Input toplevel asms. */
1194*e4b17023SJohn Marino
1195*e4b17023SJohn Marino void
lto_input_toplevel_asms(struct lto_file_decl_data * file_data,int order_base)1196*e4b17023SJohn Marino lto_input_toplevel_asms (struct lto_file_decl_data *file_data, int order_base)
1197*e4b17023SJohn Marino {
1198*e4b17023SJohn Marino size_t len;
1199*e4b17023SJohn Marino const char *data = lto_get_section_data (file_data, LTO_section_asm,
1200*e4b17023SJohn Marino NULL, &len);
1201*e4b17023SJohn Marino const struct lto_asm_header *header = (const struct lto_asm_header *) data;
1202*e4b17023SJohn Marino int string_offset;
1203*e4b17023SJohn Marino struct data_in *data_in;
1204*e4b17023SJohn Marino struct lto_input_block ib;
1205*e4b17023SJohn Marino tree str;
1206*e4b17023SJohn Marino
1207*e4b17023SJohn Marino if (! data)
1208*e4b17023SJohn Marino return;
1209*e4b17023SJohn Marino
1210*e4b17023SJohn Marino string_offset = sizeof (*header) + header->main_size;
1211*e4b17023SJohn Marino
1212*e4b17023SJohn Marino LTO_INIT_INPUT_BLOCK (ib,
1213*e4b17023SJohn Marino data + sizeof (*header),
1214*e4b17023SJohn Marino 0,
1215*e4b17023SJohn Marino header->main_size);
1216*e4b17023SJohn Marino
1217*e4b17023SJohn Marino data_in = lto_data_in_create (file_data, data + string_offset,
1218*e4b17023SJohn Marino header->string_size, NULL);
1219*e4b17023SJohn Marino
1220*e4b17023SJohn Marino /* Make sure the file was generated by the exact same compiler. */
1221*e4b17023SJohn Marino lto_check_version (header->lto_header.major_version,
1222*e4b17023SJohn Marino header->lto_header.minor_version);
1223*e4b17023SJohn Marino
1224*e4b17023SJohn Marino while ((str = streamer_read_string_cst (data_in, &ib)))
1225*e4b17023SJohn Marino {
1226*e4b17023SJohn Marino struct cgraph_asm_node *node = cgraph_add_asm_node (str);
1227*e4b17023SJohn Marino node->order = streamer_read_hwi (&ib) + order_base;
1228*e4b17023SJohn Marino if (node->order >= cgraph_order)
1229*e4b17023SJohn Marino cgraph_order = node->order + 1;
1230*e4b17023SJohn Marino }
1231*e4b17023SJohn Marino
1232*e4b17023SJohn Marino clear_line_info (data_in);
1233*e4b17023SJohn Marino lto_data_in_delete (data_in);
1234*e4b17023SJohn Marino
1235*e4b17023SJohn Marino lto_free_section_data (file_data, LTO_section_asm, NULL, data, len);
1236*e4b17023SJohn Marino }
1237*e4b17023SJohn Marino
1238*e4b17023SJohn Marino
1239*e4b17023SJohn Marino /* Initialization for the LTO reader. */
1240*e4b17023SJohn Marino
1241*e4b17023SJohn Marino void
lto_reader_init(void)1242*e4b17023SJohn Marino lto_reader_init (void)
1243*e4b17023SJohn Marino {
1244*e4b17023SJohn Marino lto_streamer_init ();
1245*e4b17023SJohn Marino file_name_hash_table = htab_create (37, hash_string_slot_node,
1246*e4b17023SJohn Marino eq_string_slot_node, free);
1247*e4b17023SJohn Marino }
1248*e4b17023SJohn Marino
1249*e4b17023SJohn Marino
1250*e4b17023SJohn Marino /* Create a new data_in object for FILE_DATA. STRINGS is the string
1251*e4b17023SJohn Marino table to use with LEN strings. RESOLUTIONS is the vector of linker
1252*e4b17023SJohn Marino resolutions (NULL if not using a linker plugin). */
1253*e4b17023SJohn Marino
1254*e4b17023SJohn Marino 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,heap)* resolutions)1255*e4b17023SJohn Marino lto_data_in_create (struct lto_file_decl_data *file_data, const char *strings,
1256*e4b17023SJohn Marino unsigned len,
1257*e4b17023SJohn Marino VEC(ld_plugin_symbol_resolution_t,heap) *resolutions)
1258*e4b17023SJohn Marino {
1259*e4b17023SJohn Marino struct data_in *data_in = XCNEW (struct data_in);
1260*e4b17023SJohn Marino data_in->file_data = file_data;
1261*e4b17023SJohn Marino data_in->strings = strings;
1262*e4b17023SJohn Marino data_in->strings_len = len;
1263*e4b17023SJohn Marino data_in->globals_resolution = resolutions;
1264*e4b17023SJohn Marino data_in->reader_cache = streamer_tree_cache_create ();
1265*e4b17023SJohn Marino
1266*e4b17023SJohn Marino return data_in;
1267*e4b17023SJohn Marino }
1268*e4b17023SJohn Marino
1269*e4b17023SJohn Marino
1270*e4b17023SJohn Marino /* Remove DATA_IN. */
1271*e4b17023SJohn Marino
1272*e4b17023SJohn Marino void
lto_data_in_delete(struct data_in * data_in)1273*e4b17023SJohn Marino lto_data_in_delete (struct data_in *data_in)
1274*e4b17023SJohn Marino {
1275*e4b17023SJohn Marino VEC_free (ld_plugin_symbol_resolution_t, heap, data_in->globals_resolution);
1276*e4b17023SJohn Marino streamer_tree_cache_delete (data_in->reader_cache);
1277*e4b17023SJohn Marino free (data_in->labels);
1278*e4b17023SJohn Marino free (data_in);
1279*e4b17023SJohn Marino }
1280