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 52405 : has_analyzed_clone_p (struct cgraph_node *node)
78 : {
79 52405 : struct cgraph_node *orig = node;
80 52405 : node = node->clones;
81 52405 : if (node)
82 3723 : while (node != orig)
83 : {
84 3723 : if (node->analyzed)
85 : return true;
86 432 : 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 192617 : lto_materialize_function (struct cgraph_node *node)
105 : {
106 192617 : tree decl;
107 :
108 192617 : decl = node->decl;
109 : /* Read in functions with body (analyzed nodes)
110 : and also functions that are needed to produce virtual clones. */
111 139723 : if ((node->has_gimple_body_p () && node->analyzed)
112 52895 : || node->used_as_abstract_origin
113 245022 : || has_analyzed_clone_p (node))
114 : {
115 : /* Clones don't need to be read. */
116 143503 : if (node->clone_of)
117 : return;
118 120525 : if (DECL_FUNCTION_PERSONALITY (decl) && !first_personality_decl)
119 649 : 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 120525 : if (DECL_FUNCTION_PERSONALITY (decl)
124 120525 : || opt_for_fn (decl, flag_exceptions))
125 42465 : lto_init_eh ();
126 : }
127 :
128 : /* Let the middle end know about the function. */
129 169639 : 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 20392 : materialize_cgraph (void)
136 : {
137 20392 : struct cgraph_node *node;
138 20392 : timevar_id_t lto_timer;
139 :
140 20392 : 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 24777 : lto_timer = (flag_wpa) ? TV_WHOPR_WPA
147 12575 : : (flag_ltrans) ? TV_WHOPR_LTRANS
148 : : TV_LTO;
149 20392 : timevar_push (lto_timer);
150 :
151 213009 : FOR_EACH_FUNCTION (node)
152 : {
153 192617 : if (node->lto_file_data)
154 : {
155 192617 : lto_materialize_function (node);
156 192617 : lto_stats.num_input_cgraph_nodes++;
157 : }
158 : }
159 :
160 20392 : current_function_decl = NULL;
161 20392 : set_cfun (NULL);
162 :
163 20392 : if (!quiet_flag)
164 0 : fprintf (stderr, "\n");
165 :
166 20392 : timevar_pop (lto_timer);
167 20392 : }
168 :
169 : /* Actually stream out ENCODER into TEMP_FILENAME. */
170 :
171 : static void
172 8190 : stream_out (char *temp_filename, lto_symtab_encoder_t encoder, int part)
173 : {
174 8190 : lto_file *file = lto_obj_file_open (temp_filename, true);
175 8190 : if (!file)
176 0 : fatal_error (input_location, "%<lto_obj_file_open()%> failed");
177 8190 : lto_set_current_out_file (file);
178 :
179 8190 : gcc_assert (!dump_file);
180 8190 : streamer_dump_file = dump_begin (TDI_lto_stream_out, NULL, part);
181 8190 : ipa_write_optimization_summaries (encoder, part == 0);
182 :
183 8190 : free (const_cast<char *> (file->filename));
184 :
185 8190 : lto_set_current_out_file (NULL);
186 8190 : lto_obj_file_close (file);
187 8190 : free (file);
188 8190 : if (streamer_dump_file)
189 : {
190 0 : dump_end (TDI_lto_stream_out, streamer_dump_file);
191 0 : streamer_dump_file = NULL;
192 : }
193 8190 : }
194 :
195 : /* Wait for forked process and signal errors. */
196 : #ifdef HAVE_WORKING_FORK
197 : static void
198 0 : wait_for_child ()
199 : {
200 0 : int status;
201 0 : do
202 : {
203 : #ifndef WCONTINUED
204 : #define WCONTINUED 0
205 : #endif
206 0 : int w = waitpid (0, &status, WUNTRACED | WCONTINUED);
207 0 : if (w == -1)
208 0 : fatal_error (input_location, "waitpid failed");
209 :
210 0 : if (WIFEXITED (status) && WEXITSTATUS (status))
211 0 : fatal_error (input_location, "streaming subprocess failed");
212 0 : else if (WIFSIGNALED (status))
213 0 : fatal_error (input_location,
214 : "streaming subprocess was killed by signal");
215 : }
216 0 : while (!WIFEXITED (status) && !WIFSIGNALED (status));
217 :
218 0 : --nruns;
219 :
220 : /* Return token to the jobserver if active. */
221 0 : if (jinfo != NULL && jinfo->is_connected)
222 0 : jinfo->return_token ();
223 0 : }
224 : #endif
225 :
226 : static void
227 8174 : stream_out_partitions_1 (char *temp_filename, int blen, int min, int max)
228 : {
229 : /* Write all the nodes in SET. */
230 16364 : for (int p = min; p < max; p ++)
231 : {
232 8190 : sprintf (temp_filename + blen, "%u.o", p);
233 8190 : stream_out (temp_filename, ltrans_partitions[p]->encoder, p);
234 8190 : ltrans_partitions[p]->encoder = NULL;
235 : }
236 8174 : }
237 :
238 : /* Stream out ENCODER into TEMP_FILENAME
239 : Fork if that seems to help. */
240 :
241 : static void
242 8174 : stream_out_partitions (char *temp_filename, int blen, int min, int max,
243 : bool ARG_UNUSED (last))
244 : {
245 : #ifdef HAVE_WORKING_FORK
246 8174 : if (lto_parallelism <= 1)
247 : {
248 7616 : stream_out_partitions_1 (temp_filename, blen, min, max);
249 7616 : return;
250 : }
251 :
252 558 : if (lto_parallelism > 0 && nruns >= lto_parallelism)
253 0 : wait_for_child ();
254 :
255 : /* If this is not the last parallel partition, execute new
256 : streaming process. */
257 558 : if (!last)
258 : {
259 357 : if (jinfo != NULL && jinfo->is_connected)
260 357 : while (true)
261 : {
262 357 : if (jinfo->get_token ())
263 : break;
264 357 : if (nruns > 0)
265 0 : wait_for_child ();
266 : else
267 : {
268 : /* There are no free tokens, lets do the job outselves. */
269 357 : stream_out_partitions_1 (temp_filename, blen, min, max);
270 357 : return;
271 : }
272 : }
273 :
274 0 : pid_t cpid = fork ();
275 :
276 0 : if (!cpid)
277 : {
278 0 : setproctitle ("lto1-wpa-streaming");
279 0 : stream_out_partitions_1 (temp_filename, blen, min, max);
280 0 : exit (0);
281 : }
282 : /* Fork failed; lets do the job ourseleves. */
283 0 : else if (cpid == -1)
284 0 : stream_out_partitions_1 (temp_filename, blen, min, max);
285 : else
286 0 : nruns++;
287 : }
288 : /* Last partition; stream it and wait for all children to die. */
289 : else
290 : {
291 201 : stream_out_partitions_1 (temp_filename, blen, min, max);
292 402 : while (nruns > 0)
293 0 : wait_for_child ();
294 :
295 201 : if (jinfo != NULL && jinfo->is_connected)
296 201 : jinfo->disconnect ();
297 : }
298 : #else
299 : stream_out_partitions_1 (temp_filename, blen, min, max);
300 : #endif
301 : }
302 :
303 : /* Write all output files in WPA mode and the file with the list of
304 : LTRANS units. */
305 :
306 : static void
307 7817 : lto_wpa_write_files (void)
308 : {
309 7817 : unsigned i, n_sets;
310 7817 : ltrans_partition part;
311 7817 : FILE *ltrans_output_list_stream;
312 7817 : char *temp_filename;
313 7817 : auto_vec <char *>temp_filenames;
314 7817 : auto_vec <int>temp_priority;
315 7817 : size_t blen;
316 :
317 : /* Open the LTRANS output list. */
318 7817 : if (!ltrans_output_list)
319 0 : fatal_error (input_location, "no LTRANS output list filename provided");
320 :
321 7817 : timevar_push (TV_WHOPR_WPA);
322 :
323 23824 : FOR_EACH_VEC_ELT (ltrans_partitions, i, part)
324 16380 : lto_stats.num_output_symtab_nodes
325 16372 : += lto_symtab_encoder_size (part->encoder);
326 :
327 7817 : timevar_pop (TV_WHOPR_WPA);
328 :
329 7817 : timevar_push (TV_WHOPR_WPA_IO);
330 :
331 7817 : cgraph_node *node;
332 : /* Do body modifications needed for streaming before we fork out
333 : worker processes. */
334 90195 : FOR_EACH_FUNCTION (node)
335 82378 : if (!node->clone_of && gimple_has_body_p (node->decl))
336 5430 : lto_prepare_function_for_streaming (node);
337 :
338 7817 : ggc_trim ();
339 7817 : report_heap_memory_use ();
340 :
341 : /* Generate a prefix for the LTRANS unit files. */
342 7817 : blen = strlen (ltrans_output_list);
343 7817 : temp_filename = (char *) xmalloc (blen + sizeof ("2147483648.o"));
344 7817 : strcpy (temp_filename, ltrans_output_list);
345 7817 : if (blen > sizeof (".out")
346 7817 : && strcmp (temp_filename + blen - sizeof (".out") + 1,
347 : ".out") == 0)
348 7817 : temp_filename[blen - sizeof (".out") + 1] = '\0';
349 7817 : blen = strlen (temp_filename);
350 :
351 7817 : n_sets = ltrans_partitions.length ();
352 7817 : unsigned sets_per_worker = n_sets;
353 7817 : if (lto_parallelism > 1)
354 : {
355 7739 : if (lto_parallelism > (int)n_sets)
356 7735 : lto_parallelism = n_sets;
357 7739 : sets_per_worker = (n_sets + lto_parallelism - 1) / lto_parallelism;
358 : }
359 :
360 16007 : for (i = 0; i < n_sets; i++)
361 : {
362 8190 : ltrans_partition part = ltrans_partitions[i];
363 :
364 : /* Write all the nodes in SET. */
365 8190 : sprintf (temp_filename + blen, "%u.o", i);
366 :
367 8190 : if (!quiet_flag)
368 0 : fprintf (stderr, " %s (%s %i insns)", temp_filename, part->name,
369 : part->insns);
370 8190 : if (symtab->dump_file)
371 : {
372 1 : lto_symtab_encoder_iterator lsei;
373 :
374 1 : fprintf (symtab->dump_file,
375 : "Writing partition %s to file %s, %i insns\n",
376 : part->name, temp_filename, part->insns);
377 1 : fprintf (symtab->dump_file, " Symbols in partition: ");
378 1 : for (lsei = lsei_start_in_partition (part->encoder);
379 10 : !lsei_end_p (lsei);
380 9 : lsei_next_in_partition (&lsei))
381 : {
382 18 : symtab_node *node = dyn_cast<symtab_node*> (lsei_node (lsei));
383 9 : if (node)
384 9 : fprintf (symtab->dump_file, "%s ", node->dump_asm_name ());
385 : }
386 1 : fprintf (symtab->dump_file, "\n Symbols in boundary: ");
387 10 : for (lsei = lsei_start (part->encoder); !lsei_end_p (lsei);
388 9 : lsei_next (&lsei))
389 : {
390 9 : symtab_node *node = dyn_cast<symtab_node*> (lsei_node (lsei));
391 9 : if (!node)
392 0 : continue;
393 9 : if (!lto_symtab_encoder_in_partition_p (part->encoder, node))
394 : {
395 0 : fprintf (symtab->dump_file, "%s ", node->dump_asm_name ());
396 0 : cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
397 0 : if (cnode
398 0 : && lto_symtab_encoder_encode_body_p (part->encoder,
399 : cnode))
400 0 : fprintf (symtab->dump_file, "(body included)");
401 : else
402 : {
403 9 : varpool_node *vnode = dyn_cast <varpool_node *> (node);
404 0 : if (vnode
405 0 : && lto_symtab_encoder_encode_initializer_p (part->encoder,
406 : vnode))
407 0 : fprintf (symtab->dump_file, "(initializer included)");
408 : }
409 : }
410 : }
411 1 : fprintf (symtab->dump_file, "\n");
412 : }
413 8190 : gcc_checking_assert (lto_symtab_encoder_size (part->encoder) || !i);
414 :
415 8190 : temp_priority.safe_push (part->insns);
416 8190 : temp_filenames.safe_push (xstrdup (temp_filename));
417 : }
418 7817 : memory_block_pool::trim (0);
419 :
420 15991 : for (int set = 0; set < MAX (lto_parallelism, 1); set++)
421 : {
422 8174 : stream_out_partitions (temp_filename, blen, set * sets_per_worker,
423 8174 : MIN ((set + 1) * sets_per_worker, n_sets),
424 8174 : set == MAX (lto_parallelism, 1) - 1);
425 : }
426 :
427 7817 : ltrans_output_list_stream = fopen (ltrans_output_list, "w");
428 7817 : if (ltrans_output_list_stream == NULL)
429 0 : fatal_error (input_location,
430 : "opening LTRANS output list %s: %m", ltrans_output_list);
431 16007 : for (i = 0; i < n_sets; i++)
432 : {
433 8190 : unsigned int len = strlen (temp_filenames[i]);
434 8190 : if (fprintf (ltrans_output_list_stream, "%i\n", temp_priority[i]) < 0
435 8190 : || fwrite (temp_filenames[i], 1, len, ltrans_output_list_stream) < len
436 16380 : || fwrite ("\n", 1, 1, ltrans_output_list_stream) < 1)
437 0 : fatal_error (input_location, "writing to LTRANS output list %s: %m",
438 : ltrans_output_list);
439 8190 : free (temp_filenames[i]);
440 : }
441 :
442 7817 : lto_stats.num_output_files += n_sets;
443 :
444 : /* Close the LTRANS output list. */
445 7817 : if (fclose (ltrans_output_list_stream))
446 0 : fatal_error (input_location,
447 : "closing LTRANS output list %s: %m", ltrans_output_list);
448 :
449 7817 : free_ltrans_partitions ();
450 7817 : free (temp_filename);
451 :
452 7817 : timevar_pop (TV_WHOPR_WPA_IO);
453 7817 : }
454 :
455 : /* Create artificial pointers for "omp declare target link" vars. */
456 :
457 : static void
458 4385 : offload_handle_link_vars (void)
459 : {
460 : #ifdef ACCEL_COMPILER
461 : varpool_node *var;
462 : FOR_EACH_VARIABLE (var)
463 : if (lookup_attribute ("omp declare target link",
464 : DECL_ATTRIBUTES (var->decl)))
465 : {
466 : tree type = build_pointer_type (TREE_TYPE (var->decl));
467 : tree link_ptr_var = build_decl (UNKNOWN_LOCATION, VAR_DECL,
468 : clone_function_name (var->decl,
469 : "linkptr"), type);
470 : TREE_USED (link_ptr_var) = 1;
471 : TREE_STATIC (link_ptr_var) = 1;
472 : TREE_PUBLIC (link_ptr_var) = TREE_PUBLIC (var->decl);
473 : DECL_ARTIFICIAL (link_ptr_var) = 1;
474 : SET_DECL_ASSEMBLER_NAME (link_ptr_var, DECL_NAME (link_ptr_var));
475 : SET_DECL_VALUE_EXPR (var->decl, build_simple_mem_ref (link_ptr_var));
476 : DECL_HAS_VALUE_EXPR_P (var->decl) = 1;
477 : }
478 : #endif
479 4385 : }
480 :
481 : /* Perform whole program analysis (WPA) on the callgraph and write out the
482 : optimization plan. */
483 :
484 : static void
485 7817 : do_whole_program_analysis (void)
486 : {
487 7817 : symtab_node *node;
488 :
489 7817 : lto_parallelism = 1;
490 :
491 7817 : if (!strcmp (flag_wpa, "jobserver"))
492 : {
493 7739 : jinfo = new jobserver_info ();
494 7739 : if (jinfo->is_active)
495 7739 : jinfo->connect ();
496 :
497 7739 : lto_parallelism = param_max_lto_streaming_parallelism;
498 : }
499 : else
500 : {
501 78 : lto_parallelism = atoi (flag_wpa);
502 78 : if (lto_parallelism <= 0)
503 78 : lto_parallelism = 0;
504 78 : if (lto_parallelism >= param_max_lto_streaming_parallelism)
505 0 : lto_parallelism = param_max_lto_streaming_parallelism;
506 : }
507 :
508 7817 : timevar_start (TV_PHASE_OPT_GEN);
509 :
510 : /* Note that since we are in WPA mode, materialize_cgraph will not
511 : actually read in all the function bodies. It only materializes
512 : the decls and cgraph nodes so that analysis can be performed. */
513 7817 : materialize_cgraph ();
514 :
515 : /* Reading in the cgraph uses different timers, start timing WPA now. */
516 7817 : timevar_push (TV_WHOPR_WPA);
517 :
518 7817 : if (pre_ipa_mem_report)
519 0 : dump_memory_report ("Memory consumption before IPA");
520 :
521 7817 : symtab->function_flags_ready = true;
522 :
523 7817 : if (symtab->dump_file)
524 1 : symtab->dump (symtab->dump_file);
525 7817 : bitmap_obstack_initialize (NULL);
526 7817 : symtab->state = IPA_SSA;
527 :
528 7817 : execute_ipa_pass_list (g->get_passes ()->all_regular_ipa_passes);
529 :
530 : /* When WPA analysis raises errors, do not bother to output anything. */
531 7817 : if (seen_error ())
532 : return;
533 :
534 : /* We are about to launch the final LTRANS phase, stop the WPA timer. */
535 7817 : timevar_pop (TV_WHOPR_WPA);
536 :
537 : /* We are no longer going to stream in anything. Free some memory. */
538 7817 : lto_free_file_name_hash ();
539 :
540 :
541 7817 : timevar_push (TV_WHOPR_PARTITIONING);
542 :
543 7817 : gcc_assert (!dump_file);
544 7817 : dump_file = dump_begin (partition_dump_id, NULL);
545 :
546 7817 : if (dump_file)
547 0 : symtab->dump (dump_file);
548 :
549 7817 : symtab_node::checking_verify_symtab_nodes ();
550 7817 : bitmap_obstack_release (NULL);
551 7817 : if (flag_ipa_reorder_for_locality)
552 0 : lto_locality_map (param_max_locality_partition_size);
553 7817 : else if (flag_lto_partition == LTO_PARTITION_1TO1)
554 303 : lto_1_to_1_map ();
555 : else if (flag_lto_partition == LTO_PARTITION_MAX)
556 15 : lto_max_map ();
557 : else if (flag_lto_partition == LTO_PARTITION_ONE)
558 70 : lto_balanced_map (1, INT_MAX);
559 : else if (flag_lto_partition == LTO_PARTITION_BALANCED)
560 7425 : lto_balanced_map (param_lto_partitions,
561 : param_max_partition_size);
562 : else if (flag_lto_partition == LTO_PARTITION_CACHE)
563 4 : lto_cache_map (param_lto_partitions, param_max_partition_size);
564 : else
565 0 : gcc_unreachable ();
566 :
567 : /* Size summaries are needed for balanced partitioning. Free them now so
568 : the memory can be used for streamer caches. */
569 7817 : ipa_free_size_summary ();
570 :
571 : /* AUX pointers are used by partitioning code to bookkeep number of
572 : partitions symbol is in. This is no longer needed. */
573 114702 : FOR_EACH_SYMBOL (node)
574 106885 : node->aux = NULL;
575 :
576 7817 : lto_stats.num_cgraph_partitions += ltrans_partitions.length ();
577 :
578 : /* Find out statics that need to be promoted
579 : to globals with hidden visibility because they are accessed from multiple
580 : partitions. */
581 7817 : lto_promote_cross_file_statics ();
582 7817 : offload_handle_link_vars ();
583 7817 : if (dump_file)
584 0 : dump_end (partition_dump_id, dump_file);
585 7817 : dump_file = NULL;
586 7817 : timevar_pop (TV_WHOPR_PARTITIONING);
587 :
588 7817 : timevar_stop (TV_PHASE_OPT_GEN);
589 :
590 : /* Collect a last time - in lto_wpa_write_files we may end up forking
591 : with the idea that this doesn't increase memory usage. So we
592 : absoultely do not want to collect after that. */
593 7817 : ggc_collect ();
594 :
595 7817 : timevar_start (TV_PHASE_STREAM_OUT);
596 7817 : if (!quiet_flag)
597 : {
598 0 : fprintf (stderr, "\nStreaming out");
599 0 : fflush (stderr);
600 : }
601 7817 : lto_wpa_write_files ();
602 7817 : if (!quiet_flag)
603 0 : fprintf (stderr, "\n");
604 7817 : timevar_stop (TV_PHASE_STREAM_OUT);
605 :
606 7817 : if (post_ipa_mem_report)
607 0 : dump_memory_report ("Memory consumption after IPA");
608 :
609 : /* Show the LTO report before launching LTRANS. */
610 7817 : if (flag_lto_report || (flag_wpa && flag_lto_report_wpa))
611 0 : print_lto_report_1 ();
612 7817 : if (mem_report_wpa)
613 0 : dump_memory_report ("Final");
614 : }
615 :
616 : unsigned int
617 44527 : lto_option_lang_mask (void)
618 : {
619 44527 : return CL_LTO;
620 : }
621 :
622 : /* Main entry point for the GIMPLE front end. This front end has
623 : three main personalities:
624 :
625 : - LTO (-flto). All the object files on the command line are
626 : loaded in memory and processed as a single translation unit.
627 : This is the traditional link-time optimization behavior.
628 :
629 : - WPA (-fwpa). Only the callgraph and summary information for
630 : files in the command file are loaded. A single callgraph
631 : (without function bodies) is instantiated for the whole set of
632 : files. IPA passes are only allowed to analyze the call graph
633 : and make transformation decisions. The callgraph is
634 : partitioned, each partition is written to a new object file
635 : together with the transformation decisions.
636 :
637 : - LTRANS (-fltrans). Similar to -flto but it prevents the IPA
638 : summary files from running again. Since WPA computed summary
639 : information and decided what transformations to apply, LTRANS
640 : simply applies them. */
641 :
642 : void
643 20392 : lto_main (void)
644 : {
645 : /* LTO is called as a front end, even though it is not a front end.
646 : Because it is called as a front end, TV_PHASE_PARSING and
647 : TV_PARSE_GLOBAL are active, and we need to turn them off while
648 : doing LTO. Later we turn them back on so they are active up in
649 : toplev.cc. */
650 20392 : timevar_pop (TV_PARSE_GLOBAL);
651 20392 : timevar_stop (TV_PHASE_PARSING);
652 :
653 20392 : timevar_start (TV_PHASE_SETUP);
654 :
655 : /* Initialize the LTO front end. */
656 20392 : lto_fe_init ();
657 :
658 20392 : timevar_stop (TV_PHASE_SETUP);
659 20392 : timevar_start (TV_PHASE_STREAM_IN);
660 :
661 : /* Read all the symbols and call graph from all the files in the
662 : command line. */
663 20392 : read_cgraph_and_symbols (num_in_fnames, in_fnames);
664 :
665 20392 : timevar_stop (TV_PHASE_STREAM_IN);
666 :
667 20392 : if (!seen_error ())
668 : {
669 20392 : offload_handle_link_vars ();
670 :
671 : /* If WPA is enabled analyze the whole call graph and create an
672 : optimization plan. Otherwise, read in all the function
673 : bodies and continue with optimization. */
674 20392 : if (flag_wpa)
675 7817 : do_whole_program_analysis ();
676 : else
677 : {
678 12575 : timevar_start (TV_PHASE_OPT_GEN);
679 :
680 12575 : materialize_cgraph ();
681 12575 : if (!flag_ltrans)
682 : {
683 4385 : lto_promote_statics_nonwpa ();
684 4385 : offload_handle_link_vars ();
685 : }
686 :
687 : /* Annotate the CU DIE and mark the early debug phase as finished. */
688 12575 : debuginfo_early_start ();
689 12575 : debug_hooks->early_finish ("<artificial>");
690 12575 : debuginfo_early_stop ();
691 :
692 : /* Let the middle end know that we have read and merged all of
693 : the input files. */
694 12575 : symtab->compile ();
695 :
696 12575 : timevar_stop (TV_PHASE_OPT_GEN);
697 :
698 : /* FIXME lto, if the processes spawned by WPA fail, we miss
699 : the chance to print WPA's report, so WPA will call
700 : print_lto_report before launching LTRANS. If LTRANS was
701 : launched directly by the driver we would not need to do
702 : this. */
703 12575 : if (flag_lto_report || (flag_wpa && flag_lto_report_wpa))
704 0 : print_lto_report_1 ();
705 : }
706 : }
707 :
708 : /* Here we make LTO pretend to be a parser. */
709 20392 : timevar_start (TV_PHASE_PARSING);
710 20392 : timevar_push (TV_PARSE_GLOBAL);
711 20392 : }
|