1 /* Driver of optimization process
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
3 2011, 2012 Free Software Foundation, Inc.
4 Contributed by Jan Hubicka
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
22 /* This module implements main driver of compilation process.
24 The main scope of this file is to act as an interface in between
25 tree based frontends and the backend.
27 The front-end is supposed to use following functionality:
29 - cgraph_finalize_function
31 This function is called once front-end has parsed whole body of function
32 and it is certain that the function body nor the declaration will change.
34 (There is one exception needed for implementing GCC extern inline
37 - varpool_finalize_decl
39 This function has same behavior as the above but is used for static
44 Insert new toplevel ASM statement
46 - finalize_compilation_unit
48 This function is called once (source level) compilation unit is finalized
49 and it will no longer change.
51 The symbol table is constructed starting from the trivially needed
52 symbols finalized by the frontend. Functions are lowered into
53 GIMPLE representation and callgraph/reference lists are constructed.
54 Those are used to discover other necessary functions and variables.
56 At the end the bodies of unreachable functions are removed.
58 The function can be called multiple times when multiple source level
59 compilation units are combined.
63 This passes control to the back-end. Optimizations are performed and
64 final assembler is generated. This is done in the following way. Note
65 that with link time optimization the process is split into three
66 stages (compile time, linktime analysis and parallel linktime as
71 1) Inter-procedural optimization.
74 This part is further split into:
76 a) early optimizations. These are local passes executed in
77 the topological order on the callgraph.
79 The purpose of early optimiations is to optimize away simple
80 things that may otherwise confuse IP analysis. Very simple
81 propagation across the callgraph is done i.e. to discover
82 functions without side effects and simple inlining is performed.
84 b) early small interprocedural passes.
86 Those are interprocedural passes executed only at compilation
87 time. These include, for exmaple, transational memory lowering,
88 unreachable code removal and other simple transformations.
90 c) IP analysis stage. All interprocedural passes do their
93 Interprocedural passes differ from small interprocedural
94 passes by their ability to operate across whole program
95 at linktime. Their analysis stage is performed early to
96 both reduce linking times and linktime memory usage by
97 not having to represent whole program in memory.
99 d) LTO sreaming. When doing LTO, everything important gets
100 streamed into the object file.
102 Compile time and or linktime analysis stage (WPA):
104 At linktime units gets streamed back and symbol table is
105 merged. Function bodies are not streamed in and not
107 e) IP propagation stage. All IP passes execute their
108 IP propagation. This is done based on the earlier analysis
109 without having function bodies at hand.
110 f) Ltrans streaming. When doing WHOPR LTO, the program
111 is partitioned and streamed into multple object files.
113 Compile time and/or parallel linktime stage (ltrans)
115 Each of the object files is streamed back and compiled
116 separately. Now the function bodies becomes available
119 2) Virtual clone materialization
120 (cgraph_materialize_clone)
122 IP passes can produce copies of existing functoins (such
123 as versioned clones or inline clones) without actually
124 manipulating their bodies by creating virtual clones in
125 the callgraph. At this time the virtual clones are
126 turned into real functions
129 All IP passes transform function bodies based on earlier
130 decision of the IP propagation.
132 4) late small IP passes
134 Simple IP passes working within single program partition.
137 (expand_all_functions)
139 At this stage functions that needs to be output into
140 assembler are identified and compiled in topological order
141 6) Output of variables and aliases
142 Now it is known what variable references was not optimized
143 out and thus all variables are output to the file.
145 Note that with -fno-toplevel-reorder passes 5 and 6
146 are combined together in cgraph_output_in_order.
148 Finally there are functions to manipulate the callgraph from
150 - cgraph_add_new_function is used to add backend produced
151 functions introduced after the unit is finalized.
152 The functions are enqueue for later processing and inserted
153 into callgraph with cgraph_process_new_functions.
155 - cgraph_function_versioning
157 produces a copy of function into new one (a version)
158 and apply simple transformations
163 #include "coretypes.h"
168 #include "tree-flow.h"
169 #include "tree-inline.h"
170 #include "langhooks.h"
171 #include "pointer-set.h"
178 #include "diagnostic.h"
182 #include "function.h"
183 #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"
196 #include "regset.h" /* FIXME: For reg_obstack. */
198 /* Queue of cgraph nodes scheduled to be added into cgraph. This is a
199 secondary queue used during optimization to accommodate passes that
200 may generate new functions that need to be optimized and expanded. */
201 cgraph_node_set cgraph_new_nodes
;
203 static void expand_all_functions (void);
204 static void mark_functions_to_output (void);
205 static void expand_function (struct cgraph_node
*);
206 static void cgraph_analyze_function (struct cgraph_node
*);
207 static void handle_alias_pairs (void);
209 FILE *cgraph_dump_file
;
211 /* Linked list of cgraph asm nodes. */
212 struct asm_node
*asm_nodes
;
214 /* Last node in cgraph_asm_nodes. */
215 static GTY(()) struct asm_node
*asm_last_node
;
217 /* Used for vtable lookup in thunk adjusting. */
218 static GTY (()) tree vtable_entry_type
;
220 /* Determine if function DECL is trivially needed and should stay in the
221 compilation unit. This is used at the symbol table construction time
222 and differs from later logic removing unnecessary functions that can
223 take into account results of analysis, whole program info etc. */
226 cgraph_decide_is_function_needed (struct cgraph_node
*node
, tree decl
)
228 /* If the user told us it is used, then it must be so. */
229 if (node
->symbol
.force_output
)
232 /* Double check that no one output the function into assembly file
234 gcc_checking_assert (!DECL_ASSEMBLER_NAME_SET_P (decl
)
235 || (node
->thunk
.thunk_p
|| node
->same_body_alias
)
236 || !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl
)));
239 /* Keep constructors, destructors and virtual functions. */
240 if (DECL_STATIC_CONSTRUCTOR (decl
)
241 || DECL_STATIC_DESTRUCTOR (decl
)
242 || (DECL_VIRTUAL_P (decl
)
243 && optimize
&& (DECL_COMDAT (decl
) || DECL_EXTERNAL (decl
))))
246 /* Externally visible functions must be output. The exception is
247 COMDAT functions that must be output only when they are needed. */
249 if (TREE_PUBLIC (decl
)
250 && !DECL_COMDAT (decl
) && !DECL_EXTERNAL (decl
))
256 /* Head of the queue of nodes to be processed while building callgraph */
258 static symtab_node first
= (symtab_node
)(void *)1;
260 /* Add NODE to queue starting at FIRST.
261 The queue is linked via AUX pointers and terminated by pointer to 1. */
264 enqueue_node (symtab_node node
)
266 if (node
->symbol
.aux
)
268 gcc_checking_assert (first
);
269 node
->symbol
.aux
= first
;
273 /* Process CGRAPH_NEW_FUNCTIONS and perform actions necessary to add these
274 functions into callgraph in a way so they look like ordinary reachable
275 functions inserted into callgraph already at construction time. */
278 cgraph_process_new_functions (void)
282 struct cgraph_node
*node
;
283 cgraph_node_set_iterator csi
;
285 if (!cgraph_new_nodes
)
287 handle_alias_pairs ();
288 /* Note that this queue may grow as its being processed, as the new
289 functions may generate new ones. */
290 for (csi
= csi_start (cgraph_new_nodes
); !csi_end_p (csi
); csi_next (&csi
))
292 node
= csi_node (csi
);
293 fndecl
= node
->symbol
.decl
;
294 switch (cgraph_state
)
296 case CGRAPH_STATE_CONSTRUCTION
:
297 /* At construction time we just need to finalize function and move
298 it into reachable functions list. */
300 cgraph_finalize_function (fndecl
, false);
302 cgraph_call_function_insertion_hooks (node
);
303 enqueue_node ((symtab_node
) node
);
306 case CGRAPH_STATE_IPA
:
307 case CGRAPH_STATE_IPA_SSA
:
308 /* When IPA optimization already started, do all essential
309 transformations that has been already performed on the whole
310 cgraph but not on this function. */
312 gimple_register_cfg_hooks ();
314 cgraph_analyze_function (node
);
315 push_cfun (DECL_STRUCT_FUNCTION (fndecl
));
316 if ((cgraph_state
== CGRAPH_STATE_IPA_SSA
317 && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl
)))
318 /* When not optimizing, be sure we run early local passes anyway
321 execute_pass_list (pass_early_local_passes
.pass
.sub
);
323 compute_inline_parameters (node
, true);
324 free_dominance_info (CDI_POST_DOMINATORS
);
325 free_dominance_info (CDI_DOMINATORS
);
327 cgraph_call_function_insertion_hooks (node
);
330 case CGRAPH_STATE_EXPANSION
:
331 /* Functions created during expansion shall be compiled
334 cgraph_call_function_insertion_hooks (node
);
335 expand_function (node
);
343 free_cgraph_node_set (cgraph_new_nodes
);
344 cgraph_new_nodes
= NULL
;
348 /* As an GCC extension we allow redefinition of the function. The
349 semantics when both copies of bodies differ is not well defined.
350 We replace the old body with new body so in unit at a time mode
351 we always use new body, while in normal mode we may end up with
352 old body inlined into some functions and new body expanded and
355 ??? It may make more sense to use one body for inlining and other
356 body for expanding the function but this is difficult to do. */
359 cgraph_reset_node (struct cgraph_node
*node
)
361 /* If node->process is set, then we have already begun whole-unit analysis.
362 This is *not* testing for whether we've already emitted the function.
363 That case can be sort-of legitimately seen with real function redefinition
364 errors. I would argue that the front end should never present us with
365 such a case, but don't enforce that for now. */
366 gcc_assert (!node
->process
);
368 /* Reset our data structures so we can analyze the function again. */
369 memset (&node
->local
, 0, sizeof (node
->local
));
370 memset (&node
->global
, 0, sizeof (node
->global
));
371 memset (&node
->rtl
, 0, sizeof (node
->rtl
));
372 node
->analyzed
= false;
373 node
->local
.finalized
= false;
375 cgraph_node_remove_callees (node
);
378 /* Return true when there are references to NODE. */
381 referred_to_p (symtab_node node
)
385 /* See if there are any references at all. */
386 if (ipa_ref_list_referring_iterate (&node
->symbol
.ref_list
, 0, ref
))
388 /* For functions check also calls. */
389 cgraph_node
*cn
= dyn_cast
<cgraph_node
> (node
);
390 if (cn
&& cn
->callers
)
395 /* DECL has been parsed. Take it, queue it, compile it at the whim of the
396 logic in effect. If NESTED is true, then our caller cannot stand to have
397 the garbage collector run at the moment. We would need to either create
398 a new GC context, or just not compile right now. */
401 cgraph_finalize_function (tree decl
, bool nested
)
403 struct cgraph_node
*node
= cgraph_get_create_node (decl
);
405 if (node
->local
.finalized
)
407 cgraph_reset_node (node
);
408 node
->local
.redefined_extern_inline
= true;
411 notice_global_symbol (decl
);
412 node
->local
.finalized
= true;
413 node
->lowered
= DECL_STRUCT_FUNCTION (decl
)->cfg
!= NULL
;
415 /* With -fkeep-inline-functions we are keeping all inline functions except
416 for extern inline ones. */
417 if (flag_keep_inline_functions
418 && DECL_DECLARED_INLINE_P (decl
)
419 && !DECL_EXTERNAL (decl
)
420 && !DECL_DISREGARD_INLINE_LIMITS (decl
))
421 node
->symbol
.force_output
= 1;
423 /* When not optimizing, also output the static functions. (see
424 PR24561), but don't do so for always_inline functions, functions
425 declared inline and nested functions. These were optimized out
426 in the original implementation and it is unclear whether we want
427 to change the behavior here. */
429 && !node
->same_body_alias
430 && !DECL_DISREGARD_INLINE_LIMITS (decl
)
431 && !DECL_DECLARED_INLINE_P (decl
)
432 && !(DECL_CONTEXT (decl
)
433 && TREE_CODE (DECL_CONTEXT (decl
)) == FUNCTION_DECL
))
434 && !DECL_COMDAT (decl
) && !DECL_EXTERNAL (decl
))
435 node
->symbol
.force_output
= 1;
437 /* If we've not yet emitted decl, tell the debug info about it. */
438 if (!TREE_ASM_WRITTEN (decl
))
439 (*debug_hooks
->deferred_inline_function
) (decl
);
441 /* Possibly warn about unused parameters. */
442 if (warn_unused_parameter
)
443 do_warn_unused_parameter (decl
);
448 if (cgraph_state
== CGRAPH_STATE_CONSTRUCTION
449 && (cgraph_decide_is_function_needed (node
, decl
)
450 || referred_to_p ((symtab_node
)node
)))
451 enqueue_node ((symtab_node
)node
);
454 /* Add the function FNDECL to the call graph.
455 Unlike cgraph_finalize_function, this function is intended to be used
456 by middle end and allows insertion of new function at arbitrary point
457 of compilation. The function can be either in high, low or SSA form
460 The function is assumed to be reachable and have address taken (so no
461 API breaking optimizations are performed on it).
463 Main work done by this function is to enqueue the function for later
464 processing to avoid need the passes to be re-entrant. */
467 cgraph_add_new_function (tree fndecl
, bool lowered
)
469 struct cgraph_node
*node
;
470 switch (cgraph_state
)
472 case CGRAPH_STATE_PARSING
:
473 cgraph_finalize_function (fndecl
, false);
475 case CGRAPH_STATE_CONSTRUCTION
:
476 /* Just enqueue function to be processed at nearest occurrence. */
477 node
= cgraph_create_node (fndecl
);
479 node
->lowered
= true;
480 if (!cgraph_new_nodes
)
481 cgraph_new_nodes
= cgraph_node_set_new ();
482 cgraph_node_set_add (cgraph_new_nodes
, node
);
485 case CGRAPH_STATE_IPA
:
486 case CGRAPH_STATE_IPA_SSA
:
487 case CGRAPH_STATE_EXPANSION
:
488 /* Bring the function into finalized state and enqueue for later
489 analyzing and compilation. */
490 node
= cgraph_get_create_node (fndecl
);
491 node
->local
.local
= false;
492 node
->local
.finalized
= true;
493 node
->symbol
.force_output
= true;
494 if (!lowered
&& cgraph_state
== CGRAPH_STATE_EXPANSION
)
496 push_cfun (DECL_STRUCT_FUNCTION (fndecl
));
497 gimple_register_cfg_hooks ();
498 bitmap_obstack_initialize (NULL
);
499 execute_pass_list (all_lowering_passes
);
500 execute_pass_list (pass_early_local_passes
.pass
.sub
);
501 bitmap_obstack_release (NULL
);
507 node
->lowered
= true;
508 if (!cgraph_new_nodes
)
509 cgraph_new_nodes
= cgraph_node_set_new ();
510 cgraph_node_set_add (cgraph_new_nodes
, node
);
513 case CGRAPH_STATE_FINISHED
:
514 /* At the very end of compilation we have to do all the work up
516 node
= cgraph_create_node (fndecl
);
518 node
->lowered
= true;
519 cgraph_analyze_function (node
);
520 push_cfun (DECL_STRUCT_FUNCTION (fndecl
));
521 gimple_register_cfg_hooks ();
522 bitmap_obstack_initialize (NULL
);
523 if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl
)))
524 execute_pass_list (pass_early_local_passes
.pass
.sub
);
525 bitmap_obstack_release (NULL
);
527 expand_function (node
);
534 /* Set a personality if required and we already passed EH lowering. */
536 && (function_needs_eh_personality (DECL_STRUCT_FUNCTION (fndecl
))
537 == eh_personality_lang
))
538 DECL_FUNCTION_PERSONALITY (fndecl
) = lang_hooks
.eh_personality ();
541 /* Add a top-level asm statement to the list. */
544 add_asm_node (tree asm_str
)
546 struct asm_node
*node
;
548 node
= ggc_alloc_cleared_asm_node ();
549 node
->asm_str
= asm_str
;
550 node
->order
= symtab_order
++;
552 if (asm_nodes
== NULL
)
555 asm_last_node
->next
= node
;
556 asm_last_node
= node
;
560 /* Output all asm statements we have stored up to be output. */
563 output_asm_statements (void)
565 struct asm_node
*can
;
570 for (can
= asm_nodes
; can
; can
= can
->next
)
571 assemble_asm (can
->asm_str
);
575 /* C++ FE sometimes change linkage flags after producing same body aliases. */
577 fixup_same_cpp_alias_visibility (symtab_node node
, symtab_node target
, tree alias
)
579 DECL_VIRTUAL_P (node
->symbol
.decl
) = DECL_VIRTUAL_P (alias
);
580 if (TREE_PUBLIC (node
->symbol
.decl
))
582 DECL_EXTERNAL (node
->symbol
.decl
) = DECL_EXTERNAL (alias
);
583 DECL_COMDAT (node
->symbol
.decl
) = DECL_COMDAT (alias
);
584 DECL_COMDAT_GROUP (node
->symbol
.decl
) = DECL_COMDAT_GROUP (alias
);
585 if (DECL_ONE_ONLY (alias
)
586 && !node
->symbol
.same_comdat_group
)
587 symtab_add_to_same_comdat_group ((symtab_node
)node
, (symtab_node
)target
);
591 /* Analyze the function scheduled to be output. */
593 cgraph_analyze_function (struct cgraph_node
*node
)
595 tree decl
= node
->symbol
.decl
;
596 location_t saved_loc
= input_location
;
597 input_location
= DECL_SOURCE_LOCATION (decl
);
599 if (node
->alias
&& node
->thunk
.alias
)
601 struct cgraph_node
*tgt
= cgraph_get_node (node
->thunk
.alias
);
602 struct cgraph_node
*n
;
604 for (n
= tgt
; n
&& n
->alias
;
605 n
= n
->analyzed
? cgraph_alias_aliased_node (n
) : NULL
)
608 error ("function %q+D part of alias cycle", node
->symbol
.decl
);
610 input_location
= saved_loc
;
613 if (!VEC_length (ipa_ref_t
, node
->symbol
.ref_list
.references
))
614 ipa_record_reference ((symtab_node
)node
, (symtab_node
)tgt
,
615 IPA_REF_ALIAS
, NULL
);
616 if (node
->same_body_alias
)
618 DECL_DECLARED_INLINE_P (node
->symbol
.decl
)
619 = DECL_DECLARED_INLINE_P (node
->thunk
.alias
);
620 DECL_DISREGARD_INLINE_LIMITS (node
->symbol
.decl
)
621 = DECL_DISREGARD_INLINE_LIMITS (node
->thunk
.alias
);
622 fixup_same_cpp_alias_visibility ((symtab_node
) node
, (symtab_node
) tgt
, node
->thunk
.alias
);
625 if (node
->symbol
.address_taken
)
626 cgraph_mark_address_taken_node (cgraph_alias_aliased_node (node
));
628 else if (node
->thunk
.thunk_p
)
630 cgraph_create_edge (node
, cgraph_get_node (node
->thunk
.alias
),
631 NULL
, 0, CGRAPH_FREQ_BASE
);
635 push_cfun (DECL_STRUCT_FUNCTION (decl
));
637 assign_assembler_name_if_neeeded (node
->symbol
.decl
);
639 /* Make sure to gimplify bodies only once. During analyzing a
640 function we lower it, which will require gimplified nested
641 functions, so we can end up here with an already gimplified
643 if (!gimple_has_body_p (decl
))
644 gimplify_function_tree (decl
);
645 dump_function (TDI_generic
, decl
);
647 /* Lower the function. */
651 lower_nested_functions (node
->symbol
.decl
);
652 gcc_assert (!node
->nested
);
654 gimple_register_cfg_hooks ();
655 bitmap_obstack_initialize (NULL
);
656 execute_pass_list (all_lowering_passes
);
657 free_dominance_info (CDI_POST_DOMINATORS
);
658 free_dominance_info (CDI_DOMINATORS
);
660 bitmap_obstack_release (NULL
);
661 node
->lowered
= true;
666 node
->analyzed
= true;
668 input_location
= saved_loc
;
671 /* C++ frontend produce same body aliases all over the place, even before PCH
672 gets streamed out. It relies on us linking the aliases with their function
673 in order to do the fixups, but ipa-ref is not PCH safe. Consequentely we
674 first produce aliases without links, but once C++ FE is sure he won't sream
675 PCH we build the links via this function. */
678 cgraph_process_same_body_aliases (void)
680 struct cgraph_node
*node
;
681 FOR_EACH_FUNCTION (node
)
682 if (node
->same_body_alias
683 && !VEC_length (ipa_ref_t
, node
->symbol
.ref_list
.references
))
685 struct cgraph_node
*tgt
= cgraph_get_node (node
->thunk
.alias
);
686 ipa_record_reference ((symtab_node
)node
, (symtab_node
)tgt
,
687 IPA_REF_ALIAS
, NULL
);
689 same_body_aliases_done
= true;
692 /* Process attributes common for vars and functions. */
695 process_common_attributes (tree decl
)
697 tree weakref
= lookup_attribute ("weakref", DECL_ATTRIBUTES (decl
));
699 if (weakref
&& !lookup_attribute ("alias", DECL_ATTRIBUTES (decl
)))
701 warning_at (DECL_SOURCE_LOCATION (decl
), OPT_Wattributes
,
702 "%<weakref%> attribute should be accompanied with"
703 " an %<alias%> attribute");
704 DECL_WEAK (decl
) = 0;
705 DECL_ATTRIBUTES (decl
) = remove_attribute ("weakref",
706 DECL_ATTRIBUTES (decl
));
710 /* Look for externally_visible and used attributes and mark cgraph nodes
713 We cannot mark the nodes at the point the attributes are processed (in
714 handle_*_attribute) because the copy of the declarations available at that
715 point may not be canonical. For example, in:
718 void f() __attribute__((used));
720 the declaration we see in handle_used_attribute will be the second
721 declaration -- but the front end will subsequently merge that declaration
722 with the original declaration and discard the second declaration.
724 Furthermore, we can't mark these nodes in cgraph_finalize_function because:
727 void f() __attribute__((externally_visible));
731 So, we walk the nodes at the end of the translation unit, applying the
732 attributes at that point. */
735 process_function_and_variable_attributes (struct cgraph_node
*first
,
736 struct varpool_node
*first_var
)
738 struct cgraph_node
*node
;
739 struct varpool_node
*vnode
;
741 for (node
= cgraph_first_function (); node
!= first
;
742 node
= cgraph_next_function (node
))
744 tree decl
= node
->symbol
.decl
;
745 if (DECL_PRESERVE_P (decl
))
746 cgraph_mark_force_output_node (node
);
747 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl
)))
749 if (! TREE_PUBLIC (node
->symbol
.decl
))
750 warning_at (DECL_SOURCE_LOCATION (node
->symbol
.decl
), OPT_Wattributes
,
751 "%<externally_visible%>"
752 " attribute have effect only on public objects");
754 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl
))
755 && (node
->local
.finalized
&& !node
->alias
))
757 warning_at (DECL_SOURCE_LOCATION (node
->symbol
.decl
), OPT_Wattributes
,
758 "%<weakref%> attribute ignored"
759 " because function is defined");
760 DECL_WEAK (decl
) = 0;
761 DECL_ATTRIBUTES (decl
) = remove_attribute ("weakref",
762 DECL_ATTRIBUTES (decl
));
765 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl
))
766 && !DECL_DECLARED_INLINE_P (decl
)
767 /* redefining extern inline function makes it DECL_UNINLINABLE. */
768 && !DECL_UNINLINABLE (decl
))
769 warning_at (DECL_SOURCE_LOCATION (decl
), OPT_Wattributes
,
770 "always_inline function might not be inlinable");
772 process_common_attributes (decl
);
774 for (vnode
= varpool_first_variable (); vnode
!= first_var
;
775 vnode
= varpool_next_variable (vnode
))
777 tree decl
= vnode
->symbol
.decl
;
778 if (DECL_EXTERNAL (decl
)
779 && DECL_INITIAL (decl
)
780 && const_value_known_p (decl
))
781 varpool_finalize_decl (decl
);
782 if (DECL_PRESERVE_P (decl
))
783 vnode
->symbol
.force_output
= true;
784 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl
)))
786 if (! TREE_PUBLIC (vnode
->symbol
.decl
))
787 warning_at (DECL_SOURCE_LOCATION (vnode
->symbol
.decl
), OPT_Wattributes
,
788 "%<externally_visible%>"
789 " attribute have effect only on public objects");
791 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl
))
793 && DECL_INITIAL (decl
))
795 warning_at (DECL_SOURCE_LOCATION (vnode
->symbol
.decl
), OPT_Wattributes
,
796 "%<weakref%> attribute ignored"
797 " because variable is initialized");
798 DECL_WEAK (decl
) = 0;
799 DECL_ATTRIBUTES (decl
) = remove_attribute ("weakref",
800 DECL_ATTRIBUTES (decl
));
802 process_common_attributes (decl
);
806 /* Mark DECL as finalized. By finalizing the declaration, frontend instruct the
807 middle end to output the variable to asm file, if needed or externally
811 varpool_finalize_decl (tree decl
)
813 struct varpool_node
*node
= varpool_node_for_decl (decl
);
815 gcc_assert (TREE_STATIC (decl
) || DECL_EXTERNAL (decl
));
819 notice_global_symbol (decl
);
820 node
->finalized
= true;
821 if (TREE_THIS_VOLATILE (decl
) || DECL_PRESERVE_P (decl
)
822 /* Traditionally we do not eliminate static variables when not
823 optimizing and when not doing toplevel reoder. */
824 || (!flag_toplevel_reorder
&& !DECL_COMDAT (node
->symbol
.decl
)
825 && !DECL_ARTIFICIAL (node
->symbol
.decl
)))
826 node
->symbol
.force_output
= true;
828 if (cgraph_state
== CGRAPH_STATE_CONSTRUCTION
829 && (decide_is_variable_needed (node
, decl
)
830 || referred_to_p ((symtab_node
)node
)))
831 enqueue_node ((symtab_node
)node
);
832 if (cgraph_state
>= CGRAPH_STATE_IPA_SSA
)
833 varpool_analyze_node (node
);
834 /* Some frontends produce various interface variables after compilation
836 if (cgraph_state
== CGRAPH_STATE_FINISHED
)
837 varpool_assemble_decl (node
);
841 /* Determine if a symbol NODE is finalized and needed. */
844 symbol_finalized_and_needed (symtab_node node
)
846 if (cgraph_node
*cnode
= dyn_cast
<cgraph_node
> (node
))
847 return cnode
->local
.finalized
848 && cgraph_decide_is_function_needed (cnode
, cnode
->symbol
.decl
);
849 if (varpool_node
*vnode
= dyn_cast
<varpool_node
> (node
))
850 return vnode
->finalized
851 && !DECL_EXTERNAL (vnode
->symbol
.decl
)
852 && decide_is_variable_needed (vnode
, vnode
->symbol
.decl
);
856 /* Determine if a symbol NODE is finalized. */
859 symbol_finalized (symtab_node node
)
861 if (cgraph_node
*cnode
= dyn_cast
<cgraph_node
> (node
))
862 return cnode
->local
.finalized
;
863 if (varpool_node
*vnode
= dyn_cast
<varpool_node
> (node
))
864 return vnode
->finalized
;
869 /* Discover all functions and variables that are trivially needed, analyze
870 them as well as all functions and variables referred by them */
873 cgraph_analyze_functions (void)
875 /* Keep track of already processed nodes when called multiple times for
876 intermodule optimization. */
877 static struct cgraph_node
*first_analyzed
;
878 struct cgraph_node
*first_handled
= first_analyzed
;
879 static struct varpool_node
*first_analyzed_var
;
880 struct varpool_node
*first_handled_var
= first_analyzed_var
;
882 symtab_node node
, next
;
887 bitmap_obstack_initialize (NULL
);
888 cgraph_state
= CGRAPH_STATE_CONSTRUCTION
;
890 /* Analysis adds static variables that in turn adds references to new functions.
891 So we need to iterate the process until it stabilize. */
895 process_function_and_variable_attributes (first_analyzed
,
898 /* First identify the trivially needed symbols. */
899 for (node
= symtab_nodes
;
900 node
!= (symtab_node
)first_analyzed
901 && node
!= (symtab_node
)first_analyzed_var
; node
= node
->symbol
.next
)
903 if (symbol_finalized_and_needed (node
))
906 if (!changed
&& cgraph_dump_file
)
907 fprintf (cgraph_dump_file
, "Trivially needed symbols:");
909 if (cgraph_dump_file
)
910 fprintf (cgraph_dump_file
, " %s", symtab_node_asm_name (node
));
912 if (node
== (symtab_node
)first_analyzed
913 || node
== (symtab_node
)first_analyzed_var
)
916 cgraph_process_new_functions ();
917 first_analyzed_var
= varpool_first_variable ();
918 first_analyzed
= cgraph_first_function ();
920 if (changed
&& dump_file
)
921 fprintf (cgraph_dump_file
, "\n");
923 /* Lower representation, build callgraph edges and references for all trivially
924 needed symbols and all symbols referred by them. */
925 while (first
!= (symtab_node
)(void *)1)
929 first
= (symtab_node
)first
->symbol
.aux
;
930 cgraph_node
*cnode
= dyn_cast
<cgraph_node
> (node
);
931 if (cnode
&& cnode
->local
.finalized
)
933 struct cgraph_edge
*edge
;
934 tree decl
= cnode
->symbol
.decl
;
936 /* ??? It is possible to create extern inline function
937 and later using weak alias attribute to kill its body.
938 See gcc.c-torture/compile/20011119-1.c */
939 if (!DECL_STRUCT_FUNCTION (decl
)
940 && (!cnode
->alias
|| !cnode
->thunk
.alias
)
941 && !cnode
->thunk
.thunk_p
)
943 cgraph_reset_node (cnode
);
944 cnode
->local
.redefined_extern_inline
= true;
948 if (!cnode
->analyzed
)
949 cgraph_analyze_function (cnode
);
951 for (edge
= cnode
->callees
; edge
; edge
= edge
->next_callee
)
952 if (edge
->callee
->local
.finalized
)
953 enqueue_node ((symtab_node
)edge
->callee
);
955 /* If decl is a clone of an abstract function,
956 mark that abstract function so that we don't release its body.
957 The DECL_INITIAL() of that abstract function declaration
958 will be later needed to output debug info. */
959 if (DECL_ABSTRACT_ORIGIN (decl
))
961 struct cgraph_node
*origin_node
962 = cgraph_get_node (DECL_ABSTRACT_ORIGIN (decl
));
963 origin_node
->abstract_and_needed
= true;
968 varpool_node
*vnode
= dyn_cast
<varpool_node
> (node
);
969 if (vnode
&& vnode
->finalized
)
970 varpool_analyze_node (vnode
);
973 if (node
->symbol
.same_comdat_group
)
976 for (next
= node
->symbol
.same_comdat_group
;
978 next
= next
->symbol
.same_comdat_group
)
981 for (i
= 0; ipa_ref_list_reference_iterate (&node
->symbol
.ref_list
, i
, ref
); i
++)
982 if (symbol_finalized (ref
->referred
))
983 enqueue_node (ref
->referred
);
984 cgraph_process_new_functions ();
988 /* Collect entry points to the unit. */
989 if (cgraph_dump_file
)
991 fprintf (cgraph_dump_file
, "\n\nInitial ");
992 dump_symtab (cgraph_dump_file
);
995 if (cgraph_dump_file
)
996 fprintf (cgraph_dump_file
, "\nRemoving unused symbols:");
998 for (node
= symtab_nodes
;
999 node
!= (symtab_node
)first_handled
1000 && node
!= (symtab_node
)first_handled_var
; node
= next
)
1002 next
= node
->symbol
.next
;
1003 if (!node
->symbol
.aux
&& !referred_to_p (node
))
1005 if (cgraph_dump_file
)
1006 fprintf (cgraph_dump_file
, " %s", symtab_node_name (node
));
1007 symtab_remove_node (node
);
1010 if (cgraph_node
*cnode
= dyn_cast
<cgraph_node
> (node
))
1012 tree decl
= node
->symbol
.decl
;
1014 if (cnode
->local
.finalized
&& !gimple_has_body_p (decl
)
1015 && (!cnode
->alias
|| !cnode
->thunk
.alias
)
1016 && !cnode
->thunk
.thunk_p
)
1017 cgraph_reset_node (cnode
);
1019 gcc_assert (!cnode
->local
.finalized
|| cnode
->thunk
.thunk_p
1021 || gimple_has_body_p (decl
));
1022 gcc_assert (cnode
->analyzed
== cnode
->local
.finalized
);
1024 node
->symbol
.aux
= NULL
;
1026 first_analyzed
= cgraph_first_function ();
1027 first_analyzed_var
= varpool_first_variable ();
1028 if (cgraph_dump_file
)
1030 fprintf (cgraph_dump_file
, "\n\nReclaimed ");
1031 dump_symtab (cgraph_dump_file
);
1033 bitmap_obstack_release (NULL
);
1037 /* Translate the ugly representation of aliases as alias pairs into nice
1038 representation in callgraph. We don't handle all cases yet,
1042 handle_alias_pairs (void)
1047 for (i
= 0; VEC_iterate (alias_pair
, alias_pairs
, i
, p
);)
1049 symtab_node target_node
= symtab_node_for_asm (p
->target
);
1051 /* Weakrefs with target not defined in current unit are easy to handle; they
1052 behave just as external variables except we need to note the alias flag
1053 to later output the weakref pseudo op into asm file. */
1054 if (!target_node
&& lookup_attribute ("weakref", DECL_ATTRIBUTES (p
->decl
)) != NULL
)
1056 if (TREE_CODE (p
->decl
) == FUNCTION_DECL
)
1057 cgraph_get_create_node (p
->decl
)->alias
= true;
1059 varpool_get_node (p
->decl
)->alias
= true;
1060 DECL_EXTERNAL (p
->decl
) = 1;
1061 VEC_unordered_remove (alias_pair
, alias_pairs
, i
);
1064 else if (!target_node
)
1066 error ("%q+D aliased to undefined symbol %qE", p
->decl
, p
->target
);
1067 VEC_unordered_remove (alias_pair
, alias_pairs
, i
);
1071 /* Normally EXTERNAL flag is used to mark external inlines,
1072 however for aliases it seems to be allowed to use it w/o
1073 any meaning. See gcc.dg/attr-alias-3.c
1074 However for weakref we insist on EXTERNAL flag being set.
1075 See gcc.dg/attr-alias-5.c */
1076 if (DECL_EXTERNAL (p
->decl
))
1077 DECL_EXTERNAL (p
->decl
)
1078 = lookup_attribute ("weakref",
1079 DECL_ATTRIBUTES (p
->decl
)) != NULL
;
1081 if (DECL_EXTERNAL (target_node
->symbol
.decl
)
1082 /* We use local aliases for C++ thunks to force the tailcall
1083 to bind locally. This is a hack - to keep it working do
1084 the following (which is not strictly correct). */
1085 && (! TREE_CODE (target_node
->symbol
.decl
) == FUNCTION_DECL
1086 || ! DECL_VIRTUAL_P (target_node
->symbol
.decl
))
1087 && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p
->decl
)))
1089 error ("%q+D aliased to external symbol %qE",
1090 p
->decl
, p
->target
);
1093 if (TREE_CODE (p
->decl
) == FUNCTION_DECL
1094 && target_node
&& is_a
<cgraph_node
> (target_node
))
1096 struct cgraph_node
*src_node
= cgraph_get_node (p
->decl
);
1097 if (src_node
&& src_node
->local
.finalized
)
1098 cgraph_reset_node (src_node
);
1099 cgraph_create_function_alias (p
->decl
, target_node
->symbol
.decl
);
1100 VEC_unordered_remove (alias_pair
, alias_pairs
, i
);
1102 else if (TREE_CODE (p
->decl
) == VAR_DECL
1103 && target_node
&& is_a
<varpool_node
> (target_node
))
1105 varpool_create_variable_alias (p
->decl
, target_node
->symbol
.decl
);
1106 VEC_unordered_remove (alias_pair
, alias_pairs
, i
);
1110 error ("%q+D alias in between function and variable is not supported",
1112 warning (0, "%q+D aliased declaration",
1113 target_node
->symbol
.decl
);
1114 VEC_unordered_remove (alias_pair
, alias_pairs
, i
);
1117 VEC_free (alias_pair
, gc
, alias_pairs
);
1121 /* Figure out what functions we want to assemble. */
1124 mark_functions_to_output (void)
1126 struct cgraph_node
*node
;
1127 #ifdef ENABLE_CHECKING
1128 bool check_same_comdat_groups
= false;
1130 FOR_EACH_FUNCTION (node
)
1131 gcc_assert (!node
->process
);
1134 FOR_EACH_FUNCTION (node
)
1136 tree decl
= node
->symbol
.decl
;
1138 gcc_assert (!node
->process
|| node
->symbol
.same_comdat_group
);
1142 /* We need to output all local functions that are used and not
1143 always inlined, as well as those that are reachable from
1144 outside the current compilation unit. */
1146 && !node
->thunk
.thunk_p
1148 && !node
->global
.inlined_to
1149 && !TREE_ASM_WRITTEN (decl
)
1150 && !DECL_EXTERNAL (decl
))
1153 if (node
->symbol
.same_comdat_group
)
1155 struct cgraph_node
*next
;
1156 for (next
= cgraph (node
->symbol
.same_comdat_group
);
1158 next
= cgraph (next
->symbol
.same_comdat_group
))
1159 if (!next
->thunk
.thunk_p
&& !next
->alias
)
1163 else if (node
->symbol
.same_comdat_group
)
1165 #ifdef ENABLE_CHECKING
1166 check_same_comdat_groups
= true;
1171 /* We should've reclaimed all functions that are not needed. */
1172 #ifdef ENABLE_CHECKING
1173 if (!node
->global
.inlined_to
1174 && gimple_has_body_p (decl
)
1175 /* FIXME: in ltrans unit when offline copy is outside partition but inline copies
1176 are inside partition, we can end up not removing the body since we no longer
1177 have analyzed node pointing to it. */
1178 && !node
->symbol
.in_other_partition
1181 && !DECL_EXTERNAL (decl
))
1183 dump_cgraph_node (stderr
, node
);
1184 internal_error ("failed to reclaim unneeded function");
1187 gcc_assert (node
->global
.inlined_to
1188 || !gimple_has_body_p (decl
)
1189 || node
->symbol
.in_other_partition
1191 || DECL_ARTIFICIAL (decl
)
1192 || DECL_EXTERNAL (decl
));
1197 #ifdef ENABLE_CHECKING
1198 if (check_same_comdat_groups
)
1199 FOR_EACH_FUNCTION (node
)
1200 if (node
->symbol
.same_comdat_group
&& !node
->process
)
1202 tree decl
= node
->symbol
.decl
;
1203 if (!node
->global
.inlined_to
1204 && gimple_has_body_p (decl
)
1205 /* FIXME: in an ltrans unit when the offline copy is outside a
1206 partition but inline copies are inside a partition, we can
1207 end up not removing the body since we no longer have an
1208 analyzed node pointing to it. */
1209 && !node
->symbol
.in_other_partition
1211 && !DECL_EXTERNAL (decl
))
1213 dump_cgraph_node (stderr
, node
);
1214 internal_error ("failed to reclaim unneeded function in same "
1221 /* DECL is FUNCTION_DECL. Initialize datastructures so DECL is a function
1222 in lowered gimple form.
1224 Set current_function_decl and cfun to newly constructed empty function body.
1225 return basic block in the function body. */
1228 init_lowered_empty_function (tree decl
)
1232 current_function_decl
= decl
;
1233 allocate_struct_function (decl
, false);
1234 gimple_register_cfg_hooks ();
1235 init_empty_tree_cfg ();
1236 init_tree_ssa (cfun
);
1237 init_ssa_operands (cfun
);
1238 cfun
->gimple_df
->in_ssa_p
= true;
1239 DECL_INITIAL (decl
) = make_node (BLOCK
);
1241 DECL_SAVED_TREE (decl
) = error_mark_node
;
1242 cfun
->curr_properties
|=
1243 (PROP_gimple_lcf
| PROP_gimple_leh
| PROP_cfg
| PROP_ssa
| PROP_gimple_any
);
1245 /* Create BB for body of the function and connect it properly. */
1246 bb
= create_basic_block (NULL
, (void *) 0, ENTRY_BLOCK_PTR
);
1247 make_edge (ENTRY_BLOCK_PTR
, bb
, 0);
1248 make_edge (bb
, EXIT_BLOCK_PTR
, 0);
1253 /* Adjust PTR by the constant FIXED_OFFSET, and by the vtable
1254 offset indicated by VIRTUAL_OFFSET, if that is
1255 non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and
1256 zero for a result adjusting thunk. */
1259 thunk_adjust (gimple_stmt_iterator
* bsi
,
1260 tree ptr
, bool this_adjusting
,
1261 HOST_WIDE_INT fixed_offset
, tree virtual_offset
)
1267 && fixed_offset
!= 0)
1269 stmt
= gimple_build_assign
1270 (ptr
, fold_build_pointer_plus_hwi_loc (input_location
,
1273 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1276 /* If there's a virtual offset, look up that value in the vtable and
1277 adjust the pointer again. */
1284 if (!vtable_entry_type
)
1286 tree vfunc_type
= make_node (FUNCTION_TYPE
);
1287 TREE_TYPE (vfunc_type
) = integer_type_node
;
1288 TYPE_ARG_TYPES (vfunc_type
) = NULL_TREE
;
1289 layout_type (vfunc_type
);
1291 vtable_entry_type
= build_pointer_type (vfunc_type
);
1295 create_tmp_reg (build_pointer_type
1296 (build_pointer_type (vtable_entry_type
)), "vptr");
1298 /* The vptr is always at offset zero in the object. */
1299 stmt
= gimple_build_assign (vtabletmp
,
1300 build1 (NOP_EXPR
, TREE_TYPE (vtabletmp
),
1302 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1304 /* Form the vtable address. */
1305 vtabletmp2
= create_tmp_reg (TREE_TYPE (TREE_TYPE (vtabletmp
)),
1307 stmt
= gimple_build_assign (vtabletmp2
,
1308 build_simple_mem_ref (vtabletmp
));
1309 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1311 /* Find the entry with the vcall offset. */
1312 stmt
= gimple_build_assign (vtabletmp2
,
1313 fold_build_pointer_plus_loc (input_location
,
1316 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1318 /* Get the offset itself. */
1319 vtabletmp3
= create_tmp_reg (TREE_TYPE (TREE_TYPE (vtabletmp2
)),
1321 stmt
= gimple_build_assign (vtabletmp3
,
1322 build_simple_mem_ref (vtabletmp2
));
1323 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1325 /* Adjust the `this' pointer. */
1326 ptr
= fold_build_pointer_plus_loc (input_location
, ptr
, vtabletmp3
);
1327 ptr
= force_gimple_operand_gsi (bsi
, ptr
, true, NULL_TREE
, false,
1328 GSI_CONTINUE_LINKING
);
1332 && fixed_offset
!= 0)
1333 /* Adjust the pointer by the constant. */
1337 if (TREE_CODE (ptr
) == VAR_DECL
)
1341 ptrtmp
= create_tmp_reg (TREE_TYPE (ptr
), "ptr");
1342 stmt
= gimple_build_assign (ptrtmp
, ptr
);
1343 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1345 ptr
= fold_build_pointer_plus_hwi_loc (input_location
,
1346 ptrtmp
, fixed_offset
);
1349 /* Emit the statement and gimplify the adjustment expression. */
1350 ret
= create_tmp_reg (TREE_TYPE (ptr
), "adjusted_this");
1351 stmt
= gimple_build_assign (ret
, ptr
);
1352 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1357 /* Produce assembler for thunk NODE. */
1360 assemble_thunk (struct cgraph_node
*node
)
1362 bool this_adjusting
= node
->thunk
.this_adjusting
;
1363 HOST_WIDE_INT fixed_offset
= node
->thunk
.fixed_offset
;
1364 HOST_WIDE_INT virtual_value
= node
->thunk
.virtual_value
;
1365 tree virtual_offset
= NULL
;
1366 tree alias
= node
->thunk
.alias
;
1367 tree thunk_fndecl
= node
->symbol
.decl
;
1368 tree a
= DECL_ARGUMENTS (thunk_fndecl
);
1370 current_function_decl
= thunk_fndecl
;
1372 /* Ensure thunks are emitted in their correct sections. */
1373 resolve_unique_section (thunk_fndecl
, 0, flag_function_sections
);
1376 && targetm
.asm_out
.can_output_mi_thunk (thunk_fndecl
, fixed_offset
,
1377 virtual_value
, alias
))
1381 tree restype
= TREE_TYPE (TREE_TYPE (thunk_fndecl
));
1383 DECL_RESULT (thunk_fndecl
)
1384 = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl
),
1385 RESULT_DECL
, 0, restype
);
1386 fnname
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl
));
1388 /* The back end expects DECL_INITIAL to contain a BLOCK, so we
1390 fn_block
= make_node (BLOCK
);
1391 BLOCK_VARS (fn_block
) = a
;
1392 DECL_INITIAL (thunk_fndecl
) = fn_block
;
1393 init_function_start (thunk_fndecl
);
1395 assemble_start_function (thunk_fndecl
, fnname
);
1396 (*debug_hooks
->source_line
) (DECL_SOURCE_LINE (thunk_fndecl
),
1397 DECL_SOURCE_FILE (thunk_fndecl
),
1398 /* discriminator */ 0,
1401 targetm
.asm_out
.output_mi_thunk (asm_out_file
, thunk_fndecl
,
1402 fixed_offset
, virtual_value
, alias
);
1404 assemble_end_function (thunk_fndecl
, fnname
);
1405 init_insn_lengths ();
1406 free_after_compilation (cfun
);
1408 TREE_ASM_WRITTEN (thunk_fndecl
) = 1;
1409 node
->thunk
.thunk_p
= false;
1410 node
->analyzed
= false;
1415 basic_block bb
, then_bb
, else_bb
, return_bb
;
1416 gimple_stmt_iterator bsi
;
1422 VEC(tree
, heap
) *vargs
;
1427 DECL_IGNORED_P (thunk_fndecl
) = 1;
1428 bitmap_obstack_initialize (NULL
);
1430 if (node
->thunk
.virtual_offset_p
)
1431 virtual_offset
= size_int (virtual_value
);
1433 /* Build the return declaration for the function. */
1434 restype
= TREE_TYPE (TREE_TYPE (thunk_fndecl
));
1435 if (DECL_RESULT (thunk_fndecl
) == NULL_TREE
)
1437 resdecl
= build_decl (input_location
, RESULT_DECL
, 0, restype
);
1438 DECL_ARTIFICIAL (resdecl
) = 1;
1439 DECL_IGNORED_P (resdecl
) = 1;
1440 DECL_RESULT (thunk_fndecl
) = resdecl
;
1443 resdecl
= DECL_RESULT (thunk_fndecl
);
1445 bb
= then_bb
= else_bb
= return_bb
= init_lowered_empty_function (thunk_fndecl
);
1447 bsi
= gsi_start_bb (bb
);
1449 /* Build call to the function being thunked. */
1450 if (!VOID_TYPE_P (restype
))
1452 if (!is_gimple_reg_type (restype
))
1455 add_local_decl (cfun
, restmp
);
1456 BLOCK_VARS (DECL_INITIAL (current_function_decl
)) = restmp
;
1459 restmp
= create_tmp_reg (restype
, "retval");
1462 for (arg
= a
; arg
; arg
= DECL_CHAIN (arg
))
1464 vargs
= VEC_alloc (tree
, heap
, nargs
);
1466 VEC_quick_push (tree
, vargs
,
1471 VEC_quick_push (tree
, vargs
, a
);
1472 for (i
= 1, arg
= DECL_CHAIN (a
); i
< nargs
; i
++, arg
= DECL_CHAIN (arg
))
1473 VEC_quick_push (tree
, vargs
, arg
);
1474 call
= gimple_build_call_vec (build_fold_addr_expr_loc (0, alias
), vargs
);
1475 VEC_free (tree
, heap
, vargs
);
1476 gimple_call_set_from_thunk (call
, true);
1478 gimple_call_set_lhs (call
, restmp
);
1479 gsi_insert_after (&bsi
, call
, GSI_NEW_STMT
);
1481 if (restmp
&& !this_adjusting
)
1483 tree true_label
= NULL_TREE
;
1485 if (TREE_CODE (TREE_TYPE (restmp
)) == POINTER_TYPE
)
1488 /* If the return type is a pointer, we need to
1489 protect against NULL. We know there will be an
1490 adjustment, because that's why we're emitting a
1492 then_bb
= create_basic_block (NULL
, (void *) 0, bb
);
1493 return_bb
= create_basic_block (NULL
, (void *) 0, then_bb
);
1494 else_bb
= create_basic_block (NULL
, (void *) 0, else_bb
);
1495 remove_edge (single_succ_edge (bb
));
1496 true_label
= gimple_block_label (then_bb
);
1497 stmt
= gimple_build_cond (NE_EXPR
, restmp
,
1498 build_zero_cst (TREE_TYPE (restmp
)),
1499 NULL_TREE
, NULL_TREE
);
1500 gsi_insert_after (&bsi
, stmt
, GSI_NEW_STMT
);
1501 make_edge (bb
, then_bb
, EDGE_TRUE_VALUE
);
1502 make_edge (bb
, else_bb
, EDGE_FALSE_VALUE
);
1503 make_edge (return_bb
, EXIT_BLOCK_PTR
, 0);
1504 make_edge (then_bb
, return_bb
, EDGE_FALLTHRU
);
1505 make_edge (else_bb
, return_bb
, EDGE_FALLTHRU
);
1506 bsi
= gsi_last_bb (then_bb
);
1509 restmp
= thunk_adjust (&bsi
, restmp
, /*this_adjusting=*/0,
1510 fixed_offset
, virtual_offset
);
1514 bsi
= gsi_last_bb (else_bb
);
1515 stmt
= gimple_build_assign (restmp
,
1516 build_zero_cst (TREE_TYPE (restmp
)));
1517 gsi_insert_after (&bsi
, stmt
, GSI_NEW_STMT
);
1518 bsi
= gsi_last_bb (return_bb
);
1522 gimple_call_set_tail (call
, true);
1524 /* Build return value. */
1525 ret
= gimple_build_return (restmp
);
1526 gsi_insert_after (&bsi
, ret
, GSI_NEW_STMT
);
1528 delete_unreachable_blocks ();
1529 update_ssa (TODO_update_ssa
);
1531 /* Since we want to emit the thunk, we explicitly mark its name as
1533 node
->thunk
.thunk_p
= false;
1534 cgraph_node_remove_callees (node
);
1535 cgraph_add_new_function (thunk_fndecl
, true);
1536 bitmap_obstack_release (NULL
);
1538 current_function_decl
= NULL
;
1544 /* Assemble thunks and aliases associated to NODE. */
1547 assemble_thunks_and_aliases (struct cgraph_node
*node
)
1549 struct cgraph_edge
*e
;
1551 struct ipa_ref
*ref
;
1553 for (e
= node
->callers
; e
;)
1554 if (e
->caller
->thunk
.thunk_p
)
1556 struct cgraph_node
*thunk
= e
->caller
;
1559 assemble_thunks_and_aliases (thunk
);
1560 assemble_thunk (thunk
);
1564 for (i
= 0; ipa_ref_list_referring_iterate (&node
->symbol
.ref_list
,
1566 if (ref
->use
== IPA_REF_ALIAS
)
1568 struct cgraph_node
*alias
= ipa_ref_referring_node (ref
);
1569 bool saved_written
= TREE_ASM_WRITTEN (alias
->thunk
.alias
);
1571 /* Force assemble_alias to really output the alias this time instead
1572 of buffering it in same alias pairs. */
1573 TREE_ASM_WRITTEN (alias
->thunk
.alias
) = 1;
1574 do_assemble_alias (alias
->symbol
.decl
,
1575 DECL_ASSEMBLER_NAME (alias
->thunk
.alias
));
1576 assemble_thunks_and_aliases (alias
);
1577 TREE_ASM_WRITTEN (alias
->thunk
.alias
) = saved_written
;
1581 /* Expand function specified by NODE. */
1584 expand_function (struct cgraph_node
*node
)
1586 tree decl
= node
->symbol
.decl
;
1587 location_t saved_loc
;
1589 /* We ought to not compile any inline clones. */
1590 gcc_assert (!node
->global
.inlined_to
);
1592 announce_function (decl
);
1594 gcc_assert (node
->lowered
);
1596 /* Generate RTL for the body of DECL. */
1598 timevar_push (TV_REST_OF_COMPILATION
);
1600 gcc_assert (cgraph_global_info_ready
);
1602 /* Initialize the default bitmap obstack. */
1603 bitmap_obstack_initialize (NULL
);
1605 /* Initialize the RTL code for the function. */
1606 current_function_decl
= decl
;
1607 saved_loc
= input_location
;
1608 input_location
= DECL_SOURCE_LOCATION (decl
);
1609 init_function_start (decl
);
1611 gimple_register_cfg_hooks ();
1613 bitmap_obstack_initialize (®_obstack
); /* FIXME, only at RTL generation*/
1615 execute_all_ipa_transforms ();
1617 /* Perform all tree transforms and optimizations. */
1619 /* Signal the start of passes. */
1620 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START
, NULL
);
1622 execute_pass_list (all_passes
);
1624 /* Signal the end of passes. */
1625 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END
, NULL
);
1627 bitmap_obstack_release (®_obstack
);
1629 /* Release the default bitmap obstack. */
1630 bitmap_obstack_release (NULL
);
1632 /* If requested, warn about function definitions where the function will
1633 return a value (usually of some struct or union type) which itself will
1634 take up a lot of stack space. */
1635 if (warn_larger_than
&& !DECL_EXTERNAL (decl
) && TREE_TYPE (decl
))
1637 tree ret_type
= TREE_TYPE (TREE_TYPE (decl
));
1639 if (ret_type
&& TYPE_SIZE_UNIT (ret_type
)
1640 && TREE_CODE (TYPE_SIZE_UNIT (ret_type
)) == INTEGER_CST
1641 && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type
),
1644 unsigned int size_as_int
1645 = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type
));
1647 if (compare_tree_int (TYPE_SIZE_UNIT (ret_type
), size_as_int
) == 0)
1648 warning (OPT_Wlarger_than_
, "size of return value of %q+D is %u bytes",
1651 warning (OPT_Wlarger_than_
, "size of return value of %q+D is larger than %wd bytes",
1652 decl
, larger_than_size
);
1656 gimple_set_body (decl
, NULL
);
1657 if (DECL_STRUCT_FUNCTION (decl
) == 0
1658 && !cgraph_get_node (decl
)->origin
)
1660 /* Stop pointing to the local nodes about to be freed.
1661 But DECL_INITIAL must remain nonzero so we know this
1662 was an actual function definition.
1663 For a nested function, this is done in c_pop_function_context.
1664 If rest_of_compilation set this to 0, leave it 0. */
1665 if (DECL_INITIAL (decl
) != 0)
1666 DECL_INITIAL (decl
) = error_mark_node
;
1669 input_location
= saved_loc
;
1672 timevar_pop (TV_REST_OF_COMPILATION
);
1674 /* Make sure that BE didn't give up on compiling. */
1675 gcc_assert (TREE_ASM_WRITTEN (decl
));
1677 current_function_decl
= NULL
;
1679 /* It would make a lot more sense to output thunks before function body to get more
1680 forward and lest backwarding jumps. This however would need solving problem
1681 with comdats. See PR48668. Also aliases must come after function itself to
1682 make one pass assemblers, like one on AIX, happy. See PR 50689.
1683 FIXME: Perhaps thunks should be move before function IFF they are not in comdat
1685 assemble_thunks_and_aliases (node
);
1686 cgraph_release_function_body (node
);
1687 /* Eliminate all call edges. This is important so the GIMPLE_CALL no longer
1688 points to the dead function body. */
1689 cgraph_node_remove_callees (node
);
1693 /* Expand all functions that must be output.
1695 Attempt to topologically sort the nodes so function is output when
1696 all called functions are already assembled to allow data to be
1697 propagated across the callgraph. Use a stack to get smaller distance
1698 between a function and its callees (later we may choose to use a more
1699 sophisticated algorithm for function reordering; we will likely want
1700 to use subsections to make the output functions appear in top-down
1704 expand_all_functions (void)
1706 struct cgraph_node
*node
;
1707 struct cgraph_node
**order
= XCNEWVEC (struct cgraph_node
*, cgraph_n_nodes
);
1708 int order_pos
, new_order_pos
= 0;
1711 order_pos
= ipa_reverse_postorder (order
);
1712 gcc_assert (order_pos
== cgraph_n_nodes
);
1714 /* Garbage collector may remove inline clones we eliminate during
1715 optimization. So we must be sure to not reference them. */
1716 for (i
= 0; i
< order_pos
; i
++)
1717 if (order
[i
]->process
)
1718 order
[new_order_pos
++] = order
[i
];
1720 for (i
= new_order_pos
- 1; i
>= 0; i
--)
1726 expand_function (node
);
1729 cgraph_process_new_functions ();
1735 /* This is used to sort the node types by the cgraph order number. */
1737 enum cgraph_order_sort_kind
1739 ORDER_UNDEFINED
= 0,
1745 struct cgraph_order_sort
1747 enum cgraph_order_sort_kind kind
;
1750 struct cgraph_node
*f
;
1751 struct varpool_node
*v
;
1756 /* Output all functions, variables, and asm statements in the order
1757 according to their order fields, which is the order in which they
1758 appeared in the file. This implements -fno-toplevel-reorder. In
1759 this mode we may output functions and variables which don't really
1760 need to be output. */
1763 output_in_order (void)
1766 struct cgraph_order_sort
*nodes
;
1768 struct cgraph_node
*pf
;
1769 struct varpool_node
*pv
;
1770 struct asm_node
*pa
;
1773 nodes
= XCNEWVEC (struct cgraph_order_sort
, max
);
1775 FOR_EACH_DEFINED_FUNCTION (pf
)
1777 if (pf
->process
&& !pf
->thunk
.thunk_p
&& !pf
->alias
)
1779 i
= pf
->symbol
.order
;
1780 gcc_assert (nodes
[i
].kind
== ORDER_UNDEFINED
);
1781 nodes
[i
].kind
= ORDER_FUNCTION
;
1786 FOR_EACH_DEFINED_VARIABLE (pv
)
1787 if (!DECL_EXTERNAL (pv
->symbol
.decl
))
1789 i
= pv
->symbol
.order
;
1790 gcc_assert (nodes
[i
].kind
== ORDER_UNDEFINED
);
1791 nodes
[i
].kind
= ORDER_VAR
;
1795 for (pa
= asm_nodes
; pa
; pa
= pa
->next
)
1798 gcc_assert (nodes
[i
].kind
== ORDER_UNDEFINED
);
1799 nodes
[i
].kind
= ORDER_ASM
;
1803 /* In toplevel reorder mode we output all statics; mark them as needed. */
1805 for (i
= 0; i
< max
; ++i
)
1806 if (nodes
[i
].kind
== ORDER_VAR
)
1807 varpool_finalize_named_section_flags (nodes
[i
].u
.v
);
1809 for (i
= 0; i
< max
; ++i
)
1811 switch (nodes
[i
].kind
)
1813 case ORDER_FUNCTION
:
1814 nodes
[i
].u
.f
->process
= 0;
1815 expand_function (nodes
[i
].u
.f
);
1819 varpool_assemble_decl (nodes
[i
].u
.v
);
1823 assemble_asm (nodes
[i
].u
.a
->asm_str
);
1826 case ORDER_UNDEFINED
:
1842 current_function_decl
= NULL
;
1843 gimple_register_cfg_hooks ();
1844 bitmap_obstack_initialize (NULL
);
1846 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START
, NULL
);
1850 execute_ipa_pass_list (all_small_ipa_passes
);
1855 /* We never run removal of unreachable nodes after early passes. This is
1856 because TODO is run before the subpasses. It is important to remove
1857 the unreachable functions to save works at IPA level and to get LTO
1858 symbol tables right. */
1859 symtab_remove_unreachable_nodes (true, cgraph_dump_file
);
1861 /* If pass_all_early_optimizations was not scheduled, the state of
1862 the cgraph will not be properly updated. Update it now. */
1863 if (cgraph_state
< CGRAPH_STATE_IPA_SSA
)
1864 cgraph_state
= CGRAPH_STATE_IPA_SSA
;
1868 /* Generate coverage variables and constructors. */
1871 /* Process new functions added. */
1873 current_function_decl
= NULL
;
1874 cgraph_process_new_functions ();
1876 execute_ipa_summary_passes
1877 ((struct ipa_opt_pass_d
*) all_regular_ipa_passes
);
1880 /* Some targets need to handle LTO assembler output specially. */
1881 if (flag_generate_lto
)
1882 targetm
.asm_out
.lto_start ();
1884 execute_ipa_summary_passes ((struct ipa_opt_pass_d
*) all_lto_gen_passes
);
1887 ipa_write_summaries ();
1889 if (flag_generate_lto
)
1890 targetm
.asm_out
.lto_end ();
1892 if (!flag_ltrans
&& (in_lto_p
|| !flag_lto
|| flag_fat_lto_objects
))
1893 execute_ipa_pass_list (all_regular_ipa_passes
);
1894 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END
, NULL
);
1896 bitmap_obstack_release (NULL
);
1900 /* Return string alias is alias of. */
1903 get_alias_symbol (tree decl
)
1905 tree alias
= lookup_attribute ("alias", DECL_ATTRIBUTES (decl
));
1906 return get_identifier (TREE_STRING_POINTER
1907 (TREE_VALUE (TREE_VALUE (alias
))));
1911 /* Weakrefs may be associated to external decls and thus not output
1912 at expansion time. Emit all necessary aliases. */
1915 output_weakrefs (void)
1917 struct cgraph_node
*node
;
1918 struct varpool_node
*vnode
;
1919 FOR_EACH_FUNCTION (node
)
1920 if (node
->alias
&& DECL_EXTERNAL (node
->symbol
.decl
)
1921 && !TREE_ASM_WRITTEN (node
->symbol
.decl
)
1922 && lookup_attribute ("weakref", DECL_ATTRIBUTES (node
->symbol
.decl
)))
1923 do_assemble_alias (node
->symbol
.decl
,
1924 node
->thunk
.alias
? DECL_ASSEMBLER_NAME (node
->thunk
.alias
)
1925 : get_alias_symbol (node
->symbol
.decl
));
1926 FOR_EACH_VARIABLE (vnode
)
1927 if (vnode
->alias
&& DECL_EXTERNAL (vnode
->symbol
.decl
)
1928 && !TREE_ASM_WRITTEN (vnode
->symbol
.decl
)
1929 && lookup_attribute ("weakref", DECL_ATTRIBUTES (vnode
->symbol
.decl
)))
1930 do_assemble_alias (vnode
->symbol
.decl
,
1931 vnode
->alias_of
? DECL_ASSEMBLER_NAME (vnode
->alias_of
)
1932 : get_alias_symbol (vnode
->symbol
.decl
));
1935 /* Initialize callgraph dump file. */
1940 if (!cgraph_dump_file
)
1941 cgraph_dump_file
= dump_begin (TDI_cgraph
, NULL
);
1945 /* Perform simple optimizations based on callgraph. */
1953 #ifdef ENABLE_CHECKING
1957 timevar_push (TV_CGRAPHOPT
);
1958 if (pre_ipa_mem_report
)
1960 fprintf (stderr
, "Memory consumption before IPA\n");
1961 dump_memory_report (false);
1964 fprintf (stderr
, "Performing interprocedural optimizations\n");
1965 cgraph_state
= CGRAPH_STATE_IPA
;
1967 /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE. */
1969 lto_streamer_hooks_init ();
1971 /* Don't run the IPA passes if there was any error or sorry messages. */
1975 /* Do nothing else if any IPA pass found errors or if we are just streaming LTO. */
1977 || (!in_lto_p
&& flag_lto
&& !flag_fat_lto_objects
))
1979 timevar_pop (TV_CGRAPHOPT
);
1983 /* This pass remove bodies of extern inline functions we never inlined.
1984 Do this later so other IPA passes see what is really going on. */
1985 symtab_remove_unreachable_nodes (false, dump_file
);
1986 cgraph_global_info_ready
= true;
1987 if (cgraph_dump_file
)
1989 fprintf (cgraph_dump_file
, "Optimized ");
1990 dump_symtab (cgraph_dump_file
);
1992 if (post_ipa_mem_report
)
1994 fprintf (stderr
, "Memory consumption after IPA\n");
1995 dump_memory_report (false);
1997 timevar_pop (TV_CGRAPHOPT
);
1999 /* Output everything. */
2000 (*debug_hooks
->assembly_start
) ();
2002 fprintf (stderr
, "Assembling functions:\n");
2003 #ifdef ENABLE_CHECKING
2007 cgraph_materialize_all_clones ();
2008 bitmap_obstack_initialize (NULL
);
2009 execute_ipa_pass_list (all_late_ipa_passes
);
2010 symtab_remove_unreachable_nodes (true, dump_file
);
2011 #ifdef ENABLE_CHECKING
2014 bitmap_obstack_release (NULL
);
2015 mark_functions_to_output ();
2017 cgraph_state
= CGRAPH_STATE_EXPANSION
;
2018 if (!flag_toplevel_reorder
)
2022 output_asm_statements ();
2024 expand_all_functions ();
2025 varpool_output_variables ();
2028 cgraph_process_new_functions ();
2029 cgraph_state
= CGRAPH_STATE_FINISHED
;
2032 if (cgraph_dump_file
)
2034 fprintf (cgraph_dump_file
, "\nFinal ");
2035 dump_symtab (cgraph_dump_file
);
2037 #ifdef ENABLE_CHECKING
2039 /* Double check that all inline clones are gone and that all
2040 function bodies have been released from memory. */
2043 struct cgraph_node
*node
;
2044 bool error_found
= false;
2046 FOR_EACH_DEFINED_FUNCTION (node
)
2047 if (node
->global
.inlined_to
2048 || gimple_has_body_p (node
->symbol
.decl
))
2051 dump_cgraph_node (stderr
, node
);
2054 internal_error ("nodes with unreleased memory found");
2060 /* Analyze the whole compilation unit once it is parsed completely. */
2063 finalize_compilation_unit (void)
2065 timevar_push (TV_CGRAPH
);
2067 /* If we're here there's no current function anymore. Some frontends
2068 are lazy in clearing these. */
2069 current_function_decl
= NULL
;
2072 /* Do not skip analyzing the functions if there were errors, we
2073 miss diagnostics for following functions otherwise. */
2075 /* Emit size functions we didn't inline. */
2076 finalize_size_functions ();
2078 /* Mark alias targets necessary and emit diagnostics. */
2079 handle_alias_pairs ();
2083 fprintf (stderr
, "\nAnalyzing compilation unit\n");
2087 if (flag_dump_passes
)
2090 /* Gimplify and lower all functions, compute reachability and
2091 remove unreachable nodes. */
2092 cgraph_analyze_functions ();
2094 /* Mark alias targets necessary and emit diagnostics. */
2095 handle_alias_pairs ();
2097 /* Gimplify and lower thunks. */
2098 cgraph_analyze_functions ();
2100 /* Finally drive the pass manager. */
2103 timevar_pop (TV_CGRAPH
);
2107 #include "gt-cgraphunit.h"