Branch data Line data Source code
1 : : /* Top-level LTO routines.
2 : : Copyright (C) 2009-2025 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 : 51456 : has_analyzed_clone_p (struct cgraph_node *node)
78 : : {
79 : 51456 : struct cgraph_node *orig = node;
80 : 51456 : node = node->clones;
81 : 51456 : if (node)
82 : 3346 : while (node != orig)
83 : : {
84 : 3346 : if (node->analyzed)
85 : : return true;
86 : 412 : 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 : 199271 : lto_materialize_function (struct cgraph_node *node)
105 : : {
106 : 199271 : tree decl;
107 : :
108 : 199271 : decl = node->decl;
109 : : /* Read in functions with body (analyzed nodes)
110 : : and also functions that are needed to produce virtual clones. */
111 : 147472 : if ((node->has_gimple_body_p () && node->analyzed)
112 : 51800 : || node->used_as_abstract_origin
113 : 250727 : || has_analyzed_clone_p (node))
114 : : {
115 : : /* Clones don't need to be read. */
116 : 150749 : if (node->clone_of)
117 : : return;
118 : 121824 : if (DECL_FUNCTION_PERSONALITY (decl) && !first_personality_decl)
119 : 655 : 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 : 121824 : if (DECL_FUNCTION_PERSONALITY (decl)
124 : 121824 : || opt_for_fn (decl, flag_exceptions))
125 : 42463 : lto_init_eh ();
126 : : }
127 : :
128 : : /* Let the middle end know about the function. */
129 : 170346 : 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 : 22373 : materialize_cgraph (void)
136 : : {
137 : 22373 : struct cgraph_node *node;
138 : 22373 : timevar_id_t lto_timer;
139 : :
140 : 22373 : 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 : 26722 : lto_timer = (flag_wpa) ? TV_WHOPR_WPA
147 : 13555 : : (flag_ltrans) ? TV_WHOPR_LTRANS
148 : : : TV_LTO;
149 : 22373 : timevar_push (lto_timer);
150 : :
151 : 443288 : FOR_EACH_FUNCTION (node)
152 : : {
153 : 199271 : if (node->lto_file_data)
154 : : {
155 : 199271 : lto_materialize_function (node);
156 : 199271 : lto_stats.num_input_cgraph_nodes++;
157 : : }
158 : : }
159 : :
160 : 22373 : current_function_decl = NULL;
161 : 22373 : set_cfun (NULL);
162 : :
163 : 22373 : if (!quiet_flag)
164 : 0 : fprintf (stderr, "\n");
165 : :
166 : 22373 : timevar_pop (lto_timer);
167 : 22373 : }
168 : :
169 : : /* Actually stream out ENCODER into TEMP_FILENAME. */
170 : :
171 : : static void
172 : 9206 : stream_out (char *temp_filename, lto_symtab_encoder_t encoder, int part)
173 : : {
174 : 9206 : lto_file *file = lto_obj_file_open (temp_filename, true);
175 : 9206 : if (!file)
176 : 0 : fatal_error (input_location, "%<lto_obj_file_open()%> failed");
177 : 9206 : lto_set_current_out_file (file);
178 : :
179 : 9206 : gcc_assert (!dump_file);
180 : 9206 : streamer_dump_file = dump_begin (TDI_lto_stream_out, NULL, part);
181 : 9206 : ipa_write_optimization_summaries (encoder, part == 0);
182 : :
183 : 9206 : free (CONST_CAST (char *, file->filename));
184 : :
185 : 9206 : lto_set_current_out_file (NULL);
186 : 9206 : lto_obj_file_close (file);
187 : 9206 : free (file);
188 : 9206 : if (streamer_dump_file)
189 : : {
190 : 0 : dump_end (TDI_lto_stream_out, streamer_dump_file);
191 : 0 : streamer_dump_file = NULL;
192 : : }
193 : 9206 : }
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 : 9190 : stream_out_partitions_1 (char *temp_filename, int blen, int min, int max)
228 : : {
229 : : /* Write all the nodes in SET. */
230 : 18396 : for (int p = min; p < max; p ++)
231 : : {
232 : 9206 : sprintf (temp_filename + blen, "%u.o", p);
233 : 9206 : stream_out (temp_filename, ltrans_partitions[p]->encoder, p);
234 : 9206 : ltrans_partitions[p]->encoder = NULL;
235 : : }
236 : 9190 : }
237 : :
238 : : /* Stream out ENCODER into TEMP_FILENAME
239 : : Fork if that seems to help. */
240 : :
241 : : static void
242 : 9190 : stream_out_partitions (char *temp_filename, int blen, int min, int max,
243 : : bool ARG_UNUSED (last))
244 : : {
245 : : #ifdef HAVE_WORKING_FORK
246 : 9190 : if (lto_parallelism <= 1)
247 : : {
248 : 8600 : stream_out_partitions_1 (temp_filename, blen, min, max);
249 : 8600 : return;
250 : : }
251 : :
252 : 590 : 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 : 590 : if (!last)
258 : : {
259 : 372 : if (jinfo != NULL && jinfo->is_connected)
260 : 372 : while (true)
261 : : {
262 : 372 : if (jinfo->get_token ())
263 : : break;
264 : 372 : if (nruns > 0)
265 : 0 : wait_for_child ();
266 : : else
267 : : {
268 : : /* There are no free tokens, lets do the job outselves. */
269 : 372 : stream_out_partitions_1 (temp_filename, blen, min, max);
270 : 372 : 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 : 218 : stream_out_partitions_1 (temp_filename, blen, min, max);
292 : 436 : while (nruns > 0)
293 : 0 : wait_for_child ();
294 : :
295 : 218 : if (jinfo != NULL && jinfo->is_connected)
296 : 218 : 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 : 8818 : lto_wpa_write_files (void)
308 : : {
309 : 8818 : unsigned i, n_sets;
310 : 8818 : ltrans_partition part;
311 : 8818 : FILE *ltrans_output_list_stream;
312 : 8818 : char *temp_filename;
313 : 8818 : auto_vec <char *>temp_filenames;
314 : 8818 : auto_vec <int>temp_priority;
315 : 8818 : size_t blen;
316 : :
317 : : /* Open the LTRANS output list. */
318 : 8818 : if (!ltrans_output_list)
319 : 0 : fatal_error (input_location, "no LTRANS output list filename provided");
320 : :
321 : 8818 : timevar_push (TV_WHOPR_WPA);
322 : :
323 : 26842 : FOR_EACH_VEC_ELT (ltrans_partitions, i, part)
324 : 18412 : lto_stats.num_output_symtab_nodes
325 : 18403 : += lto_symtab_encoder_size (part->encoder);
326 : :
327 : 8818 : timevar_pop (TV_WHOPR_WPA);
328 : :
329 : 8818 : timevar_push (TV_WHOPR_WPA_IO);
330 : :
331 : 8818 : cgraph_node *node;
332 : : /* Do body modifications needed for streaming before we fork out
333 : : worker processes. */
334 : 195058 : FOR_EACH_FUNCTION (node)
335 : 88711 : if (!node->clone_of && gimple_has_body_p (node->decl))
336 : 5427 : lto_prepare_function_for_streaming (node);
337 : :
338 : 8818 : ggc_trim ();
339 : 8818 : report_heap_memory_use ();
340 : :
341 : : /* Generate a prefix for the LTRANS unit files. */
342 : 8818 : blen = strlen (ltrans_output_list);
343 : 8818 : temp_filename = (char *) xmalloc (blen + sizeof ("2147483648.o"));
344 : 8818 : strcpy (temp_filename, ltrans_output_list);
345 : 8818 : if (blen > sizeof (".out")
346 : 8818 : && strcmp (temp_filename + blen - sizeof (".out") + 1,
347 : : ".out") == 0)
348 : 8818 : temp_filename[blen - sizeof (".out") + 1] = '\0';
349 : 8818 : blen = strlen (temp_filename);
350 : :
351 : 8818 : n_sets = ltrans_partitions.length ();
352 : 8818 : unsigned sets_per_worker = n_sets;
353 : 8818 : if (lto_parallelism > 1)
354 : : {
355 : 8740 : if (lto_parallelism > (int)n_sets)
356 : 8736 : lto_parallelism = n_sets;
357 : 8740 : sets_per_worker = (n_sets + lto_parallelism - 1) / lto_parallelism;
358 : : }
359 : :
360 : 18024 : for (i = 0; i < n_sets; i++)
361 : : {
362 : 9206 : ltrans_partition part = ltrans_partitions[i];
363 : :
364 : : /* Write all the nodes in SET. */
365 : 9206 : sprintf (temp_filename + blen, "%u.o", i);
366 : :
367 : 9206 : if (!quiet_flag)
368 : 0 : fprintf (stderr, " %s (%s %i insns)", temp_filename, part->name,
369 : : part->insns);
370 : 9206 : 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 : 9206 : gcc_checking_assert (lto_symtab_encoder_size (part->encoder) || !i);
414 : :
415 : 9206 : temp_priority.safe_push (part->insns);
416 : 9206 : temp_filenames.safe_push (xstrdup (temp_filename));
417 : : }
418 : 8818 : memory_block_pool::trim (0);
419 : :
420 : 18008 : for (int set = 0; set < MAX (lto_parallelism, 1); set++)
421 : : {
422 : 9190 : stream_out_partitions (temp_filename, blen, set * sets_per_worker,
423 : 9190 : MIN ((set + 1) * sets_per_worker, n_sets),
424 : 9190 : set == MAX (lto_parallelism, 1) - 1);
425 : : }
426 : :
427 : 8818 : ltrans_output_list_stream = fopen (ltrans_output_list, "w");
428 : 8818 : if (ltrans_output_list_stream == NULL)
429 : 0 : fatal_error (input_location,
430 : : "opening LTRANS output list %s: %m", ltrans_output_list);
431 : 18024 : for (i = 0; i < n_sets; i++)
432 : : {
433 : 9206 : unsigned int len = strlen (temp_filenames[i]);
434 : 9206 : if (fprintf (ltrans_output_list_stream, "%i\n", temp_priority[i]) < 0
435 : 9206 : || fwrite (temp_filenames[i], 1, len, ltrans_output_list_stream) < len
436 : 18412 : || 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 : 9206 : free (temp_filenames[i]);
440 : : }
441 : :
442 : 8818 : lto_stats.num_output_files += n_sets;
443 : :
444 : : /* Close the LTRANS output list. */
445 : 8818 : if (fclose (ltrans_output_list_stream))
446 : 0 : fatal_error (input_location,
447 : : "closing LTRANS output list %s: %m", ltrans_output_list);
448 : :
449 : 8818 : free_ltrans_partitions ();
450 : 8818 : free (temp_filename);
451 : :
452 : 8818 : timevar_pop (TV_WHOPR_WPA_IO);
453 : 8818 : }
454 : :
455 : : /* Create artificial pointers for "omp declare target link" vars. */
456 : :
457 : : static void
458 : 4349 : 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 : 4349 : }
480 : :
481 : : /* Perform whole program analysis (WPA) on the callgraph and write out the
482 : : optimization plan. */
483 : :
484 : : static void
485 : 8818 : do_whole_program_analysis (void)
486 : : {
487 : 8818 : symtab_node *node;
488 : :
489 : 8818 : lto_parallelism = 1;
490 : :
491 : 8818 : if (!strcmp (flag_wpa, "jobserver"))
492 : : {
493 : 8740 : jinfo = new jobserver_info ();
494 : 8740 : if (jinfo->is_active)
495 : 8740 : jinfo->connect ();
496 : :
497 : 8740 : 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 : 8818 : 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 : 8818 : materialize_cgraph ();
514 : :
515 : : /* Reading in the cgraph uses different timers, start timing WPA now. */
516 : 8818 : timevar_push (TV_WHOPR_WPA);
517 : :
518 : 8818 : if (pre_ipa_mem_report)
519 : 0 : dump_memory_report ("Memory consumption before IPA");
520 : :
521 : 8818 : symtab->function_flags_ready = true;
522 : :
523 : 8818 : if (symtab->dump_file)
524 : 1 : symtab->dump (symtab->dump_file);
525 : 8818 : bitmap_obstack_initialize (NULL);
526 : 8818 : symtab->state = IPA_SSA;
527 : :
528 : 8818 : 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 : 8818 : if (seen_error ())
532 : : return;
533 : :
534 : : /* We are about to launch the final LTRANS phase, stop the WPA timer. */
535 : 8818 : timevar_pop (TV_WHOPR_WPA);
536 : :
537 : : /* We are no longer going to stream in anything. Free some memory. */
538 : 8818 : lto_free_file_name_hash ();
539 : :
540 : :
541 : 8818 : timevar_push (TV_WHOPR_PARTITIONING);
542 : :
543 : 8818 : gcc_assert (!dump_file);
544 : 8818 : dump_file = dump_begin (partition_dump_id, NULL);
545 : :
546 : 8818 : if (dump_file)
547 : 0 : symtab->dump (dump_file);
548 : :
549 : 8818 : symtab_node::checking_verify_symtab_nodes ();
550 : 8818 : bitmap_obstack_release (NULL);
551 : 8818 : if (flag_ipa_reorder_for_locality)
552 : 0 : lto_locality_map (param_max_locality_partition_size);
553 : 8818 : else if (flag_lto_partition == LTO_PARTITION_1TO1)
554 : 296 : lto_1_to_1_map ();
555 : : else if (flag_lto_partition == LTO_PARTITION_MAX)
556 : 12 : 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 : 8439 : lto_balanced_map (param_lto_partitions,
561 : : param_max_partition_size);
562 : : else if (flag_lto_partition == LTO_PARTITION_CACHE)
563 : 1 : 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 : 8818 : 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 : 121821 : FOR_EACH_SYMBOL (node)
574 : 113003 : node->aux = NULL;
575 : :
576 : 8818 : 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 : 8818 : lto_promote_cross_file_statics ();
582 : 8818 : offload_handle_link_vars ();
583 : 8818 : if (dump_file)
584 : 0 : dump_end (partition_dump_id, dump_file);
585 : 8818 : dump_file = NULL;
586 : 8818 : timevar_pop (TV_WHOPR_PARTITIONING);
587 : :
588 : 8818 : 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 : 8818 : ggc_collect ();
594 : :
595 : 8818 : timevar_start (TV_PHASE_STREAM_OUT);
596 : 8818 : if (!quiet_flag)
597 : : {
598 : 0 : fprintf (stderr, "\nStreaming out");
599 : 0 : fflush (stderr);
600 : : }
601 : 8818 : lto_wpa_write_files ();
602 : 8818 : if (!quiet_flag)
603 : 0 : fprintf (stderr, "\n");
604 : 8818 : timevar_stop (TV_PHASE_STREAM_OUT);
605 : :
606 : 8818 : if (post_ipa_mem_report)
607 : 0 : dump_memory_report ("Memory consumption after IPA");
608 : :
609 : : /* Show the LTO report before launching LTRANS. */
610 : 8818 : if (flag_lto_report || (flag_wpa && flag_lto_report_wpa))
611 : 0 : print_lto_report_1 ();
612 : 8818 : if (mem_report_wpa)
613 : 0 : dump_memory_report ("Final");
614 : : }
615 : :
616 : : unsigned int
617 : 48446 : lto_option_lang_mask (void)
618 : : {
619 : 48446 : 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 : 22373 : 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 : 22373 : timevar_pop (TV_PARSE_GLOBAL);
651 : 22373 : timevar_stop (TV_PHASE_PARSING);
652 : :
653 : 22373 : timevar_start (TV_PHASE_SETUP);
654 : :
655 : : /* Initialize the LTO front end. */
656 : 22373 : lto_fe_init ();
657 : :
658 : 22373 : timevar_stop (TV_PHASE_SETUP);
659 : 22373 : 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 : 22373 : read_cgraph_and_symbols (num_in_fnames, in_fnames);
664 : :
665 : 22373 : timevar_stop (TV_PHASE_STREAM_IN);
666 : :
667 : 22373 : if (!seen_error ())
668 : : {
669 : 22373 : 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 : 22373 : if (flag_wpa)
675 : 8818 : do_whole_program_analysis ();
676 : : else
677 : : {
678 : 13555 : timevar_start (TV_PHASE_OPT_GEN);
679 : :
680 : 13555 : materialize_cgraph ();
681 : 13555 : if (!flag_ltrans)
682 : : {
683 : 4349 : lto_promote_statics_nonwpa ();
684 : 4349 : offload_handle_link_vars ();
685 : : }
686 : :
687 : : /* Annotate the CU DIE and mark the early debug phase as finished. */
688 : 13555 : debuginfo_early_start ();
689 : 13555 : debug_hooks->early_finish ("<artificial>");
690 : 13555 : debuginfo_early_stop ();
691 : :
692 : : /* Let the middle end know that we have read and merged all of
693 : : the input files. */
694 : 13555 : symtab->compile ();
695 : :
696 : 13555 : 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 : 13555 : 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 : 22373 : timevar_start (TV_PHASE_PARSING);
710 : 22373 : timevar_push (TV_PARSE_GLOBAL);
711 : 22373 : }
|