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_safe_length (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
);
633 else if (node
->dispatcher_function
)
635 /* Generate the dispatcher body of multi-versioned functions. */
636 struct cgraph_function_version_info
*dispatcher_version_info
637 = get_cgraph_node_version (node
);
638 if (dispatcher_version_info
!= NULL
639 && (dispatcher_version_info
->dispatcher_resolver
642 tree resolver
= NULL_TREE
;
643 gcc_assert (targetm
.generate_version_dispatcher_body
);
644 resolver
= targetm
.generate_version_dispatcher_body (node
);
645 gcc_assert (resolver
!= NULL_TREE
);
650 push_cfun (DECL_STRUCT_FUNCTION (decl
));
652 assign_assembler_name_if_neeeded (node
->symbol
.decl
);
654 /* Make sure to gimplify bodies only once. During analyzing a
655 function we lower it, which will require gimplified nested
656 functions, so we can end up here with an already gimplified
658 if (!gimple_has_body_p (decl
))
659 gimplify_function_tree (decl
);
660 dump_function (TDI_generic
, decl
);
662 /* Lower the function. */
666 lower_nested_functions (node
->symbol
.decl
);
667 gcc_assert (!node
->nested
);
669 gimple_register_cfg_hooks ();
670 bitmap_obstack_initialize (NULL
);
671 execute_pass_list (all_lowering_passes
);
672 free_dominance_info (CDI_POST_DOMINATORS
);
673 free_dominance_info (CDI_DOMINATORS
);
675 bitmap_obstack_release (NULL
);
676 node
->lowered
= true;
681 node
->analyzed
= true;
683 input_location
= saved_loc
;
686 /* C++ frontend produce same body aliases all over the place, even before PCH
687 gets streamed out. It relies on us linking the aliases with their function
688 in order to do the fixups, but ipa-ref is not PCH safe. Consequentely we
689 first produce aliases without links, but once C++ FE is sure he won't sream
690 PCH we build the links via this function. */
693 cgraph_process_same_body_aliases (void)
695 struct cgraph_node
*node
;
696 FOR_EACH_FUNCTION (node
)
697 if (node
->same_body_alias
698 && !vec_safe_length (node
->symbol
.ref_list
.references
))
700 struct cgraph_node
*tgt
= cgraph_get_node (node
->thunk
.alias
);
701 ipa_record_reference ((symtab_node
)node
, (symtab_node
)tgt
,
702 IPA_REF_ALIAS
, NULL
);
704 same_body_aliases_done
= true;
707 /* Process attributes common for vars and functions. */
710 process_common_attributes (tree decl
)
712 tree weakref
= lookup_attribute ("weakref", DECL_ATTRIBUTES (decl
));
714 if (weakref
&& !lookup_attribute ("alias", DECL_ATTRIBUTES (decl
)))
716 warning_at (DECL_SOURCE_LOCATION (decl
), OPT_Wattributes
,
717 "%<weakref%> attribute should be accompanied with"
718 " an %<alias%> attribute");
719 DECL_WEAK (decl
) = 0;
720 DECL_ATTRIBUTES (decl
) = remove_attribute ("weakref",
721 DECL_ATTRIBUTES (decl
));
725 /* Look for externally_visible and used attributes and mark cgraph nodes
728 We cannot mark the nodes at the point the attributes are processed (in
729 handle_*_attribute) because the copy of the declarations available at that
730 point may not be canonical. For example, in:
733 void f() __attribute__((used));
735 the declaration we see in handle_used_attribute will be the second
736 declaration -- but the front end will subsequently merge that declaration
737 with the original declaration and discard the second declaration.
739 Furthermore, we can't mark these nodes in cgraph_finalize_function because:
742 void f() __attribute__((externally_visible));
746 So, we walk the nodes at the end of the translation unit, applying the
747 attributes at that point. */
750 process_function_and_variable_attributes (struct cgraph_node
*first
,
751 struct varpool_node
*first_var
)
753 struct cgraph_node
*node
;
754 struct varpool_node
*vnode
;
756 for (node
= cgraph_first_function (); node
!= first
;
757 node
= cgraph_next_function (node
))
759 tree decl
= node
->symbol
.decl
;
760 if (DECL_PRESERVE_P (decl
))
761 cgraph_mark_force_output_node (node
);
762 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl
)))
764 if (! TREE_PUBLIC (node
->symbol
.decl
))
765 warning_at (DECL_SOURCE_LOCATION (node
->symbol
.decl
), OPT_Wattributes
,
766 "%<externally_visible%>"
767 " attribute have effect only on public objects");
769 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl
))
770 && (node
->local
.finalized
&& !node
->alias
))
772 warning_at (DECL_SOURCE_LOCATION (node
->symbol
.decl
), OPT_Wattributes
,
773 "%<weakref%> attribute ignored"
774 " because function is defined");
775 DECL_WEAK (decl
) = 0;
776 DECL_ATTRIBUTES (decl
) = remove_attribute ("weakref",
777 DECL_ATTRIBUTES (decl
));
780 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl
))
781 && !DECL_DECLARED_INLINE_P (decl
)
782 /* redefining extern inline function makes it DECL_UNINLINABLE. */
783 && !DECL_UNINLINABLE (decl
))
784 warning_at (DECL_SOURCE_LOCATION (decl
), OPT_Wattributes
,
785 "always_inline function might not be inlinable");
787 process_common_attributes (decl
);
789 for (vnode
= varpool_first_variable (); vnode
!= first_var
;
790 vnode
= varpool_next_variable (vnode
))
792 tree decl
= vnode
->symbol
.decl
;
793 if (DECL_EXTERNAL (decl
)
794 && DECL_INITIAL (decl
)
795 && const_value_known_p (decl
))
796 varpool_finalize_decl (decl
);
797 if (DECL_PRESERVE_P (decl
))
798 vnode
->symbol
.force_output
= true;
799 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl
)))
801 if (! TREE_PUBLIC (vnode
->symbol
.decl
))
802 warning_at (DECL_SOURCE_LOCATION (vnode
->symbol
.decl
), OPT_Wattributes
,
803 "%<externally_visible%>"
804 " attribute have effect only on public objects");
806 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl
))
808 && DECL_INITIAL (decl
))
810 warning_at (DECL_SOURCE_LOCATION (vnode
->symbol
.decl
), OPT_Wattributes
,
811 "%<weakref%> attribute ignored"
812 " because variable is initialized");
813 DECL_WEAK (decl
) = 0;
814 DECL_ATTRIBUTES (decl
) = remove_attribute ("weakref",
815 DECL_ATTRIBUTES (decl
));
817 process_common_attributes (decl
);
821 /* Mark DECL as finalized. By finalizing the declaration, frontend instruct the
822 middle end to output the variable to asm file, if needed or externally
826 varpool_finalize_decl (tree decl
)
828 struct varpool_node
*node
= varpool_node_for_decl (decl
);
830 gcc_assert (TREE_STATIC (decl
) || DECL_EXTERNAL (decl
));
834 notice_global_symbol (decl
);
835 node
->finalized
= true;
836 if (TREE_THIS_VOLATILE (decl
) || DECL_PRESERVE_P (decl
)
837 /* Traditionally we do not eliminate static variables when not
838 optimizing and when not doing toplevel reoder. */
839 || (!flag_toplevel_reorder
&& !DECL_COMDAT (node
->symbol
.decl
)
840 && !DECL_ARTIFICIAL (node
->symbol
.decl
)))
841 node
->symbol
.force_output
= true;
843 if (cgraph_state
== CGRAPH_STATE_CONSTRUCTION
844 && (decide_is_variable_needed (node
, decl
)
845 || referred_to_p ((symtab_node
)node
)))
846 enqueue_node ((symtab_node
)node
);
847 if (cgraph_state
>= CGRAPH_STATE_IPA_SSA
)
848 varpool_analyze_node (node
);
849 /* Some frontends produce various interface variables after compilation
851 if (cgraph_state
== CGRAPH_STATE_FINISHED
)
852 varpool_assemble_decl (node
);
856 /* Determine if a symbol NODE is finalized and needed. */
859 symbol_finalized_and_needed (symtab_node node
)
861 if (cgraph_node
*cnode
= dyn_cast
<cgraph_node
> (node
))
862 return cnode
->local
.finalized
863 && cgraph_decide_is_function_needed (cnode
, cnode
->symbol
.decl
);
864 if (varpool_node
*vnode
= dyn_cast
<varpool_node
> (node
))
865 return vnode
->finalized
866 && !DECL_EXTERNAL (vnode
->symbol
.decl
)
867 && decide_is_variable_needed (vnode
, vnode
->symbol
.decl
);
871 /* Determine if a symbol NODE is finalized. */
874 symbol_finalized (symtab_node node
)
876 if (cgraph_node
*cnode
= dyn_cast
<cgraph_node
> (node
))
877 return cnode
->local
.finalized
;
878 if (varpool_node
*vnode
= dyn_cast
<varpool_node
> (node
))
879 return vnode
->finalized
;
884 /* Discover all functions and variables that are trivially needed, analyze
885 them as well as all functions and variables referred by them */
888 cgraph_analyze_functions (void)
890 /* Keep track of already processed nodes when called multiple times for
891 intermodule optimization. */
892 static struct cgraph_node
*first_analyzed
;
893 struct cgraph_node
*first_handled
= first_analyzed
;
894 static struct varpool_node
*first_analyzed_var
;
895 struct varpool_node
*first_handled_var
= first_analyzed_var
;
897 symtab_node node
, next
;
902 bitmap_obstack_initialize (NULL
);
903 cgraph_state
= CGRAPH_STATE_CONSTRUCTION
;
905 /* Analysis adds static variables that in turn adds references to new functions.
906 So we need to iterate the process until it stabilize. */
910 process_function_and_variable_attributes (first_analyzed
,
913 /* First identify the trivially needed symbols. */
914 for (node
= symtab_nodes
;
915 node
!= (symtab_node
)first_analyzed
916 && node
!= (symtab_node
)first_analyzed_var
; node
= node
->symbol
.next
)
918 if (symbol_finalized_and_needed (node
))
921 if (!changed
&& cgraph_dump_file
)
922 fprintf (cgraph_dump_file
, "Trivially needed symbols:");
924 if (cgraph_dump_file
)
925 fprintf (cgraph_dump_file
, " %s", symtab_node_asm_name (node
));
927 if (node
== (symtab_node
)first_analyzed
928 || node
== (symtab_node
)first_analyzed_var
)
931 cgraph_process_new_functions ();
932 first_analyzed_var
= varpool_first_variable ();
933 first_analyzed
= cgraph_first_function ();
935 if (changed
&& dump_file
)
936 fprintf (cgraph_dump_file
, "\n");
938 /* Lower representation, build callgraph edges and references for all trivially
939 needed symbols and all symbols referred by them. */
940 while (first
!= (symtab_node
)(void *)1)
944 first
= (symtab_node
)first
->symbol
.aux
;
945 cgraph_node
*cnode
= dyn_cast
<cgraph_node
> (node
);
946 if (cnode
&& cnode
->local
.finalized
)
948 struct cgraph_edge
*edge
;
949 tree decl
= cnode
->symbol
.decl
;
951 /* ??? It is possible to create extern inline function
952 and later using weak alias attribute to kill its body.
953 See gcc.c-torture/compile/20011119-1.c */
954 if (!DECL_STRUCT_FUNCTION (decl
)
955 && (!cnode
->alias
|| !cnode
->thunk
.alias
)
956 && !cnode
->thunk
.thunk_p
957 && !cnode
->dispatcher_function
)
959 cgraph_reset_node (cnode
);
960 cnode
->local
.redefined_extern_inline
= true;
964 if (!cnode
->analyzed
)
965 cgraph_analyze_function (cnode
);
967 for (edge
= cnode
->callees
; edge
; edge
= edge
->next_callee
)
968 if (edge
->callee
->local
.finalized
)
969 enqueue_node ((symtab_node
)edge
->callee
);
971 /* If decl is a clone of an abstract function,
972 mark that abstract function so that we don't release its body.
973 The DECL_INITIAL() of that abstract function declaration
974 will be later needed to output debug info. */
975 if (DECL_ABSTRACT_ORIGIN (decl
))
977 struct cgraph_node
*origin_node
978 = cgraph_get_node (DECL_ABSTRACT_ORIGIN (decl
));
979 origin_node
->abstract_and_needed
= true;
984 varpool_node
*vnode
= dyn_cast
<varpool_node
> (node
);
985 if (vnode
&& vnode
->finalized
)
986 varpool_analyze_node (vnode
);
989 if (node
->symbol
.same_comdat_group
)
992 for (next
= node
->symbol
.same_comdat_group
;
994 next
= next
->symbol
.same_comdat_group
)
997 for (i
= 0; ipa_ref_list_reference_iterate (&node
->symbol
.ref_list
, i
, ref
); i
++)
998 if (symbol_finalized (ref
->referred
))
999 enqueue_node (ref
->referred
);
1000 cgraph_process_new_functions ();
1004 /* Collect entry points to the unit. */
1005 if (cgraph_dump_file
)
1007 fprintf (cgraph_dump_file
, "\n\nInitial ");
1008 dump_symtab (cgraph_dump_file
);
1011 if (cgraph_dump_file
)
1012 fprintf (cgraph_dump_file
, "\nRemoving unused symbols:");
1014 for (node
= symtab_nodes
;
1015 node
!= (symtab_node
)first_handled
1016 && node
!= (symtab_node
)first_handled_var
; node
= next
)
1018 next
= node
->symbol
.next
;
1019 if (!node
->symbol
.aux
&& !referred_to_p (node
))
1021 if (cgraph_dump_file
)
1022 fprintf (cgraph_dump_file
, " %s", symtab_node_name (node
));
1023 symtab_remove_node (node
);
1026 if (cgraph_node
*cnode
= dyn_cast
<cgraph_node
> (node
))
1028 tree decl
= node
->symbol
.decl
;
1030 if (cnode
->local
.finalized
&& !gimple_has_body_p (decl
)
1031 && (!cnode
->alias
|| !cnode
->thunk
.alias
)
1032 && !cnode
->thunk
.thunk_p
)
1033 cgraph_reset_node (cnode
);
1035 gcc_assert (!cnode
->local
.finalized
|| cnode
->thunk
.thunk_p
1037 || gimple_has_body_p (decl
));
1038 gcc_assert (cnode
->analyzed
== cnode
->local
.finalized
);
1040 node
->symbol
.aux
= NULL
;
1042 first_analyzed
= cgraph_first_function ();
1043 first_analyzed_var
= varpool_first_variable ();
1044 if (cgraph_dump_file
)
1046 fprintf (cgraph_dump_file
, "\n\nReclaimed ");
1047 dump_symtab (cgraph_dump_file
);
1049 bitmap_obstack_release (NULL
);
1053 /* Translate the ugly representation of aliases as alias pairs into nice
1054 representation in callgraph. We don't handle all cases yet,
1058 handle_alias_pairs (void)
1063 for (i
= 0; alias_pairs
&& alias_pairs
->iterate (i
, &p
);)
1065 symtab_node target_node
= symtab_node_for_asm (p
->target
);
1067 /* Weakrefs with target not defined in current unit are easy to handle; they
1068 behave just as external variables except we need to note the alias flag
1069 to later output the weakref pseudo op into asm file. */
1070 if (!target_node
&& lookup_attribute ("weakref", DECL_ATTRIBUTES (p
->decl
)) != NULL
)
1072 if (TREE_CODE (p
->decl
) == FUNCTION_DECL
)
1073 cgraph_get_create_node (p
->decl
)->alias
= true;
1075 varpool_get_node (p
->decl
)->alias
= true;
1076 DECL_EXTERNAL (p
->decl
) = 1;
1077 alias_pairs
->unordered_remove (i
);
1080 else if (!target_node
)
1082 error ("%q+D aliased to undefined symbol %qE", p
->decl
, p
->target
);
1083 alias_pairs
->unordered_remove (i
);
1087 /* Normally EXTERNAL flag is used to mark external inlines,
1088 however for aliases it seems to be allowed to use it w/o
1089 any meaning. See gcc.dg/attr-alias-3.c
1090 However for weakref we insist on EXTERNAL flag being set.
1091 See gcc.dg/attr-alias-5.c */
1092 if (DECL_EXTERNAL (p
->decl
))
1093 DECL_EXTERNAL (p
->decl
)
1094 = lookup_attribute ("weakref",
1095 DECL_ATTRIBUTES (p
->decl
)) != NULL
;
1097 if (DECL_EXTERNAL (target_node
->symbol
.decl
)
1098 /* We use local aliases for C++ thunks to force the tailcall
1099 to bind locally. This is a hack - to keep it working do
1100 the following (which is not strictly correct). */
1101 && (! TREE_CODE (target_node
->symbol
.decl
) == FUNCTION_DECL
1102 || ! DECL_VIRTUAL_P (target_node
->symbol
.decl
))
1103 && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p
->decl
)))
1105 error ("%q+D aliased to external symbol %qE",
1106 p
->decl
, p
->target
);
1109 if (TREE_CODE (p
->decl
) == FUNCTION_DECL
1110 && target_node
&& is_a
<cgraph_node
> (target_node
))
1112 struct cgraph_node
*src_node
= cgraph_get_node (p
->decl
);
1113 if (src_node
&& src_node
->local
.finalized
)
1114 cgraph_reset_node (src_node
);
1115 cgraph_create_function_alias (p
->decl
, target_node
->symbol
.decl
);
1116 alias_pairs
->unordered_remove (i
);
1118 else if (TREE_CODE (p
->decl
) == VAR_DECL
1119 && target_node
&& is_a
<varpool_node
> (target_node
))
1121 varpool_create_variable_alias (p
->decl
, target_node
->symbol
.decl
);
1122 alias_pairs
->unordered_remove (i
);
1126 error ("%q+D alias in between function and variable is not supported",
1128 warning (0, "%q+D aliased declaration",
1129 target_node
->symbol
.decl
);
1130 alias_pairs
->unordered_remove (i
);
1133 vec_free (alias_pairs
);
1137 /* Figure out what functions we want to assemble. */
1140 mark_functions_to_output (void)
1142 struct cgraph_node
*node
;
1143 #ifdef ENABLE_CHECKING
1144 bool check_same_comdat_groups
= false;
1146 FOR_EACH_FUNCTION (node
)
1147 gcc_assert (!node
->process
);
1150 FOR_EACH_FUNCTION (node
)
1152 tree decl
= node
->symbol
.decl
;
1154 gcc_assert (!node
->process
|| node
->symbol
.same_comdat_group
);
1158 /* We need to output all local functions that are used and not
1159 always inlined, as well as those that are reachable from
1160 outside the current compilation unit. */
1162 && !node
->thunk
.thunk_p
1164 && !node
->global
.inlined_to
1165 && !TREE_ASM_WRITTEN (decl
)
1166 && !DECL_EXTERNAL (decl
))
1169 if (node
->symbol
.same_comdat_group
)
1171 struct cgraph_node
*next
;
1172 for (next
= cgraph (node
->symbol
.same_comdat_group
);
1174 next
= cgraph (next
->symbol
.same_comdat_group
))
1175 if (!next
->thunk
.thunk_p
&& !next
->alias
)
1179 else if (node
->symbol
.same_comdat_group
)
1181 #ifdef ENABLE_CHECKING
1182 check_same_comdat_groups
= true;
1187 /* We should've reclaimed all functions that are not needed. */
1188 #ifdef ENABLE_CHECKING
1189 if (!node
->global
.inlined_to
1190 && gimple_has_body_p (decl
)
1191 /* FIXME: in ltrans unit when offline copy is outside partition but inline copies
1192 are inside partition, we can end up not removing the body since we no longer
1193 have analyzed node pointing to it. */
1194 && !node
->symbol
.in_other_partition
1197 && !DECL_EXTERNAL (decl
))
1199 dump_cgraph_node (stderr
, node
);
1200 internal_error ("failed to reclaim unneeded function");
1203 gcc_assert (node
->global
.inlined_to
1204 || !gimple_has_body_p (decl
)
1205 || node
->symbol
.in_other_partition
1207 || DECL_ARTIFICIAL (decl
)
1208 || DECL_EXTERNAL (decl
));
1213 #ifdef ENABLE_CHECKING
1214 if (check_same_comdat_groups
)
1215 FOR_EACH_FUNCTION (node
)
1216 if (node
->symbol
.same_comdat_group
&& !node
->process
)
1218 tree decl
= node
->symbol
.decl
;
1219 if (!node
->global
.inlined_to
1220 && gimple_has_body_p (decl
)
1221 /* FIXME: in an ltrans unit when the offline copy is outside a
1222 partition but inline copies are inside a partition, we can
1223 end up not removing the body since we no longer have an
1224 analyzed node pointing to it. */
1225 && !node
->symbol
.in_other_partition
1227 && !DECL_EXTERNAL (decl
))
1229 dump_cgraph_node (stderr
, node
);
1230 internal_error ("failed to reclaim unneeded function in same "
1237 /* DECL is FUNCTION_DECL. Initialize datastructures so DECL is a function
1238 in lowered gimple form. IN_SSA is true if the gimple is in SSA.
1240 Set current_function_decl and cfun to newly constructed empty function body.
1241 return basic block in the function body. */
1244 init_lowered_empty_function (tree decl
, bool in_ssa
)
1248 current_function_decl
= decl
;
1249 allocate_struct_function (decl
, false);
1250 gimple_register_cfg_hooks ();
1251 init_empty_tree_cfg ();
1255 init_tree_ssa (cfun
);
1256 init_ssa_operands (cfun
);
1257 cfun
->gimple_df
->in_ssa_p
= true;
1260 DECL_INITIAL (decl
) = make_node (BLOCK
);
1262 DECL_SAVED_TREE (decl
) = error_mark_node
;
1263 cfun
->curr_properties
|=
1264 (PROP_gimple_lcf
| PROP_gimple_leh
| PROP_cfg
| PROP_ssa
| PROP_gimple_any
);
1266 /* Create BB for body of the function and connect it properly. */
1267 bb
= create_basic_block (NULL
, (void *) 0, ENTRY_BLOCK_PTR
);
1268 make_edge (ENTRY_BLOCK_PTR
, bb
, 0);
1269 make_edge (bb
, EXIT_BLOCK_PTR
, 0);
1274 /* Adjust PTR by the constant FIXED_OFFSET, and by the vtable
1275 offset indicated by VIRTUAL_OFFSET, if that is
1276 non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and
1277 zero for a result adjusting thunk. */
1280 thunk_adjust (gimple_stmt_iterator
* bsi
,
1281 tree ptr
, bool this_adjusting
,
1282 HOST_WIDE_INT fixed_offset
, tree virtual_offset
)
1288 && fixed_offset
!= 0)
1290 stmt
= gimple_build_assign
1291 (ptr
, fold_build_pointer_plus_hwi_loc (input_location
,
1294 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1297 /* If there's a virtual offset, look up that value in the vtable and
1298 adjust the pointer again. */
1305 if (!vtable_entry_type
)
1307 tree vfunc_type
= make_node (FUNCTION_TYPE
);
1308 TREE_TYPE (vfunc_type
) = integer_type_node
;
1309 TYPE_ARG_TYPES (vfunc_type
) = NULL_TREE
;
1310 layout_type (vfunc_type
);
1312 vtable_entry_type
= build_pointer_type (vfunc_type
);
1316 create_tmp_reg (build_pointer_type
1317 (build_pointer_type (vtable_entry_type
)), "vptr");
1319 /* The vptr is always at offset zero in the object. */
1320 stmt
= gimple_build_assign (vtabletmp
,
1321 build1 (NOP_EXPR
, TREE_TYPE (vtabletmp
),
1323 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1325 /* Form the vtable address. */
1326 vtabletmp2
= create_tmp_reg (TREE_TYPE (TREE_TYPE (vtabletmp
)),
1328 stmt
= gimple_build_assign (vtabletmp2
,
1329 build_simple_mem_ref (vtabletmp
));
1330 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1332 /* Find the entry with the vcall offset. */
1333 stmt
= gimple_build_assign (vtabletmp2
,
1334 fold_build_pointer_plus_loc (input_location
,
1337 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1339 /* Get the offset itself. */
1340 vtabletmp3
= create_tmp_reg (TREE_TYPE (TREE_TYPE (vtabletmp2
)),
1342 stmt
= gimple_build_assign (vtabletmp3
,
1343 build_simple_mem_ref (vtabletmp2
));
1344 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1346 /* Adjust the `this' pointer. */
1347 ptr
= fold_build_pointer_plus_loc (input_location
, ptr
, vtabletmp3
);
1348 ptr
= force_gimple_operand_gsi (bsi
, ptr
, true, NULL_TREE
, false,
1349 GSI_CONTINUE_LINKING
);
1353 && fixed_offset
!= 0)
1354 /* Adjust the pointer by the constant. */
1358 if (TREE_CODE (ptr
) == VAR_DECL
)
1362 ptrtmp
= create_tmp_reg (TREE_TYPE (ptr
), "ptr");
1363 stmt
= gimple_build_assign (ptrtmp
, ptr
);
1364 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1366 ptr
= fold_build_pointer_plus_hwi_loc (input_location
,
1367 ptrtmp
, fixed_offset
);
1370 /* Emit the statement and gimplify the adjustment expression. */
1371 ret
= create_tmp_reg (TREE_TYPE (ptr
), "adjusted_this");
1372 stmt
= gimple_build_assign (ret
, ptr
);
1373 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1378 /* Produce assembler for thunk NODE. */
1381 assemble_thunk (struct cgraph_node
*node
)
1383 bool this_adjusting
= node
->thunk
.this_adjusting
;
1384 HOST_WIDE_INT fixed_offset
= node
->thunk
.fixed_offset
;
1385 HOST_WIDE_INT virtual_value
= node
->thunk
.virtual_value
;
1386 tree virtual_offset
= NULL
;
1387 tree alias
= node
->thunk
.alias
;
1388 tree thunk_fndecl
= node
->symbol
.decl
;
1389 tree a
= DECL_ARGUMENTS (thunk_fndecl
);
1391 current_function_decl
= thunk_fndecl
;
1393 /* Ensure thunks are emitted in their correct sections. */
1394 resolve_unique_section (thunk_fndecl
, 0, flag_function_sections
);
1397 && targetm
.asm_out
.can_output_mi_thunk (thunk_fndecl
, fixed_offset
,
1398 virtual_value
, alias
))
1402 tree restype
= TREE_TYPE (TREE_TYPE (thunk_fndecl
));
1404 DECL_RESULT (thunk_fndecl
)
1405 = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl
),
1406 RESULT_DECL
, 0, restype
);
1407 fnname
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl
));
1409 /* The back end expects DECL_INITIAL to contain a BLOCK, so we
1411 fn_block
= make_node (BLOCK
);
1412 BLOCK_VARS (fn_block
) = a
;
1413 DECL_INITIAL (thunk_fndecl
) = fn_block
;
1414 init_function_start (thunk_fndecl
);
1416 insn_locations_init ();
1417 set_curr_insn_location (DECL_SOURCE_LOCATION (thunk_fndecl
));
1418 prologue_location
= curr_insn_location ();
1419 assemble_start_function (thunk_fndecl
, fnname
);
1421 targetm
.asm_out
.output_mi_thunk (asm_out_file
, thunk_fndecl
,
1422 fixed_offset
, virtual_value
, alias
);
1424 assemble_end_function (thunk_fndecl
, fnname
);
1425 insn_locations_finalize ();
1426 init_insn_lengths ();
1427 free_after_compilation (cfun
);
1429 TREE_ASM_WRITTEN (thunk_fndecl
) = 1;
1430 node
->thunk
.thunk_p
= false;
1431 node
->analyzed
= false;
1436 basic_block bb
, then_bb
, else_bb
, return_bb
;
1437 gimple_stmt_iterator bsi
;
1448 DECL_IGNORED_P (thunk_fndecl
) = 1;
1449 bitmap_obstack_initialize (NULL
);
1451 if (node
->thunk
.virtual_offset_p
)
1452 virtual_offset
= size_int (virtual_value
);
1454 /* Build the return declaration for the function. */
1455 restype
= TREE_TYPE (TREE_TYPE (thunk_fndecl
));
1456 if (DECL_RESULT (thunk_fndecl
) == NULL_TREE
)
1458 resdecl
= build_decl (input_location
, RESULT_DECL
, 0, restype
);
1459 DECL_ARTIFICIAL (resdecl
) = 1;
1460 DECL_IGNORED_P (resdecl
) = 1;
1461 DECL_RESULT (thunk_fndecl
) = resdecl
;
1464 resdecl
= DECL_RESULT (thunk_fndecl
);
1466 bb
= then_bb
= else_bb
= return_bb
= init_lowered_empty_function (thunk_fndecl
, true);
1468 bsi
= gsi_start_bb (bb
);
1470 /* Build call to the function being thunked. */
1471 if (!VOID_TYPE_P (restype
))
1473 if (!is_gimple_reg_type (restype
))
1476 add_local_decl (cfun
, restmp
);
1477 BLOCK_VARS (DECL_INITIAL (current_function_decl
)) = restmp
;
1480 restmp
= create_tmp_reg (restype
, "retval");
1483 for (arg
= a
; arg
; arg
= DECL_CHAIN (arg
))
1485 vargs
.create (nargs
);
1487 vargs
.quick_push (thunk_adjust (&bsi
, a
, 1, fixed_offset
,
1490 vargs
.quick_push (a
);
1491 for (i
= 1, arg
= DECL_CHAIN (a
); i
< nargs
; i
++, arg
= DECL_CHAIN (arg
))
1492 vargs
.quick_push (arg
);
1493 call
= gimple_build_call_vec (build_fold_addr_expr_loc (0, alias
), vargs
);
1495 gimple_call_set_from_thunk (call
, true);
1497 gimple_call_set_lhs (call
, restmp
);
1498 gsi_insert_after (&bsi
, call
, GSI_NEW_STMT
);
1500 if (restmp
&& !this_adjusting
)
1502 tree true_label
= NULL_TREE
;
1504 if (TREE_CODE (TREE_TYPE (restmp
)) == POINTER_TYPE
)
1507 /* If the return type is a pointer, we need to
1508 protect against NULL. We know there will be an
1509 adjustment, because that's why we're emitting a
1511 then_bb
= create_basic_block (NULL
, (void *) 0, bb
);
1512 return_bb
= create_basic_block (NULL
, (void *) 0, then_bb
);
1513 else_bb
= create_basic_block (NULL
, (void *) 0, else_bb
);
1514 remove_edge (single_succ_edge (bb
));
1515 true_label
= gimple_block_label (then_bb
);
1516 stmt
= gimple_build_cond (NE_EXPR
, restmp
,
1517 build_zero_cst (TREE_TYPE (restmp
)),
1518 NULL_TREE
, NULL_TREE
);
1519 gsi_insert_after (&bsi
, stmt
, GSI_NEW_STMT
);
1520 make_edge (bb
, then_bb
, EDGE_TRUE_VALUE
);
1521 make_edge (bb
, else_bb
, EDGE_FALSE_VALUE
);
1522 make_edge (return_bb
, EXIT_BLOCK_PTR
, 0);
1523 make_edge (then_bb
, return_bb
, EDGE_FALLTHRU
);
1524 make_edge (else_bb
, return_bb
, EDGE_FALLTHRU
);
1525 bsi
= gsi_last_bb (then_bb
);
1528 restmp
= thunk_adjust (&bsi
, restmp
, /*this_adjusting=*/0,
1529 fixed_offset
, virtual_offset
);
1533 bsi
= gsi_last_bb (else_bb
);
1534 stmt
= gimple_build_assign (restmp
,
1535 build_zero_cst (TREE_TYPE (restmp
)));
1536 gsi_insert_after (&bsi
, stmt
, GSI_NEW_STMT
);
1537 bsi
= gsi_last_bb (return_bb
);
1541 gimple_call_set_tail (call
, true);
1543 /* Build return value. */
1544 ret
= gimple_build_return (restmp
);
1545 gsi_insert_after (&bsi
, ret
, GSI_NEW_STMT
);
1547 delete_unreachable_blocks ();
1548 update_ssa (TODO_update_ssa
);
1550 /* Since we want to emit the thunk, we explicitly mark its name as
1552 node
->thunk
.thunk_p
= false;
1553 cgraph_node_remove_callees (node
);
1554 cgraph_add_new_function (thunk_fndecl
, true);
1555 bitmap_obstack_release (NULL
);
1557 current_function_decl
= NULL
;
1563 /* Assemble thunks and aliases associated to NODE. */
1566 assemble_thunks_and_aliases (struct cgraph_node
*node
)
1568 struct cgraph_edge
*e
;
1570 struct ipa_ref
*ref
;
1572 for (e
= node
->callers
; e
;)
1573 if (e
->caller
->thunk
.thunk_p
)
1575 struct cgraph_node
*thunk
= e
->caller
;
1578 assemble_thunks_and_aliases (thunk
);
1579 assemble_thunk (thunk
);
1583 for (i
= 0; ipa_ref_list_referring_iterate (&node
->symbol
.ref_list
,
1585 if (ref
->use
== IPA_REF_ALIAS
)
1587 struct cgraph_node
*alias
= ipa_ref_referring_node (ref
);
1588 bool saved_written
= TREE_ASM_WRITTEN (alias
->thunk
.alias
);
1590 /* Force assemble_alias to really output the alias this time instead
1591 of buffering it in same alias pairs. */
1592 TREE_ASM_WRITTEN (alias
->thunk
.alias
) = 1;
1593 do_assemble_alias (alias
->symbol
.decl
,
1594 DECL_ASSEMBLER_NAME (alias
->thunk
.alias
));
1595 assemble_thunks_and_aliases (alias
);
1596 TREE_ASM_WRITTEN (alias
->thunk
.alias
) = saved_written
;
1600 /* Expand function specified by NODE. */
1603 expand_function (struct cgraph_node
*node
)
1605 tree decl
= node
->symbol
.decl
;
1606 location_t saved_loc
;
1608 /* We ought to not compile any inline clones. */
1609 gcc_assert (!node
->global
.inlined_to
);
1611 announce_function (decl
);
1613 gcc_assert (node
->lowered
);
1615 /* Generate RTL for the body of DECL. */
1617 timevar_push (TV_REST_OF_COMPILATION
);
1619 gcc_assert (cgraph_global_info_ready
);
1621 /* Initialize the default bitmap obstack. */
1622 bitmap_obstack_initialize (NULL
);
1624 /* Initialize the RTL code for the function. */
1625 current_function_decl
= decl
;
1626 saved_loc
= input_location
;
1627 input_location
= DECL_SOURCE_LOCATION (decl
);
1628 init_function_start (decl
);
1630 gimple_register_cfg_hooks ();
1632 bitmap_obstack_initialize (®_obstack
); /* FIXME, only at RTL generation*/
1634 execute_all_ipa_transforms ();
1636 /* Perform all tree transforms and optimizations. */
1638 /* Signal the start of passes. */
1639 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START
, NULL
);
1641 execute_pass_list (all_passes
);
1643 /* Signal the end of passes. */
1644 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END
, NULL
);
1646 bitmap_obstack_release (®_obstack
);
1648 /* Release the default bitmap obstack. */
1649 bitmap_obstack_release (NULL
);
1651 /* If requested, warn about function definitions where the function will
1652 return a value (usually of some struct or union type) which itself will
1653 take up a lot of stack space. */
1654 if (warn_larger_than
&& !DECL_EXTERNAL (decl
) && TREE_TYPE (decl
))
1656 tree ret_type
= TREE_TYPE (TREE_TYPE (decl
));
1658 if (ret_type
&& TYPE_SIZE_UNIT (ret_type
)
1659 && TREE_CODE (TYPE_SIZE_UNIT (ret_type
)) == INTEGER_CST
1660 && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type
),
1663 unsigned int size_as_int
1664 = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type
));
1666 if (compare_tree_int (TYPE_SIZE_UNIT (ret_type
), size_as_int
) == 0)
1667 warning (OPT_Wlarger_than_
, "size of return value of %q+D is %u bytes",
1670 warning (OPT_Wlarger_than_
, "size of return value of %q+D is larger than %wd bytes",
1671 decl
, larger_than_size
);
1675 gimple_set_body (decl
, NULL
);
1676 if (DECL_STRUCT_FUNCTION (decl
) == 0
1677 && !cgraph_get_node (decl
)->origin
)
1679 /* Stop pointing to the local nodes about to be freed.
1680 But DECL_INITIAL must remain nonzero so we know this
1681 was an actual function definition.
1682 For a nested function, this is done in c_pop_function_context.
1683 If rest_of_compilation set this to 0, leave it 0. */
1684 if (DECL_INITIAL (decl
) != 0)
1685 DECL_INITIAL (decl
) = error_mark_node
;
1688 input_location
= saved_loc
;
1691 timevar_pop (TV_REST_OF_COMPILATION
);
1693 /* Make sure that BE didn't give up on compiling. */
1694 gcc_assert (TREE_ASM_WRITTEN (decl
));
1696 current_function_decl
= NULL
;
1698 /* It would make a lot more sense to output thunks before function body to get more
1699 forward and lest backwarding jumps. This however would need solving problem
1700 with comdats. See PR48668. Also aliases must come after function itself to
1701 make one pass assemblers, like one on AIX, happy. See PR 50689.
1702 FIXME: Perhaps thunks should be move before function IFF they are not in comdat
1704 assemble_thunks_and_aliases (node
);
1705 cgraph_release_function_body (node
);
1706 /* Eliminate all call edges. This is important so the GIMPLE_CALL no longer
1707 points to the dead function body. */
1708 cgraph_node_remove_callees (node
);
1712 /* Expand all functions that must be output.
1714 Attempt to topologically sort the nodes so function is output when
1715 all called functions are already assembled to allow data to be
1716 propagated across the callgraph. Use a stack to get smaller distance
1717 between a function and its callees (later we may choose to use a more
1718 sophisticated algorithm for function reordering; we will likely want
1719 to use subsections to make the output functions appear in top-down
1723 expand_all_functions (void)
1725 struct cgraph_node
*node
;
1726 struct cgraph_node
**order
= XCNEWVEC (struct cgraph_node
*, cgraph_n_nodes
);
1727 int order_pos
, new_order_pos
= 0;
1730 order_pos
= ipa_reverse_postorder (order
);
1731 gcc_assert (order_pos
== cgraph_n_nodes
);
1733 /* Garbage collector may remove inline clones we eliminate during
1734 optimization. So we must be sure to not reference them. */
1735 for (i
= 0; i
< order_pos
; i
++)
1736 if (order
[i
]->process
)
1737 order
[new_order_pos
++] = order
[i
];
1739 for (i
= new_order_pos
- 1; i
>= 0; i
--)
1745 expand_function (node
);
1748 cgraph_process_new_functions ();
1754 /* This is used to sort the node types by the cgraph order number. */
1756 enum cgraph_order_sort_kind
1758 ORDER_UNDEFINED
= 0,
1764 struct cgraph_order_sort
1766 enum cgraph_order_sort_kind kind
;
1769 struct cgraph_node
*f
;
1770 struct varpool_node
*v
;
1775 /* Output all functions, variables, and asm statements in the order
1776 according to their order fields, which is the order in which they
1777 appeared in the file. This implements -fno-toplevel-reorder. In
1778 this mode we may output functions and variables which don't really
1779 need to be output. */
1782 output_in_order (void)
1785 struct cgraph_order_sort
*nodes
;
1787 struct cgraph_node
*pf
;
1788 struct varpool_node
*pv
;
1789 struct asm_node
*pa
;
1792 nodes
= XCNEWVEC (struct cgraph_order_sort
, max
);
1794 FOR_EACH_DEFINED_FUNCTION (pf
)
1796 if (pf
->process
&& !pf
->thunk
.thunk_p
&& !pf
->alias
)
1798 i
= pf
->symbol
.order
;
1799 gcc_assert (nodes
[i
].kind
== ORDER_UNDEFINED
);
1800 nodes
[i
].kind
= ORDER_FUNCTION
;
1805 FOR_EACH_DEFINED_VARIABLE (pv
)
1806 if (!DECL_EXTERNAL (pv
->symbol
.decl
))
1808 i
= pv
->symbol
.order
;
1809 gcc_assert (nodes
[i
].kind
== ORDER_UNDEFINED
);
1810 nodes
[i
].kind
= ORDER_VAR
;
1814 for (pa
= asm_nodes
; pa
; pa
= pa
->next
)
1817 gcc_assert (nodes
[i
].kind
== ORDER_UNDEFINED
);
1818 nodes
[i
].kind
= ORDER_ASM
;
1822 /* In toplevel reorder mode we output all statics; mark them as needed. */
1824 for (i
= 0; i
< max
; ++i
)
1825 if (nodes
[i
].kind
== ORDER_VAR
)
1826 varpool_finalize_named_section_flags (nodes
[i
].u
.v
);
1828 for (i
= 0; i
< max
; ++i
)
1830 switch (nodes
[i
].kind
)
1832 case ORDER_FUNCTION
:
1833 nodes
[i
].u
.f
->process
= 0;
1834 expand_function (nodes
[i
].u
.f
);
1838 varpool_assemble_decl (nodes
[i
].u
.v
);
1842 assemble_asm (nodes
[i
].u
.a
->asm_str
);
1845 case ORDER_UNDEFINED
:
1861 current_function_decl
= NULL
;
1862 gimple_register_cfg_hooks ();
1863 bitmap_obstack_initialize (NULL
);
1865 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START
, NULL
);
1869 execute_ipa_pass_list (all_small_ipa_passes
);
1874 /* We never run removal of unreachable nodes after early passes. This is
1875 because TODO is run before the subpasses. It is important to remove
1876 the unreachable functions to save works at IPA level and to get LTO
1877 symbol tables right. */
1878 symtab_remove_unreachable_nodes (true, cgraph_dump_file
);
1880 /* If pass_all_early_optimizations was not scheduled, the state of
1881 the cgraph will not be properly updated. Update it now. */
1882 if (cgraph_state
< CGRAPH_STATE_IPA_SSA
)
1883 cgraph_state
= CGRAPH_STATE_IPA_SSA
;
1887 /* Generate coverage variables and constructors. */
1890 /* Process new functions added. */
1892 current_function_decl
= NULL
;
1893 cgraph_process_new_functions ();
1895 execute_ipa_summary_passes
1896 ((struct ipa_opt_pass_d
*) all_regular_ipa_passes
);
1899 /* Some targets need to handle LTO assembler output specially. */
1900 if (flag_generate_lto
)
1901 targetm
.asm_out
.lto_start ();
1903 execute_ipa_summary_passes ((struct ipa_opt_pass_d
*) all_lto_gen_passes
);
1906 ipa_write_summaries ();
1908 if (flag_generate_lto
)
1909 targetm
.asm_out
.lto_end ();
1911 if (!flag_ltrans
&& (in_lto_p
|| !flag_lto
|| flag_fat_lto_objects
))
1912 execute_ipa_pass_list (all_regular_ipa_passes
);
1913 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END
, NULL
);
1915 bitmap_obstack_release (NULL
);
1919 /* Return string alias is alias of. */
1922 get_alias_symbol (tree decl
)
1924 tree alias
= lookup_attribute ("alias", DECL_ATTRIBUTES (decl
));
1925 return get_identifier (TREE_STRING_POINTER
1926 (TREE_VALUE (TREE_VALUE (alias
))));
1930 /* Weakrefs may be associated to external decls and thus not output
1931 at expansion time. Emit all necessary aliases. */
1934 output_weakrefs (void)
1936 struct cgraph_node
*node
;
1937 struct varpool_node
*vnode
;
1938 FOR_EACH_FUNCTION (node
)
1939 if (node
->alias
&& DECL_EXTERNAL (node
->symbol
.decl
)
1940 && !TREE_ASM_WRITTEN (node
->symbol
.decl
)
1941 && lookup_attribute ("weakref", DECL_ATTRIBUTES (node
->symbol
.decl
)))
1942 do_assemble_alias (node
->symbol
.decl
,
1943 node
->thunk
.alias
? DECL_ASSEMBLER_NAME (node
->thunk
.alias
)
1944 : get_alias_symbol (node
->symbol
.decl
));
1945 FOR_EACH_VARIABLE (vnode
)
1946 if (vnode
->alias
&& DECL_EXTERNAL (vnode
->symbol
.decl
)
1947 && !TREE_ASM_WRITTEN (vnode
->symbol
.decl
)
1948 && lookup_attribute ("weakref", DECL_ATTRIBUTES (vnode
->symbol
.decl
)))
1949 do_assemble_alias (vnode
->symbol
.decl
,
1950 vnode
->alias_of
? DECL_ASSEMBLER_NAME (vnode
->alias_of
)
1951 : get_alias_symbol (vnode
->symbol
.decl
));
1954 /* Initialize callgraph dump file. */
1959 if (!cgraph_dump_file
)
1960 cgraph_dump_file
= dump_begin (TDI_cgraph
, NULL
);
1964 /* Perform simple optimizations based on callgraph. */
1972 #ifdef ENABLE_CHECKING
1976 timevar_push (TV_CGRAPHOPT
);
1977 if (pre_ipa_mem_report
)
1979 fprintf (stderr
, "Memory consumption before IPA\n");
1980 dump_memory_report (false);
1983 fprintf (stderr
, "Performing interprocedural optimizations\n");
1984 cgraph_state
= CGRAPH_STATE_IPA
;
1986 /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE. */
1988 lto_streamer_hooks_init ();
1990 /* Don't run the IPA passes if there was any error or sorry messages. */
1994 /* Do nothing else if any IPA pass found errors or if we are just streaming LTO. */
1996 || (!in_lto_p
&& flag_lto
&& !flag_fat_lto_objects
))
1998 timevar_pop (TV_CGRAPHOPT
);
2002 /* This pass remove bodies of extern inline functions we never inlined.
2003 Do this later so other IPA passes see what is really going on. */
2004 symtab_remove_unreachable_nodes (false, dump_file
);
2005 cgraph_global_info_ready
= true;
2006 if (cgraph_dump_file
)
2008 fprintf (cgraph_dump_file
, "Optimized ");
2009 dump_symtab (cgraph_dump_file
);
2011 if (post_ipa_mem_report
)
2013 fprintf (stderr
, "Memory consumption after IPA\n");
2014 dump_memory_report (false);
2016 timevar_pop (TV_CGRAPHOPT
);
2018 /* Output everything. */
2019 (*debug_hooks
->assembly_start
) ();
2021 fprintf (stderr
, "Assembling functions:\n");
2022 #ifdef ENABLE_CHECKING
2026 cgraph_materialize_all_clones ();
2027 bitmap_obstack_initialize (NULL
);
2028 execute_ipa_pass_list (all_late_ipa_passes
);
2029 symtab_remove_unreachable_nodes (true, dump_file
);
2030 #ifdef ENABLE_CHECKING
2033 bitmap_obstack_release (NULL
);
2034 mark_functions_to_output ();
2036 cgraph_state
= CGRAPH_STATE_EXPANSION
;
2037 if (!flag_toplevel_reorder
)
2041 output_asm_statements ();
2043 expand_all_functions ();
2044 varpool_output_variables ();
2047 cgraph_process_new_functions ();
2048 cgraph_state
= CGRAPH_STATE_FINISHED
;
2051 if (cgraph_dump_file
)
2053 fprintf (cgraph_dump_file
, "\nFinal ");
2054 dump_symtab (cgraph_dump_file
);
2056 #ifdef ENABLE_CHECKING
2058 /* Double check that all inline clones are gone and that all
2059 function bodies have been released from memory. */
2062 struct cgraph_node
*node
;
2063 bool error_found
= false;
2065 FOR_EACH_DEFINED_FUNCTION (node
)
2066 if (node
->global
.inlined_to
2067 || gimple_has_body_p (node
->symbol
.decl
))
2070 dump_cgraph_node (stderr
, node
);
2073 internal_error ("nodes with unreleased memory found");
2079 /* Analyze the whole compilation unit once it is parsed completely. */
2082 finalize_compilation_unit (void)
2084 timevar_push (TV_CGRAPH
);
2086 /* If we're here there's no current function anymore. Some frontends
2087 are lazy in clearing these. */
2088 current_function_decl
= NULL
;
2091 /* Do not skip analyzing the functions if there were errors, we
2092 miss diagnostics for following functions otherwise. */
2094 /* Emit size functions we didn't inline. */
2095 finalize_size_functions ();
2097 /* Mark alias targets necessary and emit diagnostics. */
2098 handle_alias_pairs ();
2102 fprintf (stderr
, "\nAnalyzing compilation unit\n");
2106 if (flag_dump_passes
)
2109 /* Gimplify and lower all functions, compute reachability and
2110 remove unreachable nodes. */
2111 cgraph_analyze_functions ();
2113 /* Mark alias targets necessary and emit diagnostics. */
2114 handle_alias_pairs ();
2116 /* Gimplify and lower thunks. */
2117 cgraph_analyze_functions ();
2119 /* Finally drive the pass manager. */
2122 timevar_pop (TV_CGRAPH
);
2126 #include "gt-cgraphunit.h"