1e4b17023SJohn Marino /* Routines for emitting trees to a file stream.
2e4b17023SJohn Marino
3e4b17023SJohn Marino Copyright 2011 Free Software Foundation, Inc.
4e4b17023SJohn Marino Contributed by Diego Novillo <dnovillo@google.com>
5e4b17023SJohn Marino
6e4b17023SJohn Marino This file is part of GCC.
7e4b17023SJohn Marino
8e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
9e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
10e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
11e4b17023SJohn Marino version.
12e4b17023SJohn Marino
13e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
15e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16e4b17023SJohn Marino for more details.
17e4b17023SJohn Marino
18e4b17023SJohn Marino You should have received a copy of the GNU General Public License
19e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see
20e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */
21e4b17023SJohn Marino
22e4b17023SJohn Marino #include "config.h"
23e4b17023SJohn Marino #include "system.h"
24e4b17023SJohn Marino #include "coretypes.h"
25e4b17023SJohn Marino #include "diagnostic.h"
26e4b17023SJohn Marino #include "tree.h"
27e4b17023SJohn Marino #include "tree-streamer.h"
28e4b17023SJohn Marino #include "data-streamer.h"
29e4b17023SJohn Marino #include "streamer-hooks.h"
30e4b17023SJohn Marino
31e4b17023SJohn Marino /* Output the STRING constant to the string
32e4b17023SJohn Marino table in OB. Then put the index onto the INDEX_STREAM. */
33e4b17023SJohn Marino
34e4b17023SJohn Marino void
streamer_write_string_cst(struct output_block * ob,struct lto_output_stream * index_stream,tree string)35e4b17023SJohn Marino streamer_write_string_cst (struct output_block *ob,
36e4b17023SJohn Marino struct lto_output_stream *index_stream,
37e4b17023SJohn Marino tree string)
38e4b17023SJohn Marino {
39e4b17023SJohn Marino streamer_write_string_with_length (ob, index_stream,
40e4b17023SJohn Marino string ? TREE_STRING_POINTER (string)
41e4b17023SJohn Marino : NULL,
42e4b17023SJohn Marino string ? TREE_STRING_LENGTH (string) : 0,
43e4b17023SJohn Marino true);
44e4b17023SJohn Marino }
45e4b17023SJohn Marino
46e4b17023SJohn Marino
47e4b17023SJohn Marino /* Output the identifier ID to the string
48e4b17023SJohn Marino table in OB. Then put the index onto the INDEX_STREAM. */
49e4b17023SJohn Marino
50e4b17023SJohn Marino static void
write_identifier(struct output_block * ob,struct lto_output_stream * index_stream,tree id)51e4b17023SJohn Marino write_identifier (struct output_block *ob,
52e4b17023SJohn Marino struct lto_output_stream *index_stream,
53e4b17023SJohn Marino tree id)
54e4b17023SJohn Marino {
55e4b17023SJohn Marino streamer_write_string_with_length (ob, index_stream,
56e4b17023SJohn Marino IDENTIFIER_POINTER (id),
57e4b17023SJohn Marino IDENTIFIER_LENGTH (id),
58e4b17023SJohn Marino true);
59e4b17023SJohn Marino }
60e4b17023SJohn Marino
61e4b17023SJohn Marino
62e4b17023SJohn Marino /* Pack all the non-pointer fields of the TS_BASE structure of
63e4b17023SJohn Marino expression EXPR into bitpack BP. */
64e4b17023SJohn Marino
65e4b17023SJohn Marino static void
pack_ts_base_value_fields(struct bitpack_d * bp,tree expr)66e4b17023SJohn Marino pack_ts_base_value_fields (struct bitpack_d *bp, tree expr)
67e4b17023SJohn Marino {
68e4b17023SJohn Marino bp_pack_value (bp, TREE_CODE (expr), 16);
69e4b17023SJohn Marino if (!TYPE_P (expr))
70e4b17023SJohn Marino {
71e4b17023SJohn Marino bp_pack_value (bp, TREE_SIDE_EFFECTS (expr), 1);
72e4b17023SJohn Marino bp_pack_value (bp, TREE_CONSTANT (expr), 1);
73e4b17023SJohn Marino bp_pack_value (bp, TREE_READONLY (expr), 1);
74e4b17023SJohn Marino
75e4b17023SJohn Marino /* TREE_PUBLIC is used on types to indicate that the type
76e4b17023SJohn Marino has a TYPE_CACHED_VALUES vector. This is not streamed out,
77e4b17023SJohn Marino so we skip it here. */
78e4b17023SJohn Marino bp_pack_value (bp, TREE_PUBLIC (expr), 1);
79e4b17023SJohn Marino }
80e4b17023SJohn Marino else
81e4b17023SJohn Marino bp_pack_value (bp, 0, 4);
82e4b17023SJohn Marino bp_pack_value (bp, TREE_ADDRESSABLE (expr), 1);
83e4b17023SJohn Marino bp_pack_value (bp, TREE_THIS_VOLATILE (expr), 1);
84e4b17023SJohn Marino if (DECL_P (expr))
85e4b17023SJohn Marino bp_pack_value (bp, DECL_UNSIGNED (expr), 1);
86e4b17023SJohn Marino else if (TYPE_P (expr))
87e4b17023SJohn Marino bp_pack_value (bp, TYPE_UNSIGNED (expr), 1);
88e4b17023SJohn Marino else
89e4b17023SJohn Marino bp_pack_value (bp, 0, 1);
90e4b17023SJohn Marino /* We write debug info two times, do not confuse the second one. */
91e4b17023SJohn Marino bp_pack_value (bp, ((TYPE_P (expr) || TREE_CODE (expr) == TYPE_DECL)
92e4b17023SJohn Marino ? 0 : TREE_ASM_WRITTEN (expr)), 1);
93e4b17023SJohn Marino if (TYPE_P (expr))
94e4b17023SJohn Marino bp_pack_value (bp, TYPE_ARTIFICIAL (expr), 1);
95e4b17023SJohn Marino else
96e4b17023SJohn Marino bp_pack_value (bp, TREE_NO_WARNING (expr), 1);
97e4b17023SJohn Marino bp_pack_value (bp, TREE_USED (expr), 1);
98e4b17023SJohn Marino bp_pack_value (bp, TREE_NOTHROW (expr), 1);
99e4b17023SJohn Marino bp_pack_value (bp, TREE_STATIC (expr), 1);
100e4b17023SJohn Marino bp_pack_value (bp, TREE_PRIVATE (expr), 1);
101e4b17023SJohn Marino bp_pack_value (bp, TREE_PROTECTED (expr), 1);
102e4b17023SJohn Marino bp_pack_value (bp, TREE_DEPRECATED (expr), 1);
103e4b17023SJohn Marino if (TYPE_P (expr))
104e4b17023SJohn Marino {
105e4b17023SJohn Marino bp_pack_value (bp, TYPE_SATURATING (expr), 1);
106e4b17023SJohn Marino bp_pack_value (bp, TYPE_ADDR_SPACE (expr), 8);
107e4b17023SJohn Marino }
108e4b17023SJohn Marino else if (TREE_CODE (expr) == SSA_NAME)
109e4b17023SJohn Marino bp_pack_value (bp, SSA_NAME_IS_DEFAULT_DEF (expr), 1);
110e4b17023SJohn Marino else
111e4b17023SJohn Marino bp_pack_value (bp, 0, 1);
112e4b17023SJohn Marino }
113e4b17023SJohn Marino
114e4b17023SJohn Marino
115e4b17023SJohn Marino /* Pack all the non-pointer fields of the TS_REAL_CST structure of
116e4b17023SJohn Marino expression EXPR into bitpack BP. */
117e4b17023SJohn Marino
118e4b17023SJohn Marino static void
pack_ts_real_cst_value_fields(struct bitpack_d * bp,tree expr)119e4b17023SJohn Marino pack_ts_real_cst_value_fields (struct bitpack_d *bp, tree expr)
120e4b17023SJohn Marino {
121e4b17023SJohn Marino unsigned i;
122e4b17023SJohn Marino REAL_VALUE_TYPE r;
123e4b17023SJohn Marino
124e4b17023SJohn Marino r = TREE_REAL_CST (expr);
125e4b17023SJohn Marino bp_pack_value (bp, r.cl, 2);
126e4b17023SJohn Marino bp_pack_value (bp, r.decimal, 1);
127e4b17023SJohn Marino bp_pack_value (bp, r.sign, 1);
128e4b17023SJohn Marino bp_pack_value (bp, r.signalling, 1);
129e4b17023SJohn Marino bp_pack_value (bp, r.canonical, 1);
130e4b17023SJohn Marino bp_pack_value (bp, r.uexp, EXP_BITS);
131e4b17023SJohn Marino for (i = 0; i < SIGSZ; i++)
132e4b17023SJohn Marino bp_pack_value (bp, r.sig[i], HOST_BITS_PER_LONG);
133e4b17023SJohn Marino }
134e4b17023SJohn Marino
135e4b17023SJohn Marino
136e4b17023SJohn Marino /* Pack all the non-pointer fields of the TS_FIXED_CST structure of
137e4b17023SJohn Marino expression EXPR into bitpack BP. */
138e4b17023SJohn Marino
139e4b17023SJohn Marino static void
pack_ts_fixed_cst_value_fields(struct bitpack_d * bp,tree expr)140e4b17023SJohn Marino pack_ts_fixed_cst_value_fields (struct bitpack_d *bp, tree expr)
141e4b17023SJohn Marino {
142e4b17023SJohn Marino struct fixed_value fv = TREE_FIXED_CST (expr);
143e4b17023SJohn Marino bp_pack_enum (bp, machine_mode, MAX_MACHINE_MODE, fv.mode);
144e4b17023SJohn Marino bp_pack_var_len_int (bp, fv.data.low);
145e4b17023SJohn Marino bp_pack_var_len_int (bp, fv.data.high);
146e4b17023SJohn Marino }
147e4b17023SJohn Marino
148e4b17023SJohn Marino
149e4b17023SJohn Marino /* Pack all the non-pointer fields of the TS_DECL_COMMON structure
150e4b17023SJohn Marino of expression EXPR into bitpack BP. */
151e4b17023SJohn Marino
152e4b17023SJohn Marino static void
pack_ts_decl_common_value_fields(struct bitpack_d * bp,tree expr)153e4b17023SJohn Marino pack_ts_decl_common_value_fields (struct bitpack_d *bp, tree expr)
154e4b17023SJohn Marino {
155e4b17023SJohn Marino bp_pack_enum (bp, machine_mode, MAX_MACHINE_MODE, DECL_MODE (expr));
156e4b17023SJohn Marino bp_pack_value (bp, DECL_NONLOCAL (expr), 1);
157e4b17023SJohn Marino bp_pack_value (bp, DECL_VIRTUAL_P (expr), 1);
158e4b17023SJohn Marino bp_pack_value (bp, DECL_IGNORED_P (expr), 1);
159e4b17023SJohn Marino bp_pack_value (bp, DECL_ABSTRACT (expr), 1);
160e4b17023SJohn Marino bp_pack_value (bp, DECL_ARTIFICIAL (expr), 1);
161e4b17023SJohn Marino bp_pack_value (bp, DECL_USER_ALIGN (expr), 1);
162e4b17023SJohn Marino bp_pack_value (bp, DECL_PRESERVE_P (expr), 1);
163e4b17023SJohn Marino bp_pack_value (bp, DECL_DEBUG_EXPR_IS_FROM (expr), 1);
164e4b17023SJohn Marino bp_pack_value (bp, DECL_EXTERNAL (expr), 1);
165e4b17023SJohn Marino bp_pack_value (bp, DECL_GIMPLE_REG_P (expr), 1);
166e4b17023SJohn Marino bp_pack_var_len_unsigned (bp, DECL_ALIGN (expr));
167e4b17023SJohn Marino
168e4b17023SJohn Marino if (TREE_CODE (expr) == LABEL_DECL)
169e4b17023SJohn Marino {
170e4b17023SJohn Marino /* Note that we do not write LABEL_DECL_UID. The reader will
171e4b17023SJohn Marino always assume an initial value of -1 so that the
172e4b17023SJohn Marino label_to_block_map is recreated by gimple_set_bb. */
173e4b17023SJohn Marino bp_pack_value (bp, DECL_ERROR_ISSUED (expr), 1);
174e4b17023SJohn Marino bp_pack_var_len_unsigned (bp, EH_LANDING_PAD_NR (expr));
175e4b17023SJohn Marino }
176e4b17023SJohn Marino
177e4b17023SJohn Marino if (TREE_CODE (expr) == FIELD_DECL)
178e4b17023SJohn Marino {
179e4b17023SJohn Marino bp_pack_value (bp, DECL_PACKED (expr), 1);
180e4b17023SJohn Marino bp_pack_value (bp, DECL_NONADDRESSABLE_P (expr), 1);
181e4b17023SJohn Marino bp_pack_value (bp, expr->decl_common.off_align, 8);
182e4b17023SJohn Marino }
183e4b17023SJohn Marino
184e4b17023SJohn Marino if (TREE_CODE (expr) == RESULT_DECL
185e4b17023SJohn Marino || TREE_CODE (expr) == PARM_DECL
186e4b17023SJohn Marino || TREE_CODE (expr) == VAR_DECL)
187e4b17023SJohn Marino {
188e4b17023SJohn Marino bp_pack_value (bp, DECL_BY_REFERENCE (expr), 1);
189e4b17023SJohn Marino if (TREE_CODE (expr) == VAR_DECL
190e4b17023SJohn Marino || TREE_CODE (expr) == PARM_DECL)
191e4b17023SJohn Marino bp_pack_value (bp, DECL_HAS_VALUE_EXPR_P (expr), 1);
192e4b17023SJohn Marino bp_pack_value (bp, DECL_RESTRICTED_P (expr), 1);
193e4b17023SJohn Marino }
194e4b17023SJohn Marino }
195e4b17023SJohn Marino
196e4b17023SJohn Marino
197e4b17023SJohn Marino /* Pack all the non-pointer fields of the TS_DECL_WRTL structure
198e4b17023SJohn Marino of expression EXPR into bitpack BP. */
199e4b17023SJohn Marino
200e4b17023SJohn Marino static void
pack_ts_decl_wrtl_value_fields(struct bitpack_d * bp,tree expr)201e4b17023SJohn Marino pack_ts_decl_wrtl_value_fields (struct bitpack_d *bp, tree expr)
202e4b17023SJohn Marino {
203e4b17023SJohn Marino bp_pack_value (bp, DECL_REGISTER (expr), 1);
204e4b17023SJohn Marino }
205e4b17023SJohn Marino
206e4b17023SJohn Marino
207e4b17023SJohn Marino /* Pack all the non-pointer fields of the TS_DECL_WITH_VIS structure
208e4b17023SJohn Marino of expression EXPR into bitpack BP. */
209e4b17023SJohn Marino
210e4b17023SJohn Marino static void
pack_ts_decl_with_vis_value_fields(struct bitpack_d * bp,tree expr)211e4b17023SJohn Marino pack_ts_decl_with_vis_value_fields (struct bitpack_d *bp, tree expr)
212e4b17023SJohn Marino {
213e4b17023SJohn Marino bp_pack_value (bp, DECL_DEFER_OUTPUT (expr), 1);
214e4b17023SJohn Marino bp_pack_value (bp, DECL_COMMON (expr), 1);
215e4b17023SJohn Marino bp_pack_value (bp, DECL_DLLIMPORT_P (expr), 1);
216e4b17023SJohn Marino bp_pack_value (bp, DECL_WEAK (expr), 1);
217e4b17023SJohn Marino bp_pack_value (bp, DECL_SEEN_IN_BIND_EXPR_P (expr), 1);
218e4b17023SJohn Marino bp_pack_value (bp, DECL_COMDAT (expr), 1);
219e4b17023SJohn Marino bp_pack_value (bp, DECL_VISIBILITY (expr), 2);
220e4b17023SJohn Marino bp_pack_value (bp, DECL_VISIBILITY_SPECIFIED (expr), 1);
221e4b17023SJohn Marino
222e4b17023SJohn Marino if (TREE_CODE (expr) == VAR_DECL)
223e4b17023SJohn Marino {
224e4b17023SJohn Marino bp_pack_value (bp, DECL_HARD_REGISTER (expr), 1);
225e4b17023SJohn Marino bp_pack_value (bp, DECL_IN_TEXT_SECTION (expr), 1);
226e4b17023SJohn Marino bp_pack_value (bp, DECL_IN_CONSTANT_POOL (expr), 1);
227e4b17023SJohn Marino bp_pack_value (bp, DECL_TLS_MODEL (expr), 3);
228e4b17023SJohn Marino }
229e4b17023SJohn Marino
230e4b17023SJohn Marino if (VAR_OR_FUNCTION_DECL_P (expr))
231e4b17023SJohn Marino bp_pack_var_len_unsigned (bp, DECL_INIT_PRIORITY (expr));
232e4b17023SJohn Marino }
233e4b17023SJohn Marino
234e4b17023SJohn Marino
235e4b17023SJohn Marino /* Pack all the non-pointer fields of the TS_FUNCTION_DECL structure
236e4b17023SJohn Marino of expression EXPR into bitpack BP. */
237e4b17023SJohn Marino
238e4b17023SJohn Marino static void
pack_ts_function_decl_value_fields(struct bitpack_d * bp,tree expr)239e4b17023SJohn Marino pack_ts_function_decl_value_fields (struct bitpack_d *bp, tree expr)
240e4b17023SJohn Marino {
241e4b17023SJohn Marino /* For normal/md builtins we only write the class and code, so they
242e4b17023SJohn Marino should never be handled here. */
243e4b17023SJohn Marino gcc_assert (!streamer_handle_as_builtin_p (expr));
244e4b17023SJohn Marino
245e4b17023SJohn Marino bp_pack_enum (bp, built_in_class, BUILT_IN_LAST,
246e4b17023SJohn Marino DECL_BUILT_IN_CLASS (expr));
247e4b17023SJohn Marino bp_pack_value (bp, DECL_STATIC_CONSTRUCTOR (expr), 1);
248e4b17023SJohn Marino bp_pack_value (bp, DECL_STATIC_DESTRUCTOR (expr), 1);
249e4b17023SJohn Marino bp_pack_value (bp, DECL_UNINLINABLE (expr), 1);
250e4b17023SJohn Marino bp_pack_value (bp, DECL_POSSIBLY_INLINED (expr), 1);
251e4b17023SJohn Marino bp_pack_value (bp, DECL_IS_NOVOPS (expr), 1);
252e4b17023SJohn Marino bp_pack_value (bp, DECL_IS_RETURNS_TWICE (expr), 1);
253e4b17023SJohn Marino bp_pack_value (bp, DECL_IS_MALLOC (expr), 1);
254e4b17023SJohn Marino bp_pack_value (bp, DECL_IS_OPERATOR_NEW (expr), 1);
255e4b17023SJohn Marino bp_pack_value (bp, DECL_DECLARED_INLINE_P (expr), 1);
256e4b17023SJohn Marino bp_pack_value (bp, DECL_STATIC_CHAIN (expr), 1);
257e4b17023SJohn Marino bp_pack_value (bp, DECL_NO_INLINE_WARNING_P (expr), 1);
258e4b17023SJohn Marino bp_pack_value (bp, DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (expr), 1);
259e4b17023SJohn Marino bp_pack_value (bp, DECL_NO_LIMIT_STACK (expr), 1);
260e4b17023SJohn Marino bp_pack_value (bp, DECL_DISREGARD_INLINE_LIMITS (expr), 1);
261e4b17023SJohn Marino bp_pack_value (bp, DECL_PURE_P (expr), 1);
262e4b17023SJohn Marino bp_pack_value (bp, DECL_LOOPING_CONST_OR_PURE_P (expr), 1);
263e4b17023SJohn Marino if (DECL_BUILT_IN_CLASS (expr) != NOT_BUILT_IN)
264e4b17023SJohn Marino bp_pack_value (bp, DECL_FUNCTION_CODE (expr), 11);
265e4b17023SJohn Marino if (DECL_STATIC_DESTRUCTOR (expr))
266e4b17023SJohn Marino bp_pack_var_len_unsigned (bp, DECL_FINI_PRIORITY (expr));
267e4b17023SJohn Marino }
268e4b17023SJohn Marino
269e4b17023SJohn Marino
270e4b17023SJohn Marino /* Pack all the non-pointer fields of the TS_TYPE_COMMON structure
271e4b17023SJohn Marino of expression EXPR into bitpack BP. */
272e4b17023SJohn Marino
273e4b17023SJohn Marino static void
pack_ts_type_common_value_fields(struct bitpack_d * bp,tree expr)274e4b17023SJohn Marino pack_ts_type_common_value_fields (struct bitpack_d *bp, tree expr)
275e4b17023SJohn Marino {
276e4b17023SJohn Marino bp_pack_enum (bp, machine_mode, MAX_MACHINE_MODE, TYPE_MODE (expr));
277e4b17023SJohn Marino bp_pack_value (bp, TYPE_STRING_FLAG (expr), 1);
278e4b17023SJohn Marino bp_pack_value (bp, TYPE_NO_FORCE_BLK (expr), 1);
279e4b17023SJohn Marino bp_pack_value (bp, TYPE_NEEDS_CONSTRUCTING (expr), 1);
280e4b17023SJohn Marino if (RECORD_OR_UNION_TYPE_P (expr))
281e4b17023SJohn Marino bp_pack_value (bp, TYPE_TRANSPARENT_AGGR (expr), 1);
282*5ce9237cSJohn Marino else if (TREE_CODE (expr) == ARRAY_TYPE)
283*5ce9237cSJohn Marino bp_pack_value (bp, TYPE_NONALIASED_COMPONENT (expr), 1);
284e4b17023SJohn Marino bp_pack_value (bp, TYPE_PACKED (expr), 1);
285e4b17023SJohn Marino bp_pack_value (bp, TYPE_RESTRICT (expr), 1);
286e4b17023SJohn Marino bp_pack_value (bp, TYPE_CONTAINS_PLACEHOLDER_INTERNAL (expr), 2);
287e4b17023SJohn Marino bp_pack_value (bp, TYPE_USER_ALIGN (expr), 1);
288e4b17023SJohn Marino bp_pack_value (bp, TYPE_READONLY (expr), 1);
289e4b17023SJohn Marino bp_pack_var_len_unsigned (bp, TYPE_PRECISION (expr));
290e4b17023SJohn Marino bp_pack_var_len_unsigned (bp, TYPE_ALIGN (expr));
291e4b17023SJohn Marino bp_pack_var_len_int (bp, TYPE_ALIAS_SET (expr) == 0 ? 0 : -1);
292e4b17023SJohn Marino }
293e4b17023SJohn Marino
294e4b17023SJohn Marino
295e4b17023SJohn Marino /* Pack all the non-pointer fields of the TS_BLOCK structure
296e4b17023SJohn Marino of expression EXPR into bitpack BP. */
297e4b17023SJohn Marino
298e4b17023SJohn Marino static void
pack_ts_block_value_fields(struct bitpack_d * bp,tree expr)299e4b17023SJohn Marino pack_ts_block_value_fields (struct bitpack_d *bp, tree expr)
300e4b17023SJohn Marino {
301e4b17023SJohn Marino bp_pack_value (bp, BLOCK_ABSTRACT (expr), 1);
302e4b17023SJohn Marino /* BLOCK_NUMBER is recomputed. */
303e4b17023SJohn Marino }
304e4b17023SJohn Marino
305e4b17023SJohn Marino /* Pack all the non-pointer fields of the TS_TRANSLATION_UNIT_DECL structure
306e4b17023SJohn Marino of expression EXPR into bitpack BP. */
307e4b17023SJohn Marino
308e4b17023SJohn Marino static void
pack_ts_translation_unit_decl_value_fields(struct bitpack_d * bp ATTRIBUTE_UNUSED,tree expr ATTRIBUTE_UNUSED)309e4b17023SJohn Marino pack_ts_translation_unit_decl_value_fields (struct bitpack_d *bp ATTRIBUTE_UNUSED, tree expr ATTRIBUTE_UNUSED)
310e4b17023SJohn Marino {
311e4b17023SJohn Marino }
312e4b17023SJohn Marino
313e4b17023SJohn Marino
314e4b17023SJohn Marino /* Pack all the bitfields in EXPR into a bit pack. */
315e4b17023SJohn Marino
316e4b17023SJohn Marino void
streamer_pack_tree_bitfields(struct bitpack_d * bp,tree expr)317e4b17023SJohn Marino streamer_pack_tree_bitfields (struct bitpack_d *bp, tree expr)
318e4b17023SJohn Marino {
319e4b17023SJohn Marino enum tree_code code;
320e4b17023SJohn Marino
321e4b17023SJohn Marino code = TREE_CODE (expr);
322e4b17023SJohn Marino
323e4b17023SJohn Marino /* Note that all these functions are highly sensitive to changes in
324e4b17023SJohn Marino the types and sizes of each of the fields being packed. */
325e4b17023SJohn Marino pack_ts_base_value_fields (bp, expr);
326e4b17023SJohn Marino
327e4b17023SJohn Marino if (CODE_CONTAINS_STRUCT (code, TS_REAL_CST))
328e4b17023SJohn Marino pack_ts_real_cst_value_fields (bp, expr);
329e4b17023SJohn Marino
330e4b17023SJohn Marino if (CODE_CONTAINS_STRUCT (code, TS_FIXED_CST))
331e4b17023SJohn Marino pack_ts_fixed_cst_value_fields (bp, expr);
332e4b17023SJohn Marino
333e4b17023SJohn Marino if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
334e4b17023SJohn Marino pack_ts_decl_common_value_fields (bp, expr);
335e4b17023SJohn Marino
336e4b17023SJohn Marino if (CODE_CONTAINS_STRUCT (code, TS_DECL_WRTL))
337e4b17023SJohn Marino pack_ts_decl_wrtl_value_fields (bp, expr);
338e4b17023SJohn Marino
339e4b17023SJohn Marino if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
340e4b17023SJohn Marino pack_ts_decl_with_vis_value_fields (bp, expr);
341e4b17023SJohn Marino
342e4b17023SJohn Marino if (CODE_CONTAINS_STRUCT (code, TS_FUNCTION_DECL))
343e4b17023SJohn Marino pack_ts_function_decl_value_fields (bp, expr);
344e4b17023SJohn Marino
345e4b17023SJohn Marino if (CODE_CONTAINS_STRUCT (code, TS_TYPE_COMMON))
346e4b17023SJohn Marino pack_ts_type_common_value_fields (bp, expr);
347e4b17023SJohn Marino
348e4b17023SJohn Marino if (CODE_CONTAINS_STRUCT (code, TS_BLOCK))
349e4b17023SJohn Marino pack_ts_block_value_fields (bp, expr);
350e4b17023SJohn Marino
351e4b17023SJohn Marino if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
352e4b17023SJohn Marino pack_ts_translation_unit_decl_value_fields (bp, expr);
353e4b17023SJohn Marino }
354e4b17023SJohn Marino
355e4b17023SJohn Marino
356e4b17023SJohn Marino /* Write the code and class of builtin EXPR to output block OB. IX is
357e4b17023SJohn Marino the index into the streamer cache where EXPR is stored.*/
358e4b17023SJohn Marino
359e4b17023SJohn Marino void
streamer_write_builtin(struct output_block * ob,tree expr)360e4b17023SJohn Marino streamer_write_builtin (struct output_block *ob, tree expr)
361e4b17023SJohn Marino {
362e4b17023SJohn Marino gcc_assert (streamer_handle_as_builtin_p (expr));
363e4b17023SJohn Marino
364e4b17023SJohn Marino if (DECL_BUILT_IN_CLASS (expr) == BUILT_IN_MD
365e4b17023SJohn Marino && !targetm.builtin_decl)
366e4b17023SJohn Marino sorry ("tree bytecode streams do not support machine specific builtin "
367e4b17023SJohn Marino "functions on this target");
368e4b17023SJohn Marino
369e4b17023SJohn Marino streamer_write_record_start (ob, LTO_builtin_decl);
370e4b17023SJohn Marino streamer_write_enum (ob->main_stream, built_in_class, BUILT_IN_LAST,
371e4b17023SJohn Marino DECL_BUILT_IN_CLASS (expr));
372e4b17023SJohn Marino streamer_write_uhwi (ob, DECL_FUNCTION_CODE (expr));
373e4b17023SJohn Marino
374e4b17023SJohn Marino if (DECL_ASSEMBLER_NAME_SET_P (expr))
375e4b17023SJohn Marino {
376e4b17023SJohn Marino /* When the assembler name of a builtin gets a user name,
377e4b17023SJohn Marino the new name is always prefixed with '*' by
378e4b17023SJohn Marino set_builtin_user_assembler_name. So, to prevent the
379e4b17023SJohn Marino reader side from adding a second '*', we omit it here. */
380e4b17023SJohn Marino const char *str = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (expr));
381e4b17023SJohn Marino if (strlen (str) > 1 && str[0] == '*')
382e4b17023SJohn Marino streamer_write_string (ob, ob->main_stream, &str[1], true);
383e4b17023SJohn Marino else
384e4b17023SJohn Marino streamer_write_string (ob, ob->main_stream, NULL, true);
385e4b17023SJohn Marino }
386e4b17023SJohn Marino else
387e4b17023SJohn Marino streamer_write_string (ob, ob->main_stream, NULL, true);
388e4b17023SJohn Marino }
389e4b17023SJohn Marino
390e4b17023SJohn Marino
391e4b17023SJohn Marino /* Emit the chain of tree nodes starting at T. OB is the output block
392e4b17023SJohn Marino to write to. REF_P is true if chain elements should be emitted
393e4b17023SJohn Marino as references. */
394e4b17023SJohn Marino
395e4b17023SJohn Marino void
streamer_write_chain(struct output_block * ob,tree t,bool ref_p)396e4b17023SJohn Marino streamer_write_chain (struct output_block *ob, tree t, bool ref_p)
397e4b17023SJohn Marino {
398e4b17023SJohn Marino int i, count;
399e4b17023SJohn Marino
400e4b17023SJohn Marino count = list_length (t);
401e4b17023SJohn Marino streamer_write_hwi (ob, count);
402e4b17023SJohn Marino for (i = 0; i < count; i++)
403e4b17023SJohn Marino {
404e4b17023SJohn Marino tree saved_chain;
405e4b17023SJohn Marino
406e4b17023SJohn Marino /* Clear TREE_CHAIN to avoid blindly recursing into the rest
407e4b17023SJohn Marino of the list. */
408e4b17023SJohn Marino saved_chain = TREE_CHAIN (t);
409e4b17023SJohn Marino TREE_CHAIN (t) = NULL_TREE;
410e4b17023SJohn Marino
411e4b17023SJohn Marino /* We avoid outputting external vars or functions by reference
412e4b17023SJohn Marino to the global decls section as we do not want to have them
413e4b17023SJohn Marino enter decl merging. This is, of course, only for the call
414e4b17023SJohn Marino for streaming BLOCK_VARS, but other callers are safe. */
415e4b17023SJohn Marino if (VAR_OR_FUNCTION_DECL_P (t)
416e4b17023SJohn Marino && DECL_EXTERNAL (t))
417e4b17023SJohn Marino stream_write_tree_shallow_non_ref (ob, t, ref_p);
418e4b17023SJohn Marino else
419e4b17023SJohn Marino stream_write_tree (ob, t, ref_p);
420e4b17023SJohn Marino
421e4b17023SJohn Marino TREE_CHAIN (t) = saved_chain;
422e4b17023SJohn Marino t = TREE_CHAIN (t);
423e4b17023SJohn Marino }
424e4b17023SJohn Marino }
425e4b17023SJohn Marino
426e4b17023SJohn Marino
427e4b17023SJohn Marino /* Write all pointer fields in the TS_COMMON structure of EXPR to output
428e4b17023SJohn Marino block OB. If REF_P is true, write a reference to EXPR's pointer
429e4b17023SJohn Marino fields. */
430e4b17023SJohn Marino
431e4b17023SJohn Marino static void
write_ts_common_tree_pointers(struct output_block * ob,tree expr,bool ref_p)432e4b17023SJohn Marino write_ts_common_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
433e4b17023SJohn Marino {
434e4b17023SJohn Marino if (TREE_CODE (expr) != IDENTIFIER_NODE)
435e4b17023SJohn Marino stream_write_tree (ob, TREE_TYPE (expr), ref_p);
436e4b17023SJohn Marino }
437e4b17023SJohn Marino
438e4b17023SJohn Marino
439e4b17023SJohn Marino /* Write all pointer fields in the TS_VECTOR structure of EXPR to output
440e4b17023SJohn Marino block OB. If REF_P is true, write a reference to EXPR's pointer
441e4b17023SJohn Marino fields. */
442e4b17023SJohn Marino
443e4b17023SJohn Marino static void
write_ts_vector_tree_pointers(struct output_block * ob,tree expr,bool ref_p)444e4b17023SJohn Marino write_ts_vector_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
445e4b17023SJohn Marino {
446e4b17023SJohn Marino streamer_write_chain (ob, TREE_VECTOR_CST_ELTS (expr), ref_p);
447e4b17023SJohn Marino }
448e4b17023SJohn Marino
449e4b17023SJohn Marino
450e4b17023SJohn Marino /* Write all pointer fields in the TS_COMPLEX structure of EXPR to output
451e4b17023SJohn Marino block OB. If REF_P is true, write a reference to EXPR's pointer
452e4b17023SJohn Marino fields. */
453e4b17023SJohn Marino
454e4b17023SJohn Marino static void
write_ts_complex_tree_pointers(struct output_block * ob,tree expr,bool ref_p)455e4b17023SJohn Marino write_ts_complex_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
456e4b17023SJohn Marino {
457e4b17023SJohn Marino stream_write_tree (ob, TREE_REALPART (expr), ref_p);
458e4b17023SJohn Marino stream_write_tree (ob, TREE_IMAGPART (expr), ref_p);
459e4b17023SJohn Marino }
460e4b17023SJohn Marino
461e4b17023SJohn Marino
462e4b17023SJohn Marino /* Write all pointer fields in the TS_DECL_MINIMAL structure of EXPR
463e4b17023SJohn Marino to output block OB. If REF_P is true, write a reference to EXPR's
464e4b17023SJohn Marino pointer fields. */
465e4b17023SJohn Marino
466e4b17023SJohn Marino static void
write_ts_decl_minimal_tree_pointers(struct output_block * ob,tree expr,bool ref_p)467e4b17023SJohn Marino write_ts_decl_minimal_tree_pointers (struct output_block *ob, tree expr,
468e4b17023SJohn Marino bool ref_p)
469e4b17023SJohn Marino {
470e4b17023SJohn Marino stream_write_tree (ob, DECL_NAME (expr), ref_p);
471e4b17023SJohn Marino stream_write_tree (ob, DECL_CONTEXT (expr), ref_p);
472e4b17023SJohn Marino lto_output_location (ob, DECL_SOURCE_LOCATION (expr));
473e4b17023SJohn Marino }
474e4b17023SJohn Marino
475e4b17023SJohn Marino
476e4b17023SJohn Marino /* Write all pointer fields in the TS_DECL_COMMON structure of EXPR to
477e4b17023SJohn Marino output block OB. If REF_P is true, write a reference to EXPR's
478e4b17023SJohn Marino pointer fields. */
479e4b17023SJohn Marino
480e4b17023SJohn Marino static void
write_ts_decl_common_tree_pointers(struct output_block * ob,tree expr,bool ref_p)481e4b17023SJohn Marino write_ts_decl_common_tree_pointers (struct output_block *ob, tree expr,
482e4b17023SJohn Marino bool ref_p)
483e4b17023SJohn Marino {
484e4b17023SJohn Marino stream_write_tree (ob, DECL_SIZE (expr), ref_p);
485e4b17023SJohn Marino stream_write_tree (ob, DECL_SIZE_UNIT (expr), ref_p);
486e4b17023SJohn Marino
487e4b17023SJohn Marino /* Note, DECL_INITIAL is not handled here. Since DECL_INITIAL needs
488e4b17023SJohn Marino special handling in LTO, it must be handled by streamer hooks. */
489e4b17023SJohn Marino
490e4b17023SJohn Marino stream_write_tree (ob, DECL_ATTRIBUTES (expr), ref_p);
491e4b17023SJohn Marino
492e4b17023SJohn Marino /* Do not stream DECL_ABSTRACT_ORIGIN. We cannot handle debug information
493e4b17023SJohn Marino for early inlining so drop it on the floor instead of ICEing in
494e4b17023SJohn Marino dwarf2out.c. */
495e4b17023SJohn Marino
496e4b17023SJohn Marino if (TREE_CODE (expr) == PARM_DECL)
497e4b17023SJohn Marino streamer_write_chain (ob, TREE_CHAIN (expr), ref_p);
498e4b17023SJohn Marino
499e4b17023SJohn Marino if ((TREE_CODE (expr) == VAR_DECL
500e4b17023SJohn Marino || TREE_CODE (expr) == PARM_DECL)
501e4b17023SJohn Marino && DECL_HAS_VALUE_EXPR_P (expr))
502e4b17023SJohn Marino stream_write_tree (ob, DECL_VALUE_EXPR (expr), ref_p);
503e4b17023SJohn Marino
504e4b17023SJohn Marino if (TREE_CODE (expr) == VAR_DECL)
505e4b17023SJohn Marino stream_write_tree (ob, DECL_DEBUG_EXPR (expr), ref_p);
506e4b17023SJohn Marino }
507e4b17023SJohn Marino
508e4b17023SJohn Marino
509e4b17023SJohn Marino /* Write all pointer fields in the TS_DECL_NON_COMMON structure of
510e4b17023SJohn Marino EXPR to output block OB. If REF_P is true, write a reference to EXPR's
511e4b17023SJohn Marino pointer fields. */
512e4b17023SJohn Marino
513e4b17023SJohn Marino static void
write_ts_decl_non_common_tree_pointers(struct output_block * ob,tree expr,bool ref_p)514e4b17023SJohn Marino write_ts_decl_non_common_tree_pointers (struct output_block *ob, tree expr,
515e4b17023SJohn Marino bool ref_p)
516e4b17023SJohn Marino {
517e4b17023SJohn Marino if (TREE_CODE (expr) == FUNCTION_DECL)
518e4b17023SJohn Marino {
519e4b17023SJohn Marino stream_write_tree (ob, DECL_ARGUMENTS (expr), ref_p);
520e4b17023SJohn Marino stream_write_tree (ob, DECL_RESULT (expr), ref_p);
521e4b17023SJohn Marino }
522e4b17023SJohn Marino else if (TREE_CODE (expr) == TYPE_DECL)
523e4b17023SJohn Marino stream_write_tree (ob, DECL_ORIGINAL_TYPE (expr), ref_p);
524e4b17023SJohn Marino stream_write_tree (ob, DECL_VINDEX (expr), ref_p);
525e4b17023SJohn Marino }
526e4b17023SJohn Marino
527e4b17023SJohn Marino
528e4b17023SJohn Marino /* Write all pointer fields in the TS_DECL_WITH_VIS structure of EXPR
529e4b17023SJohn Marino to output block OB. If REF_P is true, write a reference to EXPR's
530e4b17023SJohn Marino pointer fields. */
531e4b17023SJohn Marino
532e4b17023SJohn Marino static void
write_ts_decl_with_vis_tree_pointers(struct output_block * ob,tree expr,bool ref_p)533e4b17023SJohn Marino write_ts_decl_with_vis_tree_pointers (struct output_block *ob, tree expr,
534e4b17023SJohn Marino bool ref_p)
535e4b17023SJohn Marino {
536e4b17023SJohn Marino /* Make sure we don't inadvertently set the assembler name. */
537e4b17023SJohn Marino if (DECL_ASSEMBLER_NAME_SET_P (expr))
538e4b17023SJohn Marino stream_write_tree (ob, DECL_ASSEMBLER_NAME (expr), ref_p);
539e4b17023SJohn Marino else
540e4b17023SJohn Marino stream_write_tree (ob, NULL_TREE, false);
541e4b17023SJohn Marino
542e4b17023SJohn Marino stream_write_tree (ob, DECL_SECTION_NAME (expr), ref_p);
543e4b17023SJohn Marino stream_write_tree (ob, DECL_COMDAT_GROUP (expr), ref_p);
544e4b17023SJohn Marino }
545e4b17023SJohn Marino
546e4b17023SJohn Marino
547e4b17023SJohn Marino /* Write all pointer fields in the TS_FIELD_DECL structure of EXPR to
548e4b17023SJohn Marino output block OB. If REF_P is true, write a reference to EXPR's
549e4b17023SJohn Marino pointer fields. */
550e4b17023SJohn Marino
551e4b17023SJohn Marino static void
write_ts_field_decl_tree_pointers(struct output_block * ob,tree expr,bool ref_p)552e4b17023SJohn Marino write_ts_field_decl_tree_pointers (struct output_block *ob, tree expr,
553e4b17023SJohn Marino bool ref_p)
554e4b17023SJohn Marino {
555e4b17023SJohn Marino stream_write_tree (ob, DECL_FIELD_OFFSET (expr), ref_p);
556e4b17023SJohn Marino stream_write_tree (ob, DECL_BIT_FIELD_TYPE (expr), ref_p);
557e4b17023SJohn Marino stream_write_tree (ob, DECL_BIT_FIELD_REPRESENTATIVE (expr), ref_p);
558e4b17023SJohn Marino stream_write_tree (ob, DECL_FIELD_BIT_OFFSET (expr), ref_p);
559e4b17023SJohn Marino stream_write_tree (ob, DECL_FCONTEXT (expr), ref_p);
560e4b17023SJohn Marino }
561e4b17023SJohn Marino
562e4b17023SJohn Marino
563e4b17023SJohn Marino /* Write all pointer fields in the TS_FUNCTION_DECL structure of EXPR
564e4b17023SJohn Marino to output block OB. If REF_P is true, write a reference to EXPR's
565e4b17023SJohn Marino pointer fields. */
566e4b17023SJohn Marino
567e4b17023SJohn Marino static void
write_ts_function_decl_tree_pointers(struct output_block * ob,tree expr,bool ref_p)568e4b17023SJohn Marino write_ts_function_decl_tree_pointers (struct output_block *ob, tree expr,
569e4b17023SJohn Marino bool ref_p)
570e4b17023SJohn Marino {
571e4b17023SJohn Marino /* DECL_STRUCT_FUNCTION is handled by lto_output_function. FIXME lto,
572e4b17023SJohn Marino maybe it should be handled here? */
573e4b17023SJohn Marino stream_write_tree (ob, DECL_FUNCTION_PERSONALITY (expr), ref_p);
574e4b17023SJohn Marino stream_write_tree (ob, DECL_FUNCTION_SPECIFIC_TARGET (expr), ref_p);
575e4b17023SJohn Marino stream_write_tree (ob, DECL_FUNCTION_SPECIFIC_OPTIMIZATION (expr), ref_p);
576e4b17023SJohn Marino }
577e4b17023SJohn Marino
578e4b17023SJohn Marino
579e4b17023SJohn Marino /* Write all pointer fields in the TS_TYPE_COMMON structure of EXPR to
580e4b17023SJohn Marino output block OB. If REF_P is true, write a reference to EXPR's
581e4b17023SJohn Marino pointer fields. */
582e4b17023SJohn Marino
583e4b17023SJohn Marino static void
write_ts_type_common_tree_pointers(struct output_block * ob,tree expr,bool ref_p)584e4b17023SJohn Marino write_ts_type_common_tree_pointers (struct output_block *ob, tree expr,
585e4b17023SJohn Marino bool ref_p)
586e4b17023SJohn Marino {
587e4b17023SJohn Marino stream_write_tree (ob, TYPE_SIZE (expr), ref_p);
588e4b17023SJohn Marino stream_write_tree (ob, TYPE_SIZE_UNIT (expr), ref_p);
589e4b17023SJohn Marino stream_write_tree (ob, TYPE_ATTRIBUTES (expr), ref_p);
590e4b17023SJohn Marino stream_write_tree (ob, TYPE_NAME (expr), ref_p);
591e4b17023SJohn Marino /* Do not stream TYPE_POINTER_TO or TYPE_REFERENCE_TO. They will be
592e4b17023SJohn Marino reconstructed during fixup. */
593e4b17023SJohn Marino /* Do not stream TYPE_NEXT_VARIANT, we reconstruct the variant lists
594e4b17023SJohn Marino during fixup. */
595e4b17023SJohn Marino stream_write_tree (ob, TYPE_MAIN_VARIANT (expr), ref_p);
596e4b17023SJohn Marino stream_write_tree (ob, TYPE_CONTEXT (expr), ref_p);
597e4b17023SJohn Marino /* TYPE_CANONICAL is re-computed during type merging, so no need
598e4b17023SJohn Marino to stream it here. */
599e4b17023SJohn Marino stream_write_tree (ob, TYPE_STUB_DECL (expr), ref_p);
600e4b17023SJohn Marino }
601e4b17023SJohn Marino
602e4b17023SJohn Marino /* Write all pointer fields in the TS_TYPE_NON_COMMON structure of EXPR
603e4b17023SJohn Marino to output block OB. If REF_P is true, write a reference to EXPR's
604e4b17023SJohn Marino pointer fields. */
605e4b17023SJohn Marino
606e4b17023SJohn Marino static void
write_ts_type_non_common_tree_pointers(struct output_block * ob,tree expr,bool ref_p)607e4b17023SJohn Marino write_ts_type_non_common_tree_pointers (struct output_block *ob, tree expr,
608e4b17023SJohn Marino bool ref_p)
609e4b17023SJohn Marino {
610e4b17023SJohn Marino if (TREE_CODE (expr) == ENUMERAL_TYPE)
611e4b17023SJohn Marino stream_write_tree (ob, TYPE_VALUES (expr), ref_p);
612e4b17023SJohn Marino else if (TREE_CODE (expr) == ARRAY_TYPE)
613e4b17023SJohn Marino stream_write_tree (ob, TYPE_DOMAIN (expr), ref_p);
614e4b17023SJohn Marino else if (RECORD_OR_UNION_TYPE_P (expr))
615e4b17023SJohn Marino streamer_write_chain (ob, TYPE_FIELDS (expr), ref_p);
616e4b17023SJohn Marino else if (TREE_CODE (expr) == FUNCTION_TYPE
617e4b17023SJohn Marino || TREE_CODE (expr) == METHOD_TYPE)
618e4b17023SJohn Marino stream_write_tree (ob, TYPE_ARG_TYPES (expr), ref_p);
619e4b17023SJohn Marino
620e4b17023SJohn Marino if (!POINTER_TYPE_P (expr))
621e4b17023SJohn Marino stream_write_tree (ob, TYPE_MINVAL (expr), ref_p);
622e4b17023SJohn Marino stream_write_tree (ob, TYPE_MAXVAL (expr), ref_p);
623e4b17023SJohn Marino if (RECORD_OR_UNION_TYPE_P (expr))
624e4b17023SJohn Marino stream_write_tree (ob, TYPE_BINFO (expr), ref_p);
625e4b17023SJohn Marino }
626e4b17023SJohn Marino
627e4b17023SJohn Marino
628e4b17023SJohn Marino /* Write all pointer fields in the TS_LIST structure of EXPR to output
629e4b17023SJohn Marino block OB. If REF_P is true, write a reference to EXPR's pointer
630e4b17023SJohn Marino fields. */
631e4b17023SJohn Marino
632e4b17023SJohn Marino static void
write_ts_list_tree_pointers(struct output_block * ob,tree expr,bool ref_p)633e4b17023SJohn Marino write_ts_list_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
634e4b17023SJohn Marino {
635e4b17023SJohn Marino stream_write_tree (ob, TREE_PURPOSE (expr), ref_p);
636e4b17023SJohn Marino stream_write_tree (ob, TREE_VALUE (expr), ref_p);
637e4b17023SJohn Marino streamer_write_chain (ob, TREE_CHAIN (expr), ref_p);
638e4b17023SJohn Marino }
639e4b17023SJohn Marino
640e4b17023SJohn Marino
641e4b17023SJohn Marino /* Write all pointer fields in the TS_VEC structure of EXPR to output
642e4b17023SJohn Marino block OB. If REF_P is true, write a reference to EXPR's pointer
643e4b17023SJohn Marino fields. */
644e4b17023SJohn Marino
645e4b17023SJohn Marino static void
write_ts_vec_tree_pointers(struct output_block * ob,tree expr,bool ref_p)646e4b17023SJohn Marino write_ts_vec_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
647e4b17023SJohn Marino {
648e4b17023SJohn Marino int i;
649e4b17023SJohn Marino
650e4b17023SJohn Marino /* Note that the number of slots for EXPR has already been emitted
651e4b17023SJohn Marino in EXPR's header (see streamer_write_tree_header). */
652e4b17023SJohn Marino for (i = 0; i < TREE_VEC_LENGTH (expr); i++)
653e4b17023SJohn Marino stream_write_tree (ob, TREE_VEC_ELT (expr, i), ref_p);
654e4b17023SJohn Marino }
655e4b17023SJohn Marino
656e4b17023SJohn Marino
657e4b17023SJohn Marino /* Write all pointer fields in the TS_EXP structure of EXPR to output
658e4b17023SJohn Marino block OB. If REF_P is true, write a reference to EXPR's pointer
659e4b17023SJohn Marino fields. */
660e4b17023SJohn Marino
661e4b17023SJohn Marino static void
write_ts_exp_tree_pointers(struct output_block * ob,tree expr,bool ref_p)662e4b17023SJohn Marino write_ts_exp_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
663e4b17023SJohn Marino {
664e4b17023SJohn Marino int i;
665e4b17023SJohn Marino
666e4b17023SJohn Marino streamer_write_hwi (ob, TREE_OPERAND_LENGTH (expr));
667e4b17023SJohn Marino for (i = 0; i < TREE_OPERAND_LENGTH (expr); i++)
668e4b17023SJohn Marino stream_write_tree (ob, TREE_OPERAND (expr, i), ref_p);
669e4b17023SJohn Marino lto_output_location (ob, EXPR_LOCATION (expr));
670e4b17023SJohn Marino stream_write_tree (ob, TREE_BLOCK (expr), ref_p);
671e4b17023SJohn Marino }
672e4b17023SJohn Marino
673e4b17023SJohn Marino
674e4b17023SJohn Marino /* Write all pointer fields in the TS_BLOCK structure of EXPR to output
675e4b17023SJohn Marino block OB. If REF_P is true, write a reference to EXPR's pointer
676e4b17023SJohn Marino fields. */
677e4b17023SJohn Marino
678e4b17023SJohn Marino static void
write_ts_block_tree_pointers(struct output_block * ob,tree expr,bool ref_p)679e4b17023SJohn Marino write_ts_block_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
680e4b17023SJohn Marino {
681e4b17023SJohn Marino /* Do not stream BLOCK_SOURCE_LOCATION. We cannot handle debug information
682e4b17023SJohn Marino for early inlining so drop it on the floor instead of ICEing in
683e4b17023SJohn Marino dwarf2out.c. */
684e4b17023SJohn Marino streamer_write_chain (ob, BLOCK_VARS (expr), ref_p);
685e4b17023SJohn Marino
686e4b17023SJohn Marino /* Do not stream BLOCK_NONLOCALIZED_VARS. We cannot handle debug information
687e4b17023SJohn Marino for early inlining so drop it on the floor instead of ICEing in
688e4b17023SJohn Marino dwarf2out.c. */
689e4b17023SJohn Marino
690e4b17023SJohn Marino stream_write_tree (ob, BLOCK_SUPERCONTEXT (expr), ref_p);
691e4b17023SJohn Marino /* Do not stream BLOCK_ABSTRACT_ORIGIN. We cannot handle debug information
692e4b17023SJohn Marino for early inlining so drop it on the floor instead of ICEing in
693e4b17023SJohn Marino dwarf2out.c. */
694e4b17023SJohn Marino stream_write_tree (ob, BLOCK_FRAGMENT_ORIGIN (expr), ref_p);
695e4b17023SJohn Marino stream_write_tree (ob, BLOCK_FRAGMENT_CHAIN (expr), ref_p);
696e4b17023SJohn Marino /* Do not output BLOCK_SUBBLOCKS. Instead on streaming-in this
697e4b17023SJohn Marino list is re-constructed from BLOCK_SUPERCONTEXT. */
698e4b17023SJohn Marino }
699e4b17023SJohn Marino
700e4b17023SJohn Marino
701e4b17023SJohn Marino /* Write all pointer fields in the TS_BINFO structure of EXPR to output
702e4b17023SJohn Marino block OB. If REF_P is true, write a reference to EXPR's pointer
703e4b17023SJohn Marino fields. */
704e4b17023SJohn Marino
705e4b17023SJohn Marino static void
write_ts_binfo_tree_pointers(struct output_block * ob,tree expr,bool ref_p)706e4b17023SJohn Marino write_ts_binfo_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
707e4b17023SJohn Marino {
708e4b17023SJohn Marino unsigned i;
709e4b17023SJohn Marino tree t;
710e4b17023SJohn Marino
711e4b17023SJohn Marino /* Note that the number of BINFO slots has already been emitted in
712e4b17023SJohn Marino EXPR's header (see streamer_write_tree_header) because this length
713e4b17023SJohn Marino is needed to build the empty BINFO node on the reader side. */
714e4b17023SJohn Marino FOR_EACH_VEC_ELT (tree, BINFO_BASE_BINFOS (expr), i, t)
715e4b17023SJohn Marino stream_write_tree (ob, t, ref_p);
716e4b17023SJohn Marino stream_write_tree (ob, NULL_TREE, false);
717e4b17023SJohn Marino
718e4b17023SJohn Marino stream_write_tree (ob, BINFO_OFFSET (expr), ref_p);
719e4b17023SJohn Marino stream_write_tree (ob, BINFO_VTABLE (expr), ref_p);
720e4b17023SJohn Marino stream_write_tree (ob, BINFO_VPTR_FIELD (expr), ref_p);
721e4b17023SJohn Marino
722e4b17023SJohn Marino streamer_write_uhwi (ob, VEC_length (tree, BINFO_BASE_ACCESSES (expr)));
723e4b17023SJohn Marino FOR_EACH_VEC_ELT (tree, BINFO_BASE_ACCESSES (expr), i, t)
724e4b17023SJohn Marino stream_write_tree (ob, t, ref_p);
725e4b17023SJohn Marino
726e4b17023SJohn Marino stream_write_tree (ob, BINFO_INHERITANCE_CHAIN (expr), ref_p);
727e4b17023SJohn Marino stream_write_tree (ob, BINFO_SUBVTT_INDEX (expr), ref_p);
728e4b17023SJohn Marino stream_write_tree (ob, BINFO_VPTR_INDEX (expr), ref_p);
729e4b17023SJohn Marino }
730e4b17023SJohn Marino
731e4b17023SJohn Marino
732e4b17023SJohn Marino /* Write all pointer fields in the TS_CONSTRUCTOR structure of EXPR to
733e4b17023SJohn Marino output block OB. If REF_P is true, write a reference to EXPR's
734e4b17023SJohn Marino pointer fields. */
735e4b17023SJohn Marino
736e4b17023SJohn Marino static void
write_ts_constructor_tree_pointers(struct output_block * ob,tree expr,bool ref_p)737e4b17023SJohn Marino write_ts_constructor_tree_pointers (struct output_block *ob, tree expr,
738e4b17023SJohn Marino bool ref_p)
739e4b17023SJohn Marino {
740e4b17023SJohn Marino unsigned i;
741e4b17023SJohn Marino tree index, value;
742e4b17023SJohn Marino
743e4b17023SJohn Marino streamer_write_uhwi (ob, CONSTRUCTOR_NELTS (expr));
744e4b17023SJohn Marino FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (expr), i, index, value)
745e4b17023SJohn Marino {
746e4b17023SJohn Marino stream_write_tree (ob, index, ref_p);
747e4b17023SJohn Marino stream_write_tree (ob, value, ref_p);
748e4b17023SJohn Marino }
749e4b17023SJohn Marino }
750e4b17023SJohn Marino
751e4b17023SJohn Marino /* Write a TS_TARGET_OPTION tree in EXPR to OB. */
752e4b17023SJohn Marino
753e4b17023SJohn Marino static void
write_ts_target_option(struct output_block * ob,tree expr)754e4b17023SJohn Marino write_ts_target_option (struct output_block *ob, tree expr)
755e4b17023SJohn Marino {
756e4b17023SJohn Marino struct cl_target_option *t = TREE_TARGET_OPTION (expr);
757e4b17023SJohn Marino struct bitpack_d bp;
758e4b17023SJohn Marino unsigned i, len;
759e4b17023SJohn Marino
760e4b17023SJohn Marino /* The cl_target_option is target specific and generated by the options
761e4b17023SJohn Marino awk script, so we just recreate a byte-by-byte copy here. */
762e4b17023SJohn Marino
763e4b17023SJohn Marino bp = bitpack_create (ob->main_stream);
764e4b17023SJohn Marino len = sizeof (struct cl_target_option);
765e4b17023SJohn Marino for (i = 0; i < len; i++)
766e4b17023SJohn Marino bp_pack_value (&bp, ((unsigned char *)t)[i], 8);
767e4b17023SJohn Marino /* Catch struct size mismatches between reader and writer. */
768e4b17023SJohn Marino bp_pack_value (&bp, 0x12345678, 32);
769e4b17023SJohn Marino streamer_write_bitpack (&bp);
770e4b17023SJohn Marino }
771e4b17023SJohn Marino
772e4b17023SJohn Marino /* Write a TS_OPTIMIZATION tree in EXPR to OB. */
773e4b17023SJohn Marino
774e4b17023SJohn Marino static void
write_ts_optimization(struct output_block * ob,tree expr)775e4b17023SJohn Marino write_ts_optimization (struct output_block *ob, tree expr)
776e4b17023SJohn Marino {
777e4b17023SJohn Marino struct cl_optimization *t = TREE_OPTIMIZATION (expr);
778e4b17023SJohn Marino struct bitpack_d bp;
779e4b17023SJohn Marino unsigned i, len;
780e4b17023SJohn Marino
781e4b17023SJohn Marino /* The cl_optimization is generated by the options
782e4b17023SJohn Marino awk script, so we just recreate a byte-by-byte copy here. */
783e4b17023SJohn Marino
784e4b17023SJohn Marino bp = bitpack_create (ob->main_stream);
785e4b17023SJohn Marino len = sizeof (struct cl_optimization);
786e4b17023SJohn Marino for (i = 0; i < len; i++)
787e4b17023SJohn Marino bp_pack_value (&bp, ((unsigned char *)t)[i], 8);
788e4b17023SJohn Marino /* Catch struct size mismatches between reader and writer. */
789e4b17023SJohn Marino bp_pack_value (&bp, 0x12345678, 32);
790e4b17023SJohn Marino streamer_write_bitpack (&bp);
791e4b17023SJohn Marino }
792e4b17023SJohn Marino
793e4b17023SJohn Marino /* Write a TS_TRANSLATION_UNIT_DECL tree in EXPR to OB. */
794e4b17023SJohn Marino
795e4b17023SJohn Marino static void
write_ts_translation_unit_decl_tree_pointers(struct output_block * ob,tree expr)796e4b17023SJohn Marino write_ts_translation_unit_decl_tree_pointers (struct output_block *ob,
797e4b17023SJohn Marino tree expr)
798e4b17023SJohn Marino {
799e4b17023SJohn Marino streamer_write_string (ob, ob->main_stream,
800e4b17023SJohn Marino TRANSLATION_UNIT_LANGUAGE (expr), true);
801e4b17023SJohn Marino }
802e4b17023SJohn Marino
803e4b17023SJohn Marino /* Write all pointer fields in EXPR to output block OB. If REF_P is true,
804e4b17023SJohn Marino the leaves of EXPR are emitted as references. */
805e4b17023SJohn Marino
806e4b17023SJohn Marino void
streamer_write_tree_body(struct output_block * ob,tree expr,bool ref_p)807e4b17023SJohn Marino streamer_write_tree_body (struct output_block *ob, tree expr, bool ref_p)
808e4b17023SJohn Marino {
809e4b17023SJohn Marino enum tree_code code;
810e4b17023SJohn Marino
811e4b17023SJohn Marino code = TREE_CODE (expr);
812e4b17023SJohn Marino
813e4b17023SJohn Marino if (CODE_CONTAINS_STRUCT (code, TS_TYPED))
814e4b17023SJohn Marino write_ts_common_tree_pointers (ob, expr, ref_p);
815e4b17023SJohn Marino
816e4b17023SJohn Marino if (CODE_CONTAINS_STRUCT (code, TS_VECTOR))
817e4b17023SJohn Marino write_ts_vector_tree_pointers (ob, expr, ref_p);
818e4b17023SJohn Marino
819e4b17023SJohn Marino if (CODE_CONTAINS_STRUCT (code, TS_COMPLEX))
820e4b17023SJohn Marino write_ts_complex_tree_pointers (ob, expr, ref_p);
821e4b17023SJohn Marino
822e4b17023SJohn Marino if (CODE_CONTAINS_STRUCT (code, TS_DECL_MINIMAL))
823e4b17023SJohn Marino write_ts_decl_minimal_tree_pointers (ob, expr, ref_p);
824e4b17023SJohn Marino
825e4b17023SJohn Marino if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
826e4b17023SJohn Marino write_ts_decl_common_tree_pointers (ob, expr, ref_p);
827e4b17023SJohn Marino
828e4b17023SJohn Marino if (CODE_CONTAINS_STRUCT (code, TS_DECL_NON_COMMON))
829e4b17023SJohn Marino write_ts_decl_non_common_tree_pointers (ob, expr, ref_p);
830e4b17023SJohn Marino
831e4b17023SJohn Marino if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
832e4b17023SJohn Marino write_ts_decl_with_vis_tree_pointers (ob, expr, ref_p);
833e4b17023SJohn Marino
834e4b17023SJohn Marino if (CODE_CONTAINS_STRUCT (code, TS_FIELD_DECL))
835e4b17023SJohn Marino write_ts_field_decl_tree_pointers (ob, expr, ref_p);
836e4b17023SJohn Marino
837e4b17023SJohn Marino if (CODE_CONTAINS_STRUCT (code, TS_FUNCTION_DECL))
838e4b17023SJohn Marino write_ts_function_decl_tree_pointers (ob, expr, ref_p);
839e4b17023SJohn Marino
840e4b17023SJohn Marino if (CODE_CONTAINS_STRUCT (code, TS_TYPE_COMMON))
841e4b17023SJohn Marino write_ts_type_common_tree_pointers (ob, expr, ref_p);
842e4b17023SJohn Marino
843e4b17023SJohn Marino if (CODE_CONTAINS_STRUCT (code, TS_TYPE_NON_COMMON))
844e4b17023SJohn Marino write_ts_type_non_common_tree_pointers (ob, expr, ref_p);
845e4b17023SJohn Marino
846e4b17023SJohn Marino if (CODE_CONTAINS_STRUCT (code, TS_LIST))
847e4b17023SJohn Marino write_ts_list_tree_pointers (ob, expr, ref_p);
848e4b17023SJohn Marino
849e4b17023SJohn Marino if (CODE_CONTAINS_STRUCT (code, TS_VEC))
850e4b17023SJohn Marino write_ts_vec_tree_pointers (ob, expr, ref_p);
851e4b17023SJohn Marino
852e4b17023SJohn Marino if (CODE_CONTAINS_STRUCT (code, TS_EXP))
853e4b17023SJohn Marino write_ts_exp_tree_pointers (ob, expr, ref_p);
854e4b17023SJohn Marino
855e4b17023SJohn Marino if (CODE_CONTAINS_STRUCT (code, TS_BLOCK))
856e4b17023SJohn Marino write_ts_block_tree_pointers (ob, expr, ref_p);
857e4b17023SJohn Marino
858e4b17023SJohn Marino if (CODE_CONTAINS_STRUCT (code, TS_BINFO))
859e4b17023SJohn Marino write_ts_binfo_tree_pointers (ob, expr, ref_p);
860e4b17023SJohn Marino
861e4b17023SJohn Marino if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
862e4b17023SJohn Marino write_ts_constructor_tree_pointers (ob, expr, ref_p);
863e4b17023SJohn Marino
864e4b17023SJohn Marino if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
865e4b17023SJohn Marino write_ts_target_option (ob, expr);
866e4b17023SJohn Marino
867e4b17023SJohn Marino if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
868e4b17023SJohn Marino write_ts_optimization (ob, expr);
869e4b17023SJohn Marino
870e4b17023SJohn Marino if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
871e4b17023SJohn Marino write_ts_translation_unit_decl_tree_pointers (ob, expr);
872e4b17023SJohn Marino }
873e4b17023SJohn Marino
874e4b17023SJohn Marino
875e4b17023SJohn Marino /* Emit header information for tree EXPR to output block OB. The header
876e4b17023SJohn Marino contains everything needed to instantiate an empty skeleton for
877e4b17023SJohn Marino EXPR on the reading side. IX is the index into the streamer cache
878e4b17023SJohn Marino where EXPR is stored. */
879e4b17023SJohn Marino
880e4b17023SJohn Marino void
streamer_write_tree_header(struct output_block * ob,tree expr)881e4b17023SJohn Marino streamer_write_tree_header (struct output_block *ob, tree expr)
882e4b17023SJohn Marino {
883e4b17023SJohn Marino enum LTO_tags tag;
884e4b17023SJohn Marino enum tree_code code;
885e4b17023SJohn Marino
886e4b17023SJohn Marino /* We should not see any tree nodes not handled by the streamer. */
887e4b17023SJohn Marino code = TREE_CODE (expr);
888e4b17023SJohn Marino
889e4b17023SJohn Marino /* The header of a tree node consists of its tag, the size of
890e4b17023SJohn Marino the node, and any other information needed to instantiate
891e4b17023SJohn Marino EXPR on the reading side (such as the number of slots in
892e4b17023SJohn Marino variable sized nodes). */
893e4b17023SJohn Marino tag = lto_tree_code_to_tag (code);
894e4b17023SJohn Marino streamer_write_record_start (ob, tag);
895e4b17023SJohn Marino
896e4b17023SJohn Marino /* The following will cause bootstrap miscomparisons. Enable with care. */
897e4b17023SJohn Marino #ifdef LTO_STREAMER_DEBUG
898e4b17023SJohn Marino /* This is used mainly for debugging purposes. When the reader
899e4b17023SJohn Marino and the writer do not agree on a streamed node, the pointer
900e4b17023SJohn Marino value for EXPR can be used to track down the differences in
901e4b17023SJohn Marino the debugger. */
902e4b17023SJohn Marino gcc_assert ((HOST_WIDEST_INT) (intptr_t) expr == (intptr_t) expr);
903e4b17023SJohn Marino streamer_write_hwi (ob, (HOST_WIDEST_INT) (intptr_t) expr);
904e4b17023SJohn Marino #endif
905e4b17023SJohn Marino
906e4b17023SJohn Marino /* The text in strings and identifiers are completely emitted in
907e4b17023SJohn Marino the header. */
908e4b17023SJohn Marino if (CODE_CONTAINS_STRUCT (code, TS_STRING))
909e4b17023SJohn Marino streamer_write_string_cst (ob, ob->main_stream, expr);
910e4b17023SJohn Marino else if (CODE_CONTAINS_STRUCT (code, TS_IDENTIFIER))
911e4b17023SJohn Marino write_identifier (ob, ob->main_stream, expr);
912e4b17023SJohn Marino else if (CODE_CONTAINS_STRUCT (code, TS_VEC))
913e4b17023SJohn Marino streamer_write_hwi (ob, TREE_VEC_LENGTH (expr));
914e4b17023SJohn Marino else if (CODE_CONTAINS_STRUCT (code, TS_BINFO))
915e4b17023SJohn Marino streamer_write_uhwi (ob, BINFO_N_BASE_BINFOS (expr));
916e4b17023SJohn Marino else if (TREE_CODE (expr) == CALL_EXPR)
917e4b17023SJohn Marino streamer_write_uhwi (ob, call_expr_nargs (expr));
918e4b17023SJohn Marino }
919e4b17023SJohn Marino
920e4b17023SJohn Marino
921e4b17023SJohn Marino /* Emit the integer constant CST to output block OB. If REF_P is true,
922e4b17023SJohn Marino CST's type will be emitted as a reference. */
923e4b17023SJohn Marino
924e4b17023SJohn Marino void
streamer_write_integer_cst(struct output_block * ob,tree cst,bool ref_p)925e4b17023SJohn Marino streamer_write_integer_cst (struct output_block *ob, tree cst, bool ref_p)
926e4b17023SJohn Marino {
927e4b17023SJohn Marino streamer_write_record_start (ob, lto_tree_code_to_tag (INTEGER_CST));
928e4b17023SJohn Marino stream_write_tree (ob, TREE_TYPE (cst), ref_p);
929e4b17023SJohn Marino streamer_write_char_stream (ob->main_stream, TREE_OVERFLOW_P (cst));
930e4b17023SJohn Marino streamer_write_uhwi (ob, TREE_INT_CST_LOW (cst));
931e4b17023SJohn Marino streamer_write_uhwi (ob, TREE_INT_CST_HIGH (cst));
932e4b17023SJohn Marino }
933