1 /* Driver of optimization process
2 Copyright (C) 2003-2025 Free Software Foundation, Inc.
3 Contributed by Jan Hubicka
5 This file is part of GCC.
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
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
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/>. */
21 /* This module implements main driver of compilation process.
23 The main scope of this file is to act as an interface in between
24 tree based frontends and the backend.
26 The front-end is supposed to use following functionality:
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.
33 (There is one exception needed for implementing GCC extern inline
36 - varpool_finalize_decl
38 This function has same behavior as the above but is used for static
43 Insert new toplevel ASM statement
45 - finalize_compilation_unit
47 This function is called once (source level) compilation unit is finalized
48 and it will no longer change.
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.
55 At the end the bodies of unreachable functions are removed.
57 The function can be called multiple times when multiple source level
58 compilation units are combined.
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
70 1) Inter-procedural optimization.
73 This part is further split into:
75 a) early optimizations. These are local passes executed in
76 the topological order on the callgraph.
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.
83 b) early small interprocedural passes.
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.
89 c) IP analysis stage. All interprocedural passes do their
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.
98 d) LTO streaming. When doing LTO, everything important gets
99 streamed into the object file.
101 Compile time and or linktime analysis stage (WPA):
103 At linktime units gets streamed back and symbol table is
104 merged. Function bodies are not streamed in and not
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.
112 Compile time and/or parallel linktime stage (ltrans)
114 Each of the object files is streamed back and compiled
115 separately. Now the function bodies becomes available
118 2) Virtual clone materialization
119 (cgraph_materialize_clone)
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
128 All IP passes transform function bodies based on earlier
129 decision of the IP propagation.
131 4) late small IP passes
133 Simple IP passes working within single program partition.
136 (expand_all_functions)
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.
144 Note that with -fno-toplevel-reorder passes 5 and 6
145 are combined together in cgraph_output_in_order.
147 Finally there are functions to manipulate the callgraph from
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.
154 - cgraph_function_versioning
156 produces a copy of function into new one (a version)
157 and apply simple transformations
162 #include "coretypes.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"
175 #include "coverage.h"
176 #include "lto-streamer.h"
177 #include "fold-const.h"
179 #include "stor-layout.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"
192 #include "symbol-summary.h"
193 #include "tree-vrp.h"
196 #include "ipa-prop.h"
197 #include "gimple-pretty-print.h"
199 #include "ipa-fnsummary.h"
200 #include "ipa-utils.h"
204 #include "pass_manager.h"
205 #include "tree-nested.h"
207 #include "lto-section-names.h"
208 #include "stringpool.h"
210 #include "ipa-inline.h"
211 #include "omp-offload.h"
212 #include "symtab-thunks.h"
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
;
219 static void expand_all_functions (void);
220 static void mark_functions_to_output (void);
221 static void handle_alias_pairs (void);
223 /* Return true if this symbol is a function from the C frontend specified
224 directly in RTL form (with "__RTL"). */
227 symtab_node::native_rtl_p () const
229 if (TREE_CODE (decl
) != FUNCTION_DECL
)
231 if (!DECL_STRUCT_FUNCTION (decl
))
233 return DECL_STRUCT_FUNCTION (decl
)->curr_properties
& PROP_rtl
;
236 /* Determine if symbol declaration is needed. That is, visible to something
237 either outside this translation unit, something magic in the system
240 symtab_node::needed_p (void)
242 /* Double check that no one output the function into assembly file
244 if (!native_rtl_p ())
246 (!DECL_ASSEMBLER_NAME_SET_P (decl
)
247 || !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl
)));
252 if (DECL_EXTERNAL (decl
))
255 /* If the user told us it is used, then it must be so. */
259 /* ABI forced symbols are needed when they are external. */
260 if (forced_by_abi
&& TREE_PUBLIC (decl
))
263 /* Keep constructors, destructors and virtual functions. */
264 if (TREE_CODE (decl
) == FUNCTION_DECL
265 && (DECL_STATIC_CONSTRUCTOR (decl
) || DECL_STATIC_DESTRUCTOR (decl
)))
268 /* Externally visible variables must be output. The exception is
269 COMDAT variables that must be output only when they are needed. */
270 if (TREE_PUBLIC (decl
) && !DECL_COMDAT (decl
))
276 /* Head and terminator of the queue of nodes to be processed while building
279 static symtab_node
symtab_terminator (SYMTAB_SYMBOL
);
280 static symtab_node
*queued_nodes
= &symtab_terminator
;
282 /* Add NODE to queue starting at QUEUED_NODES.
283 The queue is linked via AUX pointers and terminated by pointer to 1. */
286 enqueue_node (symtab_node
*node
)
290 gcc_checking_assert (queued_nodes
);
291 node
->aux
= queued_nodes
;
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. */
300 symbol_table::process_new_functions (void)
304 if (!cgraph_new_nodes
.exists ())
307 handle_alias_pairs ();
308 /* Note that this queue may grow as its being processed, as the new
309 functions may generate new ones. */
310 for (unsigned i
= 0; i
< cgraph_new_nodes
.length (); i
++)
312 cgraph_node
*node
= cgraph_new_nodes
[i
];
314 bitmap_obstack_initialize (NULL
);
318 /* At construction time we just need to finalize function and move
319 it into reachable functions list. */
321 cgraph_node::finalize_function (fndecl
, false);
322 call_cgraph_insertion_hooks (node
);
328 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. */
333 gimple_register_cfg_hooks ();
336 push_cfun (DECL_STRUCT_FUNCTION (fndecl
));
337 if ((state
== IPA_SSA
|| state
== IPA_SSA_AFTER_INLINING
)
338 && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl
)))
340 bool summaried_computed
= ipa_fn_summaries
!= NULL
;
341 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 if (!summaried_computed
)
347 ipa_free_fn_summary ();
348 ipa_free_size_summary ();
351 else if (ipa_fn_summaries
!= NULL
)
352 compute_fn_summary (node
, true);
353 free_dominance_info (CDI_POST_DOMINATORS
);
354 free_dominance_info (CDI_DOMINATORS
);
356 call_cgraph_insertion_hooks (node
);
360 /* Functions created during expansion shall be compiled
363 call_cgraph_insertion_hooks (node
);
371 bitmap_obstack_release (NULL
);
374 cgraph_new_nodes
.release ();
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
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.
387 This is also used to cancel C++ mangling aliases, which can be for
388 functions or variables. */
391 symtab_node::reset (bool preserve_comdat_group
)
393 /* Reset our data structures so we can analyze the function again. */
397 transparent_alias
= false;
399 cpp_implicit_alias
= false;
401 remove_all_references ();
402 if (!preserve_comdat_group
)
403 remove_from_same_comdat_group ();
405 if (cgraph_node
*cn
= dyn_cast
<cgraph_node
*> (this))
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 gcc_assert (!cn
->process
);
414 memset (&cn
->rtl
, 0, sizeof (cn
->rtl
));
415 cn
->inlined_to
= NULL
;
416 cn
->remove_callees ();
420 /* Return true when there are references to the node. INCLUDE_SELF is
421 true if a self reference counts as a reference. */
424 symtab_node::referred_to_p (bool include_self
)
428 /* See if there are any references at all. */
429 if (iterate_referring (0, ref
))
431 /* For functions check also calls. */
432 cgraph_node
*cn
= dyn_cast
<cgraph_node
*> (this);
433 if (cn
&& cn
->callers
)
437 for (cgraph_edge
*e
= cn
->callers
; e
; e
= e
->next_caller
)
438 if (e
->caller
!= this)
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. */
450 cgraph_node::finalize_function (tree decl
, bool no_collect
)
452 cgraph_node
*node
= cgraph_node::get_create (decl
);
454 if (node
->definition
)
456 /* Nested functions should only be defined once. */
457 gcc_assert (!DECL_CONTEXT (decl
)
458 || TREE_CODE (DECL_CONTEXT (decl
)) != FUNCTION_DECL
);
460 node
->redefined_extern_inline
= true;
463 /* Set definition first before calling notice_global_symbol so that
464 it is available to notice_global_symbol. */
465 node
->definition
= true;
466 notice_global_symbol (decl
);
467 node
->lowered
= DECL_STRUCT_FUNCTION (decl
)->cfg
!= NULL
;
468 node
->semantic_interposition
= opt_for_fn (decl
, flag_semantic_interposition
);
469 if (!flag_toplevel_reorder
)
470 node
->no_reorder
= true;
472 /* With -fkeep-inline-functions we are keeping all inline functions except
473 for extern inline ones. */
474 if (flag_keep_inline_functions
475 && DECL_DECLARED_INLINE_P (decl
)
476 && !DECL_EXTERNAL (decl
)
477 && !DECL_DISREGARD_INLINE_LIMITS (decl
))
478 node
->force_output
= 1;
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 if (node
->native_rtl_p ())
486 node
->force_output
= 1;
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 if (((!opt_for_fn (decl
, optimize
) || flag_keep_static_functions
495 && !node
->cpp_implicit_alias
496 && !DECL_DISREGARD_INLINE_LIMITS (decl
)
497 && !DECL_DECLARED_INLINE_P (decl
)
498 && !(DECL_CONTEXT (decl
)
499 && TREE_CODE (DECL_CONTEXT (decl
)) == FUNCTION_DECL
))
500 && !DECL_COMDAT (decl
) && !DECL_EXTERNAL (decl
))
501 node
->force_output
= 1;
503 /* If we've not yet emitted decl, tell the debug info about it. */
504 if (!TREE_ASM_WRITTEN (decl
))
505 (*debug_hooks
->deferred_inline_function
) (decl
);
510 if (symtab
->state
== CONSTRUCTION
511 && (node
->needed_p () || node
->referred_to_p ()))
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
521 The function is assumed to be reachable and have address taken (so no
522 API breaking optimizations are performed on it).
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. */
528 cgraph_node::add_new_function (tree fndecl
, bool lowered
)
530 gcc::pass_manager
*passes
= g
->get_passes ();
535 struct function
*fn
= DECL_STRUCT_FUNCTION (fndecl
);
536 const char *function_type
= ((gimple_has_body_p (fndecl
))
538 ? (gimple_in_ssa_p (fn
)
542 : "to-be-gimplified");
544 "Added new %s function %s to callgraph\n",
546 fndecl_name (fndecl
));
549 switch (symtab
->state
)
552 cgraph_node::finalize_function (fndecl
, false);
555 /* Just enqueue function to be processed at nearest occurrence. */
556 node
= cgraph_node::get_create (fndecl
);
558 node
->lowered
= true;
559 cgraph_new_nodes
.safe_push (node
);
564 case IPA_SSA_AFTER_INLINING
:
566 /* Bring the function into finalized state and enqueue for later
567 analyzing and compilation. */
568 node
= cgraph_node::get_create (fndecl
);
570 node
->definition
= true;
571 node
->semantic_interposition
= opt_for_fn (fndecl
,
572 flag_semantic_interposition
);
573 node
->force_output
= true;
574 if (TREE_PUBLIC (fndecl
))
575 node
->externally_visible
= true;
576 if (!lowered
&& symtab
->state
== EXPANSION
)
578 push_cfun (DECL_STRUCT_FUNCTION (fndecl
));
579 gimple_register_cfg_hooks ();
580 bitmap_obstack_initialize (NULL
);
581 execute_pass_list (cfun
, passes
->all_lowering_passes
);
582 passes
->execute_early_local_passes ();
583 bitmap_obstack_release (NULL
);
589 node
->lowered
= true;
590 cgraph_new_nodes
.safe_push (node
);
594 /* At the very end of compilation we have to do all the work up
596 node
= cgraph_node::create (fndecl
);
598 node
->lowered
= true;
599 node
->definition
= true;
600 node
->semantic_interposition
= opt_for_fn (fndecl
,
601 flag_semantic_interposition
);
603 push_cfun (DECL_STRUCT_FUNCTION (fndecl
));
604 gimple_register_cfg_hooks ();
605 bitmap_obstack_initialize (NULL
);
606 if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl
)))
607 g
->get_passes ()->execute_early_local_passes ();
608 bitmap_obstack_release (NULL
);
617 /* Set a personality if required and we already passed EH lowering. */
619 && (function_needs_eh_personality (DECL_STRUCT_FUNCTION (fndecl
))
620 == eh_personality_lang
))
621 DECL_FUNCTION_PERSONALITY (fndecl
) = lang_hooks
.eh_personality ();
624 /* Analyze the function scheduled to be output. */
626 cgraph_node::analyze (void)
634 tree decl
= this->decl
;
635 location_t saved_loc
= input_location
;
636 input_location
= DECL_SOURCE_LOCATION (decl
);
637 semantic_interposition
= opt_for_fn (decl
, flag_semantic_interposition
);
641 thunk_info
*info
= thunk_info::get (this);
642 cgraph_node
*t
= cgraph_node::get (info
->alias
);
644 create_edge (t
, NULL
, t
->count
);
645 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 if (!t
->analyzed
&& t
->definition
)
652 t
= t
->get_alias_target ();
653 if (!t
->analyzed
&& t
->definition
)
656 bool ret
= expand_thunk (this, false, false);
657 thunk_info::get (this)->alias
= NULL
;
662 resolve_alias (cgraph_node::get (alias_target
), transparent_alias
);
663 else if (dispatcher_function
)
665 /* Generate the dispatcher body of multi-versioned functions. */
666 cgraph_function_version_info
*dispatcher_version_info
667 = function_version ();
668 if (dispatcher_version_info
!= NULL
669 && (dispatcher_version_info
->dispatcher_resolver
672 tree resolver
= NULL_TREE
;
673 gcc_assert (targetm
.generate_version_dispatcher_body
);
674 resolver
= targetm
.generate_version_dispatcher_body (this);
675 gcc_assert (resolver
!= NULL_TREE
);
680 push_cfun (DECL_STRUCT_FUNCTION (decl
));
682 assign_assembler_name_if_needed (decl
);
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
688 if (!gimple_has_body_p (decl
))
689 gimplify_function_tree (decl
);
691 /* Lower the function. */
694 if (first_nested_function (this))
695 lower_nested_functions (decl
);
697 gimple_register_cfg_hooks ();
698 bitmap_obstack_initialize (NULL
);
699 execute_pass_list (cfun
, g
->get_passes ()->all_lowering_passes
);
701 bitmap_obstack_release (NULL
);
709 input_location
= saved_loc
;
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. */
719 symbol_table::process_same_body_aliases (void)
722 FOR_EACH_SYMBOL (node
)
723 if (node
->cpp_implicit_alias
&& !node
->analyzed
)
725 (VAR_P (node
->alias_target
)
726 ? (symtab_node
*)varpool_node::get_create (node
->alias_target
)
727 : (symtab_node
*)cgraph_node::get_create (node
->alias_target
));
728 cpp_implicit_aliases_done
= true;
731 /* Process a symver attribute. */
734 process_symver_attribute (symtab_node
*n
)
736 tree value
= lookup_attribute ("symver", DECL_ATTRIBUTES (n
->decl
));
738 for (; value
!= NULL
; value
= TREE_CHAIN (value
))
740 /* Starting from bintuils 2.35 gas supports:
741 # Assign foo to bar@V1 and baz@V2.
745 const char *purpose
= IDENTIFIER_POINTER (TREE_PURPOSE (value
));
746 if (strcmp (purpose
, "symver") != 0)
749 tree symver
= get_identifier_with_length
750 (TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (value
))),
751 TREE_STRING_LENGTH (TREE_VALUE (TREE_VALUE (value
))));
752 symtab_node
*def
= symtab_node::get_for_asmname (symver
);
756 error_at (DECL_SOURCE_LOCATION (n
->decl
),
757 "duplicate definition of a symbol version");
758 inform (DECL_SOURCE_LOCATION (def
->decl
),
759 "same version was previously defined here");
764 error_at (DECL_SOURCE_LOCATION (n
->decl
),
765 "symbol needs to be defined to have a version");
768 if (DECL_COMMON (n
->decl
))
770 error_at (DECL_SOURCE_LOCATION (n
->decl
),
771 "common symbol cannot be versioned");
774 if (DECL_COMDAT (n
->decl
))
776 error_at (DECL_SOURCE_LOCATION (n
->decl
),
777 "comdat symbol cannot be versioned");
782 error_at (DECL_SOURCE_LOCATION (n
->decl
),
783 "%<weakref%> cannot be versioned");
786 if (!TREE_PUBLIC (n
->decl
))
788 error_at (DECL_SOURCE_LOCATION (n
->decl
),
789 "versioned symbol must be public");
792 if (DECL_VISIBILITY (n
->decl
) != VISIBILITY_DEFAULT
)
794 error_at (DECL_SOURCE_LOCATION (n
->decl
),
795 "versioned symbol must have default visibility");
799 /* Create new symbol table entry representing the version. */
800 tree new_decl
= copy_node (n
->decl
);
802 DECL_INITIAL (new_decl
) = NULL_TREE
;
803 if (TREE_CODE (new_decl
) == FUNCTION_DECL
)
804 DECL_STRUCT_FUNCTION (new_decl
) = NULL
;
805 SET_DECL_ASSEMBLER_NAME (new_decl
, symver
);
806 TREE_PUBLIC (new_decl
) = 1;
807 DECL_ATTRIBUTES (new_decl
) = NULL
;
809 symtab_node
*symver_node
= symtab_node::get_create (new_decl
);
810 symver_node
->alias
= true;
811 symver_node
->definition
= true;
812 symver_node
->symver
= true;
813 symver_node
->create_reference (n
, IPA_REF_ALIAS
, NULL
);
814 symver_node
->analyzed
= true;
818 /* Process attributes common for vars and functions. */
821 process_common_attributes (symtab_node
*node
, tree decl
)
823 tree weakref
= lookup_attribute ("weakref", DECL_ATTRIBUTES (decl
));
825 if (weakref
&& !lookup_attribute ("alias", DECL_ATTRIBUTES (decl
)))
827 warning_at (DECL_SOURCE_LOCATION (decl
), OPT_Wattributes
,
828 "%<weakref%> attribute should be accompanied with"
829 " an %<alias%> attribute");
830 DECL_WEAK (decl
) = 0;
831 DECL_ATTRIBUTES (decl
) = remove_attribute ("weakref",
832 DECL_ATTRIBUTES (decl
));
835 if (lookup_attribute ("no_reorder", DECL_ATTRIBUTES (decl
)))
836 node
->no_reorder
= 1;
837 process_symver_attribute (node
);
840 /* Look for externally_visible and used attributes and mark cgraph nodes
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:
848 void f() __attribute__((used));
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.
854 Furthermore, we can't mark these nodes in finalize_function because:
857 void f() __attribute__((externally_visible));
861 So, we walk the nodes at the end of the translation unit, applying the
862 attributes at that point. */
865 process_function_and_variable_attributes (cgraph_node
*first
,
866 varpool_node
*first_var
)
871 for (node
= symtab
->first_function (); node
!= first
;
872 node
= symtab
->next_function (node
))
874 tree decl
= node
->decl
;
877 && lookup_attribute ("flatten", DECL_ATTRIBUTES (decl
)))
879 tree tdecl
= node
->get_alias_target_tree ();
880 if (!tdecl
|| !DECL_P (tdecl
)
881 || !lookup_attribute ("flatten", DECL_ATTRIBUTES (tdecl
)))
882 warning_at (DECL_SOURCE_LOCATION (decl
), OPT_Wattributes
,
883 "%<flatten%> attribute is ignored on aliases");
885 if (DECL_PRESERVE_P (decl
))
886 node
->mark_force_output ();
887 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl
)))
889 if (! TREE_PUBLIC (node
->decl
))
890 warning_at (DECL_SOURCE_LOCATION (node
->decl
), OPT_Wattributes
,
891 "%<externally_visible%>"
892 " attribute have effect only on public objects");
894 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl
))
896 && (!node
->alias
|| DECL_INITIAL (decl
) != error_mark_node
))
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 warning_at (DECL_SOURCE_LOCATION (decl
), OPT_Wattributes
,
902 "%<weakref%> attribute ignored"
903 " because function is defined");
904 DECL_WEAK (decl
) = 0;
905 DECL_ATTRIBUTES (decl
) = remove_attribute ("weakref",
906 DECL_ATTRIBUTES (decl
));
907 DECL_ATTRIBUTES (decl
) = remove_attribute ("alias",
908 DECL_ATTRIBUTES (decl
));
910 node
->weakref
= false;
911 node
->transparent_alias
= false;
913 else if (lookup_attribute ("alias", DECL_ATTRIBUTES (decl
))
916 warning_at (DECL_SOURCE_LOCATION (node
->decl
), OPT_Wattributes
,
917 "%<alias%> attribute ignored"
918 " because function is defined");
920 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl
))
921 && !DECL_DECLARED_INLINE_P (decl
)
922 /* redefining extern inline function makes it DECL_UNINLINABLE. */
923 && !DECL_UNINLINABLE (decl
))
924 warning_at (DECL_SOURCE_LOCATION (decl
), OPT_Wattributes
,
925 "%<always_inline%> function might not be inlinable"
926 " unless also declared %<inline%>");
928 process_common_attributes (node
, decl
);
930 for (vnode
= symtab
->first_variable (); vnode
!= first_var
;
931 vnode
= symtab
->next_variable (vnode
))
933 tree decl
= vnode
->decl
;
934 if (DECL_EXTERNAL (decl
)
935 && DECL_INITIAL (decl
))
936 varpool_node::finalize_decl (decl
);
937 if (DECL_PRESERVE_P (decl
))
938 vnode
->force_output
= true;
939 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl
)))
941 if (! TREE_PUBLIC (vnode
->decl
))
942 warning_at (DECL_SOURCE_LOCATION (vnode
->decl
), OPT_Wattributes
,
943 "%<externally_visible%>"
944 " attribute have effect only on public objects");
946 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl
))
948 && DECL_INITIAL (decl
))
950 warning_at (DECL_SOURCE_LOCATION (vnode
->decl
), OPT_Wattributes
,
951 "%<weakref%> attribute ignored"
952 " because variable is initialized");
953 DECL_WEAK (decl
) = 0;
954 DECL_ATTRIBUTES (decl
) = remove_attribute ("weakref",
955 DECL_ATTRIBUTES (decl
));
957 process_common_attributes (vnode
, decl
);
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
966 varpool_node::finalize_decl (tree decl
)
968 varpool_node
*node
= varpool_node::get_create (decl
);
970 gcc_assert (TREE_STATIC (decl
) || DECL_EXTERNAL (decl
));
972 if (node
->definition
)
974 /* Set definition first before calling notice_global_symbol so that
975 it is available to notice_global_symbol. */
976 node
->definition
= true;
977 node
->semantic_interposition
= flag_semantic_interposition
;
978 notice_global_symbol (decl
);
979 if (!flag_toplevel_reorder
)
980 node
->no_reorder
= true;
981 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 || (node
->no_reorder
&& !DECL_COMDAT (node
->decl
)
985 && !DECL_ARTIFICIAL (node
->decl
)))
986 node
->force_output
= true;
990 tree attr
= lookup_attribute ("omp allocate", DECL_ATTRIBUTES (decl
));
993 tree align
= TREE_VALUE (TREE_VALUE (attr
));
995 SET_DECL_ALIGN (decl
, MAX (tree_to_uhwi (align
) * BITS_PER_UNIT
,
1000 if (symtab
->state
== CONSTRUCTION
1001 && (node
->needed_p () || node
->referred_to_p ()))
1002 enqueue_node (node
);
1003 if (symtab
->state
>= IPA_SSA
)
1005 /* Some frontends produce various interface variables after compilation
1007 if (symtab
->state
== FINISHED
1008 || (node
->no_reorder
1009 && symtab
->state
== EXPANSION
))
1010 node
->assemble_decl ();
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. */
1019 walk_polymorphic_call_targets (hash_set
<void *> *reachable_call_targets
,
1025 vec
<cgraph_node
*>targets
1026 = possible_polymorphic_call_targets
1027 (edge
, &final
, &cache_token
);
1029 if (cache_token
!= NULL
&& !reachable_call_targets
->add (cache_token
))
1031 if (symtab
->dump_file
)
1032 dump_possible_polymorphic_call_targets
1033 (symtab
->dump_file
, edge
);
1035 for (i
= 0; i
< targets
.length (); i
++)
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
1040 if (targets
[i
]->definition
1042 (TREE_TYPE (targets
[i
]->decl
))
1044 && !type_in_anonymous_namespace_p
1045 (TYPE_METHOD_BASETYPE (TREE_TYPE (targets
[i
]->decl
))))
1046 enqueue_node (targets
[i
]);
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. */
1056 if (targets
.length () <= 1 && dbg_cnt (devirt
))
1058 cgraph_node
*target
;
1059 if (targets
.length () == 1)
1060 target
= targets
[0];
1062 target
= cgraph_node::create (builtin_decl_unreachable ());
1064 if (symtab
->dump_file
)
1066 fprintf (symtab
->dump_file
,
1067 "Devirtualizing call: ");
1068 print_gimple_stmt (symtab
->dump_file
,
1072 if (dump_enabled_p ())
1074 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS
, edge
->call_stmt
,
1075 "devirtualizing call in %s to %s\n",
1076 edge
->caller
->dump_name (),
1077 target
->dump_name ());
1080 edge
= cgraph_edge::make_direct (edge
, target
);
1081 gimple
*new_call
= cgraph_edge::redirect_call_stmt_to_callee (edge
);
1083 if (symtab
->dump_file
)
1085 fprintf (symtab
->dump_file
, "Devirtualized as: ");
1086 print_gimple_stmt (symtab
->dump_file
, new_call
, 0, TDF_SLIM
);
1092 /* Issue appropriate warnings for the global declaration DECL. */
1095 check_global_declaration (symtab_node
*snode
)
1097 const char *decl_file
;
1098 tree decl
= snode
->decl
;
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 if (TREE_CODE (decl
) == FUNCTION_DECL
1104 && DECL_INITIAL (decl
) == 0
1105 && DECL_EXTERNAL (decl
)
1106 && ! DECL_ARTIFICIAL (decl
)
1107 && ! TREE_PUBLIC (decl
))
1109 if (warning_suppressed_p (decl
, OPT_Wunused
))
1111 else if (snode
->referred_to_p (/*include_self=*/false))
1112 pedwarn (input_location
, 0, "%q+F used but never defined", decl
);
1114 warning (OPT_Wunused_function
, "%q+F declared %<static%> but never "
1118 /* Warn about static fns or vars defined but not used. */
1119 if (((warn_unused_function
&& TREE_CODE (decl
) == FUNCTION_DECL
)
1120 || (((warn_unused_variable
&& ! TREE_READONLY (decl
))
1121 || (warn_unused_const_variable
> 0 && TREE_READONLY (decl
)
1122 && (warn_unused_const_variable
== 2
1123 || (main_input_filename
!= NULL
1124 && (decl_file
= DECL_SOURCE_FILE (decl
)) != NULL
1125 && filename_cmp (main_input_filename
,
1128 && ! DECL_IN_SYSTEM_HEADER (decl
)
1129 && ! 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 && ! 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 && ! (DECL_NAME (decl
) && TREE_USED (DECL_NAME (decl
)))
1137 && ! DECL_EXTERNAL (decl
)
1138 && ! DECL_ARTIFICIAL (decl
)
1139 && ! DECL_ABSTRACT_ORIGIN (decl
)
1140 && ! TREE_PUBLIC (decl
)
1141 /* A volatile variable might be used in some non-obvious way. */
1142 && (! VAR_P (decl
) || ! TREE_THIS_VOLATILE (decl
))
1143 /* Global register variables must be declared to reserve them. */
1144 && ! (VAR_P (decl
) && DECL_REGISTER (decl
))
1145 /* Global ctors and dtors are called by the runtime. */
1146 && (TREE_CODE (decl
) != FUNCTION_DECL
1147 || (!DECL_STATIC_CONSTRUCTOR (decl
)
1148 && !DECL_STATIC_DESTRUCTOR (decl
)))
1149 && (! VAR_P (decl
) || !warning_suppressed_p (decl
, OPT_Wunused_variable
))
1150 /* Otherwise, ask the language. */
1151 && lang_hooks
.decls
.warn_unused_global (decl
))
1152 warning_at (DECL_SOURCE_LOCATION (decl
),
1153 (TREE_CODE (decl
) == FUNCTION_DECL
)
1154 ? OPT_Wunused_function
1155 : (TREE_READONLY (decl
)
1156 ? OPT_Wunused_const_variable_
1157 : OPT_Wunused_variable
),
1158 "%qD defined but not used", decl
);
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
;
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
1171 analyze_functions (bool first_time
)
1173 /* Keep track of already processed nodes when called multiple times for
1174 intermodule optimization. */
1175 cgraph_node
*first_handled
= first_analyzed
;
1176 varpool_node
*first_handled_var
= first_analyzed_var
;
1177 hash_set
<void *> reachable_call_targets
;
1183 bool changed
= true;
1184 location_t saved_loc
= input_location
;
1186 bitmap_obstack_initialize (NULL
);
1187 symtab
->state
= CONSTRUCTION
;
1188 input_location
= UNKNOWN_LOCATION
;
1190 thunk_info::process_early_thunks ();
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 if (symtab
->cpp_implicit_aliases_done
)
1195 FOR_EACH_SYMBOL (node
)
1196 if (node
->cpp_implicit_alias
)
1197 node
->fixup_same_cpp_alias_visibility (node
->get_alias_target ());
1198 build_type_inheritance_graph ();
1200 if (flag_openmp
&& first_time
)
1201 omp_discover_implicit_declare_target ();
1203 /* Analysis adds static variables that in turn adds references to new functions.
1204 So we need to iterate the process until it stabilize. */
1208 process_function_and_variable_attributes (first_analyzed
,
1209 first_analyzed_var
);
1211 /* First identify the trivially needed symbols. */
1212 for (node
= symtab
->first_symbol ();
1213 node
!= first_analyzed
1214 && node
!= first_analyzed_var
; node
= node
->next
)
1216 /* Convert COMDAT group designators to IDENTIFIER_NODEs. */
1217 node
->get_comdat_group_id ();
1218 if (node
->needed_p ())
1220 enqueue_node (node
);
1221 if (!changed
&& symtab
->dump_file
)
1222 fprintf (symtab
->dump_file
, "Trivially needed symbols:");
1224 if (symtab
->dump_file
)
1225 fprintf (symtab
->dump_file
, " %s", node
->dump_asm_name ());
1227 if (node
== first_analyzed
1228 || node
== first_analyzed_var
)
1231 symtab
->process_new_functions ();
1232 first_analyzed_var
= symtab
->first_variable ();
1233 first_analyzed
= symtab
->first_function ();
1235 if (changed
&& symtab
->dump_file
)
1236 fprintf (symtab
->dump_file
, "\n");
1238 /* Lower representation, build callgraph edges and references for all trivially
1239 needed symbols and all symbols referred by them. */
1240 while (queued_nodes
!= &symtab_terminator
)
1243 node
= queued_nodes
;
1244 queued_nodes
= (symtab_node
*)queued_nodes
->aux
;
1245 cgraph_node
*cnode
= dyn_cast
<cgraph_node
*> (node
);
1246 if (cnode
&& cnode
->definition
)
1249 tree decl
= cnode
->decl
;
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 if (!DECL_STRUCT_FUNCTION (decl
)
1257 && !cnode
->dispatcher_function
)
1260 cnode
->redefined_extern_inline
= true;
1264 if (!cnode
->analyzed
)
1267 for (edge
= cnode
->callees
; edge
; edge
= edge
->next_callee
)
1268 if (edge
->callee
->definition
1269 && (!DECL_EXTERNAL (edge
->callee
->decl
)
1270 /* When not optimizing, do not try to analyze extern
1271 inline functions. Doing so is pointless. */
1272 || opt_for_fn (edge
->callee
->decl
, optimize
)
1273 /* Weakrefs needs to be preserved. */
1274 || edge
->callee
->alias
1275 /* always_inline functions are inlined even at -O0. */
1278 DECL_ATTRIBUTES (edge
->callee
->decl
))
1279 /* Multiversioned functions needs the dispatcher to
1280 be produced locally even for extern functions. */
1281 || edge
->callee
->function_version ()))
1282 enqueue_node (edge
->callee
);
1283 if (opt_for_fn (cnode
->decl
, optimize
)
1284 && opt_for_fn (cnode
->decl
, flag_devirtualize
))
1288 for (edge
= cnode
->indirect_calls
; edge
; edge
= next
)
1290 next
= edge
->next_callee
;
1291 if (edge
->indirect_info
->polymorphic
)
1292 walk_polymorphic_call_targets (&reachable_call_targets
,
1297 /* If decl is a clone of an abstract function,
1298 mark that abstract function so that we don't release its body.
1299 The DECL_INITIAL() of that abstract function declaration
1300 will be later needed to output debug info. */
1301 if (DECL_ABSTRACT_ORIGIN (decl
))
1303 cgraph_node
*origin_node
1304 = cgraph_node::get_create (DECL_ABSTRACT_ORIGIN (decl
));
1305 origin_node
->used_as_abstract_origin
= true;
1307 /* Preserve a functions function context node. It will
1308 later be needed to output debug info. */
1309 if (tree fn
= decl_function_context (decl
))
1311 cgraph_node
*origin_node
= cgraph_node::get_create (fn
);
1312 enqueue_node (origin_node
);
1317 varpool_node
*vnode
= dyn_cast
<varpool_node
*> (node
);
1318 if (vnode
&& vnode
->definition
&& !vnode
->analyzed
)
1322 if (node
->same_comdat_group
)
1325 for (next
= node
->same_comdat_group
;
1327 next
= next
->same_comdat_group
)
1328 if (!next
->comdat_local_p ())
1329 enqueue_node (next
);
1331 for (i
= 0; node
->iterate_reference (i
, ref
); i
++)
1332 if (ref
->referred
->definition
1333 && (!DECL_EXTERNAL (ref
->referred
->decl
)
1334 || ((TREE_CODE (ref
->referred
->decl
) != FUNCTION_DECL
1336 || (TREE_CODE (ref
->referred
->decl
) == FUNCTION_DECL
1337 && opt_for_fn (ref
->referred
->decl
, optimize
))
1339 || ref
->referred
->alias
)))
1340 enqueue_node (ref
->referred
);
1341 symtab
->process_new_functions ();
1344 update_type_inheritance_graph ();
1346 /* Collect entry points to the unit. */
1347 if (symtab
->dump_file
)
1349 fprintf (symtab
->dump_file
, "\n\nInitial ");
1350 symtab
->dump (symtab
->dump_file
);
1356 FOR_EACH_SYMBOL (snode
)
1357 check_global_declaration (snode
);
1360 if (symtab
->dump_file
)
1361 fprintf (symtab
->dump_file
, "\nRemoving unused symbols:");
1363 for (node
= symtab
->first_symbol ();
1364 node
!= first_handled
1365 && node
!= first_handled_var
; node
= next
)
1368 /* For symbols declared locally we clear TREE_READONLY when emitting
1369 the constructor (if one is needed). For external declarations we can
1370 not safely assume that the type is readonly because we may be called
1371 during its construction. */
1372 if (TREE_CODE (node
->decl
) == VAR_DECL
1373 && TYPE_P (TREE_TYPE (node
->decl
))
1374 && TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (node
->decl
))
1375 && DECL_EXTERNAL (node
->decl
))
1376 TREE_READONLY (node
->decl
) = 0;
1377 if (!node
->aux
&& !node
->referred_to_p ())
1379 if (symtab
->dump_file
)
1380 fprintf (symtab
->dump_file
, " %s", node
->dump_name ());
1382 /* See if the debugger can use anything before the DECL
1383 passes away. Perhaps it can notice a DECL that is now a
1384 constant and can tag the early DIE with an appropriate
1387 Otherwise, this is the last chance the debug_hooks have
1388 at looking at optimized away DECLs, since
1389 late_global_decl will subsequently be called from the
1390 contents of the now pruned symbol table. */
1391 if (VAR_P (node
->decl
)
1392 && !decl_function_context (node
->decl
))
1394 /* We are reclaiming totally unreachable code and variables
1395 so they effectively appear as readonly. Show that to
1396 the debug machinery. */
1397 TREE_READONLY (node
->decl
) = 1;
1398 node
->definition
= false;
1399 (*debug_hooks
->late_global_decl
) (node
->decl
);
1405 if (cgraph_node
*cnode
= dyn_cast
<cgraph_node
*> (node
))
1407 tree decl
= node
->decl
;
1409 if (cnode
->definition
&& !gimple_has_body_p (decl
)
1414 gcc_assert (!cnode
->definition
|| cnode
->thunk
1416 || gimple_has_body_p (decl
)
1417 || cnode
->native_rtl_p ());
1418 gcc_assert (cnode
->analyzed
== cnode
->definition
);
1422 for (;node
; node
= node
->next
)
1424 first_analyzed
= symtab
->first_function ();
1425 first_analyzed_var
= symtab
->first_variable ();
1426 if (symtab
->dump_file
)
1428 fprintf (symtab
->dump_file
, "\n\nReclaimed ");
1429 symtab
->dump (symtab
->dump_file
);
1431 bitmap_obstack_release (NULL
);
1433 /* Initialize assembler name hash, in particular we want to trigger C++
1434 mangling and same body alias creation before we free DECL_ARGUMENTS
1437 symtab
->symtab_initialize_asm_name_hash ();
1439 input_location
= saved_loc
;
1442 /* Check declaration of the type of ALIAS for compatibility with its TARGET
1443 (which may be an ifunc resolver) and issue a diagnostic when they are
1444 not compatible according to language rules (plus a C++ extension for
1445 non-static member functions). */
1448 maybe_diag_incompatible_alias (tree alias
, tree target
)
1450 tree altype
= TREE_TYPE (alias
);
1451 tree targtype
= TREE_TYPE (target
);
1453 bool ifunc
= cgraph_node::get (alias
)->ifunc_resolver
;
1454 tree funcptr
= altype
;
1458 /* Handle attribute ifunc first. */
1459 if (TREE_CODE (altype
) == METHOD_TYPE
)
1461 /* Set FUNCPTR to the type of the alias target. If the type
1462 is a non-static member function of class C, construct a type
1463 of an ordinary function taking C* as the first argument,
1464 followed by the member function argument list, and use it
1465 instead to check for incompatibility. This conversion is
1466 not defined by the language but an extension provided by
1469 tree rettype
= TREE_TYPE (altype
);
1470 tree args
= TYPE_ARG_TYPES (altype
);
1471 altype
= build_function_type (rettype
, args
);
1475 targtype
= TREE_TYPE (targtype
);
1477 if (POINTER_TYPE_P (targtype
))
1479 targtype
= TREE_TYPE (targtype
);
1481 /* Only issue Wattribute-alias for conversions to void* with
1483 if (VOID_TYPE_P (targtype
) && !extra_warnings
)
1486 /* Proceed to handle incompatible ifunc resolvers below. */
1490 funcptr
= build_pointer_type (funcptr
);
1492 error_at (DECL_SOURCE_LOCATION (target
),
1493 "%<ifunc%> resolver for %qD must return %qT",
1495 inform (DECL_SOURCE_LOCATION (alias
),
1496 "resolver indirect function declared here");
1501 if ((!FUNC_OR_METHOD_TYPE_P (targtype
)
1502 || (prototype_p (altype
)
1503 && prototype_p (targtype
)
1504 && !types_compatible_p (altype
, targtype
))))
1506 /* Warn for incompatibilities. Avoid warning for functions
1507 without a prototype to make it possible to declare aliases
1508 without knowing the exact type, as libstdc++ does. */
1511 funcptr
= build_pointer_type (funcptr
);
1513 auto_diagnostic_group d
;
1514 if (warning_at (DECL_SOURCE_LOCATION (target
),
1515 OPT_Wattribute_alias_
,
1516 "%<ifunc%> resolver for %qD should return %qT",
1518 inform (DECL_SOURCE_LOCATION (alias
),
1519 "resolver indirect function declared here");
1523 auto_diagnostic_group d
;
1524 if (warning_at (DECL_SOURCE_LOCATION (alias
),
1525 OPT_Wattribute_alias_
,
1526 "%qD alias between functions of incompatible "
1527 "types %qT and %qT", alias
, altype
, targtype
))
1528 inform (DECL_SOURCE_LOCATION (target
),
1529 "aliased declaration here");
1534 /* Translate the ugly representation of aliases as alias pairs into nice
1535 representation in callgraph. We don't handle all cases yet,
1539 handle_alias_pairs (void)
1544 for (i
= 0; alias_pairs
&& alias_pairs
->iterate (i
, &p
);)
1546 symtab_node
*target_node
= symtab_node::get_for_asmname (p
->target
);
1548 /* Weakrefs with target not defined in current unit are easy to handle:
1549 they behave just as external variables except we need to note the
1550 alias flag to later output the weakref pseudo op into asm file. */
1552 && lookup_attribute ("weakref", DECL_ATTRIBUTES (p
->decl
)) != NULL
)
1554 symtab_node
*node
= symtab_node::get (p
->decl
);
1557 node
->alias_target
= p
->target
;
1558 node
->weakref
= true;
1560 node
->transparent_alias
= true;
1562 alias_pairs
->unordered_remove (i
);
1565 else if (!target_node
)
1567 error ("%q+D aliased to undefined symbol %qE", p
->decl
, p
->target
);
1568 symtab_node
*node
= symtab_node::get (p
->decl
);
1570 node
->alias
= false;
1571 alias_pairs
->unordered_remove (i
);
1575 if (DECL_EXTERNAL (target_node
->decl
)
1576 /* We use local aliases for C++ thunks to force the tailcall
1577 to bind locally. This is a hack - to keep it working do
1578 the following (which is not strictly correct). */
1579 && (TREE_CODE (target_node
->decl
) != FUNCTION_DECL
1580 || ! DECL_VIRTUAL_P (target_node
->decl
))
1581 && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p
->decl
)))
1583 error ("%q+D aliased to external symbol %qE",
1584 p
->decl
, p
->target
);
1587 if (TREE_CODE (p
->decl
) == FUNCTION_DECL
1588 && target_node
&& is_a
<cgraph_node
*> (target_node
))
1590 maybe_diag_incompatible_alias (p
->decl
, target_node
->decl
);
1592 maybe_diag_alias_attributes (p
->decl
, target_node
->decl
);
1594 cgraph_node
*src_node
= cgraph_node::get (p
->decl
);
1595 if (src_node
&& src_node
->definition
)
1597 cgraph_node::create_alias (p
->decl
, target_node
->decl
);
1598 alias_pairs
->unordered_remove (i
);
1600 else if (VAR_P (p
->decl
)
1601 && target_node
&& is_a
<varpool_node
*> (target_node
))
1603 varpool_node::create_alias (p
->decl
, target_node
->decl
);
1604 alias_pairs
->unordered_remove (i
);
1608 error ("%q+D alias between function and variable is not supported",
1610 inform (DECL_SOURCE_LOCATION (target_node
->decl
),
1611 "aliased declaration here");
1613 alias_pairs
->unordered_remove (i
);
1616 vec_free (alias_pairs
);
1620 /* Figure out what functions we want to assemble. */
1623 mark_functions_to_output (void)
1625 bool check_same_comdat_groups
= false;
1629 FOR_EACH_FUNCTION (node
)
1630 gcc_assert (!node
->process
);
1632 FOR_EACH_FUNCTION (node
)
1634 tree decl
= node
->decl
;
1636 gcc_assert (!node
->process
|| node
->same_comdat_group
);
1640 /* We need to output all local functions that are used and not
1641 always inlined, as well as those that are reachable from
1642 outside the current compilation unit. */
1646 && !node
->inlined_to
1647 && !TREE_ASM_WRITTEN (decl
)
1648 && !DECL_EXTERNAL (decl
))
1651 if (node
->same_comdat_group
)
1654 for (next
= dyn_cast
<cgraph_node
*> (node
->same_comdat_group
);
1656 next
= dyn_cast
<cgraph_node
*> (next
->same_comdat_group
))
1657 if (!next
->thunk
&& !next
->alias
1658 && !next
->comdat_local_p ())
1662 else if (node
->same_comdat_group
)
1665 check_same_comdat_groups
= true;
1669 /* We should've reclaimed all functions that are not needed. */
1671 && !node
->inlined_to
1672 && gimple_has_body_p (decl
)
1673 /* FIXME: in ltrans unit when offline copy is outside partition but inline copies
1674 are inside partition, we can end up not removing the body since we no longer
1675 have analyzed node pointing to it. */
1676 && !node
->in_other_partition
1679 && !DECL_EXTERNAL (decl
))
1682 internal_error ("failed to reclaim unneeded function");
1684 gcc_assert (node
->inlined_to
1685 || !gimple_has_body_p (decl
)
1686 || node
->in_other_partition
1688 || DECL_ARTIFICIAL (decl
)
1689 || DECL_EXTERNAL (decl
));
1694 if (flag_checking
&& check_same_comdat_groups
)
1695 FOR_EACH_FUNCTION (node
)
1696 if (node
->same_comdat_group
&& !node
->process
)
1698 tree decl
= node
->decl
;
1699 if (!node
->inlined_to
1700 && gimple_has_body_p (decl
)
1701 /* FIXME: in an ltrans unit when the offline copy is outside a
1702 partition but inline copies are inside a partition, we can
1703 end up not removing the body since we no longer have an
1704 analyzed node pointing to it. */
1705 && !node
->in_other_partition
1707 && !DECL_EXTERNAL (decl
))
1710 internal_error ("failed to reclaim unneeded function in same "
1716 /* DECL is FUNCTION_DECL. Initialize datastructures so DECL is a function
1717 in lowered gimple form. IN_SSA is true if the gimple is in SSA.
1719 Set current_function_decl and cfun to newly constructed empty function body.
1720 return basic block in the function body. */
1723 init_lowered_empty_function (tree decl
, bool in_ssa
, profile_count count
)
1728 current_function_decl
= decl
;
1729 allocate_struct_function (decl
, false);
1730 gimple_register_cfg_hooks ();
1731 init_empty_tree_cfg ();
1732 init_tree_ssa (cfun
);
1736 init_ssa_operands (cfun
);
1737 cfun
->gimple_df
->in_ssa_p
= true;
1738 cfun
->curr_properties
|= PROP_ssa
;
1741 DECL_INITIAL (decl
) = make_node (BLOCK
);
1742 BLOCK_SUPERCONTEXT (DECL_INITIAL (decl
)) = decl
;
1744 DECL_SAVED_TREE (decl
) = error_mark_node
;
1745 cfun
->curr_properties
|= (PROP_gimple_lcf
| PROP_gimple_leh
| PROP_gimple_any
1746 | PROP_cfg
| PROP_loops
);
1748 set_loops_for_fn (cfun
, ggc_cleared_alloc
<loops
> ());
1749 init_loops_structure (cfun
, loops_for_fn (cfun
), 1);
1750 loops_for_fn (cfun
)->state
|= LOOPS_MAY_HAVE_MULTIPLE_LATCHES
;
1752 /* Create BB for body of the function and connect it properly. */
1753 ENTRY_BLOCK_PTR_FOR_FN (cfun
)->count
= count
;
1754 EXIT_BLOCK_PTR_FOR_FN (cfun
)->count
= count
;
1755 bb
= create_basic_block (NULL
, ENTRY_BLOCK_PTR_FOR_FN (cfun
));
1757 e
= make_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun
), bb
, EDGE_FALLTHRU
);
1758 e
->probability
= profile_probability::always ();
1759 e
= make_edge (bb
, EXIT_BLOCK_PTR_FOR_FN (cfun
), 0);
1760 e
->probability
= profile_probability::always ();
1761 add_bb_to_loop (bb
, ENTRY_BLOCK_PTR_FOR_FN (cfun
)->loop_father
);
1766 /* Assemble thunks and aliases associated to node. */
1769 cgraph_node::assemble_thunks_and_aliases (void)
1774 for (e
= callers
; e
;)
1775 if (e
->caller
->thunk
1776 && !e
->caller
->inlined_to
)
1778 cgraph_node
*thunk
= e
->caller
;
1781 expand_thunk (thunk
, !rtl_dump_and_exit
, false);
1782 thunk
->assemble_thunks_and_aliases ();
1787 FOR_EACH_ALIAS (this, ref
)
1789 cgraph_node
*alias
= dyn_cast
<cgraph_node
*> (ref
->referring
);
1790 if (!alias
->transparent_alias
)
1792 bool saved_written
= TREE_ASM_WRITTEN (decl
);
1794 /* Force assemble_alias to really output the alias this time instead
1795 of buffering it in same alias pairs. */
1796 TREE_ASM_WRITTEN (decl
) = 1;
1798 do_assemble_symver (alias
->decl
,
1799 DECL_ASSEMBLER_NAME (decl
));
1801 do_assemble_alias (alias
->decl
,
1802 DECL_ASSEMBLER_NAME (decl
));
1803 alias
->assemble_thunks_and_aliases ();
1804 TREE_ASM_WRITTEN (decl
) = saved_written
;
1809 /* Expand function specified by node. */
1812 cgraph_node::expand (void)
1814 location_t saved_loc
;
1816 /* We ought to not compile any inline clones. */
1817 gcc_assert (!inlined_to
);
1819 /* __RTL functions are compiled as soon as they are parsed, so don't
1821 if (native_rtl_p ())
1824 announce_function (decl
);
1826 gcc_assert (lowered
);
1828 /* Initialize the default bitmap obstack. */
1829 bitmap_obstack_initialize (NULL
);
1830 get_untransformed_body ();
1832 /* Generate RTL for the body of DECL. */
1834 timevar_push (TV_REST_OF_COMPILATION
);
1836 gcc_assert (symtab
->global_info_ready
);
1838 /* Initialize the RTL code for the function. */
1839 saved_loc
= input_location
;
1840 input_location
= DECL_SOURCE_LOCATION (decl
);
1842 gcc_assert (DECL_STRUCT_FUNCTION (decl
));
1843 push_cfun (DECL_STRUCT_FUNCTION (decl
));
1844 init_function_start (decl
);
1846 gimple_register_cfg_hooks ();
1848 bitmap_obstack_initialize (®_obstack
); /* FIXME, only at RTL generation*/
1850 update_ssa (TODO_update_ssa_only_virtuals
);
1851 if (ipa_transforms_to_apply
.exists ())
1852 execute_all_ipa_transforms (false);
1854 /* Perform all tree transforms and optimizations. */
1856 /* Signal the start of passes. */
1857 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START
, NULL
);
1859 execute_pass_list (cfun
, g
->get_passes ()->all_passes
);
1861 /* Signal the end of passes. */
1862 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END
, NULL
);
1864 bitmap_obstack_release (®_obstack
);
1866 /* Release the default bitmap obstack. */
1867 bitmap_obstack_release (NULL
);
1869 /* If requested, warn about function definitions where the function will
1870 return a value (usually of some struct or union type) which itself will
1871 take up a lot of stack space. */
1872 if (!DECL_EXTERNAL (decl
) && TREE_TYPE (decl
))
1874 tree ret_type
= TREE_TYPE (TREE_TYPE (decl
));
1876 if (ret_type
&& TYPE_SIZE_UNIT (ret_type
)
1877 && TREE_CODE (TYPE_SIZE_UNIT (ret_type
)) == INTEGER_CST
1878 && compare_tree_int (TYPE_SIZE_UNIT (ret_type
),
1879 warn_larger_than_size
) > 0)
1881 unsigned int size_as_int
1882 = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type
));
1884 if (compare_tree_int (TYPE_SIZE_UNIT (ret_type
), size_as_int
) == 0)
1885 warning (OPT_Wlarger_than_
,
1886 "size of return value of %q+D is %u bytes",
1889 warning (OPT_Wlarger_than_
,
1890 "size of return value of %q+D is larger than %wu bytes",
1891 decl
, warn_larger_than_size
);
1895 gimple_set_body (decl
, NULL
);
1896 if (DECL_STRUCT_FUNCTION (decl
) == 0)
1898 /* Stop pointing to the local nodes about to be freed.
1899 But DECL_INITIAL must remain nonzero so we know this
1900 was an actual function definition. */
1901 if (DECL_INITIAL (decl
) != 0)
1902 DECL_INITIAL (decl
) = error_mark_node
;
1905 input_location
= saved_loc
;
1908 timevar_pop (TV_REST_OF_COMPILATION
);
1910 if (DECL_STRUCT_FUNCTION (decl
)
1911 && DECL_STRUCT_FUNCTION (decl
)->assume_function
)
1913 /* Assume functions aren't expanded into RTL, on the other side
1914 we don't want to release their body. */
1920 /* Make sure that BE didn't give up on compiling. */
1921 gcc_assert (TREE_ASM_WRITTEN (decl
));
1925 /* It would make a lot more sense to output thunks before function body to
1926 get more forward and fewer backward jumps. This however would need
1927 solving problem with comdats. See PR48668. Also aliases must come after
1928 function itself to make one pass assemblers, like one on AIX, happy.
1930 FIXME: Perhaps thunks should be move before function IFF they are not in
1932 assemble_thunks_and_aliases ();
1936 /* Node comparator that is responsible for the order that corresponds
1937 to time when a function was launched for the first time. */
1940 tp_first_run_node_cmp (const void *pa
, const void *pb
)
1942 const cgraph_node
*a
= *(const cgraph_node
* const *) pa
;
1943 const cgraph_node
*b
= *(const cgraph_node
* const *) pb
;
1944 unsigned int tp_first_run_a
= a
->tp_first_run
;
1945 unsigned int tp_first_run_b
= b
->tp_first_run
;
1947 if (!opt_for_fn (a
->decl
, flag_profile_reorder_functions
)
1950 if (!opt_for_fn (b
->decl
, flag_profile_reorder_functions
)
1954 if (tp_first_run_a
== tp_first_run_b
)
1955 return a
->order
- b
->order
;
1957 /* Functions with time profile must be before these without profile. */
1958 tp_first_run_a
= (tp_first_run_a
- 1) & INT_MAX
;
1959 tp_first_run_b
= (tp_first_run_b
- 1) & INT_MAX
;
1961 return tp_first_run_a
- tp_first_run_b
;
1964 /* Expand all functions that must be output.
1966 Attempt to topologically sort the nodes so function is output when
1967 all called functions are already assembled to allow data to be
1968 propagated across the callgraph. Use a stack to get smaller distance
1969 between a function and its callees (later we may choose to use a more
1970 sophisticated algorithm for function reordering; we will likely want
1971 to use subsections to make the output functions appear in top-down
1975 expand_all_functions (void)
1978 cgraph_node
**order
= XCNEWVEC (cgraph_node
*,
1979 symtab
->cgraph_count
);
1980 cgraph_node
**tp_first_run_order
= XCNEWVEC (cgraph_node
*,
1981 symtab
->cgraph_count
);
1982 unsigned int expanded_func_count
= 0, profiled_func_count
= 0;
1983 int order_pos
, tp_first_run_order_pos
= 0, new_order_pos
= 0;
1986 order_pos
= ipa_reverse_postorder (order
);
1987 gcc_assert (order_pos
== symtab
->cgraph_count
);
1989 /* Garbage collector may remove inline clones we eliminate during
1990 optimization. So we must be sure to not reference them. */
1991 for (i
= 0; i
< order_pos
; i
++)
1992 if (order
[i
]->process
)
1994 if (order
[i
]->tp_first_run
1995 && opt_for_fn (order
[i
]->decl
, flag_profile_reorder_functions
))
1996 tp_first_run_order
[tp_first_run_order_pos
++] = order
[i
];
1998 order
[new_order_pos
++] = order
[i
];
2001 /* First output functions with time profile in specified order. */
2002 qsort (tp_first_run_order
, tp_first_run_order_pos
,
2003 sizeof (cgraph_node
*), tp_first_run_node_cmp
);
2004 for (i
= 0; i
< tp_first_run_order_pos
; i
++)
2006 node
= tp_first_run_order
[i
];
2010 expanded_func_count
++;
2011 profiled_func_count
++;
2013 if (symtab
->dump_file
)
2014 fprintf (symtab
->dump_file
,
2015 "Time profile order in expand_all_functions:%s:%d\n",
2016 node
->dump_asm_name (), node
->tp_first_run
);
2022 /* Output functions in RPO so callees get optimized before callers. This
2023 makes ipa-ra and other propagators to work.
2024 FIXME: This is far from optimal code layout.
2025 Make multiple passes over the list to defer processing of gc
2026 candidates until all potential uses are seen. */
2027 int gc_candidates
= 0;
2028 int prev_gc_candidates
= 0;
2032 for (i
= new_order_pos
- 1; i
>= 0; i
--)
2036 if (node
->gc_candidate
)
2038 else if (node
->process
)
2040 expanded_func_count
++;
2045 if (!gc_candidates
|| gc_candidates
== prev_gc_candidates
)
2047 prev_gc_candidates
= gc_candidates
;
2051 /* Free any unused gc_candidate functions. */
2053 for (i
= new_order_pos
- 1; i
>= 0; i
--)
2056 if (node
->gc_candidate
)
2058 struct function
*fn
= DECL_STRUCT_FUNCTION (node
->decl
);
2059 if (symtab
->dump_file
)
2060 fprintf (symtab
->dump_file
,
2061 "Deleting unused function %s\n",
2062 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node
->decl
)));
2063 node
->process
= false;
2064 free_dominance_info (fn
, CDI_DOMINATORS
);
2065 free_dominance_info (fn
, CDI_POST_DOMINATORS
);
2066 node
->release_body (false);
2071 fprintf (dump_file
, "Expanded functions with time profile (%s):%u/%u\n",
2072 main_input_filename
, profiled_func_count
, expanded_func_count
);
2074 if (symtab
->dump_file
&& tp_first_run_order_pos
)
2075 fprintf (symtab
->dump_file
, "Expanded functions with time profile:%u/%u\n",
2076 profiled_func_count
, expanded_func_count
);
2078 symtab
->process_new_functions ();
2079 free_gimplify_stack ();
2080 delete ipa_saved_clone_sources
;
2081 ipa_saved_clone_sources
= NULL
;
2083 free (tp_first_run_order
);
2086 /* This is used to sort the node types by the cgraph order number. */
2088 enum cgraph_order_sort_kind
2096 struct cgraph_order_sort
2098 /* Construct from a cgraph_node. */
2099 cgraph_order_sort (cgraph_node
*node
)
2100 : kind (ORDER_FUNCTION
), order (node
->order
)
2105 /* Construct from a varpool_node. */
2106 cgraph_order_sort (varpool_node
*node
)
2107 : kind (node
->definition
? ORDER_VAR
: ORDER_VAR_UNDEF
), order (node
->order
)
2112 /* Construct from a asm_node. */
2113 cgraph_order_sort (asm_node
*node
)
2114 : kind (ORDER_ASM
), order (node
->order
)
2119 /* Assembly cgraph_order_sort based on its type. */
2122 enum cgraph_order_sort_kind kind
;
2132 /* Assembly cgraph_order_sort based on its type. */
2135 cgraph_order_sort::process ()
2139 case ORDER_FUNCTION
:
2144 u
.v
->assemble_decl ();
2146 case ORDER_VAR_UNDEF
:
2147 assemble_undefined_decl (u
.v
->decl
);
2150 assemble_asm (u
.a
->asm_str
);
2157 /* Compare cgraph_order_sort by order. */
2160 cgraph_order_cmp (const void *a_p
, const void *b_p
)
2162 const cgraph_order_sort
*nodea
= (const cgraph_order_sort
*)a_p
;
2163 const cgraph_order_sort
*nodeb
= (const cgraph_order_sort
*)b_p
;
2165 return nodea
->order
- nodeb
->order
;
2168 /* Output all functions, variables, and asm statements in the order
2169 according to their order fields, which is the order in which they
2170 appeared in the file. This implements -fno-toplevel-reorder. In
2171 this mode we may output functions and variables which don't really
2172 need to be output. */
2175 output_in_order (void)
2179 varpool_node
*vnode
;
2181 auto_vec
<cgraph_order_sort
> nodes
;
2182 cgraph_order_sort
*node
;
2184 FOR_EACH_DEFINED_FUNCTION (cnode
)
2185 if (cnode
->process
&& !cnode
->thunk
2186 && !cnode
->alias
&& cnode
->no_reorder
)
2187 nodes
.safe_push (cgraph_order_sort (cnode
));
2189 /* There is a similar loop in symbol_table::output_variables.
2190 Please keep them in sync. */
2191 FOR_EACH_VARIABLE (vnode
)
2192 if (vnode
->no_reorder
2193 && !DECL_HARD_REGISTER (vnode
->decl
)
2194 && !DECL_HAS_VALUE_EXPR_P (vnode
->decl
))
2195 nodes
.safe_push (cgraph_order_sort (vnode
));
2197 for (anode
= symtab
->first_asm_symbol (); anode
; anode
= anode
->next
)
2198 nodes
.safe_push (cgraph_order_sort (anode
));
2200 /* Sort nodes by order. */
2201 nodes
.qsort (cgraph_order_cmp
);
2203 /* In toplevel reorder mode we output all statics; mark them as needed. */
2204 FOR_EACH_VEC_ELT (nodes
, i
, node
)
2205 if (node
->kind
== ORDER_VAR
)
2206 node
->u
.v
->finalize_named_section_flags ();
2208 FOR_EACH_VEC_ELT (nodes
, i
, node
)
2211 symtab
->clear_asm_symbols ();
2217 gcc::pass_manager
*passes
= g
->get_passes ();
2220 current_function_decl
= NULL
;
2221 gimple_register_cfg_hooks ();
2222 bitmap_obstack_initialize (NULL
);
2224 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START
, NULL
);
2228 execute_ipa_pass_list (passes
->all_small_ipa_passes
);
2233 /* This extra symtab_remove_unreachable_nodes pass tends to catch some
2234 devirtualization and other changes where removal iterate. */
2235 symtab
->remove_unreachable_nodes (symtab
->dump_file
);
2237 /* If pass_all_early_optimizations was not scheduled, the state of
2238 the cgraph will not be properly updated. Update it now. */
2239 if (symtab
->state
< IPA_SSA
)
2240 symtab
->state
= IPA_SSA
;
2244 /* Generate coverage variables and constructors. */
2247 /* Process new functions added. */
2249 current_function_decl
= NULL
;
2250 symtab
->process_new_functions ();
2252 execute_ipa_summary_passes
2253 ((ipa_opt_pass_d
*) passes
->all_regular_ipa_passes
);
2256 /* Some targets need to handle LTO assembler output specially. */
2257 if (flag_generate_lto
|| flag_generate_offload
)
2258 targetm
.asm_out
.lto_start ();
2261 || flag_incremental_link
== INCREMENTAL_LINK_LTO
)
2264 fprintf (stderr
, "Streaming LTO\n");
2265 if (g
->have_offload
)
2267 section_name_prefix
= OFFLOAD_SECTION_NAME_PREFIX
;
2268 lto_stream_offload_p
= true;
2269 ipa_write_summaries ();
2270 lto_stream_offload_p
= false;
2274 section_name_prefix
= LTO_SECTION_NAME_PREFIX
;
2275 lto_stream_offload_p
= false;
2276 ipa_write_summaries ();
2280 if (flag_generate_lto
|| flag_generate_offload
)
2281 targetm
.asm_out
.lto_end ();
2284 && ((in_lto_p
&& flag_incremental_link
!= INCREMENTAL_LINK_LTO
)
2285 || !flag_lto
|| flag_fat_lto_objects
))
2286 execute_ipa_pass_list (passes
->all_regular_ipa_passes
);
2287 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END
, NULL
);
2289 bitmap_obstack_release (NULL
);
2293 /* Weakrefs may be associated to external decls and thus not output
2294 at expansion time. Emit all necessary aliases. */
2297 symbol_table::output_weakrefs (void)
2300 FOR_EACH_SYMBOL (node
)
2302 && !TREE_ASM_WRITTEN (node
->decl
)
2307 /* Weakrefs are special by not requiring target definition in current
2308 compilation unit. It is thus bit hard to work out what we want to
2310 When alias target is defined, we need to fetch it from symtab reference,
2311 otherwise it is pointed to by alias_target. */
2312 if (node
->alias_target
)
2313 target
= (DECL_P (node
->alias_target
)
2314 ? DECL_ASSEMBLER_NAME (node
->alias_target
)
2315 : node
->alias_target
);
2316 else if (node
->analyzed
)
2317 target
= DECL_ASSEMBLER_NAME (node
->get_alias_target ()->decl
);
2320 do_assemble_alias (node
->decl
, target
);
2324 /* Perform simple optimizations based on callgraph. */
2327 symbol_table::compile (void)
2332 symtab_node::checking_verify_symtab_nodes ();
2334 symtab_node::check_ifunc_callee_symtab_nodes ();
2336 timevar_push (TV_CGRAPHOPT
);
2337 if (pre_ipa_mem_report
)
2338 dump_memory_report ("Memory consumption before IPA");
2340 fprintf (stderr
, "Performing interprocedural optimizations\n");
2343 /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE. */
2344 if (flag_generate_lto
|| flag_generate_offload
)
2345 lto_streamer_hooks_init ();
2347 /* Don't run the IPA passes if there was any error or sorry messages. */
2350 timevar_start (TV_CGRAPH_IPA_PASSES
);
2352 timevar_stop (TV_CGRAPH_IPA_PASSES
);
2354 /* Do nothing else if any IPA pass found errors or if we are just streaming LTO. */
2356 || ((!in_lto_p
|| flag_incremental_link
== INCREMENTAL_LINK_LTO
)
2357 && flag_lto
&& !flag_fat_lto_objects
))
2359 timevar_pop (TV_CGRAPHOPT
);
2363 global_info_ready
= true;
2366 fprintf (dump_file
, "Optimized ");
2367 symtab
->dump (dump_file
);
2369 if (post_ipa_mem_report
)
2370 dump_memory_report ("Memory consumption after IPA");
2371 timevar_pop (TV_CGRAPHOPT
);
2373 /* Output everything. */
2374 switch_to_section (text_section
);
2375 (*debug_hooks
->assembly_start
) ();
2377 fprintf (stderr
, "Assembling functions:\n");
2378 symtab_node::checking_verify_symtab_nodes ();
2380 bitmap_obstack_initialize (NULL
);
2381 execute_ipa_pass_list (g
->get_passes ()->all_late_ipa_passes
);
2382 bitmap_obstack_release (NULL
);
2383 mark_functions_to_output ();
2385 /* When weakref support is missing, we automatically translate all
2386 references to NODE to references to its ultimate alias target.
2387 The renaming mechanism uses flag IDENTIFIER_TRANSPARENT_ALIAS and
2390 Set up this mapping before we output any assembler but once we are sure
2391 that all symbol renaming is done.
2393 FIXME: All this ugliness can go away if we just do renaming at gimple
2394 level by physically rewriting the IL. At the moment we can only redirect
2395 calls, so we need infrastructure for renaming references as well. */
2396 #ifndef ASM_OUTPUT_WEAKREF
2399 FOR_EACH_SYMBOL (node
)
2401 && lookup_attribute ("weakref", DECL_ATTRIBUTES (node
->decl
)))
2403 IDENTIFIER_TRANSPARENT_ALIAS
2404 (DECL_ASSEMBLER_NAME (node
->decl
)) = 1;
2405 TREE_CHAIN (DECL_ASSEMBLER_NAME (node
->decl
))
2406 = (node
->alias_target
? node
->alias_target
2407 : DECL_ASSEMBLER_NAME (node
->get_alias_target ()->decl
));
2413 /* Output first asm statements and anything ordered. The process
2414 flag is cleared for these nodes, so we skip them later. */
2417 timevar_start (TV_CGRAPH_FUNC_EXPANSION
);
2418 expand_all_functions ();
2419 timevar_stop (TV_CGRAPH_FUNC_EXPANSION
);
2421 output_variables ();
2423 process_new_functions ();
2429 fprintf (dump_file
, "\nFinal ");
2430 symtab
->dump (dump_file
);
2434 symtab_node::verify_symtab_nodes ();
2435 /* Double check that all inline clones are gone and that all
2436 function bodies have been released from memory. */
2440 bool error_found
= false;
2442 FOR_EACH_DEFINED_FUNCTION (node
)
2443 if (node
->inlined_to
2444 || gimple_has_body_p (node
->decl
))
2446 if (DECL_STRUCT_FUNCTION (node
->decl
)
2447 && (DECL_STRUCT_FUNCTION (node
->decl
)->curr_properties
2448 & PROP_assumptions_done
) != 0)
2454 internal_error ("nodes with unreleased memory found");
2458 /* Earlydebug dump file, flags, and number. */
2460 static int debuginfo_early_dump_nr
;
2461 static FILE *debuginfo_early_dump_file
;
2462 static dump_flags_t debuginfo_early_dump_flags
;
2464 /* Debug dump file, flags, and number. */
2466 static int debuginfo_dump_nr
;
2467 static FILE *debuginfo_dump_file
;
2468 static dump_flags_t debuginfo_dump_flags
;
2470 /* Register the debug and earlydebug dump files. */
2473 debuginfo_early_init (void)
2475 gcc::dump_manager
*dumps
= g
->get_dumps ();
2476 debuginfo_early_dump_nr
= dumps
->dump_register (".earlydebug", "earlydebug",
2477 "earlydebug", DK_tree
,
2480 debuginfo_dump_nr
= dumps
->dump_register (".debug", "debug",
2486 /* Initialize the debug and earlydebug dump files. */
2489 debuginfo_init (void)
2491 gcc::dump_manager
*dumps
= g
->get_dumps ();
2492 debuginfo_dump_file
= dump_begin (debuginfo_dump_nr
, NULL
);
2493 debuginfo_dump_flags
= dumps
->get_dump_file_info (debuginfo_dump_nr
)->pflags
;
2494 debuginfo_early_dump_file
= dump_begin (debuginfo_early_dump_nr
, NULL
);
2495 debuginfo_early_dump_flags
2496 = dumps
->get_dump_file_info (debuginfo_early_dump_nr
)->pflags
;
2499 /* Finalize the debug and earlydebug dump files. */
2502 debuginfo_fini (void)
2504 if (debuginfo_dump_file
)
2505 dump_end (debuginfo_dump_nr
, debuginfo_dump_file
);
2506 if (debuginfo_early_dump_file
)
2507 dump_end (debuginfo_early_dump_nr
, debuginfo_early_dump_file
);
2510 /* Set dump_file to the debug dump file. */
2513 debuginfo_start (void)
2515 set_dump_file (debuginfo_dump_file
);
2518 /* Undo setting dump_file to the debug dump file. */
2521 debuginfo_stop (void)
2523 set_dump_file (NULL
);
2526 /* Set dump_file to the earlydebug dump file. */
2529 debuginfo_early_start (void)
2531 set_dump_file (debuginfo_early_dump_file
);
2534 /* Undo setting dump_file to the earlydebug dump file. */
2537 debuginfo_early_stop (void)
2539 set_dump_file (NULL
);
2542 /* Analyze the whole compilation unit once it is parsed completely. */
2545 symbol_table::finalize_compilation_unit (void)
2547 timevar_push (TV_CGRAPH
);
2549 /* If we're here there's no current function anymore. Some frontends
2550 are lazy in clearing these. */
2551 current_function_decl
= NULL
;
2554 /* Do not skip analyzing the functions if there were errors, we
2555 miss diagnostics for following functions otherwise. */
2557 /* Emit size functions we didn't inline. */
2558 finalize_size_functions ();
2560 /* Mark alias targets necessary and emit diagnostics. */
2561 handle_alias_pairs ();
2565 fprintf (stderr
, "\nAnalyzing compilation unit\n");
2569 if (flag_dump_passes
)
2572 /* Gimplify and lower all functions, compute reachability and
2573 remove unreachable nodes. */
2574 analyze_functions (/*first_time=*/true);
2576 /* Mark alias targets necessary and emit diagnostics. */
2577 handle_alias_pairs ();
2579 /* Gimplify and lower thunks. */
2580 analyze_functions (/*first_time=*/false);
2582 /* All nested functions should be lowered now. */
2583 nested_function_info::release ();
2585 /* Offloading requires LTO infrastructure. */
2586 if (!in_lto_p
&& g
->have_offload
)
2587 flag_generate_offload
= 1;
2591 /* Give the frontends the chance to emit early debug based on
2592 what is still reachable in the TU. */
2593 (*lang_hooks
.finalize_early_debug
) ();
2595 /* Clean up anything that needs cleaning up after initial debug
2597 debuginfo_early_start ();
2598 (*debug_hooks
->early_finish
) (main_input_filename
);
2599 debuginfo_early_stop ();
2602 /* Finally drive the pass manager. */
2605 timevar_pop (TV_CGRAPH
);
2608 /* Reset all state within cgraphunit.cc so that we can rerun the compiler
2609 within the same process. For use by toplev::finalize. */
2612 cgraphunit_cc_finalize (void)
2614 gcc_assert (cgraph_new_nodes
.length () == 0);
2615 cgraph_new_nodes
.truncate (0);
2617 queued_nodes
= &symtab_terminator
;
2619 first_analyzed
= NULL
;
2620 first_analyzed_var
= NULL
;
2623 /* Creates a wrapper from cgraph_node to TARGET node. Thunk is used for this
2624 kind of wrapper method. */
2627 cgraph_node::create_wrapper (cgraph_node
*target
)
2629 /* Preserve DECL_RESULT so we get right by reference flag. */
2630 tree decl_result
= DECL_RESULT (decl
);
2632 /* Remove the function's body but keep arguments to be reused
2634 release_body (true);
2637 DECL_UNINLINABLE (decl
) = false;
2638 DECL_RESULT (decl
) = decl_result
;
2639 DECL_INITIAL (decl
) = NULL
;
2640 allocate_struct_function (decl
, false);
2643 /* Turn alias into thunk and expand it into GIMPLE representation. */
2645 semantic_interposition
= opt_for_fn (decl
, flag_semantic_interposition
);
2647 /* Create empty thunk, but be sure we did not keep former thunk around.
2648 In that case we would need to preserve the info. */
2649 gcc_checking_assert (!thunk_info::get (this));
2650 thunk_info::get_create (this);
2652 create_edge (target
, NULL
, count
);
2653 callees
->can_throw_external
= !TREE_NOTHROW (target
->decl
);
2655 tree arguments
= DECL_ARGUMENTS (decl
);
2659 TREE_ADDRESSABLE (arguments
) = false;
2660 arguments
= TREE_CHAIN (arguments
);
2663 expand_thunk (this, false, true);
2664 thunk_info::remove (this);
2666 /* Inline summary set-up. */
2668 inline_analyze_function (this);