110d565efSmrg /* Routines for emitting trees to a file stream.
210d565efSmrg
3*ec02198aSmrg Copyright (C) 2011-2020 Free Software Foundation, Inc.
410d565efSmrg Contributed by Diego Novillo <dnovillo@google.com>
510d565efSmrg
610d565efSmrg This file is part of GCC.
710d565efSmrg
810d565efSmrg GCC is free software; you can redistribute it and/or modify it under
910d565efSmrg the terms of the GNU General Public License as published by the Free
1010d565efSmrg Software Foundation; either version 3, or (at your option) any later
1110d565efSmrg version.
1210d565efSmrg
1310d565efSmrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
1410d565efSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
1510d565efSmrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1610d565efSmrg for more details.
1710d565efSmrg
1810d565efSmrg You should have received a copy of the GNU General Public License
1910d565efSmrg along with GCC; see the file COPYING3. If not see
2010d565efSmrg <http://www.gnu.org/licenses/>. */
2110d565efSmrg
2210d565efSmrg #include "config.h"
2310d565efSmrg #include "system.h"
2410d565efSmrg #include "coretypes.h"
2510d565efSmrg #include "backend.h"
2610d565efSmrg #include "target.h"
2710d565efSmrg #include "tree.h"
2810d565efSmrg #include "gimple.h"
2910d565efSmrg #include "tree-streamer.h"
3010d565efSmrg #include "cgraph.h"
3110d565efSmrg #include "alias.h"
3210d565efSmrg #include "stor-layout.h"
3310d565efSmrg #include "gomp-constants.h"
3410d565efSmrg
3510d565efSmrg
3610d565efSmrg /* Output the STRING constant to the string
3710d565efSmrg table in OB. Then put the index onto the INDEX_STREAM. */
3810d565efSmrg
3910d565efSmrg void
streamer_write_string_cst(struct output_block * ob,struct lto_output_stream * index_stream,tree string)4010d565efSmrg streamer_write_string_cst (struct output_block *ob,
4110d565efSmrg struct lto_output_stream *index_stream,
4210d565efSmrg tree string)
4310d565efSmrg {
4410d565efSmrg streamer_write_string_with_length (ob, index_stream,
4510d565efSmrg string ? TREE_STRING_POINTER (string)
4610d565efSmrg : NULL,
4710d565efSmrg string ? TREE_STRING_LENGTH (string) : 0,
4810d565efSmrg true);
4910d565efSmrg }
5010d565efSmrg
5110d565efSmrg
5210d565efSmrg /* Output the identifier ID to the string
5310d565efSmrg table in OB. Then put the index onto the INDEX_STREAM. */
5410d565efSmrg
5510d565efSmrg static void
write_identifier(struct output_block * ob,struct lto_output_stream * index_stream,tree id)5610d565efSmrg write_identifier (struct output_block *ob,
5710d565efSmrg struct lto_output_stream *index_stream,
5810d565efSmrg tree id)
5910d565efSmrg {
6010d565efSmrg streamer_write_string_with_length (ob, index_stream,
6110d565efSmrg IDENTIFIER_POINTER (id),
6210d565efSmrg IDENTIFIER_LENGTH (id),
6310d565efSmrg true);
6410d565efSmrg }
6510d565efSmrg
6610d565efSmrg
6710d565efSmrg /* Pack all the non-pointer fields of the TS_BASE structure of
6810d565efSmrg expression EXPR into bitpack BP. */
6910d565efSmrg
7010d565efSmrg static inline void
pack_ts_base_value_fields(struct bitpack_d * bp,tree expr)7110d565efSmrg pack_ts_base_value_fields (struct bitpack_d *bp, tree expr)
7210d565efSmrg {
73*ec02198aSmrg if (streamer_debugging)
7410d565efSmrg bp_pack_value (bp, TREE_CODE (expr), 16);
7510d565efSmrg if (!TYPE_P (expr))
7610d565efSmrg {
7710d565efSmrg bp_pack_value (bp, TREE_SIDE_EFFECTS (expr), 1);
7810d565efSmrg bp_pack_value (bp, TREE_CONSTANT (expr), 1);
7910d565efSmrg bp_pack_value (bp, TREE_READONLY (expr), 1);
8010d565efSmrg
8110d565efSmrg /* TREE_PUBLIC is used on types to indicate that the type
8210d565efSmrg has a TYPE_CACHED_VALUES vector. This is not streamed out,
8310d565efSmrg so we skip it here. */
8410d565efSmrg bp_pack_value (bp, TREE_PUBLIC (expr), 1);
8510d565efSmrg }
8610d565efSmrg else
8710d565efSmrg bp_pack_value (bp, 0, 4);
8810d565efSmrg bp_pack_value (bp, TREE_ADDRESSABLE (expr), 1);
8910d565efSmrg bp_pack_value (bp, TREE_THIS_VOLATILE (expr), 1);
9010d565efSmrg if (DECL_P (expr))
9110d565efSmrg {
9210d565efSmrg bp_pack_value (bp, DECL_UNSIGNED (expr), 1);
9310d565efSmrg bp_pack_value (bp, DECL_NAMELESS (expr), 1);
9410d565efSmrg }
9510d565efSmrg else if (TYPE_P (expr))
9610d565efSmrg bp_pack_value (bp, TYPE_UNSIGNED (expr), 1);
9710d565efSmrg else
9810d565efSmrg bp_pack_value (bp, 0, 1);
9910d565efSmrg /* We write debug info two times, do not confuse the second one.
10010d565efSmrg The only relevant TREE_ASM_WRITTEN use is on SSA names. */
10110d565efSmrg bp_pack_value (bp, (TREE_CODE (expr) != SSA_NAME
10210d565efSmrg ? 0 : TREE_ASM_WRITTEN (expr)), 1);
10310d565efSmrg if (TYPE_P (expr))
10410d565efSmrg bp_pack_value (bp, TYPE_ARTIFICIAL (expr), 1);
10510d565efSmrg else
10610d565efSmrg bp_pack_value (bp, TREE_NO_WARNING (expr), 1);
10710d565efSmrg bp_pack_value (bp, TREE_NOTHROW (expr), 1);
10810d565efSmrg bp_pack_value (bp, TREE_STATIC (expr), 1);
10910d565efSmrg if (TREE_CODE (expr) != TREE_BINFO)
11010d565efSmrg bp_pack_value (bp, TREE_PRIVATE (expr), 1);
11110d565efSmrg else
11210d565efSmrg bp_pack_value (bp, 0, 1);
11310d565efSmrg bp_pack_value (bp, TREE_PROTECTED (expr), 1);
11410d565efSmrg bp_pack_value (bp, TREE_DEPRECATED (expr), 1);
11510d565efSmrg if (TYPE_P (expr))
11610d565efSmrg {
11710d565efSmrg if (AGGREGATE_TYPE_P (expr))
11810d565efSmrg bp_pack_value (bp, TYPE_REVERSE_STORAGE_ORDER (expr), 1);
11910d565efSmrg else
12010d565efSmrg bp_pack_value (bp, TYPE_SATURATING (expr), 1);
12110d565efSmrg bp_pack_value (bp, TYPE_ADDR_SPACE (expr), 8);
12210d565efSmrg }
12310d565efSmrg else if (TREE_CODE (expr) == BIT_FIELD_REF || TREE_CODE (expr) == MEM_REF)
12410d565efSmrg {
12510d565efSmrg bp_pack_value (bp, REF_REVERSE_STORAGE_ORDER (expr), 1);
12610d565efSmrg bp_pack_value (bp, 0, 8);
12710d565efSmrg }
12810d565efSmrg else if (TREE_CODE (expr) == SSA_NAME)
12910d565efSmrg {
13010d565efSmrg bp_pack_value (bp, SSA_NAME_IS_DEFAULT_DEF (expr), 1);
13110d565efSmrg bp_pack_value (bp, 0, 8);
13210d565efSmrg }
133c7a68eb7Smrg else if (TREE_CODE (expr) == CALL_EXPR)
134c7a68eb7Smrg {
135c7a68eb7Smrg bp_pack_value (bp, CALL_EXPR_BY_DESCRIPTOR (expr), 1);
136c7a68eb7Smrg bp_pack_value (bp, 0, 8);
137c7a68eb7Smrg }
13810d565efSmrg else
13910d565efSmrg bp_pack_value (bp, 0, 9);
14010d565efSmrg }
14110d565efSmrg
14210d565efSmrg
14310d565efSmrg /* Pack all the non-pointer fields of the TS_INTEGER_CST structure of
14410d565efSmrg expression EXPR into bitpack BP. */
14510d565efSmrg
14610d565efSmrg static void
pack_ts_int_cst_value_fields(struct bitpack_d * bp,tree expr)14710d565efSmrg pack_ts_int_cst_value_fields (struct bitpack_d *bp, tree expr)
14810d565efSmrg {
14910d565efSmrg int i;
15010d565efSmrg /* Note that the number of elements has already been written out in
15110d565efSmrg streamer_write_tree_header. */
15210d565efSmrg for (i = 0; i < TREE_INT_CST_EXT_NUNITS (expr); i++)
15310d565efSmrg bp_pack_var_len_int (bp, TREE_INT_CST_ELT (expr, i));
15410d565efSmrg }
15510d565efSmrg
15610d565efSmrg
15710d565efSmrg /* Pack all the non-pointer fields of the TS_REAL_CST structure of
15810d565efSmrg expression EXPR into bitpack BP. */
15910d565efSmrg
16010d565efSmrg static void
pack_ts_real_cst_value_fields(struct bitpack_d * bp,tree expr)16110d565efSmrg pack_ts_real_cst_value_fields (struct bitpack_d *bp, tree expr)
16210d565efSmrg {
16310d565efSmrg unsigned i;
16410d565efSmrg REAL_VALUE_TYPE r;
16510d565efSmrg
16610d565efSmrg r = TREE_REAL_CST (expr);
16710d565efSmrg bp_pack_value (bp, r.cl, 2);
16810d565efSmrg bp_pack_value (bp, r.decimal, 1);
16910d565efSmrg bp_pack_value (bp, r.sign, 1);
17010d565efSmrg bp_pack_value (bp, r.signalling, 1);
17110d565efSmrg bp_pack_value (bp, r.canonical, 1);
17210d565efSmrg bp_pack_value (bp, r.uexp, EXP_BITS);
17310d565efSmrg for (i = 0; i < SIGSZ; i++)
17410d565efSmrg bp_pack_value (bp, r.sig[i], HOST_BITS_PER_LONG);
17510d565efSmrg }
17610d565efSmrg
17710d565efSmrg
17810d565efSmrg /* Pack all the non-pointer fields of the TS_FIXED_CST structure of
17910d565efSmrg expression EXPR into bitpack BP. */
18010d565efSmrg
18110d565efSmrg static void
pack_ts_fixed_cst_value_fields(struct bitpack_d * bp,tree expr)18210d565efSmrg pack_ts_fixed_cst_value_fields (struct bitpack_d *bp, tree expr)
18310d565efSmrg {
18410d565efSmrg struct fixed_value fv = TREE_FIXED_CST (expr);
18510d565efSmrg bp_pack_machine_mode (bp, fv.mode);
18610d565efSmrg bp_pack_var_len_int (bp, fv.data.low);
18710d565efSmrg bp_pack_var_len_int (bp, fv.data.high);
18810d565efSmrg }
18910d565efSmrg
19010d565efSmrg /* Pack all the non-pointer fields of the TS_DECL_COMMON structure
19110d565efSmrg of expression EXPR into bitpack BP. */
19210d565efSmrg
19310d565efSmrg static void
pack_ts_decl_common_value_fields(struct bitpack_d * bp,tree expr)19410d565efSmrg pack_ts_decl_common_value_fields (struct bitpack_d *bp, tree expr)
19510d565efSmrg {
19610d565efSmrg bp_pack_machine_mode (bp, DECL_MODE (expr));
19710d565efSmrg bp_pack_value (bp, DECL_NONLOCAL (expr), 1);
19810d565efSmrg bp_pack_value (bp, DECL_VIRTUAL_P (expr), 1);
19910d565efSmrg bp_pack_value (bp, DECL_IGNORED_P (expr), 1);
20010d565efSmrg bp_pack_value (bp, DECL_ABSTRACT_P (expr), 1);
20110d565efSmrg bp_pack_value (bp, DECL_ARTIFICIAL (expr), 1);
20210d565efSmrg bp_pack_value (bp, DECL_USER_ALIGN (expr), 1);
20310d565efSmrg bp_pack_value (bp, DECL_PRESERVE_P (expr), 1);
20410d565efSmrg bp_pack_value (bp, DECL_EXTERNAL (expr), 1);
20510d565efSmrg bp_pack_value (bp, DECL_GIMPLE_REG_P (expr), 1);
20610d565efSmrg bp_pack_var_len_unsigned (bp, DECL_ALIGN (expr));
20710d565efSmrg
20810d565efSmrg if (TREE_CODE (expr) == LABEL_DECL)
20910d565efSmrg {
21010d565efSmrg /* Note that we do not write LABEL_DECL_UID. The reader will
21110d565efSmrg always assume an initial value of -1 so that the
21210d565efSmrg label_to_block_map is recreated by gimple_set_bb. */
21310d565efSmrg bp_pack_var_len_unsigned (bp, EH_LANDING_PAD_NR (expr));
21410d565efSmrg }
21510d565efSmrg
21621ff1670Smrg else if (TREE_CODE (expr) == FIELD_DECL)
21710d565efSmrg {
21810d565efSmrg bp_pack_value (bp, DECL_PACKED (expr), 1);
21910d565efSmrg bp_pack_value (bp, DECL_NONADDRESSABLE_P (expr), 1);
220c7a68eb7Smrg bp_pack_value (bp, DECL_PADDING_P (expr), 1);
221*ec02198aSmrg bp_pack_value (bp, DECL_FIELD_ABI_IGNORED (expr), 1);
22210d565efSmrg bp_pack_value (bp, expr->decl_common.off_align, 8);
22310d565efSmrg }
22410d565efSmrg
22521ff1670Smrg else if (VAR_P (expr))
22610d565efSmrg {
22710d565efSmrg bp_pack_value (bp, DECL_HAS_DEBUG_EXPR_P (expr), 1);
22810d565efSmrg bp_pack_value (bp, DECL_NONLOCAL_FRAME (expr), 1);
22910d565efSmrg }
23010d565efSmrg
23121ff1670Smrg else if (TREE_CODE (expr) == PARM_DECL)
23221ff1670Smrg bp_pack_value (bp, DECL_HIDDEN_STRING_LENGTH (expr), 1);
23321ff1670Smrg
23410d565efSmrg if (TREE_CODE (expr) == RESULT_DECL
23510d565efSmrg || TREE_CODE (expr) == PARM_DECL
23610d565efSmrg || VAR_P (expr))
23710d565efSmrg {
23810d565efSmrg bp_pack_value (bp, DECL_BY_REFERENCE (expr), 1);
23910d565efSmrg if (VAR_P (expr) || TREE_CODE (expr) == PARM_DECL)
24010d565efSmrg bp_pack_value (bp, DECL_HAS_VALUE_EXPR_P (expr), 1);
24110d565efSmrg }
24210d565efSmrg }
24310d565efSmrg
24410d565efSmrg
24510d565efSmrg /* Pack all the non-pointer fields of the TS_DECL_WRTL structure
24610d565efSmrg of expression EXPR into bitpack BP. */
24710d565efSmrg
24810d565efSmrg static void
pack_ts_decl_wrtl_value_fields(struct bitpack_d * bp,tree expr)24910d565efSmrg pack_ts_decl_wrtl_value_fields (struct bitpack_d *bp, tree expr)
25010d565efSmrg {
25110d565efSmrg bp_pack_value (bp, DECL_REGISTER (expr), 1);
25210d565efSmrg }
25310d565efSmrg
25410d565efSmrg
25510d565efSmrg /* Pack all the non-pointer fields of the TS_DECL_WITH_VIS structure
25610d565efSmrg of expression EXPR into bitpack BP. */
25710d565efSmrg
25810d565efSmrg static void
pack_ts_decl_with_vis_value_fields(struct bitpack_d * bp,tree expr)25910d565efSmrg pack_ts_decl_with_vis_value_fields (struct bitpack_d *bp, tree expr)
26010d565efSmrg {
26110d565efSmrg bp_pack_value (bp, DECL_COMMON (expr), 1);
26210d565efSmrg bp_pack_value (bp, DECL_DLLIMPORT_P (expr), 1);
26310d565efSmrg bp_pack_value (bp, DECL_WEAK (expr), 1);
26410d565efSmrg bp_pack_value (bp, DECL_SEEN_IN_BIND_EXPR_P (expr), 1);
26510d565efSmrg bp_pack_value (bp, DECL_COMDAT (expr), 1);
26610d565efSmrg bp_pack_value (bp, DECL_VISIBILITY (expr), 2);
26710d565efSmrg bp_pack_value (bp, DECL_VISIBILITY_SPECIFIED (expr), 1);
26810d565efSmrg
26910d565efSmrg if (VAR_P (expr))
27010d565efSmrg {
27110d565efSmrg bp_pack_value (bp, DECL_HARD_REGISTER (expr), 1);
27210d565efSmrg /* DECL_IN_TEXT_SECTION is set during final asm output only. */
27310d565efSmrg bp_pack_value (bp, DECL_IN_CONSTANT_POOL (expr), 1);
27410d565efSmrg }
27510d565efSmrg
27610d565efSmrg if (TREE_CODE (expr) == FUNCTION_DECL)
27710d565efSmrg {
27810d565efSmrg bp_pack_value (bp, DECL_FINAL_P (expr), 1);
27910d565efSmrg bp_pack_value (bp, DECL_CXX_CONSTRUCTOR_P (expr), 1);
28010d565efSmrg bp_pack_value (bp, DECL_CXX_DESTRUCTOR_P (expr), 1);
28110d565efSmrg }
28210d565efSmrg }
28310d565efSmrg
28410d565efSmrg
28510d565efSmrg /* Pack all the non-pointer fields of the TS_FUNCTION_DECL structure
28610d565efSmrg of expression EXPR into bitpack BP. */
28710d565efSmrg
28810d565efSmrg static void
pack_ts_function_decl_value_fields(struct bitpack_d * bp,tree expr)28910d565efSmrg pack_ts_function_decl_value_fields (struct bitpack_d *bp, tree expr)
29010d565efSmrg {
29110d565efSmrg bp_pack_enum (bp, built_in_class, BUILT_IN_LAST,
29210d565efSmrg DECL_BUILT_IN_CLASS (expr));
29310d565efSmrg bp_pack_value (bp, DECL_STATIC_CONSTRUCTOR (expr), 1);
29410d565efSmrg bp_pack_value (bp, DECL_STATIC_DESTRUCTOR (expr), 1);
29510d565efSmrg bp_pack_value (bp, DECL_UNINLINABLE (expr), 1);
29610d565efSmrg bp_pack_value (bp, DECL_POSSIBLY_INLINED (expr), 1);
29710d565efSmrg bp_pack_value (bp, DECL_IS_NOVOPS (expr), 1);
29810d565efSmrg bp_pack_value (bp, DECL_IS_RETURNS_TWICE (expr), 1);
29910d565efSmrg bp_pack_value (bp, DECL_IS_MALLOC (expr), 1);
300*ec02198aSmrg bp_pack_value (bp, DECL_IS_OPERATOR_NEW_P (expr), 1);
301*ec02198aSmrg bp_pack_value (bp, DECL_IS_OPERATOR_DELETE_P (expr), 1);
30210d565efSmrg bp_pack_value (bp, DECL_DECLARED_INLINE_P (expr), 1);
30310d565efSmrg bp_pack_value (bp, DECL_STATIC_CHAIN (expr), 1);
30410d565efSmrg bp_pack_value (bp, DECL_NO_INLINE_WARNING_P (expr), 1);
30510d565efSmrg bp_pack_value (bp, DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (expr), 1);
30610d565efSmrg bp_pack_value (bp, DECL_NO_LIMIT_STACK (expr), 1);
30710d565efSmrg bp_pack_value (bp, DECL_DISREGARD_INLINE_LIMITS (expr), 1);
30810d565efSmrg bp_pack_value (bp, DECL_PURE_P (expr), 1);
30910d565efSmrg bp_pack_value (bp, DECL_LOOPING_CONST_OR_PURE_P (expr), 1);
310*ec02198aSmrg bp_pack_value (bp, DECL_IS_REPLACEABLE_OPERATOR (expr), 1);
31110d565efSmrg if (DECL_BUILT_IN_CLASS (expr) != NOT_BUILT_IN)
312*ec02198aSmrg bp_pack_value (bp, DECL_UNCHECKED_FUNCTION_CODE (expr), 32);
31310d565efSmrg }
31410d565efSmrg
31510d565efSmrg
31610d565efSmrg /* Pack all the non-pointer fields of the TS_TYPE_COMMON structure
31710d565efSmrg of expression EXPR into bitpack BP. */
31810d565efSmrg
31910d565efSmrg static void
pack_ts_type_common_value_fields(struct bitpack_d * bp,tree expr)32010d565efSmrg pack_ts_type_common_value_fields (struct bitpack_d *bp, tree expr)
32110d565efSmrg {
32210d565efSmrg /* for VECTOR_TYPE, TYPE_MODE reevaluates the mode using target_flags
32310d565efSmrg not necessary valid in a global context.
32410d565efSmrg Use the raw value previously set by layout_type. */
32510d565efSmrg bp_pack_machine_mode (bp, TYPE_MODE_RAW (expr));
32610d565efSmrg /* TYPE_NO_FORCE_BLK is private to stor-layout and need
32710d565efSmrg no streaming. */
32810d565efSmrg bp_pack_value (bp, TYPE_PACKED (expr), 1);
32910d565efSmrg bp_pack_value (bp, TYPE_RESTRICT (expr), 1);
33010d565efSmrg bp_pack_value (bp, TYPE_USER_ALIGN (expr), 1);
33110d565efSmrg bp_pack_value (bp, TYPE_READONLY (expr), 1);
332*ec02198aSmrg unsigned vla_p;
333*ec02198aSmrg if (in_lto_p)
334*ec02198aSmrg vla_p = TYPE_LANG_FLAG_0 (TYPE_MAIN_VARIANT (expr));
335*ec02198aSmrg else
336*ec02198aSmrg vla_p = variably_modified_type_p (expr, NULL_TREE);
337*ec02198aSmrg bp_pack_value (bp, vla_p, 1);
33810d565efSmrg /* We used to stream TYPE_ALIAS_SET == 0 information to let frontends mark
33910d565efSmrg types that are opaque for TBAA. This however did not work as intended,
34010d565efSmrg because TYPE_ALIAS_SET == 0 was regularly lost in type merging. */
34110d565efSmrg if (RECORD_OR_UNION_TYPE_P (expr))
34210d565efSmrg {
34310d565efSmrg bp_pack_value (bp, TYPE_TRANSPARENT_AGGR (expr), 1);
34410d565efSmrg bp_pack_value (bp, TYPE_FINAL_P (expr), 1);
345*ec02198aSmrg bp_pack_value (bp, TYPE_CXX_ODR_P (expr), 1);
34610d565efSmrg }
34710d565efSmrg else if (TREE_CODE (expr) == ARRAY_TYPE)
34810d565efSmrg bp_pack_value (bp, TYPE_NONALIASED_COMPONENT (expr), 1);
349*ec02198aSmrg if (TREE_CODE (expr) == ARRAY_TYPE || TREE_CODE (expr) == INTEGER_TYPE)
350*ec02198aSmrg bp_pack_value (bp, TYPE_STRING_FLAG (expr), 1);
35110d565efSmrg if (AGGREGATE_TYPE_P (expr))
35210d565efSmrg bp_pack_value (bp, TYPE_TYPELESS_STORAGE (expr), 1);
353c7a68eb7Smrg bp_pack_value (bp, TYPE_EMPTY_P (expr), 1);
35410d565efSmrg bp_pack_var_len_unsigned (bp, TYPE_PRECISION (expr));
35510d565efSmrg bp_pack_var_len_unsigned (bp, TYPE_ALIGN (expr));
35610d565efSmrg }
35710d565efSmrg
35810d565efSmrg
35910d565efSmrg /* Pack all the non-pointer fields of the TS_BLOCK structure
36010d565efSmrg of expression EXPR into bitpack BP. */
36110d565efSmrg
36210d565efSmrg static void
pack_ts_block_value_fields(struct output_block * ob,struct bitpack_d * bp,tree expr)36310d565efSmrg pack_ts_block_value_fields (struct output_block *ob,
36410d565efSmrg struct bitpack_d *bp, tree expr)
36510d565efSmrg {
36610d565efSmrg /* BLOCK_NUMBER is recomputed. */
36710d565efSmrg /* Stream BLOCK_SOURCE_LOCATION for the limited cases we can handle - those
36810d565efSmrg that represent inlined function scopes.
36910d565efSmrg For the rest them on the floor instead of ICEing in dwarf2out.c. */
37010d565efSmrg if (inlined_function_outer_scope_p (expr))
37110d565efSmrg stream_output_location (ob, bp, BLOCK_SOURCE_LOCATION (expr));
37210d565efSmrg else
37310d565efSmrg stream_output_location (ob, bp, UNKNOWN_LOCATION);
37410d565efSmrg }
37510d565efSmrg
37610d565efSmrg /* Pack all the non-pointer fields of the TS_TRANSLATION_UNIT_DECL structure
37710d565efSmrg of expression EXPR into bitpack BP. */
37810d565efSmrg
37910d565efSmrg static void
pack_ts_translation_unit_decl_value_fields(struct output_block * ob,struct bitpack_d * bp,tree expr)38010d565efSmrg pack_ts_translation_unit_decl_value_fields (struct output_block *ob,
38110d565efSmrg struct bitpack_d *bp, tree expr)
38210d565efSmrg {
38310d565efSmrg bp_pack_string (ob, bp, TRANSLATION_UNIT_LANGUAGE (expr), true);
38410d565efSmrg }
38510d565efSmrg
38610d565efSmrg
38710d565efSmrg /* Pack all the non-pointer fields of the TS_OMP_CLAUSE structure
38810d565efSmrg of expression EXPR into bitpack BP. */
38910d565efSmrg
39010d565efSmrg static void
pack_ts_omp_clause_value_fields(struct output_block * ob,struct bitpack_d * bp,tree expr)39110d565efSmrg pack_ts_omp_clause_value_fields (struct output_block *ob,
39210d565efSmrg struct bitpack_d *bp, tree expr)
39310d565efSmrg {
39410d565efSmrg stream_output_location (ob, bp, OMP_CLAUSE_LOCATION (expr));
39510d565efSmrg switch (OMP_CLAUSE_CODE (expr))
39610d565efSmrg {
39710d565efSmrg case OMP_CLAUSE_DEFAULT:
39810d565efSmrg bp_pack_enum (bp, omp_clause_default_kind, OMP_CLAUSE_DEFAULT_LAST,
39910d565efSmrg OMP_CLAUSE_DEFAULT_KIND (expr));
40010d565efSmrg break;
40110d565efSmrg case OMP_CLAUSE_SCHEDULE:
40210d565efSmrg bp_pack_enum (bp, omp_clause_schedule_kind, OMP_CLAUSE_SCHEDULE_LAST,
40310d565efSmrg OMP_CLAUSE_SCHEDULE_KIND (expr));
40410d565efSmrg break;
40510d565efSmrg case OMP_CLAUSE_DEPEND:
40610d565efSmrg bp_pack_enum (bp, omp_clause_depend_kind, OMP_CLAUSE_DEPEND_LAST,
40710d565efSmrg OMP_CLAUSE_DEPEND_KIND (expr));
40810d565efSmrg break;
40910d565efSmrg case OMP_CLAUSE_MAP:
41010d565efSmrg bp_pack_enum (bp, gomp_map_kind, GOMP_MAP_LAST,
41110d565efSmrg OMP_CLAUSE_MAP_KIND (expr));
41210d565efSmrg break;
41310d565efSmrg case OMP_CLAUSE_PROC_BIND:
41410d565efSmrg bp_pack_enum (bp, omp_clause_proc_bind_kind, OMP_CLAUSE_PROC_BIND_LAST,
41510d565efSmrg OMP_CLAUSE_PROC_BIND_KIND (expr));
41610d565efSmrg break;
41710d565efSmrg case OMP_CLAUSE_REDUCTION:
4180fc04c29Smrg case OMP_CLAUSE_TASK_REDUCTION:
4190fc04c29Smrg case OMP_CLAUSE_IN_REDUCTION:
42010d565efSmrg bp_pack_enum (bp, tree_code, MAX_TREE_CODES,
42110d565efSmrg OMP_CLAUSE_REDUCTION_CODE (expr));
42210d565efSmrg break;
42310d565efSmrg default:
42410d565efSmrg break;
42510d565efSmrg }
42610d565efSmrg }
42710d565efSmrg
42810d565efSmrg
42910d565efSmrg /* Pack all the bitfields in EXPR into a bit pack. */
43010d565efSmrg
43110d565efSmrg void
streamer_write_tree_bitfields(struct output_block * ob,tree expr)43210d565efSmrg streamer_write_tree_bitfields (struct output_block *ob, tree expr)
43310d565efSmrg {
43410d565efSmrg bitpack_d bp = bitpack_create (ob->main_stream);
43510d565efSmrg enum tree_code code;
43610d565efSmrg
43710d565efSmrg code = TREE_CODE (expr);
43810d565efSmrg
43910d565efSmrg /* Note that all these functions are highly sensitive to changes in
44010d565efSmrg the types and sizes of each of the fields being packed. */
44110d565efSmrg pack_ts_base_value_fields (&bp, expr);
44210d565efSmrg
44310d565efSmrg if (CODE_CONTAINS_STRUCT (code, TS_INT_CST))
44410d565efSmrg pack_ts_int_cst_value_fields (&bp, expr);
44510d565efSmrg
44610d565efSmrg if (CODE_CONTAINS_STRUCT (code, TS_REAL_CST))
44710d565efSmrg pack_ts_real_cst_value_fields (&bp, expr);
44810d565efSmrg
44910d565efSmrg if (CODE_CONTAINS_STRUCT (code, TS_FIXED_CST))
45010d565efSmrg pack_ts_fixed_cst_value_fields (&bp, expr);
45110d565efSmrg
45210d565efSmrg if (CODE_CONTAINS_STRUCT (code, TS_DECL_MINIMAL))
45310d565efSmrg stream_output_location (ob, &bp, DECL_SOURCE_LOCATION (expr));
45410d565efSmrg
45510d565efSmrg if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
45610d565efSmrg pack_ts_decl_common_value_fields (&bp, expr);
45710d565efSmrg
45810d565efSmrg if (CODE_CONTAINS_STRUCT (code, TS_DECL_WRTL))
45910d565efSmrg pack_ts_decl_wrtl_value_fields (&bp, expr);
46010d565efSmrg
46110d565efSmrg if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
46210d565efSmrg pack_ts_decl_with_vis_value_fields (&bp, expr);
46310d565efSmrg
46410d565efSmrg if (CODE_CONTAINS_STRUCT (code, TS_FUNCTION_DECL))
46510d565efSmrg pack_ts_function_decl_value_fields (&bp, expr);
46610d565efSmrg
46710d565efSmrg if (CODE_CONTAINS_STRUCT (code, TS_TYPE_COMMON))
46810d565efSmrg pack_ts_type_common_value_fields (&bp, expr);
46910d565efSmrg
47010d565efSmrg if (CODE_CONTAINS_STRUCT (code, TS_EXP))
47110d565efSmrg {
47210d565efSmrg stream_output_location (ob, &bp, EXPR_LOCATION (expr));
47310d565efSmrg if (code == MEM_REF
47410d565efSmrg || code == TARGET_MEM_REF)
47510d565efSmrg {
47610d565efSmrg bp_pack_value (&bp, MR_DEPENDENCE_CLIQUE (expr), sizeof (short) * 8);
47710d565efSmrg if (MR_DEPENDENCE_CLIQUE (expr) != 0)
47810d565efSmrg bp_pack_value (&bp, MR_DEPENDENCE_BASE (expr), sizeof (short) * 8);
47910d565efSmrg }
480c7a68eb7Smrg else if (code == CALL_EXPR)
481c7a68eb7Smrg bp_pack_enum (&bp, internal_fn, IFN_LAST, CALL_EXPR_IFN (expr));
48210d565efSmrg }
48310d565efSmrg
48410d565efSmrg if (CODE_CONTAINS_STRUCT (code, TS_BLOCK))
48510d565efSmrg pack_ts_block_value_fields (ob, &bp, expr);
48610d565efSmrg
48710d565efSmrg if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
48810d565efSmrg pack_ts_translation_unit_decl_value_fields (ob, &bp, expr);
48910d565efSmrg
49010d565efSmrg if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
4910fc04c29Smrg cl_optimization_stream_out (ob, &bp, TREE_OPTIMIZATION (expr));
49210d565efSmrg
49310d565efSmrg if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
49410d565efSmrg bp_pack_var_len_unsigned (&bp, CONSTRUCTOR_NELTS (expr));
49510d565efSmrg
49610d565efSmrg if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION)
49710d565efSmrg /* Don't stream these when passing things to a different target. */
49810d565efSmrg && !lto_stream_offload_p)
49910d565efSmrg cl_target_option_stream_out (ob, &bp, TREE_TARGET_OPTION (expr));
50010d565efSmrg
50110d565efSmrg if (code == OMP_CLAUSE)
50210d565efSmrg pack_ts_omp_clause_value_fields (ob, &bp, expr);
50310d565efSmrg
50410d565efSmrg streamer_write_bitpack (&bp);
50510d565efSmrg }
50610d565efSmrg
50710d565efSmrg
50810d565efSmrg /* Emit the chain of tree nodes starting at T. OB is the output block
50910d565efSmrg to write to. REF_P is true if chain elements should be emitted
51010d565efSmrg as references. */
51110d565efSmrg
51210d565efSmrg void
streamer_write_chain(struct output_block * ob,tree t,bool ref_p)51310d565efSmrg streamer_write_chain (struct output_block *ob, tree t, bool ref_p)
51410d565efSmrg {
51510d565efSmrg while (t)
51610d565efSmrg {
51710d565efSmrg /* We avoid outputting external vars or functions by reference
51810d565efSmrg to the global decls section as we do not want to have them
5190fc04c29Smrg enter decl merging. We should not need to do this anymore because
5200fc04c29Smrg free_lang_data removes them from block scopes. */
5210fc04c29Smrg gcc_assert (!VAR_OR_FUNCTION_DECL_P (t) || !DECL_EXTERNAL (t));
52210d565efSmrg stream_write_tree (ob, t, ref_p);
52310d565efSmrg
52410d565efSmrg t = TREE_CHAIN (t);
52510d565efSmrg }
52610d565efSmrg
52710d565efSmrg /* Write a sentinel to terminate the chain. */
52810d565efSmrg stream_write_tree (ob, NULL_TREE, ref_p);
52910d565efSmrg }
53010d565efSmrg
53110d565efSmrg
53210d565efSmrg /* Write all pointer fields in the TS_COMMON structure of EXPR to output
53310d565efSmrg block OB. If REF_P is true, write a reference to EXPR's pointer
53410d565efSmrg fields. */
53510d565efSmrg
53610d565efSmrg static void
write_ts_common_tree_pointers(struct output_block * ob,tree expr,bool ref_p)53710d565efSmrg write_ts_common_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
53810d565efSmrg {
53910d565efSmrg if (TREE_CODE (expr) != IDENTIFIER_NODE)
54010d565efSmrg stream_write_tree (ob, TREE_TYPE (expr), ref_p);
54110d565efSmrg }
54210d565efSmrg
54310d565efSmrg
54410d565efSmrg /* Write all pointer fields in the TS_VECTOR structure of EXPR to output
54510d565efSmrg block OB. If REF_P is true, write a reference to EXPR's pointer
54610d565efSmrg fields. */
54710d565efSmrg
54810d565efSmrg static void
write_ts_vector_tree_pointers(struct output_block * ob,tree expr,bool ref_p)54910d565efSmrg write_ts_vector_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
55010d565efSmrg {
55110d565efSmrg /* Note that the number of elements for EXPR has already been emitted
55210d565efSmrg in EXPR's header (see streamer_write_tree_header). */
553c7a68eb7Smrg unsigned int count = vector_cst_encoded_nelts (expr);
554c7a68eb7Smrg for (unsigned int i = 0; i < count; ++i)
555c7a68eb7Smrg stream_write_tree (ob, VECTOR_CST_ENCODED_ELT (expr, i), ref_p);
556c7a68eb7Smrg }
557c7a68eb7Smrg
558c7a68eb7Smrg
559c7a68eb7Smrg /* Write all pointer fields in the TS_POLY_INT_CST structure of EXPR to
560c7a68eb7Smrg output block OB. If REF_P is true, write a reference to EXPR's pointer
561c7a68eb7Smrg fields. */
562c7a68eb7Smrg
563c7a68eb7Smrg static void
write_ts_poly_tree_pointers(struct output_block * ob,tree expr,bool ref_p)564c7a68eb7Smrg write_ts_poly_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
565c7a68eb7Smrg {
566c7a68eb7Smrg for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
567c7a68eb7Smrg stream_write_tree (ob, POLY_INT_CST_COEFF (expr, i), ref_p);
56810d565efSmrg }
56910d565efSmrg
57010d565efSmrg
57110d565efSmrg /* Write all pointer fields in the TS_COMPLEX structure of EXPR to output
57210d565efSmrg block OB. If REF_P is true, write a reference to EXPR's pointer
57310d565efSmrg fields. */
57410d565efSmrg
57510d565efSmrg static void
write_ts_complex_tree_pointers(struct output_block * ob,tree expr,bool ref_p)57610d565efSmrg write_ts_complex_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
57710d565efSmrg {
57810d565efSmrg stream_write_tree (ob, TREE_REALPART (expr), ref_p);
57910d565efSmrg stream_write_tree (ob, TREE_IMAGPART (expr), ref_p);
58010d565efSmrg }
58110d565efSmrg
58210d565efSmrg
58310d565efSmrg /* Write all pointer fields in the TS_DECL_MINIMAL structure of EXPR
58410d565efSmrg to output block OB. If REF_P is true, write a reference to EXPR's
58510d565efSmrg pointer fields. */
58610d565efSmrg
58710d565efSmrg static void
write_ts_decl_minimal_tree_pointers(struct output_block * ob,tree expr,bool ref_p)58810d565efSmrg write_ts_decl_minimal_tree_pointers (struct output_block *ob, tree expr,
58910d565efSmrg bool ref_p)
59010d565efSmrg {
59110d565efSmrg /* Drop names that were created for anonymous entities. */
59210d565efSmrg if (DECL_NAME (expr)
59310d565efSmrg && TREE_CODE (DECL_NAME (expr)) == IDENTIFIER_NODE
594*ec02198aSmrg && IDENTIFIER_ANON_P (DECL_NAME (expr)))
59510d565efSmrg stream_write_tree (ob, NULL_TREE, ref_p);
59610d565efSmrg else
59710d565efSmrg stream_write_tree (ob, DECL_NAME (expr), ref_p);
598c7a68eb7Smrg if (TREE_CODE (expr) != TRANSLATION_UNIT_DECL
599c7a68eb7Smrg && ! DECL_CONTEXT (expr))
600c7a68eb7Smrg stream_write_tree (ob, (*all_translation_units)[0], ref_p);
601c7a68eb7Smrg else
60210d565efSmrg stream_write_tree (ob, DECL_CONTEXT (expr), ref_p);
60310d565efSmrg }
60410d565efSmrg
60510d565efSmrg
60610d565efSmrg /* Write all pointer fields in the TS_DECL_COMMON structure of EXPR to
60710d565efSmrg output block OB. If REF_P is true, write a reference to EXPR's
60810d565efSmrg pointer fields. */
60910d565efSmrg
61010d565efSmrg static void
write_ts_decl_common_tree_pointers(struct output_block * ob,tree expr,bool ref_p)61110d565efSmrg write_ts_decl_common_tree_pointers (struct output_block *ob, tree expr,
61210d565efSmrg bool ref_p)
61310d565efSmrg {
61410d565efSmrg stream_write_tree (ob, DECL_SIZE (expr), ref_p);
61510d565efSmrg stream_write_tree (ob, DECL_SIZE_UNIT (expr), ref_p);
61610d565efSmrg
61710d565efSmrg /* Note, DECL_INITIAL is not handled here. Since DECL_INITIAL needs
61810d565efSmrg special handling in LTO, it must be handled by streamer hooks. */
61910d565efSmrg
62010d565efSmrg stream_write_tree (ob, DECL_ATTRIBUTES (expr), ref_p);
62110d565efSmrg
622c7a68eb7Smrg /* On non-early-LTO enabled targets we claim we compiled with -g0
623c7a68eb7Smrg but dwarf2out still did its set_decl_origin_self game fooling
624c7a68eb7Smrg itself late. Und that here since we won't have access to the
625c7a68eb7Smrg early generated abstract DIEs. */
626c7a68eb7Smrg tree ao = DECL_ABSTRACT_ORIGIN (expr);
627c7a68eb7Smrg if (debug_info_level == DINFO_LEVEL_NONE
628c7a68eb7Smrg && ao == expr)
629c7a68eb7Smrg ao = NULL_TREE;
630c7a68eb7Smrg stream_write_tree (ob, ao, ref_p);
63110d565efSmrg
63210d565efSmrg if ((VAR_P (expr) || TREE_CODE (expr) == PARM_DECL)
63310d565efSmrg && DECL_HAS_VALUE_EXPR_P (expr))
63410d565efSmrg stream_write_tree (ob, DECL_VALUE_EXPR (expr), ref_p);
63510d565efSmrg
636c7a68eb7Smrg if (VAR_P (expr)
637c7a68eb7Smrg && DECL_HAS_DEBUG_EXPR_P (expr))
63810d565efSmrg stream_write_tree (ob, DECL_DEBUG_EXPR (expr), ref_p);
63910d565efSmrg }
64010d565efSmrg
64110d565efSmrg
64210d565efSmrg /* Write all pointer fields in the TS_DECL_NON_COMMON structure of
64310d565efSmrg EXPR to output block OB. If REF_P is true, write a reference to EXPR's
64410d565efSmrg pointer fields. */
64510d565efSmrg
64610d565efSmrg static void
write_ts_decl_non_common_tree_pointers(struct output_block *,tree,bool)6470fc04c29Smrg write_ts_decl_non_common_tree_pointers (struct output_block *, tree, bool)
64810d565efSmrg {
64910d565efSmrg }
65010d565efSmrg
65110d565efSmrg
65210d565efSmrg /* Write all pointer fields in the TS_DECL_WITH_VIS structure of EXPR
65310d565efSmrg to output block OB. If REF_P is true, write a reference to EXPR's
65410d565efSmrg pointer fields. */
65510d565efSmrg
65610d565efSmrg static void
write_ts_decl_with_vis_tree_pointers(struct output_block * ob,tree expr,bool ref_p)65710d565efSmrg write_ts_decl_with_vis_tree_pointers (struct output_block *ob, tree expr,
65810d565efSmrg bool ref_p)
65910d565efSmrg {
66010d565efSmrg /* Make sure we don't inadvertently set the assembler name. */
66110d565efSmrg if (DECL_ASSEMBLER_NAME_SET_P (expr))
66210d565efSmrg stream_write_tree (ob, DECL_ASSEMBLER_NAME (expr), ref_p);
66310d565efSmrg else
66410d565efSmrg stream_write_tree (ob, NULL_TREE, false);
66510d565efSmrg }
66610d565efSmrg
66710d565efSmrg
66810d565efSmrg /* Write all pointer fields in the TS_FIELD_DECL structure of EXPR to
66910d565efSmrg output block OB. If REF_P is true, write a reference to EXPR's
67010d565efSmrg pointer fields. */
67110d565efSmrg
67210d565efSmrg static void
write_ts_field_decl_tree_pointers(struct output_block * ob,tree expr,bool ref_p)67310d565efSmrg write_ts_field_decl_tree_pointers (struct output_block *ob, tree expr,
67410d565efSmrg bool ref_p)
67510d565efSmrg {
67610d565efSmrg stream_write_tree (ob, DECL_FIELD_OFFSET (expr), ref_p);
67710d565efSmrg stream_write_tree (ob, DECL_BIT_FIELD_TYPE (expr), ref_p);
67810d565efSmrg stream_write_tree (ob, DECL_BIT_FIELD_REPRESENTATIVE (expr), ref_p);
67910d565efSmrg stream_write_tree (ob, DECL_FIELD_BIT_OFFSET (expr), ref_p);
68010d565efSmrg }
68110d565efSmrg
68210d565efSmrg
68310d565efSmrg /* Write all pointer fields in the TS_FUNCTION_DECL structure of EXPR
68410d565efSmrg to output block OB. If REF_P is true, write a reference to EXPR's
68510d565efSmrg pointer fields. */
68610d565efSmrg
68710d565efSmrg static void
write_ts_function_decl_tree_pointers(struct output_block * ob,tree expr,bool ref_p)68810d565efSmrg write_ts_function_decl_tree_pointers (struct output_block *ob, tree expr,
68910d565efSmrg bool ref_p)
69010d565efSmrg {
69110d565efSmrg /* DECL_STRUCT_FUNCTION is handled by lto_output_function. */
69210d565efSmrg stream_write_tree (ob, DECL_FUNCTION_PERSONALITY (expr), ref_p);
69310d565efSmrg /* Don't stream these when passing things to a different target. */
69410d565efSmrg if (!lto_stream_offload_p)
69510d565efSmrg stream_write_tree (ob, DECL_FUNCTION_SPECIFIC_TARGET (expr), ref_p);
69610d565efSmrg stream_write_tree (ob, DECL_FUNCTION_SPECIFIC_OPTIMIZATION (expr), ref_p);
69710d565efSmrg }
69810d565efSmrg
69910d565efSmrg
70010d565efSmrg /* Write all pointer fields in the TS_TYPE_COMMON structure of EXPR to
70110d565efSmrg output block OB. If REF_P is true, write a reference to EXPR's
70210d565efSmrg pointer fields. */
70310d565efSmrg
70410d565efSmrg static void
write_ts_type_common_tree_pointers(struct output_block * ob,tree expr,bool ref_p)70510d565efSmrg write_ts_type_common_tree_pointers (struct output_block *ob, tree expr,
70610d565efSmrg bool ref_p)
70710d565efSmrg {
70810d565efSmrg stream_write_tree (ob, TYPE_SIZE (expr), ref_p);
70910d565efSmrg stream_write_tree (ob, TYPE_SIZE_UNIT (expr), ref_p);
71010d565efSmrg stream_write_tree (ob, TYPE_ATTRIBUTES (expr), ref_p);
71110d565efSmrg stream_write_tree (ob, TYPE_NAME (expr), ref_p);
71210d565efSmrg /* Do not stream TYPE_POINTER_TO or TYPE_REFERENCE_TO. They will be
71310d565efSmrg reconstructed during fixup. */
71410d565efSmrg /* Do not stream TYPE_NEXT_VARIANT, we reconstruct the variant lists
71510d565efSmrg during fixup. */
71610d565efSmrg stream_write_tree (ob, TYPE_MAIN_VARIANT (expr), ref_p);
71710d565efSmrg stream_write_tree (ob, TYPE_CONTEXT (expr), ref_p);
71810d565efSmrg /* TYPE_CANONICAL is re-computed during type merging, so no need
71910d565efSmrg to stream it here. */
7200fc04c29Smrg /* Do not stream TYPE_STUB_DECL; it is not needed by LTO but currently
7210fc04c29Smrg it cannot be freed by free_lang_data without triggering ICEs in
7220fc04c29Smrg langhooks. */
72310d565efSmrg }
72410d565efSmrg
72510d565efSmrg /* Write all pointer fields in the TS_TYPE_NON_COMMON structure of EXPR
72610d565efSmrg to output block OB. If REF_P is true, write a reference to EXPR's
72710d565efSmrg pointer fields. */
72810d565efSmrg
72910d565efSmrg static void
write_ts_type_non_common_tree_pointers(struct output_block * ob,tree expr,bool ref_p)73010d565efSmrg write_ts_type_non_common_tree_pointers (struct output_block *ob, tree expr,
73110d565efSmrg bool ref_p)
73210d565efSmrg {
733*ec02198aSmrg if (TREE_CODE (expr) == ARRAY_TYPE)
73410d565efSmrg stream_write_tree (ob, TYPE_DOMAIN (expr), ref_p);
73510d565efSmrg else if (RECORD_OR_UNION_TYPE_P (expr))
73610d565efSmrg streamer_write_chain (ob, TYPE_FIELDS (expr), ref_p);
73710d565efSmrg else if (TREE_CODE (expr) == FUNCTION_TYPE
73810d565efSmrg || TREE_CODE (expr) == METHOD_TYPE)
73910d565efSmrg stream_write_tree (ob, TYPE_ARG_TYPES (expr), ref_p);
74010d565efSmrg
74110d565efSmrg if (!POINTER_TYPE_P (expr))
742c7a68eb7Smrg stream_write_tree (ob, TYPE_MIN_VALUE_RAW (expr), ref_p);
743c7a68eb7Smrg stream_write_tree (ob, TYPE_MAX_VALUE_RAW (expr), ref_p);
74410d565efSmrg }
74510d565efSmrg
74610d565efSmrg
74710d565efSmrg /* Write all pointer fields in the TS_LIST structure of EXPR to output
74810d565efSmrg block OB. If REF_P is true, write a reference to EXPR's pointer
74910d565efSmrg fields. */
75010d565efSmrg
75110d565efSmrg static void
write_ts_list_tree_pointers(struct output_block * ob,tree expr,bool ref_p)75210d565efSmrg write_ts_list_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
75310d565efSmrg {
75410d565efSmrg stream_write_tree (ob, TREE_PURPOSE (expr), ref_p);
75510d565efSmrg stream_write_tree (ob, TREE_VALUE (expr), ref_p);
75610d565efSmrg stream_write_tree (ob, TREE_CHAIN (expr), ref_p);
75710d565efSmrg }
75810d565efSmrg
75910d565efSmrg
76010d565efSmrg /* Write all pointer fields in the TS_VEC structure of EXPR to output
76110d565efSmrg block OB. If REF_P is true, write a reference to EXPR's pointer
76210d565efSmrg fields. */
76310d565efSmrg
76410d565efSmrg static void
write_ts_vec_tree_pointers(struct output_block * ob,tree expr,bool ref_p)76510d565efSmrg write_ts_vec_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
76610d565efSmrg {
76710d565efSmrg int i;
76810d565efSmrg
76910d565efSmrg /* Note that the number of slots for EXPR has already been emitted
77010d565efSmrg in EXPR's header (see streamer_write_tree_header). */
77110d565efSmrg for (i = 0; i < TREE_VEC_LENGTH (expr); i++)
77210d565efSmrg stream_write_tree (ob, TREE_VEC_ELT (expr, i), ref_p);
77310d565efSmrg }
77410d565efSmrg
77510d565efSmrg
77610d565efSmrg /* Write all pointer fields in the TS_EXP structure of EXPR to output
77710d565efSmrg block OB. If REF_P is true, write a reference to EXPR's pointer
77810d565efSmrg fields. */
77910d565efSmrg
78010d565efSmrg static void
write_ts_exp_tree_pointers(struct output_block * ob,tree expr,bool ref_p)78110d565efSmrg write_ts_exp_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
78210d565efSmrg {
78310d565efSmrg int i;
78410d565efSmrg
78510d565efSmrg for (i = 0; i < TREE_OPERAND_LENGTH (expr); i++)
78610d565efSmrg stream_write_tree (ob, TREE_OPERAND (expr, i), ref_p);
78710d565efSmrg stream_write_tree (ob, TREE_BLOCK (expr), ref_p);
78810d565efSmrg }
78910d565efSmrg
79010d565efSmrg
79110d565efSmrg /* Write all pointer fields in the TS_BLOCK structure of EXPR to output
79210d565efSmrg block OB. If REF_P is true, write a reference to EXPR's pointer
79310d565efSmrg fields. */
79410d565efSmrg
79510d565efSmrg static void
write_ts_block_tree_pointers(struct output_block * ob,tree expr,bool ref_p)79610d565efSmrg write_ts_block_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
79710d565efSmrg {
79810d565efSmrg streamer_write_chain (ob, BLOCK_VARS (expr), ref_p);
79910d565efSmrg
80010d565efSmrg stream_write_tree (ob, BLOCK_SUPERCONTEXT (expr), ref_p);
8010fc04c29Smrg stream_write_tree (ob, BLOCK_ABSTRACT_ORIGIN (expr), ref_p);
80210d565efSmrg
80310d565efSmrg /* Do not stream BLOCK_NONLOCALIZED_VARS. We cannot handle debug information
80410d565efSmrg for early inlined BLOCKs so drop it on the floor instead of ICEing in
80510d565efSmrg dwarf2out.c. */
80610d565efSmrg
80710d565efSmrg /* BLOCK_FRAGMENT_ORIGIN and BLOCK_FRAGMENT_CHAIN is not live at LTO
80810d565efSmrg streaming time. */
80910d565efSmrg
81010d565efSmrg /* Do not output BLOCK_SUBBLOCKS. Instead on streaming-in this
81110d565efSmrg list is re-constructed from BLOCK_SUPERCONTEXT. */
81210d565efSmrg }
81310d565efSmrg
81410d565efSmrg
81510d565efSmrg /* Write all pointer fields in the TS_BINFO structure of EXPR to output
81610d565efSmrg block OB. If REF_P is true, write a reference to EXPR's pointer
81710d565efSmrg fields. */
81810d565efSmrg
81910d565efSmrg static void
write_ts_binfo_tree_pointers(struct output_block * ob,tree expr,bool ref_p)82010d565efSmrg write_ts_binfo_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
82110d565efSmrg {
82210d565efSmrg unsigned i;
82310d565efSmrg tree t;
82410d565efSmrg
82510d565efSmrg /* Note that the number of BINFO slots has already been emitted in
82610d565efSmrg EXPR's header (see streamer_write_tree_header) because this length
82710d565efSmrg is needed to build the empty BINFO node on the reader side. */
82810d565efSmrg FOR_EACH_VEC_ELT (*BINFO_BASE_BINFOS (expr), i, t)
82910d565efSmrg stream_write_tree (ob, t, ref_p);
83010d565efSmrg stream_write_tree (ob, NULL_TREE, false);
83110d565efSmrg
83210d565efSmrg stream_write_tree (ob, BINFO_OFFSET (expr), ref_p);
83310d565efSmrg stream_write_tree (ob, BINFO_VTABLE (expr), ref_p);
83410d565efSmrg
8350fc04c29Smrg /* Do not walk BINFO_INHERITANCE_CHAIN, BINFO_SUBVTT_INDEX,
8360fc04c29Smrg BINFO_BASE_ACCESSES and BINFO_VPTR_INDEX; these are used by C++ FE only. */
83710d565efSmrg }
83810d565efSmrg
83910d565efSmrg
84010d565efSmrg /* Write all pointer fields in the TS_CONSTRUCTOR structure of EXPR to
84110d565efSmrg output block OB. If REF_P is true, write a reference to EXPR's
84210d565efSmrg pointer fields. */
84310d565efSmrg
84410d565efSmrg static void
write_ts_constructor_tree_pointers(struct output_block * ob,tree expr,bool ref_p)84510d565efSmrg write_ts_constructor_tree_pointers (struct output_block *ob, tree expr,
84610d565efSmrg bool ref_p)
84710d565efSmrg {
84810d565efSmrg unsigned i;
84910d565efSmrg tree index, value;
85010d565efSmrg
85110d565efSmrg FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (expr), i, index, value)
85210d565efSmrg {
85310d565efSmrg stream_write_tree (ob, index, ref_p);
85410d565efSmrg stream_write_tree (ob, value, ref_p);
85510d565efSmrg }
85610d565efSmrg }
85710d565efSmrg
85810d565efSmrg
85910d565efSmrg /* Write all pointer fields in the TS_OMP_CLAUSE structure of EXPR
86010d565efSmrg to output block OB. If REF_P is true, write a reference to EXPR's
86110d565efSmrg pointer fields. */
86210d565efSmrg
86310d565efSmrg static void
write_ts_omp_clause_tree_pointers(struct output_block * ob,tree expr,bool ref_p)86410d565efSmrg write_ts_omp_clause_tree_pointers (struct output_block *ob, tree expr,
86510d565efSmrg bool ref_p)
86610d565efSmrg {
86710d565efSmrg int i;
86810d565efSmrg for (i = 0; i < omp_clause_num_ops[OMP_CLAUSE_CODE (expr)]; i++)
86910d565efSmrg stream_write_tree (ob, OMP_CLAUSE_OPERAND (expr, i), ref_p);
8700fc04c29Smrg switch (OMP_CLAUSE_CODE (expr))
87110d565efSmrg {
8720fc04c29Smrg case OMP_CLAUSE_REDUCTION:
8730fc04c29Smrg case OMP_CLAUSE_TASK_REDUCTION:
8740fc04c29Smrg case OMP_CLAUSE_IN_REDUCTION:
87510d565efSmrg /* We don't stream these right now, handle it if streaming
87610d565efSmrg of them is needed. */
87710d565efSmrg gcc_assert (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (expr) == NULL);
87810d565efSmrg gcc_assert (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (expr) == NULL);
8790fc04c29Smrg break;
8800fc04c29Smrg default:
8810fc04c29Smrg break;
88210d565efSmrg }
88310d565efSmrg stream_write_tree (ob, OMP_CLAUSE_CHAIN (expr), ref_p);
88410d565efSmrg }
88510d565efSmrg
88610d565efSmrg
88710d565efSmrg /* Write all pointer fields in EXPR to output block OB. If REF_P is true,
88810d565efSmrg the leaves of EXPR are emitted as references. */
88910d565efSmrg
89010d565efSmrg void
streamer_write_tree_body(struct output_block * ob,tree expr,bool ref_p)89110d565efSmrg streamer_write_tree_body (struct output_block *ob, tree expr, bool ref_p)
89210d565efSmrg {
89310d565efSmrg enum tree_code code;
89410d565efSmrg
89510d565efSmrg lto_stats.num_tree_bodies_output++;
89610d565efSmrg
89710d565efSmrg code = TREE_CODE (expr);
89810d565efSmrg
89910d565efSmrg if (CODE_CONTAINS_STRUCT (code, TS_TYPED))
90010d565efSmrg write_ts_common_tree_pointers (ob, expr, ref_p);
90110d565efSmrg
90210d565efSmrg if (CODE_CONTAINS_STRUCT (code, TS_VECTOR))
90310d565efSmrg write_ts_vector_tree_pointers (ob, expr, ref_p);
90410d565efSmrg
905c7a68eb7Smrg if (CODE_CONTAINS_STRUCT (code, TS_POLY_INT_CST))
906c7a68eb7Smrg write_ts_poly_tree_pointers (ob, expr, ref_p);
907c7a68eb7Smrg
90810d565efSmrg if (CODE_CONTAINS_STRUCT (code, TS_COMPLEX))
90910d565efSmrg write_ts_complex_tree_pointers (ob, expr, ref_p);
91010d565efSmrg
91110d565efSmrg if (CODE_CONTAINS_STRUCT (code, TS_DECL_MINIMAL))
91210d565efSmrg write_ts_decl_minimal_tree_pointers (ob, expr, ref_p);
91310d565efSmrg
91410d565efSmrg if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
91510d565efSmrg write_ts_decl_common_tree_pointers (ob, expr, ref_p);
91610d565efSmrg
91710d565efSmrg if (CODE_CONTAINS_STRUCT (code, TS_DECL_NON_COMMON))
91810d565efSmrg write_ts_decl_non_common_tree_pointers (ob, expr, ref_p);
91910d565efSmrg
92010d565efSmrg if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
92110d565efSmrg write_ts_decl_with_vis_tree_pointers (ob, expr, ref_p);
92210d565efSmrg
92310d565efSmrg if (CODE_CONTAINS_STRUCT (code, TS_FIELD_DECL))
92410d565efSmrg write_ts_field_decl_tree_pointers (ob, expr, ref_p);
92510d565efSmrg
92610d565efSmrg if (CODE_CONTAINS_STRUCT (code, TS_FUNCTION_DECL))
92710d565efSmrg write_ts_function_decl_tree_pointers (ob, expr, ref_p);
92810d565efSmrg
92910d565efSmrg if (CODE_CONTAINS_STRUCT (code, TS_TYPE_COMMON))
93010d565efSmrg write_ts_type_common_tree_pointers (ob, expr, ref_p);
93110d565efSmrg
93210d565efSmrg if (CODE_CONTAINS_STRUCT (code, TS_TYPE_NON_COMMON))
93310d565efSmrg write_ts_type_non_common_tree_pointers (ob, expr, ref_p);
93410d565efSmrg
93510d565efSmrg if (CODE_CONTAINS_STRUCT (code, TS_LIST))
93610d565efSmrg write_ts_list_tree_pointers (ob, expr, ref_p);
93710d565efSmrg
93810d565efSmrg if (CODE_CONTAINS_STRUCT (code, TS_VEC))
93910d565efSmrg write_ts_vec_tree_pointers (ob, expr, ref_p);
94010d565efSmrg
94110d565efSmrg if (CODE_CONTAINS_STRUCT (code, TS_EXP))
94210d565efSmrg write_ts_exp_tree_pointers (ob, expr, ref_p);
94310d565efSmrg
94410d565efSmrg if (CODE_CONTAINS_STRUCT (code, TS_BLOCK))
94510d565efSmrg write_ts_block_tree_pointers (ob, expr, ref_p);
94610d565efSmrg
94710d565efSmrg if (CODE_CONTAINS_STRUCT (code, TS_BINFO))
94810d565efSmrg write_ts_binfo_tree_pointers (ob, expr, ref_p);
94910d565efSmrg
95010d565efSmrg if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
95110d565efSmrg write_ts_constructor_tree_pointers (ob, expr, ref_p);
95210d565efSmrg
95310d565efSmrg if (code == OMP_CLAUSE)
95410d565efSmrg write_ts_omp_clause_tree_pointers (ob, expr, ref_p);
95510d565efSmrg }
95610d565efSmrg
95710d565efSmrg
95810d565efSmrg /* Emit header information for tree EXPR to output block OB. The header
95910d565efSmrg contains everything needed to instantiate an empty skeleton for
96010d565efSmrg EXPR on the reading side. IX is the index into the streamer cache
96110d565efSmrg where EXPR is stored. */
96210d565efSmrg
96310d565efSmrg void
streamer_write_tree_header(struct output_block * ob,tree expr)96410d565efSmrg streamer_write_tree_header (struct output_block *ob, tree expr)
96510d565efSmrg {
96610d565efSmrg enum LTO_tags tag;
96710d565efSmrg enum tree_code code;
96810d565efSmrg
96910d565efSmrg /* We should not see any tree nodes not handled by the streamer. */
97010d565efSmrg code = TREE_CODE (expr);
97110d565efSmrg
97210d565efSmrg /* The header of a tree node consists of its tag, the size of
97310d565efSmrg the node, and any other information needed to instantiate
97410d565efSmrg EXPR on the reading side (such as the number of slots in
97510d565efSmrg variable sized nodes). */
97610d565efSmrg tag = lto_tree_code_to_tag (code);
97710d565efSmrg streamer_write_record_start (ob, tag);
97810d565efSmrg
97910d565efSmrg /* The text in strings and identifiers are completely emitted in
98010d565efSmrg the header. */
98110d565efSmrg if (CODE_CONTAINS_STRUCT (code, TS_STRING))
98210d565efSmrg streamer_write_string_cst (ob, ob->main_stream, expr);
98310d565efSmrg else if (CODE_CONTAINS_STRUCT (code, TS_IDENTIFIER))
98410d565efSmrg write_identifier (ob, ob->main_stream, expr);
98510d565efSmrg else if (CODE_CONTAINS_STRUCT (code, TS_VECTOR))
986c7a68eb7Smrg {
987c7a68eb7Smrg bitpack_d bp = bitpack_create (ob->main_stream);
988c7a68eb7Smrg bp_pack_value (&bp, VECTOR_CST_LOG2_NPATTERNS (expr), 8);
989c7a68eb7Smrg bp_pack_value (&bp, VECTOR_CST_NELTS_PER_PATTERN (expr), 8);
990c7a68eb7Smrg streamer_write_bitpack (&bp);
991c7a68eb7Smrg }
99210d565efSmrg else if (CODE_CONTAINS_STRUCT (code, TS_VEC))
99310d565efSmrg streamer_write_hwi (ob, TREE_VEC_LENGTH (expr));
99410d565efSmrg else if (CODE_CONTAINS_STRUCT (code, TS_BINFO))
99510d565efSmrg streamer_write_uhwi (ob, BINFO_N_BASE_BINFOS (expr));
99610d565efSmrg else if (TREE_CODE (expr) == CALL_EXPR)
99710d565efSmrg streamer_write_uhwi (ob, call_expr_nargs (expr));
99810d565efSmrg else if (TREE_CODE (expr) == OMP_CLAUSE)
99910d565efSmrg streamer_write_uhwi (ob, OMP_CLAUSE_CODE (expr));
100010d565efSmrg else if (CODE_CONTAINS_STRUCT (code, TS_INT_CST))
100110d565efSmrg {
100210d565efSmrg gcc_checking_assert (TREE_INT_CST_NUNITS (expr));
100310d565efSmrg streamer_write_uhwi (ob, TREE_INT_CST_NUNITS (expr));
100410d565efSmrg streamer_write_uhwi (ob, TREE_INT_CST_EXT_NUNITS (expr));
100510d565efSmrg }
100610d565efSmrg }
100710d565efSmrg
100810d565efSmrg
100910d565efSmrg /* Emit the integer constant CST to output block OB. If REF_P is true,
101010d565efSmrg CST's type will be emitted as a reference. */
101110d565efSmrg
101210d565efSmrg void
streamer_write_integer_cst(struct output_block * ob,tree cst,bool ref_p)101310d565efSmrg streamer_write_integer_cst (struct output_block *ob, tree cst, bool ref_p)
101410d565efSmrg {
101510d565efSmrg int i;
101610d565efSmrg int len = TREE_INT_CST_NUNITS (cst);
101710d565efSmrg gcc_assert (!TREE_OVERFLOW (cst));
101810d565efSmrg streamer_write_record_start (ob, LTO_integer_cst);
101910d565efSmrg stream_write_tree (ob, TREE_TYPE (cst), ref_p);
102010d565efSmrg /* We're effectively streaming a non-sign-extended wide_int here,
102110d565efSmrg so there's no need to stream TREE_INT_CST_EXT_NUNITS or any
102210d565efSmrg array members beyond LEN. We'll recreate the tree from the
102310d565efSmrg wide_int and the type. */
102410d565efSmrg streamer_write_uhwi (ob, len);
102510d565efSmrg for (i = 0; i < len; i++)
102610d565efSmrg streamer_write_hwi (ob, TREE_INT_CST_ELT (cst, i));
102710d565efSmrg }
1028