1 /* Miscellaneous utilities for GIMPLE streaming. Things that are used
2 in both input and output are here.
4 Copyright (C) 2009-2025 Free Software Foundation, Inc.
5 Contributed by Doug Kwan <dougkwan@google.com>
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
25 #include "coretypes.h"
29 #include "tree-streamer.h"
31 #include "lto-streamer.h"
33 #include "lto-section-names.h"
35 /* Statistics gathered during LTO, WPA and LTRANS. */
36 struct lto_stats_d lto_stats
;
38 const char *section_name_prefix
= LTO_SECTION_NAME_PREFIX
;
39 /* Set when streaming LTO for offloading compiler. */
40 bool lto_stream_offload_p
;
42 FILE *streamer_dump_file
;
44 /* Return a string representing LTO tag TAG. */
47 lto_tag_name (enum LTO_tags tag
)
49 if (lto_tag_is_tree_code_p (tag
))
51 /* For tags representing tree nodes, return the name of the
52 associated tree code. */
53 return get_tree_code_name (lto_tag_to_tree_code (tag
));
56 if (lto_tag_is_gimple_code_p (tag
))
58 /* For tags representing gimple statements, return the name of
59 the associated gimple code. */
60 return gimple_code_name
[lto_tag_to_gimple_code (tag
)];
72 return "LTO_eh_region";
74 return "LTO_function";
76 return "LTO_eh_table";
78 return "LTO_ert_cleanup";
81 case LTO_ert_allowed_exceptions
:
82 return "LTO_ert_allowed_exceptions";
83 case LTO_ert_must_not_throw
:
84 return "LTO_ert_must_not_throw";
85 case LTO_tree_pickle_reference
:
86 return "LTO_tree_pickle_reference";
87 case LTO_global_stream_ref
:
88 return "LTO_global_sream_ref";
89 case LTO_ssa_name_ref
:
90 return "LTO_ssa_name_ref";
97 /* Get a section name for a particular type or name. The NAME field
98 is only used if SECTION_TYPE is LTO_section_function_body. For all
99 others it is ignored. The callee of this function is responsible
100 to free the returned name. */
103 lto_get_section_name (int section_type
, const char *name
,
104 int node_order
, struct lto_file_decl_data
*f
)
111 if (section_type
== LTO_section_function_body
)
113 gcc_assert (name
!= NULL
);
117 buffer
= (char *)xmalloc (strlen (name
) + 32);
118 sprintf (buffer
, "%s.%d", name
, node_order
);
123 else if (section_type
< LTO_N_SECTION_TYPES
)
125 add
= lto_section_name
[section_type
];
129 internal_error ("bytecode stream: unexpected LTO section %s", name
);
131 /* Make the section name unique so that ld -r combining sections
132 doesn't confuse the reader with merged sections.
134 For options don't add a ID, the option reader cannot deal with them
135 and merging should be ok here.
137 LTRANS files (output of wpa, input and output of ltrans) are handled
138 directly inside of linker/lto-wrapper, so name uniqueness for external
140 Randomness would inhibit incremental LTO. */
141 if (section_type
== LTO_section_opts
|| flag_ltrans
)
144 sprintf (post
, "." HOST_WIDE_INT_PRINT_HEX_PURE
, f
->id
);
148 sprintf (post
, "." HOST_WIDE_INT_PRINT_HEX_PURE
, get_random_seed (false));
149 char *res
= concat (section_name_prefix
, sep
, add
, post
, NULL
);
156 /* Show various memory usage statistics related to LTO. */
159 print_lto_report (const char *s
)
163 fprintf (stderr
, "[%s] # of input files: "
164 HOST_WIDE_INT_PRINT_UNSIGNED
"\n", s
, lto_stats
.num_input_files
);
166 fprintf (stderr
, "[%s] # of input cgraph nodes: "
167 HOST_WIDE_INT_PRINT_UNSIGNED
"\n", s
,
168 lto_stats
.num_input_cgraph_nodes
);
170 fprintf (stderr
, "[%s] # of function bodies: "
171 HOST_WIDE_INT_PRINT_UNSIGNED
"\n", s
,
172 lto_stats
.num_function_bodies
);
174 for (i
= 0; i
< NUM_TREE_CODES
; i
++)
175 if (lto_stats
.num_trees
[i
])
176 fprintf (stderr
, "[%s] # of '%s' objects read: "
177 HOST_WIDE_INT_PRINT_UNSIGNED
"\n", s
,
178 get_tree_code_name ((enum tree_code
) i
), lto_stats
.num_trees
[i
]);
182 fprintf (stderr
, "[%s] Compression: "
183 HOST_WIDE_INT_PRINT_UNSIGNED
" output bytes, "
184 HOST_WIDE_INT_PRINT_UNSIGNED
" compressed bytes", s
,
185 lto_stats
.num_output_il_bytes
,
186 lto_stats
.num_compressed_il_bytes
);
187 if (lto_stats
.num_output_il_bytes
> 0)
189 const float dividend
= (float) lto_stats
.num_compressed_il_bytes
;
190 const float divisor
= (float) lto_stats
.num_output_il_bytes
;
191 fprintf (stderr
, " (ratio: %f)", dividend
/ divisor
);
193 fprintf (stderr
, "\n");
198 fprintf (stderr
, "[%s] # of output files: "
199 HOST_WIDE_INT_PRINT_UNSIGNED
"\n", s
,
200 lto_stats
.num_output_files
);
202 fprintf (stderr
, "[%s] # of output symtab nodes: "
203 HOST_WIDE_INT_PRINT_UNSIGNED
"\n", s
,
204 lto_stats
.num_output_symtab_nodes
);
206 fprintf (stderr
, "[%s] # of output tree pickle references: "
207 HOST_WIDE_INT_PRINT_UNSIGNED
"\n", s
,
208 lto_stats
.num_pickle_refs_output
);
209 fprintf (stderr
, "[%s] # of output tree bodies: "
210 HOST_WIDE_INT_PRINT_UNSIGNED
"\n", s
,
211 lto_stats
.num_tree_bodies_output
);
213 fprintf (stderr
, "[%s] # callgraph partitions: "
214 HOST_WIDE_INT_PRINT_UNSIGNED
"\n", s
,
215 lto_stats
.num_cgraph_partitions
);
217 fprintf (stderr
, "[%s] Compression: "
218 HOST_WIDE_INT_PRINT_UNSIGNED
" input bytes, "
219 HOST_WIDE_INT_PRINT_UNSIGNED
" uncompressed bytes", s
,
220 lto_stats
.num_input_il_bytes
,
221 lto_stats
.num_uncompressed_il_bytes
);
222 if (lto_stats
.num_input_il_bytes
> 0)
224 const float dividend
= (float) lto_stats
.num_uncompressed_il_bytes
;
225 const float divisor
= (float) lto_stats
.num_input_il_bytes
;
226 fprintf (stderr
, " (ratio: %f)", dividend
/ divisor
);
228 fprintf (stderr
, "\n");
231 for (i
= 0; i
< LTO_N_SECTION_TYPES
; i
++)
232 fprintf (stderr
, "[%s] Size of mmap'd section %s: "
233 HOST_WIDE_INT_PRINT_UNSIGNED
" bytes\n", s
,
234 lto_section_name
[i
], lto_stats
.section_size
[i
]);
237 /* Initialization common to the LTO reader and writer. */
240 lto_streamer_init (void)
242 /* Check that all the TS_* handled by the reader and writer routines
243 match exactly the structures defined in treestruct.def. When a
244 new TS_* astructure is added, the streamer should be updated to
247 streamer_check_handled_ts_structures ();
251 /* Gate function for all LTO streaming passes. */
256 return ((flag_generate_lto
|| flag_generate_offload
|| in_lto_p
)
257 /* Don't bother doing anything if the program has errors. */
261 /* Check that the version MAJOR.MINOR is the correct version number. */
264 lto_check_version (int major
, int minor
, const char *file_name
)
266 if (major
!= LTO_major_version
|| minor
!= LTO_minor_version
)
267 fatal_error (input_location
,
268 "bytecode stream in file %qs generated with LTO version "
269 "%d.%d instead of the expected %d.%d",
272 LTO_major_version
, LTO_minor_version
);
276 /* Initialize all the streamer hooks used for streaming GIMPLE. */
279 lto_streamer_hooks_init (void)
281 streamer_hooks_init ();
282 streamer_hooks
.write_tree
= lto_output_tree
;
283 streamer_hooks
.read_tree
= lto_input_tree
;
284 streamer_hooks
.input_location
= lto_input_location
;
285 streamer_hooks
.output_location
= lto_output_location
;
286 streamer_hooks
.output_location_and_block
= lto_output_location_and_block
;