1 /* Driver of optimization process
2 Copyright (C) 2003-2013 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:
28 - cgraph_finalize_function
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 optimiations 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 exmaple, transational 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 sreaming. 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 multple 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 functoins (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"
167 #include "tree-flow.h"
168 #include "tree-inline.h"
169 #include "langhooks.h"
170 #include "pointer-set.h"
177 #include "diagnostic.h"
181 #include "function.h"
182 #include "ipa-prop.h"
185 #include "tree-iterator.h"
186 #include "tree-pass.h"
187 #include "tree-dump.h"
188 #include "gimple-pretty-print.h"
190 #include "coverage.h"
192 #include "ipa-inline.h"
193 #include "ipa-utils.h"
194 #include "lto-streamer.h"
197 #include "regset.h" /* FIXME: For reg_obstack. */
199 /* Queue of cgraph nodes scheduled to be added into cgraph. This is a
200 secondary queue used during optimization to accommodate passes that
201 may generate new functions that need to be optimized and expanded. */
202 cgraph_node_set cgraph_new_nodes
;
204 static void expand_all_functions (void);
205 static void mark_functions_to_output (void);
206 static void expand_function (struct cgraph_node
*);
207 static void cgraph_analyze_function (struct cgraph_node
*);
208 static void handle_alias_pairs (void);
210 FILE *cgraph_dump_file
;
212 /* Linked list of cgraph asm nodes. */
213 struct asm_node
*asm_nodes
;
215 /* Last node in cgraph_asm_nodes. */
216 static GTY(()) struct asm_node
*asm_last_node
;
218 /* Used for vtable lookup in thunk adjusting. */
219 static GTY (()) tree vtable_entry_type
;
221 /* Determine if function DECL is trivially needed and should stay in the
222 compilation unit. This is used at the symbol table construction time
223 and differs from later logic removing unnecessary functions that can
224 take into account results of analysis, whole program info etc. */
227 cgraph_decide_is_function_needed (struct cgraph_node
*node
, tree decl
)
229 /* If the user told us it is used, then it must be so. */
230 if (node
->symbol
.force_output
)
233 /* Double check that no one output the function into assembly file
235 gcc_checking_assert (!DECL_ASSEMBLER_NAME_SET_P (decl
)
236 || (node
->thunk
.thunk_p
|| node
->same_body_alias
)
237 || !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl
)));
240 /* Keep constructors, destructors and virtual functions. */
241 if (DECL_STATIC_CONSTRUCTOR (decl
)
242 || DECL_STATIC_DESTRUCTOR (decl
)
243 || (DECL_VIRTUAL_P (decl
)
244 && optimize
&& (DECL_COMDAT (decl
) || DECL_EXTERNAL (decl
))))
247 /* Externally visible functions must be output. The exception is
248 COMDAT functions that must be output only when they are needed. */
250 if (TREE_PUBLIC (decl
)
251 && !DECL_COMDAT (decl
) && !DECL_EXTERNAL (decl
))
257 /* Head of the queue of nodes to be processed while building callgraph */
259 static symtab_node first
= (symtab_node
)(void *)1;
261 /* Add NODE to queue starting at FIRST.
262 The queue is linked via AUX pointers and terminated by pointer to 1. */
265 enqueue_node (symtab_node node
)
267 if (node
->symbol
.aux
)
269 gcc_checking_assert (first
);
270 node
->symbol
.aux
= first
;
275 cgraph_enqueue_node (struct cgraph_node
*node
)
277 enqueue_node ((symtab_node
) node
);
280 /* Process CGRAPH_NEW_FUNCTIONS and perform actions necessary to add these
281 functions into callgraph in a way so they look like ordinary reachable
282 functions inserted into callgraph already at construction time. */
285 cgraph_process_new_functions (void)
289 struct cgraph_node
*node
;
290 cgraph_node_set_iterator csi
;
292 if (!cgraph_new_nodes
)
294 handle_alias_pairs ();
295 /* Note that this queue may grow as its being processed, as the new
296 functions may generate new ones. */
297 for (csi
= csi_start (cgraph_new_nodes
); !csi_end_p (csi
); csi_next (&csi
))
299 node
= csi_node (csi
);
300 fndecl
= node
->symbol
.decl
;
301 switch (cgraph_state
)
303 case CGRAPH_STATE_CONSTRUCTION
:
304 /* At construction time we just need to finalize function and move
305 it into reachable functions list. */
307 cgraph_finalize_function (fndecl
, false);
309 cgraph_call_function_insertion_hooks (node
);
310 enqueue_node ((symtab_node
) node
);
313 case CGRAPH_STATE_IPA
:
314 case CGRAPH_STATE_IPA_SSA
:
315 /* When IPA optimization already started, do all essential
316 transformations that has been already performed on the whole
317 cgraph but not on this function. */
319 gimple_register_cfg_hooks ();
321 cgraph_analyze_function (node
);
322 push_cfun (DECL_STRUCT_FUNCTION (fndecl
));
323 if ((cgraph_state
== CGRAPH_STATE_IPA_SSA
324 && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl
)))
325 /* When not optimizing, be sure we run early local passes anyway
328 execute_pass_list (pass_early_local_passes
.pass
.sub
);
330 compute_inline_parameters (node
, true);
331 free_dominance_info (CDI_POST_DOMINATORS
);
332 free_dominance_info (CDI_DOMINATORS
);
334 cgraph_call_function_insertion_hooks (node
);
337 case CGRAPH_STATE_EXPANSION
:
338 /* Functions created during expansion shall be compiled
341 cgraph_call_function_insertion_hooks (node
);
342 expand_function (node
);
350 free_cgraph_node_set (cgraph_new_nodes
);
351 cgraph_new_nodes
= NULL
;
355 /* As an GCC extension we allow redefinition of the function. The
356 semantics when both copies of bodies differ is not well defined.
357 We replace the old body with new body so in unit at a time mode
358 we always use new body, while in normal mode we may end up with
359 old body inlined into some functions and new body expanded and
362 ??? It may make more sense to use one body for inlining and other
363 body for expanding the function but this is difficult to do. */
366 cgraph_reset_node (struct cgraph_node
*node
)
368 /* If node->process is set, then we have already begun whole-unit analysis.
369 This is *not* testing for whether we've already emitted the function.
370 That case can be sort-of legitimately seen with real function redefinition
371 errors. I would argue that the front end should never present us with
372 such a case, but don't enforce that for now. */
373 gcc_assert (!node
->process
);
375 /* Reset our data structures so we can analyze the function again. */
376 memset (&node
->local
, 0, sizeof (node
->local
));
377 memset (&node
->global
, 0, sizeof (node
->global
));
378 memset (&node
->rtl
, 0, sizeof (node
->rtl
));
379 node
->analyzed
= false;
380 node
->local
.finalized
= false;
382 cgraph_node_remove_callees (node
);
385 /* Return true when there are references to NODE. */
388 referred_to_p (symtab_node node
)
392 /* See if there are any references at all. */
393 if (ipa_ref_list_referring_iterate (&node
->symbol
.ref_list
, 0, ref
))
395 /* For functions check also calls. */
396 cgraph_node
*cn
= dyn_cast
<cgraph_node
> (node
);
397 if (cn
&& cn
->callers
)
402 /* DECL has been parsed. Take it, queue it, compile it at the whim of the
403 logic in effect. If NESTED is true, then our caller cannot stand to have
404 the garbage collector run at the moment. We would need to either create
405 a new GC context, or just not compile right now. */
408 cgraph_finalize_function (tree decl
, bool nested
)
410 struct cgraph_node
*node
= cgraph_get_create_node (decl
);
412 if (node
->local
.finalized
)
414 cgraph_reset_node (node
);
415 node
->local
.redefined_extern_inline
= true;
418 notice_global_symbol (decl
);
419 node
->local
.finalized
= true;
420 node
->lowered
= DECL_STRUCT_FUNCTION (decl
)->cfg
!= NULL
;
422 /* With -fkeep-inline-functions we are keeping all inline functions except
423 for extern inline ones. */
424 if (flag_keep_inline_functions
425 && DECL_DECLARED_INLINE_P (decl
)
426 && !DECL_EXTERNAL (decl
)
427 && !DECL_DISREGARD_INLINE_LIMITS (decl
))
428 node
->symbol
.force_output
= 1;
430 /* When not optimizing, also output the static functions. (see
431 PR24561), but don't do so for always_inline functions, functions
432 declared inline and nested functions. These were optimized out
433 in the original implementation and it is unclear whether we want
434 to change the behavior here. */
436 && !node
->same_body_alias
437 && !DECL_DISREGARD_INLINE_LIMITS (decl
)
438 && !DECL_DECLARED_INLINE_P (decl
)
439 && !(DECL_CONTEXT (decl
)
440 && TREE_CODE (DECL_CONTEXT (decl
)) == FUNCTION_DECL
))
441 && !DECL_COMDAT (decl
) && !DECL_EXTERNAL (decl
))
442 node
->symbol
.force_output
= 1;
444 /* If we've not yet emitted decl, tell the debug info about it. */
445 if (!TREE_ASM_WRITTEN (decl
))
446 (*debug_hooks
->deferred_inline_function
) (decl
);
448 /* Possibly warn about unused parameters. */
449 if (warn_unused_parameter
)
450 do_warn_unused_parameter (decl
);
455 if (cgraph_state
== CGRAPH_STATE_CONSTRUCTION
456 && (cgraph_decide_is_function_needed (node
, decl
)
457 || referred_to_p ((symtab_node
)node
)))
458 enqueue_node ((symtab_node
)node
);
461 /* Add the function FNDECL to the call graph.
462 Unlike cgraph_finalize_function, this function is intended to be used
463 by middle end and allows insertion of new function at arbitrary point
464 of compilation. The function can be either in high, low or SSA form
467 The function is assumed to be reachable and have address taken (so no
468 API breaking optimizations are performed on it).
470 Main work done by this function is to enqueue the function for later
471 processing to avoid need the passes to be re-entrant. */
474 cgraph_add_new_function (tree fndecl
, bool lowered
)
476 struct cgraph_node
*node
;
478 switch (cgraph_state
)
480 case CGRAPH_STATE_PARSING
:
481 cgraph_finalize_function (fndecl
, false);
483 case CGRAPH_STATE_CONSTRUCTION
:
484 /* Just enqueue function to be processed at nearest occurrence. */
485 node
= cgraph_create_node (fndecl
);
487 node
->lowered
= true;
488 if (!cgraph_new_nodes
)
489 cgraph_new_nodes
= cgraph_node_set_new ();
490 cgraph_node_set_add (cgraph_new_nodes
, node
);
493 case CGRAPH_STATE_IPA
:
494 case CGRAPH_STATE_IPA_SSA
:
495 case CGRAPH_STATE_EXPANSION
:
496 /* Bring the function into finalized state and enqueue for later
497 analyzing and compilation. */
498 node
= cgraph_get_create_node (fndecl
);
499 node
->local
.local
= false;
500 node
->local
.finalized
= true;
501 node
->symbol
.force_output
= true;
502 if (!lowered
&& cgraph_state
== CGRAPH_STATE_EXPANSION
)
504 push_cfun (DECL_STRUCT_FUNCTION (fndecl
));
505 gimple_register_cfg_hooks ();
506 bitmap_obstack_initialize (NULL
);
507 execute_pass_list (all_lowering_passes
);
508 execute_pass_list (pass_early_local_passes
.pass
.sub
);
509 bitmap_obstack_release (NULL
);
515 node
->lowered
= true;
516 if (!cgraph_new_nodes
)
517 cgraph_new_nodes
= cgraph_node_set_new ();
518 cgraph_node_set_add (cgraph_new_nodes
, node
);
521 case CGRAPH_STATE_FINISHED
:
522 /* At the very end of compilation we have to do all the work up
524 node
= cgraph_create_node (fndecl
);
526 node
->lowered
= true;
527 cgraph_analyze_function (node
);
528 push_cfun (DECL_STRUCT_FUNCTION (fndecl
));
529 gimple_register_cfg_hooks ();
530 bitmap_obstack_initialize (NULL
);
531 if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl
)))
532 execute_pass_list (pass_early_local_passes
.pass
.sub
);
533 bitmap_obstack_release (NULL
);
535 expand_function (node
);
541 /* Set a personality if required and we already passed EH lowering. */
543 && (function_needs_eh_personality (DECL_STRUCT_FUNCTION (fndecl
))
544 == eh_personality_lang
))
545 DECL_FUNCTION_PERSONALITY (fndecl
) = lang_hooks
.eh_personality ();
548 /* Add a top-level asm statement to the list. */
551 add_asm_node (tree asm_str
)
553 struct asm_node
*node
;
555 node
= ggc_alloc_cleared_asm_node ();
556 node
->asm_str
= asm_str
;
557 node
->order
= symtab_order
++;
559 if (asm_nodes
== NULL
)
562 asm_last_node
->next
= node
;
563 asm_last_node
= node
;
567 /* Output all asm statements we have stored up to be output. */
570 output_asm_statements (void)
572 struct asm_node
*can
;
577 for (can
= asm_nodes
; can
; can
= can
->next
)
578 assemble_asm (can
->asm_str
);
582 /* C++ FE sometimes change linkage flags after producing same body aliases. */
584 fixup_same_cpp_alias_visibility (symtab_node node
, symtab_node target
, tree alias
)
586 DECL_VIRTUAL_P (node
->symbol
.decl
) = DECL_VIRTUAL_P (alias
);
587 if (TREE_PUBLIC (node
->symbol
.decl
))
589 DECL_EXTERNAL (node
->symbol
.decl
) = DECL_EXTERNAL (alias
);
590 DECL_COMDAT (node
->symbol
.decl
) = DECL_COMDAT (alias
);
591 DECL_COMDAT_GROUP (node
->symbol
.decl
) = DECL_COMDAT_GROUP (alias
);
592 if (DECL_ONE_ONLY (alias
)
593 && !node
->symbol
.same_comdat_group
)
594 symtab_add_to_same_comdat_group ((symtab_node
)node
, (symtab_node
)target
);
598 /* Analyze the function scheduled to be output. */
600 cgraph_analyze_function (struct cgraph_node
*node
)
602 tree decl
= node
->symbol
.decl
;
603 location_t saved_loc
= input_location
;
604 input_location
= DECL_SOURCE_LOCATION (decl
);
606 if (node
->alias
&& node
->thunk
.alias
)
608 struct cgraph_node
*tgt
= cgraph_get_node (node
->thunk
.alias
);
609 struct cgraph_node
*n
;
611 for (n
= tgt
; n
&& n
->alias
;
612 n
= n
->analyzed
? cgraph_alias_aliased_node (n
) : NULL
)
615 error ("function %q+D part of alias cycle", node
->symbol
.decl
);
617 input_location
= saved_loc
;
620 if (!vec_safe_length (node
->symbol
.ref_list
.references
))
621 ipa_record_reference ((symtab_node
)node
, (symtab_node
)tgt
,
622 IPA_REF_ALIAS
, NULL
);
623 if (node
->same_body_alias
)
625 DECL_DECLARED_INLINE_P (node
->symbol
.decl
)
626 = DECL_DECLARED_INLINE_P (node
->thunk
.alias
);
627 DECL_DISREGARD_INLINE_LIMITS (node
->symbol
.decl
)
628 = DECL_DISREGARD_INLINE_LIMITS (node
->thunk
.alias
);
629 fixup_same_cpp_alias_visibility ((symtab_node
) node
, (symtab_node
) tgt
, node
->thunk
.alias
);
632 if (node
->symbol
.address_taken
)
633 cgraph_mark_address_taken_node (cgraph_alias_aliased_node (node
));
635 else if (node
->thunk
.thunk_p
)
637 cgraph_create_edge (node
, cgraph_get_node (node
->thunk
.alias
),
638 NULL
, 0, CGRAPH_FREQ_BASE
);
640 else if (node
->dispatcher_function
)
642 /* Generate the dispatcher body of multi-versioned functions. */
643 struct cgraph_function_version_info
*dispatcher_version_info
644 = get_cgraph_node_version (node
);
645 if (dispatcher_version_info
!= NULL
646 && (dispatcher_version_info
->dispatcher_resolver
649 tree resolver
= NULL_TREE
;
650 gcc_assert (targetm
.generate_version_dispatcher_body
);
651 resolver
= targetm
.generate_version_dispatcher_body (node
);
652 gcc_assert (resolver
!= NULL_TREE
);
657 push_cfun (DECL_STRUCT_FUNCTION (decl
));
659 assign_assembler_name_if_neeeded (node
->symbol
.decl
);
661 /* Make sure to gimplify bodies only once. During analyzing a
662 function we lower it, which will require gimplified nested
663 functions, so we can end up here with an already gimplified
665 if (!gimple_has_body_p (decl
))
666 gimplify_function_tree (decl
);
667 dump_function (TDI_generic
, decl
);
669 /* Lower the function. */
673 lower_nested_functions (node
->symbol
.decl
);
674 gcc_assert (!node
->nested
);
676 gimple_register_cfg_hooks ();
677 bitmap_obstack_initialize (NULL
);
678 execute_pass_list (all_lowering_passes
);
679 free_dominance_info (CDI_POST_DOMINATORS
);
680 free_dominance_info (CDI_DOMINATORS
);
682 bitmap_obstack_release (NULL
);
683 node
->lowered
= true;
688 node
->analyzed
= true;
690 input_location
= saved_loc
;
693 /* C++ frontend produce same body aliases all over the place, even before PCH
694 gets streamed out. It relies on us linking the aliases with their function
695 in order to do the fixups, but ipa-ref is not PCH safe. Consequentely we
696 first produce aliases without links, but once C++ FE is sure he won't sream
697 PCH we build the links via this function. */
700 cgraph_process_same_body_aliases (void)
702 struct cgraph_node
*node
;
703 FOR_EACH_FUNCTION (node
)
704 if (node
->same_body_alias
705 && !vec_safe_length (node
->symbol
.ref_list
.references
))
707 struct cgraph_node
*tgt
= cgraph_get_node (node
->thunk
.alias
);
708 ipa_record_reference ((symtab_node
)node
, (symtab_node
)tgt
,
709 IPA_REF_ALIAS
, NULL
);
711 same_body_aliases_done
= true;
714 /* Process attributes common for vars and functions. */
717 process_common_attributes (tree decl
)
719 tree weakref
= lookup_attribute ("weakref", DECL_ATTRIBUTES (decl
));
721 if (weakref
&& !lookup_attribute ("alias", DECL_ATTRIBUTES (decl
)))
723 warning_at (DECL_SOURCE_LOCATION (decl
), OPT_Wattributes
,
724 "%<weakref%> attribute should be accompanied with"
725 " an %<alias%> attribute");
726 DECL_WEAK (decl
) = 0;
727 DECL_ATTRIBUTES (decl
) = remove_attribute ("weakref",
728 DECL_ATTRIBUTES (decl
));
732 /* Look for externally_visible and used attributes and mark cgraph nodes
735 We cannot mark the nodes at the point the attributes are processed (in
736 handle_*_attribute) because the copy of the declarations available at that
737 point may not be canonical. For example, in:
740 void f() __attribute__((used));
742 the declaration we see in handle_used_attribute will be the second
743 declaration -- but the front end will subsequently merge that declaration
744 with the original declaration and discard the second declaration.
746 Furthermore, we can't mark these nodes in cgraph_finalize_function because:
749 void f() __attribute__((externally_visible));
753 So, we walk the nodes at the end of the translation unit, applying the
754 attributes at that point. */
757 process_function_and_variable_attributes (struct cgraph_node
*first
,
758 struct varpool_node
*first_var
)
760 struct cgraph_node
*node
;
761 struct varpool_node
*vnode
;
763 for (node
= cgraph_first_function (); node
!= first
;
764 node
= cgraph_next_function (node
))
766 tree decl
= node
->symbol
.decl
;
767 if (DECL_PRESERVE_P (decl
))
768 cgraph_mark_force_output_node (node
);
769 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl
)))
771 if (! TREE_PUBLIC (node
->symbol
.decl
))
772 warning_at (DECL_SOURCE_LOCATION (node
->symbol
.decl
), OPT_Wattributes
,
773 "%<externally_visible%>"
774 " attribute have effect only on public objects");
776 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl
))
777 && (node
->local
.finalized
&& !node
->alias
))
779 warning_at (DECL_SOURCE_LOCATION (node
->symbol
.decl
), OPT_Wattributes
,
780 "%<weakref%> attribute ignored"
781 " because function is defined");
782 DECL_WEAK (decl
) = 0;
783 DECL_ATTRIBUTES (decl
) = remove_attribute ("weakref",
784 DECL_ATTRIBUTES (decl
));
787 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl
))
788 && !DECL_DECLARED_INLINE_P (decl
)
789 /* redefining extern inline function makes it DECL_UNINLINABLE. */
790 && !DECL_UNINLINABLE (decl
))
791 warning_at (DECL_SOURCE_LOCATION (decl
), OPT_Wattributes
,
792 "always_inline function might not be inlinable");
794 process_common_attributes (decl
);
796 for (vnode
= varpool_first_variable (); vnode
!= first_var
;
797 vnode
= varpool_next_variable (vnode
))
799 tree decl
= vnode
->symbol
.decl
;
800 if (DECL_EXTERNAL (decl
)
801 && DECL_INITIAL (decl
)
802 && const_value_known_p (decl
))
803 varpool_finalize_decl (decl
);
804 if (DECL_PRESERVE_P (decl
))
805 vnode
->symbol
.force_output
= true;
806 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl
)))
808 if (! TREE_PUBLIC (vnode
->symbol
.decl
))
809 warning_at (DECL_SOURCE_LOCATION (vnode
->symbol
.decl
), OPT_Wattributes
,
810 "%<externally_visible%>"
811 " attribute have effect only on public objects");
813 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl
))
815 && DECL_INITIAL (decl
))
817 warning_at (DECL_SOURCE_LOCATION (vnode
->symbol
.decl
), OPT_Wattributes
,
818 "%<weakref%> attribute ignored"
819 " because variable is initialized");
820 DECL_WEAK (decl
) = 0;
821 DECL_ATTRIBUTES (decl
) = remove_attribute ("weakref",
822 DECL_ATTRIBUTES (decl
));
824 process_common_attributes (decl
);
828 /* Mark DECL as finalized. By finalizing the declaration, frontend instruct the
829 middle end to output the variable to asm file, if needed or externally
833 varpool_finalize_decl (tree decl
)
835 struct varpool_node
*node
= varpool_node_for_decl (decl
);
837 gcc_assert (TREE_STATIC (decl
) || DECL_EXTERNAL (decl
));
841 notice_global_symbol (decl
);
842 node
->finalized
= true;
843 if (TREE_THIS_VOLATILE (decl
) || DECL_PRESERVE_P (decl
)
844 /* Traditionally we do not eliminate static variables when not
845 optimizing and when not doing toplevel reoder. */
846 || (!flag_toplevel_reorder
&& !DECL_COMDAT (node
->symbol
.decl
)
847 && !DECL_ARTIFICIAL (node
->symbol
.decl
)))
848 node
->symbol
.force_output
= true;
850 if (cgraph_state
== CGRAPH_STATE_CONSTRUCTION
851 && (decide_is_variable_needed (node
, decl
)
852 || referred_to_p ((symtab_node
)node
)))
853 enqueue_node ((symtab_node
)node
);
854 if (cgraph_state
>= CGRAPH_STATE_IPA_SSA
)
855 varpool_analyze_node (node
);
856 /* Some frontends produce various interface variables after compilation
858 if (cgraph_state
== CGRAPH_STATE_FINISHED
859 || (cgraph_state
== CGRAPH_STATE_EXPANSION
860 && flag_dyn_ipa
&& !flag_toplevel_reorder
))
861 varpool_assemble_decl (node
);
865 /* Determine if a symbol NODE is finalized and needed. */
868 symbol_finalized_and_needed (symtab_node node
)
870 if (cgraph_node
*cnode
= dyn_cast
<cgraph_node
> (node
))
871 return cnode
->local
.finalized
872 && cgraph_decide_is_function_needed (cnode
, cnode
->symbol
.decl
);
873 if (varpool_node
*vnode
= dyn_cast
<varpool_node
> (node
))
874 return vnode
->finalized
875 && !DECL_EXTERNAL (vnode
->symbol
.decl
)
876 && decide_is_variable_needed (vnode
, vnode
->symbol
.decl
);
880 /* Determine if a symbol NODE is finalized. */
883 symbol_finalized (symtab_node node
)
885 if (cgraph_node
*cnode
= dyn_cast
<cgraph_node
> (node
))
886 return cnode
->local
.finalized
;
887 if (varpool_node
*vnode
= dyn_cast
<varpool_node
> (node
))
888 return vnode
->finalized
;
893 /* Discover all functions and variables that are trivially needed, analyze
894 them as well as all functions and variables referred by them */
897 cgraph_analyze_functions (void)
899 /* Keep track of already processed nodes when called multiple times for
900 intermodule optimization. */
901 static struct cgraph_node
*first_analyzed
;
902 struct cgraph_node
*first_handled
= first_analyzed
;
903 static struct varpool_node
*first_analyzed_var
;
904 struct varpool_node
*first_handled_var
= first_analyzed_var
;
906 symtab_node node
, next
;
911 bitmap_obstack_initialize (NULL
);
912 cgraph_state
= CGRAPH_STATE_CONSTRUCTION
;
914 /* Analysis adds static variables that in turn adds references to new functions.
915 So we need to iterate the process until it stabilize. */
919 process_function_and_variable_attributes (first_analyzed
,
922 /* First identify the trivially needed symbols. */
923 for (node
= symtab_nodes
;
924 node
!= (symtab_node
)first_analyzed
925 && node
!= (symtab_node
)first_analyzed_var
; node
= node
->symbol
.next
)
927 if (symbol_finalized_and_needed (node
))
930 if (!changed
&& cgraph_dump_file
)
931 fprintf (cgraph_dump_file
, "Trivially needed symbols:");
933 if (cgraph_dump_file
)
934 fprintf (cgraph_dump_file
, " %s/%d", symtab_node_asm_name (node
), node
->symbol
.order
);
936 if (node
== (symtab_node
)first_analyzed
937 || node
== (symtab_node
)first_analyzed_var
)
940 cgraph_process_new_functions ();
941 first_analyzed_var
= varpool_first_variable ();
942 first_analyzed
= cgraph_first_function ();
944 if (changed
&& dump_file
)
945 fprintf (cgraph_dump_file
, "\n");
947 /* Lower representation, build callgraph edges and references for all trivially
948 needed symbols and all symbols referred by them. */
949 while (first
!= (symtab_node
)(void *)1)
953 first
= (symtab_node
)first
->symbol
.aux
;
954 cgraph_node
*cnode
= dyn_cast
<cgraph_node
> (node
);
955 if (cnode
&& cnode
->local
.finalized
)
957 struct cgraph_edge
*edge
;
958 tree decl
= cnode
->symbol
.decl
;
960 /* ??? It is possible to create extern inline function
961 and later using weak alias attribute to kill its body.
962 See gcc.c-torture/compile/20011119-1.c */
963 if (!DECL_STRUCT_FUNCTION (decl
)
964 && (!cnode
->alias
|| !cnode
->thunk
.alias
)
965 && !cnode
->thunk
.thunk_p
966 && !cnode
->dispatcher_function
)
968 cgraph_reset_node (cnode
);
969 cnode
->local
.redefined_extern_inline
= true;
973 if (!cnode
->analyzed
)
974 cgraph_analyze_function (cnode
);
976 for (edge
= cnode
->callees
; edge
; edge
= edge
->next_callee
)
977 if (edge
->callee
->local
.finalized
)
978 enqueue_node ((symtab_node
)edge
->callee
);
980 /* If decl is a clone of an abstract function,
981 mark that abstract function so that we don't release its body.
982 The DECL_INITIAL() of that abstract function declaration
983 will be later needed to output debug info. */
984 if (DECL_ABSTRACT_ORIGIN (decl
))
986 struct cgraph_node
*origin_node
987 = cgraph_get_node (DECL_ABSTRACT_ORIGIN (decl
));
988 origin_node
->abstract_and_needed
= true;
993 varpool_node
*vnode
= dyn_cast
<varpool_node
> (node
);
994 if (vnode
&& vnode
->finalized
)
995 varpool_analyze_node (vnode
);
998 if (node
->symbol
.same_comdat_group
)
1001 for (next
= node
->symbol
.same_comdat_group
;
1003 next
= next
->symbol
.same_comdat_group
)
1004 enqueue_node (next
);
1006 for (i
= 0; ipa_ref_list_reference_iterate (&node
->symbol
.ref_list
, i
, ref
); i
++)
1007 if (symbol_finalized (ref
->referred
))
1008 enqueue_node (ref
->referred
);
1009 cgraph_process_new_functions ();
1013 /* Collect entry points to the unit. */
1014 if (cgraph_dump_file
)
1016 fprintf (cgraph_dump_file
, "\n\nInitial ");
1017 dump_symtab (cgraph_dump_file
);
1020 if (cgraph_dump_file
)
1021 fprintf (cgraph_dump_file
, "\nRemoving unused symbols:");
1023 for (node
= symtab_nodes
;
1024 node
!= (symtab_node
)first_handled
1025 && node
!= (symtab_node
)first_handled_var
; node
= next
)
1027 next
= node
->symbol
.next
;
1028 if (!node
->symbol
.aux
&& !referred_to_p (node
))
1030 if (cgraph_dump_file
)
1031 fprintf (cgraph_dump_file
, " %s/%d", symtab_node_name (node
), node
->symbol
.order
);
1032 symtab_remove_node (node
);
1035 if (cgraph_node
*cnode
= dyn_cast
<cgraph_node
> (node
))
1037 tree decl
= node
->symbol
.decl
;
1039 if (cnode
->local
.finalized
&& !gimple_has_body_p (decl
)
1040 && (!cnode
->alias
|| !cnode
->thunk
.alias
)
1041 && !cnode
->thunk
.thunk_p
)
1042 cgraph_reset_node (cnode
);
1044 gcc_assert (!cnode
->local
.finalized
|| cnode
->thunk
.thunk_p
1046 || gimple_has_body_p (decl
));
1047 gcc_assert (cnode
->analyzed
== cnode
->local
.finalized
);
1049 node
->symbol
.aux
= NULL
;
1051 first_analyzed
= cgraph_first_function ();
1052 first_analyzed_var
= varpool_first_variable ();
1053 if (cgraph_dump_file
)
1055 fprintf (cgraph_dump_file
, "\n\nReclaimed ");
1056 dump_symtab (cgraph_dump_file
);
1058 bitmap_obstack_release (NULL
);
1062 /* Translate the ugly representation of aliases as alias pairs into nice
1063 representation in callgraph. We don't handle all cases yet,
1067 handle_alias_pairs (void)
1072 for (i
= 0; alias_pairs
&& alias_pairs
->iterate (i
, &p
);)
1074 symtab_node target_node
= symtab_node_for_asm (p
->target
);
1076 /* Weakrefs with target not defined in current unit are easy to handle; they
1077 behave just as external variables except we need to note the alias flag
1078 to later output the weakref pseudo op into asm file. */
1079 if (!target_node
&& lookup_attribute ("weakref", DECL_ATTRIBUTES (p
->decl
)) != NULL
)
1081 if (TREE_CODE (p
->decl
) == FUNCTION_DECL
)
1082 cgraph_get_create_node (p
->decl
)->alias
= true;
1084 varpool_get_node (p
->decl
)->alias
= true;
1085 DECL_EXTERNAL (p
->decl
) = 1;
1086 alias_pairs
->unordered_remove (i
);
1089 else if (!target_node
)
1091 error ("%q+D aliased to undefined symbol %qE", p
->decl
, p
->target
);
1092 alias_pairs
->unordered_remove (i
);
1096 /* Normally EXTERNAL flag is used to mark external inlines,
1097 however for aliases it seems to be allowed to use it w/o
1098 any meaning. See gcc.dg/attr-alias-3.c
1099 However for weakref we insist on EXTERNAL flag being set.
1100 See gcc.dg/attr-alias-5.c */
1101 if (DECL_EXTERNAL (p
->decl
))
1102 DECL_EXTERNAL (p
->decl
)
1103 = lookup_attribute ("weakref",
1104 DECL_ATTRIBUTES (p
->decl
)) != NULL
;
1106 if (DECL_EXTERNAL (target_node
->symbol
.decl
)
1107 /* We use local aliases for C++ thunks to force the tailcall
1108 to bind locally. This is a hack - to keep it working do
1109 the following (which is not strictly correct). */
1110 && (! TREE_CODE (target_node
->symbol
.decl
) == FUNCTION_DECL
1111 || ! DECL_VIRTUAL_P (target_node
->symbol
.decl
))
1112 && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p
->decl
)))
1114 error ("%q+D aliased to external symbol %qE",
1115 p
->decl
, p
->target
);
1118 if (TREE_CODE (p
->decl
) == FUNCTION_DECL
1119 && target_node
&& is_a
<cgraph_node
> (target_node
))
1121 struct cgraph_node
*src_node
= cgraph_get_node (p
->decl
);
1122 if (src_node
&& src_node
->local
.finalized
)
1123 cgraph_reset_node (src_node
);
1124 cgraph_create_function_alias (p
->decl
, target_node
->symbol
.decl
);
1125 alias_pairs
->unordered_remove (i
);
1127 else if (TREE_CODE (p
->decl
) == VAR_DECL
1128 && target_node
&& is_a
<varpool_node
> (target_node
))
1130 varpool_create_variable_alias (p
->decl
, target_node
->symbol
.decl
);
1131 alias_pairs
->unordered_remove (i
);
1135 error ("%q+D alias in between function and variable is not supported",
1137 warning (0, "%q+D aliased declaration",
1138 target_node
->symbol
.decl
);
1139 alias_pairs
->unordered_remove (i
);
1142 vec_free (alias_pairs
);
1145 /* Hash function for symbol (function) resolution. */
1148 hash_node_by_assembler_name (const void *p
)
1150 const struct cgraph_node
*n
= (const struct cgraph_node
*) p
;
1151 return (hashval_t
) decl_assembler_name_hash (
1152 DECL_ASSEMBLER_NAME (n
->symbol
.decl
));
1155 /* Equality function for cgraph_node table. */
1158 eq_node_assembler_name (const void *p1
, const void *p2
)
1160 const struct cgraph_node
*n1
= (const struct cgraph_node
*) p1
;
1161 const_tree name
= (const_tree
)p2
;
1162 return (decl_assembler_name_equal (n1
->symbol
.decl
, name
));
1165 /* In l-ipo mode compilation (light weight IPO), multiple bodies may
1166 be available for the same inline declared function. cgraph linking
1167 does not really merge them in order to keep the context (module info)
1168 of each body. After inlining, the linkage of the function may require
1169 them to be output (even if it is defined in an auxiliary module). This
1170 in term may result in duplicate emission. */
1172 static GTY((param_is (struct cgraph_node
))) htab_t output_node_hash
= NULL
;
1174 /* Add NODE that is expanded into the hashtable. */
1176 static struct cgraph_node
*
1177 cgraph_add_output_node (struct cgraph_node
*node
)
1182 if (!L_IPO_COMP_MODE
)
1185 /* Never common non public names except for compiler
1186 generated static functions. (they are not promoted
1187 to globals either. */
1188 if (!TREE_PUBLIC (node
->symbol
.decl
)
1189 && !(DECL_ARTIFICIAL (node
->symbol
.decl
)
1190 && DECL_ASSEMBLER_NAME_SET_P (node
->symbol
.decl
)))
1193 if (!output_node_hash
)
1195 htab_create_ggc (10, hash_node_by_assembler_name
,
1196 eq_node_assembler_name
, NULL
);
1198 name
= DECL_ASSEMBLER_NAME (node
->symbol
.decl
);
1200 aslot
= htab_find_slot_with_hash (output_node_hash
, name
,
1201 decl_assembler_name_hash (name
),
1209 return (struct cgraph_node
*)(*aslot
);
1213 /* Return the cgraph_node if the function symbol for NODE is
1214 expanded in the output. Returns NULL otherwise. */
1216 static struct cgraph_node
*
1217 cgraph_find_output_node (struct cgraph_node
*node
)
1222 if (!L_IPO_COMP_MODE
)
1225 /* We do not track non-public functions. */
1226 if (!TREE_PUBLIC (node
->symbol
.decl
))
1230 if (!output_node_hash
)
1233 name
= DECL_ASSEMBLER_NAME (node
->symbol
.decl
);
1235 aslot
= htab_find_slot_with_hash (output_node_hash
, name
,
1236 decl_assembler_name_hash (name
),
1241 return (struct cgraph_node
*)(*aslot
);
1247 /* A function used in validation. Return true if NODE was
1248 not expanded and its body was not reclaimed. */
1251 cgraph_node_expansion_skipped (struct cgraph_node
*node
)
1253 struct cgraph_node
*output_node
;
1255 if (!L_IPO_COMP_MODE
)
1258 output_node
= cgraph_find_output_node (node
);
1260 if (output_node
== node
)
1266 /* No output, no duplicate being output, and the node is not
1267 inlined (and reclaimed) either -- check if the caller node
1268 is output/expanded or not. */
1269 if (node
->global
.inlined_to
)
1270 return cgraph_node_expansion_skipped (node
->global
.inlined_to
);
1272 /* External functions not marked for output. */
1277 /* Figure out what functions we want to assemble. */
1280 mark_functions_to_output (void)
1282 struct cgraph_node
*node
;
1283 #ifdef ENABLE_CHECKING
1284 bool check_same_comdat_groups
= false;
1286 FOR_EACH_FUNCTION (node
)
1287 gcc_assert (!node
->process
);
1290 FOR_EACH_FUNCTION (node
)
1292 tree decl
= node
->symbol
.decl
;
1294 gcc_assert (!node
->process
|| node
->symbol
.same_comdat_group
);
1298 /* We need to output all local functions that are used and not
1299 always inlined, as well as those that are reachable from
1300 outside the current compilation unit. */
1302 && !node
->thunk
.thunk_p
1304 && !node
->global
.inlined_to
1305 && !TREE_ASM_WRITTEN (decl
)
1306 && !(DECL_EXTERNAL (decl
) || cgraph_is_aux_decl_external (node
)))
1308 if (cgraph_add_output_node (node
) == node
)
1311 if (node
->symbol
.same_comdat_group
)
1313 struct cgraph_node
*next
;
1314 for (next
= cgraph (node
->symbol
.same_comdat_group
);
1316 next
= cgraph (next
->symbol
.same_comdat_group
))
1317 if (!next
->thunk
.thunk_p
&& !next
->alias
1318 && cgraph_add_output_node (next
) == next
)
1323 else if (node
->symbol
.same_comdat_group
)
1325 #ifdef ENABLE_CHECKING
1326 check_same_comdat_groups
= true;
1331 /* We should've reclaimed all functions that are not needed. */
1332 #ifdef ENABLE_CHECKING
1333 if (!node
->global
.inlined_to
1334 && gimple_has_body_p (decl
)
1335 /* FIXME: in ltrans unit when offline copy is outside partition but inline copies
1336 are inside partition, we can end up not removing the body since we no longer
1337 have analyzed node pointing to it. */
1338 && !node
->symbol
.in_other_partition
1340 && !cgraph_is_auxiliary (node
->symbol
.decl
)
1342 && !DECL_EXTERNAL (decl
))
1344 dump_cgraph_node (stderr
, node
);
1345 internal_error ("failed to reclaim unneeded function");
1348 gcc_assert (node
->global
.inlined_to
1349 || !gimple_has_body_p (decl
)
1350 || node
->symbol
.in_other_partition
1352 || DECL_ARTIFICIAL (decl
)
1353 || DECL_EXTERNAL (decl
)
1354 || cgraph_is_auxiliary (node
->symbol
.decl
));
1359 #ifdef ENABLE_CHECKING
1360 if (check_same_comdat_groups
&& !L_IPO_COMP_MODE
)
1361 FOR_EACH_FUNCTION (node
)
1362 if (node
->symbol
.same_comdat_group
&& !node
->process
)
1364 tree decl
= node
->symbol
.decl
;
1365 if (!node
->global
.inlined_to
1366 && gimple_has_body_p (decl
)
1367 /* FIXME: in an ltrans unit when the offline copy is outside a
1368 partition but inline copies are inside a partition, we can
1369 end up not removing the body since we no longer have an
1370 analyzed node pointing to it. */
1371 && !node
->symbol
.in_other_partition
1373 && !(DECL_EXTERNAL (decl
) || cgraph_is_aux_decl_external (node
))
1374 && !L_IPO_COMP_MODE
)
1376 dump_cgraph_node (stderr
, node
);
1377 internal_error ("failed to reclaim unneeded function in same "
1384 /* DECL is FUNCTION_DECL. Initialize datastructures so DECL is a function
1385 in lowered gimple form. IN_SSA is true if the gimple is in SSA.
1387 Set current_function_decl and cfun to newly constructed empty function body.
1388 return basic block in the function body. */
1391 init_lowered_empty_function (tree decl
, bool in_ssa
)
1395 current_function_decl
= decl
;
1396 allocate_struct_function (decl
, false);
1397 gimple_register_cfg_hooks ();
1398 init_empty_tree_cfg ();
1402 init_tree_ssa (cfun
);
1403 init_ssa_operands (cfun
);
1404 cfun
->gimple_df
->in_ssa_p
= true;
1407 DECL_INITIAL (decl
) = make_node (BLOCK
);
1409 DECL_SAVED_TREE (decl
) = error_mark_node
;
1410 cfun
->curr_properties
|=
1411 (PROP_gimple_lcf
| PROP_gimple_leh
| PROP_cfg
| PROP_ssa
| PROP_gimple_any
);
1413 /* Create BB for body of the function and connect it properly. */
1414 bb
= create_basic_block (NULL
, (void *) 0, ENTRY_BLOCK_PTR
);
1415 make_edge (ENTRY_BLOCK_PTR
, bb
, 0);
1416 make_edge (bb
, EXIT_BLOCK_PTR
, 0);
1421 /* Adjust PTR by the constant FIXED_OFFSET, and by the vtable
1422 offset indicated by VIRTUAL_OFFSET, if that is
1423 non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and
1424 zero for a result adjusting thunk. */
1427 thunk_adjust (gimple_stmt_iterator
* bsi
,
1428 tree ptr
, bool this_adjusting
,
1429 HOST_WIDE_INT fixed_offset
, tree virtual_offset
)
1435 && fixed_offset
!= 0)
1437 stmt
= gimple_build_assign
1438 (ptr
, fold_build_pointer_plus_hwi_loc (input_location
,
1441 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1444 /* If there's a virtual offset, look up that value in the vtable and
1445 adjust the pointer again. */
1452 if (!vtable_entry_type
)
1454 tree vfunc_type
= make_node (FUNCTION_TYPE
);
1455 TREE_TYPE (vfunc_type
) = integer_type_node
;
1456 TYPE_ARG_TYPES (vfunc_type
) = NULL_TREE
;
1457 layout_type (vfunc_type
);
1459 vtable_entry_type
= build_pointer_type (vfunc_type
);
1463 create_tmp_reg (build_pointer_type
1464 (build_pointer_type (vtable_entry_type
)), "vptr");
1466 /* The vptr is always at offset zero in the object. */
1467 stmt
= gimple_build_assign (vtabletmp
,
1468 build1 (NOP_EXPR
, TREE_TYPE (vtabletmp
),
1470 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1472 /* Form the vtable address. */
1473 vtabletmp2
= create_tmp_reg (TREE_TYPE (TREE_TYPE (vtabletmp
)),
1475 stmt
= gimple_build_assign (vtabletmp2
,
1476 build_simple_mem_ref (vtabletmp
));
1477 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1479 /* Find the entry with the vcall offset. */
1480 stmt
= gimple_build_assign (vtabletmp2
,
1481 fold_build_pointer_plus_loc (input_location
,
1484 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1486 /* Get the offset itself. */
1487 vtabletmp3
= create_tmp_reg (TREE_TYPE (TREE_TYPE (vtabletmp2
)),
1489 stmt
= gimple_build_assign (vtabletmp3
,
1490 build_simple_mem_ref (vtabletmp2
));
1491 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1493 /* Adjust the `this' pointer. */
1494 ptr
= fold_build_pointer_plus_loc (input_location
, ptr
, vtabletmp3
);
1495 ptr
= force_gimple_operand_gsi (bsi
, ptr
, true, NULL_TREE
, false,
1496 GSI_CONTINUE_LINKING
);
1500 && fixed_offset
!= 0)
1501 /* Adjust the pointer by the constant. */
1505 if (TREE_CODE (ptr
) == VAR_DECL
)
1509 ptrtmp
= create_tmp_reg (TREE_TYPE (ptr
), "ptr");
1510 stmt
= gimple_build_assign (ptrtmp
, ptr
);
1511 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1513 ptr
= fold_build_pointer_plus_hwi_loc (input_location
,
1514 ptrtmp
, fixed_offset
);
1517 /* Emit the statement and gimplify the adjustment expression. */
1518 ret
= create_tmp_reg (TREE_TYPE (ptr
), "adjusted_this");
1519 stmt
= gimple_build_assign (ret
, ptr
);
1520 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1525 /* Produce assembler for thunk NODE. */
1528 assemble_thunk (struct cgraph_node
*node
)
1530 bool this_adjusting
= node
->thunk
.this_adjusting
;
1531 HOST_WIDE_INT fixed_offset
= node
->thunk
.fixed_offset
;
1532 HOST_WIDE_INT virtual_value
= node
->thunk
.virtual_value
;
1533 tree virtual_offset
= NULL
;
1534 tree alias
= node
->thunk
.alias
;
1535 tree thunk_fndecl
= node
->symbol
.decl
;
1536 tree a
= DECL_ARGUMENTS (thunk_fndecl
);
1538 current_function_decl
= thunk_fndecl
;
1540 /* Ensure thunks are emitted in their correct sections. */
1541 resolve_unique_section (thunk_fndecl
, 0, flag_function_sections
);
1544 && targetm
.asm_out
.can_output_mi_thunk (thunk_fndecl
, fixed_offset
,
1545 virtual_value
, alias
))
1549 tree restype
= TREE_TYPE (TREE_TYPE (thunk_fndecl
));
1551 DECL_RESULT (thunk_fndecl
)
1552 = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl
),
1553 RESULT_DECL
, 0, restype
);
1554 fnname
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl
));
1556 /* The back end expects DECL_INITIAL to contain a BLOCK, so we
1558 fn_block
= make_node (BLOCK
);
1559 BLOCK_VARS (fn_block
) = a
;
1560 DECL_INITIAL (thunk_fndecl
) = fn_block
;
1561 init_function_start (thunk_fndecl
);
1563 insn_locations_init ();
1564 set_curr_insn_location (DECL_SOURCE_LOCATION (thunk_fndecl
));
1565 prologue_location
= curr_insn_location ();
1566 assemble_start_function (thunk_fndecl
, fnname
);
1568 targetm
.asm_out
.output_mi_thunk (asm_out_file
, thunk_fndecl
,
1569 fixed_offset
, virtual_value
, alias
);
1571 assemble_end_function (thunk_fndecl
, fnname
);
1572 insn_locations_finalize ();
1573 init_insn_lengths ();
1574 free_after_compilation (cfun
);
1576 TREE_ASM_WRITTEN (thunk_fndecl
) = 1;
1577 node
->thunk
.thunk_p
= false;
1578 node
->analyzed
= false;
1583 basic_block bb
, then_bb
, else_bb
, return_bb
;
1584 gimple_stmt_iterator bsi
;
1595 DECL_IGNORED_P (thunk_fndecl
) = 1;
1596 bitmap_obstack_initialize (NULL
);
1598 if (node
->thunk
.virtual_offset_p
)
1599 virtual_offset
= size_int (virtual_value
);
1601 /* Build the return declaration for the function. */
1602 restype
= TREE_TYPE (TREE_TYPE (thunk_fndecl
));
1603 if (DECL_RESULT (thunk_fndecl
) == NULL_TREE
)
1605 resdecl
= build_decl (input_location
, RESULT_DECL
, 0, restype
);
1606 DECL_ARTIFICIAL (resdecl
) = 1;
1607 DECL_IGNORED_P (resdecl
) = 1;
1608 DECL_RESULT (thunk_fndecl
) = resdecl
;
1611 resdecl
= DECL_RESULT (thunk_fndecl
);
1613 bb
= then_bb
= else_bb
= return_bb
= init_lowered_empty_function (thunk_fndecl
, true);
1615 bsi
= gsi_start_bb (bb
);
1617 /* Build call to the function being thunked. */
1618 if (!VOID_TYPE_P (restype
))
1620 if (!is_gimple_reg_type (restype
))
1623 add_local_decl (cfun
, restmp
);
1624 BLOCK_VARS (DECL_INITIAL (current_function_decl
)) = restmp
;
1627 restmp
= create_tmp_reg (restype
, "retval");
1630 for (arg
= a
; arg
; arg
= DECL_CHAIN (arg
))
1632 vargs
.create (nargs
);
1634 vargs
.quick_push (thunk_adjust (&bsi
, a
, 1, fixed_offset
,
1637 vargs
.quick_push (a
);
1638 for (i
= 1, arg
= DECL_CHAIN (a
); i
< nargs
; i
++, arg
= DECL_CHAIN (arg
))
1639 vargs
.quick_push (arg
);
1640 call
= gimple_build_call_vec (build_fold_addr_expr_loc (0, alias
), vargs
);
1642 gimple_call_set_from_thunk (call
, true);
1644 gimple_call_set_lhs (call
, restmp
);
1645 gsi_insert_after (&bsi
, call
, GSI_NEW_STMT
);
1647 if (restmp
&& !this_adjusting
)
1649 tree true_label
= NULL_TREE
;
1651 if (TREE_CODE (TREE_TYPE (restmp
)) == POINTER_TYPE
)
1654 /* If the return type is a pointer, we need to
1655 protect against NULL. We know there will be an
1656 adjustment, because that's why we're emitting a
1658 then_bb
= create_basic_block (NULL
, (void *) 0, bb
);
1659 return_bb
= create_basic_block (NULL
, (void *) 0, then_bb
);
1660 else_bb
= create_basic_block (NULL
, (void *) 0, else_bb
);
1661 remove_edge (single_succ_edge (bb
));
1662 true_label
= gimple_block_label (then_bb
);
1663 stmt
= gimple_build_cond (NE_EXPR
, restmp
,
1664 build_zero_cst (TREE_TYPE (restmp
)),
1665 NULL_TREE
, NULL_TREE
);
1666 gsi_insert_after (&bsi
, stmt
, GSI_NEW_STMT
);
1667 make_edge (bb
, then_bb
, EDGE_TRUE_VALUE
);
1668 make_edge (bb
, else_bb
, EDGE_FALSE_VALUE
);
1669 make_edge (return_bb
, EXIT_BLOCK_PTR
, 0);
1670 make_edge (then_bb
, return_bb
, EDGE_FALLTHRU
);
1671 make_edge (else_bb
, return_bb
, EDGE_FALLTHRU
);
1672 bsi
= gsi_last_bb (then_bb
);
1675 restmp
= thunk_adjust (&bsi
, restmp
, /*this_adjusting=*/0,
1676 fixed_offset
, virtual_offset
);
1680 bsi
= gsi_last_bb (else_bb
);
1681 stmt
= gimple_build_assign (restmp
,
1682 build_zero_cst (TREE_TYPE (restmp
)));
1683 gsi_insert_after (&bsi
, stmt
, GSI_NEW_STMT
);
1684 bsi
= gsi_last_bb (return_bb
);
1688 gimple_call_set_tail (call
, true);
1690 /* Build return value. */
1691 ret
= gimple_build_return (restmp
);
1692 gsi_insert_after (&bsi
, ret
, GSI_NEW_STMT
);
1694 delete_unreachable_blocks ();
1695 update_ssa (TODO_update_ssa
);
1697 /* Since we want to emit the thunk, we explicitly mark its name as
1699 node
->thunk
.thunk_p
= false;
1700 cgraph_node_remove_callees (node
);
1701 cgraph_add_new_function (thunk_fndecl
, true);
1702 bitmap_obstack_release (NULL
);
1704 current_function_decl
= NULL
;
1710 /* Assemble thunks and aliases associated to NODE. */
1713 assemble_thunks_and_aliases (struct cgraph_node
*node
)
1715 struct cgraph_edge
*e
;
1717 struct ipa_ref
*ref
;
1719 for (e
= node
->callers
; e
;)
1720 if (e
->caller
->thunk
.thunk_p
)
1722 struct cgraph_node
*thunk
= e
->caller
;
1725 assemble_thunks_and_aliases (thunk
);
1726 assemble_thunk (thunk
);
1730 for (i
= 0; ipa_ref_list_referring_iterate (&node
->symbol
.ref_list
,
1732 if (ref
->use
== IPA_REF_ALIAS
)
1734 struct cgraph_node
*alias
= ipa_ref_referring_node (ref
);
1735 bool saved_written
= TREE_ASM_WRITTEN (alias
->thunk
.alias
);
1737 /* Force assemble_alias to really output the alias this time instead
1738 of buffering it in same alias pairs. */
1739 TREE_ASM_WRITTEN (alias
->thunk
.alias
) = 1;
1740 do_assemble_alias (alias
->symbol
.decl
,
1741 DECL_ASSEMBLER_NAME (alias
->thunk
.alias
));
1742 assemble_thunks_and_aliases (alias
);
1743 TREE_ASM_WRITTEN (alias
->thunk
.alias
) = saved_written
;
1747 /* Expand function specified by NODE. */
1750 expand_function (struct cgraph_node
*node
)
1752 tree decl
= node
->symbol
.decl
;
1753 location_t saved_loc
;
1755 /* We ought to not compile any inline clones. */
1756 gcc_assert (!node
->global
.inlined_to
);
1758 announce_function (decl
);
1760 gcc_assert (node
->lowered
);
1762 /* Generate RTL for the body of DECL. */
1764 timevar_push (TV_REST_OF_COMPILATION
);
1766 gcc_assert (cgraph_global_info_ready
);
1768 /* Initialize the default bitmap obstack. */
1769 bitmap_obstack_initialize (NULL
);
1771 /* Initialize the RTL code for the function. */
1772 current_function_decl
= decl
;
1773 saved_loc
= input_location
;
1774 input_location
= DECL_SOURCE_LOCATION (decl
);
1775 init_function_start (decl
);
1777 gimple_register_cfg_hooks ();
1779 bitmap_obstack_initialize (®_obstack
); /* FIXME, only at RTL generation*/
1781 execute_all_ipa_transforms ();
1783 /* Perform all tree transforms and optimizations. */
1785 /* Signal the start of passes. */
1786 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START
, NULL
);
1788 execute_pass_list (all_passes
);
1790 /* Signal the end of passes. */
1791 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END
, NULL
);
1793 bitmap_obstack_release (®_obstack
);
1795 /* Release the default bitmap obstack. */
1796 bitmap_obstack_release (NULL
);
1798 /* If requested, warn about function definitions where the function will
1799 return a value (usually of some struct or union type) which itself will
1800 take up a lot of stack space. */
1801 if (warn_larger_than
&& !DECL_EXTERNAL (decl
) && TREE_TYPE (decl
))
1803 tree ret_type
= TREE_TYPE (TREE_TYPE (decl
));
1805 if (ret_type
&& TYPE_SIZE_UNIT (ret_type
)
1806 && TREE_CODE (TYPE_SIZE_UNIT (ret_type
)) == INTEGER_CST
1807 && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type
),
1810 unsigned int size_as_int
1811 = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type
));
1813 if (compare_tree_int (TYPE_SIZE_UNIT (ret_type
), size_as_int
) == 0)
1814 warning (OPT_Wlarger_than_
, "size of return value of %q+D is %u bytes",
1817 warning (OPT_Wlarger_than_
, "size of return value of %q+D is larger than %wd bytes",
1818 decl
, larger_than_size
);
1822 gimple_set_body (decl
, NULL
);
1823 if (DECL_STRUCT_FUNCTION (decl
) == 0
1824 && !cgraph_get_node (decl
)->origin
)
1826 /* Stop pointing to the local nodes about to be freed.
1827 But DECL_INITIAL must remain nonzero so we know this
1828 was an actual function definition.
1829 For a nested function, this is done in c_pop_function_context.
1830 If rest_of_compilation set this to 0, leave it 0. */
1831 if (DECL_INITIAL (decl
) != 0)
1832 DECL_INITIAL (decl
) = error_mark_node
;
1835 input_location
= saved_loc
;
1838 timevar_pop (TV_REST_OF_COMPILATION
);
1840 /* Make sure that BE didn't give up on compiling. */
1841 gcc_assert (TREE_ASM_WRITTEN (decl
));
1843 current_function_decl
= NULL
;
1845 /* It would make a lot more sense to output thunks before function body to get more
1846 forward and lest backwarding jumps. This however would need solving problem
1847 with comdats. See PR48668. Also aliases must come after function itself to
1848 make one pass assemblers, like one on AIX, happy. See PR 50689.
1849 FIXME: Perhaps thunks should be move before function IFF they are not in comdat
1851 assemble_thunks_and_aliases (node
);
1852 cgraph_release_function_body (node
);
1853 /* Eliminate all call edges. This is important so the GIMPLE_CALL no longer
1854 points to the dead function body. */
1855 cgraph_node_remove_callees (node
);
1859 /* Expand all functions that must be output.
1861 Attempt to topologically sort the nodes so function is output when
1862 all called functions are already assembled to allow data to be
1863 propagated across the callgraph. Use a stack to get smaller distance
1864 between a function and its callees (later we may choose to use a more
1865 sophisticated algorithm for function reordering; we will likely want
1866 to use subsections to make the output functions appear in top-down
1870 expand_all_functions (void)
1872 struct cgraph_node
*node
;
1873 struct cgraph_node
**order
= XCNEWVEC (struct cgraph_node
*, cgraph_n_nodes
);
1874 int order_pos
, new_order_pos
= 0;
1877 order_pos
= ipa_reverse_postorder (order
);
1878 gcc_assert (order_pos
== cgraph_n_nodes
);
1880 /* Garbage collector may remove inline clones we eliminate during
1881 optimization. So we must be sure to not reference them. */
1882 for (i
= 0; i
< order_pos
; i
++)
1883 if (order
[i
]->process
)
1884 order
[new_order_pos
++] = order
[i
];
1886 for (i
= new_order_pos
- 1; i
>= 0; i
--)
1892 expand_function (node
);
1895 cgraph_process_new_functions ();
1901 /* This is used to sort the node types by the cgraph order number. */
1903 enum cgraph_order_sort_kind
1905 ORDER_UNDEFINED
= 0,
1911 struct cgraph_order_sort
1913 enum cgraph_order_sort_kind kind
;
1916 struct cgraph_node
*f
;
1917 struct varpool_node
*v
;
1922 /* Output all functions, variables, and asm statements in the order
1923 according to their order fields, which is the order in which they
1924 appeared in the file. This implements -fno-toplevel-reorder. In
1925 this mode we may output functions and variables which don't really
1926 need to be output. */
1929 output_in_order (void)
1932 struct cgraph_order_sort
*nodes
;
1934 struct cgraph_node
*pf
;
1935 struct varpool_node
*pv
;
1936 struct asm_node
*pa
;
1939 nodes
= XCNEWVEC (struct cgraph_order_sort
, max
);
1941 varpool_remove_duplicate_weak_decls ();
1943 FOR_EACH_DEFINED_FUNCTION (pf
)
1945 if (pf
->process
&& !pf
->thunk
.thunk_p
&& !pf
->alias
)
1947 i
= pf
->symbol
.order
;
1948 gcc_assert (nodes
[i
].kind
== ORDER_UNDEFINED
);
1949 nodes
[i
].kind
= ORDER_FUNCTION
;
1954 FOR_EACH_DEFINED_VARIABLE (pv
)
1955 if (!DECL_EXTERNAL (pv
->symbol
.decl
))
1957 i
= pv
->symbol
.order
;
1958 gcc_assert (nodes
[i
].kind
== ORDER_UNDEFINED
);
1959 nodes
[i
].kind
= ORDER_VAR
;
1963 for (pa
= asm_nodes
; pa
; pa
= pa
->next
)
1966 gcc_assert (nodes
[i
].kind
== ORDER_UNDEFINED
);
1967 nodes
[i
].kind
= ORDER_ASM
;
1971 /* In toplevel reorder mode we output all statics; mark them as needed. */
1973 for (i
= 0; i
< max
; ++i
)
1974 if (nodes
[i
].kind
== ORDER_VAR
)
1975 varpool_finalize_named_section_flags (nodes
[i
].u
.v
);
1977 for (i
= 0; i
< max
; ++i
)
1979 switch (nodes
[i
].kind
)
1981 case ORDER_FUNCTION
:
1982 nodes
[i
].u
.f
->process
= 0;
1983 expand_function (nodes
[i
].u
.f
);
1987 varpool_assemble_decl (nodes
[i
].u
.v
);
1991 assemble_asm (nodes
[i
].u
.a
->asm_str
);
1994 case ORDER_UNDEFINED
:
2010 current_function_decl
= NULL
;
2011 gimple_register_cfg_hooks ();
2012 bitmap_obstack_initialize (NULL
);
2014 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START
, NULL
);
2018 execute_ipa_pass_list (all_small_ipa_passes
);
2023 /* We never run removal of unreachable nodes after early passes. This is
2024 because TODO is run before the subpasses. It is important to remove
2025 the unreachable functions to save works at IPA level and to get LTO
2026 symbol tables right. */
2027 symtab_remove_unreachable_nodes (true, cgraph_dump_file
);
2029 /* If pass_all_early_optimizations was not scheduled, the state of
2030 the cgraph will not be properly updated. Update it now. */
2031 if (cgraph_state
< CGRAPH_STATE_IPA_SSA
)
2032 cgraph_state
= CGRAPH_STATE_IPA_SSA
;
2036 /* Generate coverage variables and constructors.
2037 In LIPO mode, delay this until direct call profiling
2042 /* Process new functions added. */
2044 current_function_decl
= NULL
;
2045 cgraph_process_new_functions ();
2047 execute_ipa_summary_passes
2048 ((struct ipa_opt_pass_d
*) all_regular_ipa_passes
);
2051 /* Some targets need to handle LTO assembler output specially. */
2052 if (flag_generate_lto
)
2053 targetm
.asm_out
.lto_start ();
2055 execute_ipa_summary_passes ((struct ipa_opt_pass_d
*) all_lto_gen_passes
);
2058 ipa_write_summaries ();
2060 if (flag_generate_lto
)
2061 targetm
.asm_out
.lto_end ();
2063 if (!flag_ltrans
&& (in_lto_p
|| !flag_lto
|| flag_fat_lto_objects
))
2064 execute_ipa_pass_list (all_regular_ipa_passes
);
2065 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END
, NULL
);
2067 bitmap_obstack_release (NULL
);
2071 /* Return string alias is alias of. */
2074 get_alias_symbol (tree decl
)
2076 tree alias
= lookup_attribute ("alias", DECL_ATTRIBUTES (decl
));
2077 return get_identifier (TREE_STRING_POINTER
2078 (TREE_VALUE (TREE_VALUE (alias
))));
2082 /* Weakrefs may be associated to external decls and thus not output
2083 at expansion time. Emit all necessary aliases. */
2086 output_weakrefs (void)
2088 struct cgraph_node
*node
;
2089 struct varpool_node
*vnode
;
2090 FOR_EACH_FUNCTION (node
)
2091 if (node
->alias
&& DECL_EXTERNAL (node
->symbol
.decl
)
2092 && !TREE_ASM_WRITTEN (node
->symbol
.decl
)
2093 && lookup_attribute ("weakref", DECL_ATTRIBUTES (node
->symbol
.decl
)))
2094 do_assemble_alias (node
->symbol
.decl
,
2095 node
->thunk
.alias
? DECL_ASSEMBLER_NAME (node
->thunk
.alias
)
2096 : get_alias_symbol (node
->symbol
.decl
));
2097 FOR_EACH_VARIABLE (vnode
)
2098 if (vnode
->alias
&& DECL_EXTERNAL (vnode
->symbol
.decl
)
2099 && !TREE_ASM_WRITTEN (vnode
->symbol
.decl
)
2100 && lookup_attribute ("weakref", DECL_ATTRIBUTES (vnode
->symbol
.decl
)))
2101 do_assemble_alias (vnode
->symbol
.decl
,
2102 vnode
->alias_of
? DECL_ASSEMBLER_NAME (vnode
->alias_of
)
2103 : get_alias_symbol (vnode
->symbol
.decl
));
2106 /* Initialize callgraph dump file. */
2111 if (!cgraph_dump_file
)
2112 cgraph_dump_file
= dump_begin (TDI_cgraph
, NULL
);
2116 /* Perform simple optimizations based on callgraph. */
2124 #ifdef ENABLE_CHECKING
2128 timevar_push (TV_CGRAPHOPT
);
2129 if (pre_ipa_mem_report
)
2131 fprintf (stderr
, "Memory consumption before IPA\n");
2132 dump_memory_report (false);
2135 fprintf (stderr
, "Performing interprocedural optimizations\n");
2136 cgraph_state
= CGRAPH_STATE_IPA
;
2138 if (L_IPO_COMP_MODE
)
2140 cgraph_init_gid_map ();
2141 cgraph_add_fake_indirect_call_edges ();
2144 /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE. */
2146 lto_streamer_hooks_init ();
2148 /* Don't run the IPA passes if there was any error or sorry messages. */
2152 /* Do nothing else if any IPA pass found errors or if we are just streaming LTO. */
2154 || (!in_lto_p
&& flag_lto
&& !flag_fat_lto_objects
))
2156 timevar_pop (TV_CGRAPHOPT
);
2160 /* This pass remove bodies of extern inline functions we never inlined.
2161 Do this later so other IPA passes see what is really going on. */
2162 symtab_remove_unreachable_nodes (false, dump_file
);
2163 cgraph_global_info_ready
= true;
2164 if (cgraph_dump_file
)
2166 fprintf (cgraph_dump_file
, "Optimized ");
2167 dump_symtab (cgraph_dump_file
);
2169 if (post_ipa_mem_report
)
2171 fprintf (stderr
, "Memory consumption after IPA\n");
2172 dump_memory_report (false);
2174 timevar_pop (TV_CGRAPHOPT
);
2176 /* Output everything. */
2177 (*debug_hooks
->assembly_start
) ();
2179 fprintf (stderr
, "Assembling functions:\n");
2180 #ifdef ENABLE_CHECKING
2184 cgraph_materialize_all_clones ();
2185 bitmap_obstack_initialize (NULL
);
2186 execute_ipa_pass_list (all_late_ipa_passes
);
2187 symtab_remove_unreachable_nodes (true, dump_file
);
2188 #ifdef ENABLE_CHECKING
2191 bitmap_obstack_release (NULL
);
2192 mark_functions_to_output ();
2194 cgraph_state
= CGRAPH_STATE_EXPANSION
;
2195 if (!flag_toplevel_reorder
)
2199 output_asm_statements ();
2201 expand_all_functions ();
2202 varpool_remove_duplicate_weak_decls ();
2203 varpool_output_variables ();
2206 cgraph_process_new_functions ();
2207 cgraph_state
= CGRAPH_STATE_FINISHED
;
2210 if (cgraph_dump_file
)
2212 fprintf (cgraph_dump_file
, "\nFinal ");
2213 dump_symtab (cgraph_dump_file
);
2215 #ifdef ENABLE_CHECKING
2217 /* Double check that all inline clones are gone and that all
2218 function bodies have been released from memory.
2219 As an exception, allow inline clones in the callgraph if
2220 they are auxiliary functions. This is because we don't
2221 expand any of the auxiliary functions, which may result
2222 in inline clones of some auxiliary functions to be left
2223 in the callgraph. */
2226 struct cgraph_node
*node
;
2227 bool error_found
= false;
2229 FOR_EACH_DEFINED_FUNCTION (node
)
2230 if (((node
->global
.inlined_to
&& !cgraph_is_auxiliary (node
->symbol
.decl
))
2231 || gimple_has_body_p (node
->symbol
.decl
))
2232 && !cgraph_node_expansion_skipped (node
))
2235 dump_cgraph_node (stderr
, node
);
2238 internal_error ("nodes with unreleased memory found");
2244 /* Analyze the whole compilation unit once it is parsed completely. */
2247 finalize_compilation_unit (void)
2249 timevar_push (TV_CGRAPH
);
2251 /* If we're here there's no current function anymore. Some frontends
2252 are lazy in clearing these. */
2253 current_function_decl
= NULL
;
2256 /* Do not skip analyzing the functions if there were errors, we
2257 miss diagnostics for following functions otherwise. */
2259 /* Emit size functions we didn't inline. */
2260 finalize_size_functions ();
2262 /* Mark alias targets necessary and emit diagnostics. */
2263 handle_alias_pairs ();
2267 fprintf (stderr
, "\nAnalyzing compilation unit\n");
2271 if (flag_dump_passes
)
2274 /* Gimplify and lower all functions, compute reachability and
2275 remove unreachable nodes. */
2276 cgraph_analyze_functions ();
2278 /* Mark alias targets necessary and emit diagnostics. */
2279 handle_alias_pairs ();
2281 /* Gimplify and lower thunks. */
2282 cgraph_analyze_functions ();
2284 /* Finally drive the pass manager. */
2287 timevar_pop (TV_CGRAPH
);
2291 #include "gt-cgraphunit.h"