1 /* Driver of optimization process
2 Copyright (C) 2003-2013 Free Software Foundation, Inc.
3 Contributed by Jan Hubicka
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 /* This module implements main driver of compilation process.
23 The main scope of this file is to act as an interface in between
24 tree based frontends and the backend.
26 The front-end is supposed to use following functionality:
28 - cgraph_finalize_function
30 This function is called once front-end has parsed whole body of function
31 and it is certain that the function body nor the declaration will change.
33 (There is one exception needed for implementing GCC extern inline
36 - varpool_finalize_decl
38 This function has same behavior as the above but is used for static
43 Insert new toplevel ASM statement
45 - finalize_compilation_unit
47 This function is called once (source level) compilation unit is finalized
48 and it will no longer change.
50 The symbol table is constructed starting from the trivially needed
51 symbols finalized by the frontend. Functions are lowered into
52 GIMPLE representation and callgraph/reference lists are constructed.
53 Those are used to discover other necessary functions and variables.
55 At the end the bodies of unreachable functions are removed.
57 The function can be called multiple times when multiple source level
58 compilation units are combined.
62 This passes control to the back-end. Optimizations are performed and
63 final assembler is generated. This is done in the following way. Note
64 that with link time optimization the process is split into three
65 stages (compile time, linktime analysis and parallel linktime as
70 1) Inter-procedural optimization.
73 This part is further split into:
75 a) early optimizations. These are local passes executed in
76 the topological order on the callgraph.
78 The purpose of early optimiations is to optimize away simple
79 things that may otherwise confuse IP analysis. Very simple
80 propagation across the callgraph is done i.e. to discover
81 functions without side effects and simple inlining is performed.
83 b) early small interprocedural passes.
85 Those are interprocedural passes executed only at compilation
86 time. These include, for example, transational memory lowering,
87 unreachable code removal and other simple transformations.
89 c) IP analysis stage. All interprocedural passes do their
92 Interprocedural passes differ from small interprocedural
93 passes by their ability to operate across whole program
94 at linktime. Their analysis stage is performed early to
95 both reduce linking times and linktime memory usage by
96 not having to represent whole program in memory.
98 d) LTO sreaming. When doing LTO, everything important gets
99 streamed into the object file.
101 Compile time and or linktime analysis stage (WPA):
103 At linktime units gets streamed back and symbol table is
104 merged. Function bodies are not streamed in and not
106 e) IP propagation stage. All IP passes execute their
107 IP propagation. This is done based on the earlier analysis
108 without having function bodies at hand.
109 f) Ltrans streaming. When doing WHOPR LTO, the program
110 is partitioned and streamed into multple object files.
112 Compile time and/or parallel linktime stage (ltrans)
114 Each of the object files is streamed back and compiled
115 separately. Now the function bodies becomes available
118 2) Virtual clone materialization
119 (cgraph_materialize_clone)
121 IP passes can produce copies of existing functoins (such
122 as versioned clones or inline clones) without actually
123 manipulating their bodies by creating virtual clones in
124 the callgraph. At this time the virtual clones are
125 turned into real functions
128 All IP passes transform function bodies based on earlier
129 decision of the IP propagation.
131 4) late small IP passes
133 Simple IP passes working within single program partition.
136 (expand_all_functions)
138 At this stage functions that needs to be output into
139 assembler are identified and compiled in topological order
140 6) Output of variables and aliases
141 Now it is known what variable references was not optimized
142 out and thus all variables are output to the file.
144 Note that with -fno-toplevel-reorder passes 5 and 6
145 are combined together in cgraph_output_in_order.
147 Finally there are functions to manipulate the callgraph from
149 - cgraph_add_new_function is used to add backend produced
150 functions introduced after the unit is finalized.
151 The functions are enqueue for later processing and inserted
152 into callgraph with cgraph_process_new_functions.
154 - cgraph_function_versioning
156 produces a copy of function into new one (a version)
157 and apply simple transformations
162 #include "coretypes.h"
166 #include "stor-layout.h"
167 #include "stringpool.h"
171 #include "gimplify.h"
172 #include "gimple-iterator.h"
173 #include "gimplify-me.h"
174 #include "gimple-ssa.h"
175 #include "tree-cfg.h"
176 #include "tree-into-ssa.h"
177 #include "tree-ssa.h"
178 #include "tree-inline.h"
179 #include "langhooks.h"
180 #include "pointer-set.h"
186 #include "diagnostic.h"
190 #include "function.h"
191 #include "ipa-prop.h"
192 #include "tree-iterator.h"
193 #include "tree-pass.h"
194 #include "tree-dump.h"
195 #include "gimple-pretty-print.h"
197 #include "coverage.h"
199 #include "ipa-inline.h"
200 #include "ipa-utils.h"
201 #include "lto-streamer.h"
204 #include "regset.h" /* FIXME: For reg_obstack. */
206 #include "pass_manager.h"
207 #include "tree-nested.h"
209 /* Queue of cgraph nodes scheduled to be added into cgraph. This is a
210 secondary queue used during optimization to accommodate passes that
211 may generate new functions that need to be optimized and expanded. */
212 cgraph_node_set cgraph_new_nodes
;
214 static void expand_all_functions (void);
215 static void mark_functions_to_output (void);
216 static void expand_function (struct cgraph_node
*);
217 static void analyze_function (struct cgraph_node
*);
218 static void handle_alias_pairs (void);
220 FILE *cgraph_dump_file
;
222 /* Linked list of cgraph asm nodes. */
223 struct asm_node
*asm_nodes
;
225 /* Last node in cgraph_asm_nodes. */
226 static GTY(()) struct asm_node
*asm_last_node
;
228 /* Used for vtable lookup in thunk adjusting. */
229 static GTY (()) tree vtable_entry_type
;
231 /* Determine if symbol DECL is needed. That is, visible to something
232 either outside this translation unit, something magic in the system
235 decide_is_symbol_needed (symtab_node
*node
)
237 tree decl
= node
->decl
;
239 /* Double check that no one output the function into assembly file
241 gcc_checking_assert (!DECL_ASSEMBLER_NAME_SET_P (decl
)
242 || !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl
)));
244 if (!node
->definition
)
247 if (DECL_EXTERNAL (decl
))
250 /* If the user told us it is used, then it must be so. */
251 if (node
->force_output
)
254 /* ABI forced symbols are needed when they are external. */
255 if (node
->forced_by_abi
&& TREE_PUBLIC (decl
))
258 /* Keep constructors, destructors and virtual functions. */
259 if (TREE_CODE (decl
) == FUNCTION_DECL
260 && (DECL_STATIC_CONSTRUCTOR (decl
) || DECL_STATIC_DESTRUCTOR (decl
)))
263 /* Externally visible variables must be output. The exception is
264 COMDAT variables that must be output only when they are needed. */
265 if (TREE_PUBLIC (decl
) && !DECL_COMDAT (decl
))
271 /* Head of the queue of nodes to be processed while building callgraph */
273 static symtab_node
*first
= (symtab_node
*)(void *)1;
275 /* Add NODE to queue starting at FIRST.
276 The queue is linked via AUX pointers and terminated by pointer to 1. */
279 enqueue_node (symtab_node
*node
)
283 gcc_checking_assert (first
);
288 /* Process CGRAPH_NEW_FUNCTIONS and perform actions necessary to add these
289 functions into callgraph in a way so they look like ordinary reachable
290 functions inserted into callgraph already at construction time. */
293 cgraph_process_new_functions (void)
297 struct cgraph_node
*node
;
298 cgraph_node_set_iterator csi
;
300 if (!cgraph_new_nodes
)
302 handle_alias_pairs ();
303 /* Note that this queue may grow as its being processed, as the new
304 functions may generate new ones. */
305 for (csi
= csi_start (cgraph_new_nodes
); !csi_end_p (csi
); csi_next (&csi
))
307 node
= csi_node (csi
);
309 switch (cgraph_state
)
311 case CGRAPH_STATE_CONSTRUCTION
:
312 /* At construction time we just need to finalize function and move
313 it into reachable functions list. */
315 cgraph_finalize_function (fndecl
, false);
317 cgraph_call_function_insertion_hooks (node
);
321 case CGRAPH_STATE_IPA
:
322 case CGRAPH_STATE_IPA_SSA
:
323 /* When IPA optimization already started, do all essential
324 transformations that has been already performed on the whole
325 cgraph but not on this function. */
327 gimple_register_cfg_hooks ();
329 analyze_function (node
);
330 push_cfun (DECL_STRUCT_FUNCTION (fndecl
));
331 if (cgraph_state
== CGRAPH_STATE_IPA_SSA
332 && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl
)))
333 g
->get_passes ()->execute_early_local_passes ();
334 else if (inline_summary_vec
!= NULL
)
335 compute_inline_parameters (node
, true);
336 free_dominance_info (CDI_POST_DOMINATORS
);
337 free_dominance_info (CDI_DOMINATORS
);
339 cgraph_call_function_insertion_hooks (node
);
342 case CGRAPH_STATE_EXPANSION
:
343 /* Functions created during expansion shall be compiled
346 cgraph_call_function_insertion_hooks (node
);
347 expand_function (node
);
355 free_cgraph_node_set (cgraph_new_nodes
);
356 cgraph_new_nodes
= NULL
;
360 /* As an GCC extension we allow redefinition of the function. The
361 semantics when both copies of bodies differ is not well defined.
362 We replace the old body with new body so in unit at a time mode
363 we always use new body, while in normal mode we may end up with
364 old body inlined into some functions and new body expanded and
367 ??? It may make more sense to use one body for inlining and other
368 body for expanding the function but this is difficult to do. */
371 cgraph_reset_node (struct cgraph_node
*node
)
373 /* If node->process is set, then we have already begun whole-unit analysis.
374 This is *not* testing for whether we've already emitted the function.
375 That case can be sort-of legitimately seen with real function redefinition
376 errors. I would argue that the front end should never present us with
377 such a case, but don't enforce that for now. */
378 gcc_assert (!node
->process
);
380 /* Reset our data structures so we can analyze the function again. */
381 memset (&node
->local
, 0, sizeof (node
->local
));
382 memset (&node
->global
, 0, sizeof (node
->global
));
383 memset (&node
->rtl
, 0, sizeof (node
->rtl
));
384 node
->analyzed
= false;
385 node
->definition
= false;
387 node
->weakref
= false;
388 node
->cpp_implicit_alias
= false;
390 cgraph_node_remove_callees (node
);
391 ipa_remove_all_references (&node
->ref_list
);
394 /* Return true when there are references to NODE. */
397 referred_to_p (symtab_node
*node
)
401 /* See if there are any references at all. */
402 if (ipa_ref_list_referring_iterate (&node
->ref_list
, 0, ref
))
404 /* For functions check also calls. */
405 cgraph_node
*cn
= dyn_cast
<cgraph_node
> (node
);
406 if (cn
&& cn
->callers
)
411 /* DECL has been parsed. Take it, queue it, compile it at the whim of the
412 logic in effect. If NO_COLLECT is true, then our caller cannot stand to have
413 the garbage collector run at the moment. We would need to either create
414 a new GC context, or just not compile right now. */
417 cgraph_finalize_function (tree decl
, bool no_collect
)
419 struct cgraph_node
*node
= cgraph_get_create_node (decl
);
421 if (node
->definition
)
423 /* Nested functions should only be defined once. */
424 gcc_assert (!DECL_CONTEXT (decl
)
425 || TREE_CODE (DECL_CONTEXT (decl
)) != FUNCTION_DECL
);
426 cgraph_reset_node (node
);
427 node
->local
.redefined_extern_inline
= true;
430 notice_global_symbol (decl
);
431 node
->definition
= true;
432 node
->lowered
= DECL_STRUCT_FUNCTION (decl
)->cfg
!= NULL
;
434 /* With -fkeep-inline-functions we are keeping all inline functions except
435 for extern inline ones. */
436 if (flag_keep_inline_functions
437 && DECL_DECLARED_INLINE_P (decl
)
438 && !DECL_EXTERNAL (decl
)
439 && !DECL_DISREGARD_INLINE_LIMITS (decl
))
440 node
->force_output
= 1;
442 /* When not optimizing, also output the static functions. (see
443 PR24561), but don't do so for always_inline functions, functions
444 declared inline and nested functions. These were optimized out
445 in the original implementation and it is unclear whether we want
446 to change the behavior here. */
448 && !node
->cpp_implicit_alias
449 && !DECL_DISREGARD_INLINE_LIMITS (decl
)
450 && !DECL_DECLARED_INLINE_P (decl
)
451 && !(DECL_CONTEXT (decl
)
452 && TREE_CODE (DECL_CONTEXT (decl
)) == FUNCTION_DECL
))
453 && !DECL_COMDAT (decl
) && !DECL_EXTERNAL (decl
))
454 node
->force_output
= 1;
456 /* If we've not yet emitted decl, tell the debug info about it. */
457 if (!TREE_ASM_WRITTEN (decl
))
458 (*debug_hooks
->deferred_inline_function
) (decl
);
460 /* Possibly warn about unused parameters. */
461 if (warn_unused_parameter
)
462 do_warn_unused_parameter (decl
);
467 if (cgraph_state
== CGRAPH_STATE_CONSTRUCTION
468 && (decide_is_symbol_needed (node
)
469 || referred_to_p (node
)))
473 /* Add the function FNDECL to the call graph.
474 Unlike cgraph_finalize_function, this function is intended to be used
475 by middle end and allows insertion of new function at arbitrary point
476 of compilation. The function can be either in high, low or SSA form
479 The function is assumed to be reachable and have address taken (so no
480 API breaking optimizations are performed on it).
482 Main work done by this function is to enqueue the function for later
483 processing to avoid need the passes to be re-entrant. */
486 cgraph_add_new_function (tree fndecl
, bool lowered
)
488 gcc::pass_manager
*passes
= g
->get_passes ();
489 struct cgraph_node
*node
;
490 switch (cgraph_state
)
492 case CGRAPH_STATE_PARSING
:
493 cgraph_finalize_function (fndecl
, false);
495 case CGRAPH_STATE_CONSTRUCTION
:
496 /* Just enqueue function to be processed at nearest occurrence. */
497 node
= cgraph_create_node (fndecl
);
499 node
->lowered
= true;
500 if (!cgraph_new_nodes
)
501 cgraph_new_nodes
= cgraph_node_set_new ();
502 cgraph_node_set_add (cgraph_new_nodes
, node
);
505 case CGRAPH_STATE_IPA
:
506 case CGRAPH_STATE_IPA_SSA
:
507 case CGRAPH_STATE_EXPANSION
:
508 /* Bring the function into finalized state and enqueue for later
509 analyzing and compilation. */
510 node
= cgraph_get_create_node (fndecl
);
511 node
->local
.local
= false;
512 node
->definition
= true;
513 node
->force_output
= true;
514 if (!lowered
&& cgraph_state
== CGRAPH_STATE_EXPANSION
)
516 push_cfun (DECL_STRUCT_FUNCTION (fndecl
));
517 gimple_register_cfg_hooks ();
518 bitmap_obstack_initialize (NULL
);
519 execute_pass_list (passes
->all_lowering_passes
);
520 passes
->execute_early_local_passes ();
521 bitmap_obstack_release (NULL
);
527 node
->lowered
= true;
528 if (!cgraph_new_nodes
)
529 cgraph_new_nodes
= cgraph_node_set_new ();
530 cgraph_node_set_add (cgraph_new_nodes
, node
);
533 case CGRAPH_STATE_FINISHED
:
534 /* At the very end of compilation we have to do all the work up
536 node
= cgraph_create_node (fndecl
);
538 node
->lowered
= true;
539 node
->definition
= true;
540 analyze_function (node
);
541 push_cfun (DECL_STRUCT_FUNCTION (fndecl
));
542 gimple_register_cfg_hooks ();
543 bitmap_obstack_initialize (NULL
);
544 if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl
)))
545 g
->get_passes ()->execute_early_local_passes ();
546 bitmap_obstack_release (NULL
);
548 expand_function (node
);
555 /* Set a personality if required and we already passed EH lowering. */
557 && (function_needs_eh_personality (DECL_STRUCT_FUNCTION (fndecl
))
558 == eh_personality_lang
))
559 DECL_FUNCTION_PERSONALITY (fndecl
) = lang_hooks
.eh_personality ();
562 /* Add a top-level asm statement to the list. */
565 add_asm_node (tree asm_str
)
567 struct asm_node
*node
;
569 node
= ggc_alloc_cleared_asm_node ();
570 node
->asm_str
= asm_str
;
571 node
->order
= symtab_order
++;
573 if (asm_nodes
== NULL
)
576 asm_last_node
->next
= node
;
577 asm_last_node
= node
;
581 /* Output all asm statements we have stored up to be output. */
584 output_asm_statements (void)
586 struct asm_node
*can
;
591 for (can
= asm_nodes
; can
; can
= can
->next
)
592 assemble_asm (can
->asm_str
);
596 /* Analyze the function scheduled to be output. */
598 analyze_function (struct cgraph_node
*node
)
600 tree decl
= node
->decl
;
601 location_t saved_loc
= input_location
;
602 input_location
= DECL_SOURCE_LOCATION (decl
);
604 if (node
->thunk
.thunk_p
)
606 cgraph_create_edge (node
, cgraph_get_node (node
->thunk
.alias
),
607 NULL
, 0, CGRAPH_FREQ_BASE
);
608 if (!expand_thunk (node
, false))
610 node
->thunk
.alias
= NULL
;
611 node
->analyzed
= true;
614 node
->thunk
.alias
= NULL
;
618 (node
, cgraph_get_node (node
->alias_target
));
619 else if (node
->dispatcher_function
)
621 /* Generate the dispatcher body of multi-versioned functions. */
622 struct cgraph_function_version_info
*dispatcher_version_info
623 = get_cgraph_node_version (node
);
624 if (dispatcher_version_info
!= NULL
625 && (dispatcher_version_info
->dispatcher_resolver
628 tree resolver
= NULL_TREE
;
629 gcc_assert (targetm
.generate_version_dispatcher_body
);
630 resolver
= targetm
.generate_version_dispatcher_body (node
);
631 gcc_assert (resolver
!= NULL_TREE
);
636 push_cfun (DECL_STRUCT_FUNCTION (decl
));
638 assign_assembler_name_if_neeeded (node
->decl
);
640 /* Make sure to gimplify bodies only once. During analyzing a
641 function we lower it, which will require gimplified nested
642 functions, so we can end up here with an already gimplified
644 if (!gimple_has_body_p (decl
))
645 gimplify_function_tree (decl
);
646 dump_function (TDI_generic
, decl
);
648 /* Lower the function. */
652 lower_nested_functions (node
->decl
);
653 gcc_assert (!node
->nested
);
655 gimple_register_cfg_hooks ();
656 bitmap_obstack_initialize (NULL
);
657 execute_pass_list (g
->get_passes ()->all_lowering_passes
);
658 free_dominance_info (CDI_POST_DOMINATORS
);
659 free_dominance_info (CDI_DOMINATORS
);
661 bitmap_obstack_release (NULL
);
662 node
->lowered
= true;
667 node
->analyzed
= true;
669 input_location
= saved_loc
;
672 /* C++ frontend produce same body aliases all over the place, even before PCH
673 gets streamed out. It relies on us linking the aliases with their function
674 in order to do the fixups, but ipa-ref is not PCH safe. Consequentely we
675 first produce aliases without links, but once C++ FE is sure he won't sream
676 PCH we build the links via this function. */
679 cgraph_process_same_body_aliases (void)
682 FOR_EACH_SYMBOL (node
)
683 if (node
->cpp_implicit_alias
&& !node
->analyzed
)
686 TREE_CODE (node
->alias_target
) == VAR_DECL
687 ? (symtab_node
*)varpool_node_for_decl (node
->alias_target
)
688 : (symtab_node
*)cgraph_get_create_node (node
->alias_target
));
689 cpp_implicit_aliases_done
= true;
692 /* Process attributes common for vars and functions. */
695 process_common_attributes (tree decl
)
697 tree weakref
= lookup_attribute ("weakref", DECL_ATTRIBUTES (decl
));
699 if (weakref
&& !lookup_attribute ("alias", DECL_ATTRIBUTES (decl
)))
701 warning_at (DECL_SOURCE_LOCATION (decl
), OPT_Wattributes
,
702 "%<weakref%> attribute should be accompanied with"
703 " an %<alias%> attribute");
704 DECL_WEAK (decl
) = 0;
705 DECL_ATTRIBUTES (decl
) = remove_attribute ("weakref",
706 DECL_ATTRIBUTES (decl
));
710 /* Look for externally_visible and used attributes and mark cgraph nodes
713 We cannot mark the nodes at the point the attributes are processed (in
714 handle_*_attribute) because the copy of the declarations available at that
715 point may not be canonical. For example, in:
718 void f() __attribute__((used));
720 the declaration we see in handle_used_attribute will be the second
721 declaration -- but the front end will subsequently merge that declaration
722 with the original declaration and discard the second declaration.
724 Furthermore, we can't mark these nodes in cgraph_finalize_function because:
727 void f() __attribute__((externally_visible));
731 So, we walk the nodes at the end of the translation unit, applying the
732 attributes at that point. */
735 process_function_and_variable_attributes (struct cgraph_node
*first
,
736 struct varpool_node
*first_var
)
738 struct cgraph_node
*node
;
739 struct varpool_node
*vnode
;
741 for (node
= cgraph_first_function (); node
!= first
;
742 node
= cgraph_next_function (node
))
744 tree decl
= node
->decl
;
745 if (DECL_PRESERVE_P (decl
))
746 cgraph_mark_force_output_node (node
);
747 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl
)))
749 if (! TREE_PUBLIC (node
->decl
))
750 warning_at (DECL_SOURCE_LOCATION (node
->decl
), OPT_Wattributes
,
751 "%<externally_visible%>"
752 " attribute have effect only on public objects");
754 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl
))
755 && (node
->definition
&& !node
->alias
))
757 warning_at (DECL_SOURCE_LOCATION (node
->decl
), OPT_Wattributes
,
758 "%<weakref%> attribute ignored"
759 " because function is defined");
760 DECL_WEAK (decl
) = 0;
761 DECL_ATTRIBUTES (decl
) = remove_attribute ("weakref",
762 DECL_ATTRIBUTES (decl
));
765 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl
))
766 && !DECL_DECLARED_INLINE_P (decl
)
767 /* redefining extern inline function makes it DECL_UNINLINABLE. */
768 && !DECL_UNINLINABLE (decl
))
769 warning_at (DECL_SOURCE_LOCATION (decl
), OPT_Wattributes
,
770 "always_inline function might not be inlinable");
772 process_common_attributes (decl
);
774 for (vnode
= varpool_first_variable (); vnode
!= first_var
;
775 vnode
= varpool_next_variable (vnode
))
777 tree decl
= vnode
->decl
;
778 if (DECL_EXTERNAL (decl
)
779 && DECL_INITIAL (decl
))
780 varpool_finalize_decl (decl
);
781 if (DECL_PRESERVE_P (decl
))
782 vnode
->force_output
= true;
783 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl
)))
785 if (! TREE_PUBLIC (vnode
->decl
))
786 warning_at (DECL_SOURCE_LOCATION (vnode
->decl
), OPT_Wattributes
,
787 "%<externally_visible%>"
788 " attribute have effect only on public objects");
790 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl
))
792 && DECL_INITIAL (decl
))
794 warning_at (DECL_SOURCE_LOCATION (vnode
->decl
), OPT_Wattributes
,
795 "%<weakref%> attribute ignored"
796 " because variable is initialized");
797 DECL_WEAK (decl
) = 0;
798 DECL_ATTRIBUTES (decl
) = remove_attribute ("weakref",
799 DECL_ATTRIBUTES (decl
));
801 process_common_attributes (decl
);
805 /* Mark DECL as finalized. By finalizing the declaration, frontend instruct the
806 middle end to output the variable to asm file, if needed or externally
810 varpool_finalize_decl (tree decl
)
812 struct varpool_node
*node
= varpool_node_for_decl (decl
);
814 gcc_assert (TREE_STATIC (decl
) || DECL_EXTERNAL (decl
));
816 if (node
->definition
)
818 notice_global_symbol (decl
);
819 node
->definition
= true;
820 if (TREE_THIS_VOLATILE (decl
) || DECL_PRESERVE_P (decl
)
821 /* Traditionally we do not eliminate static variables when not
822 optimizing and when not doing toplevel reoder. */
823 || (!flag_toplevel_reorder
&& !DECL_COMDAT (node
->decl
)
824 && !DECL_ARTIFICIAL (node
->decl
)))
825 node
->force_output
= true;
827 if (cgraph_state
== CGRAPH_STATE_CONSTRUCTION
828 && (decide_is_symbol_needed (node
)
829 || referred_to_p (node
)))
831 if (cgraph_state
>= CGRAPH_STATE_IPA_SSA
)
832 varpool_analyze_node (node
);
833 /* Some frontends produce various interface variables after compilation
835 if (cgraph_state
== CGRAPH_STATE_FINISHED
836 || (!flag_toplevel_reorder
&& cgraph_state
== CGRAPH_STATE_EXPANSION
))
837 varpool_assemble_decl (node
);
840 /* EDGE is an polymorphic call. Mark all possible targets as reachable
841 and if there is only one target, perform trivial devirtualization.
842 REACHABLE_CALL_TARGETS collects target lists we already walked to
843 avoid udplicate work. */
846 walk_polymorphic_call_targets (pointer_set_t
*reachable_call_targets
,
847 struct cgraph_edge
*edge
)
852 vec
<cgraph_node
*>targets
853 = possible_polymorphic_call_targets
854 (edge
, &final
, &cache_token
);
856 if (!pointer_set_insert (reachable_call_targets
,
859 if (cgraph_dump_file
)
860 dump_possible_polymorphic_call_targets
861 (cgraph_dump_file
, edge
);
863 for (i
= 0; i
< targets
.length (); i
++)
865 /* Do not bother to mark virtual methods in anonymous namespace;
866 either we will find use of virtual table defining it, or it is
868 if (targets
[i
]->definition
870 (TREE_TYPE (targets
[i
]->decl
))
872 && !type_in_anonymous_namespace_p
874 (TREE_TYPE (targets
[i
]->decl
))))
875 enqueue_node (targets
[i
]);
879 /* Very trivial devirtualization; when the type is
880 final or anonymous (so we know all its derivation)
881 and there is only one possible virtual call target,
882 make the edge direct. */
885 if (targets
.length () <= 1)
888 if (targets
.length () == 1)
891 target
= cgraph_get_create_node
892 (builtin_decl_implicit (BUILT_IN_UNREACHABLE
));
894 if (cgraph_dump_file
)
896 fprintf (cgraph_dump_file
,
897 "Devirtualizing call: ");
898 print_gimple_stmt (cgraph_dump_file
,
902 cgraph_make_edge_direct (edge
, target
);
903 cgraph_redirect_edge_call_stmt_to_callee (edge
);
904 if (cgraph_dump_file
)
906 fprintf (cgraph_dump_file
,
907 "Devirtualized as: ");
908 print_gimple_stmt (cgraph_dump_file
,
917 /* Discover all functions and variables that are trivially needed, analyze
918 them as well as all functions and variables referred by them */
921 analyze_functions (void)
923 /* Keep track of already processed nodes when called multiple times for
924 intermodule optimization. */
925 static struct cgraph_node
*first_analyzed
;
926 struct cgraph_node
*first_handled
= first_analyzed
;
927 static struct varpool_node
*first_analyzed_var
;
928 struct varpool_node
*first_handled_var
= first_analyzed_var
;
929 struct pointer_set_t
*reachable_call_targets
= pointer_set_create ();
936 location_t saved_loc
= input_location
;
938 bitmap_obstack_initialize (NULL
);
939 cgraph_state
= CGRAPH_STATE_CONSTRUCTION
;
940 input_location
= UNKNOWN_LOCATION
;
942 /* Ugly, but the fixup can not happen at a time same body alias is created;
943 C++ FE is confused about the COMDAT groups being right. */
944 if (cpp_implicit_aliases_done
)
945 FOR_EACH_SYMBOL (node
)
946 if (node
->cpp_implicit_alias
)
947 fixup_same_cpp_alias_visibility (node
, symtab_alias_target (node
));
948 if (optimize
&& flag_devirtualize
)
949 build_type_inheritance_graph ();
951 /* Analysis adds static variables that in turn adds references to new functions.
952 So we need to iterate the process until it stabilize. */
956 process_function_and_variable_attributes (first_analyzed
,
959 /* First identify the trivially needed symbols. */
960 for (node
= symtab_nodes
;
961 node
!= first_analyzed
962 && node
!= first_analyzed_var
; node
= node
->next
)
964 if (decide_is_symbol_needed (node
))
967 if (!changed
&& cgraph_dump_file
)
968 fprintf (cgraph_dump_file
, "Trivially needed symbols:");
970 if (cgraph_dump_file
)
971 fprintf (cgraph_dump_file
, " %s", node
->asm_name ());
972 if (!changed
&& cgraph_dump_file
)
973 fprintf (cgraph_dump_file
, "\n");
975 if (node
== first_analyzed
976 || node
== first_analyzed_var
)
979 cgraph_process_new_functions ();
980 first_analyzed_var
= varpool_first_variable ();
981 first_analyzed
= cgraph_first_function ();
983 if (changed
&& dump_file
)
984 fprintf (cgraph_dump_file
, "\n");
986 /* Lower representation, build callgraph edges and references for all trivially
987 needed symbols and all symbols referred by them. */
988 while (first
!= (symtab_node
*)(void *)1)
992 first
= (symtab_node
*)first
->aux
;
993 cgraph_node
*cnode
= dyn_cast
<cgraph_node
> (node
);
994 if (cnode
&& cnode
->definition
)
996 struct cgraph_edge
*edge
;
997 tree decl
= cnode
->decl
;
999 /* ??? It is possible to create extern inline function
1000 and later using weak alias attribute to kill its body.
1001 See gcc.c-torture/compile/20011119-1.c */
1002 if (!DECL_STRUCT_FUNCTION (decl
)
1004 && !cnode
->thunk
.thunk_p
1005 && !cnode
->dispatcher_function
)
1007 cgraph_reset_node (cnode
);
1008 cnode
->local
.redefined_extern_inline
= true;
1012 if (!cnode
->analyzed
)
1013 analyze_function (cnode
);
1015 for (edge
= cnode
->callees
; edge
; edge
= edge
->next_callee
)
1016 if (edge
->callee
->definition
)
1017 enqueue_node (edge
->callee
);
1018 if (optimize
&& flag_devirtualize
)
1020 struct cgraph_edge
*next
;
1022 for (edge
= cnode
->indirect_calls
; edge
; edge
= next
)
1024 next
= edge
->next_callee
;
1025 if (edge
->indirect_info
->polymorphic
)
1026 walk_polymorphic_call_targets (reachable_call_targets
,
1031 /* If decl is a clone of an abstract function,
1032 mark that abstract function so that we don't release its body.
1033 The DECL_INITIAL() of that abstract function declaration
1034 will be later needed to output debug info. */
1035 if (DECL_ABSTRACT_ORIGIN (decl
))
1037 struct cgraph_node
*origin_node
1038 = cgraph_get_node (DECL_ABSTRACT_ORIGIN (decl
));
1039 origin_node
->used_as_abstract_origin
= true;
1044 varpool_node
*vnode
= dyn_cast
<varpool_node
> (node
);
1045 if (vnode
&& vnode
->definition
&& !vnode
->analyzed
)
1046 varpool_analyze_node (vnode
);
1049 if (node
->same_comdat_group
)
1052 for (next
= node
->same_comdat_group
;
1054 next
= next
->same_comdat_group
)
1055 enqueue_node (next
);
1057 for (i
= 0; ipa_ref_list_reference_iterate (&node
->ref_list
, i
, ref
); i
++)
1058 if (ref
->referred
->definition
)
1059 enqueue_node (ref
->referred
);
1060 cgraph_process_new_functions ();
1063 if (optimize
&& flag_devirtualize
)
1064 update_type_inheritance_graph ();
1066 /* Collect entry points to the unit. */
1067 if (cgraph_dump_file
)
1069 fprintf (cgraph_dump_file
, "\n\nInitial ");
1070 dump_symtab (cgraph_dump_file
);
1073 if (cgraph_dump_file
)
1074 fprintf (cgraph_dump_file
, "\nRemoving unused symbols:");
1076 for (node
= symtab_nodes
;
1077 node
!= first_handled
1078 && node
!= first_handled_var
; node
= next
)
1081 if (!node
->aux
&& !referred_to_p (node
))
1083 if (cgraph_dump_file
)
1084 fprintf (cgraph_dump_file
, " %s", node
->name ());
1085 symtab_remove_node (node
);
1088 if (cgraph_node
*cnode
= dyn_cast
<cgraph_node
> (node
))
1090 tree decl
= node
->decl
;
1092 if (cnode
->definition
&& !gimple_has_body_p (decl
)
1094 && !cnode
->thunk
.thunk_p
)
1095 cgraph_reset_node (cnode
);
1097 gcc_assert (!cnode
->definition
|| cnode
->thunk
.thunk_p
1099 || gimple_has_body_p (decl
));
1100 gcc_assert (cnode
->analyzed
== cnode
->definition
);
1104 for (;node
; node
= node
->next
)
1106 first_analyzed
= cgraph_first_function ();
1107 first_analyzed_var
= varpool_first_variable ();
1108 if (cgraph_dump_file
)
1110 fprintf (cgraph_dump_file
, "\n\nReclaimed ");
1111 dump_symtab (cgraph_dump_file
);
1113 bitmap_obstack_release (NULL
);
1114 pointer_set_destroy (reachable_call_targets
);
1116 /* Initialize assembler name hash, in particular we want to trigger C++
1117 mangling and same body alias creation before we free DECL_ARGUMENTS
1120 symtab_initialize_asm_name_hash ();
1122 input_location
= saved_loc
;
1125 /* Translate the ugly representation of aliases as alias pairs into nice
1126 representation in callgraph. We don't handle all cases yet,
1130 handle_alias_pairs (void)
1135 for (i
= 0; alias_pairs
&& alias_pairs
->iterate (i
, &p
);)
1137 symtab_node
*target_node
= symtab_node_for_asm (p
->target
);
1139 /* Weakrefs with target not defined in current unit are easy to handle:
1140 they behave just as external variables except we need to note the
1141 alias flag to later output the weakref pseudo op into asm file. */
1143 && lookup_attribute ("weakref", DECL_ATTRIBUTES (p
->decl
)) != NULL
)
1145 symtab_node
*node
= symtab_get_node (p
->decl
);
1148 node
->alias_target
= p
->target
;
1149 node
->weakref
= true;
1152 alias_pairs
->unordered_remove (i
);
1155 else if (!target_node
)
1157 error ("%q+D aliased to undefined symbol %qE", p
->decl
, p
->target
);
1158 symtab_node
*node
= symtab_get_node (p
->decl
);
1160 node
->alias
= false;
1161 alias_pairs
->unordered_remove (i
);
1165 if (DECL_EXTERNAL (target_node
->decl
)
1166 /* We use local aliases for C++ thunks to force the tailcall
1167 to bind locally. This is a hack - to keep it working do
1168 the following (which is not strictly correct). */
1169 && (! TREE_CODE (target_node
->decl
) == FUNCTION_DECL
1170 || ! DECL_VIRTUAL_P (target_node
->decl
))
1171 && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p
->decl
)))
1173 error ("%q+D aliased to external symbol %qE",
1174 p
->decl
, p
->target
);
1177 if (TREE_CODE (p
->decl
) == FUNCTION_DECL
1178 && target_node
&& is_a
<cgraph_node
> (target_node
))
1180 struct cgraph_node
*src_node
= cgraph_get_node (p
->decl
);
1181 if (src_node
&& src_node
->definition
)
1182 cgraph_reset_node (src_node
);
1183 cgraph_create_function_alias (p
->decl
, target_node
->decl
);
1184 alias_pairs
->unordered_remove (i
);
1186 else if (TREE_CODE (p
->decl
) == VAR_DECL
1187 && target_node
&& is_a
<varpool_node
> (target_node
))
1189 varpool_create_variable_alias (p
->decl
, target_node
->decl
);
1190 alias_pairs
->unordered_remove (i
);
1194 error ("%q+D alias in between function and variable is not supported",
1196 warning (0, "%q+D aliased declaration",
1198 alias_pairs
->unordered_remove (i
);
1201 vec_free (alias_pairs
);
1205 /* Figure out what functions we want to assemble. */
1208 mark_functions_to_output (void)
1210 struct cgraph_node
*node
;
1211 #ifdef ENABLE_CHECKING
1212 bool check_same_comdat_groups
= false;
1214 FOR_EACH_FUNCTION (node
)
1215 gcc_assert (!node
->process
);
1218 FOR_EACH_FUNCTION (node
)
1220 tree decl
= node
->decl
;
1222 gcc_assert (!node
->process
|| node
->same_comdat_group
);
1226 /* We need to output all local functions that are used and not
1227 always inlined, as well as those that are reachable from
1228 outside the current compilation unit. */
1230 && !node
->thunk
.thunk_p
1232 && !node
->global
.inlined_to
1233 && !TREE_ASM_WRITTEN (decl
)
1234 && !DECL_EXTERNAL (decl
))
1237 if (node
->same_comdat_group
)
1239 struct cgraph_node
*next
;
1240 for (next
= cgraph (node
->same_comdat_group
);
1242 next
= cgraph (next
->same_comdat_group
))
1243 if (!next
->thunk
.thunk_p
&& !next
->alias
)
1247 else if (node
->same_comdat_group
)
1249 #ifdef ENABLE_CHECKING
1250 check_same_comdat_groups
= true;
1255 /* We should've reclaimed all functions that are not needed. */
1256 #ifdef ENABLE_CHECKING
1257 if (!node
->global
.inlined_to
1258 && gimple_has_body_p (decl
)
1259 /* FIXME: in ltrans unit when offline copy is outside partition but inline copies
1260 are inside partition, we can end up not removing the body since we no longer
1261 have analyzed node pointing to it. */
1262 && !node
->in_other_partition
1265 && !DECL_EXTERNAL (decl
))
1267 dump_cgraph_node (stderr
, node
);
1268 internal_error ("failed to reclaim unneeded function");
1271 gcc_assert (node
->global
.inlined_to
1272 || !gimple_has_body_p (decl
)
1273 || node
->in_other_partition
1275 || DECL_ARTIFICIAL (decl
)
1276 || DECL_EXTERNAL (decl
));
1281 #ifdef ENABLE_CHECKING
1282 if (check_same_comdat_groups
)
1283 FOR_EACH_FUNCTION (node
)
1284 if (node
->same_comdat_group
&& !node
->process
)
1286 tree decl
= node
->decl
;
1287 if (!node
->global
.inlined_to
1288 && gimple_has_body_p (decl
)
1289 /* FIXME: in an ltrans unit when the offline copy is outside a
1290 partition but inline copies are inside a partition, we can
1291 end up not removing the body since we no longer have an
1292 analyzed node pointing to it. */
1293 && !node
->in_other_partition
1295 && !DECL_EXTERNAL (decl
))
1297 dump_cgraph_node (stderr
, node
);
1298 internal_error ("failed to reclaim unneeded function in same "
1305 /* DECL is FUNCTION_DECL. Initialize datastructures so DECL is a function
1306 in lowered gimple form. IN_SSA is true if the gimple is in SSA.
1308 Set current_function_decl and cfun to newly constructed empty function body.
1309 return basic block in the function body. */
1312 init_lowered_empty_function (tree decl
, bool in_ssa
)
1316 current_function_decl
= decl
;
1317 allocate_struct_function (decl
, false);
1318 gimple_register_cfg_hooks ();
1319 init_empty_tree_cfg ();
1323 init_tree_ssa (cfun
);
1324 init_ssa_operands (cfun
);
1325 cfun
->gimple_df
->in_ssa_p
= true;
1326 cfun
->curr_properties
|= PROP_ssa
;
1329 DECL_INITIAL (decl
) = make_node (BLOCK
);
1331 DECL_SAVED_TREE (decl
) = error_mark_node
;
1332 cfun
->curr_properties
|= (PROP_gimple_lcf
| PROP_gimple_leh
| PROP_gimple_any
1333 | PROP_cfg
| PROP_loops
);
1335 set_loops_for_fn (cfun
, ggc_alloc_cleared_loops ());
1336 init_loops_structure (cfun
, loops_for_fn (cfun
), 1);
1337 loops_for_fn (cfun
)->state
|= LOOPS_MAY_HAVE_MULTIPLE_LATCHES
;
1339 /* Create BB for body of the function and connect it properly. */
1340 bb
= create_basic_block (NULL
, (void *) 0, ENTRY_BLOCK_PTR
);
1341 make_edge (ENTRY_BLOCK_PTR
, bb
, EDGE_FALLTHRU
);
1342 make_edge (bb
, EXIT_BLOCK_PTR
, 0);
1343 add_bb_to_loop (bb
, ENTRY_BLOCK_PTR
->loop_father
);
1348 /* Adjust PTR by the constant FIXED_OFFSET, and by the vtable
1349 offset indicated by VIRTUAL_OFFSET, if that is
1350 non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and
1351 zero for a result adjusting thunk. */
1354 thunk_adjust (gimple_stmt_iterator
* bsi
,
1355 tree ptr
, bool this_adjusting
,
1356 HOST_WIDE_INT fixed_offset
, tree virtual_offset
)
1362 && fixed_offset
!= 0)
1364 stmt
= gimple_build_assign
1365 (ptr
, fold_build_pointer_plus_hwi_loc (input_location
,
1368 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1371 /* If there's a virtual offset, look up that value in the vtable and
1372 adjust the pointer again. */
1379 if (!vtable_entry_type
)
1381 tree vfunc_type
= make_node (FUNCTION_TYPE
);
1382 TREE_TYPE (vfunc_type
) = integer_type_node
;
1383 TYPE_ARG_TYPES (vfunc_type
) = NULL_TREE
;
1384 layout_type (vfunc_type
);
1386 vtable_entry_type
= build_pointer_type (vfunc_type
);
1390 create_tmp_reg (build_pointer_type
1391 (build_pointer_type (vtable_entry_type
)), "vptr");
1393 /* The vptr is always at offset zero in the object. */
1394 stmt
= gimple_build_assign (vtabletmp
,
1395 build1 (NOP_EXPR
, TREE_TYPE (vtabletmp
),
1397 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1399 /* Form the vtable address. */
1400 vtabletmp2
= create_tmp_reg (TREE_TYPE (TREE_TYPE (vtabletmp
)),
1402 stmt
= gimple_build_assign (vtabletmp2
,
1403 build_simple_mem_ref (vtabletmp
));
1404 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1406 /* Find the entry with the vcall offset. */
1407 stmt
= gimple_build_assign (vtabletmp2
,
1408 fold_build_pointer_plus_loc (input_location
,
1411 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1413 /* Get the offset itself. */
1414 vtabletmp3
= create_tmp_reg (TREE_TYPE (TREE_TYPE (vtabletmp2
)),
1416 stmt
= gimple_build_assign (vtabletmp3
,
1417 build_simple_mem_ref (vtabletmp2
));
1418 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1420 /* Adjust the `this' pointer. */
1421 ptr
= fold_build_pointer_plus_loc (input_location
, ptr
, vtabletmp3
);
1422 ptr
= force_gimple_operand_gsi (bsi
, ptr
, true, NULL_TREE
, false,
1423 GSI_CONTINUE_LINKING
);
1427 && fixed_offset
!= 0)
1428 /* Adjust the pointer by the constant. */
1432 if (TREE_CODE (ptr
) == VAR_DECL
)
1436 ptrtmp
= create_tmp_reg (TREE_TYPE (ptr
), "ptr");
1437 stmt
= gimple_build_assign (ptrtmp
, ptr
);
1438 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1440 ptr
= fold_build_pointer_plus_hwi_loc (input_location
,
1441 ptrtmp
, fixed_offset
);
1444 /* Emit the statement and gimplify the adjustment expression. */
1445 ret
= create_tmp_reg (TREE_TYPE (ptr
), "adjusted_this");
1446 stmt
= gimple_build_assign (ret
, ptr
);
1447 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1452 /* Expand thunk NODE to gimple if possible.
1453 When OUTPUT_ASM_THUNK is true, also produce assembler for
1454 thunks that are not lowered. */
1457 expand_thunk (struct cgraph_node
*node
, bool output_asm_thunks
)
1459 bool this_adjusting
= node
->thunk
.this_adjusting
;
1460 HOST_WIDE_INT fixed_offset
= node
->thunk
.fixed_offset
;
1461 HOST_WIDE_INT virtual_value
= node
->thunk
.virtual_value
;
1462 tree virtual_offset
= NULL
;
1463 tree alias
= node
->callees
->callee
->decl
;
1464 tree thunk_fndecl
= node
->decl
;
1469 && targetm
.asm_out
.can_output_mi_thunk (thunk_fndecl
, fixed_offset
,
1470 virtual_value
, alias
))
1474 tree restype
= TREE_TYPE (TREE_TYPE (thunk_fndecl
));
1476 if (!output_asm_thunks
)
1480 cgraph_get_body (node
);
1481 a
= DECL_ARGUMENTS (thunk_fndecl
);
1483 current_function_decl
= thunk_fndecl
;
1485 /* Ensure thunks are emitted in their correct sections. */
1486 resolve_unique_section (thunk_fndecl
, 0, flag_function_sections
);
1488 DECL_RESULT (thunk_fndecl
)
1489 = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl
),
1490 RESULT_DECL
, 0, restype
);
1491 DECL_CONTEXT (DECL_RESULT (thunk_fndecl
)) = thunk_fndecl
;
1492 fnname
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl
));
1494 /* The back end expects DECL_INITIAL to contain a BLOCK, so we
1496 fn_block
= make_node (BLOCK
);
1497 BLOCK_VARS (fn_block
) = a
;
1498 DECL_INITIAL (thunk_fndecl
) = fn_block
;
1499 init_function_start (thunk_fndecl
);
1501 insn_locations_init ();
1502 set_curr_insn_location (DECL_SOURCE_LOCATION (thunk_fndecl
));
1503 prologue_location
= curr_insn_location ();
1504 assemble_start_function (thunk_fndecl
, fnname
);
1506 targetm
.asm_out
.output_mi_thunk (asm_out_file
, thunk_fndecl
,
1507 fixed_offset
, virtual_value
, alias
);
1509 assemble_end_function (thunk_fndecl
, fnname
);
1510 insn_locations_finalize ();
1511 init_insn_lengths ();
1512 free_after_compilation (cfun
);
1514 TREE_ASM_WRITTEN (thunk_fndecl
) = 1;
1515 node
->thunk
.thunk_p
= false;
1516 node
->analyzed
= false;
1521 basic_block bb
, then_bb
, else_bb
, return_bb
;
1522 gimple_stmt_iterator bsi
;
1534 cgraph_get_body (node
);
1535 a
= DECL_ARGUMENTS (thunk_fndecl
);
1537 current_function_decl
= thunk_fndecl
;
1539 /* Ensure thunks are emitted in their correct sections. */
1540 resolve_unique_section (thunk_fndecl
, 0, flag_function_sections
);
1542 DECL_IGNORED_P (thunk_fndecl
) = 1;
1543 bitmap_obstack_initialize (NULL
);
1545 if (node
->thunk
.virtual_offset_p
)
1546 virtual_offset
= size_int (virtual_value
);
1548 /* Build the return declaration for the function. */
1549 restype
= TREE_TYPE (TREE_TYPE (thunk_fndecl
));
1550 if (DECL_RESULT (thunk_fndecl
) == NULL_TREE
)
1552 resdecl
= build_decl (input_location
, RESULT_DECL
, 0, restype
);
1553 DECL_ARTIFICIAL (resdecl
) = 1;
1554 DECL_IGNORED_P (resdecl
) = 1;
1555 DECL_RESULT (thunk_fndecl
) = resdecl
;
1556 DECL_CONTEXT (DECL_RESULT (thunk_fndecl
)) = thunk_fndecl
;
1559 resdecl
= DECL_RESULT (thunk_fndecl
);
1561 bb
= then_bb
= else_bb
= return_bb
= init_lowered_empty_function (thunk_fndecl
, true);
1563 bsi
= gsi_start_bb (bb
);
1565 /* Build call to the function being thunked. */
1566 if (!VOID_TYPE_P (restype
))
1568 if (DECL_BY_REFERENCE (resdecl
))
1569 restmp
= gimple_fold_indirect_ref (resdecl
);
1570 else if (!is_gimple_reg_type (restype
))
1573 add_local_decl (cfun
, restmp
);
1574 BLOCK_VARS (DECL_INITIAL (current_function_decl
)) = restmp
;
1577 restmp
= create_tmp_reg (restype
, "retval");
1580 for (arg
= a
; arg
; arg
= DECL_CHAIN (arg
))
1582 vargs
.create (nargs
);
1584 vargs
.quick_push (thunk_adjust (&bsi
, a
, 1, fixed_offset
,
1587 vargs
.quick_push (a
);
1590 for (i
= 1, arg
= DECL_CHAIN (a
); i
< nargs
; i
++, arg
= DECL_CHAIN (arg
))
1591 vargs
.quick_push (arg
);
1592 call
= gimple_build_call_vec (build_fold_addr_expr_loc (0, alias
), vargs
);
1593 node
->callees
->call_stmt
= call
;
1595 gimple_call_set_from_thunk (call
, true);
1598 gimple_call_set_lhs (call
, restmp
);
1599 gcc_assert (useless_type_conversion_p (TREE_TYPE (restmp
),
1600 TREE_TYPE (TREE_TYPE (alias
))));
1602 gsi_insert_after (&bsi
, call
, GSI_NEW_STMT
);
1603 if (!(gimple_call_flags (call
) & ECF_NORETURN
))
1605 if (restmp
&& !this_adjusting
1606 && (fixed_offset
|| virtual_offset
))
1608 tree true_label
= NULL_TREE
;
1610 if (TREE_CODE (TREE_TYPE (restmp
)) == POINTER_TYPE
)
1613 /* If the return type is a pointer, we need to
1614 protect against NULL. We know there will be an
1615 adjustment, because that's why we're emitting a
1617 then_bb
= create_basic_block (NULL
, (void *) 0, bb
);
1618 return_bb
= create_basic_block (NULL
, (void *) 0, then_bb
);
1619 else_bb
= create_basic_block (NULL
, (void *) 0, else_bb
);
1620 add_bb_to_loop (then_bb
, bb
->loop_father
);
1621 add_bb_to_loop (return_bb
, bb
->loop_father
);
1622 add_bb_to_loop (else_bb
, bb
->loop_father
);
1623 remove_edge (single_succ_edge (bb
));
1624 true_label
= gimple_block_label (then_bb
);
1625 stmt
= gimple_build_cond (NE_EXPR
, restmp
,
1626 build_zero_cst (TREE_TYPE (restmp
)),
1627 NULL_TREE
, NULL_TREE
);
1628 gsi_insert_after (&bsi
, stmt
, GSI_NEW_STMT
);
1629 make_edge (bb
, then_bb
, EDGE_TRUE_VALUE
);
1630 make_edge (bb
, else_bb
, EDGE_FALSE_VALUE
);
1631 make_edge (return_bb
, EXIT_BLOCK_PTR
, 0);
1632 make_edge (then_bb
, return_bb
, EDGE_FALLTHRU
);
1633 make_edge (else_bb
, return_bb
, EDGE_FALLTHRU
);
1634 bsi
= gsi_last_bb (then_bb
);
1637 restmp
= thunk_adjust (&bsi
, restmp
, /*this_adjusting=*/0,
1638 fixed_offset
, virtual_offset
);
1642 bsi
= gsi_last_bb (else_bb
);
1643 stmt
= gimple_build_assign (restmp
,
1644 build_zero_cst (TREE_TYPE (restmp
)));
1645 gsi_insert_after (&bsi
, stmt
, GSI_NEW_STMT
);
1646 bsi
= gsi_last_bb (return_bb
);
1650 gimple_call_set_tail (call
, true);
1652 /* Build return value. */
1653 ret
= gimple_build_return (restmp
);
1654 gsi_insert_after (&bsi
, ret
, GSI_NEW_STMT
);
1658 gimple_call_set_tail (call
, true);
1659 remove_edge (single_succ_edge (bb
));
1662 cfun
->gimple_df
->in_ssa_p
= true;
1663 /* FIXME: C++ FE should stop setting TREE_ASM_WRITTEN on thunks. */
1664 TREE_ASM_WRITTEN (thunk_fndecl
) = false;
1665 delete_unreachable_blocks ();
1666 update_ssa (TODO_update_ssa
);
1667 #ifdef ENABLE_CHECKING
1668 verify_flow_info ();
1671 /* Since we want to emit the thunk, we explicitly mark its name as
1673 node
->thunk
.thunk_p
= false;
1674 node
->lowered
= true;
1675 bitmap_obstack_release (NULL
);
1677 current_function_decl
= NULL
;
1682 /* Assemble thunks and aliases associated to NODE. */
1685 assemble_thunks_and_aliases (struct cgraph_node
*node
)
1687 struct cgraph_edge
*e
;
1689 struct ipa_ref
*ref
;
1691 for (e
= node
->callers
; e
;)
1692 if (e
->caller
->thunk
.thunk_p
)
1694 struct cgraph_node
*thunk
= e
->caller
;
1697 assemble_thunks_and_aliases (thunk
);
1698 expand_thunk (thunk
, true);
1702 for (i
= 0; ipa_ref_list_referring_iterate (&node
->ref_list
,
1704 if (ref
->use
== IPA_REF_ALIAS
)
1706 struct cgraph_node
*alias
= ipa_ref_referring_node (ref
);
1707 bool saved_written
= TREE_ASM_WRITTEN (node
->decl
);
1709 /* Force assemble_alias to really output the alias this time instead
1710 of buffering it in same alias pairs. */
1711 TREE_ASM_WRITTEN (node
->decl
) = 1;
1712 do_assemble_alias (alias
->decl
,
1713 DECL_ASSEMBLER_NAME (node
->decl
));
1714 assemble_thunks_and_aliases (alias
);
1715 TREE_ASM_WRITTEN (node
->decl
) = saved_written
;
1719 /* Expand function specified by NODE. */
1722 expand_function (struct cgraph_node
*node
)
1724 tree decl
= node
->decl
;
1725 location_t saved_loc
;
1727 /* We ought to not compile any inline clones. */
1728 gcc_assert (!node
->global
.inlined_to
);
1730 announce_function (decl
);
1732 gcc_assert (node
->lowered
);
1733 cgraph_get_body (node
);
1735 /* Generate RTL for the body of DECL. */
1737 timevar_push (TV_REST_OF_COMPILATION
);
1739 gcc_assert (cgraph_global_info_ready
);
1741 /* Initialize the default bitmap obstack. */
1742 bitmap_obstack_initialize (NULL
);
1744 /* Initialize the RTL code for the function. */
1745 current_function_decl
= decl
;
1746 saved_loc
= input_location
;
1747 input_location
= DECL_SOURCE_LOCATION (decl
);
1748 init_function_start (decl
);
1750 gimple_register_cfg_hooks ();
1752 bitmap_obstack_initialize (®_obstack
); /* FIXME, only at RTL generation*/
1754 execute_all_ipa_transforms ();
1756 /* Perform all tree transforms and optimizations. */
1758 /* Signal the start of passes. */
1759 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START
, NULL
);
1761 execute_pass_list (g
->get_passes ()->all_passes
);
1763 /* Signal the end of passes. */
1764 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END
, NULL
);
1766 bitmap_obstack_release (®_obstack
);
1768 /* Release the default bitmap obstack. */
1769 bitmap_obstack_release (NULL
);
1771 /* If requested, warn about function definitions where the function will
1772 return a value (usually of some struct or union type) which itself will
1773 take up a lot of stack space. */
1774 if (warn_larger_than
&& !DECL_EXTERNAL (decl
) && TREE_TYPE (decl
))
1776 tree ret_type
= TREE_TYPE (TREE_TYPE (decl
));
1778 if (ret_type
&& TYPE_SIZE_UNIT (ret_type
)
1779 && TREE_CODE (TYPE_SIZE_UNIT (ret_type
)) == INTEGER_CST
1780 && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type
),
1783 unsigned int size_as_int
1784 = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type
));
1786 if (compare_tree_int (TYPE_SIZE_UNIT (ret_type
), size_as_int
) == 0)
1787 warning (OPT_Wlarger_than_
, "size of return value of %q+D is %u bytes",
1790 warning (OPT_Wlarger_than_
, "size of return value of %q+D is larger than %wd bytes",
1791 decl
, larger_than_size
);
1795 gimple_set_body (decl
, NULL
);
1796 if (DECL_STRUCT_FUNCTION (decl
) == 0
1797 && !cgraph_get_node (decl
)->origin
)
1799 /* Stop pointing to the local nodes about to be freed.
1800 But DECL_INITIAL must remain nonzero so we know this
1801 was an actual function definition.
1802 For a nested function, this is done in c_pop_function_context.
1803 If rest_of_compilation set this to 0, leave it 0. */
1804 if (DECL_INITIAL (decl
) != 0)
1805 DECL_INITIAL (decl
) = error_mark_node
;
1808 input_location
= saved_loc
;
1811 timevar_pop (TV_REST_OF_COMPILATION
);
1813 /* Make sure that BE didn't give up on compiling. */
1814 gcc_assert (TREE_ASM_WRITTEN (decl
));
1816 current_function_decl
= NULL
;
1818 /* It would make a lot more sense to output thunks before function body to get more
1819 forward and lest backwarding jumps. This however would need solving problem
1820 with comdats. See PR48668. Also aliases must come after function itself to
1821 make one pass assemblers, like one on AIX, happy. See PR 50689.
1822 FIXME: Perhaps thunks should be move before function IFF they are not in comdat
1824 assemble_thunks_and_aliases (node
);
1825 cgraph_release_function_body (node
);
1826 /* Eliminate all call edges. This is important so the GIMPLE_CALL no longer
1827 points to the dead function body. */
1828 cgraph_node_remove_callees (node
);
1829 ipa_remove_all_references (&node
->ref_list
);
1833 /* Expand all functions that must be output.
1835 Attempt to topologically sort the nodes so function is output when
1836 all called functions are already assembled to allow data to be
1837 propagated across the callgraph. Use a stack to get smaller distance
1838 between a function and its callees (later we may choose to use a more
1839 sophisticated algorithm for function reordering; we will likely want
1840 to use subsections to make the output functions appear in top-down
1844 expand_all_functions (void)
1846 struct cgraph_node
*node
;
1847 struct cgraph_node
**order
= XCNEWVEC (struct cgraph_node
*, cgraph_n_nodes
);
1848 int order_pos
, new_order_pos
= 0;
1851 order_pos
= ipa_reverse_postorder (order
);
1852 gcc_assert (order_pos
== cgraph_n_nodes
);
1854 /* Garbage collector may remove inline clones we eliminate during
1855 optimization. So we must be sure to not reference them. */
1856 for (i
= 0; i
< order_pos
; i
++)
1857 if (order
[i
]->process
)
1858 order
[new_order_pos
++] = order
[i
];
1860 for (i
= new_order_pos
- 1; i
>= 0; i
--)
1866 expand_function (node
);
1869 cgraph_process_new_functions ();
1875 /* This is used to sort the node types by the cgraph order number. */
1877 enum cgraph_order_sort_kind
1879 ORDER_UNDEFINED
= 0,
1885 struct cgraph_order_sort
1887 enum cgraph_order_sort_kind kind
;
1890 struct cgraph_node
*f
;
1891 struct varpool_node
*v
;
1896 /* Output all functions, variables, and asm statements in the order
1897 according to their order fields, which is the order in which they
1898 appeared in the file. This implements -fno-toplevel-reorder. In
1899 this mode we may output functions and variables which don't really
1900 need to be output. */
1903 output_in_order (void)
1906 struct cgraph_order_sort
*nodes
;
1908 struct cgraph_node
*pf
;
1909 struct varpool_node
*pv
;
1910 struct asm_node
*pa
;
1913 nodes
= XCNEWVEC (struct cgraph_order_sort
, max
);
1915 FOR_EACH_DEFINED_FUNCTION (pf
)
1917 if (pf
->process
&& !pf
->thunk
.thunk_p
&& !pf
->alias
)
1920 gcc_assert (nodes
[i
].kind
== ORDER_UNDEFINED
);
1921 nodes
[i
].kind
= ORDER_FUNCTION
;
1926 FOR_EACH_DEFINED_VARIABLE (pv
)
1927 if (!DECL_EXTERNAL (pv
->decl
))
1930 gcc_assert (nodes
[i
].kind
== ORDER_UNDEFINED
);
1931 nodes
[i
].kind
= ORDER_VAR
;
1935 for (pa
= asm_nodes
; pa
; pa
= pa
->next
)
1938 gcc_assert (nodes
[i
].kind
== ORDER_UNDEFINED
);
1939 nodes
[i
].kind
= ORDER_ASM
;
1943 /* In toplevel reorder mode we output all statics; mark them as needed. */
1945 for (i
= 0; i
< max
; ++i
)
1946 if (nodes
[i
].kind
== ORDER_VAR
)
1947 varpool_finalize_named_section_flags (nodes
[i
].u
.v
);
1949 for (i
= 0; i
< max
; ++i
)
1951 switch (nodes
[i
].kind
)
1953 case ORDER_FUNCTION
:
1954 nodes
[i
].u
.f
->process
= 0;
1955 expand_function (nodes
[i
].u
.f
);
1959 varpool_assemble_decl (nodes
[i
].u
.v
);
1963 assemble_asm (nodes
[i
].u
.a
->asm_str
);
1966 case ORDER_UNDEFINED
:
1981 gcc::pass_manager
*passes
= g
->get_passes ();
1984 current_function_decl
= NULL
;
1985 gimple_register_cfg_hooks ();
1986 bitmap_obstack_initialize (NULL
);
1988 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START
, NULL
);
1992 execute_ipa_pass_list (passes
->all_small_ipa_passes
);
1997 /* We never run removal of unreachable nodes after early passes. This is
1998 because TODO is run before the subpasses. It is important to remove
1999 the unreachable functions to save works at IPA level and to get LTO
2000 symbol tables right. */
2001 symtab_remove_unreachable_nodes (true, cgraph_dump_file
);
2003 /* If pass_all_early_optimizations was not scheduled, the state of
2004 the cgraph will not be properly updated. Update it now. */
2005 if (cgraph_state
< CGRAPH_STATE_IPA_SSA
)
2006 cgraph_state
= CGRAPH_STATE_IPA_SSA
;
2010 /* Generate coverage variables and constructors. */
2013 /* Process new functions added. */
2015 current_function_decl
= NULL
;
2016 cgraph_process_new_functions ();
2018 execute_ipa_summary_passes
2019 ((struct ipa_opt_pass_d
*) passes
->all_regular_ipa_passes
);
2022 /* Some targets need to handle LTO assembler output specially. */
2023 if (flag_generate_lto
)
2024 targetm
.asm_out
.lto_start ();
2027 ipa_write_summaries ();
2029 if (flag_generate_lto
)
2030 targetm
.asm_out
.lto_end ();
2032 if (!flag_ltrans
&& (in_lto_p
|| !flag_lto
|| flag_fat_lto_objects
))
2033 execute_ipa_pass_list (passes
->all_regular_ipa_passes
);
2034 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END
, NULL
);
2036 bitmap_obstack_release (NULL
);
2040 /* Return string alias is alias of. */
2043 get_alias_symbol (tree decl
)
2045 tree alias
= lookup_attribute ("alias", DECL_ATTRIBUTES (decl
));
2046 return get_identifier (TREE_STRING_POINTER
2047 (TREE_VALUE (TREE_VALUE (alias
))));
2051 /* Weakrefs may be associated to external decls and thus not output
2052 at expansion time. Emit all necessary aliases. */
2055 output_weakrefs (void)
2058 FOR_EACH_SYMBOL (node
)
2060 && !TREE_ASM_WRITTEN (node
->decl
)
2065 /* Weakrefs are special by not requiring target definition in current
2066 compilation unit. It is thus bit hard to work out what we want to
2068 When alias target is defined, we need to fetch it from symtab reference,
2069 otherwise it is pointed to by alias_target. */
2070 if (node
->alias_target
)
2071 target
= (DECL_P (node
->alias_target
)
2072 ? DECL_ASSEMBLER_NAME (node
->alias_target
)
2073 : node
->alias_target
);
2074 else if (node
->analyzed
)
2075 target
= DECL_ASSEMBLER_NAME (symtab_alias_target (node
)->decl
);
2079 target
= get_alias_symbol (node
->decl
);
2081 do_assemble_alias (node
->decl
, target
);
2085 /* Initialize callgraph dump file. */
2090 if (!cgraph_dump_file
)
2091 cgraph_dump_file
= dump_begin (TDI_cgraph
, NULL
);
2095 /* Perform simple optimizations based on callgraph. */
2103 #ifdef ENABLE_CHECKING
2107 timevar_push (TV_CGRAPHOPT
);
2108 if (pre_ipa_mem_report
)
2110 fprintf (stderr
, "Memory consumption before IPA\n");
2111 dump_memory_report (false);
2114 fprintf (stderr
, "Performing interprocedural optimizations\n");
2115 cgraph_state
= CGRAPH_STATE_IPA
;
2117 /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE. */
2119 lto_streamer_hooks_init ();
2121 /* Don't run the IPA passes if there was any error or sorry messages. */
2125 /* Do nothing else if any IPA pass found errors or if we are just streaming LTO. */
2127 || (!in_lto_p
&& flag_lto
&& !flag_fat_lto_objects
))
2129 timevar_pop (TV_CGRAPHOPT
);
2133 /* This pass remove bodies of extern inline functions we never inlined.
2134 Do this later so other IPA passes see what is really going on. */
2135 symtab_remove_unreachable_nodes (false, dump_file
);
2136 cgraph_global_info_ready
= true;
2137 if (cgraph_dump_file
)
2139 fprintf (cgraph_dump_file
, "Optimized ");
2140 dump_symtab (cgraph_dump_file
);
2142 if (post_ipa_mem_report
)
2144 fprintf (stderr
, "Memory consumption after IPA\n");
2145 dump_memory_report (false);
2147 timevar_pop (TV_CGRAPHOPT
);
2149 /* Output everything. */
2150 (*debug_hooks
->assembly_start
) ();
2152 fprintf (stderr
, "Assembling functions:\n");
2153 #ifdef ENABLE_CHECKING
2157 cgraph_materialize_all_clones ();
2158 bitmap_obstack_initialize (NULL
);
2159 execute_ipa_pass_list (g
->get_passes ()->all_late_ipa_passes
);
2160 symtab_remove_unreachable_nodes (true, dump_file
);
2161 #ifdef ENABLE_CHECKING
2164 bitmap_obstack_release (NULL
);
2165 mark_functions_to_output ();
2167 /* When weakref support is missing, we autmatically translate all
2168 references to NODE to references to its ultimate alias target.
2169 The renaming mechanizm uses flag IDENTIFIER_TRANSPARENT_ALIAS and
2172 Set up this mapping before we output any assembler but once we are sure
2173 that all symbol renaming is done.
2175 FIXME: All this uglyness can go away if we just do renaming at gimple
2176 level by physically rewritting the IL. At the moment we can only redirect
2177 calls, so we need infrastructure for renaming references as well. */
2178 #ifndef ASM_OUTPUT_WEAKREF
2181 FOR_EACH_SYMBOL (node
)
2183 && lookup_attribute ("weakref", DECL_ATTRIBUTES (node
->decl
)))
2185 IDENTIFIER_TRANSPARENT_ALIAS
2186 (DECL_ASSEMBLER_NAME (node
->decl
)) = 1;
2187 TREE_CHAIN (DECL_ASSEMBLER_NAME (node
->decl
))
2188 = (node
->alias_target
? node
->alias_target
2189 : DECL_ASSEMBLER_NAME (symtab_alias_target (node
)->decl
));
2193 cgraph_state
= CGRAPH_STATE_EXPANSION
;
2194 if (!flag_toplevel_reorder
)
2198 output_asm_statements ();
2200 expand_all_functions ();
2201 varpool_output_variables ();
2204 cgraph_process_new_functions ();
2205 cgraph_state
= CGRAPH_STATE_FINISHED
;
2208 if (cgraph_dump_file
)
2210 fprintf (cgraph_dump_file
, "\nFinal ");
2211 dump_symtab (cgraph_dump_file
);
2213 #ifdef ENABLE_CHECKING
2215 /* Double check that all inline clones are gone and that all
2216 function bodies have been released from memory. */
2219 struct cgraph_node
*node
;
2220 bool error_found
= false;
2222 FOR_EACH_DEFINED_FUNCTION (node
)
2223 if (node
->global
.inlined_to
2224 || gimple_has_body_p (node
->decl
))
2227 dump_cgraph_node (stderr
, node
);
2230 internal_error ("nodes with unreleased memory found");
2236 /* Analyze the whole compilation unit once it is parsed completely. */
2239 finalize_compilation_unit (void)
2241 timevar_push (TV_CGRAPH
);
2243 /* If we're here there's no current function anymore. Some frontends
2244 are lazy in clearing these. */
2245 current_function_decl
= NULL
;
2248 /* Do not skip analyzing the functions if there were errors, we
2249 miss diagnostics for following functions otherwise. */
2251 /* Emit size functions we didn't inline. */
2252 finalize_size_functions ();
2254 /* Mark alias targets necessary and emit diagnostics. */
2255 handle_alias_pairs ();
2259 fprintf (stderr
, "\nAnalyzing compilation unit\n");
2263 if (flag_dump_passes
)
2266 /* Gimplify and lower all functions, compute reachability and
2267 remove unreachable nodes. */
2268 analyze_functions ();
2270 /* Mark alias targets necessary and emit diagnostics. */
2271 handle_alias_pairs ();
2273 /* Gimplify and lower thunks. */
2274 analyze_functions ();
2276 /* Finally drive the pass manager. */
2279 timevar_pop (TV_CGRAPH
);
2283 #include "gt-cgraphunit.h"