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 static void cgraph_expand_all_functions (void);
149 static void cgraph_mark_functions_to_output (void);
150 static void cgraph_expand_function (struct cgraph_node *);
151 static void cgraph_output_pending_asms (void);
152 static void tree_rest_of_compilation (struct cgraph_node *);
154 FILE *cgraph_dump_file;
156 /* Used for vtable lookup in thunk adjusting. */
157 static GTY (()) tree vtable_entry_type;
159 /* Determine if function DECL is needed. That is, visible to something
160 either outside this translation unit, something magic in the system
164 cgraph_decide_is_function_needed (struct cgraph_node *node, tree decl)
166 /* If the user told us it is used, then it must be so. */
167 if (node->symbol.externally_visible)
170 /* ??? If the assembler name is set by hand, it is possible to assemble
171 the name later after finalizing the function and the fact is noticed
172 in assemble_name then. This is arguably a bug. */
173 if (DECL_ASSEMBLER_NAME_SET_P (decl)
174 && (!node->thunk.thunk_p && !node->same_body_alias)
175 && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
178 /* With -fkeep-inline-functions we are keeping all inline functions except
179 for extern inline ones. */
180 if (flag_keep_inline_functions
181 && DECL_DECLARED_INLINE_P (decl)
182 && !DECL_EXTERNAL (decl)
183 && !DECL_DISREGARD_INLINE_LIMITS (decl))
186 /* If we decided it was needed before, but at the time we didn't have
187 the body of the function available, then it's still needed. We have
188 to go back and re-check its dependencies now. */
192 /* Externally visible functions must be output. The exception is
193 COMDAT functions that must be output only when they are needed.
195 When not optimizing, also output the static functions. (see
196 PR24561), but don't do so for always_inline functions, functions
197 declared inline and nested functions. These were optimized out
198 in the original implementation and it is unclear whether we want
199 to change the behavior here. */
200 if (((TREE_PUBLIC (decl)
202 && !node->same_body_alias
203 && !DECL_DISREGARD_INLINE_LIMITS (decl)
204 && !DECL_DECLARED_INLINE_P (decl)
205 && !(DECL_CONTEXT (decl)
206 && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL)))
207 && !flag_whole_program
209 && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
215 /* Process CGRAPH_NEW_FUNCTIONS and perform actions necessary to add these
216 functions into callgraph in a way so they look like ordinary reachable
217 functions inserted into callgraph already at construction time. */
220 cgraph_process_new_functions (void)
224 struct cgraph_node *node;
226 varpool_analyze_pending_decls ();
227 /* Note that this queue may grow as its being processed, as the new
228 functions may generate new ones. */
229 while (cgraph_new_nodes)
231 node = cgraph_new_nodes;
232 fndecl = node->symbol.decl;
233 cgraph_new_nodes = cgraph_new_nodes->next_needed;
234 switch (cgraph_state)
236 case CGRAPH_STATE_CONSTRUCTION:
237 /* At construction time we just need to finalize function and move
238 it into reachable functions list. */
240 node->next_needed = NULL;
241 cgraph_finalize_function (fndecl, false);
242 cgraph_mark_reachable_node (node);
244 cgraph_call_function_insertion_hooks (node);
247 case CGRAPH_STATE_IPA:
248 case CGRAPH_STATE_IPA_SSA:
249 /* When IPA optimization already started, do all essential
250 transformations that has been already performed on the whole
251 cgraph but not on this function. */
253 gimple_register_cfg_hooks ();
255 cgraph_analyze_function (node);
256 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
257 current_function_decl = fndecl;
258 if ((cgraph_state == CGRAPH_STATE_IPA_SSA
259 && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
260 /* When not optimizing, be sure we run early local passes anyway
263 execute_pass_list (pass_early_local_passes.pass.sub);
265 compute_inline_parameters (node, true);
266 free_dominance_info (CDI_POST_DOMINATORS);
267 free_dominance_info (CDI_DOMINATORS);
269 current_function_decl = NULL;
270 cgraph_call_function_insertion_hooks (node);
273 case CGRAPH_STATE_EXPANSION:
274 /* Functions created during expansion shall be compiled
277 cgraph_call_function_insertion_hooks (node);
278 cgraph_expand_function (node);
285 varpool_analyze_pending_decls ();
290 /* As an GCC extension we allow redefinition of the function. The
291 semantics when both copies of bodies differ is not well defined.
292 We replace the old body with new body so in unit at a time mode
293 we always use new body, while in normal mode we may end up with
294 old body inlined into some functions and new body expanded and
297 ??? It may make more sense to use one body for inlining and other
298 body for expanding the function but this is difficult to do. */
301 cgraph_reset_node (struct cgraph_node *node)
303 /* If node->process is set, then we have already begun whole-unit analysis.
304 This is *not* testing for whether we've already emitted the function.
305 That case can be sort-of legitimately seen with real function redefinition
306 errors. I would argue that the front end should never present us with
307 such a case, but don't enforce that for now. */
308 gcc_assert (!node->process);
310 /* Reset our data structures so we can analyze the function again. */
311 memset (&node->local, 0, sizeof (node->local));
312 memset (&node->global, 0, sizeof (node->global));
313 memset (&node->rtl, 0, sizeof (node->rtl));
314 node->analyzed = false;
315 node->local.finalized = false;
317 cgraph_node_remove_callees (node);
320 /* DECL has been parsed. Take it, queue it, compile it at the whim of the
321 logic in effect. If NESTED is true, then our caller cannot stand to have
322 the garbage collector run at the moment. We would need to either create
323 a new GC context, or just not compile right now. */
326 cgraph_finalize_function (tree decl, bool nested)
328 struct cgraph_node *node = cgraph_get_create_node (decl);
330 if (node->local.finalized)
332 cgraph_reset_node (node);
333 node->local.redefined_extern_inline = true;
336 notice_global_symbol (decl);
337 node->local.finalized = true;
338 node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL;
340 if (cgraph_decide_is_function_needed (node, decl))
341 cgraph_mark_needed_node (node);
343 /* Since we reclaim unreachable nodes at the end of every language
344 level unit, we need to be conservative about possible entry points
346 if ((TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
347 || DECL_STATIC_CONSTRUCTOR (decl)
348 || DECL_STATIC_DESTRUCTOR (decl)
349 /* COMDAT virtual functions may be referenced by vtable from
350 other compilation unit. Still we want to devirtualize calls
351 to those so we need to analyze them.
352 FIXME: We should introduce may edges for this purpose and update
353 their handling in unreachable function removal and inliner too. */
354 || (DECL_VIRTUAL_P (decl)
355 && optimize && (DECL_COMDAT (decl) || DECL_EXTERNAL (decl))))
356 cgraph_mark_reachable_node (node);
358 /* If we've not yet emitted decl, tell the debug info about it. */
359 if (!TREE_ASM_WRITTEN (decl))
360 (*debug_hooks->deferred_inline_function) (decl);
362 /* Possibly warn about unused parameters. */
363 if (warn_unused_parameter)
364 do_warn_unused_parameter (decl);
370 /* Add the function FNDECL to the call graph.
371 Unlike cgraph_finalize_function, this function is intended to be used
372 by middle end and allows insertion of new function at arbitrary point
373 of compilation. The function can be either in high, low or SSA form
376 The function is assumed to be reachable and have address taken (so no
377 API breaking optimizations are performed on it).
379 Main work done by this function is to enqueue the function for later
380 processing to avoid need the passes to be re-entrant. */
383 cgraph_add_new_function (tree fndecl, bool lowered)
385 struct cgraph_node *node;
386 switch (cgraph_state)
388 case CGRAPH_STATE_CONSTRUCTION:
389 /* Just enqueue function to be processed at nearest occurrence. */
390 node = cgraph_create_node (fndecl);
391 node->next_needed = cgraph_new_nodes;
393 node->lowered = true;
394 cgraph_new_nodes = node;
397 case CGRAPH_STATE_IPA:
398 case CGRAPH_STATE_IPA_SSA:
399 case CGRAPH_STATE_EXPANSION:
400 /* Bring the function into finalized state and enqueue for later
401 analyzing and compilation. */
402 node = cgraph_get_create_node (fndecl);
403 node->local.local = false;
404 node->local.finalized = true;
405 node->reachable = node->needed = true;
406 if (!lowered && cgraph_state == CGRAPH_STATE_EXPANSION)
408 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
409 current_function_decl = fndecl;
410 gimple_register_cfg_hooks ();
411 bitmap_obstack_initialize (NULL);
412 execute_pass_list (all_lowering_passes);
413 execute_pass_list (pass_early_local_passes.pass.sub);
414 bitmap_obstack_release (NULL);
416 current_function_decl = NULL;
421 node->lowered = true;
422 node->next_needed = cgraph_new_nodes;
423 cgraph_new_nodes = node;
426 case CGRAPH_STATE_FINISHED:
427 /* At the very end of compilation we have to do all the work up
429 node = cgraph_create_node (fndecl);
431 node->lowered = true;
432 cgraph_analyze_function (node);
433 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
434 current_function_decl = fndecl;
435 gimple_register_cfg_hooks ();
436 bitmap_obstack_initialize (NULL);
437 if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
438 execute_pass_list (pass_early_local_passes.pass.sub);
439 bitmap_obstack_release (NULL);
440 tree_rest_of_compilation (node);
442 current_function_decl = NULL;
449 /* Set a personality if required and we already passed EH lowering. */
451 && (function_needs_eh_personality (DECL_STRUCT_FUNCTION (fndecl))
452 == eh_personality_lang))
453 DECL_FUNCTION_PERSONALITY (fndecl) = lang_hooks.eh_personality ();
456 /* C99 extern inline keywords allow changing of declaration after function
457 has been finalized. We need to re-decide if we want to mark the function as
461 cgraph_mark_if_needed (tree decl)
463 struct cgraph_node *node = cgraph_get_node (decl);
464 if (node->local.finalized && cgraph_decide_is_function_needed (node, decl))
465 cgraph_mark_needed_node (node);
468 /* Return TRUE if NODE2 is equivalent to NODE or its clone. */
470 clone_of_p (struct cgraph_node *node, struct cgraph_node *node2)
472 node = cgraph_function_or_thunk_node (node, NULL);
473 node2 = cgraph_function_or_thunk_node (node2, NULL);
474 while (node != node2 && node2)
475 node2 = node2->clone_of;
476 return node2 != NULL;
479 /* Verify edge E count and frequency. */
482 verify_edge_count_and_frequency (struct cgraph_edge *e)
484 bool error_found = false;
487 error ("caller edge count is negative");
490 if (e->frequency < 0)
492 error ("caller edge frequency is negative");
495 if (e->frequency > CGRAPH_FREQ_MAX)
497 error ("caller edge frequency is too large");
500 if (gimple_has_body_p (e->caller->symbol.decl)
501 && !e->caller->global.inlined_to
502 /* FIXME: Inline-analysis sets frequency to 0 when edge is optimized out.
503 Remove this once edges are actualy removed from the function at that time. */
505 || (inline_edge_summary_vec
506 && ((VEC_length(inline_edge_summary_t, inline_edge_summary_vec)
507 <= (unsigned) e->uid)
508 || !inline_edge_summary (e)->predicate)))
510 != compute_call_stmt_bb_frequency (e->caller->symbol.decl,
511 gimple_bb (e->call_stmt))))
513 error ("caller edge frequency %i does not match BB frequency %i",
515 compute_call_stmt_bb_frequency (e->caller->symbol.decl,
516 gimple_bb (e->call_stmt)));
522 /* Switch to THIS_CFUN if needed and print STMT to stderr. */
524 cgraph_debug_gimple_stmt (struct function *this_cfun, gimple stmt)
526 /* debug_gimple_stmt needs correct cfun */
527 if (cfun != this_cfun)
528 set_cfun (this_cfun);
529 debug_gimple_stmt (stmt);
532 /* Verify that call graph edge E corresponds to DECL from the associated
533 statement. Return true if the verification should fail. */
536 verify_edge_corresponds_to_fndecl (struct cgraph_edge *e, tree decl)
538 struct cgraph_node *node;
540 if (!decl || e->callee->global.inlined_to)
542 node = cgraph_get_node (decl);
544 /* We do not know if a node from a different partition is an alias or what it
545 aliases and therefore cannot do the former_clone_of check reliably. */
546 if (!node || node->symbol.in_other_partition)
548 node = cgraph_function_or_thunk_node (node, NULL);
550 if ((e->callee->former_clone_of != node->symbol.decl
551 && (!node->same_body_alias
552 || e->callee->former_clone_of != node->thunk.alias))
553 /* IPA-CP sometimes redirect edge to clone and then back to the former
554 function. This ping-pong has to go, eventually. */
555 && (node != cgraph_function_or_thunk_node (e->callee, NULL))
556 && !clone_of_p (node, e->callee)
557 /* If decl is a same body alias of some other decl, allow e->callee to be
558 a clone of a clone of that other decl too. */
559 && (!node->same_body_alias
560 || !clone_of_p (cgraph_get_node (node->thunk.alias), e->callee)))
566 /* Verify cgraph nodes of given cgraph node. */
568 verify_cgraph_node (struct cgraph_node *node)
570 struct cgraph_edge *e;
571 struct function *this_cfun = DECL_STRUCT_FUNCTION (node->symbol.decl);
572 basic_block this_block;
573 gimple_stmt_iterator gsi;
574 bool error_found = false;
579 timevar_push (TV_CGRAPH_VERIFY);
580 for (e = node->callees; e; e = e->next_callee)
583 error ("aux field set for edge %s->%s",
584 identifier_to_locale (cgraph_node_name (e->caller)),
585 identifier_to_locale (cgraph_node_name (e->callee)));
590 error ("execution count is negative");
593 if (node->global.inlined_to && node->symbol.externally_visible)
595 error ("externally visible inline clone");
598 if (node->global.inlined_to && node->symbol.address_taken)
600 error ("inline clone with address taken");
603 if (node->global.inlined_to && node->needed)
605 error ("inline clone is needed");
608 for (e = node->indirect_calls; e; e = e->next_callee)
612 error ("aux field set for indirect edge from %s",
613 identifier_to_locale (cgraph_node_name (e->caller)));
616 if (!e->indirect_unknown_callee
617 || !e->indirect_info)
619 error ("An indirect edge from %s is not marked as indirect or has "
620 "associated indirect_info, the corresponding statement is: ",
621 identifier_to_locale (cgraph_node_name (e->caller)));
622 cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
626 for (e = node->callers; e; e = e->next_caller)
628 if (verify_edge_count_and_frequency (e))
630 if (!e->inline_failed)
632 if (node->global.inlined_to
633 != (e->caller->global.inlined_to
634 ? e->caller->global.inlined_to : e->caller))
636 error ("inlined_to pointer is wrong");
639 if (node->callers->next_caller)
641 error ("multiple inline callers");
646 if (node->global.inlined_to)
648 error ("inlined_to pointer set for noninline callers");
652 for (e = node->indirect_calls; e; e = e->next_callee)
653 if (verify_edge_count_and_frequency (e))
655 if (!node->callers && node->global.inlined_to)
657 error ("inlined_to pointer is set but no predecessors found");
660 if (node->global.inlined_to == node)
662 error ("inlined_to pointer refers to itself");
666 if (!cgraph_get_node (node->symbol.decl))
668 error ("node not found in cgraph_hash");
674 struct cgraph_node *n;
675 for (n = node->clone_of->clones; n; n = n->next_sibling_clone)
680 error ("node has wrong clone_of");
686 struct cgraph_node *n;
687 for (n = node->clones; n; n = n->next_sibling_clone)
688 if (n->clone_of != node)
692 error ("node has wrong clone list");
696 if ((node->prev_sibling_clone || node->next_sibling_clone) && !node->clone_of)
698 error ("node is in clone list but it is not clone");
701 if (!node->prev_sibling_clone && node->clone_of && node->clone_of->clones != node)
703 error ("node has wrong prev_clone pointer");
706 if (node->prev_sibling_clone && node->prev_sibling_clone->next_sibling_clone != node)
708 error ("double linked list of clones corrupted");
711 if (node->symbol.same_comdat_group)
713 symtab_node n = node->symbol.same_comdat_group;
715 if (!DECL_ONE_ONLY (n->symbol.decl))
717 error ("non-DECL_ONE_ONLY node in a same_comdat_group list");
720 if (n == (symtab_node)node)
722 error ("node is alone in a comdat group");
727 if (!n->symbol.same_comdat_group)
729 error ("same_comdat_group is not a circular list");
733 n = n->symbol.same_comdat_group;
735 while (n != (symtab_node)node);
738 if (node->analyzed && node->alias)
740 bool ref_found = false;
746 error ("Alias has call edges");
749 for (i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list,
751 if (ref->use != IPA_REF_ALIAS)
753 error ("Alias has non-alias reference");
758 error ("Alias has more than one alias reference");
765 error ("Analyzed alias has no reference");
769 if (node->analyzed && node->thunk.thunk_p)
773 error ("No edge out of thunk node");
776 else if (node->callees->next_callee)
778 error ("More than one edge out of thunk node");
781 if (gimple_has_body_p (node->symbol.decl))
783 error ("Thunk is not supposed to have body");
787 else if (node->analyzed && gimple_has_body_p (node->symbol.decl)
788 && !TREE_ASM_WRITTEN (node->symbol.decl)
789 && (!DECL_EXTERNAL (node->symbol.decl) || node->global.inlined_to)
794 /* The nodes we're interested in are never shared, so walk
795 the tree ignoring duplicates. */
796 struct pointer_set_t *visited_nodes = pointer_set_create ();
797 /* Reach the trees by walking over the CFG, and note the
798 enclosing basic-blocks in the call edges. */
799 FOR_EACH_BB_FN (this_block, this_cfun)
800 for (gsi = gsi_start_bb (this_block);
804 gimple stmt = gsi_stmt (gsi);
805 if (is_gimple_call (stmt))
807 struct cgraph_edge *e = cgraph_edge (node, stmt);
808 tree decl = gimple_call_fndecl (stmt);
813 error ("shared call_stmt:");
814 cgraph_debug_gimple_stmt (this_cfun, stmt);
817 if (!e->indirect_unknown_callee)
819 if (verify_edge_corresponds_to_fndecl (e, decl))
821 error ("edge points to wrong declaration:");
822 debug_tree (e->callee->symbol.decl);
823 fprintf (stderr," Instead of:");
830 error ("an indirect edge with unknown callee "
831 "corresponding to a call_stmt with "
832 "a known declaration:");
834 cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
840 error ("missing callgraph edge for call stmt:");
841 cgraph_debug_gimple_stmt (this_cfun, stmt);
846 pointer_set_destroy (visited_nodes);
849 /* No CFG available?! */
852 for (e = node->callees; e; e = e->next_callee)
856 error ("edge %s->%s has no corresponding call_stmt",
857 identifier_to_locale (cgraph_node_name (e->caller)),
858 identifier_to_locale (cgraph_node_name (e->callee)));
859 cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
864 for (e = node->indirect_calls; e; e = e->next_callee)
868 error ("an indirect edge from %s has no corresponding call_stmt",
869 identifier_to_locale (cgraph_node_name (e->caller)));
870 cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
878 dump_cgraph_node (stderr, node);
879 internal_error ("verify_cgraph_node failed");
881 timevar_pop (TV_CGRAPH_VERIFY);
884 /* Verify whole cgraph structure. */
888 struct cgraph_node *node;
893 FOR_EACH_FUNCTION (node)
894 verify_cgraph_node (node);
897 /* Output all asm statements we have stored up to be output. */
900 cgraph_output_pending_asms (void)
902 struct cgraph_asm_node *can;
907 for (can = cgraph_asm_nodes; can; can = can->next)
908 assemble_asm (can->asm_str);
909 cgraph_asm_nodes = NULL;
912 /* Analyze the function scheduled to be output. */
914 cgraph_analyze_function (struct cgraph_node *node)
916 tree save = current_function_decl;
917 tree decl = node->symbol.decl;
919 if (node->alias && node->thunk.alias)
921 struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias);
922 struct cgraph_node *n;
924 for (n = tgt; n && n->alias;
925 n = n->analyzed ? cgraph_alias_aliased_node (n) : NULL)
928 error ("function %q+D part of alias cycle", node->symbol.decl);
932 if (!VEC_length (ipa_ref_t, node->symbol.ref_list.references))
933 ipa_record_reference (node, NULL, tgt, NULL, IPA_REF_ALIAS, NULL);
934 if (node->same_body_alias)
936 DECL_VIRTUAL_P (node->symbol.decl) = DECL_VIRTUAL_P (node->thunk.alias);
937 DECL_DECLARED_INLINE_P (node->symbol.decl)
938 = DECL_DECLARED_INLINE_P (node->thunk.alias);
939 DECL_DISREGARD_INLINE_LIMITS (node->symbol.decl)
940 = DECL_DISREGARD_INLINE_LIMITS (node->thunk.alias);
943 /* Fixup visibility nonsences C++ frontend produce on same body aliases. */
944 if (TREE_PUBLIC (node->symbol.decl) && node->same_body_alias)
946 DECL_EXTERNAL (node->symbol.decl) = DECL_EXTERNAL (node->thunk.alias);
947 if (DECL_ONE_ONLY (node->thunk.alias))
949 DECL_COMDAT (node->symbol.decl) = DECL_COMDAT (node->thunk.alias);
950 DECL_COMDAT_GROUP (node->symbol.decl) = DECL_COMDAT_GROUP (node->thunk.alias);
951 if (DECL_ONE_ONLY (node->thunk.alias) && !node->symbol.same_comdat_group)
953 struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias);
954 node->symbol.same_comdat_group = (symtab_node)tgt;
955 if (!tgt->symbol.same_comdat_group)
956 tgt->symbol.same_comdat_group = (symtab_node)node;
960 for (n = tgt->symbol.same_comdat_group;
961 n->symbol.same_comdat_group != (symtab_node)tgt;
962 n = n->symbol.same_comdat_group)
964 n->symbol.same_comdat_group = (symtab_node)node;
969 cgraph_mark_reachable_node (cgraph_alias_aliased_node (node));
970 if (node->symbol.address_taken)
971 cgraph_mark_address_taken_node (cgraph_alias_aliased_node (node));
972 if (cgraph_decide_is_function_needed (node, node->symbol.decl))
973 cgraph_mark_needed_node (node);
975 else if (node->thunk.thunk_p)
977 cgraph_create_edge (node, cgraph_get_node (node->thunk.alias),
978 NULL, 0, CGRAPH_FREQ_BASE);
982 current_function_decl = decl;
983 push_cfun (DECL_STRUCT_FUNCTION (decl));
985 assign_assembler_name_if_neeeded (node->symbol.decl);
987 /* Make sure to gimplify bodies only once. During analyzing a
988 function we lower it, which will require gimplified nested
989 functions, so we can end up here with an already gimplified
991 if (!gimple_body (decl))
992 gimplify_function_tree (decl);
993 dump_function (TDI_generic, decl);
995 /* Lower the function. */
999 lower_nested_functions (node->symbol.decl);
1000 gcc_assert (!node->nested);
1002 gimple_register_cfg_hooks ();
1003 bitmap_obstack_initialize (NULL);
1004 execute_pass_list (all_lowering_passes);
1005 free_dominance_info (CDI_POST_DOMINATORS);
1006 free_dominance_info (CDI_DOMINATORS);
1008 bitmap_obstack_release (NULL);
1009 node->lowered = true;
1014 node->analyzed = true;
1016 current_function_decl = save;
1019 /* C++ frontend produce same body aliases all over the place, even before PCH
1020 gets streamed out. It relies on us linking the aliases with their function
1021 in order to do the fixups, but ipa-ref is not PCH safe. Consequentely we
1022 first produce aliases without links, but once C++ FE is sure he won't sream
1023 PCH we build the links via this function. */
1026 cgraph_process_same_body_aliases (void)
1028 struct cgraph_node *node;
1029 FOR_EACH_FUNCTION (node)
1030 if (node->same_body_alias
1031 && !VEC_length (ipa_ref_t, node->symbol.ref_list.references))
1033 struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias);
1034 ipa_record_reference (node, NULL, tgt, NULL, IPA_REF_ALIAS, NULL);
1036 same_body_aliases_done = true;
1039 /* Process attributes common for vars and functions. */
1042 process_common_attributes (tree decl)
1044 tree weakref = lookup_attribute ("weakref", DECL_ATTRIBUTES (decl));
1046 if (weakref && !lookup_attribute ("alias", DECL_ATTRIBUTES (decl)))
1048 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
1049 "%<weakref%> attribute should be accompanied with"
1050 " an %<alias%> attribute");
1051 DECL_WEAK (decl) = 0;
1052 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
1053 DECL_ATTRIBUTES (decl));
1057 /* Look for externally_visible and used attributes and mark cgraph nodes
1060 We cannot mark the nodes at the point the attributes are processed (in
1061 handle_*_attribute) because the copy of the declarations available at that
1062 point may not be canonical. For example, in:
1065 void f() __attribute__((used));
1067 the declaration we see in handle_used_attribute will be the second
1068 declaration -- but the front end will subsequently merge that declaration
1069 with the original declaration and discard the second declaration.
1071 Furthermore, we can't mark these nodes in cgraph_finalize_function because:
1074 void f() __attribute__((externally_visible));
1078 So, we walk the nodes at the end of the translation unit, applying the
1079 attributes at that point. */
1082 process_function_and_variable_attributes (struct cgraph_node *first,
1083 struct varpool_node *first_var)
1085 struct cgraph_node *node;
1086 struct varpool_node *vnode;
1088 for (node = cgraph_first_function (); node != first;
1089 node = cgraph_next_function (node))
1091 tree decl = node->symbol.decl;
1092 if (DECL_PRESERVE_P (decl))
1093 cgraph_mark_needed_node (node);
1094 if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
1095 && lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl))
1096 && TREE_PUBLIC (node->symbol.decl))
1098 if (node->local.finalized)
1099 cgraph_mark_needed_node (node);
1101 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
1103 if (! TREE_PUBLIC (node->symbol.decl))
1104 warning_at (DECL_SOURCE_LOCATION (node->symbol.decl), OPT_Wattributes,
1105 "%<externally_visible%>"
1106 " attribute have effect only on public objects");
1107 else if (node->local.finalized)
1108 cgraph_mark_needed_node (node);
1110 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
1111 && (node->local.finalized && !node->alias))
1113 warning_at (DECL_SOURCE_LOCATION (node->symbol.decl), OPT_Wattributes,
1114 "%<weakref%> attribute ignored"
1115 " because function is defined");
1116 DECL_WEAK (decl) = 0;
1117 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
1118 DECL_ATTRIBUTES (decl));
1121 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl))
1122 && !DECL_DECLARED_INLINE_P (decl)
1123 /* redefining extern inline function makes it DECL_UNINLINABLE. */
1124 && !DECL_UNINLINABLE (decl))
1125 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
1126 "always_inline function might not be inlinable");
1128 process_common_attributes (decl);
1130 for (vnode = varpool_first_variable (); vnode != first_var;
1131 vnode = varpool_next_variable (vnode))
1133 tree decl = vnode->symbol.decl;
1134 if (DECL_PRESERVE_P (decl))
1136 vnode->force_output = true;
1137 if (vnode->finalized)
1138 varpool_mark_needed_node (vnode);
1140 if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
1141 && lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl))
1142 && TREE_PUBLIC (vnode->symbol.decl))
1144 if (vnode->finalized)
1145 varpool_mark_needed_node (vnode);
1147 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
1149 if (! TREE_PUBLIC (vnode->symbol.decl))
1150 warning_at (DECL_SOURCE_LOCATION (vnode->symbol.decl), OPT_Wattributes,
1151 "%<externally_visible%>"
1152 " attribute have effect only on public objects");
1153 else if (vnode->finalized)
1154 varpool_mark_needed_node (vnode);
1156 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
1158 && DECL_INITIAL (decl))
1160 warning_at (DECL_SOURCE_LOCATION (vnode->symbol.decl), OPT_Wattributes,
1161 "%<weakref%> attribute ignored"
1162 " because variable is initialized");
1163 DECL_WEAK (decl) = 0;
1164 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
1165 DECL_ATTRIBUTES (decl));
1167 process_common_attributes (decl);
1171 /* Process CGRAPH_NODES_NEEDED queue, analyze each function (and transitively
1172 each reachable functions) and build cgraph.
1173 The function can be called multiple times after inserting new nodes
1174 into beginning of queue. Just the new part of queue is re-scanned then. */
1177 cgraph_analyze_functions (void)
1179 /* Keep track of already processed nodes when called multiple times for
1180 intermodule optimization. */
1181 static struct cgraph_node *first_analyzed;
1182 struct cgraph_node *first_processed = first_analyzed;
1183 static struct varpool_node *first_analyzed_var;
1184 struct cgraph_node *node, *next;
1186 bitmap_obstack_initialize (NULL);
1187 process_function_and_variable_attributes (first_processed,
1188 first_analyzed_var);
1189 first_processed = cgraph_first_function ();
1190 first_analyzed_var = varpool_first_variable ();
1191 varpool_analyze_pending_decls ();
1192 if (cgraph_dump_file)
1194 fprintf (cgraph_dump_file, "Initial entry points:");
1195 for (node = cgraph_first_function (); node != first_analyzed;
1196 node = cgraph_next_function (node))
1198 fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
1199 fprintf (cgraph_dump_file, "\n");
1201 cgraph_process_new_functions ();
1203 /* Propagate reachability flag and lower representation of all reachable
1204 functions. In the future, lowering will introduce new functions and
1205 new entry points on the way (by template instantiation and virtual
1206 method table generation for instance). */
1207 while (cgraph_nodes_queue)
1209 struct cgraph_edge *edge;
1210 tree decl = cgraph_nodes_queue->symbol.decl;
1212 node = cgraph_nodes_queue;
1213 x_cgraph_nodes_queue = (symtab_node)cgraph_nodes_queue->next_needed;
1214 node->next_needed = NULL;
1216 /* ??? It is possible to create extern inline function and later using
1217 weak alias attribute to kill its body. See
1218 gcc.c-torture/compile/20011119-1.c */
1219 if (!DECL_STRUCT_FUNCTION (decl)
1220 && (!node->alias || !node->thunk.alias)
1221 && !node->thunk.thunk_p)
1223 cgraph_reset_node (node);
1224 node->local.redefined_extern_inline = true;
1228 if (!node->analyzed)
1229 cgraph_analyze_function (node);
1231 for (edge = node->callees; edge; edge = edge->next_callee)
1232 if (!edge->callee->reachable)
1233 cgraph_mark_reachable_node (edge->callee);
1234 for (edge = node->callers; edge; edge = edge->next_caller)
1235 if (!edge->caller->reachable && edge->caller->thunk.thunk_p)
1236 cgraph_mark_reachable_node (edge->caller);
1238 if (node->symbol.same_comdat_group)
1240 for (next = cgraph (node->symbol.same_comdat_group);
1242 next = cgraph (next->symbol.same_comdat_group))
1243 cgraph_mark_reachable_node (next);
1246 /* If decl is a clone of an abstract function, mark that abstract
1247 function so that we don't release its body. The DECL_INITIAL() of that
1248 abstract function declaration will be later needed to output debug
1250 if (DECL_ABSTRACT_ORIGIN (decl))
1252 struct cgraph_node *origin_node;
1253 origin_node = cgraph_get_node (DECL_ABSTRACT_ORIGIN (decl));
1254 origin_node->abstract_and_needed = true;
1257 /* We finalize local static variables during constructing callgraph
1258 edges. Process their attributes too. */
1259 process_function_and_variable_attributes (first_processed,
1260 first_analyzed_var);
1261 first_processed = cgraph_first_function ();
1262 first_analyzed_var = varpool_first_variable ();
1263 varpool_analyze_pending_decls ();
1264 cgraph_process_new_functions ();
1267 /* Collect entry points to the unit. */
1268 if (cgraph_dump_file)
1270 fprintf (cgraph_dump_file, "Unit entry points:");
1271 for (node = cgraph_first_function (); node != first_analyzed;
1272 node = cgraph_next_function (node))
1274 fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
1275 fprintf (cgraph_dump_file, "\n\nInitial ");
1276 dump_symtab (cgraph_dump_file);
1279 if (cgraph_dump_file)
1280 fprintf (cgraph_dump_file, "\nReclaiming functions:");
1282 for (node = cgraph_first_function (); node != first_analyzed;
1285 tree decl = node->symbol.decl;
1286 next = cgraph_next_function (node);
1288 if (node->local.finalized && !gimple_has_body_p (decl)
1289 && (!node->alias || !node->thunk.alias)
1290 && !node->thunk.thunk_p)
1291 cgraph_reset_node (node);
1293 if (!node->reachable
1294 && (gimple_has_body_p (decl) || node->thunk.thunk_p
1295 || (node->alias && node->thunk.alias)))
1297 if (cgraph_dump_file)
1298 fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
1299 cgraph_remove_node (node);
1303 node->next_needed = NULL;
1304 gcc_assert (!node->local.finalized || node->thunk.thunk_p
1306 || gimple_has_body_p (decl));
1307 gcc_assert (node->analyzed == node->local.finalized);
1309 if (cgraph_dump_file)
1311 fprintf (cgraph_dump_file, "\n\nReclaimed ");
1312 dump_symtab (cgraph_dump_file);
1314 bitmap_obstack_release (NULL);
1315 first_analyzed = cgraph_first_function ();
1319 /* Translate the ugly representation of aliases as alias pairs into nice
1320 representation in callgraph. We don't handle all cases yet,
1324 handle_alias_pairs (void)
1328 struct cgraph_node *target_node;
1329 struct cgraph_node *src_node;
1330 struct varpool_node *target_vnode;
1332 for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p);)
1334 if (TREE_CODE (p->decl) == FUNCTION_DECL
1335 && (target_node = cgraph_node_for_asm (p->target)) != NULL)
1337 src_node = cgraph_get_node (p->decl);
1338 if (src_node && src_node->local.finalized)
1339 cgraph_reset_node (src_node);
1340 /* Normally EXTERNAL flag is used to mark external inlines,
1341 however for aliases it seems to be allowed to use it w/o
1342 any meaning. See gcc.dg/attr-alias-3.c
1343 However for weakref we insist on EXTERNAL flag being set.
1344 See gcc.dg/attr-alias-5.c */
1345 if (DECL_EXTERNAL (p->decl))
1346 DECL_EXTERNAL (p->decl)
1347 = lookup_attribute ("weakref",
1348 DECL_ATTRIBUTES (p->decl)) != NULL;
1349 cgraph_create_function_alias (p->decl, target_node->symbol.decl);
1350 VEC_unordered_remove (alias_pair, alias_pairs, i);
1352 else if (TREE_CODE (p->decl) == VAR_DECL
1353 && (target_vnode = varpool_node_for_asm (p->target)) != NULL)
1355 /* Normally EXTERNAL flag is used to mark external inlines,
1356 however for aliases it seems to be allowed to use it w/o
1357 any meaning. See gcc.dg/attr-alias-3.c
1358 However for weakref we insist on EXTERNAL flag being set.
1359 See gcc.dg/attr-alias-5.c */
1360 if (DECL_EXTERNAL (p->decl))
1361 DECL_EXTERNAL (p->decl)
1362 = lookup_attribute ("weakref",
1363 DECL_ATTRIBUTES (p->decl)) != NULL;
1364 varpool_create_variable_alias (p->decl, target_vnode->symbol.decl);
1365 VEC_unordered_remove (alias_pair, alias_pairs, i);
1367 /* Weakrefs with target not defined in current unit are easy to handle; they
1368 behave just as external variables except we need to note the alias flag
1369 to later output the weakref pseudo op into asm file. */
1370 else if (lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL
1371 && (TREE_CODE (p->decl) == FUNCTION_DECL
1372 ? (varpool_node_for_asm (p->target) == NULL)
1373 : (cgraph_node_for_asm (p->target) == NULL)))
1375 if (TREE_CODE (p->decl) == FUNCTION_DECL)
1376 cgraph_get_create_node (p->decl)->alias = true;
1378 varpool_get_node (p->decl)->alias = true;
1379 DECL_EXTERNAL (p->decl) = 1;
1380 VEC_unordered_remove (alias_pair, alias_pairs, i);
1385 fprintf (dump_file, "Unhandled alias %s->%s\n",
1386 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (p->decl)),
1387 IDENTIFIER_POINTER (p->target));
1395 /* Figure out what functions we want to assemble. */
1398 cgraph_mark_functions_to_output (void)
1400 struct cgraph_node *node;
1401 #ifdef ENABLE_CHECKING
1402 bool check_same_comdat_groups = false;
1404 FOR_EACH_FUNCTION (node)
1405 gcc_assert (!node->process);
1408 FOR_EACH_FUNCTION (node)
1410 tree decl = node->symbol.decl;
1411 struct cgraph_edge *e;
1413 gcc_assert (!node->process || node->symbol.same_comdat_group);
1417 for (e = node->callers; e; e = e->next_caller)
1418 if (e->inline_failed)
1421 /* We need to output all local functions that are used and not
1422 always inlined, as well as those that are reachable from
1423 outside the current compilation unit. */
1425 && !node->thunk.thunk_p
1427 && !node->global.inlined_to
1428 && (!cgraph_only_called_directly_p (node)
1429 || ((e || ipa_ref_has_aliases_p (&node->symbol.ref_list))
1430 && node->reachable))
1431 && !TREE_ASM_WRITTEN (decl)
1432 && !DECL_EXTERNAL (decl))
1435 if (node->symbol.same_comdat_group)
1437 struct cgraph_node *next;
1438 for (next = cgraph (node->symbol.same_comdat_group);
1440 next = cgraph (next->symbol.same_comdat_group))
1441 if (!next->thunk.thunk_p && !next->alias)
1445 else if (node->symbol.same_comdat_group)
1447 #ifdef ENABLE_CHECKING
1448 check_same_comdat_groups = true;
1453 /* We should've reclaimed all functions that are not needed. */
1454 #ifdef ENABLE_CHECKING
1455 if (!node->global.inlined_to
1456 && gimple_has_body_p (decl)
1457 /* FIXME: in ltrans unit when offline copy is outside partition but inline copies
1458 are inside partition, we can end up not removing the body since we no longer
1459 have analyzed node pointing to it. */
1460 && !node->symbol.in_other_partition
1462 && !DECL_EXTERNAL (decl))
1464 dump_cgraph_node (stderr, node);
1465 internal_error ("failed to reclaim unneeded function");
1468 gcc_assert (node->global.inlined_to
1469 || !gimple_has_body_p (decl)
1470 || node->symbol.in_other_partition
1471 || DECL_EXTERNAL (decl));
1476 #ifdef ENABLE_CHECKING
1477 if (check_same_comdat_groups)
1478 FOR_EACH_FUNCTION (node)
1479 if (node->symbol.same_comdat_group && !node->process)
1481 tree decl = node->symbol.decl;
1482 if (!node->global.inlined_to
1483 && gimple_has_body_p (decl)
1484 /* FIXME: in an ltrans unit when the offline copy is outside a
1485 partition but inline copies are inside a partition, we can
1486 end up not removing the body since we no longer have an
1487 analyzed node pointing to it. */
1488 && !node->symbol.in_other_partition
1489 && !DECL_EXTERNAL (decl))
1491 dump_cgraph_node (stderr, node);
1492 internal_error ("failed to reclaim unneeded function in same "
1499 /* DECL is FUNCTION_DECL. Initialize datastructures so DECL is a function
1500 in lowered gimple form.
1502 Set current_function_decl and cfun to newly constructed empty function body.
1503 return basic block in the function body. */
1506 init_lowered_empty_function (tree decl)
1510 current_function_decl = decl;
1511 allocate_struct_function (decl, false);
1512 gimple_register_cfg_hooks ();
1513 init_empty_tree_cfg ();
1514 init_tree_ssa (cfun);
1515 init_ssa_operands ();
1516 cfun->gimple_df->in_ssa_p = true;
1517 DECL_INITIAL (decl) = make_node (BLOCK);
1519 DECL_SAVED_TREE (decl) = error_mark_node;
1520 cfun->curr_properties |=
1521 (PROP_gimple_lcf | PROP_gimple_leh | PROP_cfg | PROP_referenced_vars |
1522 PROP_ssa | PROP_gimple_any);
1524 /* Create BB for body of the function and connect it properly. */
1525 bb = create_basic_block (NULL, (void *) 0, ENTRY_BLOCK_PTR);
1526 make_edge (ENTRY_BLOCK_PTR, bb, 0);
1527 make_edge (bb, EXIT_BLOCK_PTR, 0);
1532 /* Adjust PTR by the constant FIXED_OFFSET, and by the vtable
1533 offset indicated by VIRTUAL_OFFSET, if that is
1534 non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and
1535 zero for a result adjusting thunk. */
1538 thunk_adjust (gimple_stmt_iterator * bsi,
1539 tree ptr, bool this_adjusting,
1540 HOST_WIDE_INT fixed_offset, tree virtual_offset)
1546 && fixed_offset != 0)
1548 stmt = gimple_build_assign
1549 (ptr, fold_build_pointer_plus_hwi_loc (input_location,
1552 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1555 /* If there's a virtual offset, look up that value in the vtable and
1556 adjust the pointer again. */
1563 if (!vtable_entry_type)
1565 tree vfunc_type = make_node (FUNCTION_TYPE);
1566 TREE_TYPE (vfunc_type) = integer_type_node;
1567 TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
1568 layout_type (vfunc_type);
1570 vtable_entry_type = build_pointer_type (vfunc_type);
1574 create_tmp_var (build_pointer_type
1575 (build_pointer_type (vtable_entry_type)), "vptr");
1577 /* The vptr is always at offset zero in the object. */
1578 stmt = gimple_build_assign (vtabletmp,
1579 build1 (NOP_EXPR, TREE_TYPE (vtabletmp),
1581 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1582 mark_symbols_for_renaming (stmt);
1583 find_referenced_vars_in (stmt);
1585 /* Form the vtable address. */
1586 vtabletmp2 = create_tmp_var (TREE_TYPE (TREE_TYPE (vtabletmp)),
1588 stmt = gimple_build_assign (vtabletmp2,
1589 build_simple_mem_ref (vtabletmp));
1590 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1591 mark_symbols_for_renaming (stmt);
1592 find_referenced_vars_in (stmt);
1594 /* Find the entry with the vcall offset. */
1595 stmt = gimple_build_assign (vtabletmp2,
1596 fold_build_pointer_plus_loc (input_location,
1599 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1601 /* Get the offset itself. */
1602 vtabletmp3 = create_tmp_var (TREE_TYPE (TREE_TYPE (vtabletmp2)),
1604 stmt = gimple_build_assign (vtabletmp3,
1605 build_simple_mem_ref (vtabletmp2));
1606 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1607 mark_symbols_for_renaming (stmt);
1608 find_referenced_vars_in (stmt);
1610 /* Adjust the `this' pointer. */
1611 ptr = fold_build_pointer_plus_loc (input_location, ptr, vtabletmp3);
1612 ptr = force_gimple_operand_gsi (bsi, ptr, true, NULL_TREE, false,
1613 GSI_CONTINUE_LINKING);
1617 && fixed_offset != 0)
1618 /* Adjust the pointer by the constant. */
1622 if (TREE_CODE (ptr) == VAR_DECL)
1626 ptrtmp = create_tmp_var (TREE_TYPE (ptr), "ptr");
1627 stmt = gimple_build_assign (ptrtmp, ptr);
1628 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1629 mark_symbols_for_renaming (stmt);
1630 find_referenced_vars_in (stmt);
1632 ptr = fold_build_pointer_plus_hwi_loc (input_location,
1633 ptrtmp, fixed_offset);
1636 /* Emit the statement and gimplify the adjustment expression. */
1637 ret = create_tmp_var (TREE_TYPE (ptr), "adjusted_this");
1638 stmt = gimple_build_assign (ret, ptr);
1639 mark_symbols_for_renaming (stmt);
1640 find_referenced_vars_in (stmt);
1641 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1646 /* Produce assembler for thunk NODE. */
1649 assemble_thunk (struct cgraph_node *node)
1651 bool this_adjusting = node->thunk.this_adjusting;
1652 HOST_WIDE_INT fixed_offset = node->thunk.fixed_offset;
1653 HOST_WIDE_INT virtual_value = node->thunk.virtual_value;
1654 tree virtual_offset = NULL;
1655 tree alias = node->thunk.alias;
1656 tree thunk_fndecl = node->symbol.decl;
1657 tree a = DECL_ARGUMENTS (thunk_fndecl);
1659 current_function_decl = thunk_fndecl;
1661 /* Ensure thunks are emitted in their correct sections. */
1662 resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
1665 && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
1666 virtual_value, alias))
1670 tree restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1672 DECL_RESULT (thunk_fndecl)
1673 = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl),
1674 RESULT_DECL, 0, restype);
1675 fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
1677 /* The back end expects DECL_INITIAL to contain a BLOCK, so we
1679 fn_block = make_node (BLOCK);
1680 BLOCK_VARS (fn_block) = a;
1681 DECL_INITIAL (thunk_fndecl) = fn_block;
1682 init_function_start (thunk_fndecl);
1684 assemble_start_function (thunk_fndecl, fnname);
1686 targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl,
1687 fixed_offset, virtual_value, alias);
1689 assemble_end_function (thunk_fndecl, fnname);
1690 init_insn_lengths ();
1691 free_after_compilation (cfun);
1693 TREE_ASM_WRITTEN (thunk_fndecl) = 1;
1694 node->thunk.thunk_p = false;
1695 node->analyzed = false;
1700 basic_block bb, then_bb, else_bb, return_bb;
1701 gimple_stmt_iterator bsi;
1707 VEC(tree, heap) *vargs;
1712 DECL_IGNORED_P (thunk_fndecl) = 1;
1713 bitmap_obstack_initialize (NULL);
1715 if (node->thunk.virtual_offset_p)
1716 virtual_offset = size_int (virtual_value);
1718 /* Build the return declaration for the function. */
1719 restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1720 if (DECL_RESULT (thunk_fndecl) == NULL_TREE)
1722 resdecl = build_decl (input_location, RESULT_DECL, 0, restype);
1723 DECL_ARTIFICIAL (resdecl) = 1;
1724 DECL_IGNORED_P (resdecl) = 1;
1725 DECL_RESULT (thunk_fndecl) = resdecl;
1728 resdecl = DECL_RESULT (thunk_fndecl);
1730 bb = then_bb = else_bb = return_bb = init_lowered_empty_function (thunk_fndecl);
1732 bsi = gsi_start_bb (bb);
1734 /* Build call to the function being thunked. */
1735 if (!VOID_TYPE_P (restype))
1737 if (!is_gimple_reg_type (restype))
1740 add_local_decl (cfun, restmp);
1741 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp;
1744 restmp = create_tmp_var_raw (restype, "retval");
1747 for (arg = a; arg; arg = DECL_CHAIN (arg))
1749 vargs = VEC_alloc (tree, heap, nargs);
1751 VEC_quick_push (tree, vargs,
1756 VEC_quick_push (tree, vargs, a);
1757 for (i = 1, arg = DECL_CHAIN (a); i < nargs; i++, arg = DECL_CHAIN (arg))
1758 VEC_quick_push (tree, vargs, arg);
1759 call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs);
1760 VEC_free (tree, heap, vargs);
1761 gimple_call_set_from_thunk (call, true);
1763 gimple_call_set_lhs (call, restmp);
1764 gsi_insert_after (&bsi, call, GSI_NEW_STMT);
1765 mark_symbols_for_renaming (call);
1766 find_referenced_vars_in (call);
1769 if (restmp && !this_adjusting)
1771 tree true_label = NULL_TREE;
1773 if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE)
1776 /* If the return type is a pointer, we need to
1777 protect against NULL. We know there will be an
1778 adjustment, because that's why we're emitting a
1780 then_bb = create_basic_block (NULL, (void *) 0, bb);
1781 return_bb = create_basic_block (NULL, (void *) 0, then_bb);
1782 else_bb = create_basic_block (NULL, (void *) 0, else_bb);
1783 remove_edge (single_succ_edge (bb));
1784 true_label = gimple_block_label (then_bb);
1785 stmt = gimple_build_cond (NE_EXPR, restmp,
1786 build_zero_cst (TREE_TYPE (restmp)),
1787 NULL_TREE, NULL_TREE);
1788 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1789 make_edge (bb, then_bb, EDGE_TRUE_VALUE);
1790 make_edge (bb, else_bb, EDGE_FALSE_VALUE);
1791 make_edge (return_bb, EXIT_BLOCK_PTR, 0);
1792 make_edge (then_bb, return_bb, EDGE_FALLTHRU);
1793 make_edge (else_bb, return_bb, EDGE_FALLTHRU);
1794 bsi = gsi_last_bb (then_bb);
1797 restmp = thunk_adjust (&bsi, restmp, /*this_adjusting=*/0,
1798 fixed_offset, virtual_offset);
1802 bsi = gsi_last_bb (else_bb);
1803 stmt = gimple_build_assign (restmp,
1804 build_zero_cst (TREE_TYPE (restmp)));
1805 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1806 bsi = gsi_last_bb (return_bb);
1810 gimple_call_set_tail (call, true);
1812 /* Build return value. */
1813 ret = gimple_build_return (restmp);
1814 gsi_insert_after (&bsi, ret, GSI_NEW_STMT);
1816 delete_unreachable_blocks ();
1817 update_ssa (TODO_update_ssa);
1819 /* Since we want to emit the thunk, we explicitly mark its name as
1821 node->thunk.thunk_p = false;
1822 cgraph_node_remove_callees (node);
1823 cgraph_add_new_function (thunk_fndecl, true);
1824 bitmap_obstack_release (NULL);
1826 current_function_decl = NULL;
1831 /* Assemble thunks and aliases asociated to NODE. */
1834 assemble_thunks_and_aliases (struct cgraph_node *node)
1836 struct cgraph_edge *e;
1838 struct ipa_ref *ref;
1840 for (e = node->callers; e;)
1841 if (e->caller->thunk.thunk_p)
1843 struct cgraph_node *thunk = e->caller;
1846 assemble_thunks_and_aliases (thunk);
1847 assemble_thunk (thunk);
1851 for (i = 0; ipa_ref_list_refering_iterate (&node->symbol.ref_list,
1853 if (ref->use == IPA_REF_ALIAS)
1855 struct cgraph_node *alias = ipa_ref_refering_node (ref);
1856 bool saved_written = TREE_ASM_WRITTEN (alias->thunk.alias);
1858 /* Force assemble_alias to really output the alias this time instead
1859 of buffering it in same alias pairs. */
1860 TREE_ASM_WRITTEN (alias->thunk.alias) = 1;
1861 assemble_alias (alias->symbol.decl,
1862 DECL_ASSEMBLER_NAME (alias->thunk.alias));
1863 assemble_thunks_and_aliases (alias);
1864 TREE_ASM_WRITTEN (alias->thunk.alias) = saved_written;
1868 /* Perform IPA transforms and all further optimizations and compilation
1872 tree_rest_of_compilation (struct cgraph_node *node)
1874 tree fndecl = node->symbol.decl;
1875 location_t saved_loc;
1877 timevar_push (TV_REST_OF_COMPILATION);
1879 gcc_assert (cgraph_global_info_ready);
1881 /* Initialize the default bitmap obstack. */
1882 bitmap_obstack_initialize (NULL);
1884 /* Initialize the RTL code for the function. */
1885 current_function_decl = fndecl;
1886 saved_loc = input_location;
1887 input_location = DECL_SOURCE_LOCATION (fndecl);
1888 init_function_start (fndecl);
1890 gimple_register_cfg_hooks ();
1892 bitmap_obstack_initialize (®_obstack); /* FIXME, only at RTL generation*/
1894 execute_all_ipa_transforms ();
1896 /* Perform all tree transforms and optimizations. */
1898 /* Signal the start of passes. */
1899 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START, NULL);
1901 execute_pass_list (all_passes);
1903 /* Signal the end of passes. */
1904 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END, NULL);
1906 bitmap_obstack_release (®_obstack);
1908 /* Release the default bitmap obstack. */
1909 bitmap_obstack_release (NULL);
1913 /* If requested, warn about function definitions where the function will
1914 return a value (usually of some struct or union type) which itself will
1915 take up a lot of stack space. */
1916 if (warn_larger_than && !DECL_EXTERNAL (fndecl) && TREE_TYPE (fndecl))
1918 tree ret_type = TREE_TYPE (TREE_TYPE (fndecl));
1920 if (ret_type && TYPE_SIZE_UNIT (ret_type)
1921 && TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST
1922 && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type),
1925 unsigned int size_as_int
1926 = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type));
1928 if (compare_tree_int (TYPE_SIZE_UNIT (ret_type), size_as_int) == 0)
1929 warning (OPT_Wlarger_than_, "size of return value of %q+D is %u bytes",
1930 fndecl, size_as_int);
1932 warning (OPT_Wlarger_than_, "size of return value of %q+D is larger than %wd bytes",
1933 fndecl, larger_than_size);
1937 gimple_set_body (fndecl, NULL);
1938 if (DECL_STRUCT_FUNCTION (fndecl) == 0
1939 && !cgraph_get_node (fndecl)->origin)
1941 /* Stop pointing to the local nodes about to be freed.
1942 But DECL_INITIAL must remain nonzero so we know this
1943 was an actual function definition.
1944 For a nested function, this is done in c_pop_function_context.
1945 If rest_of_compilation set this to 0, leave it 0. */
1946 if (DECL_INITIAL (fndecl) != 0)
1947 DECL_INITIAL (fndecl) = error_mark_node;
1950 input_location = saved_loc;
1953 timevar_pop (TV_REST_OF_COMPILATION);
1956 /* Expand function specified by NODE. */
1959 cgraph_expand_function (struct cgraph_node *node)
1961 tree decl = node->symbol.decl;
1963 /* We ought to not compile any inline clones. */
1964 gcc_assert (!node->global.inlined_to);
1966 announce_function (decl);
1968 gcc_assert (node->lowered);
1970 /* Generate RTL for the body of DECL. */
1971 tree_rest_of_compilation (node);
1973 /* Make sure that BE didn't give up on compiling. */
1974 gcc_assert (TREE_ASM_WRITTEN (decl));
1975 current_function_decl = NULL;
1976 gcc_assert (!cgraph_preserve_function_body_p (node));
1978 /* It would make a lot more sense to output thunks before function body to get more
1979 forward and lest backwarding jumps. This is however would need solving problem
1980 with comdats. See PR48668. Also aliases must come after function itself to
1981 make one pass assemblers, like one on AIX happy. See PR 50689.
1982 FIXME: Perhaps thunks should be move before function IFF they are not in comdat
1984 assemble_thunks_and_aliases (node);
1985 cgraph_release_function_body (node);
1986 /* Eliminate all call edges. This is important so the GIMPLE_CALL no longer
1987 points to the dead function body. */
1988 cgraph_node_remove_callees (node);
1991 /* Return true when CALLER_DECL should be inlined into CALLEE_DECL. */
1994 cgraph_inline_p (struct cgraph_edge *e, cgraph_inline_failed_t *reason)
1996 *reason = e->inline_failed;
1997 return !e->inline_failed;
2002 /* Expand all functions that must be output.
2004 Attempt to topologically sort the nodes so function is output when
2005 all called functions are already assembled to allow data to be
2006 propagated across the callgraph. Use a stack to get smaller distance
2007 between a function and its callees (later we may choose to use a more
2008 sophisticated algorithm for function reordering; we will likely want
2009 to use subsections to make the output functions appear in top-down
2013 cgraph_expand_all_functions (void)
2015 struct cgraph_node *node;
2016 struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
2017 int order_pos, new_order_pos = 0;
2020 order_pos = ipa_reverse_postorder (order);
2021 gcc_assert (order_pos == cgraph_n_nodes);
2023 /* Garbage collector may remove inline clones we eliminate during
2024 optimization. So we must be sure to not reference them. */
2025 for (i = 0; i < order_pos; i++)
2026 if (order[i]->process)
2027 order[new_order_pos++] = order[i];
2029 for (i = new_order_pos - 1; i >= 0; i--)
2034 gcc_assert (node->reachable);
2036 cgraph_expand_function (node);
2039 cgraph_process_new_functions ();
2045 /* This is used to sort the node types by the cgraph order number. */
2047 enum cgraph_order_sort_kind
2049 ORDER_UNDEFINED = 0,
2055 struct cgraph_order_sort
2057 enum cgraph_order_sort_kind kind;
2060 struct cgraph_node *f;
2061 struct varpool_node *v;
2062 struct cgraph_asm_node *a;
2066 /* Output all functions, variables, and asm statements in the order
2067 according to their order fields, which is the order in which they
2068 appeared in the file. This implements -fno-toplevel-reorder. In
2069 this mode we may output functions and variables which don't really
2070 need to be output. */
2073 cgraph_output_in_order (void)
2076 struct cgraph_order_sort *nodes;
2078 struct cgraph_node *pf;
2079 struct varpool_node *pv;
2080 struct cgraph_asm_node *pa;
2083 nodes = XCNEWVEC (struct cgraph_order_sort, max);
2085 varpool_analyze_pending_decls ();
2087 FOR_EACH_DEFINED_FUNCTION (pf)
2089 if (pf->process && !pf->thunk.thunk_p && !pf->alias)
2091 i = pf->symbol.order;
2092 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
2093 nodes[i].kind = ORDER_FUNCTION;
2098 FOR_EACH_DEFINED_VARIABLE (pv)
2100 i = pv->symbol.order;
2101 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
2102 nodes[i].kind = ORDER_VAR;
2106 for (pa = cgraph_asm_nodes; pa; pa = pa->next)
2109 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
2110 nodes[i].kind = ORDER_ASM;
2114 /* In toplevel reorder mode we output all statics; mark them as needed. */
2115 for (i = 0; i < max; ++i)
2117 if (nodes[i].kind == ORDER_VAR)
2119 varpool_mark_needed_node (nodes[i].u.v);
2122 varpool_empty_needed_queue ();
2124 for (i = 0; i < max; ++i)
2125 if (nodes[i].kind == ORDER_VAR)
2126 varpool_finalize_named_section_flags (nodes[i].u.v);
2128 for (i = 0; i < max; ++i)
2130 switch (nodes[i].kind)
2132 case ORDER_FUNCTION:
2133 nodes[i].u.f->process = 0;
2134 cgraph_expand_function (nodes[i].u.f);
2138 varpool_assemble_decl (nodes[i].u.v);
2142 assemble_asm (nodes[i].u.a->asm_str);
2145 case ORDER_UNDEFINED:
2153 cgraph_asm_nodes = NULL;
2157 /* Return true when function body of DECL still needs to be kept around
2158 for later re-use. */
2160 cgraph_preserve_function_body_p (struct cgraph_node *node)
2162 gcc_assert (cgraph_global_info_ready);
2163 gcc_assert (!node->alias && !node->thunk.thunk_p);
2165 /* Look if there is any clone around. */
2175 current_function_decl = NULL;
2176 gimple_register_cfg_hooks ();
2177 bitmap_obstack_initialize (NULL);
2179 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START, NULL);
2183 execute_ipa_pass_list (all_small_ipa_passes);
2188 /* We never run removal of unreachable nodes after early passes. This is
2189 because TODO is run before the subpasses. It is important to remove
2190 the unreachable functions to save works at IPA level and to get LTO
2191 symbol tables right. */
2192 cgraph_remove_unreachable_nodes (true, cgraph_dump_file);
2194 /* If pass_all_early_optimizations was not scheduled, the state of
2195 the cgraph will not be properly updated. Update it now. */
2196 if (cgraph_state < CGRAPH_STATE_IPA_SSA)
2197 cgraph_state = CGRAPH_STATE_IPA_SSA;
2201 /* Generate coverage variables and constructors. */
2204 /* Process new functions added. */
2206 current_function_decl = NULL;
2207 cgraph_process_new_functions ();
2209 execute_ipa_summary_passes
2210 ((struct ipa_opt_pass_d *) all_regular_ipa_passes);
2213 /* Some targets need to handle LTO assembler output specially. */
2214 if (flag_generate_lto)
2215 targetm.asm_out.lto_start ();
2217 execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_lto_gen_passes);
2220 ipa_write_summaries ();
2222 if (flag_generate_lto)
2223 targetm.asm_out.lto_end ();
2225 if (!flag_ltrans && (in_lto_p || !flag_lto || flag_fat_lto_objects))
2226 execute_ipa_pass_list (all_regular_ipa_passes);
2227 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END, NULL);
2229 bitmap_obstack_release (NULL);
2233 /* Return string alias is alias of. */
2236 get_alias_symbol (tree decl)
2238 tree alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
2239 return get_identifier (TREE_STRING_POINTER
2240 (TREE_VALUE (TREE_VALUE (alias))));
2244 /* Weakrefs may be associated to external decls and thus not output
2245 at expansion time. Emit all neccesary aliases. */
2248 output_weakrefs (void)
2250 struct cgraph_node *node;
2251 struct varpool_node *vnode;
2252 FOR_EACH_FUNCTION (node)
2253 if (node->alias && DECL_EXTERNAL (node->symbol.decl)
2254 && !TREE_ASM_WRITTEN (node->symbol.decl)
2255 && lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
2256 assemble_alias (node->symbol.decl,
2257 node->thunk.alias ? DECL_ASSEMBLER_NAME (node->thunk.alias)
2258 : get_alias_symbol (node->symbol.decl));
2259 FOR_EACH_VARIABLE (vnode)
2260 if (vnode->alias && DECL_EXTERNAL (vnode->symbol.decl)
2261 && !TREE_ASM_WRITTEN (vnode->symbol.decl)
2262 && lookup_attribute ("weakref", DECL_ATTRIBUTES (vnode->symbol.decl)))
2263 assemble_alias (vnode->symbol.decl,
2264 vnode->alias_of ? DECL_ASSEMBLER_NAME (vnode->alias_of)
2265 : get_alias_symbol (vnode->symbol.decl));
2273 if (!cgraph_dump_file)
2274 cgraph_dump_file = dump_begin (TDI_cgraph, NULL);
2277 /* The edges representing the callers of the NEW_VERSION node were
2278 fixed by cgraph_function_versioning (), now the call_expr in their
2279 respective tree code should be updated to call the NEW_VERSION. */
2282 update_call_expr (struct cgraph_node *new_version)
2284 struct cgraph_edge *e;
2286 gcc_assert (new_version);
2288 /* Update the call expr on the edges to call the new version. */
2289 for (e = new_version->callers; e; e = e->next_caller)
2291 struct function *inner_function = DECL_STRUCT_FUNCTION (e->caller->symbol.decl);
2292 gimple_call_set_fndecl (e->call_stmt, new_version->symbol.decl);
2293 maybe_clean_eh_stmt_fn (inner_function, e->call_stmt);
2298 /* Create a new cgraph node which is the new version of
2299 OLD_VERSION node. REDIRECT_CALLERS holds the callers
2300 edges which should be redirected to point to
2301 NEW_VERSION. ALL the callees edges of OLD_VERSION
2302 are cloned to the new version node. Return the new
2305 If non-NULL BLOCK_TO_COPY determine what basic blocks
2306 was copied to prevent duplications of calls that are dead
2309 struct cgraph_node *
2310 cgraph_copy_node_for_versioning (struct cgraph_node *old_version,
2312 VEC(cgraph_edge_p,heap) *redirect_callers,
2315 struct cgraph_node *new_version;
2316 struct cgraph_edge *e;
2319 gcc_assert (old_version);
2321 new_version = cgraph_create_node (new_decl);
2323 new_version->analyzed = old_version->analyzed;
2324 new_version->local = old_version->local;
2325 new_version->symbol.externally_visible = false;
2326 new_version->local.local = old_version->analyzed;
2327 new_version->global = old_version->global;
2328 new_version->rtl = old_version->rtl;
2329 new_version->reachable = true;
2330 new_version->count = old_version->count;
2332 for (e = old_version->callees; e; e=e->next_callee)
2334 || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
2335 cgraph_clone_edge (e, new_version, e->call_stmt,
2336 e->lto_stmt_uid, REG_BR_PROB_BASE,
2339 for (e = old_version->indirect_calls; e; e=e->next_callee)
2341 || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
2342 cgraph_clone_edge (e, new_version, e->call_stmt,
2343 e->lto_stmt_uid, REG_BR_PROB_BASE,
2346 FOR_EACH_VEC_ELT (cgraph_edge_p, redirect_callers, i, e)
2348 /* Redirect calls to the old version node to point to its new
2350 cgraph_redirect_edge_callee (e, new_version);
2353 cgraph_call_node_duplication_hooks (old_version, new_version);
2358 /* Perform function versioning.
2359 Function versioning includes copying of the tree and
2360 a callgraph update (creating a new cgraph node and updating
2361 its callees and callers).
2363 REDIRECT_CALLERS varray includes the edges to be redirected
2366 TREE_MAP is a mapping of tree nodes we want to replace with
2367 new ones (according to results of prior analysis).
2368 OLD_VERSION_NODE is the node that is versioned.
2370 If non-NULL ARGS_TO_SKIP determine function parameters to remove
2372 If SKIP_RETURN is true, the new version will return void.
2373 If non-NULL BLOCK_TO_COPY determine what basic blocks to copy.
2374 If non_NULL NEW_ENTRY determine new entry BB of the clone.
2376 Return the new version's cgraph node. */
2378 struct cgraph_node *
2379 cgraph_function_versioning (struct cgraph_node *old_version_node,
2380 VEC(cgraph_edge_p,heap) *redirect_callers,
2381 VEC (ipa_replace_map_p,gc)* tree_map,
2382 bitmap args_to_skip,
2385 basic_block new_entry_block,
2386 const char *clone_name)
2388 tree old_decl = old_version_node->symbol.decl;
2389 struct cgraph_node *new_version_node = NULL;
2392 if (!tree_versionable_function_p (old_decl))
2395 gcc_assert (old_version_node->local.can_change_signature || !args_to_skip);
2397 /* Make a new FUNCTION_DECL tree node for the new version. */
2398 if (!args_to_skip && !skip_return)
2399 new_decl = copy_node (old_decl);
2402 = build_function_decl_skip_args (old_decl, args_to_skip, skip_return);
2404 /* Generate a new name for the new version. */
2405 DECL_NAME (new_decl) = clone_function_name (old_decl, clone_name);
2406 SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
2407 SET_DECL_RTL (new_decl, NULL);
2409 /* When the old decl was a con-/destructor make sure the clone isn't. */
2410 DECL_STATIC_CONSTRUCTOR(new_decl) = 0;
2411 DECL_STATIC_DESTRUCTOR(new_decl) = 0;
2413 /* Create the new version's call-graph node.
2414 and update the edges of the new node. */
2416 cgraph_copy_node_for_versioning (old_version_node, new_decl,
2417 redirect_callers, bbs_to_copy);
2419 /* Copy the OLD_VERSION_NODE function tree to the new version. */
2420 tree_function_versioning (old_decl, new_decl, tree_map, false, args_to_skip,
2421 skip_return, bbs_to_copy, new_entry_block);
2423 /* Update the new version's properties.
2424 Make The new version visible only within this translation unit. Make sure
2425 that is not weak also.
2426 ??? We cannot use COMDAT linkage because there is no
2427 ABI support for this. */
2428 cgraph_make_decl_local (new_version_node->symbol.decl);
2429 DECL_VIRTUAL_P (new_version_node->symbol.decl) = 0;
2430 new_version_node->symbol.externally_visible = 0;
2431 new_version_node->local.local = 1;
2432 new_version_node->lowered = true;
2434 /* Update the call_expr on the edges to call the new version node. */
2435 update_call_expr (new_version_node);
2437 cgraph_call_function_insertion_hooks (new_version_node);
2438 return new_version_node;
2441 /* Given virtual clone, turn it into actual clone. */
2443 cgraph_materialize_clone (struct cgraph_node *node)
2445 bitmap_obstack_initialize (NULL);
2446 node->former_clone_of = node->clone_of->symbol.decl;
2447 if (node->clone_of->former_clone_of)
2448 node->former_clone_of = node->clone_of->former_clone_of;
2449 /* Copy the OLD_VERSION_NODE function tree to the new version. */
2450 tree_function_versioning (node->clone_of->symbol.decl, node->symbol.decl,
2451 node->clone.tree_map, true,
2452 node->clone.args_to_skip, false,
2454 if (cgraph_dump_file)
2456 dump_function_to_file (node->clone_of->symbol.decl, cgraph_dump_file, dump_flags);
2457 dump_function_to_file (node->symbol.decl, cgraph_dump_file, dump_flags);
2460 /* Function is no longer clone. */
2461 if (node->next_sibling_clone)
2462 node->next_sibling_clone->prev_sibling_clone = node->prev_sibling_clone;
2463 if (node->prev_sibling_clone)
2464 node->prev_sibling_clone->next_sibling_clone = node->next_sibling_clone;
2466 node->clone_of->clones = node->next_sibling_clone;
2467 node->next_sibling_clone = NULL;
2468 node->prev_sibling_clone = NULL;
2469 if (!node->clone_of->analyzed && !node->clone_of->clones)
2471 cgraph_release_function_body (node->clone_of);
2472 cgraph_node_remove_callees (node->clone_of);
2473 ipa_remove_all_references (&node->clone_of->symbol.ref_list);
2475 node->clone_of = NULL;
2476 bitmap_obstack_release (NULL);
2479 /* If necessary, change the function declaration in the call statement
2480 associated with E so that it corresponds to the edge callee. */
2483 cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *e)
2485 tree decl = gimple_call_fndecl (e->call_stmt);
2487 gimple_stmt_iterator gsi;
2488 #ifdef ENABLE_CHECKING
2489 struct cgraph_node *node;
2492 if (e->indirect_unknown_callee
2493 || decl == e->callee->symbol.decl)
2494 return e->call_stmt;
2496 #ifdef ENABLE_CHECKING
2499 node = cgraph_get_node (decl);
2500 gcc_assert (!node || !node->clone.combined_args_to_skip);
2504 if (cgraph_dump_file)
2506 fprintf (cgraph_dump_file, "updating call of %s/%i -> %s/%i: ",
2507 cgraph_node_name (e->caller), e->caller->uid,
2508 cgraph_node_name (e->callee), e->callee->uid);
2509 print_gimple_stmt (cgraph_dump_file, e->call_stmt, 0, dump_flags);
2510 if (e->callee->clone.combined_args_to_skip)
2512 fprintf (cgraph_dump_file, " combined args to skip: ");
2513 dump_bitmap (cgraph_dump_file,
2514 e->callee->clone.combined_args_to_skip);
2518 if (e->callee->clone.combined_args_to_skip)
2523 = gimple_call_copy_skip_args (e->call_stmt,
2524 e->callee->clone.combined_args_to_skip);
2525 gimple_call_set_fndecl (new_stmt, e->callee->symbol.decl);
2527 if (gimple_vdef (new_stmt)
2528 && TREE_CODE (gimple_vdef (new_stmt)) == SSA_NAME)
2529 SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt;
2531 gsi = gsi_for_stmt (e->call_stmt);
2532 gsi_replace (&gsi, new_stmt, false);
2533 /* We need to defer cleaning EH info on the new statement to
2534 fixup-cfg. We may not have dominator information at this point
2535 and thus would end up with unreachable blocks and have no way
2536 to communicate that we need to run CFG cleanup then. */
2537 lp_nr = lookup_stmt_eh_lp (e->call_stmt);
2540 remove_stmt_from_eh_lp (e->call_stmt);
2541 add_stmt_to_eh_lp (new_stmt, lp_nr);
2546 new_stmt = e->call_stmt;
2547 gimple_call_set_fndecl (new_stmt, e->callee->symbol.decl);
2548 update_stmt (new_stmt);
2551 cgraph_set_call_stmt_including_clones (e->caller, e->call_stmt, new_stmt);
2553 if (cgraph_dump_file)
2555 fprintf (cgraph_dump_file, " updated to:");
2556 print_gimple_stmt (cgraph_dump_file, e->call_stmt, 0, dump_flags);
2561 /* Once all functions from compilation unit are in memory, produce all clones
2562 and update all calls. We might also do this on demand if we don't want to
2563 bring all functions to memory prior compilation, but current WHOPR
2564 implementation does that and it is is bit easier to keep everything right in
2567 cgraph_materialize_all_clones (void)
2569 struct cgraph_node *node;
2570 bool stabilized = false;
2572 if (cgraph_dump_file)
2573 fprintf (cgraph_dump_file, "Materializing clones\n");
2574 #ifdef ENABLE_CHECKING
2578 /* We can also do topological order, but number of iterations should be
2579 bounded by number of IPA passes since single IPA pass is probably not
2580 going to create clones of clones it created itself. */
2584 FOR_EACH_FUNCTION (node)
2586 if (node->clone_of && node->symbol.decl != node->clone_of->symbol.decl
2587 && !gimple_has_body_p (node->symbol.decl))
2589 if (gimple_has_body_p (node->clone_of->symbol.decl))
2591 if (cgraph_dump_file)
2593 fprintf (cgraph_dump_file, "cloning %s to %s\n",
2594 cgraph_node_name (node->clone_of),
2595 cgraph_node_name (node));
2596 if (node->clone.tree_map)
2599 fprintf (cgraph_dump_file, " replace map: ");
2600 for (i = 0; i < VEC_length (ipa_replace_map_p,
2601 node->clone.tree_map);
2604 struct ipa_replace_map *replace_info;
2605 replace_info = VEC_index (ipa_replace_map_p,
2606 node->clone.tree_map,
2608 print_generic_expr (cgraph_dump_file, replace_info->old_tree, 0);
2609 fprintf (cgraph_dump_file, " -> ");
2610 print_generic_expr (cgraph_dump_file, replace_info->new_tree, 0);
2611 fprintf (cgraph_dump_file, "%s%s;",
2612 replace_info->replace_p ? "(replace)":"",
2613 replace_info->ref_p ? "(ref)":"");
2615 fprintf (cgraph_dump_file, "\n");
2617 if (node->clone.args_to_skip)
2619 fprintf (cgraph_dump_file, " args_to_skip: ");
2620 dump_bitmap (cgraph_dump_file, node->clone.args_to_skip);
2622 if (node->clone.args_to_skip)
2624 fprintf (cgraph_dump_file, " combined_args_to_skip:");
2625 dump_bitmap (cgraph_dump_file, node->clone.combined_args_to_skip);
2628 cgraph_materialize_clone (node);
2634 FOR_EACH_FUNCTION (node)
2635 if (!node->analyzed && node->callees)
2636 cgraph_node_remove_callees (node);
2637 if (cgraph_dump_file)
2638 fprintf (cgraph_dump_file, "Materialization Call site updates done.\n");
2639 #ifdef ENABLE_CHECKING
2642 cgraph_remove_unreachable_nodes (false, cgraph_dump_file);
2646 /* Perform simple optimizations based on callgraph. */
2649 cgraph_optimize (void)
2654 #ifdef ENABLE_CHECKING
2658 /* Frontend may output common variables after the unit has been finalized.
2659 It is safe to deal with them here as they are always zero initialized. */
2660 varpool_analyze_pending_decls ();
2662 timevar_push (TV_CGRAPHOPT);
2663 if (pre_ipa_mem_report)
2665 fprintf (stderr, "Memory consumption before IPA\n");
2666 dump_memory_report (false);
2669 fprintf (stderr, "Performing interprocedural optimizations\n");
2670 cgraph_state = CGRAPH_STATE_IPA;
2672 /* Don't run the IPA passes if there was any error or sorry messages. */
2676 /* Do nothing else if any IPA pass found errors or if we are just streaming LTO. */
2678 || (!in_lto_p && flag_lto && !flag_fat_lto_objects))
2680 timevar_pop (TV_CGRAPHOPT);
2684 /* This pass remove bodies of extern inline functions we never inlined.
2685 Do this later so other IPA passes see what is really going on. */
2686 cgraph_remove_unreachable_nodes (false, dump_file);
2687 cgraph_global_info_ready = true;
2688 if (cgraph_dump_file)
2690 fprintf (cgraph_dump_file, "Optimized ");
2691 dump_symtab (cgraph_dump_file);
2693 if (post_ipa_mem_report)
2695 fprintf (stderr, "Memory consumption after IPA\n");
2696 dump_memory_report (false);
2698 timevar_pop (TV_CGRAPHOPT);
2700 /* Output everything. */
2701 (*debug_hooks->assembly_start) ();
2703 fprintf (stderr, "Assembling functions:\n");
2704 #ifdef ENABLE_CHECKING
2708 cgraph_materialize_all_clones ();
2709 bitmap_obstack_initialize (NULL);
2710 execute_ipa_pass_list (all_late_ipa_passes);
2711 cgraph_remove_unreachable_nodes (true, dump_file);
2712 #ifdef ENABLE_CHECKING
2715 bitmap_obstack_release (NULL);
2716 cgraph_mark_functions_to_output ();
2719 cgraph_state = CGRAPH_STATE_EXPANSION;
2720 if (!flag_toplevel_reorder)
2721 cgraph_output_in_order ();
2724 cgraph_output_pending_asms ();
2726 cgraph_expand_all_functions ();
2727 varpool_remove_unreferenced_decls ();
2729 varpool_assemble_pending_decls ();
2732 cgraph_process_new_functions ();
2733 cgraph_state = CGRAPH_STATE_FINISHED;
2735 if (cgraph_dump_file)
2737 fprintf (cgraph_dump_file, "\nFinal ");
2738 dump_symtab (cgraph_dump_file);
2740 #ifdef ENABLE_CHECKING
2742 /* Double check that all inline clones are gone and that all
2743 function bodies have been released from memory. */
2746 struct cgraph_node *node;
2747 bool error_found = false;
2749 FOR_EACH_DEFINED_FUNCTION (node)
2750 if (node->global.inlined_to
2751 || gimple_has_body_p (node->symbol.decl))
2754 dump_cgraph_node (stderr, node);
2757 internal_error ("nodes with unreleased memory found");
2763 /* Analyze the whole compilation unit once it is parsed completely. */
2766 cgraph_finalize_compilation_unit (void)
2768 timevar_push (TV_CGRAPH);
2770 /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE. */
2772 lto_streamer_hooks_init ();
2774 /* If we're here there's no current function anymore. Some frontends
2775 are lazy in clearing these. */
2776 current_function_decl = NULL;
2779 /* Do not skip analyzing the functions if there were errors, we
2780 miss diagnostics for following functions otherwise. */
2782 /* Emit size functions we didn't inline. */
2783 finalize_size_functions ();
2785 /* Mark alias targets necessary and emit diagnostics. */
2786 finish_aliases_1 ();
2787 handle_alias_pairs ();
2791 fprintf (stderr, "\nAnalyzing compilation unit\n");
2795 if (flag_dump_passes)
2798 /* Gimplify and lower all functions, compute reachability and
2799 remove unreachable nodes. */
2800 cgraph_analyze_functions ();
2802 /* Mark alias targets necessary and emit diagnostics. */
2803 finish_aliases_1 ();
2804 handle_alias_pairs ();
2806 /* Gimplify and lower thunks. */
2807 cgraph_analyze_functions ();
2809 /* Finally drive the pass manager. */
2812 timevar_pop (TV_CGRAPH);
2816 #include "gt-cgraphunit.h"