1*38fd1498Szrj /* Write the GIMPLE representation to a file stream.
2*38fd1498Szrj 
3*38fd1498Szrj    Copyright (C) 2009-2018 Free Software Foundation, Inc.
4*38fd1498Szrj    Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
5*38fd1498Szrj    Re-implemented by Diego Novillo <dnovillo@google.com>
6*38fd1498Szrj 
7*38fd1498Szrj This file is part of GCC.
8*38fd1498Szrj 
9*38fd1498Szrj GCC is free software; you can redistribute it and/or modify it under
10*38fd1498Szrj the terms of the GNU General Public License as published by the Free
11*38fd1498Szrj Software Foundation; either version 3, or (at your option) any later
12*38fd1498Szrj version.
13*38fd1498Szrj 
14*38fd1498Szrj GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15*38fd1498Szrj WARRANTY; without even the implied warranty of MERCHANTABILITY or
16*38fd1498Szrj FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17*38fd1498Szrj for more details.
18*38fd1498Szrj 
19*38fd1498Szrj You should have received a copy of the GNU General Public License
20*38fd1498Szrj along with GCC; see the file COPYING3.  If not see
21*38fd1498Szrj <http://www.gnu.org/licenses/>.  */
22*38fd1498Szrj 
23*38fd1498Szrj #include "config.h"
24*38fd1498Szrj #include "system.h"
25*38fd1498Szrj #include "coretypes.h"
26*38fd1498Szrj #include "backend.h"
27*38fd1498Szrj #include "target.h"
28*38fd1498Szrj #include "rtl.h"
29*38fd1498Szrj #include "tree.h"
30*38fd1498Szrj #include "gimple.h"
31*38fd1498Szrj #include "tree-pass.h"
32*38fd1498Szrj #include "ssa.h"
33*38fd1498Szrj #include "gimple-streamer.h"
34*38fd1498Szrj #include "alias.h"
35*38fd1498Szrj #include "stor-layout.h"
36*38fd1498Szrj #include "gimple-iterator.h"
37*38fd1498Szrj #include "except.h"
38*38fd1498Szrj #include "lto-symtab.h"
39*38fd1498Szrj #include "cgraph.h"
40*38fd1498Szrj #include "cfgloop.h"
41*38fd1498Szrj #include "builtins.h"
42*38fd1498Szrj #include "gomp-constants.h"
43*38fd1498Szrj #include "debug.h"
44*38fd1498Szrj #include "omp-offload.h"
45*38fd1498Szrj 
46*38fd1498Szrj 
47*38fd1498Szrj static void lto_write_tree (struct output_block*, tree, bool);
48*38fd1498Szrj 
49*38fd1498Szrj /* Clear the line info stored in DATA_IN.  */
50*38fd1498Szrj 
51*38fd1498Szrj static void
clear_line_info(struct output_block * ob)52*38fd1498Szrj clear_line_info (struct output_block *ob)
53*38fd1498Szrj {
54*38fd1498Szrj   ob->current_file = NULL;
55*38fd1498Szrj   ob->current_line = 0;
56*38fd1498Szrj   ob->current_col = 0;
57*38fd1498Szrj   ob->current_sysp = false;
58*38fd1498Szrj }
59*38fd1498Szrj 
60*38fd1498Szrj 
61*38fd1498Szrj /* Create the output block and return it.  SECTION_TYPE is
62*38fd1498Szrj    LTO_section_function_body or LTO_static_initializer.  */
63*38fd1498Szrj 
64*38fd1498Szrj struct output_block *
create_output_block(enum lto_section_type section_type)65*38fd1498Szrj create_output_block (enum lto_section_type section_type)
66*38fd1498Szrj {
67*38fd1498Szrj   struct output_block *ob = XCNEW (struct output_block);
68*38fd1498Szrj 
69*38fd1498Szrj   ob->section_type = section_type;
70*38fd1498Szrj   ob->decl_state = lto_get_out_decl_state ();
71*38fd1498Szrj   ob->main_stream = XCNEW (struct lto_output_stream);
72*38fd1498Szrj   ob->string_stream = XCNEW (struct lto_output_stream);
73*38fd1498Szrj   ob->writer_cache = streamer_tree_cache_create (!flag_wpa, true, false);
74*38fd1498Szrj 
75*38fd1498Szrj   if (section_type == LTO_section_function_body)
76*38fd1498Szrj     ob->cfg_stream = XCNEW (struct lto_output_stream);
77*38fd1498Szrj 
78*38fd1498Szrj   clear_line_info (ob);
79*38fd1498Szrj 
80*38fd1498Szrj   ob->string_hash_table = new hash_table<string_slot_hasher> (37);
81*38fd1498Szrj   gcc_obstack_init (&ob->obstack);
82*38fd1498Szrj 
83*38fd1498Szrj   return ob;
84*38fd1498Szrj }
85*38fd1498Szrj 
86*38fd1498Szrj 
87*38fd1498Szrj /* Destroy the output block OB.  */
88*38fd1498Szrj 
89*38fd1498Szrj void
destroy_output_block(struct output_block * ob)90*38fd1498Szrj destroy_output_block (struct output_block *ob)
91*38fd1498Szrj {
92*38fd1498Szrj   enum lto_section_type section_type = ob->section_type;
93*38fd1498Szrj 
94*38fd1498Szrj   delete ob->string_hash_table;
95*38fd1498Szrj   ob->string_hash_table = NULL;
96*38fd1498Szrj 
97*38fd1498Szrj   free (ob->main_stream);
98*38fd1498Szrj   free (ob->string_stream);
99*38fd1498Szrj   if (section_type == LTO_section_function_body)
100*38fd1498Szrj     free (ob->cfg_stream);
101*38fd1498Szrj 
102*38fd1498Szrj   streamer_tree_cache_delete (ob->writer_cache);
103*38fd1498Szrj   obstack_free (&ob->obstack, NULL);
104*38fd1498Szrj 
105*38fd1498Szrj   free (ob);
106*38fd1498Szrj }
107*38fd1498Szrj 
108*38fd1498Szrj 
109*38fd1498Szrj /* Look up NODE in the type table and write the index for it to OB.  */
110*38fd1498Szrj 
111*38fd1498Szrj static void
output_type_ref(struct output_block * ob,tree node)112*38fd1498Szrj output_type_ref (struct output_block *ob, tree node)
113*38fd1498Szrj {
114*38fd1498Szrj   streamer_write_record_start (ob, LTO_type_ref);
115*38fd1498Szrj   lto_output_type_ref_index (ob->decl_state, ob->main_stream, node);
116*38fd1498Szrj }
117*38fd1498Szrj 
118*38fd1498Szrj 
119*38fd1498Szrj /* Return true if tree node T is written to various tables.  For these
120*38fd1498Szrj    nodes, we sometimes want to write their phyiscal representation
121*38fd1498Szrj    (via lto_output_tree), and sometimes we need to emit an index
122*38fd1498Szrj    reference into a table (via lto_output_tree_ref).  */
123*38fd1498Szrj 
124*38fd1498Szrj static bool
tree_is_indexable(tree t)125*38fd1498Szrj tree_is_indexable (tree t)
126*38fd1498Szrj {
127*38fd1498Szrj   /* Parameters and return values of functions of variably modified types
128*38fd1498Szrj      must go to global stream, because they may be used in the type
129*38fd1498Szrj      definition.  */
130*38fd1498Szrj   if ((TREE_CODE (t) == PARM_DECL || TREE_CODE (t) == RESULT_DECL)
131*38fd1498Szrj       && DECL_CONTEXT (t))
132*38fd1498Szrj     return variably_modified_type_p (TREE_TYPE (DECL_CONTEXT (t)), NULL_TREE);
133*38fd1498Szrj   /* IMPORTED_DECL is put into BLOCK and thus it never can be shared.  */
134*38fd1498Szrj   else if (TREE_CODE (t) == IMPORTED_DECL)
135*38fd1498Szrj     return false;
136*38fd1498Szrj   else if (((VAR_P (t) && !TREE_STATIC (t))
137*38fd1498Szrj 	    || TREE_CODE (t) == TYPE_DECL
138*38fd1498Szrj 	    || TREE_CODE (t) == CONST_DECL
139*38fd1498Szrj 	    || TREE_CODE (t) == NAMELIST_DECL)
140*38fd1498Szrj 	   && decl_function_context (t))
141*38fd1498Szrj     return false;
142*38fd1498Szrj   else if (TREE_CODE (t) == DEBUG_EXPR_DECL)
143*38fd1498Szrj     return false;
144*38fd1498Szrj   /* Variably modified types need to be streamed alongside function
145*38fd1498Szrj      bodies because they can refer to local entities.  Together with
146*38fd1498Szrj      them we have to localize their members as well.
147*38fd1498Szrj      ???  In theory that includes non-FIELD_DECLs as well.  */
148*38fd1498Szrj   else if (TYPE_P (t)
149*38fd1498Szrj 	   && variably_modified_type_p (t, NULL_TREE))
150*38fd1498Szrj     return false;
151*38fd1498Szrj   else if (TREE_CODE (t) == FIELD_DECL
152*38fd1498Szrj 	   && variably_modified_type_p (DECL_CONTEXT (t), NULL_TREE))
153*38fd1498Szrj     return false;
154*38fd1498Szrj   else
155*38fd1498Szrj     return (TYPE_P (t) || DECL_P (t) || TREE_CODE (t) == SSA_NAME);
156*38fd1498Szrj }
157*38fd1498Szrj 
158*38fd1498Szrj 
159*38fd1498Szrj /* Output info about new location into bitpack BP.
160*38fd1498Szrj    After outputting bitpack, lto_output_location_data has
161*38fd1498Szrj    to be done to output actual data.  */
162*38fd1498Szrj 
163*38fd1498Szrj void
lto_output_location(struct output_block * ob,struct bitpack_d * bp,location_t loc)164*38fd1498Szrj lto_output_location (struct output_block *ob, struct bitpack_d *bp,
165*38fd1498Szrj 		     location_t loc)
166*38fd1498Szrj {
167*38fd1498Szrj   expanded_location xloc;
168*38fd1498Szrj 
169*38fd1498Szrj   loc = LOCATION_LOCUS (loc);
170*38fd1498Szrj   bp_pack_int_in_range (bp, 0, RESERVED_LOCATION_COUNT,
171*38fd1498Szrj 		        loc < RESERVED_LOCATION_COUNT
172*38fd1498Szrj 			? loc : RESERVED_LOCATION_COUNT);
173*38fd1498Szrj   if (loc < RESERVED_LOCATION_COUNT)
174*38fd1498Szrj     return;
175*38fd1498Szrj 
176*38fd1498Szrj   xloc = expand_location (loc);
177*38fd1498Szrj 
178*38fd1498Szrj   bp_pack_value (bp, ob->current_file != xloc.file, 1);
179*38fd1498Szrj   bp_pack_value (bp, ob->current_line != xloc.line, 1);
180*38fd1498Szrj   bp_pack_value (bp, ob->current_col != xloc.column, 1);
181*38fd1498Szrj 
182*38fd1498Szrj   if (ob->current_file != xloc.file)
183*38fd1498Szrj     {
184*38fd1498Szrj       bp_pack_string (ob, bp, xloc.file, true);
185*38fd1498Szrj       bp_pack_value (bp, xloc.sysp, 1);
186*38fd1498Szrj     }
187*38fd1498Szrj   ob->current_file = xloc.file;
188*38fd1498Szrj   ob->current_sysp = xloc.sysp;
189*38fd1498Szrj 
190*38fd1498Szrj   if (ob->current_line != xloc.line)
191*38fd1498Szrj     bp_pack_var_len_unsigned (bp, xloc.line);
192*38fd1498Szrj   ob->current_line = xloc.line;
193*38fd1498Szrj 
194*38fd1498Szrj   if (ob->current_col != xloc.column)
195*38fd1498Szrj     bp_pack_var_len_unsigned (bp, xloc.column);
196*38fd1498Szrj   ob->current_col = xloc.column;
197*38fd1498Szrj }
198*38fd1498Szrj 
199*38fd1498Szrj 
200*38fd1498Szrj /* If EXPR is an indexable tree node, output a reference to it to
201*38fd1498Szrj    output block OB.  Otherwise, output the physical representation of
202*38fd1498Szrj    EXPR to OB.  */
203*38fd1498Szrj 
204*38fd1498Szrj static void
lto_output_tree_ref(struct output_block * ob,tree expr)205*38fd1498Szrj lto_output_tree_ref (struct output_block *ob, tree expr)
206*38fd1498Szrj {
207*38fd1498Szrj   enum tree_code code;
208*38fd1498Szrj 
209*38fd1498Szrj   if (TYPE_P (expr))
210*38fd1498Szrj     {
211*38fd1498Szrj       output_type_ref (ob, expr);
212*38fd1498Szrj       return;
213*38fd1498Szrj     }
214*38fd1498Szrj 
215*38fd1498Szrj   code = TREE_CODE (expr);
216*38fd1498Szrj   switch (code)
217*38fd1498Szrj     {
218*38fd1498Szrj     case SSA_NAME:
219*38fd1498Szrj       streamer_write_record_start (ob, LTO_ssa_name_ref);
220*38fd1498Szrj       streamer_write_uhwi (ob, SSA_NAME_VERSION (expr));
221*38fd1498Szrj       break;
222*38fd1498Szrj 
223*38fd1498Szrj     case FIELD_DECL:
224*38fd1498Szrj       streamer_write_record_start (ob, LTO_field_decl_ref);
225*38fd1498Szrj       lto_output_field_decl_index (ob->decl_state, ob->main_stream, expr);
226*38fd1498Szrj       break;
227*38fd1498Szrj 
228*38fd1498Szrj     case FUNCTION_DECL:
229*38fd1498Szrj       streamer_write_record_start (ob, LTO_function_decl_ref);
230*38fd1498Szrj       lto_output_fn_decl_index (ob->decl_state, ob->main_stream, expr);
231*38fd1498Szrj       break;
232*38fd1498Szrj 
233*38fd1498Szrj     case VAR_DECL:
234*38fd1498Szrj     case DEBUG_EXPR_DECL:
235*38fd1498Szrj       gcc_assert (decl_function_context (expr) == NULL || TREE_STATIC (expr));
236*38fd1498Szrj       /* FALLTHRU */
237*38fd1498Szrj     case PARM_DECL:
238*38fd1498Szrj       streamer_write_record_start (ob, LTO_global_decl_ref);
239*38fd1498Szrj       lto_output_var_decl_index (ob->decl_state, ob->main_stream, expr);
240*38fd1498Szrj       break;
241*38fd1498Szrj 
242*38fd1498Szrj     case CONST_DECL:
243*38fd1498Szrj       streamer_write_record_start (ob, LTO_const_decl_ref);
244*38fd1498Szrj       lto_output_var_decl_index (ob->decl_state, ob->main_stream, expr);
245*38fd1498Szrj       break;
246*38fd1498Szrj 
247*38fd1498Szrj     case IMPORTED_DECL:
248*38fd1498Szrj       gcc_assert (decl_function_context (expr) == NULL);
249*38fd1498Szrj       streamer_write_record_start (ob, LTO_imported_decl_ref);
250*38fd1498Szrj       lto_output_var_decl_index (ob->decl_state, ob->main_stream, expr);
251*38fd1498Szrj       break;
252*38fd1498Szrj 
253*38fd1498Szrj     case TYPE_DECL:
254*38fd1498Szrj       streamer_write_record_start (ob, LTO_type_decl_ref);
255*38fd1498Szrj       lto_output_type_decl_index (ob->decl_state, ob->main_stream, expr);
256*38fd1498Szrj       break;
257*38fd1498Szrj 
258*38fd1498Szrj     case NAMELIST_DECL:
259*38fd1498Szrj       streamer_write_record_start (ob, LTO_namelist_decl_ref);
260*38fd1498Szrj       lto_output_var_decl_index (ob->decl_state, ob->main_stream, expr);
261*38fd1498Szrj       break;
262*38fd1498Szrj 
263*38fd1498Szrj     case NAMESPACE_DECL:
264*38fd1498Szrj       streamer_write_record_start (ob, LTO_namespace_decl_ref);
265*38fd1498Szrj       lto_output_namespace_decl_index (ob->decl_state, ob->main_stream, expr);
266*38fd1498Szrj       break;
267*38fd1498Szrj 
268*38fd1498Szrj     case LABEL_DECL:
269*38fd1498Szrj       streamer_write_record_start (ob, LTO_label_decl_ref);
270*38fd1498Szrj       lto_output_var_decl_index (ob->decl_state, ob->main_stream, expr);
271*38fd1498Szrj       break;
272*38fd1498Szrj 
273*38fd1498Szrj     case RESULT_DECL:
274*38fd1498Szrj       streamer_write_record_start (ob, LTO_result_decl_ref);
275*38fd1498Szrj       lto_output_var_decl_index (ob->decl_state, ob->main_stream, expr);
276*38fd1498Szrj       break;
277*38fd1498Szrj 
278*38fd1498Szrj     case TRANSLATION_UNIT_DECL:
279*38fd1498Szrj       streamer_write_record_start (ob, LTO_translation_unit_decl_ref);
280*38fd1498Szrj       lto_output_var_decl_index (ob->decl_state, ob->main_stream, expr);
281*38fd1498Szrj       break;
282*38fd1498Szrj 
283*38fd1498Szrj     default:
284*38fd1498Szrj       /* No other node is indexable, so it should have been handled by
285*38fd1498Szrj 	 lto_output_tree.  */
286*38fd1498Szrj       gcc_unreachable ();
287*38fd1498Szrj     }
288*38fd1498Szrj }
289*38fd1498Szrj 
290*38fd1498Szrj 
291*38fd1498Szrj /* Return true if EXPR is a tree node that can be written to disk.  */
292*38fd1498Szrj 
293*38fd1498Szrj static inline bool
lto_is_streamable(tree expr)294*38fd1498Szrj lto_is_streamable (tree expr)
295*38fd1498Szrj {
296*38fd1498Szrj   enum tree_code code = TREE_CODE (expr);
297*38fd1498Szrj 
298*38fd1498Szrj   /* Notice that we reject SSA_NAMEs as well.  We only emit the SSA
299*38fd1498Szrj      name version in lto_output_tree_ref (see output_ssa_names).  */
300*38fd1498Szrj   return !is_lang_specific (expr)
301*38fd1498Szrj 	 && code != SSA_NAME
302*38fd1498Szrj 	 && code != LANG_TYPE
303*38fd1498Szrj 	 && code != MODIFY_EXPR
304*38fd1498Szrj 	 && code != INIT_EXPR
305*38fd1498Szrj 	 && code != TARGET_EXPR
306*38fd1498Szrj 	 && code != BIND_EXPR
307*38fd1498Szrj 	 && code != WITH_CLEANUP_EXPR
308*38fd1498Szrj 	 && code != STATEMENT_LIST
309*38fd1498Szrj 	 && (code == CASE_LABEL_EXPR
310*38fd1498Szrj 	     || code == DECL_EXPR
311*38fd1498Szrj 	     || TREE_CODE_CLASS (code) != tcc_statement);
312*38fd1498Szrj }
313*38fd1498Szrj 
314*38fd1498Szrj /* Very rough estimate of streaming size of the initializer.  If we ignored
315*38fd1498Szrj    presence of strings, we could simply just count number of non-indexable
316*38fd1498Szrj    tree nodes and number of references to indexable nodes.  Strings however
317*38fd1498Szrj    may be very large and we do not want to dump them int othe global stream.
318*38fd1498Szrj 
319*38fd1498Szrj    Count the size of initializer until the size in DATA is positive.  */
320*38fd1498Szrj 
321*38fd1498Szrj static tree
subtract_estimated_size(tree * tp,int * ws,void * data)322*38fd1498Szrj subtract_estimated_size (tree *tp, int *ws, void *data)
323*38fd1498Szrj {
324*38fd1498Szrj   long *sum = (long *)data;
325*38fd1498Szrj   if (tree_is_indexable (*tp))
326*38fd1498Szrj     {
327*38fd1498Szrj       /* Indexable tree is one reference to global stream.
328*38fd1498Szrj 	 Guess it may be about 4 bytes.  */
329*38fd1498Szrj       *sum -= 4;
330*38fd1498Szrj       *ws = 0;
331*38fd1498Szrj     }
332*38fd1498Szrj   /* String table entry + base of tree node needs to be streamed.  */
333*38fd1498Szrj   if (TREE_CODE (*tp) == STRING_CST)
334*38fd1498Szrj     *sum -= TREE_STRING_LENGTH (*tp) + 8;
335*38fd1498Szrj   else
336*38fd1498Szrj     {
337*38fd1498Szrj       /* Identifiers are also variable length but should not appear
338*38fd1498Szrj 	 naked in constructor.  */
339*38fd1498Szrj       gcc_checking_assert (TREE_CODE (*tp) != IDENTIFIER_NODE);
340*38fd1498Szrj       /* We do not really make attempt to work out size of pickled tree, as
341*38fd1498Szrj 	 it is very variable. Make it bigger than the reference.  */
342*38fd1498Szrj       *sum -= 16;
343*38fd1498Szrj     }
344*38fd1498Szrj   if (*sum < 0)
345*38fd1498Szrj     return *tp;
346*38fd1498Szrj   return NULL_TREE;
347*38fd1498Szrj }
348*38fd1498Szrj 
349*38fd1498Szrj 
350*38fd1498Szrj /* For EXPR lookup and return what we want to stream to OB as DECL_INITIAL.  */
351*38fd1498Szrj 
352*38fd1498Szrj static tree
get_symbol_initial_value(lto_symtab_encoder_t encoder,tree expr)353*38fd1498Szrj get_symbol_initial_value (lto_symtab_encoder_t encoder, tree expr)
354*38fd1498Szrj {
355*38fd1498Szrj   gcc_checking_assert (DECL_P (expr)
356*38fd1498Szrj 		       && TREE_CODE (expr) != FUNCTION_DECL
357*38fd1498Szrj 		       && TREE_CODE (expr) != TRANSLATION_UNIT_DECL);
358*38fd1498Szrj 
359*38fd1498Szrj   /* Handle DECL_INITIAL for symbols.  */
360*38fd1498Szrj   tree initial = DECL_INITIAL (expr);
361*38fd1498Szrj   if (VAR_P (expr)
362*38fd1498Szrj       && (TREE_STATIC (expr) || DECL_EXTERNAL (expr))
363*38fd1498Szrj       && !DECL_IN_CONSTANT_POOL (expr)
364*38fd1498Szrj       && initial)
365*38fd1498Szrj     {
366*38fd1498Szrj       varpool_node *vnode;
367*38fd1498Szrj       /* Extra section needs about 30 bytes; do not produce it for simple
368*38fd1498Szrj 	 scalar values.  */
369*38fd1498Szrj       if (!(vnode = varpool_node::get (expr))
370*38fd1498Szrj 	  || !lto_symtab_encoder_encode_initializer_p (encoder, vnode))
371*38fd1498Szrj         initial = error_mark_node;
372*38fd1498Szrj       if (initial != error_mark_node)
373*38fd1498Szrj 	{
374*38fd1498Szrj 	  long max_size = 30;
375*38fd1498Szrj 	  if (walk_tree (&initial, subtract_estimated_size, (void *)&max_size,
376*38fd1498Szrj 			 NULL))
377*38fd1498Szrj 	    initial = error_mark_node;
378*38fd1498Szrj 	}
379*38fd1498Szrj     }
380*38fd1498Szrj 
381*38fd1498Szrj   return initial;
382*38fd1498Szrj }
383*38fd1498Szrj 
384*38fd1498Szrj 
385*38fd1498Szrj /* Write a physical representation of tree node EXPR to output block
386*38fd1498Szrj    OB.  If REF_P is true, the leaves of EXPR are emitted as references
387*38fd1498Szrj    via lto_output_tree_ref.  IX is the index into the streamer cache
388*38fd1498Szrj    where EXPR is stored.  */
389*38fd1498Szrj 
390*38fd1498Szrj static void
lto_write_tree_1(struct output_block * ob,tree expr,bool ref_p)391*38fd1498Szrj lto_write_tree_1 (struct output_block *ob, tree expr, bool ref_p)
392*38fd1498Szrj {
393*38fd1498Szrj   /* Pack all the non-pointer fields in EXPR into a bitpack and write
394*38fd1498Szrj      the resulting bitpack.  */
395*38fd1498Szrj   streamer_write_tree_bitfields (ob, expr);
396*38fd1498Szrj 
397*38fd1498Szrj   /* Write all the pointer fields in EXPR.  */
398*38fd1498Szrj   streamer_write_tree_body (ob, expr, ref_p);
399*38fd1498Szrj 
400*38fd1498Szrj   /* Write any LTO-specific data to OB.  */
401*38fd1498Szrj   if (DECL_P (expr)
402*38fd1498Szrj       && TREE_CODE (expr) != FUNCTION_DECL
403*38fd1498Szrj       && TREE_CODE (expr) != TRANSLATION_UNIT_DECL)
404*38fd1498Szrj     {
405*38fd1498Szrj       /* Handle DECL_INITIAL for symbols.  */
406*38fd1498Szrj       tree initial = get_symbol_initial_value
407*38fd1498Szrj 			 (ob->decl_state->symtab_node_encoder, expr);
408*38fd1498Szrj       stream_write_tree (ob, initial, ref_p);
409*38fd1498Szrj     }
410*38fd1498Szrj 
411*38fd1498Szrj   /* Stream references to early generated DIEs.  Keep in sync with the
412*38fd1498Szrj      trees handled in dwarf2out_die_ref_for_decl.  */
413*38fd1498Szrj   if ((DECL_P (expr)
414*38fd1498Szrj        && TREE_CODE (expr) != FIELD_DECL
415*38fd1498Szrj        && TREE_CODE (expr) != DEBUG_EXPR_DECL
416*38fd1498Szrj        && TREE_CODE (expr) != TYPE_DECL)
417*38fd1498Szrj       || TREE_CODE (expr) == BLOCK)
418*38fd1498Szrj     {
419*38fd1498Szrj       const char *sym;
420*38fd1498Szrj       unsigned HOST_WIDE_INT off;
421*38fd1498Szrj       if (debug_info_level > DINFO_LEVEL_NONE
422*38fd1498Szrj 	  && debug_hooks->die_ref_for_decl (expr, &sym, &off))
423*38fd1498Szrj 	{
424*38fd1498Szrj 	  streamer_write_string (ob, ob->main_stream, sym, true);
425*38fd1498Szrj 	  streamer_write_uhwi (ob, off);
426*38fd1498Szrj 	}
427*38fd1498Szrj       else
428*38fd1498Szrj 	streamer_write_string (ob, ob->main_stream, NULL, true);
429*38fd1498Szrj     }
430*38fd1498Szrj }
431*38fd1498Szrj 
432*38fd1498Szrj /* Write a physical representation of tree node EXPR to output block
433*38fd1498Szrj    OB.  If REF_P is true, the leaves of EXPR are emitted as references
434*38fd1498Szrj    via lto_output_tree_ref.  IX is the index into the streamer cache
435*38fd1498Szrj    where EXPR is stored.  */
436*38fd1498Szrj 
437*38fd1498Szrj static void
lto_write_tree(struct output_block * ob,tree expr,bool ref_p)438*38fd1498Szrj lto_write_tree (struct output_block *ob, tree expr, bool ref_p)
439*38fd1498Szrj {
440*38fd1498Szrj   if (!lto_is_streamable (expr))
441*38fd1498Szrj     internal_error ("tree code %qs is not supported in LTO streams",
442*38fd1498Szrj 		    get_tree_code_name (TREE_CODE (expr)));
443*38fd1498Szrj 
444*38fd1498Szrj   /* Write the header, containing everything needed to materialize
445*38fd1498Szrj      EXPR on the reading side.  */
446*38fd1498Szrj   streamer_write_tree_header (ob, expr);
447*38fd1498Szrj 
448*38fd1498Szrj   lto_write_tree_1 (ob, expr, ref_p);
449*38fd1498Szrj 
450*38fd1498Szrj   /* Mark the end of EXPR.  */
451*38fd1498Szrj   streamer_write_zero (ob);
452*38fd1498Szrj }
453*38fd1498Szrj 
454*38fd1498Szrj /* Emit the physical representation of tree node EXPR to output block OB,
455*38fd1498Szrj    If THIS_REF_P is true, the leaves of EXPR are emitted as references via
456*38fd1498Szrj    lto_output_tree_ref.  REF_P is used for streaming siblings of EXPR.  */
457*38fd1498Szrj 
458*38fd1498Szrj static void
lto_output_tree_1(struct output_block * ob,tree expr,hashval_t hash,bool ref_p,bool this_ref_p)459*38fd1498Szrj lto_output_tree_1 (struct output_block *ob, tree expr, hashval_t hash,
460*38fd1498Szrj 		   bool ref_p, bool this_ref_p)
461*38fd1498Szrj {
462*38fd1498Szrj   unsigned ix;
463*38fd1498Szrj 
464*38fd1498Szrj   gcc_checking_assert (expr != NULL_TREE
465*38fd1498Szrj 		       && !(this_ref_p && tree_is_indexable (expr)));
466*38fd1498Szrj 
467*38fd1498Szrj   bool exists_p = streamer_tree_cache_insert (ob->writer_cache,
468*38fd1498Szrj 					      expr, hash, &ix);
469*38fd1498Szrj   gcc_assert (!exists_p);
470*38fd1498Szrj   if (TREE_CODE (expr) == INTEGER_CST
471*38fd1498Szrj       && !TREE_OVERFLOW (expr))
472*38fd1498Szrj     {
473*38fd1498Szrj       /* Shared INTEGER_CST nodes are special because they need their
474*38fd1498Szrj 	 original type to be materialized by the reader (to implement
475*38fd1498Szrj 	 TYPE_CACHED_VALUES).  */
476*38fd1498Szrj       streamer_write_integer_cst (ob, expr, ref_p);
477*38fd1498Szrj     }
478*38fd1498Szrj   else
479*38fd1498Szrj     {
480*38fd1498Szrj       /* This is the first time we see EXPR, write its fields
481*38fd1498Szrj 	 to OB.  */
482*38fd1498Szrj       lto_write_tree (ob, expr, ref_p);
483*38fd1498Szrj     }
484*38fd1498Szrj }
485*38fd1498Szrj 
486*38fd1498Szrj class DFS
487*38fd1498Szrj {
488*38fd1498Szrj public:
489*38fd1498Szrj   DFS (struct output_block *ob, tree expr, bool ref_p, bool this_ref_p,
490*38fd1498Szrj        bool single_p);
491*38fd1498Szrj   ~DFS ();
492*38fd1498Szrj 
493*38fd1498Szrj   struct scc_entry
494*38fd1498Szrj   {
495*38fd1498Szrj     tree t;
496*38fd1498Szrj     hashval_t hash;
497*38fd1498Szrj   };
498*38fd1498Szrj   vec<scc_entry> sccstack;
499*38fd1498Szrj 
500*38fd1498Szrj private:
501*38fd1498Szrj   struct sccs
502*38fd1498Szrj   {
503*38fd1498Szrj     unsigned int dfsnum;
504*38fd1498Szrj     unsigned int low;
505*38fd1498Szrj   };
506*38fd1498Szrj   struct worklist
507*38fd1498Szrj   {
508*38fd1498Szrj     tree expr;
509*38fd1498Szrj     sccs *from_state;
510*38fd1498Szrj     sccs *cstate;
511*38fd1498Szrj     bool ref_p;
512*38fd1498Szrj     bool this_ref_p;
513*38fd1498Szrj   };
514*38fd1498Szrj 
515*38fd1498Szrj   static int scc_entry_compare (const void *, const void *);
516*38fd1498Szrj 
517*38fd1498Szrj   void DFS_write_tree_body (struct output_block *ob,
518*38fd1498Szrj 			    tree expr, sccs *expr_state, bool ref_p);
519*38fd1498Szrj 
520*38fd1498Szrj   void DFS_write_tree (struct output_block *ob, sccs *from_state,
521*38fd1498Szrj 		       tree expr, bool ref_p, bool this_ref_p);
522*38fd1498Szrj 
523*38fd1498Szrj   hashval_t
524*38fd1498Szrj   hash_scc (struct output_block *ob, unsigned first, unsigned size,
525*38fd1498Szrj 	    bool ref_p, bool this_ref_p);
526*38fd1498Szrj 
527*38fd1498Szrj   hash_map<tree, sccs *> sccstate;
528*38fd1498Szrj   vec<worklist> worklist_vec;
529*38fd1498Szrj   struct obstack sccstate_obstack;
530*38fd1498Szrj };
531*38fd1498Szrj 
532*38fd1498Szrj /* Emit the physical representation of tree node EXPR to output block OB,
533*38fd1498Szrj    using depth-first search on the subgraph.  If THIS_REF_P is true, the
534*38fd1498Szrj    leaves of EXPR are emitted as references via lto_output_tree_ref.
535*38fd1498Szrj    REF_P is used for streaming siblings of EXPR.  If SINGLE_P is true,
536*38fd1498Szrj    this is for a rewalk of a single leaf SCC.  */
537*38fd1498Szrj 
DFS(struct output_block * ob,tree expr,bool ref_p,bool this_ref_p,bool single_p)538*38fd1498Szrj DFS::DFS (struct output_block *ob, tree expr, bool ref_p, bool this_ref_p,
539*38fd1498Szrj 	  bool single_p)
540*38fd1498Szrj {
541*38fd1498Szrj   unsigned int next_dfs_num = 1;
542*38fd1498Szrj   sccstack.create (0);
543*38fd1498Szrj   gcc_obstack_init (&sccstate_obstack);
544*38fd1498Szrj   worklist_vec = vNULL;
545*38fd1498Szrj   DFS_write_tree (ob, NULL, expr, ref_p, this_ref_p);
546*38fd1498Szrj   while (!worklist_vec.is_empty ())
547*38fd1498Szrj     {
548*38fd1498Szrj       worklist &w = worklist_vec.last ();
549*38fd1498Szrj       expr = w.expr;
550*38fd1498Szrj       sccs *from_state = w.from_state;
551*38fd1498Szrj       sccs *cstate = w.cstate;
552*38fd1498Szrj       ref_p = w.ref_p;
553*38fd1498Szrj       this_ref_p = w.this_ref_p;
554*38fd1498Szrj       if (cstate == NULL)
555*38fd1498Szrj 	{
556*38fd1498Szrj 	  sccs **slot = &sccstate.get_or_insert (expr);
557*38fd1498Szrj 	  cstate = *slot;
558*38fd1498Szrj 	  if (cstate)
559*38fd1498Szrj 	    {
560*38fd1498Szrj 	      gcc_checking_assert (from_state);
561*38fd1498Szrj 	      if (cstate->dfsnum < from_state->dfsnum)
562*38fd1498Szrj 		from_state->low = MIN (cstate->dfsnum, from_state->low);
563*38fd1498Szrj 	      worklist_vec.pop ();
564*38fd1498Szrj 	      continue;
565*38fd1498Szrj 	    }
566*38fd1498Szrj 
567*38fd1498Szrj 	  scc_entry e = { expr, 0 };
568*38fd1498Szrj 	  /* Not yet visited.  DFS recurse and push it onto the stack.  */
569*38fd1498Szrj 	  *slot = cstate = XOBNEW (&sccstate_obstack, struct sccs);
570*38fd1498Szrj 	  sccstack.safe_push (e);
571*38fd1498Szrj 	  cstate->dfsnum = next_dfs_num++;
572*38fd1498Szrj 	  cstate->low = cstate->dfsnum;
573*38fd1498Szrj 	  w.cstate = cstate;
574*38fd1498Szrj 
575*38fd1498Szrj 	  if (TREE_CODE (expr) == INTEGER_CST
576*38fd1498Szrj 	      && !TREE_OVERFLOW (expr))
577*38fd1498Szrj 	    DFS_write_tree (ob, cstate, TREE_TYPE (expr), ref_p, ref_p);
578*38fd1498Szrj 	  else
579*38fd1498Szrj 	    {
580*38fd1498Szrj 	      DFS_write_tree_body (ob, expr, cstate, ref_p);
581*38fd1498Szrj 
582*38fd1498Szrj 	      /* Walk any LTO-specific edges.  */
583*38fd1498Szrj 	      if (DECL_P (expr)
584*38fd1498Szrj 		  && TREE_CODE (expr) != FUNCTION_DECL
585*38fd1498Szrj 		  && TREE_CODE (expr) != TRANSLATION_UNIT_DECL)
586*38fd1498Szrj 		{
587*38fd1498Szrj 		  /* Handle DECL_INITIAL for symbols.  */
588*38fd1498Szrj 		  tree initial
589*38fd1498Szrj 		    = get_symbol_initial_value (ob->decl_state->symtab_node_encoder,
590*38fd1498Szrj 						expr);
591*38fd1498Szrj 		  DFS_write_tree (ob, cstate, initial, ref_p, ref_p);
592*38fd1498Szrj 		}
593*38fd1498Szrj 	    }
594*38fd1498Szrj 	  continue;
595*38fd1498Szrj 	}
596*38fd1498Szrj 
597*38fd1498Szrj       /* See if we found an SCC.  */
598*38fd1498Szrj       if (cstate->low == cstate->dfsnum)
599*38fd1498Szrj 	{
600*38fd1498Szrj 	  unsigned first, size;
601*38fd1498Szrj 	  tree x;
602*38fd1498Szrj 
603*38fd1498Szrj 	  /* If we are re-walking a single leaf SCC just pop it,
604*38fd1498Szrj 	     let earlier worklist item access the sccstack.  */
605*38fd1498Szrj 	  if (single_p)
606*38fd1498Szrj 	    {
607*38fd1498Szrj 	      worklist_vec.pop ();
608*38fd1498Szrj 	      continue;
609*38fd1498Szrj 	    }
610*38fd1498Szrj 
611*38fd1498Szrj 	  /* Pop the SCC and compute its size.  */
612*38fd1498Szrj 	  first = sccstack.length ();
613*38fd1498Szrj 	  do
614*38fd1498Szrj 	    {
615*38fd1498Szrj 	      x = sccstack[--first].t;
616*38fd1498Szrj 	    }
617*38fd1498Szrj 	  while (x != expr);
618*38fd1498Szrj 	  size = sccstack.length () - first;
619*38fd1498Szrj 
620*38fd1498Szrj 	  /* No need to compute hashes for LTRANS units, we don't perform
621*38fd1498Szrj 	     any merging there.  */
622*38fd1498Szrj 	  hashval_t scc_hash = 0;
623*38fd1498Szrj 	  unsigned scc_entry_len = 0;
624*38fd1498Szrj 	  if (!flag_wpa)
625*38fd1498Szrj 	    {
626*38fd1498Szrj 	      scc_hash = hash_scc (ob, first, size, ref_p, this_ref_p);
627*38fd1498Szrj 
628*38fd1498Szrj 	      /* Put the entries with the least number of collisions first.  */
629*38fd1498Szrj 	      unsigned entry_start = 0;
630*38fd1498Szrj 	      scc_entry_len = size + 1;
631*38fd1498Szrj 	      for (unsigned i = 0; i < size;)
632*38fd1498Szrj 		{
633*38fd1498Szrj 		  unsigned from = i;
634*38fd1498Szrj 		  for (i = i + 1; i < size
635*38fd1498Szrj 		       && (sccstack[first + i].hash
636*38fd1498Szrj 			   == sccstack[first + from].hash); ++i)
637*38fd1498Szrj 		    ;
638*38fd1498Szrj 		  if (i - from < scc_entry_len)
639*38fd1498Szrj 		    {
640*38fd1498Szrj 		      scc_entry_len = i - from;
641*38fd1498Szrj 		      entry_start = from;
642*38fd1498Szrj 		    }
643*38fd1498Szrj 		}
644*38fd1498Szrj 	      for (unsigned i = 0; i < scc_entry_len; ++i)
645*38fd1498Szrj 		std::swap (sccstack[first + i],
646*38fd1498Szrj 			   sccstack[first + entry_start + i]);
647*38fd1498Szrj 
648*38fd1498Szrj 	      /* We already sorted SCC deterministically in hash_scc.  */
649*38fd1498Szrj 
650*38fd1498Szrj 	      /* Check that we have only one SCC.
651*38fd1498Szrj 		 Naturally we may have conflicts if hash function is not
652*38fd1498Szrj 		 strong enough.  Lets see how far this gets.  */
653*38fd1498Szrj 	      gcc_checking_assert (scc_entry_len == 1);
654*38fd1498Szrj 	    }
655*38fd1498Szrj 
656*38fd1498Szrj 	  /* Write LTO_tree_scc.  */
657*38fd1498Szrj 	  streamer_write_record_start (ob, LTO_tree_scc);
658*38fd1498Szrj 	  streamer_write_uhwi (ob, size);
659*38fd1498Szrj 	  streamer_write_uhwi (ob, scc_hash);
660*38fd1498Szrj 
661*38fd1498Szrj 	  /* Write size-1 SCCs without wrapping them inside SCC bundles.
662*38fd1498Szrj 	     All INTEGER_CSTs need to be handled this way as we need
663*38fd1498Szrj 	     their type to materialize them.  Also builtins are handled
664*38fd1498Szrj 	     this way.
665*38fd1498Szrj 	     ???  We still wrap these in LTO_tree_scc so at the
666*38fd1498Szrj 	     input side we can properly identify the tree we want
667*38fd1498Szrj 	     to ultimatively return.  */
668*38fd1498Szrj 	  if (size == 1)
669*38fd1498Szrj 	    lto_output_tree_1 (ob, expr, scc_hash, ref_p, this_ref_p);
670*38fd1498Szrj 	  else
671*38fd1498Szrj 	    {
672*38fd1498Szrj 	      /* Write the size of the SCC entry candidates.  */
673*38fd1498Szrj 	      streamer_write_uhwi (ob, scc_entry_len);
674*38fd1498Szrj 
675*38fd1498Szrj 	      /* Write all headers and populate the streamer cache.  */
676*38fd1498Szrj 	      for (unsigned i = 0; i < size; ++i)
677*38fd1498Szrj 		{
678*38fd1498Szrj 		  hashval_t hash = sccstack[first+i].hash;
679*38fd1498Szrj 		  tree t = sccstack[first+i].t;
680*38fd1498Szrj 		  bool exists_p = streamer_tree_cache_insert (ob->writer_cache,
681*38fd1498Szrj 							      t, hash, NULL);
682*38fd1498Szrj 		  gcc_assert (!exists_p);
683*38fd1498Szrj 
684*38fd1498Szrj 		  if (!lto_is_streamable (t))
685*38fd1498Szrj 		    internal_error ("tree code %qs is not supported "
686*38fd1498Szrj 				    "in LTO streams",
687*38fd1498Szrj 				    get_tree_code_name (TREE_CODE (t)));
688*38fd1498Szrj 
689*38fd1498Szrj 		  /* Write the header, containing everything needed to
690*38fd1498Szrj 		     materialize EXPR on the reading side.  */
691*38fd1498Szrj 		  streamer_write_tree_header (ob, t);
692*38fd1498Szrj 		}
693*38fd1498Szrj 
694*38fd1498Szrj 	      /* Write the bitpacks and tree references.  */
695*38fd1498Szrj 	      for (unsigned i = 0; i < size; ++i)
696*38fd1498Szrj 		{
697*38fd1498Szrj 		  lto_write_tree_1 (ob, sccstack[first+i].t, ref_p);
698*38fd1498Szrj 
699*38fd1498Szrj 		  /* Mark the end of the tree.  */
700*38fd1498Szrj 		  streamer_write_zero (ob);
701*38fd1498Szrj 		}
702*38fd1498Szrj 	    }
703*38fd1498Szrj 
704*38fd1498Szrj 	  /* Finally truncate the vector.  */
705*38fd1498Szrj 	  sccstack.truncate (first);
706*38fd1498Szrj 
707*38fd1498Szrj 	  if (from_state)
708*38fd1498Szrj 	    from_state->low = MIN (from_state->low, cstate->low);
709*38fd1498Szrj 	  worklist_vec.pop ();
710*38fd1498Szrj 	  continue;
711*38fd1498Szrj 	}
712*38fd1498Szrj 
713*38fd1498Szrj       gcc_checking_assert (from_state);
714*38fd1498Szrj       from_state->low = MIN (from_state->low, cstate->low);
715*38fd1498Szrj       if (cstate->dfsnum < from_state->dfsnum)
716*38fd1498Szrj 	from_state->low = MIN (cstate->dfsnum, from_state->low);
717*38fd1498Szrj       worklist_vec.pop ();
718*38fd1498Szrj     }
719*38fd1498Szrj   worklist_vec.release ();
720*38fd1498Szrj }
721*38fd1498Szrj 
~DFS()722*38fd1498Szrj DFS::~DFS ()
723*38fd1498Szrj {
724*38fd1498Szrj   sccstack.release ();
725*38fd1498Szrj   obstack_free (&sccstate_obstack, NULL);
726*38fd1498Szrj }
727*38fd1498Szrj 
728*38fd1498Szrj /* Handle the tree EXPR in the DFS walk with SCC state EXPR_STATE and
729*38fd1498Szrj    DFS recurse for all tree edges originating from it.  */
730*38fd1498Szrj 
731*38fd1498Szrj void
DFS_write_tree_body(struct output_block * ob,tree expr,sccs * expr_state,bool ref_p)732*38fd1498Szrj DFS::DFS_write_tree_body (struct output_block *ob,
733*38fd1498Szrj 			  tree expr, sccs *expr_state, bool ref_p)
734*38fd1498Szrj {
735*38fd1498Szrj #define DFS_follow_tree_edge(DEST) \
736*38fd1498Szrj   DFS_write_tree (ob, expr_state, DEST, ref_p, ref_p)
737*38fd1498Szrj 
738*38fd1498Szrj   enum tree_code code;
739*38fd1498Szrj 
740*38fd1498Szrj   code = TREE_CODE (expr);
741*38fd1498Szrj 
742*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_TYPED))
743*38fd1498Szrj     {
744*38fd1498Szrj       if (TREE_CODE (expr) != IDENTIFIER_NODE)
745*38fd1498Szrj 	DFS_follow_tree_edge (TREE_TYPE (expr));
746*38fd1498Szrj     }
747*38fd1498Szrj 
748*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_VECTOR))
749*38fd1498Szrj     {
750*38fd1498Szrj       unsigned int count = vector_cst_encoded_nelts (expr);
751*38fd1498Szrj       for (unsigned int i = 0; i < count; ++i)
752*38fd1498Szrj 	DFS_follow_tree_edge (VECTOR_CST_ENCODED_ELT (expr, i));
753*38fd1498Szrj     }
754*38fd1498Szrj 
755*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_POLY_INT_CST))
756*38fd1498Szrj     for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
757*38fd1498Szrj       DFS_follow_tree_edge (POLY_INT_CST_COEFF (expr, i));
758*38fd1498Szrj 
759*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_COMPLEX))
760*38fd1498Szrj     {
761*38fd1498Szrj       DFS_follow_tree_edge (TREE_REALPART (expr));
762*38fd1498Szrj       DFS_follow_tree_edge (TREE_IMAGPART (expr));
763*38fd1498Szrj     }
764*38fd1498Szrj 
765*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_DECL_MINIMAL))
766*38fd1498Szrj     {
767*38fd1498Szrj       /* Drop names that were created for anonymous entities.  */
768*38fd1498Szrj       if (DECL_NAME (expr)
769*38fd1498Szrj 	  && TREE_CODE (DECL_NAME (expr)) == IDENTIFIER_NODE
770*38fd1498Szrj 	  && anon_aggrname_p (DECL_NAME (expr)))
771*38fd1498Szrj 	;
772*38fd1498Szrj       else
773*38fd1498Szrj 	DFS_follow_tree_edge (DECL_NAME (expr));
774*38fd1498Szrj       if (TREE_CODE (expr) != TRANSLATION_UNIT_DECL
775*38fd1498Szrj 	  && ! DECL_CONTEXT (expr))
776*38fd1498Szrj 	DFS_follow_tree_edge ((*all_translation_units)[0]);
777*38fd1498Szrj       else
778*38fd1498Szrj 	DFS_follow_tree_edge (DECL_CONTEXT (expr));
779*38fd1498Szrj     }
780*38fd1498Szrj 
781*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
782*38fd1498Szrj     {
783*38fd1498Szrj       DFS_follow_tree_edge (DECL_SIZE (expr));
784*38fd1498Szrj       DFS_follow_tree_edge (DECL_SIZE_UNIT (expr));
785*38fd1498Szrj 
786*38fd1498Szrj       /* Note, DECL_INITIAL is not handled here.  Since DECL_INITIAL needs
787*38fd1498Szrj 	 special handling in LTO, it must be handled by streamer hooks.  */
788*38fd1498Szrj 
789*38fd1498Szrj       DFS_follow_tree_edge (DECL_ATTRIBUTES (expr));
790*38fd1498Szrj 
791*38fd1498Szrj       /* Do not follow DECL_ABSTRACT_ORIGIN.  We cannot handle debug information
792*38fd1498Szrj 	 for early inlining so drop it on the floor instead of ICEing in
793*38fd1498Szrj 	 dwarf2out.c.
794*38fd1498Szrj 	 We however use DECL_ABSTRACT_ORIGIN == error_mark_node to mark
795*38fd1498Szrj 	 declarations which should be eliminated by decl merging. Be sure none
796*38fd1498Szrj 	 leaks to this point.  */
797*38fd1498Szrj       gcc_assert (DECL_ABSTRACT_ORIGIN (expr) != error_mark_node);
798*38fd1498Szrj       DFS_follow_tree_edge (DECL_ABSTRACT_ORIGIN (expr));
799*38fd1498Szrj 
800*38fd1498Szrj       if ((VAR_P (expr)
801*38fd1498Szrj 	   || TREE_CODE (expr) == PARM_DECL)
802*38fd1498Szrj 	  && DECL_HAS_VALUE_EXPR_P (expr))
803*38fd1498Szrj 	DFS_follow_tree_edge (DECL_VALUE_EXPR (expr));
804*38fd1498Szrj       if (VAR_P (expr)
805*38fd1498Szrj 	  && DECL_HAS_DEBUG_EXPR_P (expr))
806*38fd1498Szrj 	DFS_follow_tree_edge (DECL_DEBUG_EXPR (expr));
807*38fd1498Szrj     }
808*38fd1498Szrj 
809*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_DECL_NON_COMMON))
810*38fd1498Szrj     {
811*38fd1498Szrj       if (TREE_CODE (expr) == TYPE_DECL)
812*38fd1498Szrj 	DFS_follow_tree_edge (DECL_ORIGINAL_TYPE (expr));
813*38fd1498Szrj     }
814*38fd1498Szrj 
815*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
816*38fd1498Szrj     {
817*38fd1498Szrj       /* Make sure we don't inadvertently set the assembler name.  */
818*38fd1498Szrj       if (DECL_ASSEMBLER_NAME_SET_P (expr))
819*38fd1498Szrj 	DFS_follow_tree_edge (DECL_ASSEMBLER_NAME (expr));
820*38fd1498Szrj     }
821*38fd1498Szrj 
822*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_FIELD_DECL))
823*38fd1498Szrj     {
824*38fd1498Szrj       DFS_follow_tree_edge (DECL_FIELD_OFFSET (expr));
825*38fd1498Szrj       DFS_follow_tree_edge (DECL_BIT_FIELD_TYPE (expr));
826*38fd1498Szrj       DFS_follow_tree_edge (DECL_BIT_FIELD_REPRESENTATIVE (expr));
827*38fd1498Szrj       DFS_follow_tree_edge (DECL_FIELD_BIT_OFFSET (expr));
828*38fd1498Szrj       DFS_follow_tree_edge (DECL_FCONTEXT (expr));
829*38fd1498Szrj     }
830*38fd1498Szrj 
831*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_FUNCTION_DECL))
832*38fd1498Szrj     {
833*38fd1498Szrj       DFS_follow_tree_edge (DECL_VINDEX (expr));
834*38fd1498Szrj       DFS_follow_tree_edge (DECL_FUNCTION_PERSONALITY (expr));
835*38fd1498Szrj       DFS_follow_tree_edge (DECL_FUNCTION_SPECIFIC_TARGET (expr));
836*38fd1498Szrj       DFS_follow_tree_edge (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (expr));
837*38fd1498Szrj     }
838*38fd1498Szrj 
839*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_TYPE_COMMON))
840*38fd1498Szrj     {
841*38fd1498Szrj       DFS_follow_tree_edge (TYPE_SIZE (expr));
842*38fd1498Szrj       DFS_follow_tree_edge (TYPE_SIZE_UNIT (expr));
843*38fd1498Szrj       DFS_follow_tree_edge (TYPE_ATTRIBUTES (expr));
844*38fd1498Szrj       DFS_follow_tree_edge (TYPE_NAME (expr));
845*38fd1498Szrj       /* Do not follow TYPE_POINTER_TO or TYPE_REFERENCE_TO.  They will be
846*38fd1498Szrj 	 reconstructed during fixup.  */
847*38fd1498Szrj       /* Do not follow TYPE_NEXT_VARIANT, we reconstruct the variant lists
848*38fd1498Szrj 	 during fixup.  */
849*38fd1498Szrj       DFS_follow_tree_edge (TYPE_MAIN_VARIANT (expr));
850*38fd1498Szrj       DFS_follow_tree_edge (TYPE_CONTEXT (expr));
851*38fd1498Szrj       /* TYPE_CANONICAL is re-computed during type merging, so no need
852*38fd1498Szrj 	 to follow it here.  */
853*38fd1498Szrj       DFS_follow_tree_edge (TYPE_STUB_DECL (expr));
854*38fd1498Szrj     }
855*38fd1498Szrj 
856*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_TYPE_NON_COMMON))
857*38fd1498Szrj     {
858*38fd1498Szrj       if (TREE_CODE (expr) == ENUMERAL_TYPE)
859*38fd1498Szrj 	DFS_follow_tree_edge (TYPE_VALUES (expr));
860*38fd1498Szrj       else if (TREE_CODE (expr) == ARRAY_TYPE)
861*38fd1498Szrj 	DFS_follow_tree_edge (TYPE_DOMAIN (expr));
862*38fd1498Szrj       else if (RECORD_OR_UNION_TYPE_P (expr))
863*38fd1498Szrj 	for (tree t = TYPE_FIELDS (expr); t; t = TREE_CHAIN (t))
864*38fd1498Szrj 	  DFS_follow_tree_edge (t);
865*38fd1498Szrj       else if (TREE_CODE (expr) == FUNCTION_TYPE
866*38fd1498Szrj 	       || TREE_CODE (expr) == METHOD_TYPE)
867*38fd1498Szrj 	DFS_follow_tree_edge (TYPE_ARG_TYPES (expr));
868*38fd1498Szrj 
869*38fd1498Szrj       if (!POINTER_TYPE_P (expr))
870*38fd1498Szrj 	DFS_follow_tree_edge (TYPE_MIN_VALUE_RAW (expr));
871*38fd1498Szrj       DFS_follow_tree_edge (TYPE_MAX_VALUE_RAW (expr));
872*38fd1498Szrj     }
873*38fd1498Szrj 
874*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_LIST))
875*38fd1498Szrj     {
876*38fd1498Szrj       DFS_follow_tree_edge (TREE_PURPOSE (expr));
877*38fd1498Szrj       DFS_follow_tree_edge (TREE_VALUE (expr));
878*38fd1498Szrj       DFS_follow_tree_edge (TREE_CHAIN (expr));
879*38fd1498Szrj     }
880*38fd1498Szrj 
881*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_VEC))
882*38fd1498Szrj     {
883*38fd1498Szrj       for (int i = 0; i < TREE_VEC_LENGTH (expr); i++)
884*38fd1498Szrj 	DFS_follow_tree_edge (TREE_VEC_ELT (expr, i));
885*38fd1498Szrj     }
886*38fd1498Szrj 
887*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_EXP))
888*38fd1498Szrj     {
889*38fd1498Szrj       for (int i = 0; i < TREE_OPERAND_LENGTH (expr); i++)
890*38fd1498Szrj 	DFS_follow_tree_edge (TREE_OPERAND (expr, i));
891*38fd1498Szrj       DFS_follow_tree_edge (TREE_BLOCK (expr));
892*38fd1498Szrj     }
893*38fd1498Szrj 
894*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_BLOCK))
895*38fd1498Szrj     {
896*38fd1498Szrj       for (tree t = BLOCK_VARS (expr); t; t = TREE_CHAIN (t))
897*38fd1498Szrj 	if (VAR_OR_FUNCTION_DECL_P (t)
898*38fd1498Szrj 	    && DECL_EXTERNAL (t))
899*38fd1498Szrj 	  /* We have to stream externals in the block chain as
900*38fd1498Szrj 	     non-references.  See also
901*38fd1498Szrj 	     tree-streamer-out.c:streamer_write_chain.  */
902*38fd1498Szrj 	  DFS_write_tree (ob, expr_state, t, ref_p, false);
903*38fd1498Szrj 	else
904*38fd1498Szrj 	  DFS_follow_tree_edge (t);
905*38fd1498Szrj 
906*38fd1498Szrj       DFS_follow_tree_edge (BLOCK_SUPERCONTEXT (expr));
907*38fd1498Szrj 
908*38fd1498Szrj       /* Follow BLOCK_ABSTRACT_ORIGIN for the limited cases we can
909*38fd1498Szrj 	 handle - those that represent inlined function scopes.
910*38fd1498Szrj 	 For the drop rest them on the floor instead of ICEing
911*38fd1498Szrj 	 in dwarf2out.c, but keep the notion of whether the block
912*38fd1498Szrj 	 is an inlined block by refering to itself for the sake of
913*38fd1498Szrj 	 tree_nonartificial_location.  */
914*38fd1498Szrj       if (inlined_function_outer_scope_p (expr))
915*38fd1498Szrj 	{
916*38fd1498Szrj 	  tree ultimate_origin = block_ultimate_origin (expr);
917*38fd1498Szrj 	  DFS_follow_tree_edge (ultimate_origin);
918*38fd1498Szrj 	}
919*38fd1498Szrj       else if (BLOCK_ABSTRACT_ORIGIN (expr))
920*38fd1498Szrj 	DFS_follow_tree_edge (expr);
921*38fd1498Szrj       /* Do not follow BLOCK_NONLOCALIZED_VARS.  We cannot handle debug
922*38fd1498Szrj 	 information for early inlined BLOCKs so drop it on the floor instead
923*38fd1498Szrj 	 of ICEing in dwarf2out.c.  */
924*38fd1498Szrj 
925*38fd1498Szrj       /* BLOCK_FRAGMENT_ORIGIN and BLOCK_FRAGMENT_CHAIN is not live at LTO
926*38fd1498Szrj 	 streaming time.  */
927*38fd1498Szrj 
928*38fd1498Szrj       /* Do not output BLOCK_SUBBLOCKS.  Instead on streaming-in this
929*38fd1498Szrj 	 list is re-constructed from BLOCK_SUPERCONTEXT.  */
930*38fd1498Szrj     }
931*38fd1498Szrj 
932*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_BINFO))
933*38fd1498Szrj     {
934*38fd1498Szrj       unsigned i;
935*38fd1498Szrj       tree t;
936*38fd1498Szrj 
937*38fd1498Szrj       /* Note that the number of BINFO slots has already been emitted in
938*38fd1498Szrj 	 EXPR's header (see streamer_write_tree_header) because this length
939*38fd1498Szrj 	 is needed to build the empty BINFO node on the reader side.  */
940*38fd1498Szrj       FOR_EACH_VEC_ELT (*BINFO_BASE_BINFOS (expr), i, t)
941*38fd1498Szrj 	DFS_follow_tree_edge (t);
942*38fd1498Szrj       DFS_follow_tree_edge (BINFO_OFFSET (expr));
943*38fd1498Szrj       DFS_follow_tree_edge (BINFO_VTABLE (expr));
944*38fd1498Szrj       DFS_follow_tree_edge (BINFO_VPTR_FIELD (expr));
945*38fd1498Szrj 
946*38fd1498Szrj       /* The number of BINFO_BASE_ACCESSES has already been emitted in
947*38fd1498Szrj 	 EXPR's bitfield section.  */
948*38fd1498Szrj       FOR_EACH_VEC_SAFE_ELT (BINFO_BASE_ACCESSES (expr), i, t)
949*38fd1498Szrj 	DFS_follow_tree_edge (t);
950*38fd1498Szrj 
951*38fd1498Szrj       /* Do not walk BINFO_INHERITANCE_CHAIN, BINFO_SUBVTT_INDEX
952*38fd1498Szrj 	 and BINFO_VPTR_INDEX; these are used by C++ FE only.  */
953*38fd1498Szrj     }
954*38fd1498Szrj 
955*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
956*38fd1498Szrj     {
957*38fd1498Szrj       unsigned i;
958*38fd1498Szrj       tree index, value;
959*38fd1498Szrj 
960*38fd1498Szrj       FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (expr), i, index, value)
961*38fd1498Szrj 	{
962*38fd1498Szrj 	  DFS_follow_tree_edge (index);
963*38fd1498Szrj 	  DFS_follow_tree_edge (value);
964*38fd1498Szrj 	}
965*38fd1498Szrj     }
966*38fd1498Szrj 
967*38fd1498Szrj   if (code == OMP_CLAUSE)
968*38fd1498Szrj     {
969*38fd1498Szrj       int i;
970*38fd1498Szrj       for (i = 0; i < omp_clause_num_ops[OMP_CLAUSE_CODE (expr)]; i++)
971*38fd1498Szrj 	DFS_follow_tree_edge (OMP_CLAUSE_OPERAND (expr, i));
972*38fd1498Szrj       DFS_follow_tree_edge (OMP_CLAUSE_CHAIN (expr));
973*38fd1498Szrj     }
974*38fd1498Szrj 
975*38fd1498Szrj #undef DFS_follow_tree_edge
976*38fd1498Szrj }
977*38fd1498Szrj 
978*38fd1498Szrj /* Return a hash value for the tree T.
979*38fd1498Szrj    CACHE holds hash values of trees outside current SCC.  MAP, if non-NULL,
980*38fd1498Szrj    may hold hash values if trees inside current SCC.  */
981*38fd1498Szrj 
982*38fd1498Szrj static hashval_t
hash_tree(struct streamer_tree_cache_d * cache,hash_map<tree,hashval_t> * map,tree t)983*38fd1498Szrj hash_tree (struct streamer_tree_cache_d *cache, hash_map<tree, hashval_t> *map, tree t)
984*38fd1498Szrj {
985*38fd1498Szrj   inchash::hash hstate;
986*38fd1498Szrj 
987*38fd1498Szrj #define visit(SIBLING) \
988*38fd1498Szrj   do { \
989*38fd1498Szrj     unsigned ix; \
990*38fd1498Szrj     if (!SIBLING) \
991*38fd1498Szrj       hstate.add_int (0); \
992*38fd1498Szrj     else if (streamer_tree_cache_lookup (cache, SIBLING, &ix)) \
993*38fd1498Szrj       hstate.add_int (streamer_tree_cache_get_hash (cache, ix)); \
994*38fd1498Szrj     else if (map) \
995*38fd1498Szrj       hstate.add_int (*map->get (SIBLING)); \
996*38fd1498Szrj     else \
997*38fd1498Szrj       hstate.add_int (1); \
998*38fd1498Szrj   } while (0)
999*38fd1498Szrj 
1000*38fd1498Szrj   /* Hash TS_BASE.  */
1001*38fd1498Szrj   enum tree_code code = TREE_CODE (t);
1002*38fd1498Szrj   hstate.add_int (code);
1003*38fd1498Szrj   if (!TYPE_P (t))
1004*38fd1498Szrj     {
1005*38fd1498Szrj       hstate.add_flag (TREE_SIDE_EFFECTS (t));
1006*38fd1498Szrj       hstate.add_flag (TREE_CONSTANT (t));
1007*38fd1498Szrj       hstate.add_flag (TREE_READONLY (t));
1008*38fd1498Szrj       hstate.add_flag (TREE_PUBLIC (t));
1009*38fd1498Szrj     }
1010*38fd1498Szrj   hstate.add_flag (TREE_ADDRESSABLE (t));
1011*38fd1498Szrj   hstate.add_flag (TREE_THIS_VOLATILE (t));
1012*38fd1498Szrj   if (DECL_P (t))
1013*38fd1498Szrj     hstate.add_flag (DECL_UNSIGNED (t));
1014*38fd1498Szrj   else if (TYPE_P (t))
1015*38fd1498Szrj     hstate.add_flag (TYPE_UNSIGNED (t));
1016*38fd1498Szrj   if (TYPE_P (t))
1017*38fd1498Szrj     hstate.add_flag (TYPE_ARTIFICIAL (t));
1018*38fd1498Szrj   else
1019*38fd1498Szrj     hstate.add_flag (TREE_NO_WARNING (t));
1020*38fd1498Szrj   hstate.add_flag (TREE_NOTHROW (t));
1021*38fd1498Szrj   hstate.add_flag (TREE_STATIC (t));
1022*38fd1498Szrj   hstate.add_flag (TREE_PROTECTED (t));
1023*38fd1498Szrj   hstate.add_flag (TREE_DEPRECATED (t));
1024*38fd1498Szrj   if (code != TREE_BINFO)
1025*38fd1498Szrj     hstate.add_flag (TREE_PRIVATE (t));
1026*38fd1498Szrj   if (TYPE_P (t))
1027*38fd1498Szrj     {
1028*38fd1498Szrj       hstate.add_flag (AGGREGATE_TYPE_P (t)
1029*38fd1498Szrj 		       ? TYPE_REVERSE_STORAGE_ORDER (t) : TYPE_SATURATING (t));
1030*38fd1498Szrj       hstate.add_flag (TYPE_ADDR_SPACE (t));
1031*38fd1498Szrj     }
1032*38fd1498Szrj   else if (code == SSA_NAME)
1033*38fd1498Szrj     hstate.add_flag (SSA_NAME_IS_DEFAULT_DEF (t));
1034*38fd1498Szrj   hstate.commit_flag ();
1035*38fd1498Szrj 
1036*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_INT_CST))
1037*38fd1498Szrj     hstate.add_wide_int (wi::to_widest (t));
1038*38fd1498Szrj 
1039*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_REAL_CST))
1040*38fd1498Szrj     {
1041*38fd1498Szrj       REAL_VALUE_TYPE r = TREE_REAL_CST (t);
1042*38fd1498Szrj       hstate.add_flag (r.cl);
1043*38fd1498Szrj       hstate.add_flag (r.sign);
1044*38fd1498Szrj       hstate.add_flag (r.signalling);
1045*38fd1498Szrj       hstate.add_flag (r.canonical);
1046*38fd1498Szrj       hstate.commit_flag ();
1047*38fd1498Szrj       hstate.add_int (r.uexp);
1048*38fd1498Szrj       hstate.add (r.sig, sizeof (r.sig));
1049*38fd1498Szrj     }
1050*38fd1498Szrj 
1051*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_FIXED_CST))
1052*38fd1498Szrj     {
1053*38fd1498Szrj       FIXED_VALUE_TYPE f = TREE_FIXED_CST (t);
1054*38fd1498Szrj       hstate.add_int (f.mode);
1055*38fd1498Szrj       hstate.add_int (f.data.low);
1056*38fd1498Szrj       hstate.add_int (f.data.high);
1057*38fd1498Szrj     }
1058*38fd1498Szrj 
1059*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
1060*38fd1498Szrj     {
1061*38fd1498Szrj       hstate.add_hwi (DECL_MODE (t));
1062*38fd1498Szrj       hstate.add_flag (DECL_NONLOCAL (t));
1063*38fd1498Szrj       hstate.add_flag (DECL_VIRTUAL_P (t));
1064*38fd1498Szrj       hstate.add_flag (DECL_IGNORED_P (t));
1065*38fd1498Szrj       hstate.add_flag (DECL_ABSTRACT_P (t));
1066*38fd1498Szrj       hstate.add_flag (DECL_ARTIFICIAL (t));
1067*38fd1498Szrj       hstate.add_flag (DECL_USER_ALIGN (t));
1068*38fd1498Szrj       hstate.add_flag (DECL_PRESERVE_P (t));
1069*38fd1498Szrj       hstate.add_flag (DECL_EXTERNAL (t));
1070*38fd1498Szrj       hstate.add_flag (DECL_GIMPLE_REG_P (t));
1071*38fd1498Szrj       hstate.commit_flag ();
1072*38fd1498Szrj       hstate.add_int (DECL_ALIGN (t));
1073*38fd1498Szrj       if (code == LABEL_DECL)
1074*38fd1498Szrj 	{
1075*38fd1498Szrj           hstate.add_int (EH_LANDING_PAD_NR (t));
1076*38fd1498Szrj 	  hstate.add_int (LABEL_DECL_UID (t));
1077*38fd1498Szrj 	}
1078*38fd1498Szrj       else if (code == FIELD_DECL)
1079*38fd1498Szrj 	{
1080*38fd1498Szrj 	  hstate.add_flag (DECL_PACKED (t));
1081*38fd1498Szrj 	  hstate.add_flag (DECL_NONADDRESSABLE_P (t));
1082*38fd1498Szrj 	  hstate.add_flag (DECL_PADDING_P (t));
1083*38fd1498Szrj 	  hstate.add_int (DECL_OFFSET_ALIGN (t));
1084*38fd1498Szrj 	}
1085*38fd1498Szrj       else if (code == VAR_DECL)
1086*38fd1498Szrj 	{
1087*38fd1498Szrj 	  hstate.add_flag (DECL_HAS_DEBUG_EXPR_P (t));
1088*38fd1498Szrj 	  hstate.add_flag (DECL_NONLOCAL_FRAME (t));
1089*38fd1498Szrj 	}
1090*38fd1498Szrj       if (code == RESULT_DECL
1091*38fd1498Szrj 	  || code == PARM_DECL
1092*38fd1498Szrj 	  || code == VAR_DECL)
1093*38fd1498Szrj 	{
1094*38fd1498Szrj 	  hstate.add_flag (DECL_BY_REFERENCE (t));
1095*38fd1498Szrj 	  if (code == VAR_DECL
1096*38fd1498Szrj 	      || code == PARM_DECL)
1097*38fd1498Szrj 	    hstate.add_flag (DECL_HAS_VALUE_EXPR_P (t));
1098*38fd1498Szrj 	}
1099*38fd1498Szrj       hstate.commit_flag ();
1100*38fd1498Szrj     }
1101*38fd1498Szrj 
1102*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_DECL_WRTL))
1103*38fd1498Szrj     hstate.add_int (DECL_REGISTER (t));
1104*38fd1498Szrj 
1105*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
1106*38fd1498Szrj     {
1107*38fd1498Szrj       hstate.add_flag (DECL_COMMON (t));
1108*38fd1498Szrj       hstate.add_flag (DECL_DLLIMPORT_P (t));
1109*38fd1498Szrj       hstate.add_flag (DECL_WEAK (t));
1110*38fd1498Szrj       hstate.add_flag (DECL_SEEN_IN_BIND_EXPR_P (t));
1111*38fd1498Szrj       hstate.add_flag (DECL_COMDAT (t));
1112*38fd1498Szrj       hstate.add_flag (DECL_VISIBILITY_SPECIFIED (t));
1113*38fd1498Szrj       hstate.add_int (DECL_VISIBILITY (t));
1114*38fd1498Szrj       if (code == VAR_DECL)
1115*38fd1498Szrj 	{
1116*38fd1498Szrj 	  /* DECL_IN_TEXT_SECTION is set during final asm output only.  */
1117*38fd1498Szrj 	  hstate.add_flag (DECL_HARD_REGISTER (t));
1118*38fd1498Szrj 	  hstate.add_flag (DECL_IN_CONSTANT_POOL (t));
1119*38fd1498Szrj 	}
1120*38fd1498Szrj       if (TREE_CODE (t) == FUNCTION_DECL)
1121*38fd1498Szrj         {
1122*38fd1498Szrj 	  hstate.add_flag (DECL_FINAL_P (t));
1123*38fd1498Szrj 	  hstate.add_flag (DECL_CXX_CONSTRUCTOR_P (t));
1124*38fd1498Szrj 	  hstate.add_flag (DECL_CXX_DESTRUCTOR_P (t));
1125*38fd1498Szrj 	}
1126*38fd1498Szrj       hstate.commit_flag ();
1127*38fd1498Szrj     }
1128*38fd1498Szrj 
1129*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_FUNCTION_DECL))
1130*38fd1498Szrj     {
1131*38fd1498Szrj       hstate.add_int (DECL_BUILT_IN_CLASS (t));
1132*38fd1498Szrj       hstate.add_flag (DECL_STATIC_CONSTRUCTOR (t));
1133*38fd1498Szrj       hstate.add_flag (DECL_STATIC_DESTRUCTOR (t));
1134*38fd1498Szrj       hstate.add_flag (DECL_UNINLINABLE (t));
1135*38fd1498Szrj       hstate.add_flag (DECL_POSSIBLY_INLINED (t));
1136*38fd1498Szrj       hstate.add_flag (DECL_IS_NOVOPS (t));
1137*38fd1498Szrj       hstate.add_flag (DECL_IS_RETURNS_TWICE (t));
1138*38fd1498Szrj       hstate.add_flag (DECL_IS_MALLOC (t));
1139*38fd1498Szrj       hstate.add_flag (DECL_IS_OPERATOR_NEW (t));
1140*38fd1498Szrj       hstate.add_flag (DECL_DECLARED_INLINE_P (t));
1141*38fd1498Szrj       hstate.add_flag (DECL_STATIC_CHAIN (t));
1142*38fd1498Szrj       hstate.add_flag (DECL_NO_INLINE_WARNING_P (t));
1143*38fd1498Szrj       hstate.add_flag (DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (t));
1144*38fd1498Szrj       hstate.add_flag (DECL_NO_LIMIT_STACK (t));
1145*38fd1498Szrj       hstate.add_flag (DECL_DISREGARD_INLINE_LIMITS (t));
1146*38fd1498Szrj       hstate.add_flag (DECL_PURE_P (t));
1147*38fd1498Szrj       hstate.add_flag (DECL_LOOPING_CONST_OR_PURE_P (t));
1148*38fd1498Szrj       hstate.commit_flag ();
1149*38fd1498Szrj       if (DECL_BUILT_IN_CLASS (t) != NOT_BUILT_IN)
1150*38fd1498Szrj 	hstate.add_int (DECL_FUNCTION_CODE (t));
1151*38fd1498Szrj     }
1152*38fd1498Szrj 
1153*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_TYPE_COMMON))
1154*38fd1498Szrj     {
1155*38fd1498Szrj       hstate.add_hwi (TYPE_MODE (t));
1156*38fd1498Szrj       hstate.add_flag (TYPE_STRING_FLAG (t));
1157*38fd1498Szrj       /* TYPE_NO_FORCE_BLK is private to stor-layout and need
1158*38fd1498Szrj  	 no streaming.  */
1159*38fd1498Szrj       hstate.add_flag (TYPE_NEEDS_CONSTRUCTING (t));
1160*38fd1498Szrj       hstate.add_flag (TYPE_PACKED (t));
1161*38fd1498Szrj       hstate.add_flag (TYPE_RESTRICT (t));
1162*38fd1498Szrj       hstate.add_flag (TYPE_USER_ALIGN (t));
1163*38fd1498Szrj       hstate.add_flag (TYPE_READONLY (t));
1164*38fd1498Szrj       if (RECORD_OR_UNION_TYPE_P (t))
1165*38fd1498Szrj 	{
1166*38fd1498Szrj 	  hstate.add_flag (TYPE_TRANSPARENT_AGGR (t));
1167*38fd1498Szrj 	  hstate.add_flag (TYPE_FINAL_P (t));
1168*38fd1498Szrj 	}
1169*38fd1498Szrj       else if (code == ARRAY_TYPE)
1170*38fd1498Szrj 	hstate.add_flag (TYPE_NONALIASED_COMPONENT (t));
1171*38fd1498Szrj       if (AGGREGATE_TYPE_P (t))
1172*38fd1498Szrj 	hstate.add_flag (TYPE_TYPELESS_STORAGE (t));
1173*38fd1498Szrj       hstate.commit_flag ();
1174*38fd1498Szrj       hstate.add_int (TYPE_PRECISION (t));
1175*38fd1498Szrj       hstate.add_int (TYPE_ALIGN (t));
1176*38fd1498Szrj       hstate.add_int (TYPE_EMPTY_P (t));
1177*38fd1498Szrj     }
1178*38fd1498Szrj 
1179*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
1180*38fd1498Szrj     hstate.add (TRANSLATION_UNIT_LANGUAGE (t),
1181*38fd1498Szrj 			strlen (TRANSLATION_UNIT_LANGUAGE (t)));
1182*38fd1498Szrj 
1183*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION)
1184*38fd1498Szrj       /* We don't stream these when passing things to a different target.  */
1185*38fd1498Szrj       && !lto_stream_offload_p)
1186*38fd1498Szrj     hstate.add_hwi (cl_target_option_hash (TREE_TARGET_OPTION (t)));
1187*38fd1498Szrj 
1188*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
1189*38fd1498Szrj     hstate.add_hwi (cl_optimization_hash (TREE_OPTIMIZATION (t)));
1190*38fd1498Szrj 
1191*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_IDENTIFIER))
1192*38fd1498Szrj     hstate.merge_hash (IDENTIFIER_HASH_VALUE (t));
1193*38fd1498Szrj 
1194*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_STRING))
1195*38fd1498Szrj     hstate.add (TREE_STRING_POINTER (t), TREE_STRING_LENGTH (t));
1196*38fd1498Szrj 
1197*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_TYPED))
1198*38fd1498Szrj     {
1199*38fd1498Szrj       if (code != IDENTIFIER_NODE)
1200*38fd1498Szrj 	visit (TREE_TYPE (t));
1201*38fd1498Szrj     }
1202*38fd1498Szrj 
1203*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_VECTOR))
1204*38fd1498Szrj     {
1205*38fd1498Szrj       unsigned int count = vector_cst_encoded_nelts (t);
1206*38fd1498Szrj       for (unsigned int i = 0; i < count; ++i)
1207*38fd1498Szrj 	visit (VECTOR_CST_ENCODED_ELT (t, i));
1208*38fd1498Szrj     }
1209*38fd1498Szrj 
1210*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_POLY_INT_CST))
1211*38fd1498Szrj     for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
1212*38fd1498Szrj       visit (POLY_INT_CST_COEFF (t, i));
1213*38fd1498Szrj 
1214*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_COMPLEX))
1215*38fd1498Szrj     {
1216*38fd1498Szrj       visit (TREE_REALPART (t));
1217*38fd1498Szrj       visit (TREE_IMAGPART (t));
1218*38fd1498Szrj     }
1219*38fd1498Szrj 
1220*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_DECL_MINIMAL))
1221*38fd1498Szrj     {
1222*38fd1498Szrj       /* Drop names that were created for anonymous entities.  */
1223*38fd1498Szrj       if (DECL_NAME (t)
1224*38fd1498Szrj 	  && TREE_CODE (DECL_NAME (t)) == IDENTIFIER_NODE
1225*38fd1498Szrj 	  && anon_aggrname_p (DECL_NAME (t)))
1226*38fd1498Szrj 	;
1227*38fd1498Szrj       else
1228*38fd1498Szrj 	visit (DECL_NAME (t));
1229*38fd1498Szrj       if (DECL_FILE_SCOPE_P (t))
1230*38fd1498Szrj 	;
1231*38fd1498Szrj       else
1232*38fd1498Szrj 	visit (DECL_CONTEXT (t));
1233*38fd1498Szrj     }
1234*38fd1498Szrj 
1235*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
1236*38fd1498Szrj     {
1237*38fd1498Szrj       visit (DECL_SIZE (t));
1238*38fd1498Szrj       visit (DECL_SIZE_UNIT (t));
1239*38fd1498Szrj       visit (DECL_ATTRIBUTES (t));
1240*38fd1498Szrj       if ((code == VAR_DECL
1241*38fd1498Szrj 	   || code == PARM_DECL)
1242*38fd1498Szrj 	  && DECL_HAS_VALUE_EXPR_P (t))
1243*38fd1498Szrj 	visit (DECL_VALUE_EXPR (t));
1244*38fd1498Szrj       if (code == VAR_DECL
1245*38fd1498Szrj 	  && DECL_HAS_DEBUG_EXPR_P (t))
1246*38fd1498Szrj 	visit (DECL_DEBUG_EXPR (t));
1247*38fd1498Szrj       /* ???  Hash DECL_INITIAL as streamed.  Needs the output-block to
1248*38fd1498Szrj          be able to call get_symbol_initial_value.  */
1249*38fd1498Szrj     }
1250*38fd1498Szrj 
1251*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_DECL_NON_COMMON))
1252*38fd1498Szrj     {
1253*38fd1498Szrj       if (code == TYPE_DECL)
1254*38fd1498Szrj 	visit (DECL_ORIGINAL_TYPE (t));
1255*38fd1498Szrj     }
1256*38fd1498Szrj 
1257*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
1258*38fd1498Szrj     {
1259*38fd1498Szrj       if (DECL_ASSEMBLER_NAME_SET_P (t))
1260*38fd1498Szrj 	visit (DECL_ASSEMBLER_NAME (t));
1261*38fd1498Szrj     }
1262*38fd1498Szrj 
1263*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_FIELD_DECL))
1264*38fd1498Szrj     {
1265*38fd1498Szrj       visit (DECL_FIELD_OFFSET (t));
1266*38fd1498Szrj       visit (DECL_BIT_FIELD_TYPE (t));
1267*38fd1498Szrj       visit (DECL_BIT_FIELD_REPRESENTATIVE (t));
1268*38fd1498Szrj       visit (DECL_FIELD_BIT_OFFSET (t));
1269*38fd1498Szrj       visit (DECL_FCONTEXT (t));
1270*38fd1498Szrj     }
1271*38fd1498Szrj 
1272*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_FUNCTION_DECL))
1273*38fd1498Szrj     {
1274*38fd1498Szrj       visit (DECL_VINDEX (t));
1275*38fd1498Szrj       visit (DECL_FUNCTION_PERSONALITY (t));
1276*38fd1498Szrj       visit (DECL_FUNCTION_SPECIFIC_TARGET (t));
1277*38fd1498Szrj       visit (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (t));
1278*38fd1498Szrj     }
1279*38fd1498Szrj 
1280*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_TYPE_COMMON))
1281*38fd1498Szrj     {
1282*38fd1498Szrj       visit (TYPE_SIZE (t));
1283*38fd1498Szrj       visit (TYPE_SIZE_UNIT (t));
1284*38fd1498Szrj       visit (TYPE_ATTRIBUTES (t));
1285*38fd1498Szrj       visit (TYPE_NAME (t));
1286*38fd1498Szrj       visit (TYPE_MAIN_VARIANT (t));
1287*38fd1498Szrj       if (TYPE_FILE_SCOPE_P (t))
1288*38fd1498Szrj 	;
1289*38fd1498Szrj       else
1290*38fd1498Szrj 	visit (TYPE_CONTEXT (t));
1291*38fd1498Szrj       visit (TYPE_STUB_DECL (t));
1292*38fd1498Szrj     }
1293*38fd1498Szrj 
1294*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_TYPE_NON_COMMON))
1295*38fd1498Szrj     {
1296*38fd1498Szrj       if (code == ENUMERAL_TYPE)
1297*38fd1498Szrj 	visit (TYPE_VALUES (t));
1298*38fd1498Szrj       else if (code == ARRAY_TYPE)
1299*38fd1498Szrj 	visit (TYPE_DOMAIN (t));
1300*38fd1498Szrj       else if (RECORD_OR_UNION_TYPE_P (t))
1301*38fd1498Szrj 	for (tree f = TYPE_FIELDS (t); f; f = TREE_CHAIN (f))
1302*38fd1498Szrj 	  visit (f);
1303*38fd1498Szrj       else if (code == FUNCTION_TYPE
1304*38fd1498Szrj 	       || code == METHOD_TYPE)
1305*38fd1498Szrj 	visit (TYPE_ARG_TYPES (t));
1306*38fd1498Szrj       if (!POINTER_TYPE_P (t))
1307*38fd1498Szrj 	visit (TYPE_MIN_VALUE_RAW (t));
1308*38fd1498Szrj       visit (TYPE_MAX_VALUE_RAW (t));
1309*38fd1498Szrj     }
1310*38fd1498Szrj 
1311*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_LIST))
1312*38fd1498Szrj     {
1313*38fd1498Szrj       visit (TREE_PURPOSE (t));
1314*38fd1498Szrj       visit (TREE_VALUE (t));
1315*38fd1498Szrj       visit (TREE_CHAIN (t));
1316*38fd1498Szrj     }
1317*38fd1498Szrj 
1318*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_VEC))
1319*38fd1498Szrj     for (int i = 0; i < TREE_VEC_LENGTH (t); ++i)
1320*38fd1498Szrj       visit (TREE_VEC_ELT (t, i));
1321*38fd1498Szrj 
1322*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_EXP))
1323*38fd1498Szrj     {
1324*38fd1498Szrj       hstate.add_hwi (TREE_OPERAND_LENGTH (t));
1325*38fd1498Szrj       for (int i = 0; i < TREE_OPERAND_LENGTH (t); ++i)
1326*38fd1498Szrj 	visit (TREE_OPERAND (t, i));
1327*38fd1498Szrj     }
1328*38fd1498Szrj 
1329*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_BINFO))
1330*38fd1498Szrj     {
1331*38fd1498Szrj       unsigned i;
1332*38fd1498Szrj       tree b;
1333*38fd1498Szrj       FOR_EACH_VEC_ELT (*BINFO_BASE_BINFOS (t), i, b)
1334*38fd1498Szrj 	visit (b);
1335*38fd1498Szrj       visit (BINFO_OFFSET (t));
1336*38fd1498Szrj       visit (BINFO_VTABLE (t));
1337*38fd1498Szrj       visit (BINFO_VPTR_FIELD (t));
1338*38fd1498Szrj       FOR_EACH_VEC_SAFE_ELT (BINFO_BASE_ACCESSES (t), i, b)
1339*38fd1498Szrj 	visit (b);
1340*38fd1498Szrj       /* Do not walk BINFO_INHERITANCE_CHAIN, BINFO_SUBVTT_INDEX
1341*38fd1498Szrj 	 and BINFO_VPTR_INDEX; these are used by C++ FE only.  */
1342*38fd1498Szrj     }
1343*38fd1498Szrj 
1344*38fd1498Szrj   if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
1345*38fd1498Szrj     {
1346*38fd1498Szrj       unsigned i;
1347*38fd1498Szrj       tree index, value;
1348*38fd1498Szrj       hstate.add_hwi (CONSTRUCTOR_NELTS (t));
1349*38fd1498Szrj       FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t), i, index, value)
1350*38fd1498Szrj 	{
1351*38fd1498Szrj 	  visit (index);
1352*38fd1498Szrj 	  visit (value);
1353*38fd1498Szrj 	}
1354*38fd1498Szrj     }
1355*38fd1498Szrj 
1356*38fd1498Szrj   if (code == OMP_CLAUSE)
1357*38fd1498Szrj     {
1358*38fd1498Szrj       int i;
1359*38fd1498Szrj       HOST_WIDE_INT val;
1360*38fd1498Szrj 
1361*38fd1498Szrj       hstate.add_hwi (OMP_CLAUSE_CODE (t));
1362*38fd1498Szrj       switch (OMP_CLAUSE_CODE (t))
1363*38fd1498Szrj 	{
1364*38fd1498Szrj 	case OMP_CLAUSE_DEFAULT:
1365*38fd1498Szrj 	  val = OMP_CLAUSE_DEFAULT_KIND (t);
1366*38fd1498Szrj 	  break;
1367*38fd1498Szrj 	case OMP_CLAUSE_SCHEDULE:
1368*38fd1498Szrj 	  val = OMP_CLAUSE_SCHEDULE_KIND (t);
1369*38fd1498Szrj 	  break;
1370*38fd1498Szrj 	case OMP_CLAUSE_DEPEND:
1371*38fd1498Szrj 	  val = OMP_CLAUSE_DEPEND_KIND (t);
1372*38fd1498Szrj 	  break;
1373*38fd1498Szrj 	case OMP_CLAUSE_MAP:
1374*38fd1498Szrj 	  val = OMP_CLAUSE_MAP_KIND (t);
1375*38fd1498Szrj 	  break;
1376*38fd1498Szrj 	case OMP_CLAUSE_PROC_BIND:
1377*38fd1498Szrj 	  val = OMP_CLAUSE_PROC_BIND_KIND (t);
1378*38fd1498Szrj 	  break;
1379*38fd1498Szrj 	case OMP_CLAUSE_REDUCTION:
1380*38fd1498Szrj 	  val = OMP_CLAUSE_REDUCTION_CODE (t);
1381*38fd1498Szrj 	  break;
1382*38fd1498Szrj 	default:
1383*38fd1498Szrj 	  val = 0;
1384*38fd1498Szrj 	  break;
1385*38fd1498Szrj 	}
1386*38fd1498Szrj       hstate.add_hwi (val);
1387*38fd1498Szrj       for (i = 0; i < omp_clause_num_ops[OMP_CLAUSE_CODE (t)]; i++)
1388*38fd1498Szrj 	visit (OMP_CLAUSE_OPERAND (t, i));
1389*38fd1498Szrj       visit (OMP_CLAUSE_CHAIN (t));
1390*38fd1498Szrj     }
1391*38fd1498Szrj 
1392*38fd1498Szrj   return hstate.end ();
1393*38fd1498Szrj 
1394*38fd1498Szrj #undef visit
1395*38fd1498Szrj }
1396*38fd1498Szrj 
1397*38fd1498Szrj /* Compare two SCC entries by their hash value for qsorting them.  */
1398*38fd1498Szrj 
1399*38fd1498Szrj int
scc_entry_compare(const void * p1_,const void * p2_)1400*38fd1498Szrj DFS::scc_entry_compare (const void *p1_, const void *p2_)
1401*38fd1498Szrj {
1402*38fd1498Szrj   const scc_entry *p1 = (const scc_entry *) p1_;
1403*38fd1498Szrj   const scc_entry *p2 = (const scc_entry *) p2_;
1404*38fd1498Szrj   if (p1->hash < p2->hash)
1405*38fd1498Szrj     return -1;
1406*38fd1498Szrj   else if (p1->hash > p2->hash)
1407*38fd1498Szrj     return 1;
1408*38fd1498Szrj   return 0;
1409*38fd1498Szrj }
1410*38fd1498Szrj 
1411*38fd1498Szrj /* Return a hash value for the SCC on the SCC stack from FIRST with SIZE.
1412*38fd1498Szrj    THIS_REF_P and REF_P are as passed to lto_output_tree for FIRST.  */
1413*38fd1498Szrj 
1414*38fd1498Szrj hashval_t
hash_scc(struct output_block * ob,unsigned first,unsigned size,bool ref_p,bool this_ref_p)1415*38fd1498Szrj DFS::hash_scc (struct output_block *ob, unsigned first, unsigned size,
1416*38fd1498Szrj 	       bool ref_p, bool this_ref_p)
1417*38fd1498Szrj {
1418*38fd1498Szrj   unsigned int last_classes = 0, iterations = 0;
1419*38fd1498Szrj 
1420*38fd1498Szrj   /* Compute hash values for the SCC members.  */
1421*38fd1498Szrj   for (unsigned i = 0; i < size; ++i)
1422*38fd1498Szrj     sccstack[first+i].hash
1423*38fd1498Szrj       = hash_tree (ob->writer_cache, NULL, sccstack[first+i].t);
1424*38fd1498Szrj 
1425*38fd1498Szrj   if (size == 1)
1426*38fd1498Szrj     return sccstack[first].hash;
1427*38fd1498Szrj 
1428*38fd1498Szrj   /* We aim to get unique hash for every tree within SCC and compute hash value
1429*38fd1498Szrj      of the whole SCC by combining all values together in a stable (entry-point
1430*38fd1498Szrj      independent) order.  This guarantees that the same SCC regions within
1431*38fd1498Szrj      different translation units will get the same hash values and therefore
1432*38fd1498Szrj      will be merged at WPA time.
1433*38fd1498Szrj 
1434*38fd1498Szrj      Often the hashes are already unique.  In that case we compute the SCC hash
1435*38fd1498Szrj      by combining individual hash values in an increasing order.
1436*38fd1498Szrj 
1437*38fd1498Szrj      If there are duplicates, we seek at least one tree with unique hash (and
1438*38fd1498Szrj      pick one with minimal hash and this property).  Then we obtain a stable
1439*38fd1498Szrj      order by DFS walk starting from this unique tree and then use the index
1440*38fd1498Szrj      within this order to make individual hash values unique.
1441*38fd1498Szrj 
1442*38fd1498Szrj      If there is no tree with unique hash, we iteratively propagate the hash
1443*38fd1498Szrj      values across the internal edges of SCC.  This usually quickly leads
1444*38fd1498Szrj      to unique hashes.  Consider, for example, an SCC containing two pointers
1445*38fd1498Szrj      that are identical except for the types they point to and assume that
1446*38fd1498Szrj      these types are also part of the SCC.  The propagation will add the
1447*38fd1498Szrj      points-to type information into their hash values.  */
1448*38fd1498Szrj   do
1449*38fd1498Szrj     {
1450*38fd1498Szrj       /* Sort the SCC so we can easily check for uniqueness.  */
1451*38fd1498Szrj       qsort (&sccstack[first], size, sizeof (scc_entry), scc_entry_compare);
1452*38fd1498Szrj 
1453*38fd1498Szrj       unsigned int classes = 1;
1454*38fd1498Szrj       int firstunique = -1;
1455*38fd1498Szrj 
1456*38fd1498Szrj       /* Find the tree with lowest unique hash (if it exists) and compute
1457*38fd1498Szrj 	 the number of equivalence classes.  */
1458*38fd1498Szrj       if (sccstack[first].hash != sccstack[first+1].hash)
1459*38fd1498Szrj 	firstunique = 0;
1460*38fd1498Szrj       for (unsigned i = 1; i < size; ++i)
1461*38fd1498Szrj 	if (sccstack[first+i-1].hash != sccstack[first+i].hash)
1462*38fd1498Szrj 	  {
1463*38fd1498Szrj 	    classes++;
1464*38fd1498Szrj 	    if (firstunique == -1
1465*38fd1498Szrj 		&& (i == size - 1
1466*38fd1498Szrj 		    || sccstack[first+i+1].hash != sccstack[first+i].hash))
1467*38fd1498Szrj 	      firstunique = i;
1468*38fd1498Szrj 	  }
1469*38fd1498Szrj 
1470*38fd1498Szrj       /* If we found a tree with unique hash, stop the iteration.  */
1471*38fd1498Szrj       if (firstunique != -1
1472*38fd1498Szrj 	  /* Also terminate if we run out of iterations or if the number of
1473*38fd1498Szrj 	     equivalence classes is no longer increasing.
1474*38fd1498Szrj 	     For example a cyclic list of trees that are all equivalent will
1475*38fd1498Szrj 	     never have unique entry point; we however do not build such SCCs
1476*38fd1498Szrj 	     in our IL.  */
1477*38fd1498Szrj 	  || classes <= last_classes || iterations > 16)
1478*38fd1498Szrj 	{
1479*38fd1498Szrj           hashval_t scc_hash;
1480*38fd1498Szrj 
1481*38fd1498Szrj 	  /* If some hashes are not unique (CLASSES != SIZE), use the DFS walk
1482*38fd1498Szrj 	     starting from FIRSTUNIQUE to obtain a stable order.  */
1483*38fd1498Szrj 	  if (classes != size && firstunique != -1)
1484*38fd1498Szrj 	    {
1485*38fd1498Szrj 	      hash_map <tree, hashval_t> map(size*2);
1486*38fd1498Szrj 
1487*38fd1498Szrj 	      /* Store hash values into a map, so we can associate them with
1488*38fd1498Szrj 		 the reordered SCC.  */
1489*38fd1498Szrj 	      for (unsigned i = 0; i < size; ++i)
1490*38fd1498Szrj 		map.put (sccstack[first+i].t, sccstack[first+i].hash);
1491*38fd1498Szrj 
1492*38fd1498Szrj 	      DFS again (ob, sccstack[first+firstunique].t, ref_p, this_ref_p,
1493*38fd1498Szrj 			 true);
1494*38fd1498Szrj 	      gcc_assert (again.sccstack.length () == size);
1495*38fd1498Szrj 
1496*38fd1498Szrj 	      memcpy (sccstack.address () + first,
1497*38fd1498Szrj 		      again.sccstack.address (),
1498*38fd1498Szrj 		      sizeof (scc_entry) * size);
1499*38fd1498Szrj 
1500*38fd1498Szrj 	      /* Update hash values of individual members by hashing in the
1501*38fd1498Szrj 		 index within the stable order.  This ensures uniqueness.
1502*38fd1498Szrj 		 Also compute the SCC hash by mixing in all hash values in
1503*38fd1498Szrj 		 the stable order we obtained.  */
1504*38fd1498Szrj 	      sccstack[first].hash = *map.get (sccstack[first].t);
1505*38fd1498Szrj 	      scc_hash = sccstack[first].hash;
1506*38fd1498Szrj 	      for (unsigned i = 1; i < size; ++i)
1507*38fd1498Szrj 		{
1508*38fd1498Szrj 		  sccstack[first+i].hash
1509*38fd1498Szrj 		    = iterative_hash_hashval_t (i,
1510*38fd1498Szrj 						*map.get (sccstack[first+i].t));
1511*38fd1498Szrj 		  scc_hash
1512*38fd1498Szrj 		    = iterative_hash_hashval_t (scc_hash,
1513*38fd1498Szrj 						sccstack[first+i].hash);
1514*38fd1498Szrj 		}
1515*38fd1498Szrj 	    }
1516*38fd1498Szrj 	  /* If we got a unique hash value for each tree, then sort already
1517*38fd1498Szrj 	     ensured entry-point independent order.  Only compute the final
1518*38fd1498Szrj 	     SCC hash.
1519*38fd1498Szrj 
1520*38fd1498Szrj 	     If we failed to find the unique entry point, we go by the same
1521*38fd1498Szrj 	     route.  We will eventually introduce unwanted hash conflicts.  */
1522*38fd1498Szrj 	  else
1523*38fd1498Szrj 	    {
1524*38fd1498Szrj 	      scc_hash = sccstack[first].hash;
1525*38fd1498Szrj 	      for (unsigned i = 1; i < size; ++i)
1526*38fd1498Szrj 		scc_hash
1527*38fd1498Szrj 		  = iterative_hash_hashval_t (scc_hash, sccstack[first+i].hash);
1528*38fd1498Szrj 
1529*38fd1498Szrj 	      /* We cannot 100% guarantee that the hash won't conflict so as
1530*38fd1498Szrj 		 to make it impossible to find a unique hash.  This however
1531*38fd1498Szrj 		 should be an extremely rare case.  ICE for now so possible
1532*38fd1498Szrj 		 issues are found and evaluated.  */
1533*38fd1498Szrj 	      gcc_checking_assert (classes == size);
1534*38fd1498Szrj 	    }
1535*38fd1498Szrj 
1536*38fd1498Szrj 	  /* To avoid conflicts across SCCs, iteratively hash the whole SCC
1537*38fd1498Szrj 	     hash into the hash of each element.  */
1538*38fd1498Szrj 	  for (unsigned i = 0; i < size; ++i)
1539*38fd1498Szrj 	    sccstack[first+i].hash
1540*38fd1498Szrj 	      = iterative_hash_hashval_t (sccstack[first+i].hash, scc_hash);
1541*38fd1498Szrj 	  return scc_hash;
1542*38fd1498Szrj 	}
1543*38fd1498Szrj 
1544*38fd1498Szrj       last_classes = classes;
1545*38fd1498Szrj       iterations++;
1546*38fd1498Szrj 
1547*38fd1498Szrj       /* We failed to identify the entry point; propagate hash values across
1548*38fd1498Szrj 	 the edges.  */
1549*38fd1498Szrj       hash_map <tree, hashval_t> map(size*2);
1550*38fd1498Szrj 
1551*38fd1498Szrj       for (unsigned i = 0; i < size; ++i)
1552*38fd1498Szrj 	map.put (sccstack[first+i].t, sccstack[first+i].hash);
1553*38fd1498Szrj 
1554*38fd1498Szrj       for (unsigned i = 0; i < size; i++)
1555*38fd1498Szrj 	sccstack[first+i].hash
1556*38fd1498Szrj 	  = hash_tree (ob->writer_cache, &map, sccstack[first+i].t);
1557*38fd1498Szrj     }
1558*38fd1498Szrj   while (true);
1559*38fd1498Szrj }
1560*38fd1498Szrj 
1561*38fd1498Szrj /* DFS walk EXPR and stream SCCs of tree bodies if they are not
1562*38fd1498Szrj    already in the streamer cache.  Main routine called for
1563*38fd1498Szrj    each visit of EXPR.  */
1564*38fd1498Szrj 
1565*38fd1498Szrj void
DFS_write_tree(struct output_block * ob,sccs * from_state,tree expr,bool ref_p,bool this_ref_p)1566*38fd1498Szrj DFS::DFS_write_tree (struct output_block *ob, sccs *from_state,
1567*38fd1498Szrj 		     tree expr, bool ref_p, bool this_ref_p)
1568*38fd1498Szrj {
1569*38fd1498Szrj   /* Handle special cases.  */
1570*38fd1498Szrj   if (expr == NULL_TREE)
1571*38fd1498Szrj     return;
1572*38fd1498Szrj 
1573*38fd1498Szrj   /* Do not DFS walk into indexable trees.  */
1574*38fd1498Szrj   if (this_ref_p && tree_is_indexable (expr))
1575*38fd1498Szrj     return;
1576*38fd1498Szrj 
1577*38fd1498Szrj   /* Check if we already streamed EXPR.  */
1578*38fd1498Szrj   if (streamer_tree_cache_lookup (ob->writer_cache, expr, NULL))
1579*38fd1498Szrj     return;
1580*38fd1498Szrj 
1581*38fd1498Szrj   worklist w;
1582*38fd1498Szrj   w.expr = expr;
1583*38fd1498Szrj   w.from_state = from_state;
1584*38fd1498Szrj   w.cstate = NULL;
1585*38fd1498Szrj   w.ref_p = ref_p;
1586*38fd1498Szrj   w.this_ref_p = this_ref_p;
1587*38fd1498Szrj   worklist_vec.safe_push (w);
1588*38fd1498Szrj }
1589*38fd1498Szrj 
1590*38fd1498Szrj 
1591*38fd1498Szrj /* Emit the physical representation of tree node EXPR to output block OB.
1592*38fd1498Szrj    If THIS_REF_P is true, the leaves of EXPR are emitted as references via
1593*38fd1498Szrj    lto_output_tree_ref.  REF_P is used for streaming siblings of EXPR.  */
1594*38fd1498Szrj 
1595*38fd1498Szrj void
lto_output_tree(struct output_block * ob,tree expr,bool ref_p,bool this_ref_p)1596*38fd1498Szrj lto_output_tree (struct output_block *ob, tree expr,
1597*38fd1498Szrj 		 bool ref_p, bool this_ref_p)
1598*38fd1498Szrj {
1599*38fd1498Szrj   unsigned ix;
1600*38fd1498Szrj   bool existed_p;
1601*38fd1498Szrj 
1602*38fd1498Szrj   if (expr == NULL_TREE)
1603*38fd1498Szrj     {
1604*38fd1498Szrj       streamer_write_record_start (ob, LTO_null);
1605*38fd1498Szrj       return;
1606*38fd1498Szrj     }
1607*38fd1498Szrj 
1608*38fd1498Szrj   if (this_ref_p && tree_is_indexable (expr))
1609*38fd1498Szrj     {
1610*38fd1498Szrj       lto_output_tree_ref (ob, expr);
1611*38fd1498Szrj       return;
1612*38fd1498Szrj     }
1613*38fd1498Szrj 
1614*38fd1498Szrj   existed_p = streamer_tree_cache_lookup (ob->writer_cache, expr, &ix);
1615*38fd1498Szrj   if (existed_p)
1616*38fd1498Szrj     {
1617*38fd1498Szrj       /* If a node has already been streamed out, make sure that
1618*38fd1498Szrj 	 we don't write it more than once.  Otherwise, the reader
1619*38fd1498Szrj 	 will instantiate two different nodes for the same object.  */
1620*38fd1498Szrj       streamer_write_record_start (ob, LTO_tree_pickle_reference);
1621*38fd1498Szrj       streamer_write_uhwi (ob, ix);
1622*38fd1498Szrj       streamer_write_enum (ob->main_stream, LTO_tags, LTO_NUM_TAGS,
1623*38fd1498Szrj 			   lto_tree_code_to_tag (TREE_CODE (expr)));
1624*38fd1498Szrj       lto_stats.num_pickle_refs_output++;
1625*38fd1498Szrj     }
1626*38fd1498Szrj   else
1627*38fd1498Szrj     {
1628*38fd1498Szrj       /* This is the first time we see EXPR, write all reachable
1629*38fd1498Szrj 	 trees to OB.  */
1630*38fd1498Szrj       static bool in_dfs_walk;
1631*38fd1498Szrj 
1632*38fd1498Szrj       /* Protect against recursion which means disconnect between
1633*38fd1498Szrj          what tree edges we walk in the DFS walk and what edges
1634*38fd1498Szrj 	 we stream out.  */
1635*38fd1498Szrj       gcc_assert (!in_dfs_walk);
1636*38fd1498Szrj 
1637*38fd1498Szrj       /* Start the DFS walk.  */
1638*38fd1498Szrj       /* Save ob state ... */
1639*38fd1498Szrj       /* let's see ... */
1640*38fd1498Szrj       in_dfs_walk = true;
1641*38fd1498Szrj       DFS (ob, expr, ref_p, this_ref_p, false);
1642*38fd1498Szrj       in_dfs_walk = false;
1643*38fd1498Szrj 
1644*38fd1498Szrj       /* Finally append a reference to the tree we were writing.
1645*38fd1498Szrj 	 ???  If expr ended up as a singleton we could have
1646*38fd1498Szrj 	 inlined it here and avoid outputting a reference.  */
1647*38fd1498Szrj       existed_p = streamer_tree_cache_lookup (ob->writer_cache, expr, &ix);
1648*38fd1498Szrj       gcc_assert (existed_p);
1649*38fd1498Szrj       streamer_write_record_start (ob, LTO_tree_pickle_reference);
1650*38fd1498Szrj       streamer_write_uhwi (ob, ix);
1651*38fd1498Szrj       streamer_write_enum (ob->main_stream, LTO_tags, LTO_NUM_TAGS,
1652*38fd1498Szrj 			   lto_tree_code_to_tag (TREE_CODE (expr)));
1653*38fd1498Szrj       lto_stats.num_pickle_refs_output++;
1654*38fd1498Szrj     }
1655*38fd1498Szrj }
1656*38fd1498Szrj 
1657*38fd1498Szrj 
1658*38fd1498Szrj /* Output to OB a list of try/catch handlers starting with FIRST.  */
1659*38fd1498Szrj 
1660*38fd1498Szrj static void
output_eh_try_list(struct output_block * ob,eh_catch first)1661*38fd1498Szrj output_eh_try_list (struct output_block *ob, eh_catch first)
1662*38fd1498Szrj {
1663*38fd1498Szrj   eh_catch n;
1664*38fd1498Szrj 
1665*38fd1498Szrj   for (n = first; n; n = n->next_catch)
1666*38fd1498Szrj     {
1667*38fd1498Szrj       streamer_write_record_start (ob, LTO_eh_catch);
1668*38fd1498Szrj       stream_write_tree (ob, n->type_list, true);
1669*38fd1498Szrj       stream_write_tree (ob, n->filter_list, true);
1670*38fd1498Szrj       stream_write_tree (ob, n->label, true);
1671*38fd1498Szrj     }
1672*38fd1498Szrj 
1673*38fd1498Szrj   streamer_write_record_start (ob, LTO_null);
1674*38fd1498Szrj }
1675*38fd1498Szrj 
1676*38fd1498Szrj 
1677*38fd1498Szrj /* Output EH region R in function FN to OB.  CURR_RN is the slot index
1678*38fd1498Szrj    that is being emitted in FN->EH->REGION_ARRAY.  This is used to
1679*38fd1498Szrj    detect EH region sharing.  */
1680*38fd1498Szrj 
1681*38fd1498Szrj static void
output_eh_region(struct output_block * ob,eh_region r)1682*38fd1498Szrj output_eh_region (struct output_block *ob, eh_region r)
1683*38fd1498Szrj {
1684*38fd1498Szrj   enum LTO_tags tag;
1685*38fd1498Szrj 
1686*38fd1498Szrj   if (r == NULL)
1687*38fd1498Szrj     {
1688*38fd1498Szrj       streamer_write_record_start (ob, LTO_null);
1689*38fd1498Szrj       return;
1690*38fd1498Szrj     }
1691*38fd1498Szrj 
1692*38fd1498Szrj   if (r->type == ERT_CLEANUP)
1693*38fd1498Szrj     tag = LTO_ert_cleanup;
1694*38fd1498Szrj   else if (r->type == ERT_TRY)
1695*38fd1498Szrj     tag = LTO_ert_try;
1696*38fd1498Szrj   else if (r->type == ERT_ALLOWED_EXCEPTIONS)
1697*38fd1498Szrj     tag = LTO_ert_allowed_exceptions;
1698*38fd1498Szrj   else if (r->type == ERT_MUST_NOT_THROW)
1699*38fd1498Szrj     tag = LTO_ert_must_not_throw;
1700*38fd1498Szrj   else
1701*38fd1498Szrj     gcc_unreachable ();
1702*38fd1498Szrj 
1703*38fd1498Szrj   streamer_write_record_start (ob, tag);
1704*38fd1498Szrj   streamer_write_hwi (ob, r->index);
1705*38fd1498Szrj 
1706*38fd1498Szrj   if (r->outer)
1707*38fd1498Szrj     streamer_write_hwi (ob, r->outer->index);
1708*38fd1498Szrj   else
1709*38fd1498Szrj     streamer_write_zero (ob);
1710*38fd1498Szrj 
1711*38fd1498Szrj   if (r->inner)
1712*38fd1498Szrj     streamer_write_hwi (ob, r->inner->index);
1713*38fd1498Szrj   else
1714*38fd1498Szrj     streamer_write_zero (ob);
1715*38fd1498Szrj 
1716*38fd1498Szrj   if (r->next_peer)
1717*38fd1498Szrj     streamer_write_hwi (ob, r->next_peer->index);
1718*38fd1498Szrj   else
1719*38fd1498Szrj     streamer_write_zero (ob);
1720*38fd1498Szrj 
1721*38fd1498Szrj   if (r->type == ERT_TRY)
1722*38fd1498Szrj     {
1723*38fd1498Szrj       output_eh_try_list (ob, r->u.eh_try.first_catch);
1724*38fd1498Szrj     }
1725*38fd1498Szrj   else if (r->type == ERT_ALLOWED_EXCEPTIONS)
1726*38fd1498Szrj     {
1727*38fd1498Szrj       stream_write_tree (ob, r->u.allowed.type_list, true);
1728*38fd1498Szrj       stream_write_tree (ob, r->u.allowed.label, true);
1729*38fd1498Szrj       streamer_write_uhwi (ob, r->u.allowed.filter);
1730*38fd1498Szrj     }
1731*38fd1498Szrj   else if (r->type == ERT_MUST_NOT_THROW)
1732*38fd1498Szrj     {
1733*38fd1498Szrj       stream_write_tree (ob, r->u.must_not_throw.failure_decl, true);
1734*38fd1498Szrj       bitpack_d bp = bitpack_create (ob->main_stream);
1735*38fd1498Szrj       stream_output_location (ob, &bp, r->u.must_not_throw.failure_loc);
1736*38fd1498Szrj       streamer_write_bitpack (&bp);
1737*38fd1498Szrj     }
1738*38fd1498Szrj 
1739*38fd1498Szrj   if (r->landing_pads)
1740*38fd1498Szrj     streamer_write_hwi (ob, r->landing_pads->index);
1741*38fd1498Szrj   else
1742*38fd1498Szrj     streamer_write_zero (ob);
1743*38fd1498Szrj }
1744*38fd1498Szrj 
1745*38fd1498Szrj 
1746*38fd1498Szrj /* Output landing pad LP to OB.  */
1747*38fd1498Szrj 
1748*38fd1498Szrj static void
output_eh_lp(struct output_block * ob,eh_landing_pad lp)1749*38fd1498Szrj output_eh_lp (struct output_block *ob, eh_landing_pad lp)
1750*38fd1498Szrj {
1751*38fd1498Szrj   if (lp == NULL)
1752*38fd1498Szrj     {
1753*38fd1498Szrj       streamer_write_record_start (ob, LTO_null);
1754*38fd1498Szrj       return;
1755*38fd1498Szrj     }
1756*38fd1498Szrj 
1757*38fd1498Szrj   streamer_write_record_start (ob, LTO_eh_landing_pad);
1758*38fd1498Szrj   streamer_write_hwi (ob, lp->index);
1759*38fd1498Szrj   if (lp->next_lp)
1760*38fd1498Szrj     streamer_write_hwi (ob, lp->next_lp->index);
1761*38fd1498Szrj   else
1762*38fd1498Szrj     streamer_write_zero (ob);
1763*38fd1498Szrj 
1764*38fd1498Szrj   if (lp->region)
1765*38fd1498Szrj     streamer_write_hwi (ob, lp->region->index);
1766*38fd1498Szrj   else
1767*38fd1498Szrj     streamer_write_zero (ob);
1768*38fd1498Szrj 
1769*38fd1498Szrj   stream_write_tree (ob, lp->post_landing_pad, true);
1770*38fd1498Szrj }
1771*38fd1498Szrj 
1772*38fd1498Szrj 
1773*38fd1498Szrj /* Output the existing eh_table to OB.  */
1774*38fd1498Szrj 
1775*38fd1498Szrj static void
output_eh_regions(struct output_block * ob,struct function * fn)1776*38fd1498Szrj output_eh_regions (struct output_block *ob, struct function *fn)
1777*38fd1498Szrj {
1778*38fd1498Szrj   if (fn->eh && fn->eh->region_tree)
1779*38fd1498Szrj     {
1780*38fd1498Szrj       unsigned i;
1781*38fd1498Szrj       eh_region eh;
1782*38fd1498Szrj       eh_landing_pad lp;
1783*38fd1498Szrj       tree ttype;
1784*38fd1498Szrj 
1785*38fd1498Szrj       streamer_write_record_start (ob, LTO_eh_table);
1786*38fd1498Szrj 
1787*38fd1498Szrj       /* Emit the index of the root of the EH region tree.  */
1788*38fd1498Szrj       streamer_write_hwi (ob, fn->eh->region_tree->index);
1789*38fd1498Szrj 
1790*38fd1498Szrj       /* Emit all the EH regions in the region array.  */
1791*38fd1498Szrj       streamer_write_hwi (ob, vec_safe_length (fn->eh->region_array));
1792*38fd1498Szrj       FOR_EACH_VEC_SAFE_ELT (fn->eh->region_array, i, eh)
1793*38fd1498Szrj 	output_eh_region (ob, eh);
1794*38fd1498Szrj 
1795*38fd1498Szrj       /* Emit all landing pads.  */
1796*38fd1498Szrj       streamer_write_hwi (ob, vec_safe_length (fn->eh->lp_array));
1797*38fd1498Szrj       FOR_EACH_VEC_SAFE_ELT (fn->eh->lp_array, i, lp)
1798*38fd1498Szrj 	output_eh_lp (ob, lp);
1799*38fd1498Szrj 
1800*38fd1498Szrj       /* Emit all the runtime type data.  */
1801*38fd1498Szrj       streamer_write_hwi (ob, vec_safe_length (fn->eh->ttype_data));
1802*38fd1498Szrj       FOR_EACH_VEC_SAFE_ELT (fn->eh->ttype_data, i, ttype)
1803*38fd1498Szrj 	stream_write_tree (ob, ttype, true);
1804*38fd1498Szrj 
1805*38fd1498Szrj       /* Emit the table of action chains.  */
1806*38fd1498Szrj       if (targetm.arm_eabi_unwinder)
1807*38fd1498Szrj 	{
1808*38fd1498Szrj 	  tree t;
1809*38fd1498Szrj 	  streamer_write_hwi (ob, vec_safe_length (fn->eh->ehspec_data.arm_eabi));
1810*38fd1498Szrj 	  FOR_EACH_VEC_SAFE_ELT (fn->eh->ehspec_data.arm_eabi, i, t)
1811*38fd1498Szrj 	    stream_write_tree (ob, t, true);
1812*38fd1498Szrj 	}
1813*38fd1498Szrj       else
1814*38fd1498Szrj 	{
1815*38fd1498Szrj 	  uchar c;
1816*38fd1498Szrj 	  streamer_write_hwi (ob, vec_safe_length (fn->eh->ehspec_data.other));
1817*38fd1498Szrj 	  FOR_EACH_VEC_SAFE_ELT (fn->eh->ehspec_data.other, i, c)
1818*38fd1498Szrj 	    streamer_write_char_stream (ob->main_stream, c);
1819*38fd1498Szrj 	}
1820*38fd1498Szrj     }
1821*38fd1498Szrj 
1822*38fd1498Szrj   /* The LTO_null either terminates the record or indicates that there
1823*38fd1498Szrj      are no eh_records at all.  */
1824*38fd1498Szrj   streamer_write_record_start (ob, LTO_null);
1825*38fd1498Szrj }
1826*38fd1498Szrj 
1827*38fd1498Szrj 
1828*38fd1498Szrj /* Output all of the active ssa names to the ssa_names stream.  */
1829*38fd1498Szrj 
1830*38fd1498Szrj static void
output_ssa_names(struct output_block * ob,struct function * fn)1831*38fd1498Szrj output_ssa_names (struct output_block *ob, struct function *fn)
1832*38fd1498Szrj {
1833*38fd1498Szrj   unsigned int i, len;
1834*38fd1498Szrj 
1835*38fd1498Szrj   len = vec_safe_length (SSANAMES (fn));
1836*38fd1498Szrj   streamer_write_uhwi (ob, len);
1837*38fd1498Szrj 
1838*38fd1498Szrj   for (i = 1; i < len; i++)
1839*38fd1498Szrj     {
1840*38fd1498Szrj       tree ptr = (*SSANAMES (fn))[i];
1841*38fd1498Szrj 
1842*38fd1498Szrj       if (ptr == NULL_TREE
1843*38fd1498Szrj 	  || SSA_NAME_IN_FREE_LIST (ptr)
1844*38fd1498Szrj 	  || virtual_operand_p (ptr)
1845*38fd1498Szrj 	  /* Simply skip unreleased SSA names.  */
1846*38fd1498Szrj 	  || (! SSA_NAME_IS_DEFAULT_DEF (ptr)
1847*38fd1498Szrj 	      && (! SSA_NAME_DEF_STMT (ptr)
1848*38fd1498Szrj 		  || ! gimple_bb (SSA_NAME_DEF_STMT (ptr)))))
1849*38fd1498Szrj 	continue;
1850*38fd1498Szrj 
1851*38fd1498Szrj       streamer_write_uhwi (ob, i);
1852*38fd1498Szrj       streamer_write_char_stream (ob->main_stream,
1853*38fd1498Szrj 				  SSA_NAME_IS_DEFAULT_DEF (ptr));
1854*38fd1498Szrj       if (SSA_NAME_VAR (ptr))
1855*38fd1498Szrj 	stream_write_tree (ob, SSA_NAME_VAR (ptr), true);
1856*38fd1498Szrj       else
1857*38fd1498Szrj 	/* ???  This drops SSA_NAME_IDENTIFIER on the floor.  */
1858*38fd1498Szrj 	stream_write_tree (ob, TREE_TYPE (ptr), true);
1859*38fd1498Szrj     }
1860*38fd1498Szrj 
1861*38fd1498Szrj   streamer_write_zero (ob);
1862*38fd1498Szrj }
1863*38fd1498Szrj 
1864*38fd1498Szrj 
1865*38fd1498Szrj 
1866*38fd1498Szrj /* Output the cfg.  */
1867*38fd1498Szrj 
1868*38fd1498Szrj static void
output_cfg(struct output_block * ob,struct function * fn)1869*38fd1498Szrj output_cfg (struct output_block *ob, struct function *fn)
1870*38fd1498Szrj {
1871*38fd1498Szrj   struct lto_output_stream *tmp_stream = ob->main_stream;
1872*38fd1498Szrj   basic_block bb;
1873*38fd1498Szrj 
1874*38fd1498Szrj   ob->main_stream = ob->cfg_stream;
1875*38fd1498Szrj 
1876*38fd1498Szrj   streamer_write_enum (ob->main_stream, profile_status_d, PROFILE_LAST,
1877*38fd1498Szrj 		       profile_status_for_fn (fn));
1878*38fd1498Szrj 
1879*38fd1498Szrj   /* Output the number of the highest basic block.  */
1880*38fd1498Szrj   streamer_write_uhwi (ob, last_basic_block_for_fn (fn));
1881*38fd1498Szrj 
1882*38fd1498Szrj   FOR_ALL_BB_FN (bb, fn)
1883*38fd1498Szrj     {
1884*38fd1498Szrj       edge_iterator ei;
1885*38fd1498Szrj       edge e;
1886*38fd1498Szrj 
1887*38fd1498Szrj       streamer_write_hwi (ob, bb->index);
1888*38fd1498Szrj 
1889*38fd1498Szrj       /* Output the successors and the edge flags.  */
1890*38fd1498Szrj       streamer_write_uhwi (ob, EDGE_COUNT (bb->succs));
1891*38fd1498Szrj       FOR_EACH_EDGE (e, ei, bb->succs)
1892*38fd1498Szrj 	{
1893*38fd1498Szrj 	  streamer_write_uhwi (ob, e->dest->index);
1894*38fd1498Szrj 	  e->probability.stream_out (ob);
1895*38fd1498Szrj 	  streamer_write_uhwi (ob, e->flags);
1896*38fd1498Szrj 	}
1897*38fd1498Szrj     }
1898*38fd1498Szrj 
1899*38fd1498Szrj   streamer_write_hwi (ob, -1);
1900*38fd1498Szrj 
1901*38fd1498Szrj   bb = ENTRY_BLOCK_PTR_FOR_FN (cfun);
1902*38fd1498Szrj   while (bb->next_bb)
1903*38fd1498Szrj     {
1904*38fd1498Szrj       streamer_write_hwi (ob, bb->next_bb->index);
1905*38fd1498Szrj       bb = bb->next_bb;
1906*38fd1498Szrj     }
1907*38fd1498Szrj 
1908*38fd1498Szrj   streamer_write_hwi (ob, -1);
1909*38fd1498Szrj 
1910*38fd1498Szrj   /* ???  The cfgloop interface is tied to cfun.  */
1911*38fd1498Szrj   gcc_assert (cfun == fn);
1912*38fd1498Szrj 
1913*38fd1498Szrj   /* Output the number of loops.  */
1914*38fd1498Szrj   streamer_write_uhwi (ob, number_of_loops (fn));
1915*38fd1498Szrj 
1916*38fd1498Szrj   /* Output each loop, skipping the tree root which has number zero.  */
1917*38fd1498Szrj   for (unsigned i = 1; i < number_of_loops (fn); ++i)
1918*38fd1498Szrj     {
1919*38fd1498Szrj       struct loop *loop = get_loop (fn, i);
1920*38fd1498Szrj 
1921*38fd1498Szrj       /* Write the index of the loop header.  That's enough to rebuild
1922*38fd1498Szrj          the loop tree on the reader side.  Stream -1 for an unused
1923*38fd1498Szrj 	 loop entry.  */
1924*38fd1498Szrj       if (!loop)
1925*38fd1498Szrj 	{
1926*38fd1498Szrj 	  streamer_write_hwi (ob, -1);
1927*38fd1498Szrj 	  continue;
1928*38fd1498Szrj 	}
1929*38fd1498Szrj       else
1930*38fd1498Szrj 	streamer_write_hwi (ob, loop->header->index);
1931*38fd1498Szrj 
1932*38fd1498Szrj       /* Write everything copy_loop_info copies.  */
1933*38fd1498Szrj       streamer_write_enum (ob->main_stream,
1934*38fd1498Szrj 			   loop_estimation, EST_LAST, loop->estimate_state);
1935*38fd1498Szrj       streamer_write_hwi (ob, loop->any_upper_bound);
1936*38fd1498Szrj       if (loop->any_upper_bound)
1937*38fd1498Szrj 	streamer_write_widest_int (ob, loop->nb_iterations_upper_bound);
1938*38fd1498Szrj       streamer_write_hwi (ob, loop->any_likely_upper_bound);
1939*38fd1498Szrj       if (loop->any_likely_upper_bound)
1940*38fd1498Szrj 	streamer_write_widest_int (ob, loop->nb_iterations_likely_upper_bound);
1941*38fd1498Szrj       streamer_write_hwi (ob, loop->any_estimate);
1942*38fd1498Szrj       if (loop->any_estimate)
1943*38fd1498Szrj 	streamer_write_widest_int (ob, loop->nb_iterations_estimate);
1944*38fd1498Szrj 
1945*38fd1498Szrj       /* Write OMP SIMD related info.  */
1946*38fd1498Szrj       streamer_write_hwi (ob, loop->safelen);
1947*38fd1498Szrj       streamer_write_hwi (ob, loop->unroll);
1948*38fd1498Szrj       streamer_write_hwi (ob, loop->dont_vectorize);
1949*38fd1498Szrj       streamer_write_hwi (ob, loop->force_vectorize);
1950*38fd1498Szrj       stream_write_tree (ob, loop->simduid, true);
1951*38fd1498Szrj     }
1952*38fd1498Szrj 
1953*38fd1498Szrj   ob->main_stream = tmp_stream;
1954*38fd1498Szrj }
1955*38fd1498Szrj 
1956*38fd1498Szrj 
1957*38fd1498Szrj /* Create the header in the file using OB.  If the section type is for
1958*38fd1498Szrj    a function, set FN to the decl for that function.  */
1959*38fd1498Szrj 
1960*38fd1498Szrj void
produce_asm(struct output_block * ob,tree fn)1961*38fd1498Szrj produce_asm (struct output_block *ob, tree fn)
1962*38fd1498Szrj {
1963*38fd1498Szrj   enum lto_section_type section_type = ob->section_type;
1964*38fd1498Szrj   struct lto_function_header header;
1965*38fd1498Szrj   char *section_name;
1966*38fd1498Szrj 
1967*38fd1498Szrj   if (section_type == LTO_section_function_body)
1968*38fd1498Szrj     {
1969*38fd1498Szrj       const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fn));
1970*38fd1498Szrj       section_name = lto_get_section_name (section_type, name, NULL);
1971*38fd1498Szrj     }
1972*38fd1498Szrj   else
1973*38fd1498Szrj     section_name = lto_get_section_name (section_type, NULL, NULL);
1974*38fd1498Szrj 
1975*38fd1498Szrj   lto_begin_section (section_name, !flag_wpa);
1976*38fd1498Szrj   free (section_name);
1977*38fd1498Szrj 
1978*38fd1498Szrj   /* The entire header is stream computed here.  */
1979*38fd1498Szrj   memset (&header, 0, sizeof (struct lto_function_header));
1980*38fd1498Szrj 
1981*38fd1498Szrj   /* Write the header.  */
1982*38fd1498Szrj   header.major_version = LTO_major_version;
1983*38fd1498Szrj   header.minor_version = LTO_minor_version;
1984*38fd1498Szrj 
1985*38fd1498Szrj   if (section_type == LTO_section_function_body)
1986*38fd1498Szrj     header.cfg_size = ob->cfg_stream->total_size;
1987*38fd1498Szrj   header.main_size = ob->main_stream->total_size;
1988*38fd1498Szrj   header.string_size = ob->string_stream->total_size;
1989*38fd1498Szrj   lto_write_data (&header, sizeof header);
1990*38fd1498Szrj 
1991*38fd1498Szrj   /* Put all of the gimple and the string table out the asm file as a
1992*38fd1498Szrj      block of text.  */
1993*38fd1498Szrj   if (section_type == LTO_section_function_body)
1994*38fd1498Szrj     lto_write_stream (ob->cfg_stream);
1995*38fd1498Szrj   lto_write_stream (ob->main_stream);
1996*38fd1498Szrj   lto_write_stream (ob->string_stream);
1997*38fd1498Szrj 
1998*38fd1498Szrj   lto_end_section ();
1999*38fd1498Szrj }
2000*38fd1498Szrj 
2001*38fd1498Szrj 
2002*38fd1498Szrj /* Output the base body of struct function FN using output block OB.  */
2003*38fd1498Szrj 
2004*38fd1498Szrj static void
output_struct_function_base(struct output_block * ob,struct function * fn)2005*38fd1498Szrj output_struct_function_base (struct output_block *ob, struct function *fn)
2006*38fd1498Szrj {
2007*38fd1498Szrj   struct bitpack_d bp;
2008*38fd1498Szrj   unsigned i;
2009*38fd1498Szrj   tree t;
2010*38fd1498Szrj 
2011*38fd1498Szrj   /* Output the static chain and non-local goto save area.  */
2012*38fd1498Szrj   stream_write_tree (ob, fn->static_chain_decl, true);
2013*38fd1498Szrj   stream_write_tree (ob, fn->nonlocal_goto_save_area, true);
2014*38fd1498Szrj 
2015*38fd1498Szrj   /* Output all the local variables in the function.  */
2016*38fd1498Szrj   streamer_write_hwi (ob, vec_safe_length (fn->local_decls));
2017*38fd1498Szrj   FOR_EACH_VEC_SAFE_ELT (fn->local_decls, i, t)
2018*38fd1498Szrj     stream_write_tree (ob, t, true);
2019*38fd1498Szrj 
2020*38fd1498Szrj   /* Output current IL state of the function.  */
2021*38fd1498Szrj   streamer_write_uhwi (ob, fn->curr_properties);
2022*38fd1498Szrj 
2023*38fd1498Szrj   /* Write all the attributes for FN.  */
2024*38fd1498Szrj   bp = bitpack_create (ob->main_stream);
2025*38fd1498Szrj   bp_pack_value (&bp, fn->is_thunk, 1);
2026*38fd1498Szrj   bp_pack_value (&bp, fn->has_local_explicit_reg_vars, 1);
2027*38fd1498Szrj   bp_pack_value (&bp, fn->returns_pcc_struct, 1);
2028*38fd1498Szrj   bp_pack_value (&bp, fn->returns_struct, 1);
2029*38fd1498Szrj   bp_pack_value (&bp, fn->can_throw_non_call_exceptions, 1);
2030*38fd1498Szrj   bp_pack_value (&bp, fn->can_delete_dead_exceptions, 1);
2031*38fd1498Szrj   bp_pack_value (&bp, fn->always_inline_functions_inlined, 1);
2032*38fd1498Szrj   bp_pack_value (&bp, fn->after_inlining, 1);
2033*38fd1498Szrj   bp_pack_value (&bp, fn->stdarg, 1);
2034*38fd1498Szrj   bp_pack_value (&bp, fn->has_nonlocal_label, 1);
2035*38fd1498Szrj   bp_pack_value (&bp, fn->has_forced_label_in_static, 1);
2036*38fd1498Szrj   bp_pack_value (&bp, fn->calls_alloca, 1);
2037*38fd1498Szrj   bp_pack_value (&bp, fn->calls_setjmp, 1);
2038*38fd1498Szrj   bp_pack_value (&bp, fn->has_force_vectorize_loops, 1);
2039*38fd1498Szrj   bp_pack_value (&bp, fn->has_simduid_loops, 1);
2040*38fd1498Szrj   bp_pack_value (&bp, fn->va_list_fpr_size, 8);
2041*38fd1498Szrj   bp_pack_value (&bp, fn->va_list_gpr_size, 8);
2042*38fd1498Szrj   bp_pack_value (&bp, fn->last_clique, sizeof (short) * 8);
2043*38fd1498Szrj 
2044*38fd1498Szrj   /* Output the function start and end loci.  */
2045*38fd1498Szrj   stream_output_location (ob, &bp, fn->function_start_locus);
2046*38fd1498Szrj   stream_output_location (ob, &bp, fn->function_end_locus);
2047*38fd1498Szrj 
2048*38fd1498Szrj   streamer_write_bitpack (&bp);
2049*38fd1498Szrj }
2050*38fd1498Szrj 
2051*38fd1498Szrj 
2052*38fd1498Szrj /* Collect all leaf BLOCKs beyond ROOT into LEAFS.  */
2053*38fd1498Szrj 
2054*38fd1498Szrj static void
collect_block_tree_leafs(tree root,vec<tree> & leafs)2055*38fd1498Szrj collect_block_tree_leafs (tree root, vec<tree> &leafs)
2056*38fd1498Szrj {
2057*38fd1498Szrj   for (root = BLOCK_SUBBLOCKS (root); root; root = BLOCK_CHAIN (root))
2058*38fd1498Szrj     if (! BLOCK_SUBBLOCKS (root))
2059*38fd1498Szrj       leafs.safe_push (root);
2060*38fd1498Szrj     else
2061*38fd1498Szrj       collect_block_tree_leafs (BLOCK_SUBBLOCKS (root), leafs);
2062*38fd1498Szrj }
2063*38fd1498Szrj 
2064*38fd1498Szrj /* Output the body of function NODE->DECL.  */
2065*38fd1498Szrj 
2066*38fd1498Szrj static void
output_function(struct cgraph_node * node)2067*38fd1498Szrj output_function (struct cgraph_node *node)
2068*38fd1498Szrj {
2069*38fd1498Szrj   tree function;
2070*38fd1498Szrj   struct function *fn;
2071*38fd1498Szrj   basic_block bb;
2072*38fd1498Szrj   struct output_block *ob;
2073*38fd1498Szrj 
2074*38fd1498Szrj   function = node->decl;
2075*38fd1498Szrj   fn = DECL_STRUCT_FUNCTION (function);
2076*38fd1498Szrj   ob = create_output_block (LTO_section_function_body);
2077*38fd1498Szrj 
2078*38fd1498Szrj   clear_line_info (ob);
2079*38fd1498Szrj   ob->symbol = node;
2080*38fd1498Szrj 
2081*38fd1498Szrj   gcc_assert (current_function_decl == NULL_TREE && cfun == NULL);
2082*38fd1498Szrj 
2083*38fd1498Szrj   /* Set current_function_decl and cfun.  */
2084*38fd1498Szrj   push_cfun (fn);
2085*38fd1498Szrj 
2086*38fd1498Szrj   /* Make string 0 be a NULL string.  */
2087*38fd1498Szrj   streamer_write_char_stream (ob->string_stream, 0);
2088*38fd1498Szrj 
2089*38fd1498Szrj   streamer_write_record_start (ob, LTO_function);
2090*38fd1498Szrj 
2091*38fd1498Szrj   /* Output decls for parameters and args.  */
2092*38fd1498Szrj   stream_write_tree (ob, DECL_RESULT (function), true);
2093*38fd1498Szrj   streamer_write_chain (ob, DECL_ARGUMENTS (function), true);
2094*38fd1498Szrj 
2095*38fd1498Szrj   /* Output debug args if available. */
2096*38fd1498Szrj   vec<tree, va_gc> **debugargs = decl_debug_args_lookup (function);
2097*38fd1498Szrj   if (! debugargs)
2098*38fd1498Szrj     streamer_write_uhwi (ob, 0);
2099*38fd1498Szrj   else
2100*38fd1498Szrj     {
2101*38fd1498Szrj       streamer_write_uhwi (ob, (*debugargs)->length ());
2102*38fd1498Szrj       for (unsigned i = 0; i < (*debugargs)->length (); ++i)
2103*38fd1498Szrj 	stream_write_tree (ob, (**debugargs)[i], true);
2104*38fd1498Szrj     }
2105*38fd1498Szrj 
2106*38fd1498Szrj   /* Output DECL_INITIAL for the function, which contains the tree of
2107*38fd1498Szrj      lexical scopes.  */
2108*38fd1498Szrj   stream_write_tree (ob, DECL_INITIAL (function), true);
2109*38fd1498Szrj   /* As we do not recurse into BLOCK_SUBBLOCKS but only BLOCK_SUPERCONTEXT
2110*38fd1498Szrj      collect block tree leafs and stream those.  */
2111*38fd1498Szrj   auto_vec<tree> block_tree_leafs;
2112*38fd1498Szrj   if (DECL_INITIAL (function))
2113*38fd1498Szrj     collect_block_tree_leafs (DECL_INITIAL (function), block_tree_leafs);
2114*38fd1498Szrj   streamer_write_uhwi (ob, block_tree_leafs.length ());
2115*38fd1498Szrj   for (unsigned i = 0; i < block_tree_leafs.length (); ++i)
2116*38fd1498Szrj     stream_write_tree (ob, block_tree_leafs[i], true);
2117*38fd1498Szrj 
2118*38fd1498Szrj   /* We also stream abstract functions where we stream only stuff needed for
2119*38fd1498Szrj      debug info.  */
2120*38fd1498Szrj   if (gimple_has_body_p (function))
2121*38fd1498Szrj     {
2122*38fd1498Szrj       streamer_write_uhwi (ob, 1);
2123*38fd1498Szrj       output_struct_function_base (ob, fn);
2124*38fd1498Szrj 
2125*38fd1498Szrj       /* Output all the SSA names used in the function.  */
2126*38fd1498Szrj       output_ssa_names (ob, fn);
2127*38fd1498Szrj 
2128*38fd1498Szrj       /* Output any exception handling regions.  */
2129*38fd1498Szrj       output_eh_regions (ob, fn);
2130*38fd1498Szrj 
2131*38fd1498Szrj 
2132*38fd1498Szrj       /* We will renumber the statements.  The code that does this uses
2133*38fd1498Szrj 	 the same ordering that we use for serializing them so we can use
2134*38fd1498Szrj 	 the same code on the other end and not have to write out the
2135*38fd1498Szrj 	 statement numbers.  We do not assign UIDs to PHIs here because
2136*38fd1498Szrj 	 virtual PHIs get re-computed on-the-fly which would make numbers
2137*38fd1498Szrj 	 inconsistent.  */
2138*38fd1498Szrj       set_gimple_stmt_max_uid (cfun, 0);
2139*38fd1498Szrj       FOR_ALL_BB_FN (bb, cfun)
2140*38fd1498Szrj 	{
2141*38fd1498Szrj 	  for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
2142*38fd1498Szrj 	       gsi_next (&gsi))
2143*38fd1498Szrj 	    {
2144*38fd1498Szrj 	      gphi *stmt = gsi.phi ();
2145*38fd1498Szrj 
2146*38fd1498Szrj 	      /* Virtual PHIs are not going to be streamed.  */
2147*38fd1498Szrj 	      if (!virtual_operand_p (gimple_phi_result (stmt)))
2148*38fd1498Szrj 	        gimple_set_uid (stmt, inc_gimple_stmt_max_uid (cfun));
2149*38fd1498Szrj 	    }
2150*38fd1498Szrj 	  for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
2151*38fd1498Szrj 	       gsi_next (&gsi))
2152*38fd1498Szrj 	    {
2153*38fd1498Szrj 	      gimple *stmt = gsi_stmt (gsi);
2154*38fd1498Szrj 	      gimple_set_uid (stmt, inc_gimple_stmt_max_uid (cfun));
2155*38fd1498Szrj 	    }
2156*38fd1498Szrj 	}
2157*38fd1498Szrj       /* To avoid keeping duplicate gimple IDs in the statements, renumber
2158*38fd1498Szrj 	 virtual phis now.  */
2159*38fd1498Szrj       FOR_ALL_BB_FN (bb, cfun)
2160*38fd1498Szrj 	{
2161*38fd1498Szrj 	  for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
2162*38fd1498Szrj 	       gsi_next (&gsi))
2163*38fd1498Szrj 	    {
2164*38fd1498Szrj 	      gphi *stmt = gsi.phi ();
2165*38fd1498Szrj 	      if (virtual_operand_p (gimple_phi_result (stmt)))
2166*38fd1498Szrj 	        gimple_set_uid (stmt, inc_gimple_stmt_max_uid (cfun));
2167*38fd1498Szrj 	    }
2168*38fd1498Szrj 	}
2169*38fd1498Szrj 
2170*38fd1498Szrj       /* Output the code for the function.  */
2171*38fd1498Szrj       FOR_ALL_BB_FN (bb, fn)
2172*38fd1498Szrj 	output_bb (ob, bb, fn);
2173*38fd1498Szrj 
2174*38fd1498Szrj       /* The terminator for this function.  */
2175*38fd1498Szrj       streamer_write_record_start (ob, LTO_null);
2176*38fd1498Szrj 
2177*38fd1498Szrj       output_cfg (ob, fn);
2178*38fd1498Szrj 
2179*38fd1498Szrj       pop_cfun ();
2180*38fd1498Szrj    }
2181*38fd1498Szrj   else
2182*38fd1498Szrj     streamer_write_uhwi (ob, 0);
2183*38fd1498Szrj 
2184*38fd1498Szrj   /* Create a section to hold the pickled output of this function.   */
2185*38fd1498Szrj   produce_asm (ob, function);
2186*38fd1498Szrj 
2187*38fd1498Szrj   destroy_output_block (ob);
2188*38fd1498Szrj }
2189*38fd1498Szrj 
2190*38fd1498Szrj /* Output the body of function NODE->DECL.  */
2191*38fd1498Szrj 
2192*38fd1498Szrj static void
output_constructor(struct varpool_node * node)2193*38fd1498Szrj output_constructor (struct varpool_node *node)
2194*38fd1498Szrj {
2195*38fd1498Szrj   tree var = node->decl;
2196*38fd1498Szrj   struct output_block *ob;
2197*38fd1498Szrj 
2198*38fd1498Szrj   ob = create_output_block (LTO_section_function_body);
2199*38fd1498Szrj 
2200*38fd1498Szrj   clear_line_info (ob);
2201*38fd1498Szrj   ob->symbol = node;
2202*38fd1498Szrj 
2203*38fd1498Szrj   /* Make string 0 be a NULL string.  */
2204*38fd1498Szrj   streamer_write_char_stream (ob->string_stream, 0);
2205*38fd1498Szrj 
2206*38fd1498Szrj   /* Output DECL_INITIAL for the function, which contains the tree of
2207*38fd1498Szrj      lexical scopes.  */
2208*38fd1498Szrj   stream_write_tree (ob, DECL_INITIAL (var), true);
2209*38fd1498Szrj 
2210*38fd1498Szrj   /* Create a section to hold the pickled output of this function.   */
2211*38fd1498Szrj   produce_asm (ob, var);
2212*38fd1498Szrj 
2213*38fd1498Szrj   destroy_output_block (ob);
2214*38fd1498Szrj }
2215*38fd1498Szrj 
2216*38fd1498Szrj 
2217*38fd1498Szrj /* Emit toplevel asms.  */
2218*38fd1498Szrj 
2219*38fd1498Szrj void
lto_output_toplevel_asms(void)2220*38fd1498Szrj lto_output_toplevel_asms (void)
2221*38fd1498Szrj {
2222*38fd1498Szrj   struct output_block *ob;
2223*38fd1498Szrj   struct asm_node *can;
2224*38fd1498Szrj   char *section_name;
2225*38fd1498Szrj   struct lto_simple_header_with_strings header;
2226*38fd1498Szrj 
2227*38fd1498Szrj   if (!symtab->first_asm_symbol ())
2228*38fd1498Szrj     return;
2229*38fd1498Szrj 
2230*38fd1498Szrj   ob = create_output_block (LTO_section_asm);
2231*38fd1498Szrj 
2232*38fd1498Szrj   /* Make string 0 be a NULL string.  */
2233*38fd1498Szrj   streamer_write_char_stream (ob->string_stream, 0);
2234*38fd1498Szrj 
2235*38fd1498Szrj   for (can = symtab->first_asm_symbol (); can; can = can->next)
2236*38fd1498Szrj     {
2237*38fd1498Szrj       streamer_write_string_cst (ob, ob->main_stream, can->asm_str);
2238*38fd1498Szrj       streamer_write_hwi (ob, can->order);
2239*38fd1498Szrj     }
2240*38fd1498Szrj 
2241*38fd1498Szrj   streamer_write_string_cst (ob, ob->main_stream, NULL_TREE);
2242*38fd1498Szrj 
2243*38fd1498Szrj   section_name = lto_get_section_name (LTO_section_asm, NULL, NULL);
2244*38fd1498Szrj   lto_begin_section (section_name, !flag_wpa);
2245*38fd1498Szrj   free (section_name);
2246*38fd1498Szrj 
2247*38fd1498Szrj   /* The entire header stream is computed here.  */
2248*38fd1498Szrj   memset (&header, 0, sizeof (header));
2249*38fd1498Szrj 
2250*38fd1498Szrj   /* Write the header.  */
2251*38fd1498Szrj   header.major_version = LTO_major_version;
2252*38fd1498Szrj   header.minor_version = LTO_minor_version;
2253*38fd1498Szrj 
2254*38fd1498Szrj   header.main_size = ob->main_stream->total_size;
2255*38fd1498Szrj   header.string_size = ob->string_stream->total_size;
2256*38fd1498Szrj   lto_write_data (&header, sizeof header);
2257*38fd1498Szrj 
2258*38fd1498Szrj   /* Put all of the gimple and the string table out the asm file as a
2259*38fd1498Szrj      block of text.  */
2260*38fd1498Szrj   lto_write_stream (ob->main_stream);
2261*38fd1498Szrj   lto_write_stream (ob->string_stream);
2262*38fd1498Szrj 
2263*38fd1498Szrj   lto_end_section ();
2264*38fd1498Szrj 
2265*38fd1498Szrj   destroy_output_block (ob);
2266*38fd1498Szrj }
2267*38fd1498Szrj 
2268*38fd1498Szrj 
2269*38fd1498Szrj /* Copy the function body or variable constructor of NODE without deserializing. */
2270*38fd1498Szrj 
2271*38fd1498Szrj static void
copy_function_or_variable(struct symtab_node * node)2272*38fd1498Szrj copy_function_or_variable (struct symtab_node *node)
2273*38fd1498Szrj {
2274*38fd1498Szrj   tree function = node->decl;
2275*38fd1498Szrj   struct lto_file_decl_data *file_data = node->lto_file_data;
2276*38fd1498Szrj   const char *data;
2277*38fd1498Szrj   size_t len;
2278*38fd1498Szrj   const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (function));
2279*38fd1498Szrj   char *section_name =
2280*38fd1498Szrj     lto_get_section_name (LTO_section_function_body, name, NULL);
2281*38fd1498Szrj   size_t i, j;
2282*38fd1498Szrj   struct lto_in_decl_state *in_state;
2283*38fd1498Szrj   struct lto_out_decl_state *out_state = lto_get_out_decl_state ();
2284*38fd1498Szrj 
2285*38fd1498Szrj   lto_begin_section (section_name, false);
2286*38fd1498Szrj   free (section_name);
2287*38fd1498Szrj 
2288*38fd1498Szrj   /* We may have renamed the declaration, e.g., a static function.  */
2289*38fd1498Szrj   name = lto_get_decl_name_mapping (file_data, name);
2290*38fd1498Szrj 
2291*38fd1498Szrj   data = lto_get_raw_section_data (file_data, LTO_section_function_body,
2292*38fd1498Szrj                                    name, &len);
2293*38fd1498Szrj   gcc_assert (data);
2294*38fd1498Szrj 
2295*38fd1498Szrj   /* Do a bit copy of the function body.  */
2296*38fd1498Szrj   lto_write_raw_data (data, len);
2297*38fd1498Szrj 
2298*38fd1498Szrj   /* Copy decls. */
2299*38fd1498Szrj   in_state =
2300*38fd1498Szrj     lto_get_function_in_decl_state (node->lto_file_data, function);
2301*38fd1498Szrj   out_state->compressed = in_state->compressed;
2302*38fd1498Szrj   gcc_assert (in_state);
2303*38fd1498Szrj 
2304*38fd1498Szrj   for (i = 0; i < LTO_N_DECL_STREAMS; i++)
2305*38fd1498Szrj     {
2306*38fd1498Szrj       size_t n = vec_safe_length (in_state->streams[i]);
2307*38fd1498Szrj       vec<tree, va_gc> *trees = in_state->streams[i];
2308*38fd1498Szrj       struct lto_tree_ref_encoder *encoder = &(out_state->streams[i]);
2309*38fd1498Szrj 
2310*38fd1498Szrj       /* The out state must have the same indices and the in state.
2311*38fd1498Szrj 	 So just copy the vector.  All the encoders in the in state
2312*38fd1498Szrj 	 must be empty where we reach here. */
2313*38fd1498Szrj       gcc_assert (lto_tree_ref_encoder_size (encoder) == 0);
2314*38fd1498Szrj       encoder->trees.reserve_exact (n);
2315*38fd1498Szrj       for (j = 0; j < n; j++)
2316*38fd1498Szrj 	encoder->trees.safe_push ((*trees)[j]);
2317*38fd1498Szrj     }
2318*38fd1498Szrj 
2319*38fd1498Szrj   lto_free_raw_section_data (file_data, LTO_section_function_body, name,
2320*38fd1498Szrj 			     data, len);
2321*38fd1498Szrj   lto_end_section ();
2322*38fd1498Szrj }
2323*38fd1498Szrj 
2324*38fd1498Szrj /* Wrap symbol references in *TP inside a type-preserving MEM_REF.  */
2325*38fd1498Szrj 
2326*38fd1498Szrj static tree
wrap_refs(tree * tp,int * ws,void *)2327*38fd1498Szrj wrap_refs (tree *tp, int *ws, void *)
2328*38fd1498Szrj {
2329*38fd1498Szrj   tree t = *tp;
2330*38fd1498Szrj   if (handled_component_p (t)
2331*38fd1498Szrj       && TREE_CODE (TREE_OPERAND (t, 0)) == VAR_DECL
2332*38fd1498Szrj       && TREE_PUBLIC (TREE_OPERAND (t, 0)))
2333*38fd1498Szrj     {
2334*38fd1498Szrj       tree decl = TREE_OPERAND (t, 0);
2335*38fd1498Szrj       tree ptrtype = build_pointer_type (TREE_TYPE (decl));
2336*38fd1498Szrj       TREE_OPERAND (t, 0) = build2 (MEM_REF, TREE_TYPE (decl),
2337*38fd1498Szrj 				    build1 (ADDR_EXPR, ptrtype, decl),
2338*38fd1498Szrj 				    build_int_cst (ptrtype, 0));
2339*38fd1498Szrj       TREE_THIS_VOLATILE (TREE_OPERAND (t, 0)) = TREE_THIS_VOLATILE (decl);
2340*38fd1498Szrj       *ws = 0;
2341*38fd1498Szrj     }
2342*38fd1498Szrj   else if (TREE_CODE (t) == CONSTRUCTOR)
2343*38fd1498Szrj     ;
2344*38fd1498Szrj   else if (!EXPR_P (t))
2345*38fd1498Szrj     *ws = 0;
2346*38fd1498Szrj   return NULL_TREE;
2347*38fd1498Szrj }
2348*38fd1498Szrj 
2349*38fd1498Szrj /* Remove functions that are no longer used from offload_funcs, and mark the
2350*38fd1498Szrj    remaining ones with DECL_PRESERVE_P.  */
2351*38fd1498Szrj 
2352*38fd1498Szrj static void
prune_offload_funcs(void)2353*38fd1498Szrj prune_offload_funcs (void)
2354*38fd1498Szrj {
2355*38fd1498Szrj   if (!offload_funcs)
2356*38fd1498Szrj     return;
2357*38fd1498Szrj 
2358*38fd1498Szrj   unsigned int write_index = 0;
2359*38fd1498Szrj   for (unsigned read_index = 0; read_index < vec_safe_length (offload_funcs);
2360*38fd1498Szrj        read_index++)
2361*38fd1498Szrj     {
2362*38fd1498Szrj       tree fn_decl = (*offload_funcs)[read_index];
2363*38fd1498Szrj       bool remove_p = cgraph_node::get (fn_decl) == NULL;
2364*38fd1498Szrj       if (remove_p)
2365*38fd1498Szrj 	continue;
2366*38fd1498Szrj 
2367*38fd1498Szrj       DECL_PRESERVE_P (fn_decl) = 1;
2368*38fd1498Szrj 
2369*38fd1498Szrj       if (write_index != read_index)
2370*38fd1498Szrj 	(*offload_funcs)[write_index] = (*offload_funcs)[read_index];
2371*38fd1498Szrj 
2372*38fd1498Szrj       write_index++;
2373*38fd1498Szrj     }
2374*38fd1498Szrj 
2375*38fd1498Szrj   offload_funcs->truncate (write_index);
2376*38fd1498Szrj }
2377*38fd1498Szrj 
2378*38fd1498Szrj /* Main entry point from the pass manager.  */
2379*38fd1498Szrj 
2380*38fd1498Szrj void
lto_output(void)2381*38fd1498Szrj lto_output (void)
2382*38fd1498Szrj {
2383*38fd1498Szrj   struct lto_out_decl_state *decl_state;
2384*38fd1498Szrj   bitmap output = NULL;
2385*38fd1498Szrj   int i, n_nodes;
2386*38fd1498Szrj   lto_symtab_encoder_t encoder = lto_get_out_decl_state ()->symtab_node_encoder;
2387*38fd1498Szrj 
2388*38fd1498Szrj   prune_offload_funcs ();
2389*38fd1498Szrj 
2390*38fd1498Szrj   if (flag_checking)
2391*38fd1498Szrj     output = lto_bitmap_alloc ();
2392*38fd1498Szrj 
2393*38fd1498Szrj   /* Initialize the streamer.  */
2394*38fd1498Szrj   lto_streamer_init ();
2395*38fd1498Szrj 
2396*38fd1498Szrj   n_nodes = lto_symtab_encoder_size (encoder);
2397*38fd1498Szrj   /* Process only the functions with bodies.  */
2398*38fd1498Szrj   for (i = 0; i < n_nodes; i++)
2399*38fd1498Szrj     {
2400*38fd1498Szrj       symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
2401*38fd1498Szrj       if (cgraph_node *node = dyn_cast <cgraph_node *> (snode))
2402*38fd1498Szrj 	{
2403*38fd1498Szrj 	  if (lto_symtab_encoder_encode_body_p (encoder, node)
2404*38fd1498Szrj 	      && !node->alias
2405*38fd1498Szrj 	      && (!node->thunk.thunk_p || !node->thunk.add_pointer_bounds_args))
2406*38fd1498Szrj 	    {
2407*38fd1498Szrj 	      if (flag_checking)
2408*38fd1498Szrj 		{
2409*38fd1498Szrj 		  gcc_assert (!bitmap_bit_p (output, DECL_UID (node->decl)));
2410*38fd1498Szrj 		  bitmap_set_bit (output, DECL_UID (node->decl));
2411*38fd1498Szrj 		}
2412*38fd1498Szrj 	      decl_state = lto_new_out_decl_state ();
2413*38fd1498Szrj 	      lto_push_out_decl_state (decl_state);
2414*38fd1498Szrj 	      if (gimple_has_body_p (node->decl) || !flag_wpa
2415*38fd1498Szrj 		  /* Thunks have no body but they may be synthetized
2416*38fd1498Szrj 		     at WPA time.  */
2417*38fd1498Szrj 		  || DECL_ARGUMENTS (node->decl))
2418*38fd1498Szrj 		output_function (node);
2419*38fd1498Szrj 	      else
2420*38fd1498Szrj 		copy_function_or_variable (node);
2421*38fd1498Szrj 	      gcc_assert (lto_get_out_decl_state () == decl_state);
2422*38fd1498Szrj 	      lto_pop_out_decl_state ();
2423*38fd1498Szrj 	      lto_record_function_out_decl_state (node->decl, decl_state);
2424*38fd1498Szrj 	    }
2425*38fd1498Szrj 	}
2426*38fd1498Szrj       else if (varpool_node *node = dyn_cast <varpool_node *> (snode))
2427*38fd1498Szrj 	{
2428*38fd1498Szrj 	  /* Wrap symbol references inside the ctor in a type
2429*38fd1498Szrj 	     preserving MEM_REF.  */
2430*38fd1498Szrj 	  tree ctor = DECL_INITIAL (node->decl);
2431*38fd1498Szrj 	  if (ctor && !in_lto_p)
2432*38fd1498Szrj 	    walk_tree (&ctor, wrap_refs, NULL, NULL);
2433*38fd1498Szrj 	  if (get_symbol_initial_value (encoder, node->decl) == error_mark_node
2434*38fd1498Szrj 	      && lto_symtab_encoder_encode_initializer_p (encoder, node)
2435*38fd1498Szrj 	      && !node->alias)
2436*38fd1498Szrj 	    {
2437*38fd1498Szrj 	      timevar_push (TV_IPA_LTO_CTORS_OUT);
2438*38fd1498Szrj 	      if (flag_checking)
2439*38fd1498Szrj 		{
2440*38fd1498Szrj 		  gcc_assert (!bitmap_bit_p (output, DECL_UID (node->decl)));
2441*38fd1498Szrj 		  bitmap_set_bit (output, DECL_UID (node->decl));
2442*38fd1498Szrj 		}
2443*38fd1498Szrj 	      decl_state = lto_new_out_decl_state ();
2444*38fd1498Szrj 	      lto_push_out_decl_state (decl_state);
2445*38fd1498Szrj 	      if (DECL_INITIAL (node->decl) != error_mark_node
2446*38fd1498Szrj 		  || !flag_wpa)
2447*38fd1498Szrj 		output_constructor (node);
2448*38fd1498Szrj 	      else
2449*38fd1498Szrj 		copy_function_or_variable (node);
2450*38fd1498Szrj 	      gcc_assert (lto_get_out_decl_state () == decl_state);
2451*38fd1498Szrj 	      lto_pop_out_decl_state ();
2452*38fd1498Szrj 	      lto_record_function_out_decl_state (node->decl, decl_state);
2453*38fd1498Szrj 	      timevar_pop (TV_IPA_LTO_CTORS_OUT);
2454*38fd1498Szrj 	    }
2455*38fd1498Szrj 	}
2456*38fd1498Szrj     }
2457*38fd1498Szrj 
2458*38fd1498Szrj   /* Emit the callgraph after emitting function bodies.  This needs to
2459*38fd1498Szrj      be done now to make sure that all the statements in every function
2460*38fd1498Szrj      have been renumbered so that edges can be associated with call
2461*38fd1498Szrj      statements using the statement UIDs.  */
2462*38fd1498Szrj   output_symtab ();
2463*38fd1498Szrj 
2464*38fd1498Szrj   output_offload_tables ();
2465*38fd1498Szrj 
2466*38fd1498Szrj #if CHECKING_P
2467*38fd1498Szrj   lto_bitmap_free (output);
2468*38fd1498Szrj #endif
2469*38fd1498Szrj }
2470*38fd1498Szrj 
2471*38fd1498Szrj /* Write each node in encoded by ENCODER to OB, as well as those reachable
2472*38fd1498Szrj    from it and required for correct representation of its semantics.
2473*38fd1498Szrj    Each node in ENCODER must be a global declaration or a type.  A node
2474*38fd1498Szrj    is written only once, even if it appears multiple times in the
2475*38fd1498Szrj    vector.  Certain transitively-reachable nodes, such as those
2476*38fd1498Szrj    representing expressions, may be duplicated, but such nodes
2477*38fd1498Szrj    must not appear in ENCODER itself.  */
2478*38fd1498Szrj 
2479*38fd1498Szrj static void
write_global_stream(struct output_block * ob,struct lto_tree_ref_encoder * encoder)2480*38fd1498Szrj write_global_stream (struct output_block *ob,
2481*38fd1498Szrj 		     struct lto_tree_ref_encoder *encoder)
2482*38fd1498Szrj {
2483*38fd1498Szrj   tree t;
2484*38fd1498Szrj   size_t index;
2485*38fd1498Szrj   const size_t size = lto_tree_ref_encoder_size (encoder);
2486*38fd1498Szrj 
2487*38fd1498Szrj   for (index = 0; index < size; index++)
2488*38fd1498Szrj     {
2489*38fd1498Szrj       t = lto_tree_ref_encoder_get_tree (encoder, index);
2490*38fd1498Szrj       if (!streamer_tree_cache_lookup (ob->writer_cache, t, NULL))
2491*38fd1498Szrj 	stream_write_tree (ob, t, false);
2492*38fd1498Szrj     }
2493*38fd1498Szrj }
2494*38fd1498Szrj 
2495*38fd1498Szrj 
2496*38fd1498Szrj /* Write a sequence of indices into the globals vector corresponding
2497*38fd1498Szrj    to the trees in ENCODER.  These are used by the reader to map the
2498*38fd1498Szrj    indices used to refer to global entities within function bodies to
2499*38fd1498Szrj    their referents.  */
2500*38fd1498Szrj 
2501*38fd1498Szrj static void
write_global_references(struct output_block * ob,struct lto_tree_ref_encoder * encoder)2502*38fd1498Szrj write_global_references (struct output_block *ob,
2503*38fd1498Szrj  			 struct lto_tree_ref_encoder *encoder)
2504*38fd1498Szrj {
2505*38fd1498Szrj   tree t;
2506*38fd1498Szrj   uint32_t index;
2507*38fd1498Szrj   const uint32_t size = lto_tree_ref_encoder_size (encoder);
2508*38fd1498Szrj 
2509*38fd1498Szrj   /* Write size and slot indexes as 32-bit unsigned numbers. */
2510*38fd1498Szrj   uint32_t *data = XNEWVEC (uint32_t, size + 1);
2511*38fd1498Szrj   data[0] = size;
2512*38fd1498Szrj 
2513*38fd1498Szrj   for (index = 0; index < size; index++)
2514*38fd1498Szrj     {
2515*38fd1498Szrj       unsigned slot_num;
2516*38fd1498Szrj 
2517*38fd1498Szrj       t = lto_tree_ref_encoder_get_tree (encoder, index);
2518*38fd1498Szrj       streamer_tree_cache_lookup (ob->writer_cache, t, &slot_num);
2519*38fd1498Szrj       gcc_assert (slot_num != (unsigned)-1);
2520*38fd1498Szrj       data[index + 1] = slot_num;
2521*38fd1498Szrj     }
2522*38fd1498Szrj 
2523*38fd1498Szrj   lto_write_data (data, sizeof (int32_t) * (size + 1));
2524*38fd1498Szrj   free (data);
2525*38fd1498Szrj }
2526*38fd1498Szrj 
2527*38fd1498Szrj 
2528*38fd1498Szrj /* Write all the streams in an lto_out_decl_state STATE using
2529*38fd1498Szrj    output block OB and output stream OUT_STREAM.  */
2530*38fd1498Szrj 
2531*38fd1498Szrj void
lto_output_decl_state_streams(struct output_block * ob,struct lto_out_decl_state * state)2532*38fd1498Szrj lto_output_decl_state_streams (struct output_block *ob,
2533*38fd1498Szrj 			       struct lto_out_decl_state *state)
2534*38fd1498Szrj {
2535*38fd1498Szrj   int i;
2536*38fd1498Szrj 
2537*38fd1498Szrj   for (i = 0;  i < LTO_N_DECL_STREAMS; i++)
2538*38fd1498Szrj     write_global_stream (ob, &state->streams[i]);
2539*38fd1498Szrj }
2540*38fd1498Szrj 
2541*38fd1498Szrj 
2542*38fd1498Szrj /* Write all the references in an lto_out_decl_state STATE using
2543*38fd1498Szrj    output block OB and output stream OUT_STREAM.  */
2544*38fd1498Szrj 
2545*38fd1498Szrj void
lto_output_decl_state_refs(struct output_block * ob,struct lto_out_decl_state * state)2546*38fd1498Szrj lto_output_decl_state_refs (struct output_block *ob,
2547*38fd1498Szrj 			    struct lto_out_decl_state *state)
2548*38fd1498Szrj {
2549*38fd1498Szrj   unsigned i;
2550*38fd1498Szrj   unsigned ref;
2551*38fd1498Szrj   tree decl;
2552*38fd1498Szrj 
2553*38fd1498Szrj   /* Write reference to FUNCTION_DECL.  If there is not function,
2554*38fd1498Szrj      write reference to void_type_node. */
2555*38fd1498Szrj   decl = (state->fn_decl) ? state->fn_decl : void_type_node;
2556*38fd1498Szrj   streamer_tree_cache_lookup (ob->writer_cache, decl, &ref);
2557*38fd1498Szrj   gcc_assert (ref != (unsigned)-1);
2558*38fd1498Szrj   ref = ref * 2 + (state->compressed ? 1 : 0);
2559*38fd1498Szrj   lto_write_data (&ref, sizeof (uint32_t));
2560*38fd1498Szrj 
2561*38fd1498Szrj   for (i = 0;  i < LTO_N_DECL_STREAMS; i++)
2562*38fd1498Szrj     write_global_references (ob, &state->streams[i]);
2563*38fd1498Szrj }
2564*38fd1498Szrj 
2565*38fd1498Szrj 
2566*38fd1498Szrj /* Return the written size of STATE. */
2567*38fd1498Szrj 
2568*38fd1498Szrj static size_t
lto_out_decl_state_written_size(struct lto_out_decl_state * state)2569*38fd1498Szrj lto_out_decl_state_written_size (struct lto_out_decl_state *state)
2570*38fd1498Szrj {
2571*38fd1498Szrj   int i;
2572*38fd1498Szrj   size_t size;
2573*38fd1498Szrj 
2574*38fd1498Szrj   size = sizeof (int32_t);	/* fn_ref. */
2575*38fd1498Szrj   for (i = 0; i < LTO_N_DECL_STREAMS; i++)
2576*38fd1498Szrj     {
2577*38fd1498Szrj       size += sizeof (int32_t); /* vector size. */
2578*38fd1498Szrj       size += (lto_tree_ref_encoder_size (&state->streams[i])
2579*38fd1498Szrj 	       * sizeof (int32_t));
2580*38fd1498Szrj     }
2581*38fd1498Szrj   return size;
2582*38fd1498Szrj }
2583*38fd1498Szrj 
2584*38fd1498Szrj 
2585*38fd1498Szrj /* Write symbol T into STREAM in CACHE. SEEN specifies symbols we wrote
2586*38fd1498Szrj    so far.  */
2587*38fd1498Szrj 
2588*38fd1498Szrj static void
write_symbol(struct streamer_tree_cache_d * cache,tree t,hash_set<const char * > * seen,bool alias)2589*38fd1498Szrj write_symbol (struct streamer_tree_cache_d *cache,
2590*38fd1498Szrj 	      tree t, hash_set<const char *> *seen, bool alias)
2591*38fd1498Szrj {
2592*38fd1498Szrj   const char *name;
2593*38fd1498Szrj   enum gcc_plugin_symbol_kind kind;
2594*38fd1498Szrj   enum gcc_plugin_symbol_visibility visibility = GCCPV_DEFAULT;
2595*38fd1498Szrj   unsigned slot_num;
2596*38fd1498Szrj   uint64_t size;
2597*38fd1498Szrj   const char *comdat;
2598*38fd1498Szrj   unsigned char c;
2599*38fd1498Szrj 
2600*38fd1498Szrj   gcc_checking_assert (TREE_PUBLIC (t)
2601*38fd1498Szrj 		       && !is_builtin_fn (t)
2602*38fd1498Szrj 		       && !DECL_ABSTRACT_P (t)
2603*38fd1498Szrj 		       && (!VAR_P (t) || !DECL_HARD_REGISTER (t)));
2604*38fd1498Szrj 
2605*38fd1498Szrj   gcc_assert (VAR_OR_FUNCTION_DECL_P (t));
2606*38fd1498Szrj 
2607*38fd1498Szrj   name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (t));
2608*38fd1498Szrj 
2609*38fd1498Szrj   /* This behaves like assemble_name_raw in varasm.c, performing the
2610*38fd1498Szrj      same name manipulations that ASM_OUTPUT_LABELREF does. */
2611*38fd1498Szrj   name = IDENTIFIER_POINTER ((*targetm.asm_out.mangle_assembler_name) (name));
2612*38fd1498Szrj 
2613*38fd1498Szrj   if (seen->add (name))
2614*38fd1498Szrj     return;
2615*38fd1498Szrj 
2616*38fd1498Szrj   streamer_tree_cache_lookup (cache, t, &slot_num);
2617*38fd1498Szrj   gcc_assert (slot_num != (unsigned)-1);
2618*38fd1498Szrj 
2619*38fd1498Szrj   if (DECL_EXTERNAL (t))
2620*38fd1498Szrj     {
2621*38fd1498Szrj       if (DECL_WEAK (t))
2622*38fd1498Szrj 	kind = GCCPK_WEAKUNDEF;
2623*38fd1498Szrj       else
2624*38fd1498Szrj 	kind = GCCPK_UNDEF;
2625*38fd1498Szrj     }
2626*38fd1498Szrj   else
2627*38fd1498Szrj     {
2628*38fd1498Szrj       if (DECL_WEAK (t))
2629*38fd1498Szrj 	kind = GCCPK_WEAKDEF;
2630*38fd1498Szrj       else if (DECL_COMMON (t))
2631*38fd1498Szrj 	kind = GCCPK_COMMON;
2632*38fd1498Szrj       else
2633*38fd1498Szrj 	kind = GCCPK_DEF;
2634*38fd1498Szrj 
2635*38fd1498Szrj       /* When something is defined, it should have node attached.  */
2636*38fd1498Szrj       gcc_assert (alias || !VAR_P (t) || varpool_node::get (t)->definition);
2637*38fd1498Szrj       gcc_assert (alias || TREE_CODE (t) != FUNCTION_DECL
2638*38fd1498Szrj 		  || (cgraph_node::get (t)
2639*38fd1498Szrj 		      && cgraph_node::get (t)->definition));
2640*38fd1498Szrj     }
2641*38fd1498Szrj 
2642*38fd1498Szrj   /* Imitate what default_elf_asm_output_external do.
2643*38fd1498Szrj      When symbol is external, we need to output it with DEFAULT visibility
2644*38fd1498Szrj      when compiling with -fvisibility=default, while with HIDDEN visibility
2645*38fd1498Szrj      when symbol has attribute (visibility("hidden")) specified.
2646*38fd1498Szrj      targetm.binds_local_p check DECL_VISIBILITY_SPECIFIED and gets this
2647*38fd1498Szrj      right. */
2648*38fd1498Szrj 
2649*38fd1498Szrj   if (DECL_EXTERNAL (t)
2650*38fd1498Szrj       && !targetm.binds_local_p (t))
2651*38fd1498Szrj     visibility = GCCPV_DEFAULT;
2652*38fd1498Szrj   else
2653*38fd1498Szrj     switch (DECL_VISIBILITY (t))
2654*38fd1498Szrj       {
2655*38fd1498Szrj       case VISIBILITY_DEFAULT:
2656*38fd1498Szrj 	visibility = GCCPV_DEFAULT;
2657*38fd1498Szrj 	break;
2658*38fd1498Szrj       case VISIBILITY_PROTECTED:
2659*38fd1498Szrj 	visibility = GCCPV_PROTECTED;
2660*38fd1498Szrj 	break;
2661*38fd1498Szrj       case VISIBILITY_HIDDEN:
2662*38fd1498Szrj 	visibility = GCCPV_HIDDEN;
2663*38fd1498Szrj 	break;
2664*38fd1498Szrj       case VISIBILITY_INTERNAL:
2665*38fd1498Szrj 	visibility = GCCPV_INTERNAL;
2666*38fd1498Szrj 	break;
2667*38fd1498Szrj       }
2668*38fd1498Szrj 
2669*38fd1498Szrj   if (kind == GCCPK_COMMON
2670*38fd1498Szrj       && DECL_SIZE_UNIT (t)
2671*38fd1498Szrj       && TREE_CODE (DECL_SIZE_UNIT (t)) == INTEGER_CST)
2672*38fd1498Szrj     size = TREE_INT_CST_LOW (DECL_SIZE_UNIT (t));
2673*38fd1498Szrj   else
2674*38fd1498Szrj     size = 0;
2675*38fd1498Szrj 
2676*38fd1498Szrj   if (DECL_ONE_ONLY (t))
2677*38fd1498Szrj     comdat = IDENTIFIER_POINTER (decl_comdat_group_id (t));
2678*38fd1498Szrj   else
2679*38fd1498Szrj     comdat = "";
2680*38fd1498Szrj 
2681*38fd1498Szrj   lto_write_data (name, strlen (name) + 1);
2682*38fd1498Szrj   lto_write_data (comdat, strlen (comdat) + 1);
2683*38fd1498Szrj   c = (unsigned char) kind;
2684*38fd1498Szrj   lto_write_data (&c, 1);
2685*38fd1498Szrj   c = (unsigned char) visibility;
2686*38fd1498Szrj   lto_write_data (&c, 1);
2687*38fd1498Szrj   lto_write_data (&size, 8);
2688*38fd1498Szrj   lto_write_data (&slot_num, 4);
2689*38fd1498Szrj }
2690*38fd1498Szrj 
2691*38fd1498Szrj /* Write an IL symbol table to OB.
2692*38fd1498Szrj    SET and VSET are cgraph/varpool node sets we are outputting.  */
2693*38fd1498Szrj 
2694*38fd1498Szrj static void
produce_symtab(struct output_block * ob)2695*38fd1498Szrj produce_symtab (struct output_block *ob)
2696*38fd1498Szrj {
2697*38fd1498Szrj   struct streamer_tree_cache_d *cache = ob->writer_cache;
2698*38fd1498Szrj   char *section_name = lto_get_section_name (LTO_section_symtab, NULL, NULL);
2699*38fd1498Szrj   lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
2700*38fd1498Szrj   lto_symtab_encoder_iterator lsei;
2701*38fd1498Szrj 
2702*38fd1498Szrj   lto_begin_section (section_name, false);
2703*38fd1498Szrj   free (section_name);
2704*38fd1498Szrj 
2705*38fd1498Szrj   hash_set<const char *> seen;
2706*38fd1498Szrj 
2707*38fd1498Szrj   /* Write the symbol table.
2708*38fd1498Szrj      First write everything defined and then all declarations.
2709*38fd1498Szrj      This is necessary to handle cases where we have duplicated symbols.  */
2710*38fd1498Szrj   for (lsei = lsei_start (encoder);
2711*38fd1498Szrj        !lsei_end_p (lsei); lsei_next (&lsei))
2712*38fd1498Szrj     {
2713*38fd1498Szrj       symtab_node *node = lsei_node (lsei);
2714*38fd1498Szrj 
2715*38fd1498Szrj       if (DECL_EXTERNAL (node->decl) || !node->output_to_lto_symbol_table_p ())
2716*38fd1498Szrj 	continue;
2717*38fd1498Szrj       write_symbol (cache, node->decl, &seen, false);
2718*38fd1498Szrj     }
2719*38fd1498Szrj   for (lsei = lsei_start (encoder);
2720*38fd1498Szrj        !lsei_end_p (lsei); lsei_next (&lsei))
2721*38fd1498Szrj     {
2722*38fd1498Szrj       symtab_node *node = lsei_node (lsei);
2723*38fd1498Szrj 
2724*38fd1498Szrj       if (!DECL_EXTERNAL (node->decl) || !node->output_to_lto_symbol_table_p ())
2725*38fd1498Szrj 	continue;
2726*38fd1498Szrj       write_symbol (cache, node->decl, &seen, false);
2727*38fd1498Szrj     }
2728*38fd1498Szrj 
2729*38fd1498Szrj   lto_end_section ();
2730*38fd1498Szrj }
2731*38fd1498Szrj 
2732*38fd1498Szrj 
2733*38fd1498Szrj /* Init the streamer_mode_table for output, where we collect info on what
2734*38fd1498Szrj    machine_mode values have been streamed.  */
2735*38fd1498Szrj void
lto_output_init_mode_table(void)2736*38fd1498Szrj lto_output_init_mode_table (void)
2737*38fd1498Szrj {
2738*38fd1498Szrj   memset (streamer_mode_table, '\0', MAX_MACHINE_MODE);
2739*38fd1498Szrj }
2740*38fd1498Szrj 
2741*38fd1498Szrj 
2742*38fd1498Szrj /* Write the mode table.  */
2743*38fd1498Szrj static void
lto_write_mode_table(void)2744*38fd1498Szrj lto_write_mode_table (void)
2745*38fd1498Szrj {
2746*38fd1498Szrj   struct output_block *ob;
2747*38fd1498Szrj   ob = create_output_block (LTO_section_mode_table);
2748*38fd1498Szrj   bitpack_d bp = bitpack_create (ob->main_stream);
2749*38fd1498Szrj 
2750*38fd1498Szrj   /* Ensure that for GET_MODE_INNER (m) != m we have
2751*38fd1498Szrj      also the inner mode marked.  */
2752*38fd1498Szrj   for (int i = 0; i < (int) MAX_MACHINE_MODE; i++)
2753*38fd1498Szrj     if (streamer_mode_table[i])
2754*38fd1498Szrj       {
2755*38fd1498Szrj 	machine_mode m = (machine_mode) i;
2756*38fd1498Szrj 	machine_mode inner_m = GET_MODE_INNER (m);
2757*38fd1498Szrj 	if (inner_m != m)
2758*38fd1498Szrj 	  streamer_mode_table[(int) inner_m] = 1;
2759*38fd1498Szrj       }
2760*38fd1498Szrj   /* First stream modes that have GET_MODE_INNER (m) == m,
2761*38fd1498Szrj      so that we can refer to them afterwards.  */
2762*38fd1498Szrj   for (int pass = 0; pass < 2; pass++)
2763*38fd1498Szrj     for (int i = 0; i < (int) MAX_MACHINE_MODE; i++)
2764*38fd1498Szrj       if (streamer_mode_table[i] && i != (int) VOIDmode && i != (int) BLKmode)
2765*38fd1498Szrj 	{
2766*38fd1498Szrj 	  machine_mode m = (machine_mode) i;
2767*38fd1498Szrj 	  if ((GET_MODE_INNER (m) == m) ^ (pass == 0))
2768*38fd1498Szrj 	    continue;
2769*38fd1498Szrj 	  bp_pack_value (&bp, m, 8);
2770*38fd1498Szrj 	  bp_pack_enum (&bp, mode_class, MAX_MODE_CLASS, GET_MODE_CLASS (m));
2771*38fd1498Szrj 	  bp_pack_poly_value (&bp, GET_MODE_SIZE (m), 16);
2772*38fd1498Szrj 	  bp_pack_poly_value (&bp, GET_MODE_PRECISION (m), 16);
2773*38fd1498Szrj 	  bp_pack_value (&bp, GET_MODE_INNER (m), 8);
2774*38fd1498Szrj 	  bp_pack_poly_value (&bp, GET_MODE_NUNITS (m), 16);
2775*38fd1498Szrj 	  switch (GET_MODE_CLASS (m))
2776*38fd1498Szrj 	    {
2777*38fd1498Szrj 	    case MODE_FRACT:
2778*38fd1498Szrj 	    case MODE_UFRACT:
2779*38fd1498Szrj 	    case MODE_ACCUM:
2780*38fd1498Szrj 	    case MODE_UACCUM:
2781*38fd1498Szrj 	      bp_pack_value (&bp, GET_MODE_IBIT (m), 8);
2782*38fd1498Szrj 	      bp_pack_value (&bp, GET_MODE_FBIT (m), 8);
2783*38fd1498Szrj 	      break;
2784*38fd1498Szrj 	    case MODE_FLOAT:
2785*38fd1498Szrj 	    case MODE_DECIMAL_FLOAT:
2786*38fd1498Szrj 	      bp_pack_string (ob, &bp, REAL_MODE_FORMAT (m)->name, true);
2787*38fd1498Szrj 	      break;
2788*38fd1498Szrj 	    default:
2789*38fd1498Szrj 	      break;
2790*38fd1498Szrj 	    }
2791*38fd1498Szrj 	  bp_pack_string (ob, &bp, GET_MODE_NAME (m), true);
2792*38fd1498Szrj 	}
2793*38fd1498Szrj   bp_pack_value (&bp, VOIDmode, 8);
2794*38fd1498Szrj 
2795*38fd1498Szrj   streamer_write_bitpack (&bp);
2796*38fd1498Szrj 
2797*38fd1498Szrj   char *section_name
2798*38fd1498Szrj     = lto_get_section_name (LTO_section_mode_table, NULL, NULL);
2799*38fd1498Szrj   lto_begin_section (section_name, !flag_wpa);
2800*38fd1498Szrj   free (section_name);
2801*38fd1498Szrj 
2802*38fd1498Szrj   /* The entire header stream is computed here.  */
2803*38fd1498Szrj   struct lto_simple_header_with_strings header;
2804*38fd1498Szrj   memset (&header, 0, sizeof (header));
2805*38fd1498Szrj 
2806*38fd1498Szrj   /* Write the header.  */
2807*38fd1498Szrj   header.major_version = LTO_major_version;
2808*38fd1498Szrj   header.minor_version = LTO_minor_version;
2809*38fd1498Szrj 
2810*38fd1498Szrj   header.main_size = ob->main_stream->total_size;
2811*38fd1498Szrj   header.string_size = ob->string_stream->total_size;
2812*38fd1498Szrj   lto_write_data (&header, sizeof header);
2813*38fd1498Szrj 
2814*38fd1498Szrj   /* Put all of the gimple and the string table out the asm file as a
2815*38fd1498Szrj      block of text.  */
2816*38fd1498Szrj   lto_write_stream (ob->main_stream);
2817*38fd1498Szrj   lto_write_stream (ob->string_stream);
2818*38fd1498Szrj 
2819*38fd1498Szrj   lto_end_section ();
2820*38fd1498Szrj   destroy_output_block (ob);
2821*38fd1498Szrj }
2822*38fd1498Szrj 
2823*38fd1498Szrj 
2824*38fd1498Szrj /* This pass is run after all of the functions are serialized and all
2825*38fd1498Szrj    of the IPA passes have written their serialized forms.  This pass
2826*38fd1498Szrj    causes the vector of all of the global decls and types used from
2827*38fd1498Szrj    this file to be written in to a section that can then be read in to
2828*38fd1498Szrj    recover these on other side.  */
2829*38fd1498Szrj 
2830*38fd1498Szrj void
produce_asm_for_decls(void)2831*38fd1498Szrj produce_asm_for_decls (void)
2832*38fd1498Szrj {
2833*38fd1498Szrj   struct lto_out_decl_state *out_state;
2834*38fd1498Szrj   struct lto_out_decl_state *fn_out_state;
2835*38fd1498Szrj   struct lto_decl_header header;
2836*38fd1498Szrj   char *section_name;
2837*38fd1498Szrj   struct output_block *ob;
2838*38fd1498Szrj   unsigned idx, num_fns;
2839*38fd1498Szrj   size_t decl_state_size;
2840*38fd1498Szrj   int32_t num_decl_states;
2841*38fd1498Szrj 
2842*38fd1498Szrj   ob = create_output_block (LTO_section_decls);
2843*38fd1498Szrj 
2844*38fd1498Szrj   memset (&header, 0, sizeof (struct lto_decl_header));
2845*38fd1498Szrj 
2846*38fd1498Szrj   section_name = lto_get_section_name (LTO_section_decls, NULL, NULL);
2847*38fd1498Szrj   lto_begin_section (section_name, !flag_wpa);
2848*38fd1498Szrj   free (section_name);
2849*38fd1498Szrj 
2850*38fd1498Szrj   /* Make string 0 be a NULL string.  */
2851*38fd1498Szrj   streamer_write_char_stream (ob->string_stream, 0);
2852*38fd1498Szrj 
2853*38fd1498Szrj   gcc_assert (!alias_pairs);
2854*38fd1498Szrj 
2855*38fd1498Szrj   /* Get rid of the global decl state hash tables to save some memory.  */
2856*38fd1498Szrj   out_state = lto_get_out_decl_state ();
2857*38fd1498Szrj   for (int i = 0; i < LTO_N_DECL_STREAMS; i++)
2858*38fd1498Szrj     if (out_state->streams[i].tree_hash_table)
2859*38fd1498Szrj       {
2860*38fd1498Szrj 	delete out_state->streams[i].tree_hash_table;
2861*38fd1498Szrj 	out_state->streams[i].tree_hash_table = NULL;
2862*38fd1498Szrj       }
2863*38fd1498Szrj 
2864*38fd1498Szrj   /* Write the global symbols.  */
2865*38fd1498Szrj   lto_output_decl_state_streams (ob, out_state);
2866*38fd1498Szrj   num_fns = lto_function_decl_states.length ();
2867*38fd1498Szrj   for (idx = 0; idx < num_fns; idx++)
2868*38fd1498Szrj     {
2869*38fd1498Szrj       fn_out_state =
2870*38fd1498Szrj 	lto_function_decl_states[idx];
2871*38fd1498Szrj       lto_output_decl_state_streams (ob, fn_out_state);
2872*38fd1498Szrj     }
2873*38fd1498Szrj 
2874*38fd1498Szrj   header.major_version = LTO_major_version;
2875*38fd1498Szrj   header.minor_version = LTO_minor_version;
2876*38fd1498Szrj 
2877*38fd1498Szrj   /* Currently not used.  This field would allow us to preallocate
2878*38fd1498Szrj      the globals vector, so that it need not be resized as it is extended.  */
2879*38fd1498Szrj   header.num_nodes = -1;
2880*38fd1498Szrj 
2881*38fd1498Szrj   /* Compute the total size of all decl out states. */
2882*38fd1498Szrj   decl_state_size = sizeof (int32_t);
2883*38fd1498Szrj   decl_state_size += lto_out_decl_state_written_size (out_state);
2884*38fd1498Szrj   for (idx = 0; idx < num_fns; idx++)
2885*38fd1498Szrj     {
2886*38fd1498Szrj       fn_out_state =
2887*38fd1498Szrj 	lto_function_decl_states[idx];
2888*38fd1498Szrj       decl_state_size += lto_out_decl_state_written_size (fn_out_state);
2889*38fd1498Szrj     }
2890*38fd1498Szrj   header.decl_state_size = decl_state_size;
2891*38fd1498Szrj 
2892*38fd1498Szrj   header.main_size = ob->main_stream->total_size;
2893*38fd1498Szrj   header.string_size = ob->string_stream->total_size;
2894*38fd1498Szrj 
2895*38fd1498Szrj   lto_write_data (&header, sizeof header);
2896*38fd1498Szrj 
2897*38fd1498Szrj   /* Write the main out-decl state, followed by out-decl states of
2898*38fd1498Szrj      functions. */
2899*38fd1498Szrj   num_decl_states = num_fns + 1;
2900*38fd1498Szrj   lto_write_data (&num_decl_states, sizeof (num_decl_states));
2901*38fd1498Szrj   lto_output_decl_state_refs (ob, out_state);
2902*38fd1498Szrj   for (idx = 0; idx < num_fns; idx++)
2903*38fd1498Szrj     {
2904*38fd1498Szrj       fn_out_state = lto_function_decl_states[idx];
2905*38fd1498Szrj       lto_output_decl_state_refs (ob, fn_out_state);
2906*38fd1498Szrj     }
2907*38fd1498Szrj 
2908*38fd1498Szrj   lto_write_stream (ob->main_stream);
2909*38fd1498Szrj   lto_write_stream (ob->string_stream);
2910*38fd1498Szrj 
2911*38fd1498Szrj   lto_end_section ();
2912*38fd1498Szrj 
2913*38fd1498Szrj   /* Write the symbol table.  It is used by linker to determine dependencies
2914*38fd1498Szrj      and thus we can skip it for WPA.  */
2915*38fd1498Szrj   if (!flag_wpa)
2916*38fd1498Szrj     produce_symtab (ob);
2917*38fd1498Szrj 
2918*38fd1498Szrj   /* Write command line opts.  */
2919*38fd1498Szrj   lto_write_options ();
2920*38fd1498Szrj 
2921*38fd1498Szrj   /* Deallocate memory and clean up.  */
2922*38fd1498Szrj   for (idx = 0; idx < num_fns; idx++)
2923*38fd1498Szrj     {
2924*38fd1498Szrj       fn_out_state =
2925*38fd1498Szrj 	lto_function_decl_states[idx];
2926*38fd1498Szrj       lto_delete_out_decl_state (fn_out_state);
2927*38fd1498Szrj     }
2928*38fd1498Szrj   lto_symtab_encoder_delete (ob->decl_state->symtab_node_encoder);
2929*38fd1498Szrj   lto_function_decl_states.release ();
2930*38fd1498Szrj   destroy_output_block (ob);
2931*38fd1498Szrj   if (lto_stream_offload_p)
2932*38fd1498Szrj     lto_write_mode_table ();
2933*38fd1498Szrj }
2934