]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/lto-section-out.c
PR fortran/95090 - ICE: identifier overflow
[thirdparty/gcc.git] / gcc / lto-section-out.c
CommitLineData
d7f09764
DN
1/* Functions for writing LTO sections.
2
8d9254fc 3 Copyright (C) 2009-2020 Free Software Foundation, Inc.
d7f09764
DN
4 Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 3, or (at your option) any later
11version.
12
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License
19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
21
22#include "config.h"
23#include "system.h"
24#include "coretypes.h"
c7131fb2 25#include "backend.h"
957060b5 26#include "rtl.h"
40e23961 27#include "tree.h"
8e9055ae 28#include "gimple.h"
957060b5
AM
29#include "cgraph.h"
30#include "data-streamer.h"
d7f09764 31#include "langhooks.h"
d7f09764 32#include "lto-compress.h"
b4da704c 33#include "print-tree.h"
d7f09764 34
9771b263 35static vec<lto_out_decl_state_ptr> decl_state_stack;
d7f09764
DN
36
37/* List of out decl states used by functions. We use this to
38 generate the decl directory later. */
39
9771b263 40vec<lto_out_decl_state_ptr> lto_function_decl_states;
d7f09764 41
d7f09764
DN
42
43/*****************************************************************************
44 Output routines shared by all of the serialization passes.
45*****************************************************************************/
46
47
48/* Flush compressed stream data function, sends NUM_CHARS from CHARS
49 to the append lang hook, OPAQUE is currently always NULL. */
50
51static void
52lto_append_data (const char *chars, unsigned int num_chars, void *opaque)
53{
54 gcc_assert (opaque == NULL);
55 lang_hooks.lto.append_data (chars, num_chars, opaque);
56}
57
58/* Pointer to the current compression stream. */
59
60static struct lto_compression_stream *compression_stream = NULL;
61
62/* Begin a new output section named NAME. If COMPRESS is true, zlib compress
63 the section. */
64
65void
66lto_begin_section (const char *name, bool compress)
67{
68 lang_hooks.lto.begin_section (name);
69
b4da704c 70 if (streamer_dump_file)
aa7c78ca
JH
71 {
72 if (flag_dump_unnumbered || flag_dump_noaddr)
73 fprintf (streamer_dump_file, "Creating %ssection\n",
74 compress ? "compressed " : "");
75 else
76 fprintf (streamer_dump_file, "Creating %ssection %s\n",
77 compress ? "compressed " : "", name);
78 }
d7f09764
DN
79 gcc_assert (compression_stream == NULL);
80 if (compress)
81 compression_stream = lto_start_compression (lto_append_data, NULL);
82}
83
84
85/* End the current output section. */
86
87void
88lto_end_section (void)
89{
90 if (compression_stream)
91 {
92 lto_end_compression (compression_stream);
93 compression_stream = NULL;
94 }
95 lang_hooks.lto.end_section ();
96}
97
f6bcdb5e
RB
98/* Write SIZE bytes starting at DATA to the assembler. */
99
100void
101lto_write_data (const void *data, unsigned int size)
102{
103 if (compression_stream)
104 lto_compress_block (compression_stream, (const char *)data, size);
105 else
106 lang_hooks.lto.append_data ((const char *)data, size, NULL);
107}
d7f09764 108
7fa658c2
JH
109/* Write SIZE bytes starting at DATA to the assembler. */
110
111void
112lto_write_raw_data (const void *data, unsigned int size)
113{
114 lang_hooks.lto.append_data ((const char *)data, size, NULL);
115}
116
d7f09764
DN
117/* Write all of the chars in OBS to the assembler. Recycle the blocks
118 in obs as this is being done. */
119
120void
121lto_write_stream (struct lto_output_stream *obs)
122{
123 unsigned int block_size = 1024;
124 struct lto_char_ptr_base *block;
125 struct lto_char_ptr_base *next_block;
126 if (!obs->first_block)
127 return;
128
129 for (block = obs->first_block; block; block = next_block)
130 {
131 const char *base = ((char *)block) + sizeof (struct lto_char_ptr_base);
132 unsigned int num_chars = block_size - sizeof (struct lto_char_ptr_base);
133
134 /* If this is not the last block, it is full. If it is the last
135 block, left_in_block indicates how many chars are unoccupied in
136 this block; subtract from num_chars to obtain occupancy. */
137 next_block = (struct lto_char_ptr_base *) block->ptr;
138 if (!next_block)
139 num_chars -= obs->left_in_block;
140
d7f09764 141 if (compression_stream)
f6bcdb5e 142 lto_compress_block (compression_stream, base, num_chars);
d7f09764
DN
143 else
144 lang_hooks.lto.append_data (base, num_chars, block);
f6bcdb5e 145 free (block);
d7f09764
DN
146 block_size *= 2;
147 }
148}
149
150
d7f09764
DN
151/* Lookup NAME in ENCODER. If NAME is not found, create a new entry in
152 ENCODER for NAME with the next available index of ENCODER, then
153 print the index to OBS. True is returned if NAME was added to
154 ENCODER. The resulting index is stored in THIS_INDEX.
155
156 If OBS is NULL, the only action is to add NAME to the encoder. */
157
158bool
159lto_output_decl_index (struct lto_output_stream *obs,
160 struct lto_tree_ref_encoder *encoder,
161 tree name, unsigned int *this_index)
162{
d7f09764 163 bool new_entry_p = FALSE;
7c5848b8 164 bool existed_p;
d7f09764 165
1eb68d2d
TS
166 unsigned int &index
167 = encoder->tree_hash_table->get_or_insert (name, &existed_p);
7c5848b8 168 if (!existed_p)
d7f09764 169 {
d579fcda 170 index = encoder->trees.length ();
b4da704c
JH
171 if (streamer_dump_file)
172 {
0896cc42 173 print_node_brief (streamer_dump_file, " Encoding indexable ",
b4da704c
JH
174 name, 4);
175 fprintf (streamer_dump_file, " as %i \n", index);
176 }
9771b263 177 encoder->trees.safe_push (name);
d7f09764
DN
178 new_entry_p = TRUE;
179 }
d7f09764
DN
180
181 if (obs)
412288f1 182 streamer_write_uhwi_stream (obs, index);
d7f09764
DN
183 *this_index = index;
184 return new_entry_p;
185}
186
187/* Output a field DECL to OBS. */
188
189void
190lto_output_field_decl_index (struct lto_out_decl_state *decl_state,
191 struct lto_output_stream * obs, tree decl)
192{
193 unsigned int index;
194 lto_output_decl_index (obs, &decl_state->streams[LTO_DECL_STREAM_FIELD_DECL],
195 decl, &index);
196}
197
198/* Output a function DECL to OBS. */
199
200void
b8698a0f 201lto_output_fn_decl_index (struct lto_out_decl_state *decl_state,
d7f09764
DN
202 struct lto_output_stream * obs, tree decl)
203{
204 unsigned int index;
205 lto_output_decl_index (obs, &decl_state->streams[LTO_DECL_STREAM_FN_DECL],
206 decl, &index);
207}
208
209/* Output a namespace DECL to OBS. */
210
211void
212lto_output_namespace_decl_index (struct lto_out_decl_state *decl_state,
213 struct lto_output_stream * obs, tree decl)
214{
215 unsigned int index;
216 lto_output_decl_index (obs,
217 &decl_state->streams[LTO_DECL_STREAM_NAMESPACE_DECL],
218 decl, &index);
219}
220
221/* Output a static or extern var DECL to OBS. */
222
223void
224lto_output_var_decl_index (struct lto_out_decl_state *decl_state,
225 struct lto_output_stream * obs, tree decl)
226{
227 unsigned int index;
228 lto_output_decl_index (obs, &decl_state->streams[LTO_DECL_STREAM_VAR_DECL],
229 decl, &index);
230}
231
232/* Output a type DECL to OBS. */
233
234void
235lto_output_type_decl_index (struct lto_out_decl_state *decl_state,
236 struct lto_output_stream * obs, tree decl)
237{
238 unsigned int index;
239 lto_output_decl_index (obs, &decl_state->streams[LTO_DECL_STREAM_TYPE_DECL],
240 decl, &index);
241}
242
243/* Output a type REF to OBS. */
244
245void
246lto_output_type_ref_index (struct lto_out_decl_state *decl_state,
247 struct lto_output_stream *obs, tree ref)
248{
249 unsigned int index;
250 lto_output_decl_index (obs, &decl_state->streams[LTO_DECL_STREAM_TYPE],
251 ref, &index);
252}
253
254
255/* Create the output block and return it. */
256
257struct lto_simple_output_block *
258lto_create_simple_output_block (enum lto_section_type section_type)
259{
260 struct lto_simple_output_block *ob
261 = ((struct lto_simple_output_block *)
262 xcalloc (1, sizeof (struct lto_simple_output_block)));
263
264 ob->section_type = section_type;
265 ob->decl_state = lto_get_out_decl_state ();
266 ob->main_stream = ((struct lto_output_stream *)
267 xcalloc (1, sizeof (struct lto_output_stream)));
268
269 return ob;
270}
271
272
273/* Produce a simple section for one of the ipa passes. */
274
275void
276lto_destroy_simple_output_block (struct lto_simple_output_block *ob)
277{
278 char *section_name;
279 struct lto_simple_header header;
d7f09764 280
3c56d8d8 281 section_name = lto_get_section_name (ob->section_type, NULL, 0, NULL);
d7f09764
DN
282 lto_begin_section (section_name, !flag_wpa);
283 free (section_name);
284
285 /* Write the header which says how to decode the pieces of the
286 t. */
287 memset (&header, 0, sizeof (struct lto_simple_header));
d7f09764 288 header.main_size = ob->main_stream->total_size;
f6bcdb5e 289 lto_write_data (&header, sizeof header);
d7f09764
DN
290
291 lto_write_stream (ob->main_stream);
292
293 /* Put back the assembly section that was there before we started
294 writing lto info. */
295 lto_end_section ();
296
297 free (ob->main_stream);
298 free (ob);
299}
300
301
302/* Return a new lto_out_decl_state. */
303
304struct lto_out_decl_state *
305lto_new_out_decl_state (void)
306{
307 struct lto_out_decl_state *state = XCNEW (struct lto_out_decl_state);
308 int i;
d7f09764
DN
309
310 for (i = 0; i < LTO_N_DECL_STREAMS; i++)
d579fcda 311 lto_init_tree_ref_encoder (&state->streams[i]);
d7f09764 312
7fa658c2
JH
313 /* At WPA time we do not compress sections by default. */
314 state->compressed = !flag_wpa;
315
d7f09764
DN
316 return state;
317}
318
319
320/* Delete STATE and components. */
321
322void
323lto_delete_out_decl_state (struct lto_out_decl_state *state)
324{
325 int i;
326
327 for (i = 0; i < LTO_N_DECL_STREAMS; i++)
328 lto_destroy_tree_ref_encoder (&state->streams[i]);
329
330 free (state);
331}
332
333
334/* Get the currently used lto_out_decl_state structure. */
335
336struct lto_out_decl_state *
337lto_get_out_decl_state (void)
338{
9771b263 339 return decl_state_stack.last ();
d7f09764
DN
340}
341
342/* Push STATE to top of out decl stack. */
343
344void
345lto_push_out_decl_state (struct lto_out_decl_state *state)
346{
9771b263 347 decl_state_stack.safe_push (state);
d7f09764
DN
348}
349
350/* Pop the currently used out-decl state from top of stack. */
351
352struct lto_out_decl_state *
353lto_pop_out_decl_state (void)
354{
9771b263 355 return decl_state_stack.pop ();
d7f09764
DN
356}
357
358/* Record STATE after it has been used in serializing the body of
359 FN_DECL. STATE should no longer be used by the caller. The ownership
360 of it is taken over from this point. */
361
362void
363lto_record_function_out_decl_state (tree fn_decl,
364 struct lto_out_decl_state *state)
365{
366 int i;
367
368 /* Strip all hash tables to save some memory. */
369 for (i = 0; i < LTO_N_DECL_STREAMS; i++)
370 if (state->streams[i].tree_hash_table)
371 {
7c5848b8 372 delete state->streams[i].tree_hash_table;
d7f09764
DN
373 state->streams[i].tree_hash_table = NULL;
374 }
375 state->fn_decl = fn_decl;
9771b263 376 lto_function_decl_states.safe_push (state);
d7f09764 377}