xref: /dflybsd-src/contrib/gcc-4.7/gcc/lto-streamer-in.c (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
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