Line data Source code
1 : /* Driver of optimization process
2 : Copyright (C) 2003-2026 Free Software Foundation, Inc.
3 : Contributed by Jan Hubicka
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 : /* This module implements main driver of compilation process.
22 :
23 : The main scope of this file is to act as an interface in between
24 : tree based frontends and the backend.
25 :
26 : The front-end is supposed to use following functionality:
27 :
28 : - finalize_function
29 :
30 : This function is called once front-end has parsed whole body of function
31 : and it is certain that the function body nor the declaration will change.
32 :
33 : (There is one exception needed for implementing GCC extern inline
34 : function.)
35 :
36 : - varpool_finalize_decl
37 :
38 : This function has same behavior as the above but is used for static
39 : variables.
40 :
41 : - add_asm_node
42 :
43 : Insert new toplevel ASM statement
44 :
45 : - finalize_compilation_unit
46 :
47 : This function is called once (source level) compilation unit is finalized
48 : and it will no longer change.
49 :
50 : The symbol table is constructed starting from the trivially needed
51 : symbols finalized by the frontend. Functions are lowered into
52 : GIMPLE representation and callgraph/reference lists are constructed.
53 : Those are used to discover other necessary functions and variables.
54 :
55 : At the end the bodies of unreachable functions are removed.
56 :
57 : The function can be called multiple times when multiple source level
58 : compilation units are combined.
59 :
60 : - compile
61 :
62 : This passes control to the back-end. Optimizations are performed and
63 : final assembler is generated. This is done in the following way. Note
64 : that with link time optimization the process is split into three
65 : stages (compile time, linktime analysis and parallel linktime as
66 : indicated below).
67 :
68 : Compile time:
69 :
70 : 1) Inter-procedural optimization.
71 : (ipa_passes)
72 :
73 : This part is further split into:
74 :
75 : a) early optimizations. These are local passes executed in
76 : the topological order on the callgraph.
77 :
78 : The purpose of early optimizations is to optimize away simple
79 : things that may otherwise confuse IP analysis. Very simple
80 : propagation across the callgraph is done i.e. to discover
81 : functions without side effects and simple inlining is performed.
82 :
83 : b) early small interprocedural passes.
84 :
85 : Those are interprocedural passes executed only at compilation
86 : time. These include, for example, transactional memory lowering,
87 : unreachable code removal and other simple transformations.
88 :
89 : c) IP analysis stage. All interprocedural passes do their
90 : analysis.
91 :
92 : Interprocedural passes differ from small interprocedural
93 : passes by their ability to operate across whole program
94 : at linktime. Their analysis stage is performed early to
95 : both reduce linking times and linktime memory usage by
96 : not having to represent whole program in memory.
97 :
98 : d) LTO streaming. When doing LTO, everything important gets
99 : streamed into the object file.
100 :
101 : Compile time and or linktime analysis stage (WPA):
102 :
103 : At linktime units gets streamed back and symbol table is
104 : merged. Function bodies are not streamed in and not
105 : available.
106 : e) IP propagation stage. All IP passes execute their
107 : IP propagation. This is done based on the earlier analysis
108 : without having function bodies at hand.
109 : f) Ltrans streaming. When doing WHOPR LTO, the program
110 : is partitioned and streamed into multiple object files.
111 :
112 : Compile time and/or parallel linktime stage (ltrans)
113 :
114 : Each of the object files is streamed back and compiled
115 : separately. Now the function bodies becomes available
116 : again.
117 :
118 : 2) Virtual clone materialization
119 : (cgraph_materialize_clone)
120 :
121 : IP passes can produce copies of existing functions (such
122 : as versioned clones or inline clones) without actually
123 : manipulating their bodies by creating virtual clones in
124 : the callgraph. At this time the virtual clones are
125 : turned into real functions
126 : 3) IP transformation
127 :
128 : All IP passes transform function bodies based on earlier
129 : decision of the IP propagation.
130 :
131 : 4) late small IP passes
132 :
133 : Simple IP passes working within single program partition.
134 :
135 : 5) Expansion
136 : (expand_all_functions)
137 :
138 : At this stage functions that needs to be output into
139 : assembler are identified and compiled in topological order
140 : 6) Output of variables and aliases
141 : Now it is known what variable references was not optimized
142 : out and thus all variables are output to the file.
143 :
144 : Note that with -fno-toplevel-reorder passes 5 and 6
145 : are combined together in cgraph_output_in_order.
146 :
147 : Finally there are functions to manipulate the callgraph from
148 : backend.
149 : - cgraph_add_new_function is used to add backend produced
150 : functions introduced after the unit is finalized.
151 : The functions are enqueue for later processing and inserted
152 : into callgraph with cgraph_process_new_functions.
153 :
154 : - cgraph_function_versioning
155 :
156 : produces a copy of function into new one (a version)
157 : and apply simple transformations
158 : */
159 :
160 : #include "config.h"
161 : #include "system.h"
162 : #include "coretypes.h"
163 : #include "backend.h"
164 : #include "target.h"
165 : #include "rtl.h"
166 : #include "tree.h"
167 : #include "gimple.h"
168 : #include "cfghooks.h"
169 : #include "regset.h" /* FIXME: For reg_obstack. */
170 : #include "alloc-pool.h"
171 : #include "tree-pass.h"
172 : #include "stringpool.h"
173 : #include "gimple-ssa.h"
174 : #include "cgraph.h"
175 : #include "coverage.h"
176 : #include "lto-streamer.h"
177 : #include "fold-const.h"
178 : #include "varasm.h"
179 : #include "stor-layout.h"
180 : #include "output.h"
181 : #include "cfgcleanup.h"
182 : #include "gimple-iterator.h"
183 : #include "gimple-fold.h"
184 : #include "gimplify.h"
185 : #include "gimplify-me.h"
186 : #include "tree-cfg.h"
187 : #include "tree-into-ssa.h"
188 : #include "tree-ssa.h"
189 : #include "langhooks.h"
190 : #include "toplev.h"
191 : #include "debug.h"
192 : #include "symbol-summary.h"
193 : #include "tree-vrp.h"
194 : #include "sreal.h"
195 : #include "ipa-cp.h"
196 : #include "ipa-prop.h"
197 : #include "gimple-pretty-print.h"
198 : #include "plugin.h"
199 : #include "ipa-fnsummary.h"
200 : #include "ipa-utils.h"
201 : #include "except.h"
202 : #include "cfgloop.h"
203 : #include "context.h"
204 : #include "pass_manager.h"
205 : #include "tree-nested.h"
206 : #include "dbgcnt.h"
207 : #include "lto-section-names.h"
208 : #include "attribs.h"
209 : #include "ipa-inline.h"
210 : #include "omp-offload.h"
211 : #include "symtab-thunks.h"
212 :
213 : /* Queue of cgraph nodes scheduled to be added into cgraph. This is a
214 : secondary queue used during optimization to accommodate passes that
215 : may generate new functions that need to be optimized and expanded. */
216 : vec<cgraph_node *> cgraph_new_nodes;
217 :
218 : static void expand_all_functions (void);
219 : static void mark_functions_to_output (void);
220 : static void handle_alias_pairs (void);
221 :
222 : /* Return true if this symbol is a function from the C frontend specified
223 : directly in RTL form (with "__RTL"). */
224 :
225 : bool
226 246688945 : symtab_node::native_rtl_p () const
227 : {
228 246688945 : if (TREE_CODE (decl) != FUNCTION_DECL)
229 : return false;
230 206405824 : if (!DECL_STRUCT_FUNCTION (decl))
231 : return false;
232 204426069 : return DECL_STRUCT_FUNCTION (decl)->curr_properties & PROP_rtl;
233 : }
234 :
235 : /* Determine if symbol declaration is needed. That is, visible to something
236 : either outside this translation unit, something magic in the system
237 : configury */
238 : bool
239 150368187 : symtab_node::needed_p (void)
240 : {
241 : /* Double check that no one output the function into assembly file
242 : early. */
243 150368187 : if (!native_rtl_p ())
244 150368164 : gcc_checking_assert
245 : (!DECL_ASSEMBLER_NAME_SET_P (decl)
246 : || !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)));
247 :
248 150368187 : if (!definition)
249 : return false;
250 :
251 136744234 : if (DECL_EXTERNAL (decl))
252 : return false;
253 :
254 : /* If the user told us it is used, then it must be so. */
255 77044897 : if (force_output)
256 : return true;
257 76093239 : if (ref_by_asm)
258 : return true;
259 :
260 : /* ABI forced symbols are needed when they are external. */
261 76093237 : if (forced_by_abi && TREE_PUBLIC (decl))
262 : return true;
263 :
264 : /* Keep constructors, destructors and virtual functions. */
265 76057517 : if (TREE_CODE (decl) == FUNCTION_DECL
266 76057517 : && (DECL_STATIC_CONSTRUCTOR (decl) || DECL_STATIC_DESTRUCTOR (decl)))
267 : return true;
268 :
269 : /* Externally visible variables must be output. The exception is
270 : COMDAT variables that must be output only when they are needed. */
271 76046926 : if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
272 1921887 : return true;
273 :
274 : return false;
275 : }
276 :
277 : /* Head and terminator of the queue of nodes to be processed while building
278 : callgraph. */
279 :
280 : static symtab_node symtab_terminator (SYMTAB_SYMBOL);
281 : static symtab_node *queued_nodes = &symtab_terminator;
282 :
283 : /* Add NODE to queue starting at QUEUED_NODES.
284 : The queue is linked via AUX pointers and terminated by pointer to 1. */
285 :
286 : static void
287 17185277 : enqueue_node (symtab_node *node)
288 : {
289 17185277 : if (node->aux)
290 : return;
291 6530042 : gcc_checking_assert (queued_nodes);
292 6530042 : node->aux = queued_nodes;
293 6530042 : queued_nodes = node;
294 : }
295 :
296 : /* Process CGRAPH_NEW_FUNCTIONS and perform actions necessary to add these
297 : functions into callgraph in a way so they look like ordinary reachable
298 : functions inserted into callgraph already at construction time. */
299 :
300 : void
301 22121086 : symbol_table::process_new_functions (void)
302 : {
303 22121086 : tree fndecl;
304 :
305 22121086 : if (!cgraph_new_nodes.exists ())
306 : return;
307 :
308 19961 : handle_alias_pairs ();
309 : /* Note that this queue may grow as its being processed, as the new
310 : functions may generate new ones. */
311 85692 : for (unsigned i = 0; i < cgraph_new_nodes.length (); i++)
312 : {
313 45770 : cgraph_node *node = cgraph_new_nodes[i];
314 45770 : fndecl = node->decl;
315 45770 : bitmap_obstack_initialize (NULL);
316 45770 : switch (state)
317 : {
318 44578 : case CONSTRUCTION:
319 : /* At construction time we just need to finalize function and move
320 : it into reachable functions list. */
321 :
322 44578 : cgraph_node::finalize_function (fndecl, false);
323 44578 : call_cgraph_insertion_hooks (node);
324 44578 : enqueue_node (node);
325 44578 : break;
326 :
327 999 : case IPA:
328 999 : case IPA_SSA:
329 999 : case IPA_SSA_AFTER_INLINING:
330 : /* When IPA optimization already started, do all essential
331 : transformations that has been already performed on the whole
332 : cgraph but not on this function. */
333 :
334 999 : gimple_register_cfg_hooks ();
335 999 : if (!node->analyzed)
336 999 : node->analyze ();
337 999 : push_cfun (DECL_STRUCT_FUNCTION (fndecl));
338 999 : if ((state == IPA_SSA || state == IPA_SSA_AFTER_INLINING)
339 1998 : && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
340 : {
341 999 : bool summaried_computed = ipa_fn_summaries != NULL;
342 999 : g->get_passes ()->execute_early_local_passes ();
343 : /* Early passes compute inline parameters to do inlining
344 : and splitting. This is redundant for functions added late.
345 : Just throw away whatever it did. */
346 999 : if (!summaried_computed)
347 : {
348 902 : ipa_free_fn_summary ();
349 902 : ipa_free_size_summary ();
350 : }
351 : }
352 0 : else if (ipa_fn_summaries != NULL)
353 0 : compute_fn_summary (node, true);
354 999 : free_dominance_info (CDI_POST_DOMINATORS);
355 999 : free_dominance_info (CDI_DOMINATORS);
356 999 : pop_cfun ();
357 999 : call_cgraph_insertion_hooks (node);
358 999 : break;
359 :
360 193 : case EXPANSION:
361 : /* Functions created during expansion shall be compiled
362 : directly. */
363 193 : node->process = 0;
364 193 : call_cgraph_insertion_hooks (node);
365 193 : node->expand ();
366 193 : break;
367 :
368 0 : default:
369 0 : gcc_unreachable ();
370 45770 : break;
371 : }
372 45770 : bitmap_obstack_release (NULL);
373 : }
374 :
375 19961 : cgraph_new_nodes.release ();
376 : }
377 :
378 : /* As an GCC extension we allow redefinition of the function. The
379 : semantics when both copies of bodies differ is not well defined.
380 : We replace the old body with new body so in unit at a time mode
381 : we always use new body, while in normal mode we may end up with
382 : old body inlined into some functions and new body expanded and
383 : inlined in others.
384 :
385 : ??? It may make more sense to use one body for inlining and other
386 : body for expanding the function but this is difficult to do.
387 :
388 : This is also used to cancel C++ mangling aliases, which can be for
389 : functions or variables. */
390 :
391 : void
392 38027 : symtab_node::reset (bool preserve_comdat_group)
393 : {
394 : /* Reset our data structures so we can analyze the function again. */
395 38027 : analyzed = false;
396 38027 : definition = false;
397 38027 : alias = false;
398 38027 : transparent_alias = false;
399 38027 : weakref = false;
400 38027 : cpp_implicit_alias = false;
401 :
402 38027 : remove_all_references ();
403 38027 : if (!preserve_comdat_group)
404 37550 : remove_from_same_comdat_group ();
405 :
406 38027 : if (cgraph_node *cn = dyn_cast <cgraph_node *> (this))
407 : {
408 : /* If process is set, then we have already begun whole-unit analysis.
409 : This is *not* testing for whether we've already emitted the function.
410 : That case can be sort-of legitimately seen with real function
411 : redefinition errors. I would argue that the front end should never
412 : present us with such a case, but don't enforce that for now. */
413 38027 : gcc_assert (!cn->process);
414 :
415 38027 : memset (&cn->rtl, 0, sizeof (cn->rtl));
416 38027 : cn->inlined_to = NULL;
417 38027 : cn->remove_callees ();
418 : }
419 38027 : }
420 :
421 : /* Return true when there are references to the node. INCLUDE_SELF is
422 : true if a self reference counts as a reference. */
423 :
424 : bool
425 147649722 : symtab_node::referred_to_p (bool include_self)
426 : {
427 147649722 : ipa_ref *ref = NULL;
428 :
429 : /* See if there are any references at all. */
430 147649722 : if (iterate_referring (0, ref))
431 : return true;
432 : /* For functions check also calls. */
433 145301601 : cgraph_node *cn = dyn_cast <cgraph_node *> (this);
434 108617077 : if (cn && cn->callers)
435 : {
436 3102780 : if (include_self)
437 : return true;
438 2087386 : for (cgraph_edge *e = cn->callers; e; e = e->next_caller)
439 2087050 : if (e->caller != this)
440 : return true;
441 : }
442 : return false;
443 : }
444 :
445 : /* DECL has been parsed. Take it, queue it, compile it at the whim of the
446 : logic in effect. If NO_COLLECT is true, then our caller cannot stand to have
447 : the garbage collector run at the moment. We would need to either create
448 : a new GC context, or just not compile right now. */
449 :
450 : void
451 91683184 : cgraph_node::finalize_function (tree decl, bool no_collect)
452 : {
453 91683184 : cgraph_node *node = cgraph_node::get_create (decl);
454 :
455 91683184 : if (node->definition)
456 : {
457 : /* Nested functions should only be defined once. */
458 150 : gcc_assert (!DECL_CONTEXT (decl)
459 : || TREE_CODE (DECL_CONTEXT (decl)) != FUNCTION_DECL);
460 150 : node->reset ();
461 150 : node->redefined_extern_inline = true;
462 : }
463 :
464 : /* Set definition first before calling notice_global_symbol so that
465 : it is available to notice_global_symbol. */
466 91683184 : node->definition = true;
467 91683184 : notice_global_symbol (decl);
468 91683184 : node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL;
469 91683184 : node->semantic_interposition = opt_for_fn (decl, flag_semantic_interposition);
470 91683184 : if (!flag_toplevel_reorder)
471 4502815 : node->no_reorder = true;
472 :
473 : /* With -fkeep-inline-functions we are keeping all inline functions except
474 : for extern inline ones. */
475 91683184 : if (flag_keep_inline_functions
476 25382 : && DECL_DECLARED_INLINE_P (decl)
477 25264 : && !DECL_EXTERNAL (decl)
478 91685261 : && !DECL_DISREGARD_INLINE_LIMITS (decl))
479 1880 : node->force_output = 1;
480 :
481 : /* __RTL functions were already output as soon as they were parsed (due
482 : to the large amount of global state in the backend).
483 : Mark such functions as "force_output" to reflect the fact that they
484 : will be in the asm file when considering the symbols they reference.
485 : The attempt to output them later on will bail out immediately. */
486 91683184 : if (node->native_rtl_p ())
487 127 : node->force_output = 1;
488 :
489 : /* When not optimizing, also output the static functions. (see
490 : PR24561), but don't do so for always_inline functions, functions
491 : declared inline and nested functions. These were optimized out
492 : in the original implementation and it is unclear whether we want
493 : to change the behavior here. */
494 178967224 : if (((!opt_for_fn (decl, optimize) || flag_keep_static_functions
495 87284039 : || node->no_reorder)
496 4502970 : && !node->cpp_implicit_alias
497 4502970 : && !DECL_DISREGARD_INLINE_LIMITS (decl)
498 2825807 : && !DECL_DECLARED_INLINE_P (decl)
499 510471 : && !(DECL_CONTEXT (decl)
500 251449 : && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL))
501 92178366 : && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
502 440098 : node->force_output = 1;
503 :
504 : /* If we've not yet emitted decl, tell the debug info about it. */
505 91683184 : if (!TREE_ASM_WRITTEN (decl))
506 91683184 : (*debug_hooks->deferred_inline_function) (decl);
507 :
508 91683184 : if (!no_collect)
509 81353878 : ggc_collect ();
510 :
511 91683184 : if (symtab->state == CONSTRUCTION
512 91683184 : && (node->needed_p () || node->referred_to_p ()))
513 44982 : enqueue_node (node);
514 91683184 : }
515 :
516 : /* Add the function FNDECL to the call graph.
517 : Unlike finalize_function, this function is intended to be used
518 : by middle end and allows insertion of new function at arbitrary point
519 : of compilation. The function can be either in high, low or SSA form
520 : GIMPLE.
521 :
522 : The function is assumed to be reachable and have address taken (so no
523 : API breaking optimizations are performed on it).
524 :
525 : Main work done by this function is to enqueue the function for later
526 : processing to avoid need the passes to be re-entrant. */
527 :
528 : void
529 49736 : cgraph_node::add_new_function (tree fndecl, bool lowered)
530 : {
531 49736 : gcc::pass_manager *passes = g->get_passes ();
532 49736 : cgraph_node *node;
533 :
534 49736 : if (dump_file)
535 : {
536 130 : struct function *fn = DECL_STRUCT_FUNCTION (fndecl);
537 130 : const char *function_type = ((gimple_has_body_p (fndecl))
538 130 : ? (lowered
539 130 : ? (gimple_in_ssa_p (fn)
540 : ? "ssa gimple"
541 : : "low gimple")
542 : : "high gimple")
543 125 : : "to-be-gimplified");
544 130 : fprintf (dump_file,
545 : "Added new %s function %s to callgraph\n",
546 : function_type,
547 : fndecl_name (fndecl));
548 : }
549 :
550 49736 : switch (symtab->state)
551 : {
552 0 : case PARSING:
553 0 : cgraph_node::finalize_function (fndecl, false);
554 0 : break;
555 44581 : case CONSTRUCTION:
556 : /* Just enqueue function to be processed at nearest occurrence. */
557 44581 : node = cgraph_node::get_create (fndecl);
558 44581 : if (lowered)
559 43946 : node->lowered = true;
560 44581 : cgraph_new_nodes.safe_push (node);
561 44581 : break;
562 :
563 1192 : case IPA:
564 1192 : case IPA_SSA:
565 1192 : case IPA_SSA_AFTER_INLINING:
566 1192 : case EXPANSION:
567 : /* Bring the function into finalized state and enqueue for later
568 : analyzing and compilation. */
569 1192 : node = cgraph_node::get_create (fndecl);
570 1192 : node->local = false;
571 1192 : node->definition = true;
572 1192 : node->semantic_interposition = opt_for_fn (fndecl,
573 : flag_semantic_interposition);
574 1192 : node->force_output = true;
575 1192 : if (TREE_PUBLIC (fndecl))
576 67 : node->externally_visible = true;
577 1192 : if (!lowered && symtab->state == EXPANSION)
578 : {
579 0 : push_cfun (DECL_STRUCT_FUNCTION (fndecl));
580 0 : gimple_register_cfg_hooks ();
581 0 : bitmap_obstack_initialize (NULL);
582 0 : execute_pass_list (cfun, passes->all_lowering_passes);
583 0 : passes->execute_early_local_passes ();
584 0 : bitmap_obstack_release (NULL);
585 0 : pop_cfun ();
586 :
587 0 : lowered = true;
588 : }
589 0 : if (lowered)
590 282 : node->lowered = true;
591 1192 : cgraph_new_nodes.safe_push (node);
592 1192 : break;
593 :
594 3963 : case FINISHED:
595 : /* At the very end of compilation we have to do all the work up
596 : to expansion. */
597 3963 : node = cgraph_node::create (fndecl);
598 3963 : if (lowered)
599 0 : node->lowered = true;
600 3963 : node->definition = true;
601 3963 : node->semantic_interposition = opt_for_fn (fndecl,
602 : flag_semantic_interposition);
603 3963 : node->analyze ();
604 3963 : push_cfun (DECL_STRUCT_FUNCTION (fndecl));
605 3963 : gimple_register_cfg_hooks ();
606 3963 : bitmap_obstack_initialize (NULL);
607 3963 : if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
608 3963 : g->get_passes ()->execute_early_local_passes ();
609 3963 : bitmap_obstack_release (NULL);
610 3963 : pop_cfun ();
611 3963 : node->expand ();
612 3963 : break;
613 :
614 0 : default:
615 0 : gcc_unreachable ();
616 : }
617 :
618 : /* Set a personality if required and we already passed EH lowering. */
619 49736 : if (lowered
620 93964 : && (function_needs_eh_personality (DECL_STRUCT_FUNCTION (fndecl))
621 : == eh_personality_lang))
622 2046 : DECL_FUNCTION_PERSONALITY (fndecl) = lang_hooks.eh_personality ();
623 49736 : }
624 :
625 : /* Analyze the function scheduled to be output. */
626 : void
627 3120694 : cgraph_node::analyze (void)
628 : {
629 3120694 : if (native_rtl_p ())
630 : {
631 23 : analyzed = true;
632 23 : return;
633 : }
634 :
635 3120671 : tree decl = this->decl;
636 3120671 : location_t saved_loc = input_location;
637 3120671 : input_location = DECL_SOURCE_LOCATION (decl);
638 3120671 : semantic_interposition = opt_for_fn (decl, flag_semantic_interposition);
639 :
640 3120671 : if (thunk)
641 : {
642 3461 : thunk_info *info = thunk_info::get (this);
643 3461 : cgraph_node *t = cgraph_node::get (info->alias);
644 :
645 3461 : create_edge (t, NULL, t->count);
646 3461 : callees->can_throw_external = !TREE_NOTHROW (t->decl);
647 : /* Target code in expand_thunk may need the thunk's target
648 : to be analyzed, so recurse here. */
649 3461 : if (!t->analyzed && t->definition)
650 0 : t->analyze ();
651 3461 : if (t->alias)
652 : {
653 3461 : t = t->get_alias_target ();
654 3461 : if (!t->analyzed && t->definition)
655 1337 : t->analyze ();
656 : }
657 3461 : bool ret = expand_thunk (this, false, false);
658 3461 : thunk_info::get (this)->alias = NULL;
659 3461 : if (!ret)
660 : return;
661 : }
662 3117371 : if (alias)
663 5114 : resolve_alias (cgraph_node::get (alias_target), transparent_alias);
664 3112257 : else if (dispatcher_function)
665 : {
666 : /* Generate the dispatcher body of multi-versioned functions. */
667 114 : cgraph_function_version_info *dispatcher_version_info
668 114 : = function_version ();
669 114 : if (dispatcher_version_info != NULL
670 114 : && (dispatcher_version_info->dispatcher_resolver
671 : == NULL_TREE))
672 : {
673 114 : tree resolver = NULL_TREE;
674 114 : gcc_assert (targetm.generate_version_dispatcher_body);
675 114 : resolver = targetm.generate_version_dispatcher_body (this);
676 114 : gcc_assert (resolver != NULL_TREE);
677 : }
678 : }
679 : else
680 : {
681 3112143 : push_cfun (DECL_STRUCT_FUNCTION (decl));
682 :
683 3112143 : assign_assembler_name_if_needed (decl);
684 :
685 : /* Make sure to gimplify bodies only once. During analyzing a
686 : function we lower it, which will require gimplified nested
687 : functions, so we can end up here with an already gimplified
688 : body. */
689 3112143 : if (!gimple_has_body_p (decl))
690 3012732 : gimplify_function_tree (decl);
691 :
692 : /* Lower the function. */
693 3112143 : if (!lowered)
694 : {
695 3057966 : if (first_nested_function (this))
696 9955 : lower_nested_functions (decl);
697 :
698 3048011 : gimple_register_cfg_hooks ();
699 3048011 : bitmap_obstack_initialize (NULL);
700 3048011 : execute_pass_list (cfun, g->get_passes ()->all_lowering_passes);
701 3047998 : compact_blocks ();
702 3047998 : bitmap_obstack_release (NULL);
703 3047998 : lowered = true;
704 : }
705 :
706 3112130 : pop_cfun ();
707 : }
708 3117358 : analyzed = true;
709 :
710 3117358 : input_location = saved_loc;
711 : }
712 :
713 : /* C++ frontend produce same body aliases all over the place, even before PCH
714 : gets streamed out. It relies on us linking the aliases with their function
715 : in order to do the fixups, but ipa-ref is not PCH safe. Consequently we
716 : first produce aliases without links, but once C++ FE is sure he won't stream
717 : PCH we build the links via this function. */
718 :
719 : void
720 206481 : symbol_table::process_same_body_aliases (void)
721 : {
722 206481 : symtab_node *node;
723 102738713 : FOR_EACH_SYMBOL (node)
724 102532232 : if (node->cpp_implicit_alias && !node->analyzed)
725 4462165 : node->resolve_alias
726 8924330 : (VAR_P (node->alias_target)
727 0 : ? (symtab_node *)varpool_node::get_create (node->alias_target)
728 4462165 : : (symtab_node *)cgraph_node::get_create (node->alias_target));
729 206481 : cpp_implicit_aliases_done = true;
730 206481 : }
731 :
732 : /* Process a symver attribute. */
733 :
734 : static void
735 147933031 : process_symver_attribute (symtab_node *n)
736 : {
737 147933031 : tree value = lookup_attribute ("symver", DECL_ATTRIBUTES (n->decl));
738 :
739 295866064 : for (; value != NULL; value = TREE_CHAIN (value))
740 : {
741 : /* Starting from binutils 2.35 gas supports:
742 : # Assign foo to bar@V1 and baz@V2.
743 : .symver foo, bar@V1
744 : .symver foo, baz@V2
745 : */
746 2 : const char *purpose = IDENTIFIER_POINTER (TREE_PURPOSE (value));
747 2 : if (strcmp (purpose, "symver") != 0)
748 0 : continue;
749 :
750 2 : tree symver = get_identifier_with_length
751 4 : (TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (value))),
752 2 : TREE_STRING_LENGTH (TREE_VALUE (TREE_VALUE (value))));
753 2 : symtab_node *def = symtab_node::get_for_asmname (symver);
754 :
755 2 : if (def)
756 : {
757 0 : error_at (DECL_SOURCE_LOCATION (n->decl),
758 : "duplicate definition of a symbol version");
759 0 : inform (DECL_SOURCE_LOCATION (def->decl),
760 : "same version was previously defined here");
761 0 : return;
762 : }
763 2 : if (!n->definition)
764 : {
765 0 : error_at (DECL_SOURCE_LOCATION (n->decl),
766 : "symbol needs to be defined to have a version");
767 0 : return;
768 : }
769 2 : if (DECL_COMMON (n->decl))
770 : {
771 0 : error_at (DECL_SOURCE_LOCATION (n->decl),
772 : "common symbol cannot be versioned");
773 0 : return;
774 : }
775 2 : if (DECL_COMDAT (n->decl))
776 : {
777 0 : error_at (DECL_SOURCE_LOCATION (n->decl),
778 : "comdat symbol cannot be versioned");
779 0 : return;
780 : }
781 2 : if (n->weakref)
782 : {
783 0 : error_at (DECL_SOURCE_LOCATION (n->decl),
784 : "%<weakref%> cannot be versioned");
785 0 : return;
786 : }
787 2 : if (!TREE_PUBLIC (n->decl))
788 : {
789 0 : error_at (DECL_SOURCE_LOCATION (n->decl),
790 : "versioned symbol must be public");
791 0 : return;
792 : }
793 2 : if (DECL_VISIBILITY (n->decl) != VISIBILITY_DEFAULT)
794 : {
795 0 : error_at (DECL_SOURCE_LOCATION (n->decl),
796 : "versioned symbol must have default visibility");
797 0 : return;
798 : }
799 :
800 : /* Create new symbol table entry representing the version. */
801 2 : tree new_decl = copy_node (n->decl);
802 :
803 2 : DECL_INITIAL (new_decl) = NULL_TREE;
804 2 : if (TREE_CODE (new_decl) == FUNCTION_DECL)
805 2 : DECL_STRUCT_FUNCTION (new_decl) = NULL;
806 2 : SET_DECL_ASSEMBLER_NAME (new_decl, symver);
807 2 : TREE_PUBLIC (new_decl) = 1;
808 2 : DECL_ATTRIBUTES (new_decl) = NULL;
809 :
810 2 : symtab_node *symver_node = symtab_node::get_create (new_decl);
811 2 : symver_node->alias = true;
812 2 : symver_node->definition = true;
813 2 : symver_node->symver = true;
814 2 : symver_node->create_reference (n, IPA_REF_ALIAS, NULL);
815 2 : symver_node->analyzed = true;
816 : }
817 : }
818 :
819 : /* Process attributes common for vars and functions. */
820 :
821 : static void
822 147933031 : process_common_attributes (symtab_node *node, tree decl)
823 : {
824 147933031 : tree weakref = lookup_attribute ("weakref", DECL_ATTRIBUTES (decl));
825 :
826 147933031 : if (weakref && !lookup_attribute ("alias", DECL_ATTRIBUTES (decl)))
827 : {
828 1 : warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
829 : "%<weakref%> attribute should be accompanied with"
830 : " an %<alias%> attribute");
831 1 : DECL_WEAK (decl) = 0;
832 1 : DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
833 1 : DECL_ATTRIBUTES (decl));
834 : }
835 :
836 147933031 : if (lookup_attribute ("no_reorder", DECL_ATTRIBUTES (decl)))
837 17 : node->no_reorder = 1;
838 147933031 : process_symver_attribute (node);
839 147933031 : }
840 :
841 : /* Look for externally_visible and used attributes and mark cgraph nodes
842 : accordingly.
843 :
844 : We cannot mark the nodes at the point the attributes are processed (in
845 : handle_*_attribute) because the copy of the declarations available at that
846 : point may not be canonical. For example, in:
847 :
848 : void f();
849 : void f() __attribute__((used));
850 :
851 : the declaration we see in handle_used_attribute will be the second
852 : declaration -- but the front end will subsequently merge that declaration
853 : with the original declaration and discard the second declaration.
854 :
855 : Furthermore, we can't mark these nodes in finalize_function because:
856 :
857 : void f() {}
858 : void f() __attribute__((externally_visible));
859 :
860 : is valid.
861 :
862 : So, we walk the nodes at the end of the translation unit, applying the
863 : attributes at that point. */
864 :
865 : static void
866 775757 : process_function_and_variable_attributes (cgraph_node *first,
867 : varpool_node *first_var)
868 : {
869 775757 : cgraph_node *node;
870 775757 : varpool_node *vnode;
871 :
872 110789748 : for (node = symtab->first_function (); node != first;
873 110013991 : node = symtab->next_function (node))
874 : {
875 110013991 : tree decl = node->decl;
876 :
877 110013991 : if (node->alias
878 110013991 : && lookup_attribute ("flatten", DECL_ATTRIBUTES (decl)))
879 : {
880 8 : tree tdecl = node->get_alias_target_tree ();
881 8 : if (!tdecl || !DECL_P (tdecl)
882 16 : || !lookup_attribute ("flatten", DECL_ATTRIBUTES (tdecl)))
883 1 : warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
884 : "%<flatten%> attribute is ignored on aliases");
885 : }
886 110013991 : if (DECL_PRESERVE_P (decl))
887 5145 : node->mark_force_output ();
888 110008846 : else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
889 : {
890 41881 : if (! TREE_PUBLIC (node->decl))
891 4 : warning_at (DECL_SOURCE_LOCATION (node->decl), OPT_Wattributes,
892 : "%<externally_visible%>"
893 : " attribute have effect only on public objects");
894 : }
895 110013991 : if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
896 394 : && node->definition
897 110014041 : && (!node->alias || DECL_INITIAL (decl) != error_mark_node))
898 : {
899 : /* NODE->DEFINITION && NODE->ALIAS is nonzero for valid weakref
900 : function declarations; DECL_INITIAL is non-null for invalid
901 : weakref functions that are also defined. */
902 3 : warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
903 : "%<weakref%> attribute ignored"
904 : " because function is defined");
905 3 : DECL_WEAK (decl) = 0;
906 3 : DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
907 3 : DECL_ATTRIBUTES (decl));
908 3 : DECL_ATTRIBUTES (decl) = remove_attribute ("alias",
909 3 : DECL_ATTRIBUTES (decl));
910 3 : node->alias = false;
911 3 : node->weakref = false;
912 3 : node->transparent_alias = false;
913 : }
914 110013988 : else if (lookup_attribute ("alias", DECL_ATTRIBUTES (decl))
915 5489 : && node->definition
916 110019124 : && !node->alias)
917 1 : warning_at (DECL_SOURCE_LOCATION (node->decl), OPT_Wattributes,
918 : "%<alias%> attribute ignored"
919 : " because function is defined");
920 :
921 110013991 : if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl))
922 45387055 : && !DECL_DECLARED_INLINE_P (decl)
923 : /* redefining extern inline function makes it DECL_UNINLINABLE. */
924 110083159 : && !DECL_UNINLINABLE (decl))
925 69163 : warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
926 : "%<always_inline%> function might not be inlinable"
927 : " unless also declared %<inline%>");
928 :
929 110013991 : process_common_attributes (node, decl);
930 : }
931 38694797 : for (vnode = symtab->first_variable (); vnode != first_var;
932 37919040 : vnode = symtab->next_variable (vnode))
933 : {
934 37919040 : tree decl = vnode->decl;
935 37919040 : if (DECL_EXTERNAL (decl)
936 37919040 : && DECL_INITIAL (decl))
937 2113350 : varpool_node::finalize_decl (decl);
938 37919040 : if (DECL_PRESERVE_P (decl))
939 3226 : vnode->force_output = true;
940 37915814 : else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
941 : {
942 42 : if (! TREE_PUBLIC (vnode->decl))
943 4 : warning_at (DECL_SOURCE_LOCATION (vnode->decl), OPT_Wattributes,
944 : "%<externally_visible%>"
945 : " attribute have effect only on public objects");
946 : }
947 37919040 : if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
948 69 : && vnode->definition
949 37919053 : && DECL_INITIAL (decl))
950 : {
951 1 : warning_at (DECL_SOURCE_LOCATION (vnode->decl), OPT_Wattributes,
952 : "%<weakref%> attribute ignored"
953 : " because variable is initialized");
954 1 : DECL_WEAK (decl) = 0;
955 1 : DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
956 1 : DECL_ATTRIBUTES (decl));
957 : }
958 37919040 : process_common_attributes (vnode, decl);
959 : }
960 775757 : }
961 :
962 : /* Mark DECL as finalized. By finalizing the declaration, frontend instruct the
963 : middle end to output the variable to asm file, if needed or externally
964 : visible. */
965 :
966 : void
967 35542685 : varpool_node::finalize_decl (tree decl)
968 : {
969 35542685 : varpool_node *node = varpool_node::get_create (decl);
970 :
971 35542685 : gcc_assert (TREE_STATIC (decl) || DECL_EXTERNAL (decl));
972 :
973 35542685 : if (node->definition)
974 : return;
975 : /* Set definition first before calling notice_global_symbol so that
976 : it is available to notice_global_symbol. */
977 35517412 : node->definition = true;
978 35517412 : node->semantic_interposition = flag_semantic_interposition;
979 35517412 : notice_global_symbol (decl);
980 35517412 : if (!flag_toplevel_reorder)
981 3453101 : node->no_reorder = true;
982 35426834 : if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
983 : /* Traditionally we do not eliminate static variables when not
984 : optimizing and when not doing toplevel reorder. */
985 70940922 : || (node->no_reorder && !DECL_COMDAT (node->decl)
986 1091158 : && !DECL_ARTIFICIAL (node->decl)))
987 475906 : node->force_output = true;
988 :
989 35517412 : if (flag_openmp)
990 : {
991 156279 : tree attr = lookup_attribute ("omp allocate", DECL_ATTRIBUTES (decl));
992 156279 : if (attr)
993 : {
994 43 : tree align = TREE_VALUE (TREE_VALUE (attr));
995 43 : if (align)
996 16 : SET_DECL_ALIGN (decl, MAX (tree_to_uhwi (align) * BITS_PER_UNIT,
997 : DECL_ALIGN (decl)));
998 : }
999 : }
1000 :
1001 35517412 : if (symtab->state == CONSTRUCTION
1002 35517412 : && (node->needed_p () || node->referred_to_p ()))
1003 248515 : enqueue_node (node);
1004 35517412 : if (symtab->state >= IPA_SSA)
1005 33293 : node->analyze ();
1006 : /* Some frontends produce various interface variables after compilation
1007 : finished. */
1008 35517412 : if (symtab->state == FINISHED
1009 35512716 : || (node->no_reorder
1010 3452442 : && symtab->state == EXPANSION))
1011 12767 : node->assemble_decl ();
1012 : }
1013 :
1014 : /* EDGE is an polymorphic call. Mark all possible targets as reachable
1015 : and if there is only one target, perform trivial devirtualization.
1016 : REACHABLE_CALL_TARGETS collects target lists we already walked to
1017 : avoid duplicate work. */
1018 :
1019 : static void
1020 19667 : walk_polymorphic_call_targets (hash_set<void *> *reachable_call_targets,
1021 : cgraph_edge *edge)
1022 : {
1023 19667 : unsigned int i;
1024 19667 : void *cache_token;
1025 19667 : bool final;
1026 19667 : vec <cgraph_node *>targets
1027 : = possible_polymorphic_call_targets
1028 19667 : (edge, &final, &cache_token);
1029 :
1030 19667 : if (cache_token != NULL && !reachable_call_targets->add (cache_token))
1031 : {
1032 15361 : if (symtab->dump_file)
1033 12 : dump_possible_polymorphic_call_targets
1034 12 : (symtab->dump_file, edge);
1035 :
1036 42897 : for (i = 0; i < targets.length (); i++)
1037 : {
1038 : /* Do not bother to mark virtual methods in anonymous namespace;
1039 : either we will find use of virtual table defining it, or it is
1040 : unused. */
1041 27536 : if (targets[i]->definition
1042 18885 : && TREE_CODE
1043 : (TREE_TYPE (targets[i]->decl))
1044 : == METHOD_TYPE
1045 46421 : && !type_in_anonymous_namespace_p
1046 18885 : (TYPE_METHOD_BASETYPE (TREE_TYPE (targets[i]->decl))))
1047 18210 : enqueue_node (targets[i]);
1048 : }
1049 : }
1050 :
1051 : /* Very trivial devirtualization; when the type is
1052 : final or anonymous (so we know all its derivation)
1053 : and there is only one possible virtual call target,
1054 : make the edge direct. */
1055 19667 : if (final)
1056 : {
1057 84 : if (targets.length () <= 1 && dbg_cnt (devirt))
1058 : {
1059 0 : cgraph_node *target;
1060 0 : if (targets.length () == 1)
1061 0 : target = targets[0];
1062 : else
1063 0 : target = cgraph_node::create (builtin_decl_unreachable ());
1064 :
1065 0 : if (symtab->dump_file)
1066 : {
1067 0 : fprintf (symtab->dump_file,
1068 : "Devirtualizing call: ");
1069 0 : print_gimple_stmt (symtab->dump_file,
1070 0 : edge->call_stmt, 0,
1071 : TDF_SLIM);
1072 : }
1073 0 : if (dump_enabled_p ())
1074 : {
1075 0 : dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, edge->call_stmt,
1076 : "devirtualizing call in %s to %s\n",
1077 0 : edge->caller->dump_name (),
1078 : target->dump_name ());
1079 : }
1080 :
1081 0 : edge = cgraph_edge::make_direct (edge, target);
1082 0 : gimple *new_call = cgraph_edge::redirect_call_stmt_to_callee (edge);
1083 :
1084 0 : if (symtab->dump_file)
1085 : {
1086 0 : fprintf (symtab->dump_file, "Devirtualized as: ");
1087 0 : print_gimple_stmt (symtab->dump_file, new_call, 0, TDF_SLIM);
1088 : }
1089 : }
1090 : }
1091 19667 : }
1092 :
1093 : /* Issue appropriate warnings for the global declaration DECL. */
1094 :
1095 : static void
1096 147957135 : check_global_declaration (symtab_node *snode)
1097 : {
1098 147957135 : const char *decl_file;
1099 147957135 : tree decl = snode->decl;
1100 :
1101 : /* Warn about any function declared static but not defined. We don't
1102 : warn about variables, because many programs have static variables
1103 : that exist only to get some text into the object file. */
1104 147957135 : if (TREE_CODE (decl) == FUNCTION_DECL
1105 110038034 : && DECL_INITIAL (decl) == 0
1106 1872397 : && DECL_EXTERNAL (decl)
1107 1867138 : && ! DECL_ARTIFICIAL (decl)
1108 149671888 : && ! TREE_PUBLIC (decl))
1109 : {
1110 170 : if (warning_suppressed_p (decl, OPT_Wunused))
1111 : ;
1112 109 : else if (snode->referred_to_p (/*include_self=*/false))
1113 : {
1114 106 : if (pedwarn (input_location, 0, "%q+F used but never defined", decl))
1115 61 : suppress_warning (decl, OPT_Wunused);
1116 : }
1117 3 : else if (warning (OPT_Wunused_function,
1118 : "%q+F declared %<static%> but never defined", decl))
1119 0 : suppress_warning (decl, OPT_Wunused);
1120 : }
1121 :
1122 : /* Warn about static fns or vars defined but not used. */
1123 5091319 : if (((warn_unused_function && TREE_CODE (decl) == FUNCTION_DECL)
1124 143348371 : || (((warn_unused_variable && ! TREE_READONLY (decl))
1125 143286539 : || (warn_unused_const_variable > 0 && TREE_READONLY (decl)
1126 6671 : && (warn_unused_const_variable == 2
1127 6665 : || (main_input_filename != NULL
1128 147963176 : && (decl_file = DECL_SOURCE_FILE (decl)) != NULL
1129 6658 : && filename_cmp (main_input_filename,
1130 : decl_file) == 0))))
1131 67639 : && VAR_P (decl)))
1132 4655927 : && ! DECL_IN_SYSTEM_HEADER (decl)
1133 922165 : && ! snode->referred_to_p (/*include_self=*/false)
1134 : /* This TREE_USED check is needed in addition to referred_to_p
1135 : above, because the `__unused__' attribute is not being
1136 : considered for referred_to_p. */
1137 604630 : && ! TREE_USED (decl)
1138 : /* The TREE_USED bit for file-scope decls is kept in the identifier,
1139 : to handle multiple external decls in different scopes. */
1140 336201 : && ! (DECL_NAME (decl) && TREE_USED (DECL_NAME (decl)))
1141 336201 : && ! DECL_EXTERNAL (decl)
1142 138574 : && ! DECL_ARTIFICIAL (decl)
1143 137808 : && ! DECL_ABSTRACT_ORIGIN (decl)
1144 110308 : && ! TREE_PUBLIC (decl)
1145 : /* A volatile variable might be used in some non-obvious way. */
1146 18036 : && (! VAR_P (decl) || ! TREE_THIS_VOLATILE (decl))
1147 : /* Global register variables must be declared to reserve them. */
1148 18035 : && ! (VAR_P (decl) && DECL_REGISTER (decl))
1149 : /* Global ctors and dtors are called by the runtime. */
1150 18035 : && (TREE_CODE (decl) != FUNCTION_DECL
1151 17955 : || (!DECL_STATIC_CONSTRUCTOR (decl)
1152 17955 : && !DECL_STATIC_DESTRUCTOR (decl)))
1153 18035 : && (! VAR_P (decl) || !warning_suppressed_p (decl, OPT_Wunused_variable))
1154 : /* Otherwise, ask the language. */
1155 147975157 : && lang_hooks.decls.warn_unused_global (decl))
1156 617 : warning_at (DECL_SOURCE_LOCATION (decl),
1157 617 : (TREE_CODE (decl) == FUNCTION_DECL)
1158 684 : ? OPT_Wunused_function
1159 67 : : (TREE_READONLY (decl)
1160 : ? OPT_Wunused_const_variable_
1161 : : OPT_Wunused_variable),
1162 : "%qD defined but not used", decl);
1163 147957135 : }
1164 :
1165 : /* Discover all functions and variables that are trivially needed, analyze
1166 : them as well as all functions and variables referred by them */
1167 : static cgraph_node *first_analyzed;
1168 : static varpool_node *first_analyzed_var;
1169 :
1170 : /* FIRST_TIME is set to TRUE for the first time we are called for a
1171 : translation unit from finalize_compilation_unit() or false
1172 : otherwise. */
1173 :
1174 : static void
1175 527351 : analyze_functions (bool first_time)
1176 : {
1177 : /* Keep track of already processed nodes when called multiple times for
1178 : intermodule optimization. */
1179 527351 : cgraph_node *first_handled = first_analyzed;
1180 527351 : varpool_node *first_handled_var = first_analyzed_var;
1181 527351 : hash_set<void *> reachable_call_targets;
1182 :
1183 527351 : symtab_node *node;
1184 527351 : symtab_node *next;
1185 527351 : int i;
1186 527351 : ipa_ref *ref;
1187 527351 : bool changed = true;
1188 527351 : location_t saved_loc = input_location;
1189 :
1190 527351 : bitmap_obstack_initialize (NULL);
1191 527351 : symtab->state = CONSTRUCTION;
1192 527351 : input_location = UNKNOWN_LOCATION;
1193 :
1194 527351 : thunk_info::process_early_thunks ();
1195 :
1196 : /* Ugly, but the fixup cannot happen at a time same body alias is created;
1197 : C++ FE is confused about the COMDAT groups being right. */
1198 527351 : if (symtab->cpp_implicit_aliases_done)
1199 149460021 : FOR_EACH_SYMBOL (node)
1200 149047586 : if (node->cpp_implicit_alias)
1201 8602130 : node->fixup_same_cpp_alias_visibility (node->get_alias_target ());
1202 527351 : build_type_inheritance_graph ();
1203 :
1204 527351 : if (flag_openmp && first_time)
1205 9737 : omp_discover_implicit_declare_target ();
1206 :
1207 : /* Analysis adds static variables that in turn adds references to new functions.
1208 : So we need to iterate the process until it stabilize. */
1209 1303095 : while (changed)
1210 : {
1211 775757 : changed = false;
1212 775757 : process_function_and_variable_attributes (first_analyzed,
1213 : first_analyzed_var);
1214 :
1215 : /* First identify the trivially needed symbols. */
1216 775757 : for (node = symtab->first_symbol ();
1217 148708790 : node != first_analyzed && node != first_analyzed_var;
1218 147933033 : node = safe_as_a<symtab_node *>(node->next))
1219 : {
1220 : /* Convert COMDAT group designators to IDENTIFIER_NODEs. */
1221 147933033 : node->get_comdat_group_id ();
1222 147933033 : if (node->needed_p ())
1223 : {
1224 2837562 : enqueue_node (node);
1225 2837562 : if (!changed && symtab->dump_file)
1226 75 : fprintf (symtab->dump_file, "Trivially needed symbols:");
1227 2837562 : changed = true;
1228 2837562 : if (symtab->dump_file)
1229 128 : fprintf (symtab->dump_file, " %s", node->dump_asm_name ());
1230 : }
1231 147933033 : if (node == first_analyzed
1232 147933033 : || node == first_analyzed_var)
1233 : break;
1234 : }
1235 775757 : symtab->process_new_functions ();
1236 775757 : first_analyzed_var = symtab->first_variable ();
1237 775757 : first_analyzed = symtab->first_function ();
1238 :
1239 775757 : if (changed && symtab->dump_file)
1240 75 : fprintf (symtab->dump_file, "\n");
1241 :
1242 : /* Lower representation, build callgraph edges and references for all trivially
1243 : needed symbols and all symbols referred by them. */
1244 7305772 : while (queued_nodes != &symtab_terminator)
1245 : {
1246 6530028 : changed = true;
1247 6530028 : node = queued_nodes;
1248 6530028 : queued_nodes = (symtab_node *)queued_nodes->aux;
1249 6530028 : cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
1250 3463769 : if (cnode && cnode->definition)
1251 : {
1252 3460528 : cgraph_edge *edge;
1253 3460528 : tree decl = cnode->decl;
1254 :
1255 : /* ??? It is possible to create extern inline function
1256 : and later using weak alias attribute to kill its body.
1257 : See gcc.c-torture/compile/20011119-1.c */
1258 3460528 : if (!DECL_STRUCT_FUNCTION (decl)
1259 15277 : && !cnode->alias
1260 3525 : && !cnode->thunk
1261 3460642 : && !cnode->dispatcher_function)
1262 : {
1263 0 : cnode->reset ();
1264 0 : cnode->redefined_extern_inline = true;
1265 0 : continue;
1266 : }
1267 :
1268 3460528 : if (!cnode->analyzed)
1269 3094763 : cnode->analyze ();
1270 :
1271 : /* A reference to a default node in a function set implies a
1272 : reference to all versions in the set. */
1273 3460515 : cgraph_function_version_info *node_v = cnode->function_version ();
1274 3460515 : if (node_v && is_function_default_version (node->decl))
1275 129 : for (cgraph_function_version_info *fvi = node_v->next;
1276 750 : fvi;
1277 621 : fvi = fvi->next)
1278 621 : enqueue_node (fvi->this_node);
1279 :
1280 13725447 : for (edge = cnode->callees; edge; edge = edge->next_callee)
1281 10264932 : if (edge->callee->definition
1282 10264932 : && (!DECL_EXTERNAL (edge->callee->decl)
1283 : /* When not optimizing, do not try to analyze extern
1284 : inline functions. Doing so is pointless. */
1285 695499 : || opt_for_fn (edge->callee->decl, optimize)
1286 : /* Weakrefs needs to be preserved. */
1287 4984 : || edge->callee->alias
1288 : /* always_inline functions are inlined even at -O0. */
1289 3354 : || lookup_attribute
1290 3354 : ("always_inline",
1291 3354 : DECL_ATTRIBUTES (edge->callee->decl))
1292 : /* Multiversioned functions needs the dispatcher to
1293 : be produced locally even for extern functions. */
1294 2002 : || edge->callee->function_version ()))
1295 5392029 : enqueue_node (edge->callee);
1296 3460515 : if (opt_for_fn (cnode->decl, optimize)
1297 3460515 : && opt_for_fn (cnode->decl, flag_devirtualize))
1298 : {
1299 2822927 : cgraph_edge *next;
1300 :
1301 2956432 : for (edge = cnode->indirect_calls; edge; edge = next)
1302 : {
1303 133505 : next = edge->next_callee;
1304 133505 : if (is_a <cgraph_polymorphic_indirect_info *>
1305 267010 : (edge->indirect_info))
1306 19667 : walk_polymorphic_call_targets (&reachable_call_targets,
1307 : edge);
1308 : }
1309 : }
1310 :
1311 : /* If decl is a clone of an abstract function,
1312 : mark that abstract function so that we don't release its body.
1313 : The DECL_INITIAL() of that abstract function declaration
1314 : will be later needed to output debug info. */
1315 3460515 : if (DECL_ABSTRACT_ORIGIN (decl))
1316 : {
1317 755558 : cgraph_node *origin_node
1318 755558 : = cgraph_node::get_create (DECL_ABSTRACT_ORIGIN (decl));
1319 755558 : origin_node->used_as_abstract_origin = true;
1320 : }
1321 : /* Preserve a functions function context node. It will
1322 : later be needed to output debug info. */
1323 3460515 : if (tree fn = decl_function_context (decl))
1324 : {
1325 129817 : cgraph_node *origin_node = cgraph_node::get_create (fn);
1326 129817 : enqueue_node (origin_node);
1327 : }
1328 : }
1329 : else
1330 : {
1331 3069500 : varpool_node *vnode = dyn_cast <varpool_node *> (node);
1332 3066259 : if (vnode && vnode->definition && !vnode->analyzed)
1333 3066252 : vnode->analyze ();
1334 : }
1335 :
1336 6530015 : if (node->same_comdat_group)
1337 : {
1338 : symtab_node *next;
1339 955190 : for (next = node->same_comdat_group;
1340 1644031 : next != node;
1341 955190 : next = next->same_comdat_group)
1342 1910380 : if (!next->comdat_local_p ())
1343 942945 : enqueue_node (next);
1344 : }
1345 18037355 : for (i = 0; node->iterate_reference (i, ref); i++)
1346 11507340 : if (ref->referred->definition
1347 11507340 : && (!DECL_EXTERNAL (ref->referred->decl)
1348 98209 : || ((TREE_CODE (ref->referred->decl) != FUNCTION_DECL
1349 28374 : && optimize)
1350 70449 : || (TREE_CODE (ref->referred->decl) == FUNCTION_DECL
1351 69835 : && opt_for_fn (ref->referred->decl, optimize))
1352 1498 : || node->alias
1353 1006 : || ref->referred->alias)))
1354 7526018 : enqueue_node (ref->referred);
1355 6530015 : symtab->process_new_functions ();
1356 : }
1357 : }
1358 527338 : update_type_inheritance_graph ();
1359 :
1360 : /* Collect entry points to the unit. */
1361 527338 : if (symtab->dump_file)
1362 : {
1363 150 : fprintf (symtab->dump_file, "\n\nInitial ");
1364 150 : symtab->dump (symtab->dump_file);
1365 : }
1366 :
1367 527338 : if (first_time)
1368 : {
1369 263669 : symtab_node *snode;
1370 148220804 : FOR_EACH_SYMBOL (snode)
1371 147957135 : check_global_declaration (snode);
1372 : }
1373 :
1374 527338 : if (symtab->dump_file)
1375 150 : fprintf (symtab->dump_file, "\nRemoving unused symbols:");
1376 :
1377 527338 : for (node = symtab->first_symbol ();
1378 148484491 : node != first_handled
1379 148484491 : && node != first_handled_var; node = next)
1380 : {
1381 147957153 : next = safe_as_a<symtab_node *>(node->next);
1382 : /* For symbols declared locally we clear TREE_READONLY when emitting
1383 : the constructor (if one is needed). For external declarations we can
1384 : not safely assume that the type is readonly because we may be called
1385 : during its construction. */
1386 147957153 : if (TREE_CODE (node->decl) == VAR_DECL
1387 37919102 : && TYPE_P (TREE_TYPE (node->decl))
1388 37918047 : && TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (node->decl))
1389 148700900 : && DECL_EXTERNAL (node->decl))
1390 348277 : TREE_READONLY (node->decl) = 0;
1391 147957153 : if (!node->aux && !node->referred_to_p () && !node->ref_by_asm)
1392 : {
1393 139260414 : if (symtab->dump_file)
1394 21 : fprintf (symtab->dump_file, " %s", node->dump_name ());
1395 :
1396 : /* See if the debugger can use anything before the DECL
1397 : passes away. Perhaps it can notice a DECL that is now a
1398 : constant and can tag the early DIE with an appropriate
1399 : attribute.
1400 :
1401 : Otherwise, this is the last chance the debug_hooks have
1402 : at looking at optimized away DECLs, since
1403 : late_global_decl will subsequently be called from the
1404 : contents of the now pruned symbol table. */
1405 139260414 : if (VAR_P (node->decl)
1406 139260414 : && !decl_function_context (node->decl))
1407 : {
1408 : /* We are reclaiming totally unreachable code and variables
1409 : so they effectively appear as readonly. Show that to
1410 : the debug machinery. */
1411 34416417 : TREE_READONLY (node->decl) = 1;
1412 34416417 : node->definition = false;
1413 34416417 : (*debug_hooks->late_global_decl) (node->decl);
1414 : }
1415 :
1416 139260414 : node->remove ();
1417 139260414 : continue;
1418 : }
1419 8696739 : if (cgraph_node *cnode = dyn_cast <cgraph_node *> (node))
1420 : {
1421 5331659 : tree decl = node->decl;
1422 :
1423 3461509 : if (cnode->definition && !gimple_has_body_p (decl)
1424 373981 : && !cnode->alias
1425 5335986 : && !cnode->thunk)
1426 1027 : cnode->reset ();
1427 :
1428 5331659 : gcc_assert (!cnode->definition || cnode->thunk
1429 : || cnode->alias
1430 : || gimple_has_body_p (decl)
1431 : || cnode->native_rtl_p ());
1432 5331659 : gcc_assert (cnode->analyzed == cnode->definition);
1433 : }
1434 8696739 : node->aux = NULL;
1435 : }
1436 9224076 : for (;node; node = safe_as_a<symtab_node *>(node->next))
1437 8696738 : node->aux = NULL;
1438 527338 : first_analyzed = symtab->first_function ();
1439 527338 : first_analyzed_var = symtab->first_variable ();
1440 527338 : if (symtab->dump_file)
1441 : {
1442 150 : fprintf (symtab->dump_file, "\n\nReclaimed ");
1443 150 : symtab->dump (symtab->dump_file);
1444 : }
1445 527338 : bitmap_obstack_release (NULL);
1446 527338 : ggc_collect ();
1447 : /* Initialize assembler name hash, in particular we want to trigger C++
1448 : mangling and same body alias creation before we free DECL_ARGUMENTS
1449 : used by it. */
1450 527338 : if (!seen_error ())
1451 474383 : symtab->symtab_initialize_asm_name_hash ();
1452 :
1453 527338 : input_location = saved_loc;
1454 527338 : }
1455 :
1456 : /* Check declaration of the type of ALIAS for compatibility with its TARGET
1457 : (which may be an ifunc resolver) and issue a diagnostic when they are
1458 : not compatible according to language rules (plus a C++ extension for
1459 : non-static member functions). */
1460 :
1461 : static void
1462 5143 : maybe_diag_incompatible_alias (tree alias, tree target)
1463 : {
1464 5143 : tree altype = TREE_TYPE (alias);
1465 5143 : tree targtype = TREE_TYPE (target);
1466 :
1467 5143 : bool ifunc = cgraph_node::get (alias)->ifunc_resolver;
1468 5143 : tree funcptr = altype;
1469 :
1470 5143 : if (ifunc)
1471 : {
1472 : /* Handle attribute ifunc first. */
1473 117 : if (TREE_CODE (altype) == METHOD_TYPE)
1474 : {
1475 : /* Set FUNCPTR to the type of the alias target. If the type
1476 : is a non-static member function of class C, construct a type
1477 : of an ordinary function taking C* as the first argument,
1478 : followed by the member function argument list, and use it
1479 : instead to check for incompatibility. This conversion is
1480 : not defined by the language but an extension provided by
1481 : G++. */
1482 :
1483 21 : tree rettype = TREE_TYPE (altype);
1484 21 : tree args = TYPE_ARG_TYPES (altype);
1485 21 : altype = build_function_type (rettype, args);
1486 21 : funcptr = altype;
1487 : }
1488 :
1489 117 : targtype = TREE_TYPE (targtype);
1490 :
1491 117 : if (POINTER_TYPE_P (targtype))
1492 : {
1493 113 : targtype = TREE_TYPE (targtype);
1494 :
1495 : /* Only issue Wattribute-alias for conversions to void* with
1496 : -Wextra. */
1497 113 : if (VOID_TYPE_P (targtype) && !extra_warnings)
1498 : return;
1499 :
1500 : /* Proceed to handle incompatible ifunc resolvers below. */
1501 : }
1502 : else
1503 : {
1504 4 : funcptr = build_pointer_type (funcptr);
1505 :
1506 4 : error_at (DECL_SOURCE_LOCATION (target),
1507 : "%<ifunc%> resolver for %qD must return %qT",
1508 : alias, funcptr);
1509 4 : inform (DECL_SOURCE_LOCATION (alias),
1510 : "resolver indirect function declared here");
1511 4 : return;
1512 : }
1513 : }
1514 :
1515 5139 : if ((!FUNC_OR_METHOD_TYPE_P (targtype)
1516 5139 : || (prototype_p (altype)
1517 5013 : && prototype_p (targtype)
1518 5011 : && !types_compatible_p (altype, targtype))))
1519 : {
1520 : /* Warn for incompatibilities. Avoid warning for functions
1521 : without a prototype to make it possible to declare aliases
1522 : without knowing the exact type, as libstdc++ does. */
1523 16 : if (ifunc)
1524 : {
1525 5 : funcptr = build_pointer_type (funcptr);
1526 :
1527 5 : auto_diagnostic_group d;
1528 5 : if (warning_at (DECL_SOURCE_LOCATION (target),
1529 5 : OPT_Wattribute_alias_,
1530 : "%<ifunc%> resolver for %qD should return %qT",
1531 : alias, funcptr))
1532 5 : inform (DECL_SOURCE_LOCATION (alias),
1533 : "resolver indirect function declared here");
1534 5 : }
1535 : else
1536 : {
1537 11 : auto_diagnostic_group d;
1538 11 : if (warning_at (DECL_SOURCE_LOCATION (alias),
1539 11 : OPT_Wattribute_alias_,
1540 : "%qD alias between functions of incompatible "
1541 : "types %qT and %qT", alias, altype, targtype))
1542 3 : inform (DECL_SOURCE_LOCATION (target),
1543 : "aliased declaration here");
1544 11 : }
1545 : }
1546 : }
1547 :
1548 : /* Translate the ugly representation of aliases as alias pairs into nice
1549 : representation in callgraph. We don't handle all cases yet,
1550 : unfortunately. */
1551 :
1552 : static void
1553 547312 : handle_alias_pairs (void)
1554 : {
1555 547312 : alias_pair *p;
1556 547312 : unsigned i;
1557 :
1558 553005 : for (i = 0; alias_pairs && alias_pairs->iterate (i, &p);)
1559 : {
1560 5693 : symtab_node *target_node = symtab_node::get_for_asmname (p->target);
1561 :
1562 : /* Weakrefs with target not defined in current unit are easy to handle:
1563 : they behave just as external variables except we need to note the
1564 : alias flag to later output the weakref pseudo op into asm file. */
1565 5693 : if (!target_node
1566 5693 : && lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL)
1567 : {
1568 402 : symtab_node *node = symtab_node::get (p->decl);
1569 402 : if (node)
1570 : {
1571 402 : node->alias_target = p->target;
1572 402 : node->weakref = true;
1573 402 : node->alias = true;
1574 402 : node->transparent_alias = true;
1575 : }
1576 402 : alias_pairs->unordered_remove (i);
1577 402 : continue;
1578 402 : }
1579 5291 : else if (!target_node)
1580 : {
1581 8 : error ("%q+D aliased to undefined symbol %qE", p->decl, p->target);
1582 8 : symtab_node *node = symtab_node::get (p->decl);
1583 8 : if (node)
1584 8 : node->alias = false;
1585 8 : alias_pairs->unordered_remove (i);
1586 8 : continue;
1587 8 : }
1588 :
1589 5283 : if (DECL_EXTERNAL (target_node->decl)
1590 : /* We use local aliases for C++ thunks to force the tailcall
1591 : to bind locally. This is a hack - to keep it working do
1592 : the following (which is not strictly correct). */
1593 24 : && (TREE_CODE (target_node->decl) != FUNCTION_DECL
1594 24 : || ! DECL_VIRTUAL_P (target_node->decl))
1595 5307 : && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)))
1596 : {
1597 0 : error ("%q+D aliased to external symbol %qE",
1598 : p->decl, p->target);
1599 : }
1600 :
1601 5283 : if (TREE_CODE (p->decl) == FUNCTION_DECL
1602 5283 : && target_node && is_a <cgraph_node *> (target_node))
1603 : {
1604 5143 : maybe_diag_incompatible_alias (p->decl, target_node->decl);
1605 :
1606 5143 : maybe_diag_alias_attributes (p->decl, target_node->decl);
1607 :
1608 5143 : cgraph_node *src_node = cgraph_node::get (p->decl);
1609 5143 : if (src_node && src_node->definition)
1610 18 : src_node->reset ();
1611 5143 : cgraph_node::create_alias (p->decl, target_node->decl);
1612 5143 : alias_pairs->unordered_remove (i);
1613 : }
1614 140 : else if (VAR_P (p->decl)
1615 140 : && target_node && is_a <varpool_node *> (target_node))
1616 : {
1617 139 : varpool_node::create_alias (p->decl, target_node->decl);
1618 139 : alias_pairs->unordered_remove (i);
1619 : }
1620 : else
1621 : {
1622 1 : error ("%q+D alias between function and variable is not supported",
1623 : p->decl);
1624 1 : inform (DECL_SOURCE_LOCATION (target_node->decl),
1625 : "aliased declaration here");
1626 :
1627 1 : alias_pairs->unordered_remove (i);
1628 : }
1629 : }
1630 547312 : vec_free (alias_pairs);
1631 547312 : }
1632 :
1633 :
1634 : /* Figure out what functions we want to assemble. */
1635 :
1636 : static void
1637 237841 : mark_functions_to_output (void)
1638 : {
1639 237841 : bool check_same_comdat_groups = false;
1640 237841 : cgraph_node *node;
1641 :
1642 237841 : if (flag_checking)
1643 5144797 : FOR_EACH_FUNCTION (node)
1644 4906970 : gcc_assert (!node->process);
1645 :
1646 5144858 : FOR_EACH_FUNCTION (node)
1647 : {
1648 4907017 : tree decl = node->decl;
1649 :
1650 4907017 : gcc_assert (!node->process || node->same_comdat_group);
1651 4907017 : if (node->process)
1652 12226 : continue;
1653 :
1654 : /* We need to output all local functions that are used and not
1655 : always inlined, as well as those that are reachable from
1656 : outside the current compilation unit. */
1657 4894791 : if (node->analyzed
1658 3073846 : && !node->thunk
1659 3071776 : && !node->alias
1660 3006274 : && !node->inlined_to
1661 1500588 : && !TREE_ASM_WRITTEN (decl)
1662 6395379 : && !DECL_EXTERNAL (decl))
1663 : {
1664 1500588 : node->process = 1;
1665 1500588 : if (node->same_comdat_group)
1666 : {
1667 49254 : cgraph_node *next;
1668 49254 : for (next = dyn_cast<cgraph_node *> (node->same_comdat_group);
1669 132870 : next != node;
1670 83616 : next = dyn_cast<cgraph_node *> (next->same_comdat_group))
1671 82101 : if (!next->thunk && !next->alias
1672 206480 : && !next->comdat_local_p ())
1673 16061 : next->process = 1;
1674 : }
1675 : }
1676 3394203 : else if (node->same_comdat_group)
1677 : {
1678 42665 : if (flag_checking)
1679 4907017 : check_same_comdat_groups = true;
1680 : }
1681 : else
1682 : {
1683 : /* We should've reclaimed all functions that are not needed. */
1684 3351538 : if (flag_checking
1685 3351511 : && !node->inlined_to
1686 1845678 : && gimple_has_body_p (decl)
1687 : /* FIXME: in ltrans unit when offline copy is outside partition but inline copies
1688 : are inside partition, we can end up not removing the body since we no longer
1689 : have analyzed node pointing to it. */
1690 140985 : && !node->in_other_partition
1691 140985 : && !node->alias
1692 140985 : && !node->clones
1693 3351538 : && !DECL_EXTERNAL (decl))
1694 : {
1695 0 : node->debug ();
1696 0 : internal_error ("failed to reclaim unneeded function");
1697 : }
1698 3351538 : gcc_assert (node->inlined_to
1699 : || !gimple_has_body_p (decl)
1700 : || node->in_other_partition
1701 : || node->clones
1702 : || DECL_ARTIFICIAL (decl)
1703 : || DECL_EXTERNAL (decl));
1704 :
1705 : }
1706 :
1707 : }
1708 237841 : if (flag_checking && check_same_comdat_groups)
1709 1532416 : FOR_EACH_FUNCTION (node)
1710 1521277 : if (node->same_comdat_group && !node->process)
1711 : {
1712 42665 : tree decl = node->decl;
1713 42665 : if (!node->inlined_to
1714 42665 : && gimple_has_body_p (decl)
1715 : /* FIXME: in an ltrans unit when the offline copy is outside a
1716 : partition but inline copies are inside a partition, we can
1717 : end up not removing the body since we no longer have an
1718 : analyzed node pointing to it. */
1719 1 : && !node->in_other_partition
1720 1 : && !node->clones
1721 42665 : && !DECL_EXTERNAL (decl))
1722 : {
1723 0 : node->debug ();
1724 0 : internal_error ("failed to reclaim unneeded function in same "
1725 : "comdat group");
1726 : }
1727 : }
1728 237841 : }
1729 :
1730 : /* DECL is FUNCTION_DECL. Initialize datastructures so DECL is a function
1731 : in lowered gimple form. IN_SSA is true if the gimple is in SSA.
1732 :
1733 : Set current_function_decl and cfun to newly constructed empty function body.
1734 : return basic block in the function body. */
1735 :
1736 : basic_block
1737 20714 : init_lowered_empty_function (tree decl, bool in_ssa, profile_count count)
1738 : {
1739 20714 : basic_block bb;
1740 20714 : edge e;
1741 :
1742 20714 : current_function_decl = decl;
1743 20714 : allocate_struct_function (decl, false);
1744 20714 : gimple_register_cfg_hooks ();
1745 20714 : init_empty_tree_cfg ();
1746 20714 : init_tree_ssa (cfun);
1747 :
1748 20714 : if (in_ssa)
1749 : {
1750 20511 : init_ssa_operands (cfun);
1751 20511 : cfun->gimple_df->in_ssa_p = true;
1752 20511 : cfun->curr_properties |= PROP_ssa;
1753 : }
1754 :
1755 20714 : DECL_INITIAL (decl) = make_node (BLOCK);
1756 20714 : BLOCK_SUPERCONTEXT (DECL_INITIAL (decl)) = decl;
1757 :
1758 20714 : DECL_SAVED_TREE (decl) = error_mark_node;
1759 20714 : cfun->curr_properties |= (PROP_gimple_lcf | PROP_gimple_leh | PROP_gimple_any
1760 : | PROP_cfg | PROP_loops);
1761 :
1762 20714 : set_loops_for_fn (cfun, ggc_cleared_alloc<loops> ());
1763 20714 : init_loops_structure (cfun, loops_for_fn (cfun), 1);
1764 20714 : loops_for_fn (cfun)->state |= LOOPS_MAY_HAVE_MULTIPLE_LATCHES;
1765 :
1766 : /* Create BB for body of the function and connect it properly. */
1767 20714 : ENTRY_BLOCK_PTR_FOR_FN (cfun)->count = count;
1768 20714 : EXIT_BLOCK_PTR_FOR_FN (cfun)->count = count;
1769 20714 : bb = create_basic_block (NULL, ENTRY_BLOCK_PTR_FOR_FN (cfun));
1770 20714 : bb->count = count;
1771 20714 : e = make_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun), bb, EDGE_FALLTHRU);
1772 20714 : e->probability = profile_probability::always ();
1773 20714 : e = make_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
1774 20714 : e->probability = profile_probability::always ();
1775 20714 : add_bb_to_loop (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun)->loop_father);
1776 :
1777 20714 : return bb;
1778 : }
1779 :
1780 : /* Assemble thunks and aliases associated to node. */
1781 :
1782 : void
1783 1582884 : cgraph_node::assemble_thunks_and_aliases (void)
1784 : {
1785 1582884 : cgraph_edge *e;
1786 1582884 : ipa_ref *ref;
1787 :
1788 3190672 : for (e = callers; e;)
1789 1607788 : if (e->caller->thunk
1790 1940 : && !e->caller->inlined_to)
1791 : {
1792 1916 : cgraph_node *thunk = e->caller;
1793 :
1794 1916 : e = e->next_caller;
1795 1916 : expand_thunk (thunk, !rtl_dump_and_exit, false);
1796 1916 : thunk->assemble_thunks_and_aliases ();
1797 1916 : }
1798 : else
1799 1605872 : e = e->next_caller;
1800 :
1801 1647100 : FOR_EACH_ALIAS (this, ref)
1802 : {
1803 64216 : cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
1804 64216 : if (!alias->transparent_alias)
1805 : {
1806 64210 : bool saved_written = TREE_ASM_WRITTEN (decl);
1807 :
1808 : /* Force assemble_alias to really output the alias this time instead
1809 : of buffering it in same alias pairs. */
1810 64210 : TREE_ASM_WRITTEN (decl) = 1;
1811 64210 : if (alias->symver)
1812 2 : do_assemble_symver (alias->decl,
1813 : DECL_ASSEMBLER_NAME (decl));
1814 : else
1815 64208 : do_assemble_alias (alias->decl,
1816 : DECL_ASSEMBLER_NAME (decl));
1817 64210 : alias->assemble_thunks_and_aliases ();
1818 64210 : TREE_ASM_WRITTEN (decl) = saved_written;
1819 : }
1820 : }
1821 1582884 : }
1822 :
1823 : /* Expand function specified by node. */
1824 :
1825 : void
1826 1516880 : cgraph_node::expand (void)
1827 : {
1828 1516880 : location_t saved_loc;
1829 :
1830 : /* We ought to not compile any inline clones. */
1831 1516880 : gcc_assert (!inlined_to);
1832 :
1833 : /* __RTL functions are compiled as soon as they are parsed, so don't
1834 : do it again. */
1835 1516880 : if (native_rtl_p ())
1836 : return;
1837 :
1838 1516880 : announce_function (decl);
1839 1516880 : process = 0;
1840 1516880 : gcc_assert (lowered);
1841 :
1842 : /* Initialize the default bitmap obstack. */
1843 1516880 : bitmap_obstack_initialize (NULL);
1844 1516880 : get_untransformed_body ();
1845 :
1846 : /* Generate RTL for the body of DECL. */
1847 :
1848 1516880 : timevar_push (TV_REST_OF_COMPILATION);
1849 :
1850 1516880 : gcc_assert (symtab->global_info_ready);
1851 :
1852 : /* Initialize the RTL code for the function. */
1853 1516880 : saved_loc = input_location;
1854 1516880 : input_location = DECL_SOURCE_LOCATION (decl);
1855 :
1856 1516880 : gcc_assert (DECL_STRUCT_FUNCTION (decl));
1857 1516880 : push_cfun (DECL_STRUCT_FUNCTION (decl));
1858 1516880 : init_function_start (decl);
1859 :
1860 1516880 : gimple_register_cfg_hooks ();
1861 :
1862 1516880 : bitmap_obstack_initialize (®_obstack); /* FIXME, only at RTL generation*/
1863 :
1864 1516880 : update_ssa (TODO_update_ssa_only_virtuals);
1865 1516880 : if (ipa_transforms_to_apply.exists ())
1866 1495815 : execute_all_ipa_transforms (false);
1867 :
1868 : /* Perform all tree transforms and optimizations. */
1869 :
1870 : /* Signal the start of passes. */
1871 1516880 : invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START, NULL);
1872 :
1873 1516880 : execute_pass_list (cfun, g->get_passes ()->all_passes);
1874 :
1875 : /* Signal the end of passes. */
1876 1516870 : invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END, NULL);
1877 :
1878 1516870 : bitmap_obstack_release (®_obstack);
1879 :
1880 : /* Release the default bitmap obstack. */
1881 1516870 : bitmap_obstack_release (NULL);
1882 :
1883 : /* If requested, warn about function definitions where the function will
1884 : return a value (usually of some struct or union type) which itself will
1885 : take up a lot of stack space. */
1886 1516870 : if (!DECL_EXTERNAL (decl) && TREE_TYPE (decl))
1887 : {
1888 1516870 : tree ret_type = TREE_TYPE (TREE_TYPE (decl));
1889 :
1890 1516870 : if (ret_type && TYPE_SIZE_UNIT (ret_type)
1891 808471 : && TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST
1892 2325302 : && compare_tree_int (TYPE_SIZE_UNIT (ret_type),
1893 808432 : warn_larger_than_size) > 0)
1894 : {
1895 0 : unsigned int size_as_int
1896 0 : = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type));
1897 :
1898 0 : if (compare_tree_int (TYPE_SIZE_UNIT (ret_type), size_as_int) == 0)
1899 0 : warning (OPT_Wlarger_than_,
1900 : "size of return value of %q+D is %u bytes",
1901 : decl, size_as_int);
1902 : else
1903 0 : warning (OPT_Wlarger_than_,
1904 : "size of return value of %q+D is larger than %wu bytes",
1905 : decl, warn_larger_than_size);
1906 : }
1907 : }
1908 :
1909 1516870 : gimple_set_body (decl, NULL);
1910 1516870 : if (DECL_STRUCT_FUNCTION (decl) == 0)
1911 : {
1912 : /* Stop pointing to the local nodes about to be freed.
1913 : But DECL_INITIAL must remain nonzero so we know this
1914 : was an actual function definition. */
1915 62 : if (DECL_INITIAL (decl) != 0)
1916 62 : DECL_INITIAL (decl) = error_mark_node;
1917 : }
1918 :
1919 1516870 : input_location = saved_loc;
1920 :
1921 1516870 : ggc_collect ();
1922 1516870 : timevar_pop (TV_REST_OF_COMPILATION);
1923 :
1924 1516870 : if (DECL_STRUCT_FUNCTION (decl)
1925 1516870 : && DECL_STRUCT_FUNCTION (decl)->assume_function)
1926 : {
1927 : /* Assume functions aren't expanded into RTL, on the other side
1928 : we don't want to release their body. */
1929 112 : if (cfun)
1930 0 : pop_cfun ();
1931 : return;
1932 : }
1933 :
1934 : /* Make sure that BE didn't give up on compiling. */
1935 1516758 : gcc_assert (TREE_ASM_WRITTEN (decl));
1936 1516758 : if (cfun)
1937 1516696 : pop_cfun ();
1938 :
1939 : /* It would make a lot more sense to output thunks before function body to
1940 : get more forward and fewer backward jumps. This however would need
1941 : solving problem with comdats. See PR48668. Also aliases must come after
1942 : function itself to make one pass assemblers, like one on AIX, happy.
1943 : See PR 50689.
1944 : FIXME: Perhaps thunks should be move before function IFF they are not in
1945 : comdat groups. */
1946 1516758 : assemble_thunks_and_aliases ();
1947 1516758 : release_body ();
1948 : }
1949 :
1950 : /* Node comparator that is responsible for the order that corresponds
1951 : to time when a function was launched for the first time. */
1952 :
1953 : int
1954 868641 : tp_first_run_node_cmp (const void *pa, const void *pb)
1955 : {
1956 868641 : const cgraph_node *a = *(const cgraph_node * const *) pa;
1957 868641 : const cgraph_node *b = *(const cgraph_node * const *) pb;
1958 868641 : unsigned int tp_first_run_a = a->tp_first_run;
1959 868641 : unsigned int tp_first_run_b = b->tp_first_run;
1960 :
1961 868641 : if (!opt_for_fn (a->decl, flag_profile_reorder_functions)
1962 868641 : || a->no_reorder)
1963 : tp_first_run_a = 0;
1964 868641 : if (!opt_for_fn (b->decl, flag_profile_reorder_functions)
1965 868641 : || b->no_reorder)
1966 : tp_first_run_b = 0;
1967 :
1968 868641 : if (tp_first_run_a == tp_first_run_b)
1969 866097 : return a->order - b->order;
1970 :
1971 : /* Functions with time profile must be before these without profile. */
1972 2544 : tp_first_run_a = (tp_first_run_a - 1) & INT_MAX;
1973 2544 : tp_first_run_b = (tp_first_run_b - 1) & INT_MAX;
1974 :
1975 2544 : return tp_first_run_a - tp_first_run_b;
1976 : }
1977 :
1978 : /* Expand all functions that must be output.
1979 :
1980 : Attempt to topologically sort the nodes so function is output when
1981 : all called functions are already assembled to allow data to be
1982 : propagated across the callgraph. Use a stack to get smaller distance
1983 : between a function and its callees (later we may choose to use a more
1984 : sophisticated algorithm for function reordering; we will likely want
1985 : to use subsections to make the output functions appear in top-down
1986 : order). */
1987 :
1988 : static void
1989 237831 : expand_all_functions (void)
1990 : {
1991 237831 : cgraph_node *node;
1992 237831 : cgraph_node **order = XCNEWVEC (cgraph_node *,
1993 : symtab->cgraph_count);
1994 237831 : cgraph_node **tp_first_run_order = XCNEWVEC (cgraph_node *,
1995 : symtab->cgraph_count);
1996 237831 : unsigned int expanded_func_count = 0, profiled_func_count = 0;
1997 237831 : int order_pos, tp_first_run_order_pos = 0, new_order_pos = 0;
1998 237831 : int i;
1999 :
2000 237831 : order_pos = ipa_reverse_postorder (order);
2001 237831 : gcc_assert (order_pos == symtab->cgraph_count);
2002 :
2003 : /* Garbage collector may remove inline clones we eliminate during
2004 : optimization. So we must be sure to not reference them. */
2005 5110485 : for (i = 0; i < order_pos; i++)
2006 4872654 : if (order[i]->process)
2007 : {
2008 969439 : if (order[i]->tp_first_run
2009 969439 : && opt_for_fn (order[i]->decl, flag_profile_reorder_functions))
2010 283 : tp_first_run_order[tp_first_run_order_pos++] = order[i];
2011 : else
2012 969156 : order[new_order_pos++] = order[i];
2013 : }
2014 :
2015 : /* First output functions with time profile in specified order. */
2016 237831 : qsort (tp_first_run_order, tp_first_run_order_pos,
2017 : sizeof (cgraph_node *), tp_first_run_node_cmp);
2018 475945 : for (i = 0; i < tp_first_run_order_pos; i++)
2019 : {
2020 283 : node = tp_first_run_order[i];
2021 :
2022 283 : if (node->process)
2023 : {
2024 283 : expanded_func_count++;
2025 283 : profiled_func_count++;
2026 :
2027 283 : if (symtab->dump_file)
2028 0 : fprintf (symtab->dump_file,
2029 : "Time profile order in expand_all_functions:%s:%d\n",
2030 : node->dump_asm_name (), node->tp_first_run);
2031 283 : node->process = 0;
2032 283 : node->expand ();
2033 : }
2034 : }
2035 :
2036 : /* Output functions in RPO so callees get optimized before callers. This
2037 : makes ipa-ra and other propagators to work.
2038 : FIXME: This is far from optimal code layout.
2039 : Make multiple passes over the list to defer processing of gc
2040 : candidates until all potential uses are seen. */
2041 : int gc_candidates = 0;
2042 : int prev_gc_candidates = 0;
2043 :
2044 237879 : while (1)
2045 : {
2046 1207626 : for (i = new_order_pos - 1; i >= 0; i--)
2047 : {
2048 969747 : node = order[i];
2049 :
2050 969747 : if (node->gc_candidate)
2051 159 : gc_candidates++;
2052 969588 : else if (node->process)
2053 : {
2054 969096 : expanded_func_count++;
2055 969096 : node->process = 0;
2056 969096 : node->expand ();
2057 : }
2058 : }
2059 237879 : if (!gc_candidates || gc_candidates == prev_gc_candidates)
2060 : break;
2061 : prev_gc_candidates = gc_candidates;
2062 : gc_candidates = 0;
2063 : }
2064 :
2065 : /* Free any unused gc_candidate functions. */
2066 237831 : if (gc_candidates)
2067 374 : for (i = new_order_pos - 1; i >= 0; i--)
2068 : {
2069 342 : node = order[i];
2070 342 : if (node->gc_candidate)
2071 : {
2072 60 : struct function *fn = DECL_STRUCT_FUNCTION (node->decl);
2073 60 : if (symtab->dump_file)
2074 8 : fprintf (symtab->dump_file,
2075 : "Deleting unused function %s\n",
2076 4 : IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->decl)));
2077 60 : node->process = false;
2078 60 : free_dominance_info (fn, CDI_DOMINATORS);
2079 60 : free_dominance_info (fn, CDI_POST_DOMINATORS);
2080 60 : node->release_body (false);
2081 : }
2082 : }
2083 :
2084 237831 : if (dump_file)
2085 0 : fprintf (dump_file, "Expanded functions with time profile (%s):%u/%u\n",
2086 : main_input_filename, profiled_func_count, expanded_func_count);
2087 :
2088 237831 : if (symtab->dump_file && tp_first_run_order_pos)
2089 0 : fprintf (symtab->dump_file, "Expanded functions with time profile:%u/%u\n",
2090 : profiled_func_count, expanded_func_count);
2091 :
2092 237831 : symtab->process_new_functions ();
2093 237831 : free_gimplify_stack ();
2094 237831 : delete ipa_saved_clone_sources;
2095 237831 : ipa_saved_clone_sources = NULL;
2096 237831 : free (order);
2097 237831 : free (tp_first_run_order);
2098 237831 : }
2099 :
2100 : /* This is used to sort the node types by the cgraph order number. */
2101 :
2102 : enum cgraph_order_sort_kind
2103 : {
2104 : ORDER_FUNCTION,
2105 : ORDER_VAR,
2106 : ORDER_VAR_UNDEF,
2107 : ORDER_ASM
2108 : };
2109 :
2110 : struct cgraph_order_sort
2111 : {
2112 : /* Construct from a cgraph_node. */
2113 543375 : cgraph_order_sort (cgraph_node *node)
2114 543375 : : kind (ORDER_FUNCTION), order (node->order)
2115 : {
2116 543375 : u.f = node;
2117 : }
2118 :
2119 : /* Construct from a varpool_node. */
2120 1001291 : cgraph_order_sort (varpool_node *node)
2121 2002582 : : kind (node->definition ? ORDER_VAR : ORDER_VAR_UNDEF), order (node->order)
2122 : {
2123 1001291 : u.v = node;
2124 : }
2125 :
2126 : /* Construct from a asm_node. */
2127 12802 : cgraph_order_sort (asm_node *node)
2128 12802 : : kind (ORDER_ASM), order (node->order)
2129 : {
2130 12802 : u.a = node;
2131 : }
2132 :
2133 : /* Assembly cgraph_order_sort based on its type. */
2134 : void process ();
2135 :
2136 : enum cgraph_order_sort_kind kind;
2137 : union
2138 : {
2139 : cgraph_node *f;
2140 : varpool_node *v;
2141 : asm_node *a;
2142 : } u;
2143 : int order;
2144 : };
2145 :
2146 : /* Assembly cgraph_order_sort based on its type. */
2147 :
2148 : void
2149 1557438 : cgraph_order_sort::process ()
2150 : {
2151 1557438 : switch (kind)
2152 : {
2153 543345 : case ORDER_FUNCTION:
2154 543345 : u.f->process = 0;
2155 543345 : u.f->expand ();
2156 543345 : break;
2157 1000608 : case ORDER_VAR:
2158 1000608 : u.v->assemble_decl ();
2159 1000608 : break;
2160 683 : case ORDER_VAR_UNDEF:
2161 683 : assemble_undefined_decl (u.v->decl);
2162 683 : break;
2163 12802 : case ORDER_ASM:
2164 12802 : assemble_asm (u.a->asm_str);
2165 12802 : break;
2166 0 : default:
2167 0 : gcc_unreachable ();
2168 : }
2169 1557428 : }
2170 :
2171 : /* Compare cgraph_order_sort by order. */
2172 :
2173 : static int
2174 63721037 : cgraph_order_cmp (const void *a_p, const void *b_p)
2175 : {
2176 63721037 : const cgraph_order_sort *nodea = (const cgraph_order_sort *)a_p;
2177 63721037 : const cgraph_order_sort *nodeb = (const cgraph_order_sort *)b_p;
2178 :
2179 63721037 : return nodea->order - nodeb->order;
2180 : }
2181 :
2182 : /* Output all functions, variables, and asm statements in the order
2183 : according to their order fields, which is the order in which they
2184 : appeared in the file. This implements -fno-toplevel-reorder. In
2185 : this mode we may output functions and variables which don't really
2186 : need to be output. */
2187 :
2188 : static void
2189 237841 : output_in_order (void)
2190 : {
2191 237841 : int i;
2192 237841 : cgraph_node *cnode;
2193 237841 : varpool_node *vnode;
2194 237841 : asm_node *anode;
2195 237841 : auto_vec<cgraph_order_sort> nodes;
2196 237841 : cgraph_order_sort *node;
2197 :
2198 3323914 : FOR_EACH_DEFINED_FUNCTION (cnode)
2199 3086073 : if (cnode->process && !cnode->thunk
2200 1512814 : && !cnode->alias && cnode->no_reorder)
2201 543375 : nodes.safe_push (cgraph_order_sort (cnode));
2202 :
2203 : /* There is a similar loop in symbol_table::output_variables.
2204 : Please keep them in sync. */
2205 3431263 : FOR_EACH_VARIABLE (vnode)
2206 3193422 : if (vnode->no_reorder
2207 1001313 : && !DECL_HARD_REGISTER (vnode->decl)
2208 4194713 : && !DECL_HAS_VALUE_EXPR_P (vnode->decl))
2209 1001974 : nodes.safe_push (cgraph_order_sort (vnode));
2210 :
2211 250643 : for (anode = symtab->first_asm_symbol (); anode;
2212 12802 : anode = safe_as_a<asm_node*>(anode->next))
2213 12802 : nodes.safe_push (cgraph_order_sort (anode));
2214 :
2215 : /* Sort nodes by order. */
2216 237841 : nodes.qsort (cgraph_order_cmp);
2217 :
2218 : /* In toplevel reorder mode we output all statics; mark them as needed. */
2219 1795309 : FOR_EACH_VEC_ELT (nodes, i, node)
2220 1557468 : if (node->kind == ORDER_VAR)
2221 1000608 : node->u.v->finalize_named_section_flags ();
2222 :
2223 1795269 : FOR_EACH_VEC_ELT (nodes, i, node)
2224 1557438 : node->process ();
2225 :
2226 237831 : symtab->clear_asm_symbols ();
2227 237831 : }
2228 :
2229 : static void
2230 249974 : ipa_passes (void)
2231 : {
2232 249974 : gcc::pass_manager *passes = g->get_passes ();
2233 :
2234 249974 : set_cfun (NULL);
2235 249974 : current_function_decl = NULL;
2236 249974 : gimple_register_cfg_hooks ();
2237 249974 : bitmap_obstack_initialize (NULL);
2238 :
2239 249974 : invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START, NULL);
2240 :
2241 249974 : if (!in_lto_p)
2242 : {
2243 237187 : execute_ipa_pass_list (passes->all_small_ipa_passes);
2244 237187 : if (seen_error ())
2245 : return;
2246 : }
2247 :
2248 : /* This extra symtab_remove_unreachable_nodes pass tends to catch some
2249 : devirtualization and other changes where removal iterate. */
2250 249825 : symtab->remove_unreachable_nodes (symtab->dump_file);
2251 :
2252 : /* If pass_all_early_optimizations was not scheduled, the state of
2253 : the cgraph will not be properly updated. Update it now. */
2254 249825 : if (symtab->state < IPA_SSA)
2255 12787 : symtab->state = IPA_SSA;
2256 :
2257 249825 : if (!in_lto_p)
2258 : {
2259 : /* Generate coverage variables and constructors. */
2260 237038 : coverage_finish ();
2261 :
2262 : /* Process new functions added. */
2263 237038 : set_cfun (NULL);
2264 237038 : current_function_decl = NULL;
2265 237038 : symtab->process_new_functions ();
2266 :
2267 237038 : execute_ipa_summary_passes
2268 237038 : ((ipa_opt_pass_d *) passes->all_regular_ipa_passes);
2269 : }
2270 :
2271 : /* Some targets need to handle LTO assembler output specially. */
2272 249825 : if (flag_generate_lto || flag_generate_offload)
2273 23417 : targetm.asm_out.lto_start ();
2274 :
2275 249825 : if (!in_lto_p
2276 12787 : || flag_incremental_link == INCREMENTAL_LINK_LTO)
2277 : {
2278 237073 : if (!quiet_flag)
2279 0 : fprintf (stderr, "Streaming LTO\n");
2280 237073 : if (g->have_offload)
2281 : {
2282 0 : section_name_prefix = OFFLOAD_SECTION_NAME_PREFIX;
2283 0 : lto_stream_offload_p = true;
2284 0 : ipa_write_summaries ();
2285 0 : lto_stream_offload_p = false;
2286 : }
2287 237073 : if (flag_lto)
2288 : {
2289 23417 : section_name_prefix = LTO_SECTION_NAME_PREFIX;
2290 23417 : lto_stream_offload_p = false;
2291 23417 : ipa_write_summaries ();
2292 : }
2293 : }
2294 :
2295 249825 : if (flag_generate_lto || flag_generate_offload)
2296 23417 : targetm.asm_out.lto_end ();
2297 :
2298 249825 : if (!flag_ltrans
2299 241578 : && ((in_lto_p && flag_incremental_link != INCREMENTAL_LINK_LTO)
2300 237073 : || !flag_lto || flag_fat_lto_objects))
2301 229602 : execute_ipa_pass_list (passes->all_regular_ipa_passes);
2302 249825 : invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END, NULL);
2303 :
2304 249825 : bitmap_obstack_release (NULL);
2305 : }
2306 :
2307 :
2308 : /* Weakrefs may be associated to external decls and thus not output
2309 : at expansion time. Emit all necessary aliases. */
2310 :
2311 : void
2312 237831 : symbol_table::output_weakrefs (void)
2313 : {
2314 237831 : symtab_node *node;
2315 6813023 : FOR_EACH_SYMBOL (node)
2316 6575192 : if (node->alias
2317 70954 : && !TREE_ASM_WRITTEN (node->decl)
2318 1419 : && node->weakref)
2319 : {
2320 127 : tree target;
2321 :
2322 : /* Weakrefs are special by not requiring target definition in current
2323 : compilation unit. It is thus bit hard to work out what we want to
2324 : alias.
2325 : When alias target is defined, we need to fetch it from symtab reference,
2326 : otherwise it is pointed to by alias_target. */
2327 127 : if (node->alias_target)
2328 122 : target = (DECL_P (node->alias_target)
2329 122 : ? DECL_ASSEMBLER_NAME (node->alias_target)
2330 : : node->alias_target);
2331 5 : else if (node->analyzed)
2332 5 : target = DECL_ASSEMBLER_NAME (node->get_alias_target ()->decl);
2333 : else
2334 0 : gcc_unreachable ();
2335 127 : do_assemble_alias (node->decl, target);
2336 : }
2337 237831 : }
2338 :
2339 : /* Perform simple optimizations based on callgraph. */
2340 :
2341 : void
2342 276456 : symbol_table::compile (void)
2343 : {
2344 276456 : if (seen_error ())
2345 : return;
2346 :
2347 249974 : symtab_node::checking_verify_symtab_nodes ();
2348 :
2349 249974 : symtab_node::check_ifunc_callee_symtab_nodes ();
2350 :
2351 249974 : timevar_push (TV_CGRAPHOPT);
2352 249974 : if (pre_ipa_mem_report)
2353 0 : dump_memory_report ("Memory consumption before IPA");
2354 249974 : if (!quiet_flag)
2355 0 : fprintf (stderr, "Performing interprocedural optimizations\n");
2356 249974 : state = IPA;
2357 :
2358 : /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE. */
2359 249974 : if (flag_generate_lto || flag_generate_offload)
2360 23429 : lto_streamer_hooks_init ();
2361 :
2362 : /* Don't run the IPA passes if there was any error or sorry messages. */
2363 249974 : if (!seen_error ())
2364 : {
2365 249974 : timevar_start (TV_CGRAPH_IPA_PASSES);
2366 249974 : ipa_passes ();
2367 249974 : timevar_stop (TV_CGRAPH_IPA_PASSES);
2368 : }
2369 : /* Do nothing else if any IPA pass found errors or if we are just streaming LTO. */
2370 249974 : if (seen_error ()
2371 249974 : || ((!in_lto_p || flag_incremental_link == INCREMENTAL_LINK_LTO)
2372 237065 : && flag_lto && !flag_fat_lto_objects))
2373 : {
2374 12133 : timevar_pop (TV_CGRAPHOPT);
2375 12133 : return;
2376 : }
2377 :
2378 237841 : global_info_ready = true;
2379 237841 : if (dump_file)
2380 : {
2381 72 : fprintf (dump_file, "Optimized ");
2382 72 : symtab->dump (dump_file);
2383 : }
2384 237841 : if (post_ipa_mem_report)
2385 0 : dump_memory_report ("Memory consumption after IPA");
2386 237841 : timevar_pop (TV_CGRAPHOPT);
2387 :
2388 : /* Output everything. */
2389 237841 : switch_to_section (text_section);
2390 237841 : (*debug_hooks->assembly_start) ();
2391 237841 : if (!quiet_flag)
2392 0 : fprintf (stderr, "Assembling functions:\n");
2393 237841 : symtab_node::checking_verify_symtab_nodes ();
2394 :
2395 237841 : bitmap_obstack_initialize (NULL);
2396 237841 : execute_ipa_pass_list (g->get_passes ()->all_late_ipa_passes);
2397 237841 : bitmap_obstack_release (NULL);
2398 237841 : mark_functions_to_output ();
2399 :
2400 : /* When weakref support is missing, we automatically translate all
2401 : references to NODE to references to its ultimate alias target.
2402 : The renaming mechanism uses flag IDENTIFIER_TRANSPARENT_ALIAS and
2403 : TREE_CHAIN.
2404 :
2405 : Set up this mapping before we output any assembler but once we are sure
2406 : that all symbol renaming is done.
2407 :
2408 : FIXME: All this ugliness can go away if we just do renaming at gimple
2409 : level by physically rewriting the IL. At the moment we can only redirect
2410 : calls, so we need infrastructure for renaming references as well. */
2411 : #ifndef ASM_OUTPUT_WEAKREF
2412 : symtab_node *node;
2413 :
2414 : FOR_EACH_SYMBOL (node)
2415 : if (node->alias
2416 : && lookup_attribute ("weakref", DECL_ATTRIBUTES (node->decl)))
2417 : {
2418 : tree id = DECL_ASSEMBLER_NAME (node->decl);
2419 : gcc_assert (!IDENTIFIER_INTERNAL_P (id));
2420 : IDENTIFIER_TRANSPARENT_ALIAS (id) = 1;
2421 : TREE_CHAIN (id)
2422 : = (node->alias_target ? node->alias_target
2423 : : DECL_ASSEMBLER_NAME (node->get_alias_target ()->decl));
2424 : }
2425 : #endif
2426 :
2427 237841 : state = EXPANSION;
2428 :
2429 : /* Output first asm statements and anything ordered. The process
2430 : flag is cleared for these nodes, so we skip them later. */
2431 237841 : output_in_order ();
2432 :
2433 237831 : timevar_start (TV_CGRAPH_FUNC_EXPANSION);
2434 237831 : expand_all_functions ();
2435 237831 : timevar_stop (TV_CGRAPH_FUNC_EXPANSION);
2436 :
2437 237831 : output_variables ();
2438 :
2439 237831 : process_new_functions ();
2440 237831 : state = FINISHED;
2441 237831 : output_weakrefs ();
2442 :
2443 237831 : if (dump_file)
2444 : {
2445 72 : fprintf (dump_file, "\nFinal ");
2446 72 : symtab->dump (dump_file);
2447 : }
2448 237831 : if (!flag_checking)
2449 : return;
2450 237817 : symtab_node::verify_symtab_nodes ();
2451 : /* Double check that all inline clones are gone and that all
2452 : function bodies have been released from memory. */
2453 237817 : if (!seen_error ())
2454 : {
2455 237530 : cgraph_node *node;
2456 237530 : bool error_found = false;
2457 :
2458 1816994 : FOR_EACH_DEFINED_FUNCTION (node)
2459 1579464 : if (node->inlined_to
2460 1579464 : || gimple_has_body_p (node->decl))
2461 : {
2462 112 : if (DECL_STRUCT_FUNCTION (node->decl)
2463 112 : && (DECL_STRUCT_FUNCTION (node->decl)->curr_properties
2464 112 : & PROP_assumptions_done) != 0)
2465 112 : continue;
2466 0 : error_found = true;
2467 0 : node->debug ();
2468 : }
2469 237530 : if (error_found)
2470 0 : internal_error ("nodes with unreleased memory found");
2471 : }
2472 : }
2473 :
2474 : /* Earlydebug dump file, flags, and number. */
2475 :
2476 : static int debuginfo_early_dump_nr;
2477 : static FILE *debuginfo_early_dump_file;
2478 : static dump_flags_t debuginfo_early_dump_flags;
2479 :
2480 : /* Debug dump file, flags, and number. */
2481 :
2482 : static int debuginfo_dump_nr;
2483 : static FILE *debuginfo_dump_file;
2484 : static dump_flags_t debuginfo_dump_flags;
2485 :
2486 : /* Register the debug and earlydebug dump files. */
2487 :
2488 : void
2489 294536 : debuginfo_early_init (void)
2490 : {
2491 294536 : gcc::dump_manager *dumps = g->get_dumps ();
2492 294536 : debuginfo_early_dump_nr = dumps->dump_register (".earlydebug", "earlydebug",
2493 : "earlydebug", DK_tree,
2494 : OPTGROUP_NONE,
2495 : false);
2496 294536 : debuginfo_dump_nr = dumps->dump_register (".debug", "debug",
2497 : "debug", DK_tree,
2498 : OPTGROUP_NONE,
2499 : false);
2500 294536 : }
2501 :
2502 : /* Initialize the debug and earlydebug dump files. */
2503 :
2504 : void
2505 286914 : debuginfo_init (void)
2506 : {
2507 286914 : gcc::dump_manager *dumps = g->get_dumps ();
2508 286914 : debuginfo_dump_file = dump_begin (debuginfo_dump_nr, NULL);
2509 286914 : debuginfo_dump_flags = dumps->get_dump_file_info (debuginfo_dump_nr)->pflags;
2510 286914 : debuginfo_early_dump_file = dump_begin (debuginfo_early_dump_nr, NULL);
2511 286914 : debuginfo_early_dump_flags
2512 286914 : = dumps->get_dump_file_info (debuginfo_early_dump_nr)->pflags;
2513 286914 : }
2514 :
2515 : /* Finalize the debug and earlydebug dump files. */
2516 :
2517 : void
2518 285006 : debuginfo_fini (void)
2519 : {
2520 285006 : if (debuginfo_dump_file)
2521 49 : dump_end (debuginfo_dump_nr, debuginfo_dump_file);
2522 285006 : if (debuginfo_early_dump_file)
2523 49 : dump_end (debuginfo_early_dump_nr, debuginfo_early_dump_file);
2524 285006 : }
2525 :
2526 : /* Set dump_file to the debug dump file. */
2527 :
2528 : void
2529 237544 : debuginfo_start (void)
2530 : {
2531 237544 : set_dump_file (debuginfo_dump_file);
2532 237544 : }
2533 :
2534 : /* Undo setting dump_file to the debug dump file. */
2535 :
2536 : void
2537 237544 : debuginfo_stop (void)
2538 : {
2539 237544 : set_dump_file (NULL);
2540 237544 : }
2541 :
2542 : /* Set dump_file to the earlydebug dump file. */
2543 :
2544 : void
2545 249974 : debuginfo_early_start (void)
2546 : {
2547 249974 : set_dump_file (debuginfo_early_dump_file);
2548 249974 : }
2549 :
2550 : /* Undo setting dump_file to the earlydebug dump file. */
2551 :
2552 : void
2553 249974 : debuginfo_early_stop (void)
2554 : {
2555 249974 : set_dump_file (NULL);
2556 249974 : }
2557 :
2558 : /* Analyze the whole compilation unit once it is parsed completely. */
2559 :
2560 : void
2561 263682 : symbol_table::finalize_compilation_unit (void)
2562 : {
2563 263682 : timevar_push (TV_CGRAPH);
2564 :
2565 : /* If we're here there's no current function anymore. Some frontends
2566 : are lazy in clearing these. */
2567 263682 : current_function_decl = NULL;
2568 263682 : set_cfun (NULL);
2569 :
2570 : /* Do not skip analyzing the functions if there were errors, we
2571 : miss diagnostics for following functions otherwise. */
2572 :
2573 : /* Emit size functions we didn't inline. */
2574 263682 : finalize_size_functions ();
2575 :
2576 : /* Mark alias targets necessary and emit diagnostics. */
2577 263682 : handle_alias_pairs ();
2578 :
2579 263682 : if (!quiet_flag)
2580 : {
2581 0 : fprintf (stderr, "\nAnalyzing compilation unit\n");
2582 0 : fflush (stderr);
2583 : }
2584 :
2585 263682 : if (flag_dump_passes)
2586 5 : dump_passes ();
2587 :
2588 263682 : analyze_toplevel_extended_asm ();
2589 :
2590 : /* Gimplify and lower all functions, compute reachability and
2591 : remove unreachable nodes. */
2592 263682 : analyze_functions (/*first_time=*/true);
2593 :
2594 : /* Mark alias targets necessary and emit diagnostics. */
2595 263669 : handle_alias_pairs ();
2596 :
2597 : /* Gimplify and lower thunks. */
2598 263669 : analyze_functions (/*first_time=*/false);
2599 :
2600 : /* All nested functions should be lowered now. */
2601 263669 : nested_function_info::release ();
2602 :
2603 : /* Offloading requires LTO infrastructure. */
2604 263669 : if (!in_lto_p && g->have_offload)
2605 0 : flag_generate_offload = 1;
2606 :
2607 263669 : if (!seen_error ())
2608 : {
2609 237187 : timevar_push (TV_SYMOUT);
2610 :
2611 : /* Give the frontends the chance to emit early debug based on
2612 : what is still reachable in the TU. */
2613 237187 : (*lang_hooks.finalize_early_debug) ();
2614 :
2615 : /* Clean up anything that needs cleaning up after initial debug
2616 : generation. */
2617 237187 : debuginfo_early_start ();
2618 237187 : (*debug_hooks->early_finish) (main_input_filename);
2619 237187 : debuginfo_early_stop ();
2620 :
2621 237187 : timevar_pop (TV_SYMOUT);
2622 : }
2623 :
2624 : /* Finally drive the pass manager. */
2625 263669 : compile ();
2626 :
2627 263659 : timevar_pop (TV_CGRAPH);
2628 263659 : }
2629 :
2630 : /* Reset all state within cgraphunit.cc so that we can rerun the compiler
2631 : within the same process. For use by toplev::finalize. */
2632 :
2633 : void
2634 264460 : cgraphunit_cc_finalize (void)
2635 : {
2636 264460 : gcc_assert (cgraph_new_nodes.length () == 0);
2637 264460 : cgraph_new_nodes.truncate (0);
2638 :
2639 264460 : queued_nodes = &symtab_terminator;
2640 :
2641 264460 : first_analyzed = NULL;
2642 264460 : first_analyzed_var = NULL;
2643 264460 : }
2644 :
2645 : /* Creates a wrapper from cgraph_node to TARGET node. Thunk is used for this
2646 : kind of wrapper method. */
2647 :
2648 : void
2649 18678 : cgraph_node::create_wrapper (cgraph_node *target)
2650 : {
2651 : /* Preserve DECL_RESULT so we get right by reference flag. */
2652 18678 : tree decl_result = DECL_RESULT (decl);
2653 :
2654 : /* Remove the function's body but keep arguments to be reused
2655 : for thunk. */
2656 18678 : release_body (true);
2657 18678 : reset ();
2658 :
2659 18678 : DECL_UNINLINABLE (decl) = false;
2660 18678 : DECL_RESULT (decl) = decl_result;
2661 18678 : DECL_INITIAL (decl) = NULL;
2662 18678 : allocate_struct_function (decl, false);
2663 18678 : set_cfun (NULL);
2664 :
2665 : /* Turn alias into thunk and expand it into GIMPLE representation. */
2666 18678 : definition = true;
2667 18678 : semantic_interposition = opt_for_fn (decl, flag_semantic_interposition);
2668 :
2669 : /* Create empty thunk, but be sure we did not keep former thunk around.
2670 : In that case we would need to preserve the info. */
2671 18678 : gcc_checking_assert (!thunk_info::get (this));
2672 18678 : thunk_info::get_create (this);
2673 18678 : thunk = true;
2674 18678 : create_edge (target, NULL, count);
2675 18678 : callees->can_throw_external = !TREE_NOTHROW (target->decl);
2676 :
2677 18678 : tree arguments = DECL_ARGUMENTS (decl);
2678 :
2679 51317 : while (arguments)
2680 : {
2681 32639 : TREE_ADDRESSABLE (arguments) = false;
2682 32639 : arguments = TREE_CHAIN (arguments);
2683 : }
2684 :
2685 : /* Forced GIMPLE thunks are normally ignored because they are created
2686 : after early debug. ICF wrappers retain the original function decl and
2687 : its early DIE, so preserve its original debug state. */
2688 18678 : bool ignored_p = DECL_IGNORED_P (decl);
2689 18678 : expand_thunk (this, false, true);
2690 18678 : DECL_IGNORED_P (decl) = ignored_p;
2691 18678 : thunk_info::remove (this);
2692 :
2693 : /* Inline summary set-up. */
2694 18678 : analyze ();
2695 18678 : inline_analyze_function (this);
2696 18678 : }
|