]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/lto-section-out.c
2015-06-25 Andrew MacLeod <amacleod@redhat.com>
[thirdparty/gcc.git] / gcc / lto-section-out.c
CommitLineData
7bfefa9d 1/* Functions for writing LTO sections.
2
d353bf18 3 Copyright (C) 2009-2015 Free Software Foundation, Inc.
7bfefa9d 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"
25#include "tm.h"
b20a8bb4 26#include "alias.h"
27#include "symtab.h"
b20a8bb4 28#include "tree.h"
29#include "fold-const.h"
30#include "predict.h"
94ea8568 31#include "hard-reg-set.h"
94ea8568 32#include "function.h"
bc61cadb 33#include "basic-block.h"
34#include "tree-ssa-alias.h"
35#include "internal-fn.h"
36#include "gimple-expr.h"
b23fb4cb 37#include "gimple.h"
d53441c8 38#include "rtl.h"
39#include "flags.h"
d53441c8 40#include "insn-config.h"
41#include "expmed.h"
42#include "dojump.h"
43#include "explow.h"
44#include "calls.h"
45#include "emit-rtl.h"
46#include "varasm.h"
47#include "stmt.h"
7bfefa9d 48#include "expr.h"
49#include "params.h"
7bfefa9d 50#include "except.h"
7bfefa9d 51#include "langhooks.h"
1140c305 52#include "cgraph.h"
7f385784 53#include "data-streamer.h"
7bfefa9d 54#include "lto-streamer.h"
55#include "lto-compress.h"
56
f1f41a6c 57static vec<lto_out_decl_state_ptr> decl_state_stack;
7bfefa9d 58
59/* List of out decl states used by functions. We use this to
60 generate the decl directory later. */
61
f1f41a6c 62vec<lto_out_decl_state_ptr> lto_function_decl_states;
7bfefa9d 63
7bfefa9d 64
65/*****************************************************************************
66 Output routines shared by all of the serialization passes.
67*****************************************************************************/
68
69
70/* Flush compressed stream data function, sends NUM_CHARS from CHARS
71 to the append lang hook, OPAQUE is currently always NULL. */
72
73static void
74lto_append_data (const char *chars, unsigned int num_chars, void *opaque)
75{
76 gcc_assert (opaque == NULL);
77 lang_hooks.lto.append_data (chars, num_chars, opaque);
78}
79
80/* Pointer to the current compression stream. */
81
82static struct lto_compression_stream *compression_stream = NULL;
83
84/* Begin a new output section named NAME. If COMPRESS is true, zlib compress
85 the section. */
86
87void
88lto_begin_section (const char *name, bool compress)
89{
90 lang_hooks.lto.begin_section (name);
91
92 /* FIXME lto: for now, suppress compression if the lang_hook that appends
93 data is anything other than assembler output. The effect here is that
94 we get compression of IL only in non-ltrans object files. */
95 gcc_assert (compression_stream == NULL);
96 if (compress)
97 compression_stream = lto_start_compression (lto_append_data, NULL);
98}
99
100
101/* End the current output section. */
102
103void
104lto_end_section (void)
105{
106 if (compression_stream)
107 {
108 lto_end_compression (compression_stream);
109 compression_stream = NULL;
110 }
111 lang_hooks.lto.end_section ();
112}
113
2d97af95 114/* Write SIZE bytes starting at DATA to the assembler. */
115
116void
117lto_write_data (const void *data, unsigned int size)
118{
119 if (compression_stream)
120 lto_compress_block (compression_stream, (const char *)data, size);
121 else
122 lang_hooks.lto.append_data ((const char *)data, size, NULL);
123}
7bfefa9d 124
125/* Write all of the chars in OBS to the assembler. Recycle the blocks
126 in obs as this is being done. */
127
128void
129lto_write_stream (struct lto_output_stream *obs)
130{
131 unsigned int block_size = 1024;
132 struct lto_char_ptr_base *block;
133 struct lto_char_ptr_base *next_block;
134 if (!obs->first_block)
135 return;
136
137 for (block = obs->first_block; block; block = next_block)
138 {
139 const char *base = ((char *)block) + sizeof (struct lto_char_ptr_base);
140 unsigned int num_chars = block_size - sizeof (struct lto_char_ptr_base);
141
142 /* If this is not the last block, it is full. If it is the last
143 block, left_in_block indicates how many chars are unoccupied in
144 this block; subtract from num_chars to obtain occupancy. */
145 next_block = (struct lto_char_ptr_base *) block->ptr;
146 if (!next_block)
147 num_chars -= obs->left_in_block;
148
149 /* FIXME lto: WPA mode uses an ELF function as a lang_hook to append
150 output data. This hook is not happy with the way that compression
151 blocks up output differently to the way it's blocked here. So for
152 now, we don't compress WPA output. */
153 if (compression_stream)
2d97af95 154 lto_compress_block (compression_stream, base, num_chars);
7bfefa9d 155 else
156 lang_hooks.lto.append_data (base, num_chars, block);
2d97af95 157 free (block);
7bfefa9d 158 block_size *= 2;
159 }
160}
161
162
7bfefa9d 163/* Lookup NAME in ENCODER. If NAME is not found, create a new entry in
164 ENCODER for NAME with the next available index of ENCODER, then
165 print the index to OBS. True is returned if NAME was added to
166 ENCODER. The resulting index is stored in THIS_INDEX.
167
168 If OBS is NULL, the only action is to add NAME to the encoder. */
169
170bool
171lto_output_decl_index (struct lto_output_stream *obs,
172 struct lto_tree_ref_encoder *encoder,
173 tree name, unsigned int *this_index)
174{
7bfefa9d 175 bool new_entry_p = FALSE;
ea1a929f 176 bool existed_p;
7bfefa9d 177
d62dd039 178 unsigned int &index
179 = encoder->tree_hash_table->get_or_insert (name, &existed_p);
ea1a929f 180 if (!existed_p)
7bfefa9d 181 {
32d76803 182 index = encoder->trees.length ();
f1f41a6c 183 encoder->trees.safe_push (name);
7bfefa9d 184 new_entry_p = TRUE;
185 }
7bfefa9d 186
187 if (obs)
7f385784 188 streamer_write_uhwi_stream (obs, index);
7bfefa9d 189 *this_index = index;
190 return new_entry_p;
191}
192
193/* Output a field DECL to OBS. */
194
195void
196lto_output_field_decl_index (struct lto_out_decl_state *decl_state,
197 struct lto_output_stream * obs, tree decl)
198{
199 unsigned int index;
200 lto_output_decl_index (obs, &decl_state->streams[LTO_DECL_STREAM_FIELD_DECL],
201 decl, &index);
202}
203
204/* Output a function DECL to OBS. */
205
206void
48e1416a 207lto_output_fn_decl_index (struct lto_out_decl_state *decl_state,
7bfefa9d 208 struct lto_output_stream * obs, tree decl)
209{
210 unsigned int index;
211 lto_output_decl_index (obs, &decl_state->streams[LTO_DECL_STREAM_FN_DECL],
212 decl, &index);
213}
214
215/* Output a namespace DECL to OBS. */
216
217void
218lto_output_namespace_decl_index (struct lto_out_decl_state *decl_state,
219 struct lto_output_stream * obs, tree decl)
220{
221 unsigned int index;
222 lto_output_decl_index (obs,
223 &decl_state->streams[LTO_DECL_STREAM_NAMESPACE_DECL],
224 decl, &index);
225}
226
227/* Output a static or extern var DECL to OBS. */
228
229void
230lto_output_var_decl_index (struct lto_out_decl_state *decl_state,
231 struct lto_output_stream * obs, tree decl)
232{
233 unsigned int index;
234 lto_output_decl_index (obs, &decl_state->streams[LTO_DECL_STREAM_VAR_DECL],
235 decl, &index);
236}
237
238/* Output a type DECL to OBS. */
239
240void
241lto_output_type_decl_index (struct lto_out_decl_state *decl_state,
242 struct lto_output_stream * obs, tree decl)
243{
244 unsigned int index;
245 lto_output_decl_index (obs, &decl_state->streams[LTO_DECL_STREAM_TYPE_DECL],
246 decl, &index);
247}
248
249/* Output a type REF to OBS. */
250
251void
252lto_output_type_ref_index (struct lto_out_decl_state *decl_state,
253 struct lto_output_stream *obs, tree ref)
254{
255 unsigned int index;
256 lto_output_decl_index (obs, &decl_state->streams[LTO_DECL_STREAM_TYPE],
257 ref, &index);
258}
259
260
261/* Create the output block and return it. */
262
263struct lto_simple_output_block *
264lto_create_simple_output_block (enum lto_section_type section_type)
265{
266 struct lto_simple_output_block *ob
267 = ((struct lto_simple_output_block *)
268 xcalloc (1, sizeof (struct lto_simple_output_block)));
269
270 ob->section_type = section_type;
271 ob->decl_state = lto_get_out_decl_state ();
272 ob->main_stream = ((struct lto_output_stream *)
273 xcalloc (1, sizeof (struct lto_output_stream)));
274
275 return ob;
276}
277
278
279/* Produce a simple section for one of the ipa passes. */
280
281void
282lto_destroy_simple_output_block (struct lto_simple_output_block *ob)
283{
284 char *section_name;
285 struct lto_simple_header header;
7bfefa9d 286
f18bad33 287 section_name = lto_get_section_name (ob->section_type, NULL, NULL);
7bfefa9d 288 lto_begin_section (section_name, !flag_wpa);
289 free (section_name);
290
291 /* Write the header which says how to decode the pieces of the
292 t. */
293 memset (&header, 0, sizeof (struct lto_simple_header));
472ca566 294 header.major_version = LTO_major_version;
295 header.minor_version = LTO_minor_version;
7bfefa9d 296 header.main_size = ob->main_stream->total_size;
2d97af95 297 lto_write_data (&header, sizeof header);
7bfefa9d 298
299 lto_write_stream (ob->main_stream);
300
301 /* Put back the assembly section that was there before we started
302 writing lto info. */
303 lto_end_section ();
304
305 free (ob->main_stream);
306 free (ob);
307}
308
309
310/* Return a new lto_out_decl_state. */
311
312struct lto_out_decl_state *
313lto_new_out_decl_state (void)
314{
315 struct lto_out_decl_state *state = XCNEW (struct lto_out_decl_state);
316 int i;
7bfefa9d 317
318 for (i = 0; i < LTO_N_DECL_STREAMS; i++)
32d76803 319 lto_init_tree_ref_encoder (&state->streams[i]);
7bfefa9d 320
7bfefa9d 321 return state;
322}
323
324
325/* Delete STATE and components. */
326
327void
328lto_delete_out_decl_state (struct lto_out_decl_state *state)
329{
330 int i;
331
332 for (i = 0; i < LTO_N_DECL_STREAMS; i++)
333 lto_destroy_tree_ref_encoder (&state->streams[i]);
334
335 free (state);
336}
337
338
339/* Get the currently used lto_out_decl_state structure. */
340
341struct lto_out_decl_state *
342lto_get_out_decl_state (void)
343{
f1f41a6c 344 return decl_state_stack.last ();
7bfefa9d 345}
346
347/* Push STATE to top of out decl stack. */
348
349void
350lto_push_out_decl_state (struct lto_out_decl_state *state)
351{
f1f41a6c 352 decl_state_stack.safe_push (state);
7bfefa9d 353}
354
355/* Pop the currently used out-decl state from top of stack. */
356
357struct lto_out_decl_state *
358lto_pop_out_decl_state (void)
359{
f1f41a6c 360 return decl_state_stack.pop ();
7bfefa9d 361}
362
363/* Record STATE after it has been used in serializing the body of
364 FN_DECL. STATE should no longer be used by the caller. The ownership
365 of it is taken over from this point. */
366
367void
368lto_record_function_out_decl_state (tree fn_decl,
369 struct lto_out_decl_state *state)
370{
371 int i;
372
373 /* Strip all hash tables to save some memory. */
374 for (i = 0; i < LTO_N_DECL_STREAMS; i++)
375 if (state->streams[i].tree_hash_table)
376 {
ea1a929f 377 delete state->streams[i].tree_hash_table;
7bfefa9d 378 state->streams[i].tree_hash_table = NULL;
379 }
380 state->fn_decl = fn_decl;
f1f41a6c 381 lto_function_decl_states.safe_push (state);
7bfefa9d 382}