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_PRESERVE_P (decl
))
786 vnode
->symbol
.force_output
= true;
787 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl
)))
789 if (! TREE_PUBLIC (vnode
->symbol
.decl
))
790 warning_at (DECL_SOURCE_LOCATION (vnode
->symbol
.decl
), OPT_Wattributes
,
791 "%<externally_visible%>"
792 " attribute have effect only on public objects");
794 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl
))
796 && DECL_INITIAL (decl
))
798 warning_at (DECL_SOURCE_LOCATION (vnode
->symbol
.decl
), OPT_Wattributes
,
799 "%<weakref%> attribute ignored"
800 " because variable is initialized");
801 DECL_WEAK (decl
) = 0;
802 DECL_ATTRIBUTES (decl
) = remove_attribute ("weakref",
803 DECL_ATTRIBUTES (decl
));
805 process_common_attributes (decl
);
809 /* Mark DECL as finalized. By finalizing the declaration, frontend instruct the
810 middle end to output the variable to asm file, if needed or externally
814 varpool_finalize_decl (tree decl
)
816 struct varpool_node
*node
= varpool_node (decl
);
818 gcc_assert (TREE_STATIC (decl
));
822 notice_global_symbol (decl
);
823 node
->finalized
= true;
824 if (TREE_THIS_VOLATILE (decl
) || DECL_PRESERVE_P (decl
)
825 /* Traditionally we do not eliminate static variables when not
826 optimizing and when not doing toplevel reoder. */
827 || (!flag_toplevel_reorder
&& !DECL_COMDAT (node
->symbol
.decl
)
828 && !DECL_ARTIFICIAL (node
->symbol
.decl
)))
829 node
->symbol
.force_output
= true;
831 if (cgraph_state
== CGRAPH_STATE_CONSTRUCTION
832 && (decide_is_variable_needed (node
, decl
)
833 || referred_to_p ((symtab_node
)node
)))
834 enqueue_node ((symtab_node
)node
);
835 if (cgraph_state
>= CGRAPH_STATE_IPA_SSA
)
836 varpool_analyze_node (node
);
839 /* Discover all functions and variables that are trivially needed, analyze
840 them as well as all functions and variables referred by them */
843 cgraph_analyze_functions (void)
845 /* Keep track of already processed nodes when called multiple times for
846 intermodule optimization. */
847 static struct cgraph_node
*first_analyzed
;
848 struct cgraph_node
*first_handled
= first_analyzed
;
849 static struct varpool_node
*first_analyzed_var
;
850 struct varpool_node
*first_handled_var
= first_analyzed_var
;
852 symtab_node node
, next
;
857 bitmap_obstack_initialize (NULL
);
858 cgraph_state
= CGRAPH_STATE_CONSTRUCTION
;
860 /* Analysis adds static variables that in turn adds references to new functions.
861 So we need to iterate the process until it stabilize. */
865 process_function_and_variable_attributes (first_analyzed
,
868 /* First identify the trivially needed symbols. */
869 for (node
= symtab_nodes
;
870 node
!= (symtab_node
)first_analyzed
871 && node
!= (symtab_node
)first_analyzed_var
; node
= node
->symbol
.next
)
873 if ((symtab_function_p (node
)
874 && cgraph (node
)->local
.finalized
875 && cgraph_decide_is_function_needed (cgraph (node
), node
->symbol
.decl
))
876 || (symtab_variable_p (node
)
877 && varpool (node
)->finalized
878 && !DECL_EXTERNAL (node
->symbol
.decl
)
879 && decide_is_variable_needed (varpool (node
), node
->symbol
.decl
)))
882 if (!changed
&& cgraph_dump_file
)
883 fprintf (cgraph_dump_file
, "Trivially needed symbols:");
885 if (cgraph_dump_file
)
886 fprintf (cgraph_dump_file
, " %s", symtab_node_asm_name (node
));
888 if (node
== (symtab_node
)first_analyzed
889 || node
== (symtab_node
)first_analyzed_var
)
892 cgraph_process_new_functions ();
893 first_analyzed_var
= varpool_first_variable ();
894 first_analyzed
= cgraph_first_function ();
896 if (changed
&& dump_file
)
897 fprintf (cgraph_dump_file
, "\n");
899 /* Lower representation, build callgraph edges and references for all trivially
900 needed symbols and all symbols referred by them. */
901 while (first
!= (symtab_node
)(void *)1)
905 first
= (symtab_node
)first
->symbol
.aux
;
906 if (symtab_function_p (node
) && cgraph (node
)->local
.finalized
)
908 struct cgraph_edge
*edge
;
909 struct cgraph_node
*cnode
;
912 cnode
= cgraph (node
);
913 decl
= cnode
->symbol
.decl
;
915 /* ??? It is possible to create extern inline function and later using
916 weak alias attribute to kill its body. See
917 gcc.c-torture/compile/20011119-1.c */
918 if (!DECL_STRUCT_FUNCTION (decl
)
919 && (!cnode
->alias
|| !cnode
->thunk
.alias
)
920 && !cnode
->thunk
.thunk_p
)
922 cgraph_reset_node (cnode
);
923 cnode
->local
.redefined_extern_inline
= true;
927 if (!cnode
->analyzed
)
928 cgraph_analyze_function (cnode
);
930 for (edge
= cnode
->callees
; edge
; edge
= edge
->next_callee
)
931 if (edge
->callee
->local
.finalized
)
932 enqueue_node ((symtab_node
)edge
->callee
);
934 /* If decl is a clone of an abstract function, mark that abstract
935 function so that we don't release its body. The DECL_INITIAL() of that
936 abstract function declaration will be later needed to output debug
938 if (DECL_ABSTRACT_ORIGIN (decl
))
940 struct cgraph_node
*origin_node
;
941 origin_node
= cgraph_get_node (DECL_ABSTRACT_ORIGIN (decl
));
942 origin_node
->abstract_and_needed
= true;
946 else if (symtab_variable_p (node
)
947 && varpool (node
)->finalized
)
948 varpool_analyze_node (varpool (node
));
950 if (node
->symbol
.same_comdat_group
)
953 for (next
= node
->symbol
.same_comdat_group
;
955 next
= next
->symbol
.same_comdat_group
)
958 for (i
= 0; ipa_ref_list_reference_iterate (&node
->symbol
.ref_list
, i
, ref
); i
++)
959 if ((symtab_function_p (ref
->referred
) && cgraph (ref
->referred
)->local
.finalized
)
960 || (symtab_variable_p (ref
->referred
) && varpool (ref
->referred
)->finalized
))
961 enqueue_node (ref
->referred
);
962 cgraph_process_new_functions ();
966 /* Collect entry points to the unit. */
967 if (cgraph_dump_file
)
969 fprintf (cgraph_dump_file
, "\n\nInitial ");
970 dump_symtab (cgraph_dump_file
);
973 if (cgraph_dump_file
)
974 fprintf (cgraph_dump_file
, "\nRemoving unused symbols:");
976 for (node
= symtab_nodes
;
977 node
!= (symtab_node
)first_handled
978 && node
!= (symtab_node
)first_handled_var
; node
= next
)
980 next
= node
->symbol
.next
;
981 if (!node
->symbol
.aux
&& !referred_to_p (node
))
983 if (cgraph_dump_file
)
984 fprintf (cgraph_dump_file
, " %s", symtab_node_name (node
));
985 symtab_remove_node (node
);
988 if (symtab_function_p (node
))
990 tree decl
= node
->symbol
.decl
;
991 struct cgraph_node
*cnode
= cgraph (node
);
993 if (cnode
->local
.finalized
&& !gimple_has_body_p (decl
)
994 && (!cnode
->alias
|| !cnode
->thunk
.alias
)
995 && !cnode
->thunk
.thunk_p
)
996 cgraph_reset_node (cnode
);
998 gcc_assert (!cnode
->local
.finalized
|| cnode
->thunk
.thunk_p
1000 || gimple_has_body_p (decl
));
1001 gcc_assert (cnode
->analyzed
== cnode
->local
.finalized
);
1003 node
->symbol
.aux
= NULL
;
1005 first_analyzed
= cgraph_first_function ();
1006 first_analyzed_var
= varpool_first_variable ();
1007 if (cgraph_dump_file
)
1009 fprintf (cgraph_dump_file
, "\n\nReclaimed ");
1010 dump_symtab (cgraph_dump_file
);
1012 bitmap_obstack_release (NULL
);
1016 /* Translate the ugly representation of aliases as alias pairs into nice
1017 representation in callgraph. We don't handle all cases yet,
1021 handle_alias_pairs (void)
1025 struct cgraph_node
*target_node
;
1026 struct cgraph_node
*src_node
;
1027 struct varpool_node
*target_vnode
;
1029 for (i
= 0; VEC_iterate (alias_pair
, alias_pairs
, i
, p
);)
1031 if (TREE_CODE (p
->decl
) == FUNCTION_DECL
1032 && (target_node
= cgraph_node_for_asm (p
->target
)) != NULL
)
1034 src_node
= cgraph_get_node (p
->decl
);
1035 if (src_node
&& src_node
->local
.finalized
)
1036 cgraph_reset_node (src_node
);
1037 /* Normally EXTERNAL flag is used to mark external inlines,
1038 however for aliases it seems to be allowed to use it w/o
1039 any meaning. See gcc.dg/attr-alias-3.c
1040 However for weakref we insist on EXTERNAL flag being set.
1041 See gcc.dg/attr-alias-5.c */
1042 if (DECL_EXTERNAL (p
->decl
))
1043 DECL_EXTERNAL (p
->decl
)
1044 = lookup_attribute ("weakref",
1045 DECL_ATTRIBUTES (p
->decl
)) != NULL
;
1046 cgraph_create_function_alias (p
->decl
, target_node
->symbol
.decl
);
1047 VEC_unordered_remove (alias_pair
, alias_pairs
, i
);
1049 else if (TREE_CODE (p
->decl
) == VAR_DECL
1050 && (target_vnode
= varpool_node_for_asm (p
->target
)) != NULL
)
1052 /* Normally EXTERNAL flag is used to mark external inlines,
1053 however for aliases it seems to be allowed to use it w/o
1054 any meaning. See gcc.dg/attr-alias-3.c
1055 However for weakref we insist on EXTERNAL flag being set.
1056 See gcc.dg/attr-alias-5.c */
1057 if (DECL_EXTERNAL (p
->decl
))
1058 DECL_EXTERNAL (p
->decl
)
1059 = lookup_attribute ("weakref",
1060 DECL_ATTRIBUTES (p
->decl
)) != NULL
;
1061 varpool_create_variable_alias (p
->decl
, target_vnode
->symbol
.decl
);
1062 VEC_unordered_remove (alias_pair
, alias_pairs
, i
);
1064 /* Weakrefs with target not defined in current unit are easy to handle; they
1065 behave just as external variables except we need to note the alias flag
1066 to later output the weakref pseudo op into asm file. */
1067 else if (lookup_attribute ("weakref", DECL_ATTRIBUTES (p
->decl
)) != NULL
1068 && (TREE_CODE (p
->decl
) == FUNCTION_DECL
1069 ? (varpool_node_for_asm (p
->target
) == NULL
)
1070 : (cgraph_node_for_asm (p
->target
) == NULL
)))
1072 if (TREE_CODE (p
->decl
) == FUNCTION_DECL
)
1073 cgraph_get_create_node (p
->decl
)->alias
= true;
1075 varpool_get_node (p
->decl
)->alias
= true;
1076 DECL_EXTERNAL (p
->decl
) = 1;
1077 VEC_unordered_remove (alias_pair
, alias_pairs
, i
);
1082 fprintf (dump_file
, "Unhandled alias %s->%s\n",
1083 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (p
->decl
)),
1084 IDENTIFIER_POINTER (p
->target
));
1092 /* Figure out what functions we want to assemble. */
1095 mark_functions_to_output (void)
1097 struct cgraph_node
*node
;
1098 #ifdef ENABLE_CHECKING
1099 bool check_same_comdat_groups
= false;
1101 FOR_EACH_FUNCTION (node
)
1102 gcc_assert (!node
->process
);
1105 FOR_EACH_FUNCTION (node
)
1107 tree decl
= node
->symbol
.decl
;
1109 gcc_assert (!node
->process
|| node
->symbol
.same_comdat_group
);
1113 /* We need to output all local functions that are used and not
1114 always inlined, as well as those that are reachable from
1115 outside the current compilation unit. */
1117 && !node
->thunk
.thunk_p
1119 && !node
->global
.inlined_to
1120 && !TREE_ASM_WRITTEN (decl
)
1121 && !DECL_EXTERNAL (decl
))
1124 if (node
->symbol
.same_comdat_group
)
1126 struct cgraph_node
*next
;
1127 for (next
= cgraph (node
->symbol
.same_comdat_group
);
1129 next
= cgraph (next
->symbol
.same_comdat_group
))
1130 if (!next
->thunk
.thunk_p
&& !next
->alias
)
1134 else if (node
->symbol
.same_comdat_group
)
1136 #ifdef ENABLE_CHECKING
1137 check_same_comdat_groups
= true;
1142 /* We should've reclaimed all functions that are not needed. */
1143 #ifdef ENABLE_CHECKING
1144 if (!node
->global
.inlined_to
1145 && gimple_has_body_p (decl
)
1146 /* FIXME: in ltrans unit when offline copy is outside partition but inline copies
1147 are inside partition, we can end up not removing the body since we no longer
1148 have analyzed node pointing to it. */
1149 && !node
->symbol
.in_other_partition
1151 && !DECL_EXTERNAL (decl
))
1153 dump_cgraph_node (stderr
, node
);
1154 internal_error ("failed to reclaim unneeded function");
1157 gcc_assert (node
->global
.inlined_to
1158 || !gimple_has_body_p (decl
)
1159 || node
->symbol
.in_other_partition
1160 || DECL_EXTERNAL (decl
));
1165 #ifdef ENABLE_CHECKING
1166 if (check_same_comdat_groups
)
1167 FOR_EACH_FUNCTION (node
)
1168 if (node
->symbol
.same_comdat_group
&& !node
->process
)
1170 tree decl
= node
->symbol
.decl
;
1171 if (!node
->global
.inlined_to
1172 && gimple_has_body_p (decl
)
1173 /* FIXME: in an ltrans unit when the offline copy is outside a
1174 partition but inline copies are inside a partition, we can
1175 end up not removing the body since we no longer have an
1176 analyzed node pointing to it. */
1177 && !node
->symbol
.in_other_partition
1178 && !DECL_EXTERNAL (decl
))
1180 dump_cgraph_node (stderr
, node
);
1181 internal_error ("failed to reclaim unneeded function in same "
1188 /* DECL is FUNCTION_DECL. Initialize datastructures so DECL is a function
1189 in lowered gimple form.
1191 Set current_function_decl and cfun to newly constructed empty function body.
1192 return basic block in the function body. */
1195 init_lowered_empty_function (tree decl
)
1199 current_function_decl
= decl
;
1200 allocate_struct_function (decl
, false);
1201 gimple_register_cfg_hooks ();
1202 init_empty_tree_cfg ();
1203 init_tree_ssa (cfun
);
1204 init_ssa_operands ();
1205 cfun
->gimple_df
->in_ssa_p
= true;
1206 DECL_INITIAL (decl
) = make_node (BLOCK
);
1208 DECL_SAVED_TREE (decl
) = error_mark_node
;
1209 cfun
->curr_properties
|=
1210 (PROP_gimple_lcf
| PROP_gimple_leh
| PROP_cfg
| PROP_referenced_vars
|
1211 PROP_ssa
| PROP_gimple_any
);
1213 /* Create BB for body of the function and connect it properly. */
1214 bb
= create_basic_block (NULL
, (void *) 0, ENTRY_BLOCK_PTR
);
1215 make_edge (ENTRY_BLOCK_PTR
, bb
, 0);
1216 make_edge (bb
, EXIT_BLOCK_PTR
, 0);
1221 /* Adjust PTR by the constant FIXED_OFFSET, and by the vtable
1222 offset indicated by VIRTUAL_OFFSET, if that is
1223 non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and
1224 zero for a result adjusting thunk. */
1227 thunk_adjust (gimple_stmt_iterator
* bsi
,
1228 tree ptr
, bool this_adjusting
,
1229 HOST_WIDE_INT fixed_offset
, tree virtual_offset
)
1235 && fixed_offset
!= 0)
1237 stmt
= gimple_build_assign
1238 (ptr
, fold_build_pointer_plus_hwi_loc (input_location
,
1241 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1244 /* If there's a virtual offset, look up that value in the vtable and
1245 adjust the pointer again. */
1252 if (!vtable_entry_type
)
1254 tree vfunc_type
= make_node (FUNCTION_TYPE
);
1255 TREE_TYPE (vfunc_type
) = integer_type_node
;
1256 TYPE_ARG_TYPES (vfunc_type
) = NULL_TREE
;
1257 layout_type (vfunc_type
);
1259 vtable_entry_type
= build_pointer_type (vfunc_type
);
1263 create_tmp_var (build_pointer_type
1264 (build_pointer_type (vtable_entry_type
)), "vptr");
1266 /* The vptr is always at offset zero in the object. */
1267 stmt
= gimple_build_assign (vtabletmp
,
1268 build1 (NOP_EXPR
, TREE_TYPE (vtabletmp
),
1270 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1271 mark_symbols_for_renaming (stmt
);
1272 find_referenced_vars_in (stmt
);
1274 /* Form the vtable address. */
1275 vtabletmp2
= create_tmp_var (TREE_TYPE (TREE_TYPE (vtabletmp
)),
1277 stmt
= gimple_build_assign (vtabletmp2
,
1278 build_simple_mem_ref (vtabletmp
));
1279 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1280 mark_symbols_for_renaming (stmt
);
1281 find_referenced_vars_in (stmt
);
1283 /* Find the entry with the vcall offset. */
1284 stmt
= gimple_build_assign (vtabletmp2
,
1285 fold_build_pointer_plus_loc (input_location
,
1288 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1290 /* Get the offset itself. */
1291 vtabletmp3
= create_tmp_var (TREE_TYPE (TREE_TYPE (vtabletmp2
)),
1293 stmt
= gimple_build_assign (vtabletmp3
,
1294 build_simple_mem_ref (vtabletmp2
));
1295 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1296 mark_symbols_for_renaming (stmt
);
1297 find_referenced_vars_in (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
= create_tmp_var (TREE_TYPE (ptr
), "ptr");
1316 stmt
= gimple_build_assign (ptrtmp
, ptr
);
1317 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1318 mark_symbols_for_renaming (stmt
);
1319 find_referenced_vars_in (stmt
);
1321 ptr
= fold_build_pointer_plus_hwi_loc (input_location
,
1322 ptrtmp
, fixed_offset
);
1325 /* Emit the statement and gimplify the adjustment expression. */
1326 ret
= create_tmp_var (TREE_TYPE (ptr
), "adjusted_this");
1327 stmt
= gimple_build_assign (ret
, ptr
);
1328 mark_symbols_for_renaming (stmt
);
1329 find_referenced_vars_in (stmt
);
1330 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1335 /* Produce assembler for thunk NODE. */
1338 assemble_thunk (struct cgraph_node
*node
)
1340 bool this_adjusting
= node
->thunk
.this_adjusting
;
1341 HOST_WIDE_INT fixed_offset
= node
->thunk
.fixed_offset
;
1342 HOST_WIDE_INT virtual_value
= node
->thunk
.virtual_value
;
1343 tree virtual_offset
= NULL
;
1344 tree alias
= node
->thunk
.alias
;
1345 tree thunk_fndecl
= node
->symbol
.decl
;
1346 tree a
= DECL_ARGUMENTS (thunk_fndecl
);
1348 current_function_decl
= thunk_fndecl
;
1350 /* Ensure thunks are emitted in their correct sections. */
1351 resolve_unique_section (thunk_fndecl
, 0, flag_function_sections
);
1354 && targetm
.asm_out
.can_output_mi_thunk (thunk_fndecl
, fixed_offset
,
1355 virtual_value
, alias
))
1359 tree restype
= TREE_TYPE (TREE_TYPE (thunk_fndecl
));
1361 DECL_RESULT (thunk_fndecl
)
1362 = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl
),
1363 RESULT_DECL
, 0, restype
);
1364 fnname
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl
));
1366 /* The back end expects DECL_INITIAL to contain a BLOCK, so we
1368 fn_block
= make_node (BLOCK
);
1369 BLOCK_VARS (fn_block
) = a
;
1370 DECL_INITIAL (thunk_fndecl
) = fn_block
;
1371 init_function_start (thunk_fndecl
);
1373 assemble_start_function (thunk_fndecl
, fnname
);
1375 targetm
.asm_out
.output_mi_thunk (asm_out_file
, thunk_fndecl
,
1376 fixed_offset
, virtual_value
, alias
);
1378 assemble_end_function (thunk_fndecl
, fnname
);
1379 init_insn_lengths ();
1380 free_after_compilation (cfun
);
1382 TREE_ASM_WRITTEN (thunk_fndecl
) = 1;
1383 node
->thunk
.thunk_p
= false;
1384 node
->analyzed
= false;
1389 basic_block bb
, then_bb
, else_bb
, return_bb
;
1390 gimple_stmt_iterator bsi
;
1396 VEC(tree
, heap
) *vargs
;
1401 DECL_IGNORED_P (thunk_fndecl
) = 1;
1402 bitmap_obstack_initialize (NULL
);
1404 if (node
->thunk
.virtual_offset_p
)
1405 virtual_offset
= size_int (virtual_value
);
1407 /* Build the return declaration for the function. */
1408 restype
= TREE_TYPE (TREE_TYPE (thunk_fndecl
));
1409 if (DECL_RESULT (thunk_fndecl
) == NULL_TREE
)
1411 resdecl
= build_decl (input_location
, RESULT_DECL
, 0, restype
);
1412 DECL_ARTIFICIAL (resdecl
) = 1;
1413 DECL_IGNORED_P (resdecl
) = 1;
1414 DECL_RESULT (thunk_fndecl
) = resdecl
;
1417 resdecl
= DECL_RESULT (thunk_fndecl
);
1419 bb
= then_bb
= else_bb
= return_bb
= init_lowered_empty_function (thunk_fndecl
);
1421 bsi
= gsi_start_bb (bb
);
1423 /* Build call to the function being thunked. */
1424 if (!VOID_TYPE_P (restype
))
1426 if (!is_gimple_reg_type (restype
))
1429 add_local_decl (cfun
, restmp
);
1430 BLOCK_VARS (DECL_INITIAL (current_function_decl
)) = restmp
;
1433 restmp
= create_tmp_var_raw (restype
, "retval");
1436 for (arg
= a
; arg
; arg
= DECL_CHAIN (arg
))
1438 vargs
= VEC_alloc (tree
, heap
, nargs
);
1440 VEC_quick_push (tree
, vargs
,
1445 VEC_quick_push (tree
, vargs
, a
);
1446 for (i
= 1, arg
= DECL_CHAIN (a
); i
< nargs
; i
++, arg
= DECL_CHAIN (arg
))
1447 VEC_quick_push (tree
, vargs
, arg
);
1448 call
= gimple_build_call_vec (build_fold_addr_expr_loc (0, alias
), vargs
);
1449 VEC_free (tree
, heap
, vargs
);
1450 gimple_call_set_from_thunk (call
, true);
1452 gimple_call_set_lhs (call
, restmp
);
1453 gsi_insert_after (&bsi
, call
, GSI_NEW_STMT
);
1454 mark_symbols_for_renaming (call
);
1455 find_referenced_vars_in (call
);
1458 if (restmp
&& !this_adjusting
)
1460 tree true_label
= NULL_TREE
;
1462 if (TREE_CODE (TREE_TYPE (restmp
)) == POINTER_TYPE
)
1465 /* If the return type is a pointer, we need to
1466 protect against NULL. We know there will be an
1467 adjustment, because that's why we're emitting a
1469 then_bb
= create_basic_block (NULL
, (void *) 0, bb
);
1470 return_bb
= create_basic_block (NULL
, (void *) 0, then_bb
);
1471 else_bb
= create_basic_block (NULL
, (void *) 0, else_bb
);
1472 remove_edge (single_succ_edge (bb
));
1473 true_label
= gimple_block_label (then_bb
);
1474 stmt
= gimple_build_cond (NE_EXPR
, restmp
,
1475 build_zero_cst (TREE_TYPE (restmp
)),
1476 NULL_TREE
, NULL_TREE
);
1477 gsi_insert_after (&bsi
, stmt
, GSI_NEW_STMT
);
1478 make_edge (bb
, then_bb
, EDGE_TRUE_VALUE
);
1479 make_edge (bb
, else_bb
, EDGE_FALSE_VALUE
);
1480 make_edge (return_bb
, EXIT_BLOCK_PTR
, 0);
1481 make_edge (then_bb
, return_bb
, EDGE_FALLTHRU
);
1482 make_edge (else_bb
, return_bb
, EDGE_FALLTHRU
);
1483 bsi
= gsi_last_bb (then_bb
);
1486 restmp
= thunk_adjust (&bsi
, restmp
, /*this_adjusting=*/0,
1487 fixed_offset
, virtual_offset
);
1491 bsi
= gsi_last_bb (else_bb
);
1492 stmt
= gimple_build_assign (restmp
,
1493 build_zero_cst (TREE_TYPE (restmp
)));
1494 gsi_insert_after (&bsi
, stmt
, GSI_NEW_STMT
);
1495 bsi
= gsi_last_bb (return_bb
);
1499 gimple_call_set_tail (call
, true);
1501 /* Build return value. */
1502 ret
= gimple_build_return (restmp
);
1503 gsi_insert_after (&bsi
, ret
, GSI_NEW_STMT
);
1505 delete_unreachable_blocks ();
1506 update_ssa (TODO_update_ssa
);
1508 /* Since we want to emit the thunk, we explicitly mark its name as
1510 node
->thunk
.thunk_p
= false;
1511 cgraph_node_remove_callees (node
);
1512 cgraph_add_new_function (thunk_fndecl
, true);
1513 bitmap_obstack_release (NULL
);
1515 current_function_decl
= NULL
;
1520 /* Assemble thunks and aliases asociated to NODE. */
1523 assemble_thunks_and_aliases (struct cgraph_node
*node
)
1525 struct cgraph_edge
*e
;
1527 struct ipa_ref
*ref
;
1529 for (e
= node
->callers
; e
;)
1530 if (e
->caller
->thunk
.thunk_p
)
1532 struct cgraph_node
*thunk
= e
->caller
;
1535 assemble_thunks_and_aliases (thunk
);
1536 assemble_thunk (thunk
);
1540 for (i
= 0; ipa_ref_list_referring_iterate (&node
->symbol
.ref_list
,
1542 if (ref
->use
== IPA_REF_ALIAS
)
1544 struct cgraph_node
*alias
= ipa_ref_referring_node (ref
);
1545 bool saved_written
= TREE_ASM_WRITTEN (alias
->thunk
.alias
);
1547 /* Force assemble_alias to really output the alias this time instead
1548 of buffering it in same alias pairs. */
1549 TREE_ASM_WRITTEN (alias
->thunk
.alias
) = 1;
1550 assemble_alias (alias
->symbol
.decl
,
1551 DECL_ASSEMBLER_NAME (alias
->thunk
.alias
));
1552 assemble_thunks_and_aliases (alias
);
1553 TREE_ASM_WRITTEN (alias
->thunk
.alias
) = saved_written
;
1557 /* Expand function specified by NODE. */
1560 expand_function (struct cgraph_node
*node
)
1562 tree decl
= node
->symbol
.decl
;
1563 location_t saved_loc
;
1565 /* We ought to not compile any inline clones. */
1566 gcc_assert (!node
->global
.inlined_to
);
1568 announce_function (decl
);
1570 gcc_assert (node
->lowered
);
1572 /* Generate RTL for the body of DECL. */
1574 timevar_push (TV_REST_OF_COMPILATION
);
1576 gcc_assert (cgraph_global_info_ready
);
1578 /* Initialize the default bitmap obstack. */
1579 bitmap_obstack_initialize (NULL
);
1581 /* Initialize the RTL code for the function. */
1582 current_function_decl
= decl
;
1583 saved_loc
= input_location
;
1584 input_location
= DECL_SOURCE_LOCATION (decl
);
1585 init_function_start (decl
);
1587 gimple_register_cfg_hooks ();
1589 bitmap_obstack_initialize (®_obstack
); /* FIXME, only at RTL generation*/
1591 execute_all_ipa_transforms ();
1593 /* Perform all tree transforms and optimizations. */
1595 /* Signal the start of passes. */
1596 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START
, NULL
);
1598 execute_pass_list (all_passes
);
1600 /* Signal the end of passes. */
1601 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END
, NULL
);
1603 bitmap_obstack_release (®_obstack
);
1605 /* Release the default bitmap obstack. */
1606 bitmap_obstack_release (NULL
);
1610 /* If requested, warn about function definitions where the function will
1611 return a value (usually of some struct or union type) which itself will
1612 take up a lot of stack space. */
1613 if (warn_larger_than
&& !DECL_EXTERNAL (decl
) && TREE_TYPE (decl
))
1615 tree ret_type
= TREE_TYPE (TREE_TYPE (decl
));
1617 if (ret_type
&& TYPE_SIZE_UNIT (ret_type
)
1618 && TREE_CODE (TYPE_SIZE_UNIT (ret_type
)) == INTEGER_CST
1619 && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type
),
1622 unsigned int size_as_int
1623 = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type
));
1625 if (compare_tree_int (TYPE_SIZE_UNIT (ret_type
), size_as_int
) == 0)
1626 warning (OPT_Wlarger_than_
, "size of return value of %q+D is %u bytes",
1629 warning (OPT_Wlarger_than_
, "size of return value of %q+D is larger than %wd bytes",
1630 decl
, larger_than_size
);
1634 gimple_set_body (decl
, NULL
);
1635 if (DECL_STRUCT_FUNCTION (decl
) == 0
1636 && !cgraph_get_node (decl
)->origin
)
1638 /* Stop pointing to the local nodes about to be freed.
1639 But DECL_INITIAL must remain nonzero so we know this
1640 was an actual function definition.
1641 For a nested function, this is done in c_pop_function_context.
1642 If rest_of_compilation set this to 0, leave it 0. */
1643 if (DECL_INITIAL (decl
) != 0)
1644 DECL_INITIAL (decl
) = error_mark_node
;
1647 input_location
= saved_loc
;
1650 timevar_pop (TV_REST_OF_COMPILATION
);
1652 /* Make sure that BE didn't give up on compiling. */
1653 gcc_assert (TREE_ASM_WRITTEN (decl
));
1654 current_function_decl
= NULL
;
1656 /* It would make a lot more sense to output thunks before function body to get more
1657 forward and lest backwarding jumps. This however would need solving problem
1658 with comdats. See PR48668. Also aliases must come after function itself to
1659 make one pass assemblers, like one on AIX, happy. See PR 50689.
1660 FIXME: Perhaps thunks should be move before function IFF they are not in comdat
1662 assemble_thunks_and_aliases (node
);
1663 cgraph_release_function_body (node
);
1664 /* Eliminate all call edges. This is important so the GIMPLE_CALL no longer
1665 points to the dead function body. */
1666 cgraph_node_remove_callees (node
);
1670 /* Expand all functions that must be output.
1672 Attempt to topologically sort the nodes so function is output when
1673 all called functions are already assembled to allow data to be
1674 propagated across the callgraph. Use a stack to get smaller distance
1675 between a function and its callees (later we may choose to use a more
1676 sophisticated algorithm for function reordering; we will likely want
1677 to use subsections to make the output functions appear in top-down
1681 expand_all_functions (void)
1683 struct cgraph_node
*node
;
1684 struct cgraph_node
**order
= XCNEWVEC (struct cgraph_node
*, cgraph_n_nodes
);
1685 int order_pos
, new_order_pos
= 0;
1688 order_pos
= ipa_reverse_postorder (order
);
1689 gcc_assert (order_pos
== cgraph_n_nodes
);
1691 /* Garbage collector may remove inline clones we eliminate during
1692 optimization. So we must be sure to not reference them. */
1693 for (i
= 0; i
< order_pos
; i
++)
1694 if (order
[i
]->process
)
1695 order
[new_order_pos
++] = order
[i
];
1697 for (i
= new_order_pos
- 1; i
>= 0; i
--)
1703 expand_function (node
);
1706 cgraph_process_new_functions ();
1712 /* This is used to sort the node types by the cgraph order number. */
1714 enum cgraph_order_sort_kind
1716 ORDER_UNDEFINED
= 0,
1722 struct cgraph_order_sort
1724 enum cgraph_order_sort_kind kind
;
1727 struct cgraph_node
*f
;
1728 struct varpool_node
*v
;
1733 /* Output all functions, variables, and asm statements in the order
1734 according to their order fields, which is the order in which they
1735 appeared in the file. This implements -fno-toplevel-reorder. In
1736 this mode we may output functions and variables which don't really
1737 need to be output. */
1740 output_in_order (void)
1743 struct cgraph_order_sort
*nodes
;
1745 struct cgraph_node
*pf
;
1746 struct varpool_node
*pv
;
1747 struct asm_node
*pa
;
1750 nodes
= XCNEWVEC (struct cgraph_order_sort
, max
);
1752 FOR_EACH_DEFINED_FUNCTION (pf
)
1754 if (pf
->process
&& !pf
->thunk
.thunk_p
&& !pf
->alias
)
1756 i
= pf
->symbol
.order
;
1757 gcc_assert (nodes
[i
].kind
== ORDER_UNDEFINED
);
1758 nodes
[i
].kind
= ORDER_FUNCTION
;
1763 FOR_EACH_DEFINED_VARIABLE (pv
)
1765 i
= pv
->symbol
.order
;
1766 gcc_assert (nodes
[i
].kind
== ORDER_UNDEFINED
);
1767 nodes
[i
].kind
= ORDER_VAR
;
1771 for (pa
= asm_nodes
; pa
; pa
= pa
->next
)
1774 gcc_assert (nodes
[i
].kind
== ORDER_UNDEFINED
);
1775 nodes
[i
].kind
= ORDER_ASM
;
1779 /* In toplevel reorder mode we output all statics; mark them as needed. */
1781 for (i
= 0; i
< max
; ++i
)
1782 if (nodes
[i
].kind
== ORDER_VAR
)
1783 varpool_finalize_named_section_flags (nodes
[i
].u
.v
);
1785 for (i
= 0; i
< max
; ++i
)
1787 switch (nodes
[i
].kind
)
1789 case ORDER_FUNCTION
:
1790 nodes
[i
].u
.f
->process
= 0;
1791 expand_function (nodes
[i
].u
.f
);
1795 varpool_assemble_decl (nodes
[i
].u
.v
);
1799 assemble_asm (nodes
[i
].u
.a
->asm_str
);
1802 case ORDER_UNDEFINED
:
1818 current_function_decl
= NULL
;
1819 gimple_register_cfg_hooks ();
1820 bitmap_obstack_initialize (NULL
);
1822 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START
, NULL
);
1826 execute_ipa_pass_list (all_small_ipa_passes
);
1831 /* We never run removal of unreachable nodes after early passes. This is
1832 because TODO is run before the subpasses. It is important to remove
1833 the unreachable functions to save works at IPA level and to get LTO
1834 symbol tables right. */
1835 cgraph_remove_unreachable_nodes (true, cgraph_dump_file
);
1837 /* If pass_all_early_optimizations was not scheduled, the state of
1838 the cgraph will not be properly updated. Update it now. */
1839 if (cgraph_state
< CGRAPH_STATE_IPA_SSA
)
1840 cgraph_state
= CGRAPH_STATE_IPA_SSA
;
1844 /* Generate coverage variables and constructors. */
1847 /* Process new functions added. */
1849 current_function_decl
= NULL
;
1850 cgraph_process_new_functions ();
1852 execute_ipa_summary_passes
1853 ((struct ipa_opt_pass_d
*) all_regular_ipa_passes
);
1856 /* Some targets need to handle LTO assembler output specially. */
1857 if (flag_generate_lto
)
1858 targetm
.asm_out
.lto_start ();
1860 execute_ipa_summary_passes ((struct ipa_opt_pass_d
*) all_lto_gen_passes
);
1863 ipa_write_summaries ();
1865 if (flag_generate_lto
)
1866 targetm
.asm_out
.lto_end ();
1868 if (!flag_ltrans
&& (in_lto_p
|| !flag_lto
|| flag_fat_lto_objects
))
1869 execute_ipa_pass_list (all_regular_ipa_passes
);
1870 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END
, NULL
);
1872 bitmap_obstack_release (NULL
);
1876 /* Return string alias is alias of. */
1879 get_alias_symbol (tree decl
)
1881 tree alias
= lookup_attribute ("alias", DECL_ATTRIBUTES (decl
));
1882 return get_identifier (TREE_STRING_POINTER
1883 (TREE_VALUE (TREE_VALUE (alias
))));
1887 /* Weakrefs may be associated to external decls and thus not output
1888 at expansion time. Emit all neccesary aliases. */
1891 output_weakrefs (void)
1893 struct cgraph_node
*node
;
1894 struct varpool_node
*vnode
;
1895 FOR_EACH_FUNCTION (node
)
1896 if (node
->alias
&& DECL_EXTERNAL (node
->symbol
.decl
)
1897 && !TREE_ASM_WRITTEN (node
->symbol
.decl
)
1898 && lookup_attribute ("weakref", DECL_ATTRIBUTES (node
->symbol
.decl
)))
1899 assemble_alias (node
->symbol
.decl
,
1900 node
->thunk
.alias
? DECL_ASSEMBLER_NAME (node
->thunk
.alias
)
1901 : get_alias_symbol (node
->symbol
.decl
));
1902 FOR_EACH_VARIABLE (vnode
)
1903 if (vnode
->alias
&& DECL_EXTERNAL (vnode
->symbol
.decl
)
1904 && !TREE_ASM_WRITTEN (vnode
->symbol
.decl
)
1905 && lookup_attribute ("weakref", DECL_ATTRIBUTES (vnode
->symbol
.decl
)))
1906 assemble_alias (vnode
->symbol
.decl
,
1907 vnode
->alias_of
? DECL_ASSEMBLER_NAME (vnode
->alias_of
)
1908 : get_alias_symbol (vnode
->symbol
.decl
));
1911 /* Initialize callgraph dump file. */
1916 if (!cgraph_dump_file
)
1917 cgraph_dump_file
= dump_begin (TDI_cgraph
, NULL
);
1920 /* The edges representing the callers of the NEW_VERSION node were
1921 fixed by cgraph_function_versioning (), now the call_expr in their
1922 respective tree code should be updated to call the NEW_VERSION. */
1925 update_call_expr (struct cgraph_node
*new_version
)
1927 struct cgraph_edge
*e
;
1929 gcc_assert (new_version
);
1931 /* Update the call expr on the edges to call the new version. */
1932 for (e
= new_version
->callers
; e
; e
= e
->next_caller
)
1934 struct function
*inner_function
= DECL_STRUCT_FUNCTION (e
->caller
->symbol
.decl
);
1935 gimple_call_set_fndecl (e
->call_stmt
, new_version
->symbol
.decl
);
1936 maybe_clean_eh_stmt_fn (inner_function
, e
->call_stmt
);
1941 /* Create a new cgraph node which is the new version of
1942 OLD_VERSION node. REDIRECT_CALLERS holds the callers
1943 edges which should be redirected to point to
1944 NEW_VERSION. ALL the callees edges of OLD_VERSION
1945 are cloned to the new version node. Return the new
1948 If non-NULL BLOCK_TO_COPY determine what basic blocks
1949 was copied to prevent duplications of calls that are dead
1952 struct cgraph_node
*
1953 cgraph_copy_node_for_versioning (struct cgraph_node
*old_version
,
1955 VEC(cgraph_edge_p
,heap
) *redirect_callers
,
1958 struct cgraph_node
*new_version
;
1959 struct cgraph_edge
*e
;
1962 gcc_assert (old_version
);
1964 new_version
= cgraph_create_node (new_decl
);
1966 new_version
->analyzed
= old_version
->analyzed
;
1967 new_version
->local
= old_version
->local
;
1968 new_version
->symbol
.externally_visible
= false;
1969 new_version
->local
.local
= old_version
->analyzed
;
1970 new_version
->global
= old_version
->global
;
1971 new_version
->rtl
= old_version
->rtl
;
1972 new_version
->count
= old_version
->count
;
1974 for (e
= old_version
->callees
; e
; e
=e
->next_callee
)
1976 || bitmap_bit_p (bbs_to_copy
, gimple_bb (e
->call_stmt
)->index
))
1977 cgraph_clone_edge (e
, new_version
, e
->call_stmt
,
1978 e
->lto_stmt_uid
, REG_BR_PROB_BASE
,
1981 for (e
= old_version
->indirect_calls
; e
; e
=e
->next_callee
)
1983 || bitmap_bit_p (bbs_to_copy
, gimple_bb (e
->call_stmt
)->index
))
1984 cgraph_clone_edge (e
, new_version
, e
->call_stmt
,
1985 e
->lto_stmt_uid
, REG_BR_PROB_BASE
,
1988 FOR_EACH_VEC_ELT (cgraph_edge_p
, redirect_callers
, i
, e
)
1990 /* Redirect calls to the old version node to point to its new
1992 cgraph_redirect_edge_callee (e
, new_version
);
1995 cgraph_call_node_duplication_hooks (old_version
, new_version
);
2000 /* Perform function versioning.
2001 Function versioning includes copying of the tree and
2002 a callgraph update (creating a new cgraph node and updating
2003 its callees and callers).
2005 REDIRECT_CALLERS varray includes the edges to be redirected
2008 TREE_MAP is a mapping of tree nodes we want to replace with
2009 new ones (according to results of prior analysis).
2010 OLD_VERSION_NODE is the node that is versioned.
2012 If non-NULL ARGS_TO_SKIP determine function parameters to remove
2014 If SKIP_RETURN is true, the new version will return void.
2015 If non-NULL BLOCK_TO_COPY determine what basic blocks to copy.
2016 If non_NULL NEW_ENTRY determine new entry BB of the clone.
2018 Return the new version's cgraph node. */
2020 struct cgraph_node
*
2021 cgraph_function_versioning (struct cgraph_node
*old_version_node
,
2022 VEC(cgraph_edge_p
,heap
) *redirect_callers
,
2023 VEC (ipa_replace_map_p
,gc
)* tree_map
,
2024 bitmap args_to_skip
,
2027 basic_block new_entry_block
,
2028 const char *clone_name
)
2030 tree old_decl
= old_version_node
->symbol
.decl
;
2031 struct cgraph_node
*new_version_node
= NULL
;
2034 if (!tree_versionable_function_p (old_decl
))
2037 gcc_assert (old_version_node
->local
.can_change_signature
|| !args_to_skip
);
2039 /* Make a new FUNCTION_DECL tree node for the new version. */
2040 if (!args_to_skip
&& !skip_return
)
2041 new_decl
= copy_node (old_decl
);
2044 = build_function_decl_skip_args (old_decl
, args_to_skip
, skip_return
);
2046 /* Generate a new name for the new version. */
2047 DECL_NAME (new_decl
) = clone_function_name (old_decl
, clone_name
);
2048 SET_DECL_ASSEMBLER_NAME (new_decl
, DECL_NAME (new_decl
));
2049 SET_DECL_RTL (new_decl
, NULL
);
2051 /* When the old decl was a con-/destructor make sure the clone isn't. */
2052 DECL_STATIC_CONSTRUCTOR(new_decl
) = 0;
2053 DECL_STATIC_DESTRUCTOR(new_decl
) = 0;
2055 /* Create the new version's call-graph node.
2056 and update the edges of the new node. */
2058 cgraph_copy_node_for_versioning (old_version_node
, new_decl
,
2059 redirect_callers
, bbs_to_copy
);
2061 /* Copy the OLD_VERSION_NODE function tree to the new version. */
2062 tree_function_versioning (old_decl
, new_decl
, tree_map
, false, args_to_skip
,
2063 skip_return
, bbs_to_copy
, new_entry_block
);
2065 /* Update the new version's properties.
2066 Make The new version visible only within this translation unit. Make sure
2067 that is not weak also.
2068 ??? We cannot use COMDAT linkage because there is no
2069 ABI support for this. */
2070 symtab_make_decl_local (new_version_node
->symbol
.decl
);
2071 DECL_VIRTUAL_P (new_version_node
->symbol
.decl
) = 0;
2072 new_version_node
->symbol
.externally_visible
= 0;
2073 new_version_node
->local
.local
= 1;
2074 new_version_node
->lowered
= true;
2076 /* Update the call_expr on the edges to call the new version node. */
2077 update_call_expr (new_version_node
);
2079 cgraph_call_function_insertion_hooks (new_version_node
);
2080 return new_version_node
;
2083 /* Given virtual clone, turn it into actual clone. */
2085 cgraph_materialize_clone (struct cgraph_node
*node
)
2087 bitmap_obstack_initialize (NULL
);
2088 node
->former_clone_of
= node
->clone_of
->symbol
.decl
;
2089 if (node
->clone_of
->former_clone_of
)
2090 node
->former_clone_of
= node
->clone_of
->former_clone_of
;
2091 /* Copy the OLD_VERSION_NODE function tree to the new version. */
2092 tree_function_versioning (node
->clone_of
->symbol
.decl
, node
->symbol
.decl
,
2093 node
->clone
.tree_map
, true,
2094 node
->clone
.args_to_skip
, false,
2096 if (cgraph_dump_file
)
2098 dump_function_to_file (node
->clone_of
->symbol
.decl
, cgraph_dump_file
, dump_flags
);
2099 dump_function_to_file (node
->symbol
.decl
, cgraph_dump_file
, dump_flags
);
2102 /* Function is no longer clone. */
2103 if (node
->next_sibling_clone
)
2104 node
->next_sibling_clone
->prev_sibling_clone
= node
->prev_sibling_clone
;
2105 if (node
->prev_sibling_clone
)
2106 node
->prev_sibling_clone
->next_sibling_clone
= node
->next_sibling_clone
;
2108 node
->clone_of
->clones
= node
->next_sibling_clone
;
2109 node
->next_sibling_clone
= NULL
;
2110 node
->prev_sibling_clone
= NULL
;
2111 if (!node
->clone_of
->analyzed
&& !node
->clone_of
->clones
)
2113 cgraph_release_function_body (node
->clone_of
);
2114 cgraph_node_remove_callees (node
->clone_of
);
2115 ipa_remove_all_references (&node
->clone_of
->symbol
.ref_list
);
2117 node
->clone_of
= NULL
;
2118 bitmap_obstack_release (NULL
);
2121 /* If necessary, change the function declaration in the call statement
2122 associated with E so that it corresponds to the edge callee. */
2125 cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge
*e
)
2127 tree decl
= gimple_call_fndecl (e
->call_stmt
);
2129 gimple_stmt_iterator gsi
;
2130 #ifdef ENABLE_CHECKING
2131 struct cgraph_node
*node
;
2134 if (e
->indirect_unknown_callee
2135 || decl
== e
->callee
->symbol
.decl
)
2136 return e
->call_stmt
;
2138 #ifdef ENABLE_CHECKING
2141 node
= cgraph_get_node (decl
);
2142 gcc_assert (!node
|| !node
->clone
.combined_args_to_skip
);
2146 if (cgraph_dump_file
)
2148 fprintf (cgraph_dump_file
, "updating call of %s/%i -> %s/%i: ",
2149 xstrdup (cgraph_node_name (e
->caller
)), e
->caller
->uid
,
2150 xstrdup (cgraph_node_name (e
->callee
)), e
->callee
->uid
);
2151 print_gimple_stmt (cgraph_dump_file
, e
->call_stmt
, 0, dump_flags
);
2152 if (e
->callee
->clone
.combined_args_to_skip
)
2154 fprintf (cgraph_dump_file
, " combined args to skip: ");
2155 dump_bitmap (cgraph_dump_file
,
2156 e
->callee
->clone
.combined_args_to_skip
);
2160 if (e
->callee
->clone
.combined_args_to_skip
)
2165 = gimple_call_copy_skip_args (e
->call_stmt
,
2166 e
->callee
->clone
.combined_args_to_skip
);
2167 gimple_call_set_fndecl (new_stmt
, e
->callee
->symbol
.decl
);
2169 if (gimple_vdef (new_stmt
)
2170 && TREE_CODE (gimple_vdef (new_stmt
)) == SSA_NAME
)
2171 SSA_NAME_DEF_STMT (gimple_vdef (new_stmt
)) = new_stmt
;
2173 gsi
= gsi_for_stmt (e
->call_stmt
);
2174 gsi_replace (&gsi
, new_stmt
, false);
2175 /* We need to defer cleaning EH info on the new statement to
2176 fixup-cfg. We may not have dominator information at this point
2177 and thus would end up with unreachable blocks and have no way
2178 to communicate that we need to run CFG cleanup then. */
2179 lp_nr
= lookup_stmt_eh_lp (e
->call_stmt
);
2182 remove_stmt_from_eh_lp (e
->call_stmt
);
2183 add_stmt_to_eh_lp (new_stmt
, lp_nr
);
2188 new_stmt
= e
->call_stmt
;
2189 gimple_call_set_fndecl (new_stmt
, e
->callee
->symbol
.decl
);
2190 update_stmt (new_stmt
);
2193 cgraph_set_call_stmt_including_clones (e
->caller
, e
->call_stmt
, new_stmt
);
2195 if (cgraph_dump_file
)
2197 fprintf (cgraph_dump_file
, " updated to:");
2198 print_gimple_stmt (cgraph_dump_file
, e
->call_stmt
, 0, dump_flags
);
2203 /* Once all functions from compilation unit are in memory, produce all clones
2204 and update all calls. We might also do this on demand if we don't want to
2205 bring all functions to memory prior compilation, but current WHOPR
2206 implementation does that and it is is bit easier to keep everything right in
2209 cgraph_materialize_all_clones (void)
2211 struct cgraph_node
*node
;
2212 bool stabilized
= false;
2214 if (cgraph_dump_file
)
2215 fprintf (cgraph_dump_file
, "Materializing clones\n");
2216 #ifdef ENABLE_CHECKING
2220 /* We can also do topological order, but number of iterations should be
2221 bounded by number of IPA passes since single IPA pass is probably not
2222 going to create clones of clones it created itself. */
2226 FOR_EACH_FUNCTION (node
)
2228 if (node
->clone_of
&& node
->symbol
.decl
!= node
->clone_of
->symbol
.decl
2229 && !gimple_has_body_p (node
->symbol
.decl
))
2231 if (gimple_has_body_p (node
->clone_of
->symbol
.decl
))
2233 if (cgraph_dump_file
)
2235 fprintf (cgraph_dump_file
, "cloning %s to %s\n",
2236 xstrdup (cgraph_node_name (node
->clone_of
)),
2237 xstrdup (cgraph_node_name (node
)));
2238 if (node
->clone
.tree_map
)
2241 fprintf (cgraph_dump_file
, " replace map: ");
2242 for (i
= 0; i
< VEC_length (ipa_replace_map_p
,
2243 node
->clone
.tree_map
);
2246 struct ipa_replace_map
*replace_info
;
2247 replace_info
= VEC_index (ipa_replace_map_p
,
2248 node
->clone
.tree_map
,
2250 print_generic_expr (cgraph_dump_file
, replace_info
->old_tree
, 0);
2251 fprintf (cgraph_dump_file
, " -> ");
2252 print_generic_expr (cgraph_dump_file
, replace_info
->new_tree
, 0);
2253 fprintf (cgraph_dump_file
, "%s%s;",
2254 replace_info
->replace_p
? "(replace)":"",
2255 replace_info
->ref_p
? "(ref)":"");
2257 fprintf (cgraph_dump_file
, "\n");
2259 if (node
->clone
.args_to_skip
)
2261 fprintf (cgraph_dump_file
, " args_to_skip: ");
2262 dump_bitmap (cgraph_dump_file
, node
->clone
.args_to_skip
);
2264 if (node
->clone
.args_to_skip
)
2266 fprintf (cgraph_dump_file
, " combined_args_to_skip:");
2267 dump_bitmap (cgraph_dump_file
, node
->clone
.combined_args_to_skip
);
2270 cgraph_materialize_clone (node
);
2276 FOR_EACH_FUNCTION (node
)
2277 if (!node
->analyzed
&& node
->callees
)
2278 cgraph_node_remove_callees (node
);
2279 if (cgraph_dump_file
)
2280 fprintf (cgraph_dump_file
, "Materialization Call site updates done.\n");
2281 #ifdef ENABLE_CHECKING
2284 cgraph_remove_unreachable_nodes (false, cgraph_dump_file
);
2288 /* Perform simple optimizations based on callgraph. */
2296 #ifdef ENABLE_CHECKING
2300 timevar_push (TV_CGRAPHOPT
);
2301 if (pre_ipa_mem_report
)
2303 fprintf (stderr
, "Memory consumption before IPA\n");
2304 dump_memory_report (false);
2307 fprintf (stderr
, "Performing interprocedural optimizations\n");
2308 cgraph_state
= CGRAPH_STATE_IPA
;
2310 /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE. */
2312 lto_streamer_hooks_init ();
2314 /* Don't run the IPA passes if there was any error or sorry messages. */
2318 /* Do nothing else if any IPA pass found errors or if we are just streaming LTO. */
2320 || (!in_lto_p
&& flag_lto
&& !flag_fat_lto_objects
))
2322 timevar_pop (TV_CGRAPHOPT
);
2326 /* This pass remove bodies of extern inline functions we never inlined.
2327 Do this later so other IPA passes see what is really going on. */
2328 cgraph_remove_unreachable_nodes (false, dump_file
);
2329 cgraph_global_info_ready
= true;
2330 if (cgraph_dump_file
)
2332 fprintf (cgraph_dump_file
, "Optimized ");
2333 dump_symtab (cgraph_dump_file
);
2335 if (post_ipa_mem_report
)
2337 fprintf (stderr
, "Memory consumption after IPA\n");
2338 dump_memory_report (false);
2340 timevar_pop (TV_CGRAPHOPT
);
2342 /* Output everything. */
2343 (*debug_hooks
->assembly_start
) ();
2345 fprintf (stderr
, "Assembling functions:\n");
2346 #ifdef ENABLE_CHECKING
2350 cgraph_materialize_all_clones ();
2351 bitmap_obstack_initialize (NULL
);
2352 execute_ipa_pass_list (all_late_ipa_passes
);
2353 cgraph_remove_unreachable_nodes (true, dump_file
);
2354 #ifdef ENABLE_CHECKING
2357 bitmap_obstack_release (NULL
);
2358 mark_functions_to_output ();
2361 cgraph_state
= CGRAPH_STATE_EXPANSION
;
2362 if (!flag_toplevel_reorder
)
2366 output_asm_statements ();
2368 expand_all_functions ();
2369 varpool_output_variables ();
2372 cgraph_process_new_functions ();
2373 cgraph_state
= CGRAPH_STATE_FINISHED
;
2375 if (cgraph_dump_file
)
2377 fprintf (cgraph_dump_file
, "\nFinal ");
2378 dump_symtab (cgraph_dump_file
);
2380 #ifdef ENABLE_CHECKING
2382 /* Double check that all inline clones are gone and that all
2383 function bodies have been released from memory. */
2386 struct cgraph_node
*node
;
2387 bool error_found
= false;
2389 FOR_EACH_DEFINED_FUNCTION (node
)
2390 if (node
->global
.inlined_to
2391 || gimple_has_body_p (node
->symbol
.decl
))
2394 dump_cgraph_node (stderr
, node
);
2397 internal_error ("nodes with unreleased memory found");
2403 /* Analyze the whole compilation unit once it is parsed completely. */
2406 finalize_compilation_unit (void)
2408 timevar_push (TV_CGRAPH
);
2410 /* If we're here there's no current function anymore. Some frontends
2411 are lazy in clearing these. */
2412 current_function_decl
= NULL
;
2415 /* Do not skip analyzing the functions if there were errors, we
2416 miss diagnostics for following functions otherwise. */
2418 /* Emit size functions we didn't inline. */
2419 finalize_size_functions ();
2421 /* Mark alias targets necessary and emit diagnostics. */
2422 finish_aliases_1 ();
2423 handle_alias_pairs ();
2427 fprintf (stderr
, "\nAnalyzing compilation unit\n");
2431 if (flag_dump_passes
)
2434 /* Gimplify and lower all functions, compute reachability and
2435 remove unreachable nodes. */
2436 cgraph_analyze_functions ();
2438 /* Mark alias targets necessary and emit diagnostics. */
2439 finish_aliases_1 ();
2440 handle_alias_pairs ();
2442 /* Gimplify and lower thunks. */
2443 cgraph_analyze_functions ();
2445 /* Finally drive the pass manager. */
2448 timevar_pop (TV_CGRAPH
);
2452 #include "gt-cgraphunit.h"