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