1 /* Functions for writing LTO sections.
2 
3    Copyright (C) 2009-2019 Free Software Foundation, Inc.
4    Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
5 
6 This file is part of GCC.
7 
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
12 
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along 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 "backend.h"
26 #include "rtl.h"
27 #include "tree.h"
28 #include "gimple.h"
29 #include "cgraph.h"
30 #include "data-streamer.h"
31 #include "langhooks.h"
32 #include "lto-compress.h"
33 #include "print-tree.h"
34 
35 static vec<lto_out_decl_state_ptr> decl_state_stack;
36 
37 /* List of out decl states used by functions.  We use this to
38    generate the decl directory later. */
39 
40 vec<lto_out_decl_state_ptr> lto_function_decl_states;
41 
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 
51 static void
lto_append_data(const char * chars,unsigned int num_chars,void * opaque)52 lto_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 
60 static 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 
65 void
lto_begin_section(const char * name,bool compress)66 lto_begin_section (const char *name, bool compress)
67 {
68   lang_hooks.lto.begin_section (name);
69 
70   if (streamer_dump_file)
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     }
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 
87 void
lto_end_section(void)88 lto_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 
98 /* Write SIZE bytes starting at DATA to the assembler.  */
99 
100 void
lto_write_data(const void * data,unsigned int size)101 lto_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 }
108 
109 /* Write SIZE bytes starting at DATA to the assembler.  */
110 
111 void
lto_write_raw_data(const void * data,unsigned int size)112 lto_write_raw_data (const void *data, unsigned int size)
113 {
114   lang_hooks.lto.append_data ((const char *)data, size, NULL);
115 }
116 
117 /* Write all of the chars in OBS to the assembler.  Recycle the blocks
118    in obs as this is being done.  */
119 
120 void
lto_write_stream(struct lto_output_stream * obs)121 lto_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 
141       if (compression_stream)
142 	lto_compress_block (compression_stream, base, num_chars);
143       else
144 	lang_hooks.lto.append_data (base, num_chars, block);
145       free (block);
146       block_size *= 2;
147     }
148 }
149 
150 
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 
158 bool
lto_output_decl_index(struct lto_output_stream * obs,struct lto_tree_ref_encoder * encoder,tree name,unsigned int * this_index)159 lto_output_decl_index (struct lto_output_stream *obs,
160 		       struct lto_tree_ref_encoder *encoder,
161 		       tree name, unsigned int *this_index)
162 {
163   bool new_entry_p = FALSE;
164   bool existed_p;
165 
166   unsigned int &index
167     = encoder->tree_hash_table->get_or_insert (name, &existed_p);
168   if (!existed_p)
169     {
170       index = encoder->trees.length ();
171       if (streamer_dump_file)
172 	{
173 	  print_node_brief (streamer_dump_file, "    Encoding indexable ",
174 			    name, 4);
175 	  fprintf (streamer_dump_file, "  as %i \n", index);
176 	}
177       encoder->trees.safe_push (name);
178       new_entry_p = TRUE;
179     }
180 
181   if (obs)
182     streamer_write_uhwi_stream (obs, index);
183   *this_index = index;
184   return new_entry_p;
185 }
186 
187 /* Output a field DECL to OBS.  */
188 
189 void
lto_output_field_decl_index(struct lto_out_decl_state * decl_state,struct lto_output_stream * obs,tree decl)190 lto_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 
200 void
lto_output_fn_decl_index(struct lto_out_decl_state * decl_state,struct lto_output_stream * obs,tree decl)201 lto_output_fn_decl_index (struct lto_out_decl_state *decl_state,
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 
211 void
lto_output_namespace_decl_index(struct lto_out_decl_state * decl_state,struct lto_output_stream * obs,tree decl)212 lto_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 
223 void
lto_output_var_decl_index(struct lto_out_decl_state * decl_state,struct lto_output_stream * obs,tree decl)224 lto_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 
234 void
lto_output_type_decl_index(struct lto_out_decl_state * decl_state,struct lto_output_stream * obs,tree decl)235 lto_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 
245 void
lto_output_type_ref_index(struct lto_out_decl_state * decl_state,struct lto_output_stream * obs,tree ref)246 lto_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 
257 struct lto_simple_output_block *
lto_create_simple_output_block(enum lto_section_type section_type)258 lto_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 
275 void
lto_destroy_simple_output_block(struct lto_simple_output_block * ob)276 lto_destroy_simple_output_block (struct lto_simple_output_block *ob)
277 {
278   char *section_name;
279   struct lto_simple_header header;
280 
281   section_name = lto_get_section_name (ob->section_type, NULL, NULL);
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));
288   header.major_version = LTO_major_version;
289   header.minor_version = LTO_minor_version;
290   header.main_size = ob->main_stream->total_size;
291   lto_write_data (&header, sizeof header);
292 
293   lto_write_stream (ob->main_stream);
294 
295   /* Put back the assembly section that was there before we started
296      writing lto info.  */
297   lto_end_section ();
298 
299   free (ob->main_stream);
300   free (ob);
301 }
302 
303 
304 /* Return a new lto_out_decl_state. */
305 
306 struct lto_out_decl_state *
lto_new_out_decl_state(void)307 lto_new_out_decl_state (void)
308 {
309   struct lto_out_decl_state *state = XCNEW (struct lto_out_decl_state);
310   int i;
311 
312   for (i = 0; i < LTO_N_DECL_STREAMS; i++)
313     lto_init_tree_ref_encoder (&state->streams[i]);
314 
315   /* At WPA time we do not compress sections by default.  */
316   state->compressed = !flag_wpa;
317 
318   return state;
319 }
320 
321 
322 /* Delete STATE and components.  */
323 
324 void
lto_delete_out_decl_state(struct lto_out_decl_state * state)325 lto_delete_out_decl_state (struct lto_out_decl_state *state)
326 {
327   int i;
328 
329   for (i = 0; i < LTO_N_DECL_STREAMS; i++)
330     lto_destroy_tree_ref_encoder (&state->streams[i]);
331 
332   free (state);
333 }
334 
335 
336 /* Get the currently used lto_out_decl_state structure. */
337 
338 struct lto_out_decl_state *
lto_get_out_decl_state(void)339 lto_get_out_decl_state (void)
340 {
341   return decl_state_stack.last ();
342 }
343 
344 /* Push STATE to top of out decl stack. */
345 
346 void
lto_push_out_decl_state(struct lto_out_decl_state * state)347 lto_push_out_decl_state (struct lto_out_decl_state *state)
348 {
349   decl_state_stack.safe_push (state);
350 }
351 
352 /* Pop the currently used out-decl state from top of stack. */
353 
354 struct lto_out_decl_state *
lto_pop_out_decl_state(void)355 lto_pop_out_decl_state (void)
356 {
357   return decl_state_stack.pop ();
358 }
359 
360 /* Record STATE after it has been used in serializing the body of
361    FN_DECL.  STATE should no longer be used by the caller.  The ownership
362    of it is taken over from this point.  */
363 
364 void
lto_record_function_out_decl_state(tree fn_decl,struct lto_out_decl_state * state)365 lto_record_function_out_decl_state (tree fn_decl,
366 				    struct lto_out_decl_state *state)
367 {
368   int i;
369 
370   /* Strip all hash tables to save some memory. */
371   for (i = 0; i < LTO_N_DECL_STREAMS; i++)
372     if (state->streams[i].tree_hash_table)
373       {
374 	delete state->streams[i].tree_hash_table;
375 	state->streams[i].tree_hash_table = NULL;
376       }
377   state->fn_decl = fn_decl;
378   lto_function_decl_states.safe_push (state);
379 }
380