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_variable
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 neccesary 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"
183 #include "function.h"
184 #include "ipa-prop.h"
186 #include "tree-iterator.h"
187 #include "tree-pass.h"
188 #include "tree-dump.h"
189 #include "gimple-pretty-print.h"
191 #include "coverage.h"
193 #include "ipa-inline.h"
194 #include "ipa-utils.h"
195 #include "lto-streamer.h"
197 #include "regset.h" /* FIXME: For reg_obstack. */
199 /* Queue of cgraph nodes scheduled to be added into cgraph. This is a
200 secondary queue used during optimization to accommodate passes that
201 may generate new functions that need to be optimized and expanded. */
202 cgraph_node_set cgraph_new_nodes;
204 static void expand_all_functions (void);
205 static void mark_functions_to_output (void);
206 static void expand_function (struct cgraph_node *);
207 static void cgraph_analyze_function (struct cgraph_node *);
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 unnecesary 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 /* Note that this queue may grow as its being processed, as the new
288 functions may generate new ones. */
289 for (csi = csi_start (cgraph_new_nodes); !csi_end_p (csi); csi_next (&csi))
291 node = csi_node (csi);
292 fndecl = node->symbol.decl;
293 switch (cgraph_state)
295 case CGRAPH_STATE_CONSTRUCTION:
296 /* At construction time we just need to finalize function and move
297 it into reachable functions list. */
299 cgraph_finalize_function (fndecl, false);
301 cgraph_call_function_insertion_hooks (node);
302 enqueue_node ((symtab_node) node);
305 case CGRAPH_STATE_IPA:
306 case CGRAPH_STATE_IPA_SSA:
307 /* When IPA optimization already started, do all essential
308 transformations that has been already performed on the whole
309 cgraph but not on this function. */
311 gimple_register_cfg_hooks ();
313 cgraph_analyze_function (node);
314 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
315 current_function_decl = 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 current_function_decl = NULL;
328 cgraph_call_function_insertion_hooks (node);
331 case CGRAPH_STATE_EXPANSION:
332 /* Functions created during expansion shall be compiled
335 cgraph_call_function_insertion_hooks (node);
336 expand_function (node);
344 free_cgraph_node_set (cgraph_new_nodes);
345 cgraph_new_nodes = NULL;
349 /* As an GCC extension we allow redefinition of the function. The
350 semantics when both copies of bodies differ is not well defined.
351 We replace the old body with new body so in unit at a time mode
352 we always use new body, while in normal mode we may end up with
353 old body inlined into some functions and new body expanded and
356 ??? It may make more sense to use one body for inlining and other
357 body for expanding the function but this is difficult to do. */
360 cgraph_reset_node (struct cgraph_node *node)
362 /* If node->process is set, then we have already begun whole-unit analysis.
363 This is *not* testing for whether we've already emitted the function.
364 That case can be sort-of legitimately seen with real function redefinition
365 errors. I would argue that the front end should never present us with
366 such a case, but don't enforce that for now. */
367 gcc_assert (!node->process);
369 /* Reset our data structures so we can analyze the function again. */
370 memset (&node->local, 0, sizeof (node->local));
371 memset (&node->global, 0, sizeof (node->global));
372 memset (&node->rtl, 0, sizeof (node->rtl));
373 node->analyzed = false;
374 node->local.finalized = false;
376 cgraph_node_remove_callees (node);
379 /* Return true when there are references to NODE. */
382 referred_to_p (symtab_node node)
386 /* See if there are any refrences at all. */
387 if (ipa_ref_list_referring_iterate (&node->symbol.ref_list, 0, ref))
389 /* For functions check also calls. */
390 if (symtab_function_p (node) && cgraph (node)->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 current_function_decl = fndecl;
498 gimple_register_cfg_hooks ();
499 bitmap_obstack_initialize (NULL);
500 execute_pass_list (all_lowering_passes);
501 execute_pass_list (pass_early_local_passes.pass.sub);
502 bitmap_obstack_release (NULL);
504 current_function_decl = NULL;
509 node->lowered = true;
510 if (!cgraph_new_nodes)
511 cgraph_new_nodes = cgraph_node_set_new ();
512 cgraph_node_set_add (cgraph_new_nodes, node);
515 case CGRAPH_STATE_FINISHED:
516 /* At the very end of compilation we have to do all the work up
518 node = cgraph_create_node (fndecl);
520 node->lowered = true;
521 cgraph_analyze_function (node);
522 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
523 current_function_decl = fndecl;
524 gimple_register_cfg_hooks ();
525 bitmap_obstack_initialize (NULL);
526 if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
527 execute_pass_list (pass_early_local_passes.pass.sub);
528 bitmap_obstack_release (NULL);
530 expand_function (node);
531 current_function_decl = NULL;
538 /* Set a personality if required and we already passed EH lowering. */
540 && (function_needs_eh_personality (DECL_STRUCT_FUNCTION (fndecl))
541 == eh_personality_lang))
542 DECL_FUNCTION_PERSONALITY (fndecl) = lang_hooks.eh_personality ();
545 /* Add a top-level asm statement to the list. */
548 add_asm_node (tree asm_str)
550 struct asm_node *node;
552 node = ggc_alloc_cleared_asm_node ();
553 node->asm_str = asm_str;
554 node->order = symtab_order++;
556 if (asm_nodes == NULL)
559 asm_last_node->next = node;
560 asm_last_node = node;
564 /* Output all asm statements we have stored up to be output. */
567 output_asm_statements (void)
569 struct asm_node *can;
574 for (can = asm_nodes; can; can = can->next)
575 assemble_asm (can->asm_str);
579 /* C++ FE sometimes change linkage flags after producing same body aliases. */
581 fixup_same_cpp_alias_visibility (symtab_node node, symtab_node target, tree alias)
583 DECL_VIRTUAL_P (node->symbol.decl) = DECL_VIRTUAL_P (alias);
584 if (TREE_PUBLIC (node->symbol.decl))
586 DECL_EXTERNAL (node->symbol.decl) = DECL_EXTERNAL (alias);
587 DECL_COMDAT (node->symbol.decl) = DECL_COMDAT (alias);
588 DECL_COMDAT_GROUP (node->symbol.decl) = DECL_COMDAT_GROUP (alias);
589 if (DECL_ONE_ONLY (alias)
590 && !node->symbol.same_comdat_group)
591 symtab_add_to_same_comdat_group ((symtab_node)node, (symtab_node)target);
595 /* Analyze the function scheduled to be output. */
597 cgraph_analyze_function (struct cgraph_node *node)
599 tree save = current_function_decl;
600 tree decl = node->symbol.decl;
601 location_t saved_loc = input_location;
602 input_location = DECL_SOURCE_LOCATION (decl);
604 if (node->alias && node->thunk.alias)
606 struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias);
607 struct cgraph_node *n;
609 for (n = tgt; n && n->alias;
610 n = n->analyzed ? cgraph_alias_aliased_node (n) : NULL)
613 error ("function %q+D part of alias cycle", node->symbol.decl);
615 input_location = saved_loc;
618 if (!VEC_length (ipa_ref_t, node->symbol.ref_list.references))
619 ipa_record_reference ((symtab_node)node, (symtab_node)tgt,
620 IPA_REF_ALIAS, NULL);
621 if (node->same_body_alias)
623 DECL_DECLARED_INLINE_P (node->symbol.decl)
624 = DECL_DECLARED_INLINE_P (node->thunk.alias);
625 DECL_DISREGARD_INLINE_LIMITS (node->symbol.decl)
626 = DECL_DISREGARD_INLINE_LIMITS (node->thunk.alias);
627 fixup_same_cpp_alias_visibility ((symtab_node) node, (symtab_node) tgt, node->thunk.alias);
630 if (node->symbol.address_taken)
631 cgraph_mark_address_taken_node (cgraph_alias_aliased_node (node));
633 else if (node->thunk.thunk_p)
635 cgraph_create_edge (node, cgraph_get_node (node->thunk.alias),
636 NULL, 0, CGRAPH_FREQ_BASE);
640 current_function_decl = decl;
641 push_cfun (DECL_STRUCT_FUNCTION (decl));
643 assign_assembler_name_if_neeeded (node->symbol.decl);
645 /* Make sure to gimplify bodies only once. During analyzing a
646 function we lower it, which will require gimplified nested
647 functions, so we can end up here with an already gimplified
649 if (!gimple_has_body_p (decl))
650 gimplify_function_tree (decl);
651 dump_function (TDI_generic, decl);
653 /* Lower the function. */
657 lower_nested_functions (node->symbol.decl);
658 gcc_assert (!node->nested);
660 gimple_register_cfg_hooks ();
661 bitmap_obstack_initialize (NULL);
662 execute_pass_list (all_lowering_passes);
663 free_dominance_info (CDI_POST_DOMINATORS);
664 free_dominance_info (CDI_DOMINATORS);
666 bitmap_obstack_release (NULL);
667 node->lowered = true;
672 node->analyzed = true;
674 current_function_decl = save;
675 input_location = saved_loc;
678 /* C++ frontend produce same body aliases all over the place, even before PCH
679 gets streamed out. It relies on us linking the aliases with their function
680 in order to do the fixups, but ipa-ref is not PCH safe. Consequentely we
681 first produce aliases without links, but once C++ FE is sure he won't sream
682 PCH we build the links via this function. */
685 cgraph_process_same_body_aliases (void)
687 struct cgraph_node *node;
688 FOR_EACH_FUNCTION (node)
689 if (node->same_body_alias
690 && !VEC_length (ipa_ref_t, node->symbol.ref_list.references))
692 struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias);
693 ipa_record_reference ((symtab_node)node, (symtab_node)tgt,
694 IPA_REF_ALIAS, NULL);
696 same_body_aliases_done = true;
699 /* Process attributes common for vars and functions. */
702 process_common_attributes (tree decl)
704 tree weakref = lookup_attribute ("weakref", DECL_ATTRIBUTES (decl));
706 if (weakref && !lookup_attribute ("alias", DECL_ATTRIBUTES (decl)))
708 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
709 "%<weakref%> attribute should be accompanied with"
710 " an %<alias%> attribute");
711 DECL_WEAK (decl) = 0;
712 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
713 DECL_ATTRIBUTES (decl));
717 /* Look for externally_visible and used attributes and mark cgraph nodes
720 We cannot mark the nodes at the point the attributes are processed (in
721 handle_*_attribute) because the copy of the declarations available at that
722 point may not be canonical. For example, in:
725 void f() __attribute__((used));
727 the declaration we see in handle_used_attribute will be the second
728 declaration -- but the front end will subsequently merge that declaration
729 with the original declaration and discard the second declaration.
731 Furthermore, we can't mark these nodes in cgraph_finalize_function because:
734 void f() __attribute__((externally_visible));
738 So, we walk the nodes at the end of the translation unit, applying the
739 attributes at that point. */
742 process_function_and_variable_attributes (struct cgraph_node *first,
743 struct varpool_node *first_var)
745 struct cgraph_node *node;
746 struct varpool_node *vnode;
748 for (node = cgraph_first_function (); node != first;
749 node = cgraph_next_function (node))
751 tree decl = node->symbol.decl;
752 if (DECL_PRESERVE_P (decl))
753 cgraph_mark_force_output_node (node);
754 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
756 if (! TREE_PUBLIC (node->symbol.decl))
757 warning_at (DECL_SOURCE_LOCATION (node->symbol.decl), OPT_Wattributes,
758 "%<externally_visible%>"
759 " attribute have effect only on public objects");
761 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
762 && (node->local.finalized && !node->alias))
764 warning_at (DECL_SOURCE_LOCATION (node->symbol.decl), OPT_Wattributes,
765 "%<weakref%> attribute ignored"
766 " because function is defined");
767 DECL_WEAK (decl) = 0;
768 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
769 DECL_ATTRIBUTES (decl));
772 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl))
773 && !DECL_DECLARED_INLINE_P (decl)
774 /* redefining extern inline function makes it DECL_UNINLINABLE. */
775 && !DECL_UNINLINABLE (decl))
776 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
777 "always_inline function might not be inlinable");
779 process_common_attributes (decl);
781 for (vnode = varpool_first_variable (); vnode != first_var;
782 vnode = varpool_next_variable (vnode))
784 tree decl = vnode->symbol.decl;
785 if (DECL_EXTERNAL (decl)
786 && DECL_INITIAL (decl)
787 && const_value_known_p (decl))
788 varpool_finalize_decl (decl);
789 if (DECL_PRESERVE_P (decl))
790 vnode->symbol.force_output = true;
791 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
793 if (! TREE_PUBLIC (vnode->symbol.decl))
794 warning_at (DECL_SOURCE_LOCATION (vnode->symbol.decl), OPT_Wattributes,
795 "%<externally_visible%>"
796 " attribute have effect only on public objects");
798 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
800 && DECL_INITIAL (decl))
802 warning_at (DECL_SOURCE_LOCATION (vnode->symbol.decl), OPT_Wattributes,
803 "%<weakref%> attribute ignored"
804 " because variable is initialized");
805 DECL_WEAK (decl) = 0;
806 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
807 DECL_ATTRIBUTES (decl));
809 process_common_attributes (decl);
813 /* Mark DECL as finalized. By finalizing the declaration, frontend instruct the
814 middle end to output the variable to asm file, if needed or externally
818 varpool_finalize_decl (tree decl)
820 struct varpool_node *node = varpool_node (decl);
822 gcc_assert (TREE_STATIC (decl) || DECL_EXTERNAL (decl));
826 notice_global_symbol (decl);
827 node->finalized = true;
828 if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
829 /* Traditionally we do not eliminate static variables when not
830 optimizing and when not doing toplevel reoder. */
831 || (!flag_toplevel_reorder && !DECL_COMDAT (node->symbol.decl)
832 && !DECL_ARTIFICIAL (node->symbol.decl)))
833 node->symbol.force_output = true;
835 if (cgraph_state == CGRAPH_STATE_CONSTRUCTION
836 && (decide_is_variable_needed (node, decl)
837 || referred_to_p ((symtab_node)node)))
838 enqueue_node ((symtab_node)node);
839 if (cgraph_state >= CGRAPH_STATE_IPA_SSA)
840 varpool_analyze_node (node);
841 /* Some frontends produce various interface variables after compilation
843 if (cgraph_state == CGRAPH_STATE_FINISHED)
844 varpool_assemble_decl (node);
847 /* Discover all functions and variables that are trivially needed, analyze
848 them as well as all functions and variables referred by them */
851 cgraph_analyze_functions (void)
853 /* Keep track of already processed nodes when called multiple times for
854 intermodule optimization. */
855 static struct cgraph_node *first_analyzed;
856 struct cgraph_node *first_handled = first_analyzed;
857 static struct varpool_node *first_analyzed_var;
858 struct varpool_node *first_handled_var = first_analyzed_var;
860 symtab_node node, next;
865 bitmap_obstack_initialize (NULL);
866 cgraph_state = CGRAPH_STATE_CONSTRUCTION;
868 /* Analysis adds static variables that in turn adds references to new functions.
869 So we need to iterate the process until it stabilize. */
873 process_function_and_variable_attributes (first_analyzed,
876 /* First identify the trivially needed symbols. */
877 for (node = symtab_nodes;
878 node != (symtab_node)first_analyzed
879 && node != (symtab_node)first_analyzed_var; node = node->symbol.next)
881 if ((symtab_function_p (node)
882 && cgraph (node)->local.finalized
883 && cgraph_decide_is_function_needed (cgraph (node), node->symbol.decl))
884 || (symtab_variable_p (node)
885 && varpool (node)->finalized
886 && !DECL_EXTERNAL (node->symbol.decl)
887 && decide_is_variable_needed (varpool (node), node->symbol.decl)))
890 if (!changed && cgraph_dump_file)
891 fprintf (cgraph_dump_file, "Trivially needed symbols:");
893 if (cgraph_dump_file)
894 fprintf (cgraph_dump_file, " %s", symtab_node_asm_name (node));
896 if (node == (symtab_node)first_analyzed
897 || node == (symtab_node)first_analyzed_var)
900 cgraph_process_new_functions ();
901 first_analyzed_var = varpool_first_variable ();
902 first_analyzed = cgraph_first_function ();
904 if (changed && dump_file)
905 fprintf (cgraph_dump_file, "\n");
907 /* Lower representation, build callgraph edges and references for all trivially
908 needed symbols and all symbols referred by them. */
909 while (first != (symtab_node)(void *)1)
913 first = (symtab_node)first->symbol.aux;
914 if (symtab_function_p (node) && cgraph (node)->local.finalized)
916 struct cgraph_edge *edge;
917 struct cgraph_node *cnode;
920 cnode = cgraph (node);
921 decl = cnode->symbol.decl;
923 /* ??? It is possible to create extern inline function and later using
924 weak alias attribute to kill its body. See
925 gcc.c-torture/compile/20011119-1.c */
926 if (!DECL_STRUCT_FUNCTION (decl)
927 && (!cnode->alias || !cnode->thunk.alias)
928 && !cnode->thunk.thunk_p)
930 cgraph_reset_node (cnode);
931 cnode->local.redefined_extern_inline = true;
935 if (!cnode->analyzed)
936 cgraph_analyze_function (cnode);
938 for (edge = cnode->callees; edge; edge = edge->next_callee)
939 if (edge->callee->local.finalized)
940 enqueue_node ((symtab_node)edge->callee);
942 /* If decl is a clone of an abstract function, mark that abstract
943 function so that we don't release its body. The DECL_INITIAL() of that
944 abstract function declaration will be later needed to output debug
946 if (DECL_ABSTRACT_ORIGIN (decl))
948 struct cgraph_node *origin_node;
949 origin_node = cgraph_get_node (DECL_ABSTRACT_ORIGIN (decl));
950 origin_node->abstract_and_needed = true;
954 else if (symtab_variable_p (node)
955 && varpool (node)->finalized)
956 varpool_analyze_node (varpool (node));
958 if (node->symbol.same_comdat_group)
961 for (next = node->symbol.same_comdat_group;
963 next = next->symbol.same_comdat_group)
966 for (i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list, i, ref); i++)
967 if ((symtab_function_p (ref->referred) && cgraph (ref->referred)->local.finalized)
968 || (symtab_variable_p (ref->referred) && varpool (ref->referred)->finalized))
969 enqueue_node (ref->referred);
970 cgraph_process_new_functions ();
974 /* Collect entry points to the unit. */
975 if (cgraph_dump_file)
977 fprintf (cgraph_dump_file, "\n\nInitial ");
978 dump_symtab (cgraph_dump_file);
981 if (cgraph_dump_file)
982 fprintf (cgraph_dump_file, "\nRemoving unused symbols:");
984 for (node = symtab_nodes;
985 node != (symtab_node)first_handled
986 && node != (symtab_node)first_handled_var; node = next)
988 next = node->symbol.next;
989 if (!node->symbol.aux && !referred_to_p (node))
991 if (cgraph_dump_file)
992 fprintf (cgraph_dump_file, " %s", symtab_node_name (node));
993 symtab_remove_node (node);
996 if (symtab_function_p (node))
998 tree decl = node->symbol.decl;
999 struct cgraph_node *cnode = cgraph (node);
1001 if (cnode->local.finalized && !gimple_has_body_p (decl)
1002 && (!cnode->alias || !cnode->thunk.alias)
1003 && !cnode->thunk.thunk_p)
1004 cgraph_reset_node (cnode);
1006 gcc_assert (!cnode->local.finalized || cnode->thunk.thunk_p
1008 || gimple_has_body_p (decl));
1009 gcc_assert (cnode->analyzed == cnode->local.finalized);
1011 node->symbol.aux = NULL;
1013 first_analyzed = cgraph_first_function ();
1014 first_analyzed_var = varpool_first_variable ();
1015 if (cgraph_dump_file)
1017 fprintf (cgraph_dump_file, "\n\nReclaimed ");
1018 dump_symtab (cgraph_dump_file);
1020 bitmap_obstack_release (NULL);
1024 /* Translate the ugly representation of aliases as alias pairs into nice
1025 representation in callgraph. We don't handle all cases yet,
1029 handle_alias_pairs (void)
1034 for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p);)
1036 symtab_node target_node = symtab_node_for_asm (p->target);
1038 /* Weakrefs with target not defined in current unit are easy to handle; they
1039 behave just as external variables except we need to note the alias flag
1040 to later output the weakref pseudo op into asm file. */
1041 if (!target_node && lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL)
1043 if (TREE_CODE (p->decl) == FUNCTION_DECL)
1044 cgraph_get_create_node (p->decl)->alias = true;
1046 varpool_get_node (p->decl)->alias = true;
1047 DECL_EXTERNAL (p->decl) = 1;
1048 VEC_unordered_remove (alias_pair, alias_pairs, i);
1051 else if (!target_node)
1053 error ("%q+D aliased to undefined symbol %qE", p->decl, p->target);
1054 VEC_unordered_remove (alias_pair, alias_pairs, i);
1058 /* Normally EXTERNAL flag is used to mark external inlines,
1059 however for aliases it seems to be allowed to use it w/o
1060 any meaning. See gcc.dg/attr-alias-3.c
1061 However for weakref we insist on EXTERNAL flag being set.
1062 See gcc.dg/attr-alias-5.c */
1063 if (DECL_EXTERNAL (p->decl))
1064 DECL_EXTERNAL (p->decl)
1065 = lookup_attribute ("weakref",
1066 DECL_ATTRIBUTES (p->decl)) != NULL;
1068 if (TREE_CODE (p->decl) == FUNCTION_DECL
1069 && target_node && symtab_function_p (target_node))
1071 struct cgraph_node *src_node = cgraph_get_node (p->decl);
1072 if (src_node && src_node->local.finalized)
1073 cgraph_reset_node (src_node);
1074 cgraph_create_function_alias (p->decl, target_node->symbol.decl);
1075 VEC_unordered_remove (alias_pair, alias_pairs, i);
1077 else if (TREE_CODE (p->decl) == VAR_DECL
1078 && target_node && symtab_variable_p (target_node))
1080 varpool_create_variable_alias (p->decl, target_node->symbol.decl);
1081 VEC_unordered_remove (alias_pair, alias_pairs, i);
1085 error ("%q+D alias in between function and variable is not supported",
1087 warning (0, "%q+D aliased declaration",
1088 target_node->symbol.decl);
1089 VEC_unordered_remove (alias_pair, alias_pairs, i);
1095 /* Figure out what functions we want to assemble. */
1098 mark_functions_to_output (void)
1100 struct cgraph_node *node;
1101 #ifdef ENABLE_CHECKING
1102 bool check_same_comdat_groups = false;
1104 FOR_EACH_FUNCTION (node)
1105 gcc_assert (!node->process);
1108 FOR_EACH_FUNCTION (node)
1110 tree decl = node->symbol.decl;
1112 gcc_assert (!node->process || node->symbol.same_comdat_group);
1116 /* We need to output all local functions that are used and not
1117 always inlined, as well as those that are reachable from
1118 outside the current compilation unit. */
1120 && !node->thunk.thunk_p
1122 && !node->global.inlined_to
1123 && !TREE_ASM_WRITTEN (decl)
1124 && !DECL_EXTERNAL (decl))
1127 if (node->symbol.same_comdat_group)
1129 struct cgraph_node *next;
1130 for (next = cgraph (node->symbol.same_comdat_group);
1132 next = cgraph (next->symbol.same_comdat_group))
1133 if (!next->thunk.thunk_p && !next->alias)
1137 else if (node->symbol.same_comdat_group)
1139 #ifdef ENABLE_CHECKING
1140 check_same_comdat_groups = true;
1145 /* We should've reclaimed all functions that are not needed. */
1146 #ifdef ENABLE_CHECKING
1147 if (!node->global.inlined_to
1148 && gimple_has_body_p (decl)
1149 /* FIXME: in ltrans unit when offline copy is outside partition but inline copies
1150 are inside partition, we can end up not removing the body since we no longer
1151 have analyzed node pointing to it. */
1152 && !node->symbol.in_other_partition
1155 && !DECL_EXTERNAL (decl))
1157 dump_cgraph_node (stderr, node);
1158 internal_error ("failed to reclaim unneeded function");
1161 gcc_assert (node->global.inlined_to
1162 || !gimple_has_body_p (decl)
1163 || node->symbol.in_other_partition
1165 || DECL_ARTIFICIAL (decl)
1166 || DECL_EXTERNAL (decl));
1171 #ifdef ENABLE_CHECKING
1172 if (check_same_comdat_groups)
1173 FOR_EACH_FUNCTION (node)
1174 if (node->symbol.same_comdat_group && !node->process)
1176 tree decl = node->symbol.decl;
1177 if (!node->global.inlined_to
1178 && gimple_has_body_p (decl)
1179 /* FIXME: in an ltrans unit when the offline copy is outside a
1180 partition but inline copies are inside a partition, we can
1181 end up not removing the body since we no longer have an
1182 analyzed node pointing to it. */
1183 && !node->symbol.in_other_partition
1184 && !DECL_EXTERNAL (decl))
1186 dump_cgraph_node (stderr, node);
1187 internal_error ("failed to reclaim unneeded function in same "
1194 /* DECL is FUNCTION_DECL. Initialize datastructures so DECL is a function
1195 in lowered gimple form.
1197 Set current_function_decl and cfun to newly constructed empty function body.
1198 return basic block in the function body. */
1201 init_lowered_empty_function (tree decl)
1205 current_function_decl = decl;
1206 allocate_struct_function (decl, false);
1207 gimple_register_cfg_hooks ();
1208 init_empty_tree_cfg ();
1209 init_tree_ssa (cfun);
1210 init_ssa_operands ();
1211 cfun->gimple_df->in_ssa_p = true;
1212 DECL_INITIAL (decl) = make_node (BLOCK);
1214 DECL_SAVED_TREE (decl) = error_mark_node;
1215 cfun->curr_properties |=
1216 (PROP_gimple_lcf | PROP_gimple_leh | PROP_cfg | PROP_referenced_vars |
1217 PROP_ssa | PROP_gimple_any);
1219 /* Create BB for body of the function and connect it properly. */
1220 bb = create_basic_block (NULL, (void *) 0, ENTRY_BLOCK_PTR);
1221 make_edge (ENTRY_BLOCK_PTR, bb, 0);
1222 make_edge (bb, EXIT_BLOCK_PTR, 0);
1227 /* Adjust PTR by the constant FIXED_OFFSET, and by the vtable
1228 offset indicated by VIRTUAL_OFFSET, if that is
1229 non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and
1230 zero for a result adjusting thunk. */
1233 thunk_adjust (gimple_stmt_iterator * bsi,
1234 tree ptr, bool this_adjusting,
1235 HOST_WIDE_INT fixed_offset, tree virtual_offset)
1241 && fixed_offset != 0)
1243 stmt = gimple_build_assign
1244 (ptr, fold_build_pointer_plus_hwi_loc (input_location,
1247 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1250 /* If there's a virtual offset, look up that value in the vtable and
1251 adjust the pointer again. */
1258 if (!vtable_entry_type)
1260 tree vfunc_type = make_node (FUNCTION_TYPE);
1261 TREE_TYPE (vfunc_type) = integer_type_node;
1262 TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
1263 layout_type (vfunc_type);
1265 vtable_entry_type = build_pointer_type (vfunc_type);
1269 make_rename_temp (build_pointer_type
1270 (build_pointer_type (vtable_entry_type)), "vptr");
1272 /* The vptr is always at offset zero in the object. */
1273 stmt = gimple_build_assign (vtabletmp,
1274 build1 (NOP_EXPR, TREE_TYPE (vtabletmp),
1276 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1278 /* Form the vtable address. */
1279 vtabletmp2 = make_rename_temp (TREE_TYPE (TREE_TYPE (vtabletmp)),
1281 stmt = gimple_build_assign (vtabletmp2,
1282 build_simple_mem_ref (vtabletmp));
1283 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1285 /* Find the entry with the vcall offset. */
1286 stmt = gimple_build_assign (vtabletmp2,
1287 fold_build_pointer_plus_loc (input_location,
1290 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1292 /* Get the offset itself. */
1293 vtabletmp3 = make_rename_temp (TREE_TYPE (TREE_TYPE (vtabletmp2)),
1295 stmt = gimple_build_assign (vtabletmp3,
1296 build_simple_mem_ref (vtabletmp2));
1297 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1299 /* Adjust the `this' pointer. */
1300 ptr = fold_build_pointer_plus_loc (input_location, ptr, vtabletmp3);
1301 ptr = force_gimple_operand_gsi (bsi, ptr, true, NULL_TREE, false,
1302 GSI_CONTINUE_LINKING);
1306 && fixed_offset != 0)
1307 /* Adjust the pointer by the constant. */
1311 if (TREE_CODE (ptr) == VAR_DECL)
1315 ptrtmp = make_rename_temp (TREE_TYPE (ptr), "ptr");
1316 stmt = gimple_build_assign (ptrtmp, ptr);
1317 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1319 ptr = fold_build_pointer_plus_hwi_loc (input_location,
1320 ptrtmp, fixed_offset);
1323 /* Emit the statement and gimplify the adjustment expression. */
1324 ret = make_rename_temp (TREE_TYPE (ptr), "adjusted_this");
1325 stmt = gimple_build_assign (ret, ptr);
1326 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1331 /* Produce assembler for thunk NODE. */
1334 assemble_thunk (struct cgraph_node *node)
1336 bool this_adjusting = node->thunk.this_adjusting;
1337 HOST_WIDE_INT fixed_offset = node->thunk.fixed_offset;
1338 HOST_WIDE_INT virtual_value = node->thunk.virtual_value;
1339 tree virtual_offset = NULL;
1340 tree alias = node->thunk.alias;
1341 tree thunk_fndecl = node->symbol.decl;
1342 tree a = DECL_ARGUMENTS (thunk_fndecl);
1344 current_function_decl = thunk_fndecl;
1346 /* Ensure thunks are emitted in their correct sections. */
1347 resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
1350 && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
1351 virtual_value, alias))
1355 tree restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1357 DECL_RESULT (thunk_fndecl)
1358 = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl),
1359 RESULT_DECL, 0, restype);
1360 fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
1362 /* The back end expects DECL_INITIAL to contain a BLOCK, so we
1364 fn_block = make_node (BLOCK);
1365 BLOCK_VARS (fn_block) = a;
1366 DECL_INITIAL (thunk_fndecl) = fn_block;
1367 init_function_start (thunk_fndecl);
1369 assemble_start_function (thunk_fndecl, fnname);
1371 targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl,
1372 fixed_offset, virtual_value, alias);
1374 assemble_end_function (thunk_fndecl, fnname);
1375 init_insn_lengths ();
1376 free_after_compilation (cfun);
1378 TREE_ASM_WRITTEN (thunk_fndecl) = 1;
1379 node->thunk.thunk_p = false;
1380 node->analyzed = false;
1385 basic_block bb, then_bb, else_bb, return_bb;
1386 gimple_stmt_iterator bsi;
1392 VEC(tree, heap) *vargs;
1397 DECL_IGNORED_P (thunk_fndecl) = 1;
1398 bitmap_obstack_initialize (NULL);
1400 if (node->thunk.virtual_offset_p)
1401 virtual_offset = size_int (virtual_value);
1403 /* Build the return declaration for the function. */
1404 restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1405 if (DECL_RESULT (thunk_fndecl) == NULL_TREE)
1407 resdecl = build_decl (input_location, RESULT_DECL, 0, restype);
1408 DECL_ARTIFICIAL (resdecl) = 1;
1409 DECL_IGNORED_P (resdecl) = 1;
1410 DECL_RESULT (thunk_fndecl) = resdecl;
1413 resdecl = DECL_RESULT (thunk_fndecl);
1415 bb = then_bb = else_bb = return_bb = init_lowered_empty_function (thunk_fndecl);
1417 bsi = gsi_start_bb (bb);
1419 /* Build call to the function being thunked. */
1420 if (!VOID_TYPE_P (restype))
1422 if (!is_gimple_reg_type (restype))
1425 add_local_decl (cfun, restmp);
1426 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp;
1429 restmp = make_rename_temp (restype, "retval");
1432 for (arg = a; arg; arg = DECL_CHAIN (arg))
1434 vargs = VEC_alloc (tree, heap, nargs);
1436 VEC_quick_push (tree, vargs,
1441 VEC_quick_push (tree, vargs, a);
1442 add_referenced_var (a);
1443 if (is_gimple_reg (a))
1444 mark_sym_for_renaming (a);
1445 for (i = 1, arg = DECL_CHAIN (a); i < nargs; i++, arg = DECL_CHAIN (arg))
1447 add_referenced_var (arg);
1448 if (is_gimple_reg (arg))
1449 mark_sym_for_renaming (arg);
1450 VEC_quick_push (tree, vargs, arg);
1452 call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs);
1453 VEC_free (tree, heap, vargs);
1454 gimple_call_set_from_thunk (call, true);
1456 gimple_call_set_lhs (call, restmp);
1457 gsi_insert_after (&bsi, call, GSI_NEW_STMT);
1459 if (restmp && !this_adjusting)
1461 tree true_label = NULL_TREE;
1463 if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE)
1466 /* If the return type is a pointer, we need to
1467 protect against NULL. We know there will be an
1468 adjustment, because that's why we're emitting a
1470 then_bb = create_basic_block (NULL, (void *) 0, bb);
1471 return_bb = create_basic_block (NULL, (void *) 0, then_bb);
1472 else_bb = create_basic_block (NULL, (void *) 0, else_bb);
1473 remove_edge (single_succ_edge (bb));
1474 true_label = gimple_block_label (then_bb);
1475 stmt = gimple_build_cond (NE_EXPR, restmp,
1476 build_zero_cst (TREE_TYPE (restmp)),
1477 NULL_TREE, NULL_TREE);
1478 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1479 make_edge (bb, then_bb, EDGE_TRUE_VALUE);
1480 make_edge (bb, else_bb, EDGE_FALSE_VALUE);
1481 make_edge (return_bb, EXIT_BLOCK_PTR, 0);
1482 make_edge (then_bb, return_bb, EDGE_FALLTHRU);
1483 make_edge (else_bb, return_bb, EDGE_FALLTHRU);
1484 bsi = gsi_last_bb (then_bb);
1487 restmp = thunk_adjust (&bsi, restmp, /*this_adjusting=*/0,
1488 fixed_offset, virtual_offset);
1492 bsi = gsi_last_bb (else_bb);
1493 stmt = gimple_build_assign (restmp,
1494 build_zero_cst (TREE_TYPE (restmp)));
1495 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1496 bsi = gsi_last_bb (return_bb);
1500 gimple_call_set_tail (call, true);
1502 /* Build return value. */
1503 ret = gimple_build_return (restmp);
1504 gsi_insert_after (&bsi, ret, GSI_NEW_STMT);
1506 delete_unreachable_blocks ();
1507 update_ssa (TODO_update_ssa);
1509 /* Since we want to emit the thunk, we explicitly mark its name as
1511 node->thunk.thunk_p = false;
1512 cgraph_node_remove_callees (node);
1513 cgraph_add_new_function (thunk_fndecl, true);
1514 bitmap_obstack_release (NULL);
1516 current_function_decl = NULL;
1521 /* Assemble thunks and aliases asociated to NODE. */
1524 assemble_thunks_and_aliases (struct cgraph_node *node)
1526 struct cgraph_edge *e;
1528 struct ipa_ref *ref;
1530 for (e = node->callers; e;)
1531 if (e->caller->thunk.thunk_p)
1533 struct cgraph_node *thunk = e->caller;
1536 assemble_thunks_and_aliases (thunk);
1537 assemble_thunk (thunk);
1541 for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list,
1543 if (ref->use == IPA_REF_ALIAS)
1545 struct cgraph_node *alias = ipa_ref_referring_node (ref);
1546 bool saved_written = TREE_ASM_WRITTEN (alias->thunk.alias);
1548 /* Force assemble_alias to really output the alias this time instead
1549 of buffering it in same alias pairs. */
1550 TREE_ASM_WRITTEN (alias->thunk.alias) = 1;
1551 assemble_alias (alias->symbol.decl,
1552 DECL_ASSEMBLER_NAME (alias->thunk.alias));
1553 assemble_thunks_and_aliases (alias);
1554 TREE_ASM_WRITTEN (alias->thunk.alias) = saved_written;
1558 /* Expand function specified by NODE. */
1561 expand_function (struct cgraph_node *node)
1563 tree decl = node->symbol.decl;
1564 location_t saved_loc;
1566 /* We ought to not compile any inline clones. */
1567 gcc_assert (!node->global.inlined_to);
1569 announce_function (decl);
1571 gcc_assert (node->lowered);
1573 /* Generate RTL for the body of DECL. */
1575 timevar_push (TV_REST_OF_COMPILATION);
1577 gcc_assert (cgraph_global_info_ready);
1579 /* Initialize the default bitmap obstack. */
1580 bitmap_obstack_initialize (NULL);
1582 /* Initialize the RTL code for the function. */
1583 current_function_decl = decl;
1584 saved_loc = input_location;
1585 input_location = DECL_SOURCE_LOCATION (decl);
1586 init_function_start (decl);
1588 gimple_register_cfg_hooks ();
1590 bitmap_obstack_initialize (®_obstack); /* FIXME, only at RTL generation*/
1592 execute_all_ipa_transforms ();
1594 /* Perform all tree transforms and optimizations. */
1596 /* Signal the start of passes. */
1597 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START, NULL);
1599 execute_pass_list (all_passes);
1601 /* Signal the end of passes. */
1602 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END, NULL);
1604 bitmap_obstack_release (®_obstack);
1606 /* Release the default bitmap obstack. */
1607 bitmap_obstack_release (NULL);
1611 /* If requested, warn about function definitions where the function will
1612 return a value (usually of some struct or union type) which itself will
1613 take up a lot of stack space. */
1614 if (warn_larger_than && !DECL_EXTERNAL (decl) && TREE_TYPE (decl))
1616 tree ret_type = TREE_TYPE (TREE_TYPE (decl));
1618 if (ret_type && TYPE_SIZE_UNIT (ret_type)
1619 && TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST
1620 && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type),
1623 unsigned int size_as_int
1624 = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type));
1626 if (compare_tree_int (TYPE_SIZE_UNIT (ret_type), size_as_int) == 0)
1627 warning (OPT_Wlarger_than_, "size of return value of %q+D is %u bytes",
1630 warning (OPT_Wlarger_than_, "size of return value of %q+D is larger than %wd bytes",
1631 decl, larger_than_size);
1635 gimple_set_body (decl, NULL);
1636 if (DECL_STRUCT_FUNCTION (decl) == 0
1637 && !cgraph_get_node (decl)->origin)
1639 /* Stop pointing to the local nodes about to be freed.
1640 But DECL_INITIAL must remain nonzero so we know this
1641 was an actual function definition.
1642 For a nested function, this is done in c_pop_function_context.
1643 If rest_of_compilation set this to 0, leave it 0. */
1644 if (DECL_INITIAL (decl) != 0)
1645 DECL_INITIAL (decl) = error_mark_node;
1648 input_location = saved_loc;
1651 timevar_pop (TV_REST_OF_COMPILATION);
1653 /* Make sure that BE didn't give up on compiling. */
1654 gcc_assert (TREE_ASM_WRITTEN (decl));
1655 current_function_decl = NULL;
1657 /* It would make a lot more sense to output thunks before function body to get more
1658 forward and lest backwarding jumps. This however would need solving problem
1659 with comdats. See PR48668. Also aliases must come after function itself to
1660 make one pass assemblers, like one on AIX, happy. See PR 50689.
1661 FIXME: Perhaps thunks should be move before function IFF they are not in comdat
1663 assemble_thunks_and_aliases (node);
1664 cgraph_release_function_body (node);
1665 /* Eliminate all call edges. This is important so the GIMPLE_CALL no longer
1666 points to the dead function body. */
1667 cgraph_node_remove_callees (node);
1671 /* Expand all functions that must be output.
1673 Attempt to topologically sort the nodes so function is output when
1674 all called functions are already assembled to allow data to be
1675 propagated across the callgraph. Use a stack to get smaller distance
1676 between a function and its callees (later we may choose to use a more
1677 sophisticated algorithm for function reordering; we will likely want
1678 to use subsections to make the output functions appear in top-down
1682 expand_all_functions (void)
1684 struct cgraph_node *node;
1685 struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
1686 int order_pos, new_order_pos = 0;
1689 order_pos = ipa_reverse_postorder (order);
1690 gcc_assert (order_pos == cgraph_n_nodes);
1692 /* Garbage collector may remove inline clones we eliminate during
1693 optimization. So we must be sure to not reference them. */
1694 for (i = 0; i < order_pos; i++)
1695 if (order[i]->process)
1696 order[new_order_pos++] = order[i];
1698 for (i = new_order_pos - 1; i >= 0; i--)
1704 expand_function (node);
1707 cgraph_process_new_functions ();
1713 /* This is used to sort the node types by the cgraph order number. */
1715 enum cgraph_order_sort_kind
1717 ORDER_UNDEFINED = 0,
1723 struct cgraph_order_sort
1725 enum cgraph_order_sort_kind kind;
1728 struct cgraph_node *f;
1729 struct varpool_node *v;
1734 /* Output all functions, variables, and asm statements in the order
1735 according to their order fields, which is the order in which they
1736 appeared in the file. This implements -fno-toplevel-reorder. In
1737 this mode we may output functions and variables which don't really
1738 need to be output. */
1741 output_in_order (void)
1744 struct cgraph_order_sort *nodes;
1746 struct cgraph_node *pf;
1747 struct varpool_node *pv;
1748 struct asm_node *pa;
1751 nodes = XCNEWVEC (struct cgraph_order_sort, max);
1753 FOR_EACH_DEFINED_FUNCTION (pf)
1755 if (pf->process && !pf->thunk.thunk_p && !pf->alias)
1757 i = pf->symbol.order;
1758 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1759 nodes[i].kind = ORDER_FUNCTION;
1764 FOR_EACH_DEFINED_VARIABLE (pv)
1765 if (!DECL_EXTERNAL (pv->symbol.decl))
1767 i = pv->symbol.order;
1768 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1769 nodes[i].kind = ORDER_VAR;
1773 for (pa = asm_nodes; pa; pa = pa->next)
1776 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1777 nodes[i].kind = ORDER_ASM;
1781 /* In toplevel reorder mode we output all statics; mark them as needed. */
1783 for (i = 0; i < max; ++i)
1784 if (nodes[i].kind == ORDER_VAR)
1785 varpool_finalize_named_section_flags (nodes[i].u.v);
1787 for (i = 0; i < max; ++i)
1789 switch (nodes[i].kind)
1791 case ORDER_FUNCTION:
1792 nodes[i].u.f->process = 0;
1793 expand_function (nodes[i].u.f);
1797 varpool_assemble_decl (nodes[i].u.v);
1801 assemble_asm (nodes[i].u.a->asm_str);
1804 case ORDER_UNDEFINED:
1820 current_function_decl = NULL;
1821 gimple_register_cfg_hooks ();
1822 bitmap_obstack_initialize (NULL);
1824 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START, NULL);
1828 execute_ipa_pass_list (all_small_ipa_passes);
1833 /* We never run removal of unreachable nodes after early passes. This is
1834 because TODO is run before the subpasses. It is important to remove
1835 the unreachable functions to save works at IPA level and to get LTO
1836 symbol tables right. */
1837 symtab_remove_unreachable_nodes (true, cgraph_dump_file);
1839 /* If pass_all_early_optimizations was not scheduled, the state of
1840 the cgraph will not be properly updated. Update it now. */
1841 if (cgraph_state < CGRAPH_STATE_IPA_SSA)
1842 cgraph_state = CGRAPH_STATE_IPA_SSA;
1846 /* Generate coverage variables and constructors. */
1849 /* Process new functions added. */
1851 current_function_decl = NULL;
1852 cgraph_process_new_functions ();
1854 execute_ipa_summary_passes
1855 ((struct ipa_opt_pass_d *) all_regular_ipa_passes);
1858 /* Some targets need to handle LTO assembler output specially. */
1859 if (flag_generate_lto)
1860 targetm.asm_out.lto_start ();
1862 execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_lto_gen_passes);
1865 ipa_write_summaries ();
1867 if (flag_generate_lto)
1868 targetm.asm_out.lto_end ();
1870 if (!flag_ltrans && (in_lto_p || !flag_lto || flag_fat_lto_objects))
1871 execute_ipa_pass_list (all_regular_ipa_passes);
1872 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END, NULL);
1874 bitmap_obstack_release (NULL);
1878 /* Return string alias is alias of. */
1881 get_alias_symbol (tree decl)
1883 tree alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
1884 return get_identifier (TREE_STRING_POINTER
1885 (TREE_VALUE (TREE_VALUE (alias))));
1889 /* Weakrefs may be associated to external decls and thus not output
1890 at expansion time. Emit all neccesary aliases. */
1893 output_weakrefs (void)
1895 struct cgraph_node *node;
1896 struct varpool_node *vnode;
1897 FOR_EACH_FUNCTION (node)
1898 if (node->alias && DECL_EXTERNAL (node->symbol.decl)
1899 && !TREE_ASM_WRITTEN (node->symbol.decl)
1900 && lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
1901 assemble_alias (node->symbol.decl,
1902 node->thunk.alias ? DECL_ASSEMBLER_NAME (node->thunk.alias)
1903 : get_alias_symbol (node->symbol.decl));
1904 FOR_EACH_VARIABLE (vnode)
1905 if (vnode->alias && DECL_EXTERNAL (vnode->symbol.decl)
1906 && !TREE_ASM_WRITTEN (vnode->symbol.decl)
1907 && lookup_attribute ("weakref", DECL_ATTRIBUTES (vnode->symbol.decl)))
1908 assemble_alias (vnode->symbol.decl,
1909 vnode->alias_of ? DECL_ASSEMBLER_NAME (vnode->alias_of)
1910 : get_alias_symbol (vnode->symbol.decl));
1913 /* Initialize callgraph dump file. */
1918 if (!cgraph_dump_file)
1919 cgraph_dump_file = dump_begin (TDI_cgraph, NULL);
1923 /* Perform simple optimizations based on callgraph. */
1931 #ifdef ENABLE_CHECKING
1935 timevar_push (TV_CGRAPHOPT);
1936 if (pre_ipa_mem_report)
1938 fprintf (stderr, "Memory consumption before IPA\n");
1939 dump_memory_report (false);
1942 fprintf (stderr, "Performing interprocedural optimizations\n");
1943 cgraph_state = CGRAPH_STATE_IPA;
1945 /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE. */
1947 lto_streamer_hooks_init ();
1949 /* Don't run the IPA passes if there was any error or sorry messages. */
1953 /* Do nothing else if any IPA pass found errors or if we are just streaming LTO. */
1955 || (!in_lto_p && flag_lto && !flag_fat_lto_objects))
1957 timevar_pop (TV_CGRAPHOPT);
1961 /* This pass remove bodies of extern inline functions we never inlined.
1962 Do this later so other IPA passes see what is really going on. */
1963 symtab_remove_unreachable_nodes (false, dump_file);
1964 cgraph_global_info_ready = true;
1965 if (cgraph_dump_file)
1967 fprintf (cgraph_dump_file, "Optimized ");
1968 dump_symtab (cgraph_dump_file);
1970 if (post_ipa_mem_report)
1972 fprintf (stderr, "Memory consumption after IPA\n");
1973 dump_memory_report (false);
1975 timevar_pop (TV_CGRAPHOPT);
1977 /* Output everything. */
1978 (*debug_hooks->assembly_start) ();
1980 fprintf (stderr, "Assembling functions:\n");
1981 #ifdef ENABLE_CHECKING
1985 cgraph_materialize_all_clones ();
1986 bitmap_obstack_initialize (NULL);
1987 execute_ipa_pass_list (all_late_ipa_passes);
1988 symtab_remove_unreachable_nodes (true, dump_file);
1989 #ifdef ENABLE_CHECKING
1992 bitmap_obstack_release (NULL);
1993 mark_functions_to_output ();
1996 cgraph_state = CGRAPH_STATE_EXPANSION;
1997 if (!flag_toplevel_reorder)
2001 output_asm_statements ();
2003 expand_all_functions ();
2004 varpool_output_variables ();
2007 cgraph_process_new_functions ();
2008 cgraph_state = CGRAPH_STATE_FINISHED;
2010 if (cgraph_dump_file)
2012 fprintf (cgraph_dump_file, "\nFinal ");
2013 dump_symtab (cgraph_dump_file);
2015 #ifdef ENABLE_CHECKING
2017 /* Double check that all inline clones are gone and that all
2018 function bodies have been released from memory. */
2021 struct cgraph_node *node;
2022 bool error_found = false;
2024 FOR_EACH_DEFINED_FUNCTION (node)
2025 if (node->global.inlined_to
2026 || gimple_has_body_p (node->symbol.decl))
2029 dump_cgraph_node (stderr, node);
2032 internal_error ("nodes with unreleased memory found");
2038 /* Analyze the whole compilation unit once it is parsed completely. */
2041 finalize_compilation_unit (void)
2043 timevar_push (TV_CGRAPH);
2045 /* If we're here there's no current function anymore. Some frontends
2046 are lazy in clearing these. */
2047 current_function_decl = NULL;
2050 /* Do not skip analyzing the functions if there were errors, we
2051 miss diagnostics for following functions otherwise. */
2053 /* Emit size functions we didn't inline. */
2054 finalize_size_functions ();
2056 /* Mark alias targets necessary and emit diagnostics. */
2057 finish_aliases_1 ();
2058 handle_alias_pairs ();
2062 fprintf (stderr, "\nAnalyzing compilation unit\n");
2066 if (flag_dump_passes)
2069 /* Gimplify and lower all functions, compute reachability and
2070 remove unreachable nodes. */
2071 cgraph_analyze_functions ();
2073 /* Mark alias targets necessary and emit diagnostics. */
2074 finish_aliases_1 ();
2075 handle_alias_pairs ();
2077 /* Gimplify and lower thunks. */
2078 cgraph_analyze_functions ();
2080 /* Finally drive the pass manager. */
2083 timevar_pop (TV_CGRAPH);
2087 #include "gt-cgraphunit.h"