1 /* Callgraph based interprocedural optimizations.
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 as well as
23 few basic interprocedural optimizers.
25 The main scope of this file is to act as an interface in between
26 tree based frontends and the backend (and middle end)
28 The front-end is supposed to use following functionality:
30 - cgraph_finalize_function
32 This function is called once front-end has parsed whole body of function
33 and it is certain that the function body nor the declaration will change.
35 (There is one exception needed for implementing GCC extern inline
38 - varpool_finalize_variable
40 This function has same behavior as the above but is used for static
43 - cgraph_finalize_compilation_unit
45 This function is called once (source level) compilation unit is finalized
46 and it will no longer change.
48 In the call-graph construction and local function analysis takes
49 place here. Bodies of unreachable functions are released to
50 conserve memory usage.
52 The function can be called multiple times when multiple source level
53 compilation units are combined (such as in C frontend)
57 In this unit-at-a-time compilation the intra procedural analysis takes
58 place here. In particular the static functions whose address is never
59 taken are marked as local. Backend can then use this information to
60 modify calling conventions, do better inlining or similar optimizations.
62 - cgraph_mark_needed_node
63 - varpool_mark_needed_node
65 When function or variable is referenced by some hidden way the call-graph
66 data structure must be updated accordingly by this function.
67 There should be little need to call this function and all the references
68 should be made explicit to cgraph code. At present these functions are
69 used by C++ frontend to explicitly mark the keyed methods.
71 - analyze_expr callback
73 This function is responsible for lowering tree nodes not understood by
74 generic code into understandable ones or alternatively marking
75 callgraph and varpool nodes referenced by the as needed.
77 ??? On the tree-ssa genericizing should take place here and we will avoid
78 need for these hooks (replacing them by genericizing hook)
80 Analyzing of all functions is deferred
81 to cgraph_finalize_compilation_unit and expansion into cgraph_optimize.
83 In cgraph_finalize_compilation_unit the reachable functions are
84 analyzed. During analysis the call-graph edges from reachable
85 functions are constructed and their destinations are marked as
86 reachable. References to functions and variables are discovered too
87 and variables found to be needed output to the assembly file. Via
88 mark_referenced call in assemble_variable functions referenced by
89 static variables are noticed too.
91 The intra-procedural information is produced and its existence
92 indicated by global_info_ready. Once this flag is set it is impossible
93 to change function from !reachable to reachable and thus
94 assemble_variable no longer call mark_referenced.
96 Finally the call-graph is topologically sorted and all reachable functions
97 that has not been completely inlined or are not external are output.
99 ??? It is possible that reference to function or variable is optimized
100 out. We can not deal with this nicely because topological order is not
101 suitable for it. For tree-ssa we may consider another pass doing
102 optimization and re-discovering reachable functions.
104 ??? Reorganize code so variables are output very last and only if they
105 really has been referenced by produced code, so we catch more cases
106 where reference has been optimized out. */
111 #include "coretypes.h"
116 #include "tree-flow.h"
117 #include "tree-inline.h"
118 #include "langhooks.h"
119 #include "pointer-set.h"
126 #include "diagnostic.h"
127 #include "tree-pretty-print.h"
128 #include "gimple-pretty-print.h"
133 #include "function.h"
134 #include "ipa-prop.h"
136 #include "tree-iterator.h"
137 #include "tree-pass.h"
138 #include "tree-dump.h"
140 #include "coverage.h"
142 #include "ipa-inline.h"
143 #include "ipa-utils.h"
144 #include "lto-streamer.h"
146 #include "regset.h" /* FIXME: For reg_obstack. */
148 /* Queue of cgraph nodes scheduled to be added into cgraph. This is a
149 secondary queue used during optimization to accommodate passes that
150 may generate new functions that need to be optimized and expanded. */
151 cgraph_node_set cgraph_new_nodes
;
153 static void cgraph_expand_all_functions (void);
154 static void cgraph_mark_functions_to_output (void);
155 static void cgraph_expand_function (struct cgraph_node
*);
156 static void cgraph_output_pending_asms (void);
157 static void tree_rest_of_compilation (struct cgraph_node
*);
159 FILE *cgraph_dump_file
;
161 /* Used for vtable lookup in thunk adjusting. */
162 static GTY (()) tree vtable_entry_type
;
164 /* Determine if function DECL is trivially needed and should stay in the
165 compilation unit. This is used at the symbol table construction time
166 and differs from later logic removing unnecesary functions that can
167 take into account results of analysis, whole program info etc. */
170 cgraph_decide_is_function_needed (struct cgraph_node
*node
, tree decl
)
172 /* If the user told us it is used, then it must be so. */
173 if (node
->symbol
.force_output
)
176 /* Double check that no one output the function into assembly file
178 gcc_checking_assert (!DECL_ASSEMBLER_NAME_SET_P (decl
)
179 || (node
->thunk
.thunk_p
|| node
->same_body_alias
)
180 || !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl
)));
183 /* Keep constructors, destructors and virtual functions. */
184 if (DECL_STATIC_CONSTRUCTOR (decl
)
185 || DECL_STATIC_DESTRUCTOR (decl
)
186 || (DECL_VIRTUAL_P (decl
)
187 && optimize
&& (DECL_COMDAT (decl
) || DECL_EXTERNAL (decl
))))
190 /* Externally visible functions must be output. The exception is
191 COMDAT functions that must be output only when they are needed. */
193 if (TREE_PUBLIC (decl
)
194 && !DECL_COMDAT (decl
) && !DECL_EXTERNAL (decl
))
200 /* Head of the queue of nodes to be processed while building callgraph */
202 static symtab_node first
= (symtab_node
)(void *)1;
204 /* Add NODE to queue starting at FIRST.
205 The queue is linked via AUX pointers and terminated by pointer to 1. */
208 enqueue_node (symtab_node node
)
210 if (node
->symbol
.aux
)
212 gcc_checking_assert (first
);
213 node
->symbol
.aux
= first
;
217 /* Process CGRAPH_NEW_FUNCTIONS and perform actions necessary to add these
218 functions into callgraph in a way so they look like ordinary reachable
219 functions inserted into callgraph already at construction time. */
222 cgraph_process_new_functions (void)
226 struct cgraph_node
*node
;
227 cgraph_node_set_iterator csi
;
229 if (!cgraph_new_nodes
)
231 /* Note that this queue may grow as its being processed, as the new
232 functions may generate new ones. */
233 for (csi
= csi_start (cgraph_new_nodes
); !csi_end_p (csi
); csi_next (&csi
))
235 node
= csi_node (csi
);
236 fndecl
= node
->symbol
.decl
;
237 switch (cgraph_state
)
239 case CGRAPH_STATE_CONSTRUCTION
:
240 /* At construction time we just need to finalize function and move
241 it into reachable functions list. */
243 cgraph_finalize_function (fndecl
, false);
245 cgraph_call_function_insertion_hooks (node
);
246 enqueue_node ((symtab_node
) node
);
249 case CGRAPH_STATE_IPA
:
250 case CGRAPH_STATE_IPA_SSA
:
251 /* When IPA optimization already started, do all essential
252 transformations that has been already performed on the whole
253 cgraph but not on this function. */
255 gimple_register_cfg_hooks ();
257 cgraph_analyze_function (node
);
258 push_cfun (DECL_STRUCT_FUNCTION (fndecl
));
259 current_function_decl
= fndecl
;
260 if ((cgraph_state
== CGRAPH_STATE_IPA_SSA
261 && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl
)))
262 /* When not optimizing, be sure we run early local passes anyway
265 execute_pass_list (pass_early_local_passes
.pass
.sub
);
267 compute_inline_parameters (node
, true);
268 free_dominance_info (CDI_POST_DOMINATORS
);
269 free_dominance_info (CDI_DOMINATORS
);
271 current_function_decl
= NULL
;
272 cgraph_call_function_insertion_hooks (node
);
275 case CGRAPH_STATE_EXPANSION
:
276 /* Functions created during expansion shall be compiled
279 cgraph_call_function_insertion_hooks (node
);
280 cgraph_expand_function (node
);
288 free_cgraph_node_set (cgraph_new_nodes
);
289 cgraph_new_nodes
= NULL
;
293 /* As an GCC extension we allow redefinition of the function. The
294 semantics when both copies of bodies differ is not well defined.
295 We replace the old body with new body so in unit at a time mode
296 we always use new body, while in normal mode we may end up with
297 old body inlined into some functions and new body expanded and
300 ??? It may make more sense to use one body for inlining and other
301 body for expanding the function but this is difficult to do. */
304 cgraph_reset_node (struct cgraph_node
*node
)
306 /* If node->process is set, then we have already begun whole-unit analysis.
307 This is *not* testing for whether we've already emitted the function.
308 That case can be sort-of legitimately seen with real function redefinition
309 errors. I would argue that the front end should never present us with
310 such a case, but don't enforce that for now. */
311 gcc_assert (!node
->process
);
313 /* Reset our data structures so we can analyze the function again. */
314 memset (&node
->local
, 0, sizeof (node
->local
));
315 memset (&node
->global
, 0, sizeof (node
->global
));
316 memset (&node
->rtl
, 0, sizeof (node
->rtl
));
317 node
->analyzed
= false;
318 node
->local
.finalized
= false;
320 cgraph_node_remove_callees (node
);
323 /* DECL has been parsed. Take it, queue it, compile it at the whim of the
324 logic in effect. If NESTED is true, then our caller cannot stand to have
325 the garbage collector run at the moment. We would need to either create
326 a new GC context, or just not compile right now. */
329 cgraph_finalize_function (tree decl
, bool nested
)
331 struct cgraph_node
*node
= cgraph_get_create_node (decl
);
333 if (node
->local
.finalized
)
335 cgraph_reset_node (node
);
336 node
->local
.redefined_extern_inline
= true;
339 notice_global_symbol (decl
);
340 node
->local
.finalized
= true;
341 node
->lowered
= DECL_STRUCT_FUNCTION (decl
)->cfg
!= NULL
;
343 /* With -fkeep-inline-functions we are keeping all inline functions except
344 for extern inline ones. */
345 if (flag_keep_inline_functions
346 && DECL_DECLARED_INLINE_P (decl
)
347 && !DECL_EXTERNAL (decl
)
348 && !DECL_DISREGARD_INLINE_LIMITS (decl
))
349 node
->symbol
.force_output
= 1;
351 /* When not optimizing, also output the static functions. (see
352 PR24561), but don't do so for always_inline functions, functions
353 declared inline and nested functions. These were optimized out
354 in the original implementation and it is unclear whether we want
355 to change the behavior here. */
357 && !node
->same_body_alias
358 && !DECL_DISREGARD_INLINE_LIMITS (decl
)
359 && !DECL_DECLARED_INLINE_P (decl
)
360 && !(DECL_CONTEXT (decl
)
361 && TREE_CODE (DECL_CONTEXT (decl
)) == FUNCTION_DECL
))
362 && !DECL_COMDAT (decl
) && !DECL_EXTERNAL (decl
))
363 node
->symbol
.force_output
= 1;
365 if (cgraph_decide_is_function_needed (node
, decl
))
366 cgraph_mark_reachable_node (node
);
368 /* If we've not yet emitted decl, tell the debug info about it. */
369 if (!TREE_ASM_WRITTEN (decl
))
370 (*debug_hooks
->deferred_inline_function
) (decl
);
372 /* Possibly warn about unused parameters. */
373 if (warn_unused_parameter
)
374 do_warn_unused_parameter (decl
);
380 /* Add the function FNDECL to the call graph.
381 Unlike cgraph_finalize_function, this function is intended to be used
382 by middle end and allows insertion of new function at arbitrary point
383 of compilation. The function can be either in high, low or SSA form
386 The function is assumed to be reachable and have address taken (so no
387 API breaking optimizations are performed on it).
389 Main work done by this function is to enqueue the function for later
390 processing to avoid need the passes to be re-entrant. */
393 cgraph_add_new_function (tree fndecl
, bool lowered
)
395 struct cgraph_node
*node
;
396 switch (cgraph_state
)
398 case CGRAPH_STATE_PARSING
:
399 cgraph_finalize_function (fndecl
, false);
401 case CGRAPH_STATE_CONSTRUCTION
:
402 /* Just enqueue function to be processed at nearest occurrence. */
403 node
= cgraph_create_node (fndecl
);
405 node
->lowered
= true;
406 if (!cgraph_new_nodes
)
407 cgraph_new_nodes
= cgraph_node_set_new ();
408 cgraph_node_set_add (cgraph_new_nodes
, node
);
411 case CGRAPH_STATE_IPA
:
412 case CGRAPH_STATE_IPA_SSA
:
413 case CGRAPH_STATE_EXPANSION
:
414 /* Bring the function into finalized state and enqueue for later
415 analyzing and compilation. */
416 node
= cgraph_get_create_node (fndecl
);
417 node
->local
.local
= false;
418 node
->local
.finalized
= true;
419 node
->reachable
= node
->symbol
.force_output
= true;
420 if (!lowered
&& cgraph_state
== CGRAPH_STATE_EXPANSION
)
422 push_cfun (DECL_STRUCT_FUNCTION (fndecl
));
423 current_function_decl
= fndecl
;
424 gimple_register_cfg_hooks ();
425 bitmap_obstack_initialize (NULL
);
426 execute_pass_list (all_lowering_passes
);
427 execute_pass_list (pass_early_local_passes
.pass
.sub
);
428 bitmap_obstack_release (NULL
);
430 current_function_decl
= NULL
;
435 node
->lowered
= true;
436 if (!cgraph_new_nodes
)
437 cgraph_new_nodes
= cgraph_node_set_new ();
438 cgraph_node_set_add (cgraph_new_nodes
, node
);
441 case CGRAPH_STATE_FINISHED
:
442 /* At the very end of compilation we have to do all the work up
444 node
= cgraph_create_node (fndecl
);
446 node
->lowered
= true;
447 cgraph_analyze_function (node
);
448 push_cfun (DECL_STRUCT_FUNCTION (fndecl
));
449 current_function_decl
= fndecl
;
450 gimple_register_cfg_hooks ();
451 bitmap_obstack_initialize (NULL
);
452 if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl
)))
453 execute_pass_list (pass_early_local_passes
.pass
.sub
);
454 bitmap_obstack_release (NULL
);
455 tree_rest_of_compilation (node
);
457 current_function_decl
= NULL
;
464 /* Set a personality if required and we already passed EH lowering. */
466 && (function_needs_eh_personality (DECL_STRUCT_FUNCTION (fndecl
))
467 == eh_personality_lang
))
468 DECL_FUNCTION_PERSONALITY (fndecl
) = lang_hooks
.eh_personality ();
471 /* C99 extern inline keywords allow changing of declaration after function
472 has been finalized. We need to re-decide if we want to mark the function as
476 cgraph_mark_if_needed (tree decl
)
478 struct cgraph_node
*node
= cgraph_get_node (decl
);
479 if (node
->local
.finalized
&& cgraph_decide_is_function_needed (node
, decl
))
480 cgraph_mark_reachable_node (node
);
483 /* Return TRUE if NODE2 is equivalent to NODE or its clone. */
485 clone_of_p (struct cgraph_node
*node
, struct cgraph_node
*node2
)
487 node
= cgraph_function_or_thunk_node (node
, NULL
);
488 node2
= cgraph_function_or_thunk_node (node2
, NULL
);
489 while (node
!= node2
&& node2
)
490 node2
= node2
->clone_of
;
491 return node2
!= NULL
;
494 /* Verify edge E count and frequency. */
497 verify_edge_count_and_frequency (struct cgraph_edge
*e
)
499 bool error_found
= false;
502 error ("caller edge count is negative");
505 if (e
->frequency
< 0)
507 error ("caller edge frequency is negative");
510 if (e
->frequency
> CGRAPH_FREQ_MAX
)
512 error ("caller edge frequency is too large");
515 if (gimple_has_body_p (e
->caller
->symbol
.decl
)
516 && !e
->caller
->global
.inlined_to
517 /* FIXME: Inline-analysis sets frequency to 0 when edge is optimized out.
518 Remove this once edges are actualy removed from the function at that time. */
520 || (inline_edge_summary_vec
521 && ((VEC_length(inline_edge_summary_t
, inline_edge_summary_vec
)
522 <= (unsigned) e
->uid
)
523 || !inline_edge_summary (e
)->predicate
)))
525 != compute_call_stmt_bb_frequency (e
->caller
->symbol
.decl
,
526 gimple_bb (e
->call_stmt
))))
528 error ("caller edge frequency %i does not match BB frequency %i",
530 compute_call_stmt_bb_frequency (e
->caller
->symbol
.decl
,
531 gimple_bb (e
->call_stmt
)));
537 /* Switch to THIS_CFUN if needed and print STMT to stderr. */
539 cgraph_debug_gimple_stmt (struct function
*this_cfun
, gimple stmt
)
541 /* debug_gimple_stmt needs correct cfun */
542 if (cfun
!= this_cfun
)
543 set_cfun (this_cfun
);
544 debug_gimple_stmt (stmt
);
547 /* Verify that call graph edge E corresponds to DECL from the associated
548 statement. Return true if the verification should fail. */
551 verify_edge_corresponds_to_fndecl (struct cgraph_edge
*e
, tree decl
)
553 struct cgraph_node
*node
;
555 if (!decl
|| e
->callee
->global
.inlined_to
)
557 node
= cgraph_get_node (decl
);
559 /* We do not know if a node from a different partition is an alias or what it
560 aliases and therefore cannot do the former_clone_of check reliably. */
561 if (!node
|| node
->symbol
.in_other_partition
)
563 node
= cgraph_function_or_thunk_node (node
, NULL
);
565 if ((e
->callee
->former_clone_of
!= node
->symbol
.decl
566 && (!node
->same_body_alias
567 || e
->callee
->former_clone_of
!= node
->thunk
.alias
))
568 /* IPA-CP sometimes redirect edge to clone and then back to the former
569 function. This ping-pong has to go, eventually. */
570 && (node
!= cgraph_function_or_thunk_node (e
->callee
, NULL
))
571 && !clone_of_p (node
, e
->callee
)
572 /* If decl is a same body alias of some other decl, allow e->callee to be
573 a clone of a clone of that other decl too. */
574 && (!node
->same_body_alias
575 || !clone_of_p (cgraph_get_node (node
->thunk
.alias
), e
->callee
)))
581 /* Verify cgraph nodes of given cgraph node. */
583 verify_cgraph_node (struct cgraph_node
*node
)
585 struct cgraph_edge
*e
;
586 struct function
*this_cfun
= DECL_STRUCT_FUNCTION (node
->symbol
.decl
);
587 basic_block this_block
;
588 gimple_stmt_iterator gsi
;
589 bool error_found
= false;
594 timevar_push (TV_CGRAPH_VERIFY
);
595 error_found
|= verify_symtab_base ((symtab_node
) node
);
596 for (e
= node
->callees
; e
; e
= e
->next_callee
)
599 error ("aux field set for edge %s->%s",
600 identifier_to_locale (cgraph_node_name (e
->caller
)),
601 identifier_to_locale (cgraph_node_name (e
->callee
)));
606 error ("execution count is negative");
609 if (node
->global
.inlined_to
&& node
->symbol
.externally_visible
)
611 error ("externally visible inline clone");
614 if (node
->global
.inlined_to
&& node
->symbol
.address_taken
)
616 error ("inline clone with address taken");
619 if (node
->global
.inlined_to
&& node
->symbol
.force_output
)
621 error ("inline clone is forced to output");
624 for (e
= node
->indirect_calls
; e
; e
= e
->next_callee
)
628 error ("aux field set for indirect edge from %s",
629 identifier_to_locale (cgraph_node_name (e
->caller
)));
632 if (!e
->indirect_unknown_callee
633 || !e
->indirect_info
)
635 error ("An indirect edge from %s is not marked as indirect or has "
636 "associated indirect_info, the corresponding statement is: ",
637 identifier_to_locale (cgraph_node_name (e
->caller
)));
638 cgraph_debug_gimple_stmt (this_cfun
, e
->call_stmt
);
642 for (e
= node
->callers
; e
; e
= e
->next_caller
)
644 if (verify_edge_count_and_frequency (e
))
646 if (!e
->inline_failed
)
648 if (node
->global
.inlined_to
649 != (e
->caller
->global
.inlined_to
650 ? e
->caller
->global
.inlined_to
: e
->caller
))
652 error ("inlined_to pointer is wrong");
655 if (node
->callers
->next_caller
)
657 error ("multiple inline callers");
662 if (node
->global
.inlined_to
)
664 error ("inlined_to pointer set for noninline callers");
668 for (e
= node
->indirect_calls
; e
; e
= e
->next_callee
)
669 if (verify_edge_count_and_frequency (e
))
671 if (!node
->callers
&& node
->global
.inlined_to
)
673 error ("inlined_to pointer is set but no predecessors found");
676 if (node
->global
.inlined_to
== node
)
678 error ("inlined_to pointer refers to itself");
684 struct cgraph_node
*n
;
685 for (n
= node
->clone_of
->clones
; n
; n
= n
->next_sibling_clone
)
690 error ("node has wrong clone_of");
696 struct cgraph_node
*n
;
697 for (n
= node
->clones
; n
; n
= n
->next_sibling_clone
)
698 if (n
->clone_of
!= node
)
702 error ("node has wrong clone list");
706 if ((node
->prev_sibling_clone
|| node
->next_sibling_clone
) && !node
->clone_of
)
708 error ("node is in clone list but it is not clone");
711 if (!node
->prev_sibling_clone
&& node
->clone_of
&& node
->clone_of
->clones
!= node
)
713 error ("node has wrong prev_clone pointer");
716 if (node
->prev_sibling_clone
&& node
->prev_sibling_clone
->next_sibling_clone
!= node
)
718 error ("double linked list of clones corrupted");
722 if (node
->analyzed
&& node
->alias
)
724 bool ref_found
= false;
730 error ("Alias has call edges");
733 for (i
= 0; ipa_ref_list_reference_iterate (&node
->symbol
.ref_list
,
735 if (ref
->use
!= IPA_REF_ALIAS
)
737 error ("Alias has non-alias reference");
742 error ("Alias has more than one alias reference");
749 error ("Analyzed alias has no reference");
753 if (node
->analyzed
&& node
->thunk
.thunk_p
)
757 error ("No edge out of thunk node");
760 else if (node
->callees
->next_callee
)
762 error ("More than one edge out of thunk node");
765 if (gimple_has_body_p (node
->symbol
.decl
))
767 error ("Thunk is not supposed to have body");
771 else if (node
->analyzed
&& gimple_has_body_p (node
->symbol
.decl
)
772 && !TREE_ASM_WRITTEN (node
->symbol
.decl
)
773 && (!DECL_EXTERNAL (node
->symbol
.decl
) || node
->global
.inlined_to
)
778 /* The nodes we're interested in are never shared, so walk
779 the tree ignoring duplicates. */
780 struct pointer_set_t
*visited_nodes
= pointer_set_create ();
781 /* Reach the trees by walking over the CFG, and note the
782 enclosing basic-blocks in the call edges. */
783 FOR_EACH_BB_FN (this_block
, this_cfun
)
784 for (gsi
= gsi_start_bb (this_block
);
788 gimple stmt
= gsi_stmt (gsi
);
789 if (is_gimple_call (stmt
))
791 struct cgraph_edge
*e
= cgraph_edge (node
, stmt
);
792 tree decl
= gimple_call_fndecl (stmt
);
797 error ("shared call_stmt:");
798 cgraph_debug_gimple_stmt (this_cfun
, stmt
);
801 if (!e
->indirect_unknown_callee
)
803 if (verify_edge_corresponds_to_fndecl (e
, decl
))
805 error ("edge points to wrong declaration:");
806 debug_tree (e
->callee
->symbol
.decl
);
807 fprintf (stderr
," Instead of:");
814 error ("an indirect edge with unknown callee "
815 "corresponding to a call_stmt with "
816 "a known declaration:");
818 cgraph_debug_gimple_stmt (this_cfun
, e
->call_stmt
);
824 error ("missing callgraph edge for call stmt:");
825 cgraph_debug_gimple_stmt (this_cfun
, stmt
);
830 pointer_set_destroy (visited_nodes
);
833 /* No CFG available?! */
836 for (e
= node
->callees
; e
; e
= e
->next_callee
)
840 error ("edge %s->%s has no corresponding call_stmt",
841 identifier_to_locale (cgraph_node_name (e
->caller
)),
842 identifier_to_locale (cgraph_node_name (e
->callee
)));
843 cgraph_debug_gimple_stmt (this_cfun
, e
->call_stmt
);
848 for (e
= node
->indirect_calls
; e
; e
= e
->next_callee
)
852 error ("an indirect edge from %s has no corresponding call_stmt",
853 identifier_to_locale (cgraph_node_name (e
->caller
)));
854 cgraph_debug_gimple_stmt (this_cfun
, e
->call_stmt
);
862 dump_cgraph_node (stderr
, node
);
863 internal_error ("verify_cgraph_node failed");
865 timevar_pop (TV_CGRAPH_VERIFY
);
868 /* Verify whole cgraph structure. */
872 struct cgraph_node
*node
;
877 FOR_EACH_FUNCTION (node
)
878 verify_cgraph_node (node
);
881 /* Output all asm statements we have stored up to be output. */
884 cgraph_output_pending_asms (void)
886 struct cgraph_asm_node
*can
;
891 for (can
= cgraph_asm_nodes
; can
; can
= can
->next
)
892 assemble_asm (can
->asm_str
);
893 cgraph_asm_nodes
= NULL
;
896 /* Analyze the function scheduled to be output. */
898 cgraph_analyze_function (struct cgraph_node
*node
)
900 tree save
= current_function_decl
;
901 tree decl
= node
->symbol
.decl
;
903 if (node
->alias
&& node
->thunk
.alias
)
905 struct cgraph_node
*tgt
= cgraph_get_node (node
->thunk
.alias
);
906 struct cgraph_node
*n
;
908 for (n
= tgt
; n
&& n
->alias
;
909 n
= n
->analyzed
? cgraph_alias_aliased_node (n
) : NULL
)
912 error ("function %q+D part of alias cycle", node
->symbol
.decl
);
916 if (!VEC_length (ipa_ref_t
, node
->symbol
.ref_list
.references
))
917 ipa_record_reference ((symtab_node
)node
, (symtab_node
)tgt
,
918 IPA_REF_ALIAS
, NULL
);
919 cgraph_mark_reachable_node (tgt
);
920 if (node
->same_body_alias
)
922 DECL_VIRTUAL_P (node
->symbol
.decl
) = DECL_VIRTUAL_P (node
->thunk
.alias
);
923 DECL_DECLARED_INLINE_P (node
->symbol
.decl
)
924 = DECL_DECLARED_INLINE_P (node
->thunk
.alias
);
925 DECL_DISREGARD_INLINE_LIMITS (node
->symbol
.decl
)
926 = DECL_DISREGARD_INLINE_LIMITS (node
->thunk
.alias
);
929 /* Fixup visibility nonsences C++ frontend produce on same body aliases. */
930 if (TREE_PUBLIC (node
->symbol
.decl
) && node
->same_body_alias
)
932 DECL_EXTERNAL (node
->symbol
.decl
) = DECL_EXTERNAL (node
->thunk
.alias
);
933 if (DECL_ONE_ONLY (node
->thunk
.alias
))
935 DECL_COMDAT (node
->symbol
.decl
) = DECL_COMDAT (node
->thunk
.alias
);
936 DECL_COMDAT_GROUP (node
->symbol
.decl
) = DECL_COMDAT_GROUP (node
->thunk
.alias
);
937 if (DECL_ONE_ONLY (node
->thunk
.alias
) && !node
->symbol
.same_comdat_group
)
939 struct cgraph_node
*tgt
= cgraph_get_node (node
->thunk
.alias
);
940 node
->symbol
.same_comdat_group
= (symtab_node
)tgt
;
941 if (!tgt
->symbol
.same_comdat_group
)
942 tgt
->symbol
.same_comdat_group
= (symtab_node
)node
;
946 for (n
= tgt
->symbol
.same_comdat_group
;
947 n
->symbol
.same_comdat_group
!= (symtab_node
)tgt
;
948 n
= n
->symbol
.same_comdat_group
)
950 n
->symbol
.same_comdat_group
= (symtab_node
)node
;
955 cgraph_mark_reachable_node (cgraph_alias_aliased_node (node
));
956 if (node
->symbol
.address_taken
)
957 cgraph_mark_address_taken_node (cgraph_alias_aliased_node (node
));
958 if (cgraph_decide_is_function_needed (node
, node
->symbol
.decl
))
959 cgraph_mark_reachable_node (node
);
961 else if (node
->thunk
.thunk_p
)
963 cgraph_create_edge (node
, cgraph_get_node (node
->thunk
.alias
),
964 NULL
, 0, CGRAPH_FREQ_BASE
);
968 current_function_decl
= decl
;
969 push_cfun (DECL_STRUCT_FUNCTION (decl
));
971 assign_assembler_name_if_neeeded (node
->symbol
.decl
);
973 /* Make sure to gimplify bodies only once. During analyzing a
974 function we lower it, which will require gimplified nested
975 functions, so we can end up here with an already gimplified
977 if (!gimple_body (decl
))
978 gimplify_function_tree (decl
);
979 dump_function (TDI_generic
, decl
);
981 /* Lower the function. */
985 lower_nested_functions (node
->symbol
.decl
);
986 gcc_assert (!node
->nested
);
988 gimple_register_cfg_hooks ();
989 bitmap_obstack_initialize (NULL
);
990 execute_pass_list (all_lowering_passes
);
991 free_dominance_info (CDI_POST_DOMINATORS
);
992 free_dominance_info (CDI_DOMINATORS
);
994 bitmap_obstack_release (NULL
);
995 node
->lowered
= true;
1000 node
->analyzed
= true;
1002 current_function_decl
= save
;
1005 /* C++ frontend produce same body aliases all over the place, even before PCH
1006 gets streamed out. It relies on us linking the aliases with their function
1007 in order to do the fixups, but ipa-ref is not PCH safe. Consequentely we
1008 first produce aliases without links, but once C++ FE is sure he won't sream
1009 PCH we build the links via this function. */
1012 cgraph_process_same_body_aliases (void)
1014 struct cgraph_node
*node
;
1015 FOR_EACH_FUNCTION (node
)
1016 if (node
->same_body_alias
1017 && !VEC_length (ipa_ref_t
, node
->symbol
.ref_list
.references
))
1019 struct cgraph_node
*tgt
= cgraph_get_node (node
->thunk
.alias
);
1020 ipa_record_reference ((symtab_node
)node
, (symtab_node
)tgt
,
1021 IPA_REF_ALIAS
, NULL
);
1023 same_body_aliases_done
= true;
1026 /* Process attributes common for vars and functions. */
1029 process_common_attributes (tree decl
)
1031 tree weakref
= lookup_attribute ("weakref", DECL_ATTRIBUTES (decl
));
1033 if (weakref
&& !lookup_attribute ("alias", DECL_ATTRIBUTES (decl
)))
1035 warning_at (DECL_SOURCE_LOCATION (decl
), OPT_Wattributes
,
1036 "%<weakref%> attribute should be accompanied with"
1037 " an %<alias%> attribute");
1038 DECL_WEAK (decl
) = 0;
1039 DECL_ATTRIBUTES (decl
) = remove_attribute ("weakref",
1040 DECL_ATTRIBUTES (decl
));
1044 /* Look for externally_visible and used attributes and mark cgraph nodes
1047 We cannot mark the nodes at the point the attributes are processed (in
1048 handle_*_attribute) because the copy of the declarations available at that
1049 point may not be canonical. For example, in:
1052 void f() __attribute__((used));
1054 the declaration we see in handle_used_attribute will be the second
1055 declaration -- but the front end will subsequently merge that declaration
1056 with the original declaration and discard the second declaration.
1058 Furthermore, we can't mark these nodes in cgraph_finalize_function because:
1061 void f() __attribute__((externally_visible));
1065 So, we walk the nodes at the end of the translation unit, applying the
1066 attributes at that point. */
1069 process_function_and_variable_attributes (struct cgraph_node
*first
,
1070 struct varpool_node
*first_var
)
1072 struct cgraph_node
*node
;
1073 struct varpool_node
*vnode
;
1075 for (node
= cgraph_first_function (); node
!= first
;
1076 node
= cgraph_next_function (node
))
1078 tree decl
= node
->symbol
.decl
;
1079 if (DECL_PRESERVE_P (decl
))
1080 cgraph_mark_force_output_node (node
);
1081 if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
1082 && lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl
))
1083 && TREE_PUBLIC (node
->symbol
.decl
))
1085 if (node
->local
.finalized
)
1086 cgraph_mark_reachable_node (node
);
1088 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl
)))
1090 if (! TREE_PUBLIC (node
->symbol
.decl
))
1091 warning_at (DECL_SOURCE_LOCATION (node
->symbol
.decl
), OPT_Wattributes
,
1092 "%<externally_visible%>"
1093 " attribute have effect only on public objects");
1094 else if (node
->local
.finalized
)
1095 cgraph_mark_reachable_node (node
);
1097 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl
))
1098 && (node
->local
.finalized
&& !node
->alias
))
1100 warning_at (DECL_SOURCE_LOCATION (node
->symbol
.decl
), OPT_Wattributes
,
1101 "%<weakref%> attribute ignored"
1102 " because function is defined");
1103 DECL_WEAK (decl
) = 0;
1104 DECL_ATTRIBUTES (decl
) = remove_attribute ("weakref",
1105 DECL_ATTRIBUTES (decl
));
1108 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl
))
1109 && !DECL_DECLARED_INLINE_P (decl
)
1110 /* redefining extern inline function makes it DECL_UNINLINABLE. */
1111 && !DECL_UNINLINABLE (decl
))
1112 warning_at (DECL_SOURCE_LOCATION (decl
), OPT_Wattributes
,
1113 "always_inline function might not be inlinable");
1115 process_common_attributes (decl
);
1117 for (vnode
= varpool_first_variable (); vnode
!= first_var
;
1118 vnode
= varpool_next_variable (vnode
))
1120 tree decl
= vnode
->symbol
.decl
;
1121 if (DECL_PRESERVE_P (decl
))
1122 vnode
->symbol
.force_output
= true;
1123 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl
)))
1125 if (! TREE_PUBLIC (vnode
->symbol
.decl
))
1126 warning_at (DECL_SOURCE_LOCATION (vnode
->symbol
.decl
), OPT_Wattributes
,
1127 "%<externally_visible%>"
1128 " attribute have effect only on public objects");
1130 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl
))
1132 && DECL_INITIAL (decl
))
1134 warning_at (DECL_SOURCE_LOCATION (vnode
->symbol
.decl
), OPT_Wattributes
,
1135 "%<weakref%> attribute ignored"
1136 " because variable is initialized");
1137 DECL_WEAK (decl
) = 0;
1138 DECL_ATTRIBUTES (decl
) = remove_attribute ("weakref",
1139 DECL_ATTRIBUTES (decl
));
1141 process_common_attributes (decl
);
1145 /* Return true when there are references to NODE. */
1148 referred_to_p (symtab_node node
)
1151 struct ipa_ref
*ref
;
1153 for (i
= 0; ipa_ref_list_referring_iterate (&node
->symbol
.ref_list
, i
, ref
);
1156 if (symtab_function_p (node
) && cgraph (node
)->callers
)
1161 /* Mark DECL as finalized. By finalizing the declaration, frontend instruct the
1162 middle end to output the variable to asm file, if needed or externally
1166 varpool_finalize_decl (tree decl
)
1168 struct varpool_node
*node
= varpool_node (decl
);
1170 gcc_assert (TREE_STATIC (decl
));
1172 if (node
->finalized
)
1174 notice_global_symbol (decl
);
1175 node
->finalized
= true;
1176 if (TREE_THIS_VOLATILE (decl
) || DECL_PRESERVE_P (decl
)
1177 /* Traditionally we do not eliminate static variables when not
1178 optimizing and when not doing toplevel reoder. */
1179 || (!flag_toplevel_reorder
&& !DECL_COMDAT (node
->symbol
.decl
)
1180 && !DECL_ARTIFICIAL (node
->symbol
.decl
)))
1181 node
->symbol
.force_output
= true;
1183 if (cgraph_state
== CGRAPH_STATE_CONSTRUCTION
1184 && (decide_is_variable_needed (node
, decl
)
1185 || referred_to_p ((symtab_node
)node
)))
1186 enqueue_node ((symtab_node
)node
);
1187 if (cgraph_state
>= CGRAPH_STATE_IPA_SSA
)
1188 varpool_analyze_node (node
);
1191 /* Discover all functions and variables that are trivially needed, analyze
1192 them as well as all functions and variables referred by them */
1195 cgraph_analyze_functions (void)
1197 /* Keep track of already processed nodes when called multiple times for
1198 intermodule optimization. */
1199 static struct cgraph_node
*first_analyzed
;
1200 struct cgraph_node
*first_handled
= first_analyzed
;
1201 static struct varpool_node
*first_analyzed_var
;
1202 struct varpool_node
*first_handled_var
= first_analyzed_var
;
1204 symtab_node node
, next
;
1206 struct ipa_ref
*ref
;
1207 bool changed
= true;
1209 bitmap_obstack_initialize (NULL
);
1210 cgraph_state
= CGRAPH_STATE_CONSTRUCTION
;
1212 /* Analysis adds static variables that in turn adds references to new functions.
1213 So we need to iterate the process until it stabilize. */
1217 process_function_and_variable_attributes (first_analyzed
,
1218 first_analyzed_var
);
1220 /* First identify the trivially needed symbols. */
1221 for (node
= symtab_nodes
;
1222 node
!= (symtab_node
)first_analyzed
1223 && node
!= (symtab_node
)first_analyzed_var
; node
= node
->symbol
.next
)
1225 if ((symtab_function_p (node
)
1226 && cgraph (node
)->local
.finalized
1227 && cgraph_decide_is_function_needed (cgraph (node
), node
->symbol
.decl
))
1228 || (symtab_variable_p (node
)
1229 && varpool (node
)->finalized
1230 && !DECL_EXTERNAL (node
->symbol
.decl
)
1231 && decide_is_variable_needed (varpool (node
), node
->symbol
.decl
)))
1233 enqueue_node (node
);
1234 if (!changed
&& cgraph_dump_file
)
1235 fprintf (cgraph_dump_file
, "Trivially needed symbols:");
1237 if (cgraph_dump_file
)
1238 fprintf (cgraph_dump_file
, " %s", symtab_node_asm_name (node
));
1240 if (node
== (symtab_node
)first_analyzed
1241 || node
== (symtab_node
)first_analyzed_var
)
1244 cgraph_process_new_functions ();
1245 first_analyzed_var
= varpool_first_variable ();
1246 first_analyzed
= cgraph_first_function ();
1248 if (changed
&& dump_file
)
1249 fprintf (cgraph_dump_file
, "\n");
1251 /* Lower representation, build callgraph edges and references for all trivially
1252 needed symbols and all symbols referred by them. */
1253 while (first
!= (symtab_node
)(void *)1)
1257 first
= (symtab_node
)first
->symbol
.aux
;
1258 if (symtab_function_p (node
) && cgraph (node
)->local
.finalized
)
1260 struct cgraph_edge
*edge
;
1261 struct cgraph_node
*cnode
;
1264 cnode
= cgraph (node
);
1265 decl
= cnode
->symbol
.decl
;
1267 /* ??? It is possible to create extern inline function and later using
1268 weak alias attribute to kill its body. See
1269 gcc.c-torture/compile/20011119-1.c */
1270 if (!DECL_STRUCT_FUNCTION (decl
)
1271 && (!cnode
->alias
|| !cnode
->thunk
.alias
)
1272 && !cnode
->thunk
.thunk_p
)
1274 cgraph_reset_node (cnode
);
1275 cnode
->local
.redefined_extern_inline
= true;
1279 if (!cnode
->analyzed
)
1280 cgraph_analyze_function (cnode
);
1282 for (edge
= cnode
->callees
; edge
; edge
= edge
->next_callee
)
1284 cgraph_mark_reachable_node (edge
->callee
);
1285 if (edge
->callee
->local
.finalized
)
1286 enqueue_node ((symtab_node
)edge
->callee
);
1289 /* If decl is a clone of an abstract function, mark that abstract
1290 function so that we don't release its body. The DECL_INITIAL() of that
1291 abstract function declaration will be later needed to output debug
1293 if (DECL_ABSTRACT_ORIGIN (decl
))
1295 struct cgraph_node
*origin_node
;
1296 origin_node
= cgraph_get_node (DECL_ABSTRACT_ORIGIN (decl
));
1297 origin_node
->abstract_and_needed
= true;
1301 else if (symtab_variable_p (node
)
1302 && varpool (node
)->finalized
)
1304 varpool_analyze_node (varpool (node
));
1307 if (node
->symbol
.same_comdat_group
)
1310 for (next
= node
->symbol
.same_comdat_group
;
1312 next
= next
->symbol
.same_comdat_group
)
1313 enqueue_node (next
);
1315 for (i
= 0; ipa_ref_list_reference_iterate (&node
->symbol
.ref_list
, i
, ref
); i
++)
1316 if ((symtab_function_p (ref
->referred
) && cgraph (ref
->referred
)->local
.finalized
)
1317 || (symtab_variable_p (ref
->referred
) && varpool (ref
->referred
)->finalized
))
1318 enqueue_node (ref
->referred
);
1319 cgraph_process_new_functions ();
1323 /* Collect entry points to the unit. */
1324 if (cgraph_dump_file
)
1326 fprintf (cgraph_dump_file
, "\n\nInitial ");
1327 dump_symtab (cgraph_dump_file
);
1330 if (cgraph_dump_file
)
1331 fprintf (cgraph_dump_file
, "\nRemoving unused symbols:");
1333 for (node
= symtab_nodes
;
1334 node
!= (symtab_node
)first_handled
1335 && node
!= (symtab_node
)first_handled_var
; node
= next
)
1337 next
= node
->symbol
.next
;
1338 if (!node
->symbol
.aux
&& !referred_to_p (node
))
1340 if (cgraph_dump_file
)
1341 fprintf (cgraph_dump_file
, " %s", symtab_node_name (node
));
1342 symtab_remove_node (node
);
1345 if (symtab_function_p (node
))
1347 tree decl
= node
->symbol
.decl
;
1348 struct cgraph_node
*cnode
= cgraph (node
);
1350 if (cnode
->local
.finalized
&& !gimple_has_body_p (decl
)
1351 && (!cnode
->alias
|| !cnode
->thunk
.alias
)
1352 && !cnode
->thunk
.thunk_p
)
1353 cgraph_reset_node (cnode
);
1355 gcc_assert (!cnode
->local
.finalized
|| cnode
->thunk
.thunk_p
1357 || gimple_has_body_p (decl
));
1358 gcc_assert (cnode
->analyzed
== cnode
->local
.finalized
);
1360 node
->symbol
.aux
= NULL
;
1362 first_analyzed
= cgraph_first_function ();
1363 first_analyzed_var
= varpool_first_variable ();
1364 if (cgraph_dump_file
)
1366 fprintf (cgraph_dump_file
, "\n\nReclaimed ");
1367 dump_symtab (cgraph_dump_file
);
1369 bitmap_obstack_release (NULL
);
1373 /* Translate the ugly representation of aliases as alias pairs into nice
1374 representation in callgraph. We don't handle all cases yet,
1378 handle_alias_pairs (void)
1382 struct cgraph_node
*target_node
;
1383 struct cgraph_node
*src_node
;
1384 struct varpool_node
*target_vnode
;
1386 for (i
= 0; VEC_iterate (alias_pair
, alias_pairs
, i
, p
);)
1388 if (TREE_CODE (p
->decl
) == FUNCTION_DECL
1389 && (target_node
= cgraph_node_for_asm (p
->target
)) != NULL
)
1391 src_node
= cgraph_get_node (p
->decl
);
1392 if (src_node
&& src_node
->local
.finalized
)
1393 cgraph_reset_node (src_node
);
1394 /* Normally EXTERNAL flag is used to mark external inlines,
1395 however for aliases it seems to be allowed to use it w/o
1396 any meaning. See gcc.dg/attr-alias-3.c
1397 However for weakref we insist on EXTERNAL flag being set.
1398 See gcc.dg/attr-alias-5.c */
1399 if (DECL_EXTERNAL (p
->decl
))
1400 DECL_EXTERNAL (p
->decl
)
1401 = lookup_attribute ("weakref",
1402 DECL_ATTRIBUTES (p
->decl
)) != NULL
;
1403 cgraph_create_function_alias (p
->decl
, target_node
->symbol
.decl
);
1404 VEC_unordered_remove (alias_pair
, alias_pairs
, i
);
1406 else if (TREE_CODE (p
->decl
) == VAR_DECL
1407 && (target_vnode
= varpool_node_for_asm (p
->target
)) != NULL
)
1409 /* Normally EXTERNAL flag is used to mark external inlines,
1410 however for aliases it seems to be allowed to use it w/o
1411 any meaning. See gcc.dg/attr-alias-3.c
1412 However for weakref we insist on EXTERNAL flag being set.
1413 See gcc.dg/attr-alias-5.c */
1414 if (DECL_EXTERNAL (p
->decl
))
1415 DECL_EXTERNAL (p
->decl
)
1416 = lookup_attribute ("weakref",
1417 DECL_ATTRIBUTES (p
->decl
)) != NULL
;
1418 varpool_create_variable_alias (p
->decl
, target_vnode
->symbol
.decl
);
1419 VEC_unordered_remove (alias_pair
, alias_pairs
, i
);
1421 /* Weakrefs with target not defined in current unit are easy to handle; they
1422 behave just as external variables except we need to note the alias flag
1423 to later output the weakref pseudo op into asm file. */
1424 else if (lookup_attribute ("weakref", DECL_ATTRIBUTES (p
->decl
)) != NULL
1425 && (TREE_CODE (p
->decl
) == FUNCTION_DECL
1426 ? (varpool_node_for_asm (p
->target
) == NULL
)
1427 : (cgraph_node_for_asm (p
->target
) == NULL
)))
1429 if (TREE_CODE (p
->decl
) == FUNCTION_DECL
)
1430 cgraph_get_create_node (p
->decl
)->alias
= true;
1432 varpool_get_node (p
->decl
)->alias
= true;
1433 DECL_EXTERNAL (p
->decl
) = 1;
1434 VEC_unordered_remove (alias_pair
, alias_pairs
, i
);
1439 fprintf (dump_file
, "Unhandled alias %s->%s\n",
1440 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (p
->decl
)),
1441 IDENTIFIER_POINTER (p
->target
));
1449 /* Figure out what functions we want to assemble. */
1452 cgraph_mark_functions_to_output (void)
1454 struct cgraph_node
*node
;
1455 #ifdef ENABLE_CHECKING
1456 bool check_same_comdat_groups
= false;
1458 FOR_EACH_FUNCTION (node
)
1459 gcc_assert (!node
->process
);
1462 FOR_EACH_FUNCTION (node
)
1464 tree decl
= node
->symbol
.decl
;
1465 struct cgraph_edge
*e
;
1467 gcc_assert (!node
->process
|| node
->symbol
.same_comdat_group
);
1471 for (e
= node
->callers
; e
; e
= e
->next_caller
)
1472 if (e
->inline_failed
)
1475 /* We need to output all local functions that are used and not
1476 always inlined, as well as those that are reachable from
1477 outside the current compilation unit. */
1479 && !node
->thunk
.thunk_p
1481 && !node
->global
.inlined_to
1482 && (!cgraph_only_called_directly_p (node
)
1483 || ((e
|| ipa_ref_has_aliases_p (&node
->symbol
.ref_list
))
1484 && node
->reachable
))
1485 && !TREE_ASM_WRITTEN (decl
)
1486 && !DECL_EXTERNAL (decl
))
1489 if (node
->symbol
.same_comdat_group
)
1491 struct cgraph_node
*next
;
1492 for (next
= cgraph (node
->symbol
.same_comdat_group
);
1494 next
= cgraph (next
->symbol
.same_comdat_group
))
1495 if (!next
->thunk
.thunk_p
&& !next
->alias
)
1499 else if (node
->symbol
.same_comdat_group
)
1501 #ifdef ENABLE_CHECKING
1502 check_same_comdat_groups
= true;
1507 /* We should've reclaimed all functions that are not needed. */
1508 #ifdef ENABLE_CHECKING
1509 if (!node
->global
.inlined_to
1510 && gimple_has_body_p (decl
)
1511 /* FIXME: in ltrans unit when offline copy is outside partition but inline copies
1512 are inside partition, we can end up not removing the body since we no longer
1513 have analyzed node pointing to it. */
1514 && !node
->symbol
.in_other_partition
1516 && !DECL_EXTERNAL (decl
))
1518 dump_cgraph_node (stderr
, node
);
1519 internal_error ("failed to reclaim unneeded function");
1522 gcc_assert (node
->global
.inlined_to
1523 || !gimple_has_body_p (decl
)
1524 || node
->symbol
.in_other_partition
1525 || DECL_EXTERNAL (decl
));
1530 #ifdef ENABLE_CHECKING
1531 if (check_same_comdat_groups
)
1532 FOR_EACH_FUNCTION (node
)
1533 if (node
->symbol
.same_comdat_group
&& !node
->process
)
1535 tree decl
= node
->symbol
.decl
;
1536 if (!node
->global
.inlined_to
1537 && gimple_has_body_p (decl
)
1538 /* FIXME: in an ltrans unit when the offline copy is outside a
1539 partition but inline copies are inside a partition, we can
1540 end up not removing the body since we no longer have an
1541 analyzed node pointing to it. */
1542 && !node
->symbol
.in_other_partition
1543 && !DECL_EXTERNAL (decl
))
1545 dump_cgraph_node (stderr
, node
);
1546 internal_error ("failed to reclaim unneeded function in same "
1553 /* DECL is FUNCTION_DECL. Initialize datastructures so DECL is a function
1554 in lowered gimple form.
1556 Set current_function_decl and cfun to newly constructed empty function body.
1557 return basic block in the function body. */
1560 init_lowered_empty_function (tree decl
)
1564 current_function_decl
= decl
;
1565 allocate_struct_function (decl
, false);
1566 gimple_register_cfg_hooks ();
1567 init_empty_tree_cfg ();
1568 init_tree_ssa (cfun
);
1569 init_ssa_operands ();
1570 cfun
->gimple_df
->in_ssa_p
= true;
1571 DECL_INITIAL (decl
) = make_node (BLOCK
);
1573 DECL_SAVED_TREE (decl
) = error_mark_node
;
1574 cfun
->curr_properties
|=
1575 (PROP_gimple_lcf
| PROP_gimple_leh
| PROP_cfg
| PROP_referenced_vars
|
1576 PROP_ssa
| PROP_gimple_any
);
1578 /* Create BB for body of the function and connect it properly. */
1579 bb
= create_basic_block (NULL
, (void *) 0, ENTRY_BLOCK_PTR
);
1580 make_edge (ENTRY_BLOCK_PTR
, bb
, 0);
1581 make_edge (bb
, EXIT_BLOCK_PTR
, 0);
1586 /* Adjust PTR by the constant FIXED_OFFSET, and by the vtable
1587 offset indicated by VIRTUAL_OFFSET, if that is
1588 non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and
1589 zero for a result adjusting thunk. */
1592 thunk_adjust (gimple_stmt_iterator
* bsi
,
1593 tree ptr
, bool this_adjusting
,
1594 HOST_WIDE_INT fixed_offset
, tree virtual_offset
)
1600 && fixed_offset
!= 0)
1602 stmt
= gimple_build_assign
1603 (ptr
, fold_build_pointer_plus_hwi_loc (input_location
,
1606 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1609 /* If there's a virtual offset, look up that value in the vtable and
1610 adjust the pointer again. */
1617 if (!vtable_entry_type
)
1619 tree vfunc_type
= make_node (FUNCTION_TYPE
);
1620 TREE_TYPE (vfunc_type
) = integer_type_node
;
1621 TYPE_ARG_TYPES (vfunc_type
) = NULL_TREE
;
1622 layout_type (vfunc_type
);
1624 vtable_entry_type
= build_pointer_type (vfunc_type
);
1628 create_tmp_var (build_pointer_type
1629 (build_pointer_type (vtable_entry_type
)), "vptr");
1631 /* The vptr is always at offset zero in the object. */
1632 stmt
= gimple_build_assign (vtabletmp
,
1633 build1 (NOP_EXPR
, TREE_TYPE (vtabletmp
),
1635 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1636 mark_symbols_for_renaming (stmt
);
1637 find_referenced_vars_in (stmt
);
1639 /* Form the vtable address. */
1640 vtabletmp2
= create_tmp_var (TREE_TYPE (TREE_TYPE (vtabletmp
)),
1642 stmt
= gimple_build_assign (vtabletmp2
,
1643 build_simple_mem_ref (vtabletmp
));
1644 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1645 mark_symbols_for_renaming (stmt
);
1646 find_referenced_vars_in (stmt
);
1648 /* Find the entry with the vcall offset. */
1649 stmt
= gimple_build_assign (vtabletmp2
,
1650 fold_build_pointer_plus_loc (input_location
,
1653 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1655 /* Get the offset itself. */
1656 vtabletmp3
= create_tmp_var (TREE_TYPE (TREE_TYPE (vtabletmp2
)),
1658 stmt
= gimple_build_assign (vtabletmp3
,
1659 build_simple_mem_ref (vtabletmp2
));
1660 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1661 mark_symbols_for_renaming (stmt
);
1662 find_referenced_vars_in (stmt
);
1664 /* Adjust the `this' pointer. */
1665 ptr
= fold_build_pointer_plus_loc (input_location
, ptr
, vtabletmp3
);
1666 ptr
= force_gimple_operand_gsi (bsi
, ptr
, true, NULL_TREE
, false,
1667 GSI_CONTINUE_LINKING
);
1671 && fixed_offset
!= 0)
1672 /* Adjust the pointer by the constant. */
1676 if (TREE_CODE (ptr
) == VAR_DECL
)
1680 ptrtmp
= create_tmp_var (TREE_TYPE (ptr
), "ptr");
1681 stmt
= gimple_build_assign (ptrtmp
, ptr
);
1682 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1683 mark_symbols_for_renaming (stmt
);
1684 find_referenced_vars_in (stmt
);
1686 ptr
= fold_build_pointer_plus_hwi_loc (input_location
,
1687 ptrtmp
, fixed_offset
);
1690 /* Emit the statement and gimplify the adjustment expression. */
1691 ret
= create_tmp_var (TREE_TYPE (ptr
), "adjusted_this");
1692 stmt
= gimple_build_assign (ret
, ptr
);
1693 mark_symbols_for_renaming (stmt
);
1694 find_referenced_vars_in (stmt
);
1695 gsi_insert_after (bsi
, stmt
, GSI_NEW_STMT
);
1700 /* Produce assembler for thunk NODE. */
1703 assemble_thunk (struct cgraph_node
*node
)
1705 bool this_adjusting
= node
->thunk
.this_adjusting
;
1706 HOST_WIDE_INT fixed_offset
= node
->thunk
.fixed_offset
;
1707 HOST_WIDE_INT virtual_value
= node
->thunk
.virtual_value
;
1708 tree virtual_offset
= NULL
;
1709 tree alias
= node
->thunk
.alias
;
1710 tree thunk_fndecl
= node
->symbol
.decl
;
1711 tree a
= DECL_ARGUMENTS (thunk_fndecl
);
1713 current_function_decl
= thunk_fndecl
;
1715 /* Ensure thunks are emitted in their correct sections. */
1716 resolve_unique_section (thunk_fndecl
, 0, flag_function_sections
);
1719 && targetm
.asm_out
.can_output_mi_thunk (thunk_fndecl
, fixed_offset
,
1720 virtual_value
, alias
))
1724 tree restype
= TREE_TYPE (TREE_TYPE (thunk_fndecl
));
1726 DECL_RESULT (thunk_fndecl
)
1727 = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl
),
1728 RESULT_DECL
, 0, restype
);
1729 fnname
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl
));
1731 /* The back end expects DECL_INITIAL to contain a BLOCK, so we
1733 fn_block
= make_node (BLOCK
);
1734 BLOCK_VARS (fn_block
) = a
;
1735 DECL_INITIAL (thunk_fndecl
) = fn_block
;
1736 init_function_start (thunk_fndecl
);
1738 assemble_start_function (thunk_fndecl
, fnname
);
1740 targetm
.asm_out
.output_mi_thunk (asm_out_file
, thunk_fndecl
,
1741 fixed_offset
, virtual_value
, alias
);
1743 assemble_end_function (thunk_fndecl
, fnname
);
1744 init_insn_lengths ();
1745 free_after_compilation (cfun
);
1747 TREE_ASM_WRITTEN (thunk_fndecl
) = 1;
1748 node
->thunk
.thunk_p
= false;
1749 node
->analyzed
= false;
1754 basic_block bb
, then_bb
, else_bb
, return_bb
;
1755 gimple_stmt_iterator bsi
;
1761 VEC(tree
, heap
) *vargs
;
1766 DECL_IGNORED_P (thunk_fndecl
) = 1;
1767 bitmap_obstack_initialize (NULL
);
1769 if (node
->thunk
.virtual_offset_p
)
1770 virtual_offset
= size_int (virtual_value
);
1772 /* Build the return declaration for the function. */
1773 restype
= TREE_TYPE (TREE_TYPE (thunk_fndecl
));
1774 if (DECL_RESULT (thunk_fndecl
) == NULL_TREE
)
1776 resdecl
= build_decl (input_location
, RESULT_DECL
, 0, restype
);
1777 DECL_ARTIFICIAL (resdecl
) = 1;
1778 DECL_IGNORED_P (resdecl
) = 1;
1779 DECL_RESULT (thunk_fndecl
) = resdecl
;
1782 resdecl
= DECL_RESULT (thunk_fndecl
);
1784 bb
= then_bb
= else_bb
= return_bb
= init_lowered_empty_function (thunk_fndecl
);
1786 bsi
= gsi_start_bb (bb
);
1788 /* Build call to the function being thunked. */
1789 if (!VOID_TYPE_P (restype
))
1791 if (!is_gimple_reg_type (restype
))
1794 add_local_decl (cfun
, restmp
);
1795 BLOCK_VARS (DECL_INITIAL (current_function_decl
)) = restmp
;
1798 restmp
= create_tmp_var_raw (restype
, "retval");
1801 for (arg
= a
; arg
; arg
= DECL_CHAIN (arg
))
1803 vargs
= VEC_alloc (tree
, heap
, nargs
);
1805 VEC_quick_push (tree
, vargs
,
1810 VEC_quick_push (tree
, vargs
, a
);
1811 for (i
= 1, arg
= DECL_CHAIN (a
); i
< nargs
; i
++, arg
= DECL_CHAIN (arg
))
1812 VEC_quick_push (tree
, vargs
, arg
);
1813 call
= gimple_build_call_vec (build_fold_addr_expr_loc (0, alias
), vargs
);
1814 VEC_free (tree
, heap
, vargs
);
1815 gimple_call_set_from_thunk (call
, true);
1817 gimple_call_set_lhs (call
, restmp
);
1818 gsi_insert_after (&bsi
, call
, GSI_NEW_STMT
);
1819 mark_symbols_for_renaming (call
);
1820 find_referenced_vars_in (call
);
1823 if (restmp
&& !this_adjusting
)
1825 tree true_label
= NULL_TREE
;
1827 if (TREE_CODE (TREE_TYPE (restmp
)) == POINTER_TYPE
)
1830 /* If the return type is a pointer, we need to
1831 protect against NULL. We know there will be an
1832 adjustment, because that's why we're emitting a
1834 then_bb
= create_basic_block (NULL
, (void *) 0, bb
);
1835 return_bb
= create_basic_block (NULL
, (void *) 0, then_bb
);
1836 else_bb
= create_basic_block (NULL
, (void *) 0, else_bb
);
1837 remove_edge (single_succ_edge (bb
));
1838 true_label
= gimple_block_label (then_bb
);
1839 stmt
= gimple_build_cond (NE_EXPR
, restmp
,
1840 build_zero_cst (TREE_TYPE (restmp
)),
1841 NULL_TREE
, NULL_TREE
);
1842 gsi_insert_after (&bsi
, stmt
, GSI_NEW_STMT
);
1843 make_edge (bb
, then_bb
, EDGE_TRUE_VALUE
);
1844 make_edge (bb
, else_bb
, EDGE_FALSE_VALUE
);
1845 make_edge (return_bb
, EXIT_BLOCK_PTR
, 0);
1846 make_edge (then_bb
, return_bb
, EDGE_FALLTHRU
);
1847 make_edge (else_bb
, return_bb
, EDGE_FALLTHRU
);
1848 bsi
= gsi_last_bb (then_bb
);
1851 restmp
= thunk_adjust (&bsi
, restmp
, /*this_adjusting=*/0,
1852 fixed_offset
, virtual_offset
);
1856 bsi
= gsi_last_bb (else_bb
);
1857 stmt
= gimple_build_assign (restmp
,
1858 build_zero_cst (TREE_TYPE (restmp
)));
1859 gsi_insert_after (&bsi
, stmt
, GSI_NEW_STMT
);
1860 bsi
= gsi_last_bb (return_bb
);
1864 gimple_call_set_tail (call
, true);
1866 /* Build return value. */
1867 ret
= gimple_build_return (restmp
);
1868 gsi_insert_after (&bsi
, ret
, GSI_NEW_STMT
);
1870 delete_unreachable_blocks ();
1871 update_ssa (TODO_update_ssa
);
1873 /* Since we want to emit the thunk, we explicitly mark its name as
1875 node
->thunk
.thunk_p
= false;
1876 cgraph_node_remove_callees (node
);
1877 cgraph_add_new_function (thunk_fndecl
, true);
1878 bitmap_obstack_release (NULL
);
1880 current_function_decl
= NULL
;
1885 /* Assemble thunks and aliases asociated to NODE. */
1888 assemble_thunks_and_aliases (struct cgraph_node
*node
)
1890 struct cgraph_edge
*e
;
1892 struct ipa_ref
*ref
;
1894 for (e
= node
->callers
; e
;)
1895 if (e
->caller
->thunk
.thunk_p
)
1897 struct cgraph_node
*thunk
= e
->caller
;
1900 assemble_thunks_and_aliases (thunk
);
1901 assemble_thunk (thunk
);
1905 for (i
= 0; ipa_ref_list_referring_iterate (&node
->symbol
.ref_list
,
1907 if (ref
->use
== IPA_REF_ALIAS
)
1909 struct cgraph_node
*alias
= ipa_ref_referring_node (ref
);
1910 bool saved_written
= TREE_ASM_WRITTEN (alias
->thunk
.alias
);
1912 /* Force assemble_alias to really output the alias this time instead
1913 of buffering it in same alias pairs. */
1914 TREE_ASM_WRITTEN (alias
->thunk
.alias
) = 1;
1915 assemble_alias (alias
->symbol
.decl
,
1916 DECL_ASSEMBLER_NAME (alias
->thunk
.alias
));
1917 assemble_thunks_and_aliases (alias
);
1918 TREE_ASM_WRITTEN (alias
->thunk
.alias
) = saved_written
;
1922 /* Perform IPA transforms and all further optimizations and compilation
1926 tree_rest_of_compilation (struct cgraph_node
*node
)
1928 tree fndecl
= node
->symbol
.decl
;
1929 location_t saved_loc
;
1931 timevar_push (TV_REST_OF_COMPILATION
);
1933 gcc_assert (cgraph_global_info_ready
);
1935 /* Initialize the default bitmap obstack. */
1936 bitmap_obstack_initialize (NULL
);
1938 /* Initialize the RTL code for the function. */
1939 current_function_decl
= fndecl
;
1940 saved_loc
= input_location
;
1941 input_location
= DECL_SOURCE_LOCATION (fndecl
);
1942 init_function_start (fndecl
);
1944 gimple_register_cfg_hooks ();
1946 bitmap_obstack_initialize (®_obstack
); /* FIXME, only at RTL generation*/
1948 execute_all_ipa_transforms ();
1950 /* Perform all tree transforms and optimizations. */
1952 /* Signal the start of passes. */
1953 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START
, NULL
);
1955 execute_pass_list (all_passes
);
1957 /* Signal the end of passes. */
1958 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END
, NULL
);
1960 bitmap_obstack_release (®_obstack
);
1962 /* Release the default bitmap obstack. */
1963 bitmap_obstack_release (NULL
);
1967 /* If requested, warn about function definitions where the function will
1968 return a value (usually of some struct or union type) which itself will
1969 take up a lot of stack space. */
1970 if (warn_larger_than
&& !DECL_EXTERNAL (fndecl
) && TREE_TYPE (fndecl
))
1972 tree ret_type
= TREE_TYPE (TREE_TYPE (fndecl
));
1974 if (ret_type
&& TYPE_SIZE_UNIT (ret_type
)
1975 && TREE_CODE (TYPE_SIZE_UNIT (ret_type
)) == INTEGER_CST
1976 && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type
),
1979 unsigned int size_as_int
1980 = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type
));
1982 if (compare_tree_int (TYPE_SIZE_UNIT (ret_type
), size_as_int
) == 0)
1983 warning (OPT_Wlarger_than_
, "size of return value of %q+D is %u bytes",
1984 fndecl
, size_as_int
);
1986 warning (OPT_Wlarger_than_
, "size of return value of %q+D is larger than %wd bytes",
1987 fndecl
, larger_than_size
);
1991 gimple_set_body (fndecl
, NULL
);
1992 if (DECL_STRUCT_FUNCTION (fndecl
) == 0
1993 && !cgraph_get_node (fndecl
)->origin
)
1995 /* Stop pointing to the local nodes about to be freed.
1996 But DECL_INITIAL must remain nonzero so we know this
1997 was an actual function definition.
1998 For a nested function, this is done in c_pop_function_context.
1999 If rest_of_compilation set this to 0, leave it 0. */
2000 if (DECL_INITIAL (fndecl
) != 0)
2001 DECL_INITIAL (fndecl
) = error_mark_node
;
2004 input_location
= saved_loc
;
2007 timevar_pop (TV_REST_OF_COMPILATION
);
2010 /* Expand function specified by NODE. */
2013 cgraph_expand_function (struct cgraph_node
*node
)
2015 tree decl
= node
->symbol
.decl
;
2017 /* We ought to not compile any inline clones. */
2018 gcc_assert (!node
->global
.inlined_to
);
2020 announce_function (decl
);
2022 gcc_assert (node
->lowered
);
2024 /* Generate RTL for the body of DECL. */
2025 tree_rest_of_compilation (node
);
2027 /* Make sure that BE didn't give up on compiling. */
2028 gcc_assert (TREE_ASM_WRITTEN (decl
));
2029 current_function_decl
= NULL
;
2030 gcc_assert (!cgraph_preserve_function_body_p (node
));
2032 /* It would make a lot more sense to output thunks before function body to get more
2033 forward and lest backwarding jumps. This is however would need solving problem
2034 with comdats. See PR48668. Also aliases must come after function itself to
2035 make one pass assemblers, like one on AIX happy. See PR 50689.
2036 FIXME: Perhaps thunks should be move before function IFF they are not in comdat
2038 assemble_thunks_and_aliases (node
);
2039 cgraph_release_function_body (node
);
2040 /* Eliminate all call edges. This is important so the GIMPLE_CALL no longer
2041 points to the dead function body. */
2042 cgraph_node_remove_callees (node
);
2045 /* Return true when CALLER_DECL should be inlined into CALLEE_DECL. */
2048 cgraph_inline_p (struct cgraph_edge
*e
, cgraph_inline_failed_t
*reason
)
2050 *reason
= e
->inline_failed
;
2051 return !e
->inline_failed
;
2056 /* Expand all functions that must be output.
2058 Attempt to topologically sort the nodes so function is output when
2059 all called functions are already assembled to allow data to be
2060 propagated across the callgraph. Use a stack to get smaller distance
2061 between a function and its callees (later we may choose to use a more
2062 sophisticated algorithm for function reordering; we will likely want
2063 to use subsections to make the output functions appear in top-down
2067 cgraph_expand_all_functions (void)
2069 struct cgraph_node
*node
;
2070 struct cgraph_node
**order
= XCNEWVEC (struct cgraph_node
*, cgraph_n_nodes
);
2071 int order_pos
, new_order_pos
= 0;
2074 order_pos
= ipa_reverse_postorder (order
);
2075 gcc_assert (order_pos
== cgraph_n_nodes
);
2077 /* Garbage collector may remove inline clones we eliminate during
2078 optimization. So we must be sure to not reference them. */
2079 for (i
= 0; i
< order_pos
; i
++)
2080 if (order
[i
]->process
)
2081 order
[new_order_pos
++] = order
[i
];
2083 for (i
= new_order_pos
- 1; i
>= 0; i
--)
2088 gcc_assert (node
->reachable
);
2090 cgraph_expand_function (node
);
2093 cgraph_process_new_functions ();
2099 /* This is used to sort the node types by the cgraph order number. */
2101 enum cgraph_order_sort_kind
2103 ORDER_UNDEFINED
= 0,
2109 struct cgraph_order_sort
2111 enum cgraph_order_sort_kind kind
;
2114 struct cgraph_node
*f
;
2115 struct varpool_node
*v
;
2116 struct cgraph_asm_node
*a
;
2120 /* Output all functions, variables, and asm statements in the order
2121 according to their order fields, which is the order in which they
2122 appeared in the file. This implements -fno-toplevel-reorder. In
2123 this mode we may output functions and variables which don't really
2124 need to be output. */
2127 cgraph_output_in_order (void)
2130 struct cgraph_order_sort
*nodes
;
2132 struct cgraph_node
*pf
;
2133 struct varpool_node
*pv
;
2134 struct cgraph_asm_node
*pa
;
2137 nodes
= XCNEWVEC (struct cgraph_order_sort
, max
);
2139 FOR_EACH_DEFINED_FUNCTION (pf
)
2141 if (pf
->process
&& !pf
->thunk
.thunk_p
&& !pf
->alias
)
2143 i
= pf
->symbol
.order
;
2144 gcc_assert (nodes
[i
].kind
== ORDER_UNDEFINED
);
2145 nodes
[i
].kind
= ORDER_FUNCTION
;
2150 FOR_EACH_DEFINED_VARIABLE (pv
)
2152 i
= pv
->symbol
.order
;
2153 gcc_assert (nodes
[i
].kind
== ORDER_UNDEFINED
);
2154 nodes
[i
].kind
= ORDER_VAR
;
2158 for (pa
= cgraph_asm_nodes
; pa
; pa
= pa
->next
)
2161 gcc_assert (nodes
[i
].kind
== ORDER_UNDEFINED
);
2162 nodes
[i
].kind
= ORDER_ASM
;
2166 /* In toplevel reorder mode we output all statics; mark them as needed. */
2168 for (i
= 0; i
< max
; ++i
)
2169 if (nodes
[i
].kind
== ORDER_VAR
)
2170 varpool_finalize_named_section_flags (nodes
[i
].u
.v
);
2172 for (i
= 0; i
< max
; ++i
)
2174 switch (nodes
[i
].kind
)
2176 case ORDER_FUNCTION
:
2177 nodes
[i
].u
.f
->process
= 0;
2178 cgraph_expand_function (nodes
[i
].u
.f
);
2182 varpool_assemble_decl (nodes
[i
].u
.v
);
2186 assemble_asm (nodes
[i
].u
.a
->asm_str
);
2189 case ORDER_UNDEFINED
:
2197 cgraph_asm_nodes
= NULL
;
2201 /* Return true when function body of DECL still needs to be kept around
2202 for later re-use. */
2204 cgraph_preserve_function_body_p (struct cgraph_node
*node
)
2206 gcc_assert (cgraph_global_info_ready
);
2207 gcc_assert (!node
->alias
&& !node
->thunk
.thunk_p
);
2209 /* Look if there is any clone around. */
2219 current_function_decl
= NULL
;
2220 gimple_register_cfg_hooks ();
2221 bitmap_obstack_initialize (NULL
);
2223 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START
, NULL
);
2227 execute_ipa_pass_list (all_small_ipa_passes
);
2232 /* We never run removal of unreachable nodes after early passes. This is
2233 because TODO is run before the subpasses. It is important to remove
2234 the unreachable functions to save works at IPA level and to get LTO
2235 symbol tables right. */
2236 cgraph_remove_unreachable_nodes (true, cgraph_dump_file
);
2238 /* If pass_all_early_optimizations was not scheduled, the state of
2239 the cgraph will not be properly updated. Update it now. */
2240 if (cgraph_state
< CGRAPH_STATE_IPA_SSA
)
2241 cgraph_state
= CGRAPH_STATE_IPA_SSA
;
2245 /* Generate coverage variables and constructors. */
2248 /* Process new functions added. */
2250 current_function_decl
= NULL
;
2251 cgraph_process_new_functions ();
2253 execute_ipa_summary_passes
2254 ((struct ipa_opt_pass_d
*) all_regular_ipa_passes
);
2257 /* Some targets need to handle LTO assembler output specially. */
2258 if (flag_generate_lto
)
2259 targetm
.asm_out
.lto_start ();
2261 execute_ipa_summary_passes ((struct ipa_opt_pass_d
*) all_lto_gen_passes
);
2264 ipa_write_summaries ();
2266 if (flag_generate_lto
)
2267 targetm
.asm_out
.lto_end ();
2269 if (!flag_ltrans
&& (in_lto_p
|| !flag_lto
|| flag_fat_lto_objects
))
2270 execute_ipa_pass_list (all_regular_ipa_passes
);
2271 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END
, NULL
);
2273 bitmap_obstack_release (NULL
);
2277 /* Return string alias is alias of. */
2280 get_alias_symbol (tree decl
)
2282 tree alias
= lookup_attribute ("alias", DECL_ATTRIBUTES (decl
));
2283 return get_identifier (TREE_STRING_POINTER
2284 (TREE_VALUE (TREE_VALUE (alias
))));
2288 /* Weakrefs may be associated to external decls and thus not output
2289 at expansion time. Emit all neccesary aliases. */
2292 output_weakrefs (void)
2294 struct cgraph_node
*node
;
2295 struct varpool_node
*vnode
;
2296 FOR_EACH_FUNCTION (node
)
2297 if (node
->alias
&& DECL_EXTERNAL (node
->symbol
.decl
)
2298 && !TREE_ASM_WRITTEN (node
->symbol
.decl
)
2299 && lookup_attribute ("weakref", DECL_ATTRIBUTES (node
->symbol
.decl
)))
2300 assemble_alias (node
->symbol
.decl
,
2301 node
->thunk
.alias
? DECL_ASSEMBLER_NAME (node
->thunk
.alias
)
2302 : get_alias_symbol (node
->symbol
.decl
));
2303 FOR_EACH_VARIABLE (vnode
)
2304 if (vnode
->alias
&& DECL_EXTERNAL (vnode
->symbol
.decl
)
2305 && !TREE_ASM_WRITTEN (vnode
->symbol
.decl
)
2306 && lookup_attribute ("weakref", DECL_ATTRIBUTES (vnode
->symbol
.decl
)))
2307 assemble_alias (vnode
->symbol
.decl
,
2308 vnode
->alias_of
? DECL_ASSEMBLER_NAME (vnode
->alias_of
)
2309 : get_alias_symbol (vnode
->symbol
.decl
));
2317 if (!cgraph_dump_file
)
2318 cgraph_dump_file
= dump_begin (TDI_cgraph
, NULL
);
2321 /* The edges representing the callers of the NEW_VERSION node were
2322 fixed by cgraph_function_versioning (), now the call_expr in their
2323 respective tree code should be updated to call the NEW_VERSION. */
2326 update_call_expr (struct cgraph_node
*new_version
)
2328 struct cgraph_edge
*e
;
2330 gcc_assert (new_version
);
2332 /* Update the call expr on the edges to call the new version. */
2333 for (e
= new_version
->callers
; e
; e
= e
->next_caller
)
2335 struct function
*inner_function
= DECL_STRUCT_FUNCTION (e
->caller
->symbol
.decl
);
2336 gimple_call_set_fndecl (e
->call_stmt
, new_version
->symbol
.decl
);
2337 maybe_clean_eh_stmt_fn (inner_function
, e
->call_stmt
);
2342 /* Create a new cgraph node which is the new version of
2343 OLD_VERSION node. REDIRECT_CALLERS holds the callers
2344 edges which should be redirected to point to
2345 NEW_VERSION. ALL the callees edges of OLD_VERSION
2346 are cloned to the new version node. Return the new
2349 If non-NULL BLOCK_TO_COPY determine what basic blocks
2350 was copied to prevent duplications of calls that are dead
2353 struct cgraph_node
*
2354 cgraph_copy_node_for_versioning (struct cgraph_node
*old_version
,
2356 VEC(cgraph_edge_p
,heap
) *redirect_callers
,
2359 struct cgraph_node
*new_version
;
2360 struct cgraph_edge
*e
;
2363 gcc_assert (old_version
);
2365 new_version
= cgraph_create_node (new_decl
);
2367 new_version
->analyzed
= old_version
->analyzed
;
2368 new_version
->local
= old_version
->local
;
2369 new_version
->symbol
.externally_visible
= false;
2370 new_version
->local
.local
= old_version
->analyzed
;
2371 new_version
->global
= old_version
->global
;
2372 new_version
->rtl
= old_version
->rtl
;
2373 new_version
->reachable
= true;
2374 new_version
->count
= old_version
->count
;
2376 for (e
= old_version
->callees
; e
; e
=e
->next_callee
)
2378 || bitmap_bit_p (bbs_to_copy
, gimple_bb (e
->call_stmt
)->index
))
2379 cgraph_clone_edge (e
, new_version
, e
->call_stmt
,
2380 e
->lto_stmt_uid
, REG_BR_PROB_BASE
,
2383 for (e
= old_version
->indirect_calls
; e
; e
=e
->next_callee
)
2385 || bitmap_bit_p (bbs_to_copy
, gimple_bb (e
->call_stmt
)->index
))
2386 cgraph_clone_edge (e
, new_version
, e
->call_stmt
,
2387 e
->lto_stmt_uid
, REG_BR_PROB_BASE
,
2390 FOR_EACH_VEC_ELT (cgraph_edge_p
, redirect_callers
, i
, e
)
2392 /* Redirect calls to the old version node to point to its new
2394 cgraph_redirect_edge_callee (e
, new_version
);
2397 cgraph_call_node_duplication_hooks (old_version
, new_version
);
2402 /* Perform function versioning.
2403 Function versioning includes copying of the tree and
2404 a callgraph update (creating a new cgraph node and updating
2405 its callees and callers).
2407 REDIRECT_CALLERS varray includes the edges to be redirected
2410 TREE_MAP is a mapping of tree nodes we want to replace with
2411 new ones (according to results of prior analysis).
2412 OLD_VERSION_NODE is the node that is versioned.
2414 If non-NULL ARGS_TO_SKIP determine function parameters to remove
2416 If SKIP_RETURN is true, the new version will return void.
2417 If non-NULL BLOCK_TO_COPY determine what basic blocks to copy.
2418 If non_NULL NEW_ENTRY determine new entry BB of the clone.
2420 Return the new version's cgraph node. */
2422 struct cgraph_node
*
2423 cgraph_function_versioning (struct cgraph_node
*old_version_node
,
2424 VEC(cgraph_edge_p
,heap
) *redirect_callers
,
2425 VEC (ipa_replace_map_p
,gc
)* tree_map
,
2426 bitmap args_to_skip
,
2429 basic_block new_entry_block
,
2430 const char *clone_name
)
2432 tree old_decl
= old_version_node
->symbol
.decl
;
2433 struct cgraph_node
*new_version_node
= NULL
;
2436 if (!tree_versionable_function_p (old_decl
))
2439 gcc_assert (old_version_node
->local
.can_change_signature
|| !args_to_skip
);
2441 /* Make a new FUNCTION_DECL tree node for the new version. */
2442 if (!args_to_skip
&& !skip_return
)
2443 new_decl
= copy_node (old_decl
);
2446 = build_function_decl_skip_args (old_decl
, args_to_skip
, skip_return
);
2448 /* Generate a new name for the new version. */
2449 DECL_NAME (new_decl
) = clone_function_name (old_decl
, clone_name
);
2450 SET_DECL_ASSEMBLER_NAME (new_decl
, DECL_NAME (new_decl
));
2451 SET_DECL_RTL (new_decl
, NULL
);
2453 /* When the old decl was a con-/destructor make sure the clone isn't. */
2454 DECL_STATIC_CONSTRUCTOR(new_decl
) = 0;
2455 DECL_STATIC_DESTRUCTOR(new_decl
) = 0;
2457 /* Create the new version's call-graph node.
2458 and update the edges of the new node. */
2460 cgraph_copy_node_for_versioning (old_version_node
, new_decl
,
2461 redirect_callers
, bbs_to_copy
);
2463 /* Copy the OLD_VERSION_NODE function tree to the new version. */
2464 tree_function_versioning (old_decl
, new_decl
, tree_map
, false, args_to_skip
,
2465 skip_return
, bbs_to_copy
, new_entry_block
);
2467 /* Update the new version's properties.
2468 Make The new version visible only within this translation unit. Make sure
2469 that is not weak also.
2470 ??? We cannot use COMDAT linkage because there is no
2471 ABI support for this. */
2472 cgraph_make_decl_local (new_version_node
->symbol
.decl
);
2473 DECL_VIRTUAL_P (new_version_node
->symbol
.decl
) = 0;
2474 new_version_node
->symbol
.externally_visible
= 0;
2475 new_version_node
->local
.local
= 1;
2476 new_version_node
->lowered
= true;
2478 /* Update the call_expr on the edges to call the new version node. */
2479 update_call_expr (new_version_node
);
2481 cgraph_call_function_insertion_hooks (new_version_node
);
2482 return new_version_node
;
2485 /* Given virtual clone, turn it into actual clone. */
2487 cgraph_materialize_clone (struct cgraph_node
*node
)
2489 bitmap_obstack_initialize (NULL
);
2490 node
->former_clone_of
= node
->clone_of
->symbol
.decl
;
2491 if (node
->clone_of
->former_clone_of
)
2492 node
->former_clone_of
= node
->clone_of
->former_clone_of
;
2493 /* Copy the OLD_VERSION_NODE function tree to the new version. */
2494 tree_function_versioning (node
->clone_of
->symbol
.decl
, node
->symbol
.decl
,
2495 node
->clone
.tree_map
, true,
2496 node
->clone
.args_to_skip
, false,
2498 if (cgraph_dump_file
)
2500 dump_function_to_file (node
->clone_of
->symbol
.decl
, cgraph_dump_file
, dump_flags
);
2501 dump_function_to_file (node
->symbol
.decl
, cgraph_dump_file
, dump_flags
);
2504 /* Function is no longer clone. */
2505 if (node
->next_sibling_clone
)
2506 node
->next_sibling_clone
->prev_sibling_clone
= node
->prev_sibling_clone
;
2507 if (node
->prev_sibling_clone
)
2508 node
->prev_sibling_clone
->next_sibling_clone
= node
->next_sibling_clone
;
2510 node
->clone_of
->clones
= node
->next_sibling_clone
;
2511 node
->next_sibling_clone
= NULL
;
2512 node
->prev_sibling_clone
= NULL
;
2513 if (!node
->clone_of
->analyzed
&& !node
->clone_of
->clones
)
2515 cgraph_release_function_body (node
->clone_of
);
2516 cgraph_node_remove_callees (node
->clone_of
);
2517 ipa_remove_all_references (&node
->clone_of
->symbol
.ref_list
);
2519 node
->clone_of
= NULL
;
2520 bitmap_obstack_release (NULL
);
2523 /* If necessary, change the function declaration in the call statement
2524 associated with E so that it corresponds to the edge callee. */
2527 cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge
*e
)
2529 tree decl
= gimple_call_fndecl (e
->call_stmt
);
2531 gimple_stmt_iterator gsi
;
2532 #ifdef ENABLE_CHECKING
2533 struct cgraph_node
*node
;
2536 if (e
->indirect_unknown_callee
2537 || decl
== e
->callee
->symbol
.decl
)
2538 return e
->call_stmt
;
2540 #ifdef ENABLE_CHECKING
2543 node
= cgraph_get_node (decl
);
2544 gcc_assert (!node
|| !node
->clone
.combined_args_to_skip
);
2548 if (cgraph_dump_file
)
2550 fprintf (cgraph_dump_file
, "updating call of %s/%i -> %s/%i: ",
2551 cgraph_node_name (e
->caller
), e
->caller
->uid
,
2552 cgraph_node_name (e
->callee
), e
->callee
->uid
);
2553 print_gimple_stmt (cgraph_dump_file
, e
->call_stmt
, 0, dump_flags
);
2554 if (e
->callee
->clone
.combined_args_to_skip
)
2556 fprintf (cgraph_dump_file
, " combined args to skip: ");
2557 dump_bitmap (cgraph_dump_file
,
2558 e
->callee
->clone
.combined_args_to_skip
);
2562 if (e
->callee
->clone
.combined_args_to_skip
)
2567 = gimple_call_copy_skip_args (e
->call_stmt
,
2568 e
->callee
->clone
.combined_args_to_skip
);
2569 gimple_call_set_fndecl (new_stmt
, e
->callee
->symbol
.decl
);
2571 if (gimple_vdef (new_stmt
)
2572 && TREE_CODE (gimple_vdef (new_stmt
)) == SSA_NAME
)
2573 SSA_NAME_DEF_STMT (gimple_vdef (new_stmt
)) = new_stmt
;
2575 gsi
= gsi_for_stmt (e
->call_stmt
);
2576 gsi_replace (&gsi
, new_stmt
, false);
2577 /* We need to defer cleaning EH info on the new statement to
2578 fixup-cfg. We may not have dominator information at this point
2579 and thus would end up with unreachable blocks and have no way
2580 to communicate that we need to run CFG cleanup then. */
2581 lp_nr
= lookup_stmt_eh_lp (e
->call_stmt
);
2584 remove_stmt_from_eh_lp (e
->call_stmt
);
2585 add_stmt_to_eh_lp (new_stmt
, lp_nr
);
2590 new_stmt
= e
->call_stmt
;
2591 gimple_call_set_fndecl (new_stmt
, e
->callee
->symbol
.decl
);
2592 update_stmt (new_stmt
);
2595 cgraph_set_call_stmt_including_clones (e
->caller
, e
->call_stmt
, new_stmt
);
2597 if (cgraph_dump_file
)
2599 fprintf (cgraph_dump_file
, " updated to:");
2600 print_gimple_stmt (cgraph_dump_file
, e
->call_stmt
, 0, dump_flags
);
2605 /* Once all functions from compilation unit are in memory, produce all clones
2606 and update all calls. We might also do this on demand if we don't want to
2607 bring all functions to memory prior compilation, but current WHOPR
2608 implementation does that and it is is bit easier to keep everything right in
2611 cgraph_materialize_all_clones (void)
2613 struct cgraph_node
*node
;
2614 bool stabilized
= false;
2616 if (cgraph_dump_file
)
2617 fprintf (cgraph_dump_file
, "Materializing clones\n");
2618 #ifdef ENABLE_CHECKING
2622 /* We can also do topological order, but number of iterations should be
2623 bounded by number of IPA passes since single IPA pass is probably not
2624 going to create clones of clones it created itself. */
2628 FOR_EACH_FUNCTION (node
)
2630 if (node
->clone_of
&& node
->symbol
.decl
!= node
->clone_of
->symbol
.decl
2631 && !gimple_has_body_p (node
->symbol
.decl
))
2633 if (gimple_has_body_p (node
->clone_of
->symbol
.decl
))
2635 if (cgraph_dump_file
)
2637 fprintf (cgraph_dump_file
, "cloning %s to %s\n",
2638 cgraph_node_name (node
->clone_of
),
2639 cgraph_node_name (node
));
2640 if (node
->clone
.tree_map
)
2643 fprintf (cgraph_dump_file
, " replace map: ");
2644 for (i
= 0; i
< VEC_length (ipa_replace_map_p
,
2645 node
->clone
.tree_map
);
2648 struct ipa_replace_map
*replace_info
;
2649 replace_info
= VEC_index (ipa_replace_map_p
,
2650 node
->clone
.tree_map
,
2652 print_generic_expr (cgraph_dump_file
, replace_info
->old_tree
, 0);
2653 fprintf (cgraph_dump_file
, " -> ");
2654 print_generic_expr (cgraph_dump_file
, replace_info
->new_tree
, 0);
2655 fprintf (cgraph_dump_file
, "%s%s;",
2656 replace_info
->replace_p
? "(replace)":"",
2657 replace_info
->ref_p
? "(ref)":"");
2659 fprintf (cgraph_dump_file
, "\n");
2661 if (node
->clone
.args_to_skip
)
2663 fprintf (cgraph_dump_file
, " args_to_skip: ");
2664 dump_bitmap (cgraph_dump_file
, node
->clone
.args_to_skip
);
2666 if (node
->clone
.args_to_skip
)
2668 fprintf (cgraph_dump_file
, " combined_args_to_skip:");
2669 dump_bitmap (cgraph_dump_file
, node
->clone
.combined_args_to_skip
);
2672 cgraph_materialize_clone (node
);
2678 FOR_EACH_FUNCTION (node
)
2679 if (!node
->analyzed
&& node
->callees
)
2680 cgraph_node_remove_callees (node
);
2681 if (cgraph_dump_file
)
2682 fprintf (cgraph_dump_file
, "Materialization Call site updates done.\n");
2683 #ifdef ENABLE_CHECKING
2686 cgraph_remove_unreachable_nodes (false, cgraph_dump_file
);
2690 /* Perform simple optimizations based on callgraph. */
2693 cgraph_optimize (void)
2698 #ifdef ENABLE_CHECKING
2702 timevar_push (TV_CGRAPHOPT
);
2703 if (pre_ipa_mem_report
)
2705 fprintf (stderr
, "Memory consumption before IPA\n");
2706 dump_memory_report (false);
2709 fprintf (stderr
, "Performing interprocedural optimizations\n");
2710 cgraph_state
= CGRAPH_STATE_IPA
;
2712 /* Don't run the IPA passes if there was any error or sorry messages. */
2716 /* Do nothing else if any IPA pass found errors or if we are just streaming LTO. */
2718 || (!in_lto_p
&& flag_lto
&& !flag_fat_lto_objects
))
2720 timevar_pop (TV_CGRAPHOPT
);
2724 /* This pass remove bodies of extern inline functions we never inlined.
2725 Do this later so other IPA passes see what is really going on. */
2726 cgraph_remove_unreachable_nodes (false, dump_file
);
2727 cgraph_global_info_ready
= true;
2728 if (cgraph_dump_file
)
2730 fprintf (cgraph_dump_file
, "Optimized ");
2731 dump_symtab (cgraph_dump_file
);
2733 if (post_ipa_mem_report
)
2735 fprintf (stderr
, "Memory consumption after IPA\n");
2736 dump_memory_report (false);
2738 timevar_pop (TV_CGRAPHOPT
);
2740 /* Output everything. */
2741 (*debug_hooks
->assembly_start
) ();
2743 fprintf (stderr
, "Assembling functions:\n");
2744 #ifdef ENABLE_CHECKING
2748 cgraph_materialize_all_clones ();
2749 bitmap_obstack_initialize (NULL
);
2750 execute_ipa_pass_list (all_late_ipa_passes
);
2751 cgraph_remove_unreachable_nodes (true, dump_file
);
2752 #ifdef ENABLE_CHECKING
2755 bitmap_obstack_release (NULL
);
2756 cgraph_mark_functions_to_output ();
2759 cgraph_state
= CGRAPH_STATE_EXPANSION
;
2760 if (!flag_toplevel_reorder
)
2761 cgraph_output_in_order ();
2764 cgraph_output_pending_asms ();
2766 cgraph_expand_all_functions ();
2767 varpool_remove_unreferenced_decls ();
2769 varpool_assemble_pending_decls ();
2772 cgraph_process_new_functions ();
2773 cgraph_state
= CGRAPH_STATE_FINISHED
;
2775 if (cgraph_dump_file
)
2777 fprintf (cgraph_dump_file
, "\nFinal ");
2778 dump_symtab (cgraph_dump_file
);
2780 #ifdef ENABLE_CHECKING
2782 /* Double check that all inline clones are gone and that all
2783 function bodies have been released from memory. */
2786 struct cgraph_node
*node
;
2787 bool error_found
= false;
2789 FOR_EACH_DEFINED_FUNCTION (node
)
2790 if (node
->global
.inlined_to
2791 || gimple_has_body_p (node
->symbol
.decl
))
2794 dump_cgraph_node (stderr
, node
);
2797 internal_error ("nodes with unreleased memory found");
2803 /* Analyze the whole compilation unit once it is parsed completely. */
2806 cgraph_finalize_compilation_unit (void)
2808 timevar_push (TV_CGRAPH
);
2810 /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE. */
2812 lto_streamer_hooks_init ();
2814 /* If we're here there's no current function anymore. Some frontends
2815 are lazy in clearing these. */
2816 current_function_decl
= NULL
;
2819 /* Do not skip analyzing the functions if there were errors, we
2820 miss diagnostics for following functions otherwise. */
2822 /* Emit size functions we didn't inline. */
2823 finalize_size_functions ();
2825 /* Mark alias targets necessary and emit diagnostics. */
2826 finish_aliases_1 ();
2827 handle_alias_pairs ();
2831 fprintf (stderr
, "\nAnalyzing compilation unit\n");
2835 if (flag_dump_passes
)
2838 /* Gimplify and lower all functions, compute reachability and
2839 remove unreachable nodes. */
2840 cgraph_analyze_functions ();
2842 /* Mark alias targets necessary and emit diagnostics. */
2843 finish_aliases_1 ();
2844 handle_alias_pairs ();
2846 /* Gimplify and lower thunks. */
2847 cgraph_analyze_functions ();
2849 /* Finally drive the pass manager. */
2852 timevar_pop (TV_CGRAPH
);
2856 #include "gt-cgraphunit.h"