Line data Source code
1 : /* Top-level LTO routines.
2 : Copyright (C) 2009-2026 Free Software Foundation, Inc.
3 : Contributed by CodeSourcery, Inc.
4 :
5 : This file is part of GCC.
6 :
7 : GCC is free software; you can redistribute it and/or modify it under
8 : the terms of the GNU General Public License as published by the Free
9 : Software Foundation; either version 3, or (at your option) any later
10 : version.
11 :
12 : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 : WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 : for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with GCC; see the file COPYING3. If not see
19 : <http://www.gnu.org/licenses/>. */
20 :
21 : #define INCLUDE_STRING
22 : #include "config.h"
23 : #include "system.h"
24 : #include "coretypes.h"
25 : #include "tm.h"
26 : #include "function.h"
27 : #include "bitmap.h"
28 : #include "basic-block.h"
29 : #include "tree.h"
30 : #include "gimple.h"
31 : #include "cfghooks.h"
32 : #include "alloc-pool.h"
33 : #include "tree-pass.h"
34 : #include "tree-streamer.h"
35 : #include "cgraph.h"
36 : #include "opts.h"
37 : #include "toplev.h"
38 : #include "stor-layout.h"
39 : #include "symbol-summary.h"
40 : #include "tree-vrp.h"
41 : #include "sreal.h"
42 : #include "ipa-cp.h"
43 : #include "ipa-prop.h"
44 : #include "debug.h"
45 : #include "lto.h"
46 : #include "lto-section-names.h"
47 : #include "splay-tree.h"
48 : #include "lto-partition.h"
49 : #include "context.h"
50 : #include "pass_manager.h"
51 : #include "ipa-fnsummary.h"
52 : #include "ipa-utils.h"
53 : #include "gomp-constants.h"
54 : #include "lto-symtab.h"
55 : #include "stringpool.h"
56 : #include "fold-const.h"
57 : #include "attribs.h"
58 : #include "builtins.h"
59 : #include "lto-common.h"
60 : #include "opts-jobserver.h"
61 :
62 : /* Number of parallel tasks to run. */
63 : static int lto_parallelism;
64 :
65 : #ifdef HAVE_WORKING_FORK
66 : /* Number of active WPA streaming processes. */
67 : static int nruns = 0;
68 : #endif
69 :
70 : /* GNU make's jobserver info. */
71 : static jobserver_info *jinfo = NULL;
72 :
73 : /* Return true when NODE has a clone that is analyzed (i.e. we need
74 : to load its body even if the node itself is not needed). */
75 :
76 : static bool
77 53451 : has_analyzed_clone_p (struct cgraph_node *node)
78 : {
79 53451 : struct cgraph_node *orig = node;
80 53451 : node = node->clones;
81 53451 : if (node)
82 3830 : while (node != orig)
83 : {
84 3830 : if (node->analyzed)
85 : return true;
86 435 : if (node->clones)
87 : node = node->clones;
88 0 : else if (node->next_sibling_clone)
89 : node = node->next_sibling_clone;
90 : else
91 : {
92 0 : while (node != orig && !node->next_sibling_clone)
93 0 : node = node->clone_of;
94 0 : if (node != orig)
95 0 : node = node->next_sibling_clone;
96 : }
97 : }
98 : return false;
99 : }
100 :
101 : /* Read the function body for the function associated with NODE. */
102 :
103 : static void
104 195640 : lto_materialize_function (struct cgraph_node *node)
105 : {
106 195640 : tree decl;
107 :
108 195640 : decl = node->decl;
109 : /* Read in functions with body (analyzed nodes)
110 : and also functions that are needed to produce virtual clones. */
111 141693 : if ((node->has_gimple_body_p () && node->analyzed)
112 53948 : || node->used_as_abstract_origin
113 249091 : || has_analyzed_clone_p (node))
114 : {
115 : /* Clones don't need to be read. */
116 145584 : if (node->clone_of)
117 : return;
118 122360 : if (DECL_FUNCTION_PERSONALITY (decl) && !first_personality_decl)
119 672 : first_personality_decl = DECL_FUNCTION_PERSONALITY (decl);
120 : /* If the file contains a function with a language specific EH
121 : personality set or with EH enabled initialize the backend EH
122 : machinery. */
123 122360 : if (DECL_FUNCTION_PERSONALITY (decl)
124 122360 : || opt_for_fn (decl, flag_exceptions))
125 43313 : lto_init_eh ();
126 : }
127 :
128 : /* Let the middle end know about the function. */
129 172416 : rest_of_decl_compilation (decl, 1, 0);
130 : }
131 :
132 : /* Materialize all the bodies for all the nodes in the callgraph. */
133 :
134 : static void
135 20801 : materialize_cgraph (void)
136 : {
137 20801 : struct cgraph_node *node;
138 20801 : timevar_id_t lto_timer;
139 :
140 20801 : if (!quiet_flag)
141 0 : fprintf (stderr,
142 0 : flag_wpa ? "Materializing decls:" : "Reading function bodies:");
143 :
144 : /* Start the appropriate timer depending on the mode that we are
145 : operating in. */
146 25321 : lto_timer = (flag_wpa) ? TV_WHOPR_WPA
147 12853 : : (flag_ltrans) ? TV_WHOPR_LTRANS
148 : : TV_LTO;
149 20801 : timevar_push (lto_timer);
150 :
151 216441 : FOR_EACH_FUNCTION (node)
152 : {
153 195640 : if (node->lto_file_data)
154 : {
155 195640 : lto_materialize_function (node);
156 195640 : lto_stats.num_input_cgraph_nodes++;
157 : }
158 : }
159 :
160 20801 : current_function_decl = NULL;
161 20801 : set_cfun (NULL);
162 :
163 20801 : if (!quiet_flag)
164 0 : fprintf (stderr, "\n");
165 :
166 20801 : timevar_pop (lto_timer);
167 20801 : }
168 :
169 : /* Stream out all the linemap sections so they are available for LTRANS. */
170 :
171 : static void
172 7948 : stream_out_linemaps (const char *filename)
173 : {
174 7948 : const auto file = lto_obj_file_open (filename, true);
175 7948 : if (!file)
176 0 : fatal_error (input_location, "%<lto_obj_file_open()%> failed");
177 7948 : lto_set_current_out_file (file);
178 7948 : lto_copy_linemaps ();
179 7948 : free (const_cast<char *> (file->filename));
180 7948 : lto_set_current_out_file (nullptr);
181 7948 : lto_obj_file_close (file);
182 7948 : free (file);
183 7948 : }
184 :
185 : /* Actually stream out ENCODER into TEMP_FILENAME. */
186 :
187 : static void
188 8333 : stream_out (char *temp_filename, lto_symtab_encoder_t encoder, int part)
189 : {
190 8333 : lto_file *file = lto_obj_file_open (temp_filename, true);
191 8333 : if (!file)
192 0 : fatal_error (input_location, "%<lto_obj_file_open()%> failed");
193 8333 : lto_set_current_out_file (file);
194 :
195 8333 : gcc_assert (!dump_file);
196 8333 : streamer_dump_file = dump_begin (TDI_lto_stream_out, NULL, part);
197 8333 : ipa_write_optimization_summaries (encoder, part == 0);
198 :
199 8333 : free (const_cast<char *> (file->filename));
200 :
201 8333 : lto_set_current_out_file (NULL);
202 8333 : lto_obj_file_close (file);
203 8333 : free (file);
204 8333 : if (streamer_dump_file)
205 : {
206 0 : dump_end (TDI_lto_stream_out, streamer_dump_file);
207 0 : streamer_dump_file = NULL;
208 : }
209 8333 : }
210 :
211 : /* Wait for forked process and signal errors. */
212 : #ifdef HAVE_WORKING_FORK
213 : static void
214 0 : wait_for_child ()
215 : {
216 0 : int status;
217 0 : do
218 : {
219 : #ifndef WCONTINUED
220 : #define WCONTINUED 0
221 : #endif
222 0 : int w = waitpid (0, &status, WUNTRACED | WCONTINUED);
223 0 : if (w == -1)
224 0 : fatal_error (input_location, "waitpid failed");
225 :
226 0 : if (WIFEXITED (status) && WEXITSTATUS (status))
227 0 : fatal_error (input_location, "streaming subprocess failed");
228 0 : else if (WIFSIGNALED (status))
229 0 : fatal_error (input_location,
230 : "streaming subprocess was killed by signal");
231 : }
232 0 : while (!WIFEXITED (status) && !WIFSIGNALED (status));
233 :
234 0 : --nruns;
235 :
236 : /* Return token to the jobserver if active. */
237 0 : if (jinfo != NULL && jinfo->is_connected)
238 0 : jinfo->return_token ();
239 0 : }
240 : #endif
241 :
242 : static void
243 8317 : stream_out_partitions_1 (char *temp_filename, int blen, int min, int max)
244 : {
245 : /* Write all the nodes in SET. */
246 16650 : for (int p = min; p < max; p ++)
247 : {
248 8333 : sprintf (temp_filename + blen, "%u.o", p);
249 8333 : stream_out (temp_filename, ltrans_partitions[p]->encoder, p);
250 8333 : ltrans_partitions[p]->encoder = NULL;
251 : }
252 8317 : }
253 :
254 : /* Stream out ENCODER into TEMP_FILENAME
255 : Fork if that seems to help. */
256 :
257 : static void
258 8317 : stream_out_partitions (char *temp_filename, int blen, int min, int max,
259 : bool ARG_UNUSED (last))
260 : {
261 : #ifdef HAVE_WORKING_FORK
262 8317 : if (lto_parallelism <= 1)
263 : {
264 7737 : stream_out_partitions_1 (temp_filename, blen, min, max);
265 7737 : return;
266 : }
267 :
268 580 : if (lto_parallelism > 0 && nruns >= lto_parallelism)
269 0 : wait_for_child ();
270 :
271 : /* If this is not the last parallel partition, execute new
272 : streaming process. */
273 580 : if (!last)
274 : {
275 369 : if (jinfo != NULL && jinfo->is_connected)
276 369 : while (true)
277 : {
278 369 : if (jinfo->get_token ())
279 : break;
280 369 : if (nruns > 0)
281 0 : wait_for_child ();
282 : else
283 : {
284 : /* There are no free tokens, lets do the job ourselves. */
285 369 : stream_out_partitions_1 (temp_filename, blen, min, max);
286 369 : return;
287 : }
288 : }
289 :
290 0 : pid_t cpid = fork ();
291 :
292 0 : if (!cpid)
293 : {
294 0 : setproctitle ("lto1-wpa-streaming");
295 0 : stream_out_partitions_1 (temp_filename, blen, min, max);
296 0 : exit (0);
297 : }
298 : /* Fork failed; lets do the job ourseleves. */
299 0 : else if (cpid == -1)
300 0 : stream_out_partitions_1 (temp_filename, blen, min, max);
301 : else
302 0 : nruns++;
303 : }
304 : /* Last partition; stream it and wait for all children to die. */
305 : else
306 : {
307 211 : stream_out_partitions_1 (temp_filename, blen, min, max);
308 422 : while (nruns > 0)
309 0 : wait_for_child ();
310 :
311 211 : if (jinfo != NULL && jinfo->is_connected)
312 211 : jinfo->disconnect ();
313 : }
314 : #else
315 : stream_out_partitions_1 (temp_filename, blen, min, max);
316 : #endif
317 : }
318 :
319 : /* Write all output files in WPA mode and the file with the list of
320 : LTRANS units. */
321 :
322 : static void
323 7948 : lto_wpa_write_files (void)
324 : {
325 7948 : unsigned i, n_sets;
326 7948 : ltrans_partition part;
327 7948 : FILE *ltrans_output_list_stream;
328 7948 : char *temp_filename;
329 7948 : auto_vec <char *>temp_filenames;
330 7948 : auto_vec <int>temp_priority;
331 7948 : size_t blen;
332 :
333 : /* Open the LTRANS output list. */
334 7948 : if (!ltrans_output_list)
335 0 : fatal_error (input_location, "no LTRANS output list filename provided");
336 :
337 7948 : timevar_push (TV_WHOPR_WPA);
338 :
339 24229 : FOR_EACH_VEC_ELT (ltrans_partitions, i, part)
340 16666 : lto_stats.num_output_symtab_nodes
341 16658 : += lto_symtab_encoder_size (part->encoder);
342 :
343 7948 : timevar_pop (TV_WHOPR_WPA);
344 :
345 7948 : timevar_push (TV_WHOPR_WPA_IO);
346 :
347 7948 : cgraph_node *node;
348 : /* Do body modifications needed for streaming before we fork out
349 : worker processes. */
350 91513 : FOR_EACH_FUNCTION (node)
351 83565 : if (!node->clone_of && gimple_has_body_p (node->decl))
352 5447 : lto_prepare_function_for_streaming (node);
353 :
354 7948 : ggc_trim ();
355 7948 : report_heap_memory_use ();
356 :
357 : /* Generate a prefix for the LTRANS unit files. */
358 7948 : blen = strlen (ltrans_output_list);
359 7948 : temp_filename = (char *) xmalloc (blen + sizeof ("2147483648.o"));
360 7948 : strcpy (temp_filename, ltrans_output_list);
361 7948 : if (blen > sizeof (".out")
362 7948 : && strcmp (temp_filename + blen - sizeof (".out") + 1,
363 : ".out") == 0)
364 7948 : temp_filename[blen - sizeof (".out") + 1] = '\0';
365 7948 : blen = strlen (temp_filename);
366 :
367 7948 : n_sets = ltrans_partitions.length ();
368 7948 : unsigned sets_per_worker = n_sets;
369 7948 : if (lto_parallelism > 1)
370 : {
371 7870 : if (lto_parallelism > (int)n_sets)
372 7866 : lto_parallelism = n_sets;
373 7870 : sets_per_worker = (n_sets + lto_parallelism - 1) / lto_parallelism;
374 : }
375 :
376 : /* Write out all the linemaps since they will be needed during LTRANS. */
377 7948 : sprintf (temp_filename + blen, "%u.o", n_sets);
378 7948 : const auto linemap_filename = xstrdup (temp_filename);
379 7948 : stream_out_linemaps (linemap_filename);
380 :
381 : /* Write out the partitions. */
382 24229 : for (i = 0; i < n_sets; i++)
383 : {
384 8333 : ltrans_partition part = ltrans_partitions[i];
385 :
386 : /* Write all the nodes in SET. */
387 8333 : sprintf (temp_filename + blen, "%u.o", i);
388 :
389 8333 : if (!quiet_flag)
390 0 : fprintf (stderr, " %s (%s %i insns)", temp_filename, part->name,
391 : part->insns);
392 8333 : if (symtab->dump_file)
393 : {
394 1 : lto_symtab_encoder_iterator lsei;
395 :
396 1 : fprintf (symtab->dump_file,
397 : "Writing partition %s to file %s, %i insns\n",
398 : part->name, temp_filename, part->insns);
399 1 : fprintf (symtab->dump_file, " Symbols in partition: ");
400 1 : for (lsei = lsei_start_in_partition (part->encoder);
401 10 : !lsei_end_p (lsei);
402 9 : lsei_next_in_partition (&lsei))
403 : {
404 18 : symtab_node *node = dyn_cast<symtab_node*> (lsei_node (lsei));
405 9 : if (node)
406 9 : fprintf (symtab->dump_file, "%s ", node->dump_asm_name ());
407 : }
408 1 : fprintf (symtab->dump_file, "\n Symbols in boundary: ");
409 10 : for (lsei = lsei_start (part->encoder); !lsei_end_p (lsei);
410 9 : lsei_next (&lsei))
411 : {
412 9 : symtab_node *node = dyn_cast<symtab_node*> (lsei_node (lsei));
413 9 : if (!node)
414 0 : continue;
415 9 : if (!lto_symtab_encoder_in_partition_p (part->encoder, node))
416 : {
417 0 : fprintf (symtab->dump_file, "%s ", node->dump_asm_name ());
418 0 : cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
419 0 : if (cnode
420 0 : && lto_symtab_encoder_encode_body_p (part->encoder,
421 : cnode))
422 0 : fprintf (symtab->dump_file, "(body included)");
423 : else
424 : {
425 9 : varpool_node *vnode = dyn_cast <varpool_node *> (node);
426 0 : if (vnode
427 0 : && lto_symtab_encoder_encode_initializer_p (part->encoder,
428 : vnode))
429 0 : fprintf (symtab->dump_file, "(initializer included)");
430 : }
431 : }
432 : }
433 1 : fprintf (symtab->dump_file, "\n");
434 : }
435 8333 : gcc_checking_assert (lto_symtab_encoder_size (part->encoder) || !i);
436 :
437 8333 : temp_priority.safe_push (part->insns);
438 8333 : temp_filenames.safe_push (xstrdup (temp_filename));
439 : }
440 7948 : memory_block_pool::trim (0);
441 :
442 24213 : for (int set = 0; set < MAX (lto_parallelism, 1); set++)
443 : {
444 8317 : stream_out_partitions (temp_filename, blen, set * sets_per_worker,
445 8317 : MIN ((set + 1) * sets_per_worker, n_sets),
446 8317 : set == MAX (lto_parallelism, 1) - 1);
447 : }
448 :
449 7948 : ltrans_output_list_stream = fopen (ltrans_output_list, "w");
450 7948 : if (ltrans_output_list_stream == NULL)
451 0 : fatal_error (input_location,
452 : "opening LTRANS output list %s: %m", ltrans_output_list);
453 7948 : fprintf (ltrans_output_list_stream, "0\n%s\n", linemap_filename);
454 7948 : free (linemap_filename);
455 16281 : for (i = 0; i < n_sets; i++)
456 : {
457 8333 : unsigned int len = strlen (temp_filenames[i]);
458 8333 : if (fprintf (ltrans_output_list_stream, "%i\n", temp_priority[i]) < 0
459 8333 : || fwrite (temp_filenames[i], 1, len, ltrans_output_list_stream) < len
460 16666 : || fwrite ("\n", 1, 1, ltrans_output_list_stream) < 1)
461 0 : fatal_error (input_location, "writing to LTRANS output list %s: %m",
462 : ltrans_output_list);
463 8333 : free (temp_filenames[i]);
464 : }
465 :
466 7948 : lto_stats.num_output_files += n_sets;
467 :
468 : /* Close the LTRANS output list. */
469 7948 : if (fclose (ltrans_output_list_stream))
470 0 : fatal_error (input_location,
471 : "closing LTRANS output list %s: %m", ltrans_output_list);
472 :
473 7948 : free_ltrans_partitions ();
474 7948 : free (temp_filename);
475 :
476 7948 : timevar_pop (TV_WHOPR_WPA_IO);
477 7948 : }
478 :
479 : /* Create artificial pointers for "omp declare target link" vars. */
480 :
481 : static void
482 0 : offload_handle_link_vars (void)
483 : {
484 : #ifdef ACCEL_COMPILER
485 : size_t i;
486 : varpool_node *var;
487 : auto_vec <varpool_node *>temp_link_vars;
488 : FOR_EACH_VARIABLE (var)
489 : if (lookup_attribute ("omp declare target link",
490 : DECL_ATTRIBUTES (var->decl)))
491 : temp_link_vars.safe_push (var);
492 : FOR_EACH_VEC_ELT (temp_link_vars, i, var)
493 : {
494 : tree type = build_pointer_type (TREE_TYPE (var->decl));
495 : tree link_ptr_var = build_decl (UNKNOWN_LOCATION, VAR_DECL,
496 : clone_function_name (var->decl,
497 : "linkptr"), type);
498 : TREE_USED (link_ptr_var) = 1;
499 : TREE_STATIC (link_ptr_var) = 1;
500 : TREE_PUBLIC (link_ptr_var) = TREE_PUBLIC (var->decl);
501 : DECL_ARTIFICIAL (link_ptr_var) = 1;
502 : SET_DECL_ASSEMBLER_NAME (link_ptr_var, DECL_NAME (link_ptr_var));
503 : SET_DECL_VALUE_EXPR (var->decl, build_simple_mem_ref (link_ptr_var));
504 : DECL_HAS_VALUE_EXPR_P (var->decl) = 1;
505 : varpool_node::finalize_decl (link_ptr_var);
506 : varpool_node::get (link_ptr_var)->force_output = var->force_output;
507 : }
508 : #endif
509 0 : }
510 :
511 : /* Perform whole program analysis (WPA) on the callgraph and write out the
512 : optimization plan. */
513 :
514 : static void
515 7948 : do_whole_program_analysis (void)
516 : {
517 7948 : symtab_node *node;
518 :
519 7948 : lto_parallelism = 1;
520 :
521 7948 : if (!strcmp (flag_wpa, "jobserver"))
522 : {
523 7870 : jinfo = new jobserver_info ();
524 7870 : if (jinfo->is_active)
525 7870 : jinfo->connect ();
526 :
527 7870 : lto_parallelism = param_max_lto_streaming_parallelism;
528 : }
529 : else
530 : {
531 78 : lto_parallelism = atoi (flag_wpa);
532 78 : if (lto_parallelism <= 0)
533 78 : lto_parallelism = 0;
534 78 : if (lto_parallelism >= param_max_lto_streaming_parallelism)
535 0 : lto_parallelism = param_max_lto_streaming_parallelism;
536 : }
537 :
538 7948 : timevar_start (TV_PHASE_OPT_GEN);
539 :
540 : /* Note that since we are in WPA mode, materialize_cgraph will not
541 : actually read in all the function bodies. It only materializes
542 : the decls and cgraph nodes so that analysis can be performed. */
543 7948 : materialize_cgraph ();
544 :
545 : /* Reading in the cgraph uses different timers, start timing WPA now. */
546 7948 : timevar_push (TV_WHOPR_WPA);
547 :
548 7948 : if (pre_ipa_mem_report)
549 0 : dump_memory_report ("Memory consumption before IPA");
550 :
551 7948 : symtab->function_flags_ready = true;
552 :
553 7948 : if (symtab->dump_file)
554 1 : symtab->dump (symtab->dump_file);
555 7948 : bitmap_obstack_initialize (NULL);
556 7948 : symtab->state = IPA_SSA;
557 :
558 7948 : execute_ipa_pass_list (g->get_passes ()->all_regular_ipa_passes);
559 :
560 : /* When WPA analysis raises errors, do not bother to output anything. */
561 7948 : if (seen_error ())
562 : return;
563 :
564 : /* We are about to launch the final LTRANS phase, stop the WPA timer. */
565 7948 : timevar_pop (TV_WHOPR_WPA);
566 :
567 : /* We are no longer going to stream in anything. Free some memory. */
568 7948 : lto_free_file_name_hash ();
569 :
570 :
571 7948 : timevar_push (TV_WHOPR_PARTITIONING);
572 :
573 7948 : gcc_assert (!dump_file);
574 7948 : dump_file = dump_begin (partition_dump_id, NULL);
575 :
576 7948 : if (dump_file)
577 0 : symtab->dump (dump_file);
578 :
579 7948 : symtab_node::checking_verify_symtab_nodes ();
580 7948 : bitmap_obstack_release (NULL);
581 7948 : if (flag_ipa_reorder_for_locality)
582 0 : lto_locality_map (param_max_locality_partition_size);
583 7948 : else if (flag_lto_partition == LTO_PARTITION_1TO1)
584 313 : lto_1_to_1_map ();
585 : else if (flag_lto_partition == LTO_PARTITION_MAX)
586 15 : lto_max_map ();
587 : else if (flag_lto_partition == LTO_PARTITION_ONE)
588 72 : lto_balanced_map (1, INT_MAX);
589 : else if (flag_lto_partition == LTO_PARTITION_BALANCED)
590 7544 : lto_balanced_map (param_lto_partitions,
591 : param_max_partition_size);
592 : else if (flag_lto_partition == LTO_PARTITION_CACHE)
593 4 : lto_cache_map (param_lto_partitions, param_max_partition_size);
594 : else
595 0 : gcc_unreachable ();
596 :
597 : /* Size summaries are needed for balanced partitioning. Free them now so
598 : the memory can be used for streamer caches. */
599 7948 : ipa_free_size_summary ();
600 :
601 : /* AUX pointers are used by partitioning code to bookkeep number of
602 : partitions symbol is in. This is no longer needed. */
603 116319 : FOR_EACH_SYMBOL (node)
604 108371 : node->aux = NULL;
605 :
606 7948 : lto_stats.num_cgraph_partitions += ltrans_partitions.length ();
607 :
608 : /* Find out statics that need to be promoted
609 : to globals with hidden visibility because they are accessed from multiple
610 : partitions. */
611 7948 : lto_promote_cross_file_statics ();
612 7948 : offload_handle_link_vars ();
613 7948 : if (dump_file)
614 0 : dump_end (partition_dump_id, dump_file);
615 7948 : dump_file = NULL;
616 7948 : timevar_pop (TV_WHOPR_PARTITIONING);
617 :
618 7948 : timevar_stop (TV_PHASE_OPT_GEN);
619 :
620 : /* Collect a last time - in lto_wpa_write_files we may end up forking
621 : with the idea that this doesn't increase memory usage. So we
622 : absolutely do not want to collect after that. */
623 7948 : ggc_collect ();
624 :
625 7948 : timevar_start (TV_PHASE_STREAM_OUT);
626 7948 : if (!quiet_flag)
627 : {
628 0 : fprintf (stderr, "\nStreaming out");
629 0 : fflush (stderr);
630 : }
631 7948 : lto_wpa_write_files ();
632 7948 : if (!quiet_flag)
633 0 : fprintf (stderr, "\n");
634 7948 : timevar_stop (TV_PHASE_STREAM_OUT);
635 :
636 7948 : if (post_ipa_mem_report)
637 0 : dump_memory_report ("Memory consumption after IPA");
638 :
639 : /* Show the LTO report before launching LTRANS. */
640 7948 : if (flag_lto_report || (flag_wpa && flag_lto_report_wpa))
641 0 : print_lto_report_1 ();
642 7948 : if (mem_report_wpa)
643 0 : dump_memory_report ("Final");
644 : }
645 :
646 : unsigned int
647 45512 : lto_option_lang_mask (void)
648 : {
649 45512 : return CL_LTO;
650 : }
651 :
652 : /* Main entry point for the GIMPLE front end. This front end has
653 : three main personalities:
654 :
655 : - LTO (-flto). All the object files on the command line are
656 : loaded in memory and processed as a single translation unit.
657 : This is the traditional link-time optimization behavior.
658 :
659 : - WPA (-fwpa). Only the callgraph and summary information for
660 : files in the command file are loaded. A single callgraph
661 : (without function bodies) is instantiated for the whole set of
662 : files. IPA passes are only allowed to analyze the call graph
663 : and make transformation decisions. The callgraph is
664 : partitioned, each partition is written to a new object file
665 : together with the transformation decisions.
666 :
667 : - LTRANS (-fltrans). Similar to -flto but it prevents the IPA
668 : summary files from running again. Since WPA computed summary
669 : information and decided what transformations to apply, LTRANS
670 : simply applies them. */
671 :
672 : void
673 20801 : lto_main (void)
674 : {
675 : /* LTO is called as a front end, even though it is not a front end.
676 : Because it is called as a front end, TV_PHASE_PARSING and
677 : TV_PARSE_GLOBAL are active, and we need to turn them off while
678 : doing LTO. Later we turn them back on so they are active up in
679 : toplev.cc. */
680 20801 : timevar_pop (TV_PARSE_GLOBAL);
681 20801 : timevar_stop (TV_PHASE_PARSING);
682 :
683 20801 : timevar_start (TV_PHASE_SETUP);
684 :
685 : /* Initialize the LTO front end. */
686 20801 : lto_fe_init ();
687 :
688 20801 : timevar_stop (TV_PHASE_SETUP);
689 20801 : timevar_start (TV_PHASE_STREAM_IN);
690 :
691 : /* Read all the symbols and call graph from all the files in the
692 : command line. */
693 20801 : read_cgraph_and_symbols (num_in_fnames, in_fnames);
694 :
695 20801 : timevar_stop (TV_PHASE_STREAM_IN);
696 :
697 20801 : if (!seen_error ())
698 : {
699 : /* If WPA is enabled analyze the whole call graph and create an
700 : optimization plan. Otherwise, read in all the function
701 : bodies and continue with optimization. */
702 20801 : if (flag_wpa)
703 7948 : do_whole_program_analysis ();
704 : else
705 : {
706 12853 : timevar_start (TV_PHASE_OPT_GEN);
707 :
708 12853 : materialize_cgraph ();
709 12853 : if (!flag_ltrans)
710 : {
711 4520 : lto_promote_statics_nonwpa ();
712 4520 : offload_handle_link_vars ();
713 : }
714 :
715 : /* Annotate the CU DIE and mark the early debug phase as finished. */
716 12853 : debuginfo_early_start ();
717 12853 : debug_hooks->early_finish ("<artificial>");
718 12853 : debuginfo_early_stop ();
719 :
720 : /* Let the middle end know that we have read and merged all of
721 : the input files. */
722 12853 : symtab->compile ();
723 :
724 12853 : timevar_stop (TV_PHASE_OPT_GEN);
725 :
726 : /* FIXME lto, if the processes spawned by WPA fail, we miss
727 : the chance to print WPA's report, so WPA will call
728 : print_lto_report before launching LTRANS. If LTRANS was
729 : launched directly by the driver we would not need to do
730 : this. */
731 12853 : if (flag_lto_report || (flag_wpa && flag_lto_report_wpa))
732 0 : print_lto_report_1 ();
733 : }
734 : }
735 :
736 : /* Here we make LTO pretend to be a parser. */
737 20801 : timevar_start (TV_PHASE_PARSING);
738 20801 : timevar_push (TV_PARSE_GLOBAL);
739 20801 : }
|