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 we've not yet emitted decl, tell the debug info about it. */
366 if (!TREE_ASM_WRITTEN (decl))
367 (*debug_hooks->deferred_inline_function) (decl);
369 /* Possibly warn about unused parameters. */
370 if (warn_unused_parameter)
371 do_warn_unused_parameter (decl);
377 /* Add the function FNDECL to the call graph.
378 Unlike cgraph_finalize_function, this function is intended to be used
379 by middle end and allows insertion of new function at arbitrary point
380 of compilation. The function can be either in high, low or SSA form
383 The function is assumed to be reachable and have address taken (so no
384 API breaking optimizations are performed on it).
386 Main work done by this function is to enqueue the function for later
387 processing to avoid need the passes to be re-entrant. */
390 cgraph_add_new_function (tree fndecl, bool lowered)
392 struct cgraph_node *node;
393 switch (cgraph_state)
395 case CGRAPH_STATE_PARSING:
396 cgraph_finalize_function (fndecl, false);
398 case CGRAPH_STATE_CONSTRUCTION:
399 /* Just enqueue function to be processed at nearest occurrence. */
400 node = cgraph_create_node (fndecl);
402 node->lowered = true;
403 if (!cgraph_new_nodes)
404 cgraph_new_nodes = cgraph_node_set_new ();
405 cgraph_node_set_add (cgraph_new_nodes, node);
408 case CGRAPH_STATE_IPA:
409 case CGRAPH_STATE_IPA_SSA:
410 case CGRAPH_STATE_EXPANSION:
411 /* Bring the function into finalized state and enqueue for later
412 analyzing and compilation. */
413 node = cgraph_get_create_node (fndecl);
414 node->local.local = false;
415 node->local.finalized = true;
416 node->symbol.force_output = true;
417 if (!lowered && cgraph_state == CGRAPH_STATE_EXPANSION)
419 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
420 current_function_decl = fndecl;
421 gimple_register_cfg_hooks ();
422 bitmap_obstack_initialize (NULL);
423 execute_pass_list (all_lowering_passes);
424 execute_pass_list (pass_early_local_passes.pass.sub);
425 bitmap_obstack_release (NULL);
427 current_function_decl = NULL;
432 node->lowered = true;
433 if (!cgraph_new_nodes)
434 cgraph_new_nodes = cgraph_node_set_new ();
435 cgraph_node_set_add (cgraph_new_nodes, node);
438 case CGRAPH_STATE_FINISHED:
439 /* At the very end of compilation we have to do all the work up
441 node = cgraph_create_node (fndecl);
443 node->lowered = true;
444 cgraph_analyze_function (node);
445 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
446 current_function_decl = fndecl;
447 gimple_register_cfg_hooks ();
448 bitmap_obstack_initialize (NULL);
449 if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
450 execute_pass_list (pass_early_local_passes.pass.sub);
451 bitmap_obstack_release (NULL);
452 tree_rest_of_compilation (node);
454 current_function_decl = NULL;
461 /* Set a personality if required and we already passed EH lowering. */
463 && (function_needs_eh_personality (DECL_STRUCT_FUNCTION (fndecl))
464 == eh_personality_lang))
465 DECL_FUNCTION_PERSONALITY (fndecl) = lang_hooks.eh_personality ();
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 error_found |= verify_symtab_base ((symtab_node) node);
581 for (e = node->callees; e; e = e->next_callee)
584 error ("aux field set for edge %s->%s",
585 identifier_to_locale (cgraph_node_name (e->caller)),
586 identifier_to_locale (cgraph_node_name (e->callee)));
591 error ("execution count is negative");
594 if (node->global.inlined_to && node->symbol.externally_visible)
596 error ("externally visible inline clone");
599 if (node->global.inlined_to && node->symbol.address_taken)
601 error ("inline clone with address taken");
604 if (node->global.inlined_to && node->symbol.force_output)
606 error ("inline clone is forced to output");
609 for (e = node->indirect_calls; e; e = e->next_callee)
613 error ("aux field set for indirect edge from %s",
614 identifier_to_locale (cgraph_node_name (e->caller)));
617 if (!e->indirect_unknown_callee
618 || !e->indirect_info)
620 error ("An indirect edge from %s is not marked as indirect or has "
621 "associated indirect_info, the corresponding statement is: ",
622 identifier_to_locale (cgraph_node_name (e->caller)));
623 cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
627 for (e = node->callers; e; e = e->next_caller)
629 if (verify_edge_count_and_frequency (e))
631 if (!e->inline_failed)
633 if (node->global.inlined_to
634 != (e->caller->global.inlined_to
635 ? e->caller->global.inlined_to : e->caller))
637 error ("inlined_to pointer is wrong");
640 if (node->callers->next_caller)
642 error ("multiple inline callers");
647 if (node->global.inlined_to)
649 error ("inlined_to pointer set for noninline callers");
653 for (e = node->indirect_calls; e; e = e->next_callee)
654 if (verify_edge_count_and_frequency (e))
656 if (!node->callers && node->global.inlined_to)
658 error ("inlined_to pointer is set but no predecessors found");
661 if (node->global.inlined_to == node)
663 error ("inlined_to pointer refers to itself");
669 struct cgraph_node *n;
670 for (n = node->clone_of->clones; n; n = n->next_sibling_clone)
675 error ("node has wrong clone_of");
681 struct cgraph_node *n;
682 for (n = node->clones; n; n = n->next_sibling_clone)
683 if (n->clone_of != node)
687 error ("node has wrong clone list");
691 if ((node->prev_sibling_clone || node->next_sibling_clone) && !node->clone_of)
693 error ("node is in clone list but it is not clone");
696 if (!node->prev_sibling_clone && node->clone_of && node->clone_of->clones != node)
698 error ("node has wrong prev_clone pointer");
701 if (node->prev_sibling_clone && node->prev_sibling_clone->next_sibling_clone != node)
703 error ("double linked list of clones corrupted");
707 if (node->analyzed && node->alias)
709 bool ref_found = false;
715 error ("Alias has call edges");
718 for (i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list,
720 if (ref->use != IPA_REF_ALIAS)
722 error ("Alias has non-alias reference");
727 error ("Alias has more than one alias reference");
734 error ("Analyzed alias has no reference");
738 if (node->analyzed && node->thunk.thunk_p)
742 error ("No edge out of thunk node");
745 else if (node->callees->next_callee)
747 error ("More than one edge out of thunk node");
750 if (gimple_has_body_p (node->symbol.decl))
752 error ("Thunk is not supposed to have body");
756 else if (node->analyzed && gimple_has_body_p (node->symbol.decl)
757 && !TREE_ASM_WRITTEN (node->symbol.decl)
758 && (!DECL_EXTERNAL (node->symbol.decl) || node->global.inlined_to)
763 /* The nodes we're interested in are never shared, so walk
764 the tree ignoring duplicates. */
765 struct pointer_set_t *visited_nodes = pointer_set_create ();
766 /* Reach the trees by walking over the CFG, and note the
767 enclosing basic-blocks in the call edges. */
768 FOR_EACH_BB_FN (this_block, this_cfun)
769 for (gsi = gsi_start_bb (this_block);
773 gimple stmt = gsi_stmt (gsi);
774 if (is_gimple_call (stmt))
776 struct cgraph_edge *e = cgraph_edge (node, stmt);
777 tree decl = gimple_call_fndecl (stmt);
782 error ("shared call_stmt:");
783 cgraph_debug_gimple_stmt (this_cfun, stmt);
786 if (!e->indirect_unknown_callee)
788 if (verify_edge_corresponds_to_fndecl (e, decl))
790 error ("edge points to wrong declaration:");
791 debug_tree (e->callee->symbol.decl);
792 fprintf (stderr," Instead of:");
799 error ("an indirect edge with unknown callee "
800 "corresponding to a call_stmt with "
801 "a known declaration:");
803 cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
809 error ("missing callgraph edge for call stmt:");
810 cgraph_debug_gimple_stmt (this_cfun, stmt);
815 pointer_set_destroy (visited_nodes);
818 /* No CFG available?! */
821 for (e = node->callees; e; e = e->next_callee)
825 error ("edge %s->%s has no corresponding call_stmt",
826 identifier_to_locale (cgraph_node_name (e->caller)),
827 identifier_to_locale (cgraph_node_name (e->callee)));
828 cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
833 for (e = node->indirect_calls; e; e = e->next_callee)
837 error ("an indirect edge from %s has no corresponding call_stmt",
838 identifier_to_locale (cgraph_node_name (e->caller)));
839 cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
847 dump_cgraph_node (stderr, node);
848 internal_error ("verify_cgraph_node failed");
850 timevar_pop (TV_CGRAPH_VERIFY);
853 /* Verify whole cgraph structure. */
857 struct cgraph_node *node;
862 FOR_EACH_FUNCTION (node)
863 verify_cgraph_node (node);
866 /* Output all asm statements we have stored up to be output. */
869 cgraph_output_pending_asms (void)
871 struct cgraph_asm_node *can;
876 for (can = cgraph_asm_nodes; can; can = can->next)
877 assemble_asm (can->asm_str);
878 cgraph_asm_nodes = NULL;
881 /* Analyze the function scheduled to be output. */
883 cgraph_analyze_function (struct cgraph_node *node)
885 tree save = current_function_decl;
886 tree decl = node->symbol.decl;
888 if (node->alias && node->thunk.alias)
890 struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias);
891 struct cgraph_node *n;
893 for (n = tgt; n && n->alias;
894 n = n->analyzed ? cgraph_alias_aliased_node (n) : NULL)
897 error ("function %q+D part of alias cycle", node->symbol.decl);
901 if (!VEC_length (ipa_ref_t, node->symbol.ref_list.references))
902 ipa_record_reference ((symtab_node)node, (symtab_node)tgt,
903 IPA_REF_ALIAS, NULL);
904 if (node->same_body_alias)
906 DECL_VIRTUAL_P (node->symbol.decl) = DECL_VIRTUAL_P (node->thunk.alias);
907 DECL_DECLARED_INLINE_P (node->symbol.decl)
908 = DECL_DECLARED_INLINE_P (node->thunk.alias);
909 DECL_DISREGARD_INLINE_LIMITS (node->symbol.decl)
910 = DECL_DISREGARD_INLINE_LIMITS (node->thunk.alias);
913 /* Fixup visibility nonsences C++ frontend produce on same body aliases. */
914 if (TREE_PUBLIC (node->symbol.decl) && node->same_body_alias)
916 DECL_EXTERNAL (node->symbol.decl) = DECL_EXTERNAL (node->thunk.alias);
917 if (DECL_ONE_ONLY (node->thunk.alias))
919 DECL_COMDAT (node->symbol.decl) = DECL_COMDAT (node->thunk.alias);
920 DECL_COMDAT_GROUP (node->symbol.decl) = DECL_COMDAT_GROUP (node->thunk.alias);
921 if (DECL_ONE_ONLY (node->thunk.alias) && !node->symbol.same_comdat_group)
923 struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias);
924 node->symbol.same_comdat_group = (symtab_node)tgt;
925 if (!tgt->symbol.same_comdat_group)
926 tgt->symbol.same_comdat_group = (symtab_node)node;
930 for (n = tgt->symbol.same_comdat_group;
931 n->symbol.same_comdat_group != (symtab_node)tgt;
932 n = n->symbol.same_comdat_group)
934 n->symbol.same_comdat_group = (symtab_node)node;
939 if (node->symbol.address_taken)
940 cgraph_mark_address_taken_node (cgraph_alias_aliased_node (node));
942 else if (node->thunk.thunk_p)
944 cgraph_create_edge (node, cgraph_get_node (node->thunk.alias),
945 NULL, 0, CGRAPH_FREQ_BASE);
949 current_function_decl = decl;
950 push_cfun (DECL_STRUCT_FUNCTION (decl));
952 assign_assembler_name_if_neeeded (node->symbol.decl);
954 /* Make sure to gimplify bodies only once. During analyzing a
955 function we lower it, which will require gimplified nested
956 functions, so we can end up here with an already gimplified
958 if (!gimple_body (decl))
959 gimplify_function_tree (decl);
960 dump_function (TDI_generic, decl);
962 /* Lower the function. */
966 lower_nested_functions (node->symbol.decl);
967 gcc_assert (!node->nested);
969 gimple_register_cfg_hooks ();
970 bitmap_obstack_initialize (NULL);
971 execute_pass_list (all_lowering_passes);
972 free_dominance_info (CDI_POST_DOMINATORS);
973 free_dominance_info (CDI_DOMINATORS);
975 bitmap_obstack_release (NULL);
976 node->lowered = true;
981 node->analyzed = true;
983 current_function_decl = save;
986 /* C++ frontend produce same body aliases all over the place, even before PCH
987 gets streamed out. It relies on us linking the aliases with their function
988 in order to do the fixups, but ipa-ref is not PCH safe. Consequentely we
989 first produce aliases without links, but once C++ FE is sure he won't sream
990 PCH we build the links via this function. */
993 cgraph_process_same_body_aliases (void)
995 struct cgraph_node *node;
996 FOR_EACH_FUNCTION (node)
997 if (node->same_body_alias
998 && !VEC_length (ipa_ref_t, node->symbol.ref_list.references))
1000 struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias);
1001 ipa_record_reference ((symtab_node)node, (symtab_node)tgt,
1002 IPA_REF_ALIAS, NULL);
1004 same_body_aliases_done = true;
1007 /* Process attributes common for vars and functions. */
1010 process_common_attributes (tree decl)
1012 tree weakref = lookup_attribute ("weakref", DECL_ATTRIBUTES (decl));
1014 if (weakref && !lookup_attribute ("alias", DECL_ATTRIBUTES (decl)))
1016 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
1017 "%<weakref%> attribute should be accompanied with"
1018 " an %<alias%> attribute");
1019 DECL_WEAK (decl) = 0;
1020 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
1021 DECL_ATTRIBUTES (decl));
1025 /* Look for externally_visible and used attributes and mark cgraph nodes
1028 We cannot mark the nodes at the point the attributes are processed (in
1029 handle_*_attribute) because the copy of the declarations available at that
1030 point may not be canonical. For example, in:
1033 void f() __attribute__((used));
1035 the declaration we see in handle_used_attribute will be the second
1036 declaration -- but the front end will subsequently merge that declaration
1037 with the original declaration and discard the second declaration.
1039 Furthermore, we can't mark these nodes in cgraph_finalize_function because:
1042 void f() __attribute__((externally_visible));
1046 So, we walk the nodes at the end of the translation unit, applying the
1047 attributes at that point. */
1050 process_function_and_variable_attributes (struct cgraph_node *first,
1051 struct varpool_node *first_var)
1053 struct cgraph_node *node;
1054 struct varpool_node *vnode;
1056 for (node = cgraph_first_function (); node != first;
1057 node = cgraph_next_function (node))
1059 tree decl = node->symbol.decl;
1060 if (DECL_PRESERVE_P (decl))
1061 cgraph_mark_force_output_node (node);
1062 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
1064 if (! TREE_PUBLIC (node->symbol.decl))
1065 warning_at (DECL_SOURCE_LOCATION (node->symbol.decl), OPT_Wattributes,
1066 "%<externally_visible%>"
1067 " attribute have effect only on public objects");
1069 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
1070 && (node->local.finalized && !node->alias))
1072 warning_at (DECL_SOURCE_LOCATION (node->symbol.decl), OPT_Wattributes,
1073 "%<weakref%> attribute ignored"
1074 " because function is defined");
1075 DECL_WEAK (decl) = 0;
1076 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
1077 DECL_ATTRIBUTES (decl));
1080 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl))
1081 && !DECL_DECLARED_INLINE_P (decl)
1082 /* redefining extern inline function makes it DECL_UNINLINABLE. */
1083 && !DECL_UNINLINABLE (decl))
1084 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
1085 "always_inline function might not be inlinable");
1087 process_common_attributes (decl);
1089 for (vnode = varpool_first_variable (); vnode != first_var;
1090 vnode = varpool_next_variable (vnode))
1092 tree decl = vnode->symbol.decl;
1093 if (DECL_PRESERVE_P (decl))
1094 vnode->symbol.force_output = true;
1095 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
1097 if (! TREE_PUBLIC (vnode->symbol.decl))
1098 warning_at (DECL_SOURCE_LOCATION (vnode->symbol.decl), OPT_Wattributes,
1099 "%<externally_visible%>"
1100 " attribute have effect only on public objects");
1102 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
1104 && DECL_INITIAL (decl))
1106 warning_at (DECL_SOURCE_LOCATION (vnode->symbol.decl), OPT_Wattributes,
1107 "%<weakref%> attribute ignored"
1108 " because variable is initialized");
1109 DECL_WEAK (decl) = 0;
1110 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
1111 DECL_ATTRIBUTES (decl));
1113 process_common_attributes (decl);
1117 /* Return true when there are references to NODE. */
1120 referred_to_p (symtab_node node)
1123 struct ipa_ref *ref;
1125 for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list, i, ref);
1128 if (symtab_function_p (node) && cgraph (node)->callers)
1133 /* Mark DECL as finalized. By finalizing the declaration, frontend instruct the
1134 middle end to output the variable to asm file, if needed or externally
1138 varpool_finalize_decl (tree decl)
1140 struct varpool_node *node = varpool_node (decl);
1142 gcc_assert (TREE_STATIC (decl));
1144 if (node->finalized)
1146 notice_global_symbol (decl);
1147 node->finalized = true;
1148 if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
1149 /* Traditionally we do not eliminate static variables when not
1150 optimizing and when not doing toplevel reoder. */
1151 || (!flag_toplevel_reorder && !DECL_COMDAT (node->symbol.decl)
1152 && !DECL_ARTIFICIAL (node->symbol.decl)))
1153 node->symbol.force_output = true;
1155 if (cgraph_state == CGRAPH_STATE_CONSTRUCTION
1156 && (decide_is_variable_needed (node, decl)
1157 || referred_to_p ((symtab_node)node)))
1158 enqueue_node ((symtab_node)node);
1159 if (cgraph_state >= CGRAPH_STATE_IPA_SSA)
1160 varpool_analyze_node (node);
1163 /* Discover all functions and variables that are trivially needed, analyze
1164 them as well as all functions and variables referred by them */
1167 cgraph_analyze_functions (void)
1169 /* Keep track of already processed nodes when called multiple times for
1170 intermodule optimization. */
1171 static struct cgraph_node *first_analyzed;
1172 struct cgraph_node *first_handled = first_analyzed;
1173 static struct varpool_node *first_analyzed_var;
1174 struct varpool_node *first_handled_var = first_analyzed_var;
1176 symtab_node node, next;
1178 struct ipa_ref *ref;
1179 bool changed = true;
1181 bitmap_obstack_initialize (NULL);
1182 cgraph_state = CGRAPH_STATE_CONSTRUCTION;
1184 /* Analysis adds static variables that in turn adds references to new functions.
1185 So we need to iterate the process until it stabilize. */
1189 process_function_and_variable_attributes (first_analyzed,
1190 first_analyzed_var);
1192 /* First identify the trivially needed symbols. */
1193 for (node = symtab_nodes;
1194 node != (symtab_node)first_analyzed
1195 && node != (symtab_node)first_analyzed_var; node = node->symbol.next)
1197 if ((symtab_function_p (node)
1198 && cgraph (node)->local.finalized
1199 && cgraph_decide_is_function_needed (cgraph (node), node->symbol.decl))
1200 || (symtab_variable_p (node)
1201 && varpool (node)->finalized
1202 && !DECL_EXTERNAL (node->symbol.decl)
1203 && decide_is_variable_needed (varpool (node), node->symbol.decl)))
1205 enqueue_node (node);
1206 if (!changed && cgraph_dump_file)
1207 fprintf (cgraph_dump_file, "Trivially needed symbols:");
1209 if (cgraph_dump_file)
1210 fprintf (cgraph_dump_file, " %s", symtab_node_asm_name (node));
1212 if (node == (symtab_node)first_analyzed
1213 || node == (symtab_node)first_analyzed_var)
1216 cgraph_process_new_functions ();
1217 first_analyzed_var = varpool_first_variable ();
1218 first_analyzed = cgraph_first_function ();
1220 if (changed && dump_file)
1221 fprintf (cgraph_dump_file, "\n");
1223 /* Lower representation, build callgraph edges and references for all trivially
1224 needed symbols and all symbols referred by them. */
1225 while (first != (symtab_node)(void *)1)
1229 first = (symtab_node)first->symbol.aux;
1230 if (symtab_function_p (node) && cgraph (node)->local.finalized)
1232 struct cgraph_edge *edge;
1233 struct cgraph_node *cnode;
1236 cnode = cgraph (node);
1237 decl = cnode->symbol.decl;
1239 /* ??? It is possible to create extern inline function and later using
1240 weak alias attribute to kill its body. See
1241 gcc.c-torture/compile/20011119-1.c */
1242 if (!DECL_STRUCT_FUNCTION (decl)
1243 && (!cnode->alias || !cnode->thunk.alias)
1244 && !cnode->thunk.thunk_p)
1246 cgraph_reset_node (cnode);
1247 cnode->local.redefined_extern_inline = true;
1251 if (!cnode->analyzed)
1252 cgraph_analyze_function (cnode);
1254 for (edge = cnode->callees; edge; edge = edge->next_callee)
1255 if (edge->callee->local.finalized)
1256 enqueue_node ((symtab_node)edge->callee);
1258 /* If decl is a clone of an abstract function, mark that abstract
1259 function so that we don't release its body. The DECL_INITIAL() of that
1260 abstract function declaration will be later needed to output debug
1262 if (DECL_ABSTRACT_ORIGIN (decl))
1264 struct cgraph_node *origin_node;
1265 origin_node = cgraph_get_node (DECL_ABSTRACT_ORIGIN (decl));
1266 origin_node->abstract_and_needed = true;
1270 else if (symtab_variable_p (node)
1271 && varpool (node)->finalized)
1272 varpool_analyze_node (varpool (node));
1274 if (node->symbol.same_comdat_group)
1277 for (next = node->symbol.same_comdat_group;
1279 next = next->symbol.same_comdat_group)
1280 enqueue_node (next);
1282 for (i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list, i, ref); i++)
1283 if ((symtab_function_p (ref->referred) && cgraph (ref->referred)->local.finalized)
1284 || (symtab_variable_p (ref->referred) && varpool (ref->referred)->finalized))
1285 enqueue_node (ref->referred);
1286 cgraph_process_new_functions ();
1290 /* Collect entry points to the unit. */
1291 if (cgraph_dump_file)
1293 fprintf (cgraph_dump_file, "\n\nInitial ");
1294 dump_symtab (cgraph_dump_file);
1297 if (cgraph_dump_file)
1298 fprintf (cgraph_dump_file, "\nRemoving unused symbols:");
1300 for (node = symtab_nodes;
1301 node != (symtab_node)first_handled
1302 && node != (symtab_node)first_handled_var; node = next)
1304 next = node->symbol.next;
1305 if (!node->symbol.aux && !referred_to_p (node))
1307 if (cgraph_dump_file)
1308 fprintf (cgraph_dump_file, " %s", symtab_node_name (node));
1309 symtab_remove_node (node);
1312 if (symtab_function_p (node))
1314 tree decl = node->symbol.decl;
1315 struct cgraph_node *cnode = cgraph (node);
1317 if (cnode->local.finalized && !gimple_has_body_p (decl)
1318 && (!cnode->alias || !cnode->thunk.alias)
1319 && !cnode->thunk.thunk_p)
1320 cgraph_reset_node (cnode);
1322 gcc_assert (!cnode->local.finalized || cnode->thunk.thunk_p
1324 || gimple_has_body_p (decl));
1325 gcc_assert (cnode->analyzed == cnode->local.finalized);
1327 node->symbol.aux = NULL;
1329 first_analyzed = cgraph_first_function ();
1330 first_analyzed_var = varpool_first_variable ();
1331 if (cgraph_dump_file)
1333 fprintf (cgraph_dump_file, "\n\nReclaimed ");
1334 dump_symtab (cgraph_dump_file);
1336 bitmap_obstack_release (NULL);
1340 /* Translate the ugly representation of aliases as alias pairs into nice
1341 representation in callgraph. We don't handle all cases yet,
1345 handle_alias_pairs (void)
1349 struct cgraph_node *target_node;
1350 struct cgraph_node *src_node;
1351 struct varpool_node *target_vnode;
1353 for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p);)
1355 if (TREE_CODE (p->decl) == FUNCTION_DECL
1356 && (target_node = cgraph_node_for_asm (p->target)) != NULL)
1358 src_node = cgraph_get_node (p->decl);
1359 if (src_node && src_node->local.finalized)
1360 cgraph_reset_node (src_node);
1361 /* Normally EXTERNAL flag is used to mark external inlines,
1362 however for aliases it seems to be allowed to use it w/o
1363 any meaning. See gcc.dg/attr-alias-3.c
1364 However for weakref we insist on EXTERNAL flag being set.
1365 See gcc.dg/attr-alias-5.c */
1366 if (DECL_EXTERNAL (p->decl))
1367 DECL_EXTERNAL (p->decl)
1368 = lookup_attribute ("weakref",
1369 DECL_ATTRIBUTES (p->decl)) != NULL;
1370 cgraph_create_function_alias (p->decl, target_node->symbol.decl);
1371 VEC_unordered_remove (alias_pair, alias_pairs, i);
1373 else if (TREE_CODE (p->decl) == VAR_DECL
1374 && (target_vnode = varpool_node_for_asm (p->target)) != NULL)
1376 /* Normally EXTERNAL flag is used to mark external inlines,
1377 however for aliases it seems to be allowed to use it w/o
1378 any meaning. See gcc.dg/attr-alias-3.c
1379 However for weakref we insist on EXTERNAL flag being set.
1380 See gcc.dg/attr-alias-5.c */
1381 if (DECL_EXTERNAL (p->decl))
1382 DECL_EXTERNAL (p->decl)
1383 = lookup_attribute ("weakref",
1384 DECL_ATTRIBUTES (p->decl)) != NULL;
1385 varpool_create_variable_alias (p->decl, target_vnode->symbol.decl);
1386 VEC_unordered_remove (alias_pair, alias_pairs, i);
1388 /* Weakrefs with target not defined in current unit are easy to handle; they
1389 behave just as external variables except we need to note the alias flag
1390 to later output the weakref pseudo op into asm file. */
1391 else if (lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL
1392 && (TREE_CODE (p->decl) == FUNCTION_DECL
1393 ? (varpool_node_for_asm (p->target) == NULL)
1394 : (cgraph_node_for_asm (p->target) == NULL)))
1396 if (TREE_CODE (p->decl) == FUNCTION_DECL)
1397 cgraph_get_create_node (p->decl)->alias = true;
1399 varpool_get_node (p->decl)->alias = true;
1400 DECL_EXTERNAL (p->decl) = 1;
1401 VEC_unordered_remove (alias_pair, alias_pairs, i);
1406 fprintf (dump_file, "Unhandled alias %s->%s\n",
1407 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (p->decl)),
1408 IDENTIFIER_POINTER (p->target));
1416 /* Figure out what functions we want to assemble. */
1419 cgraph_mark_functions_to_output (void)
1421 struct cgraph_node *node;
1422 #ifdef ENABLE_CHECKING
1423 bool check_same_comdat_groups = false;
1425 FOR_EACH_FUNCTION (node)
1426 gcc_assert (!node->process);
1429 FOR_EACH_FUNCTION (node)
1431 tree decl = node->symbol.decl;
1432 struct cgraph_edge *e;
1434 gcc_assert (!node->process || node->symbol.same_comdat_group);
1438 for (e = node->callers; e; e = e->next_caller)
1439 if (e->inline_failed)
1442 /* We need to output all local functions that are used and not
1443 always inlined, as well as those that are reachable from
1444 outside the current compilation unit. */
1446 && !node->thunk.thunk_p
1448 && !node->global.inlined_to
1449 && !TREE_ASM_WRITTEN (decl)
1450 && !DECL_EXTERNAL (decl))
1453 if (node->symbol.same_comdat_group)
1455 struct cgraph_node *next;
1456 for (next = cgraph (node->symbol.same_comdat_group);
1458 next = cgraph (next->symbol.same_comdat_group))
1459 if (!next->thunk.thunk_p && !next->alias)
1463 else if (node->symbol.same_comdat_group)
1465 #ifdef ENABLE_CHECKING
1466 check_same_comdat_groups = true;
1471 /* We should've reclaimed all functions that are not needed. */
1472 #ifdef ENABLE_CHECKING
1473 if (!node->global.inlined_to
1474 && gimple_has_body_p (decl)
1475 /* FIXME: in ltrans unit when offline copy is outside partition but inline copies
1476 are inside partition, we can end up not removing the body since we no longer
1477 have analyzed node pointing to it. */
1478 && !node->symbol.in_other_partition
1480 && !DECL_EXTERNAL (decl))
1482 dump_cgraph_node (stderr, node);
1483 internal_error ("failed to reclaim unneeded function");
1486 gcc_assert (node->global.inlined_to
1487 || !gimple_has_body_p (decl)
1488 || node->symbol.in_other_partition
1489 || DECL_EXTERNAL (decl));
1494 #ifdef ENABLE_CHECKING
1495 if (check_same_comdat_groups)
1496 FOR_EACH_FUNCTION (node)
1497 if (node->symbol.same_comdat_group && !node->process)
1499 tree decl = node->symbol.decl;
1500 if (!node->global.inlined_to
1501 && gimple_has_body_p (decl)
1502 /* FIXME: in an ltrans unit when the offline copy is outside a
1503 partition but inline copies are inside a partition, we can
1504 end up not removing the body since we no longer have an
1505 analyzed node pointing to it. */
1506 && !node->symbol.in_other_partition
1507 && !DECL_EXTERNAL (decl))
1509 dump_cgraph_node (stderr, node);
1510 internal_error ("failed to reclaim unneeded function in same "
1517 /* DECL is FUNCTION_DECL. Initialize datastructures so DECL is a function
1518 in lowered gimple form.
1520 Set current_function_decl and cfun to newly constructed empty function body.
1521 return basic block in the function body. */
1524 init_lowered_empty_function (tree decl)
1528 current_function_decl = decl;
1529 allocate_struct_function (decl, false);
1530 gimple_register_cfg_hooks ();
1531 init_empty_tree_cfg ();
1532 init_tree_ssa (cfun);
1533 init_ssa_operands ();
1534 cfun->gimple_df->in_ssa_p = true;
1535 DECL_INITIAL (decl) = make_node (BLOCK);
1537 DECL_SAVED_TREE (decl) = error_mark_node;
1538 cfun->curr_properties |=
1539 (PROP_gimple_lcf | PROP_gimple_leh | PROP_cfg | PROP_referenced_vars |
1540 PROP_ssa | PROP_gimple_any);
1542 /* Create BB for body of the function and connect it properly. */
1543 bb = create_basic_block (NULL, (void *) 0, ENTRY_BLOCK_PTR);
1544 make_edge (ENTRY_BLOCK_PTR, bb, 0);
1545 make_edge (bb, EXIT_BLOCK_PTR, 0);
1550 /* Adjust PTR by the constant FIXED_OFFSET, and by the vtable
1551 offset indicated by VIRTUAL_OFFSET, if that is
1552 non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and
1553 zero for a result adjusting thunk. */
1556 thunk_adjust (gimple_stmt_iterator * bsi,
1557 tree ptr, bool this_adjusting,
1558 HOST_WIDE_INT fixed_offset, tree virtual_offset)
1564 && fixed_offset != 0)
1566 stmt = gimple_build_assign
1567 (ptr, fold_build_pointer_plus_hwi_loc (input_location,
1570 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1573 /* If there's a virtual offset, look up that value in the vtable and
1574 adjust the pointer again. */
1581 if (!vtable_entry_type)
1583 tree vfunc_type = make_node (FUNCTION_TYPE);
1584 TREE_TYPE (vfunc_type) = integer_type_node;
1585 TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
1586 layout_type (vfunc_type);
1588 vtable_entry_type = build_pointer_type (vfunc_type);
1592 create_tmp_var (build_pointer_type
1593 (build_pointer_type (vtable_entry_type)), "vptr");
1595 /* The vptr is always at offset zero in the object. */
1596 stmt = gimple_build_assign (vtabletmp,
1597 build1 (NOP_EXPR, TREE_TYPE (vtabletmp),
1599 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1600 mark_symbols_for_renaming (stmt);
1601 find_referenced_vars_in (stmt);
1603 /* Form the vtable address. */
1604 vtabletmp2 = create_tmp_var (TREE_TYPE (TREE_TYPE (vtabletmp)),
1606 stmt = gimple_build_assign (vtabletmp2,
1607 build_simple_mem_ref (vtabletmp));
1608 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1609 mark_symbols_for_renaming (stmt);
1610 find_referenced_vars_in (stmt);
1612 /* Find the entry with the vcall offset. */
1613 stmt = gimple_build_assign (vtabletmp2,
1614 fold_build_pointer_plus_loc (input_location,
1617 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1619 /* Get the offset itself. */
1620 vtabletmp3 = create_tmp_var (TREE_TYPE (TREE_TYPE (vtabletmp2)),
1622 stmt = gimple_build_assign (vtabletmp3,
1623 build_simple_mem_ref (vtabletmp2));
1624 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1625 mark_symbols_for_renaming (stmt);
1626 find_referenced_vars_in (stmt);
1628 /* Adjust the `this' pointer. */
1629 ptr = fold_build_pointer_plus_loc (input_location, ptr, vtabletmp3);
1630 ptr = force_gimple_operand_gsi (bsi, ptr, true, NULL_TREE, false,
1631 GSI_CONTINUE_LINKING);
1635 && fixed_offset != 0)
1636 /* Adjust the pointer by the constant. */
1640 if (TREE_CODE (ptr) == VAR_DECL)
1644 ptrtmp = create_tmp_var (TREE_TYPE (ptr), "ptr");
1645 stmt = gimple_build_assign (ptrtmp, ptr);
1646 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1647 mark_symbols_for_renaming (stmt);
1648 find_referenced_vars_in (stmt);
1650 ptr = fold_build_pointer_plus_hwi_loc (input_location,
1651 ptrtmp, fixed_offset);
1654 /* Emit the statement and gimplify the adjustment expression. */
1655 ret = create_tmp_var (TREE_TYPE (ptr), "adjusted_this");
1656 stmt = gimple_build_assign (ret, ptr);
1657 mark_symbols_for_renaming (stmt);
1658 find_referenced_vars_in (stmt);
1659 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1664 /* Produce assembler for thunk NODE. */
1667 assemble_thunk (struct cgraph_node *node)
1669 bool this_adjusting = node->thunk.this_adjusting;
1670 HOST_WIDE_INT fixed_offset = node->thunk.fixed_offset;
1671 HOST_WIDE_INT virtual_value = node->thunk.virtual_value;
1672 tree virtual_offset = NULL;
1673 tree alias = node->thunk.alias;
1674 tree thunk_fndecl = node->symbol.decl;
1675 tree a = DECL_ARGUMENTS (thunk_fndecl);
1677 current_function_decl = thunk_fndecl;
1679 /* Ensure thunks are emitted in their correct sections. */
1680 resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
1683 && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
1684 virtual_value, alias))
1688 tree restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1690 DECL_RESULT (thunk_fndecl)
1691 = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl),
1692 RESULT_DECL, 0, restype);
1693 fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
1695 /* The back end expects DECL_INITIAL to contain a BLOCK, so we
1697 fn_block = make_node (BLOCK);
1698 BLOCK_VARS (fn_block) = a;
1699 DECL_INITIAL (thunk_fndecl) = fn_block;
1700 init_function_start (thunk_fndecl);
1702 assemble_start_function (thunk_fndecl, fnname);
1704 targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl,
1705 fixed_offset, virtual_value, alias);
1707 assemble_end_function (thunk_fndecl, fnname);
1708 init_insn_lengths ();
1709 free_after_compilation (cfun);
1711 TREE_ASM_WRITTEN (thunk_fndecl) = 1;
1712 node->thunk.thunk_p = false;
1713 node->analyzed = false;
1718 basic_block bb, then_bb, else_bb, return_bb;
1719 gimple_stmt_iterator bsi;
1725 VEC(tree, heap) *vargs;
1730 DECL_IGNORED_P (thunk_fndecl) = 1;
1731 bitmap_obstack_initialize (NULL);
1733 if (node->thunk.virtual_offset_p)
1734 virtual_offset = size_int (virtual_value);
1736 /* Build the return declaration for the function. */
1737 restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1738 if (DECL_RESULT (thunk_fndecl) == NULL_TREE)
1740 resdecl = build_decl (input_location, RESULT_DECL, 0, restype);
1741 DECL_ARTIFICIAL (resdecl) = 1;
1742 DECL_IGNORED_P (resdecl) = 1;
1743 DECL_RESULT (thunk_fndecl) = resdecl;
1746 resdecl = DECL_RESULT (thunk_fndecl);
1748 bb = then_bb = else_bb = return_bb = init_lowered_empty_function (thunk_fndecl);
1750 bsi = gsi_start_bb (bb);
1752 /* Build call to the function being thunked. */
1753 if (!VOID_TYPE_P (restype))
1755 if (!is_gimple_reg_type (restype))
1758 add_local_decl (cfun, restmp);
1759 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp;
1762 restmp = create_tmp_var_raw (restype, "retval");
1765 for (arg = a; arg; arg = DECL_CHAIN (arg))
1767 vargs = VEC_alloc (tree, heap, nargs);
1769 VEC_quick_push (tree, vargs,
1774 VEC_quick_push (tree, vargs, a);
1775 for (i = 1, arg = DECL_CHAIN (a); i < nargs; i++, arg = DECL_CHAIN (arg))
1776 VEC_quick_push (tree, vargs, arg);
1777 call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs);
1778 VEC_free (tree, heap, vargs);
1779 gimple_call_set_from_thunk (call, true);
1781 gimple_call_set_lhs (call, restmp);
1782 gsi_insert_after (&bsi, call, GSI_NEW_STMT);
1783 mark_symbols_for_renaming (call);
1784 find_referenced_vars_in (call);
1787 if (restmp && !this_adjusting)
1789 tree true_label = NULL_TREE;
1791 if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE)
1794 /* If the return type is a pointer, we need to
1795 protect against NULL. We know there will be an
1796 adjustment, because that's why we're emitting a
1798 then_bb = create_basic_block (NULL, (void *) 0, bb);
1799 return_bb = create_basic_block (NULL, (void *) 0, then_bb);
1800 else_bb = create_basic_block (NULL, (void *) 0, else_bb);
1801 remove_edge (single_succ_edge (bb));
1802 true_label = gimple_block_label (then_bb);
1803 stmt = gimple_build_cond (NE_EXPR, restmp,
1804 build_zero_cst (TREE_TYPE (restmp)),
1805 NULL_TREE, NULL_TREE);
1806 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1807 make_edge (bb, then_bb, EDGE_TRUE_VALUE);
1808 make_edge (bb, else_bb, EDGE_FALSE_VALUE);
1809 make_edge (return_bb, EXIT_BLOCK_PTR, 0);
1810 make_edge (then_bb, return_bb, EDGE_FALLTHRU);
1811 make_edge (else_bb, return_bb, EDGE_FALLTHRU);
1812 bsi = gsi_last_bb (then_bb);
1815 restmp = thunk_adjust (&bsi, restmp, /*this_adjusting=*/0,
1816 fixed_offset, virtual_offset);
1820 bsi = gsi_last_bb (else_bb);
1821 stmt = gimple_build_assign (restmp,
1822 build_zero_cst (TREE_TYPE (restmp)));
1823 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1824 bsi = gsi_last_bb (return_bb);
1828 gimple_call_set_tail (call, true);
1830 /* Build return value. */
1831 ret = gimple_build_return (restmp);
1832 gsi_insert_after (&bsi, ret, GSI_NEW_STMT);
1834 delete_unreachable_blocks ();
1835 update_ssa (TODO_update_ssa);
1837 /* Since we want to emit the thunk, we explicitly mark its name as
1839 node->thunk.thunk_p = false;
1840 cgraph_node_remove_callees (node);
1841 cgraph_add_new_function (thunk_fndecl, true);
1842 bitmap_obstack_release (NULL);
1844 current_function_decl = NULL;
1849 /* Assemble thunks and aliases asociated to NODE. */
1852 assemble_thunks_and_aliases (struct cgraph_node *node)
1854 struct cgraph_edge *e;
1856 struct ipa_ref *ref;
1858 for (e = node->callers; e;)
1859 if (e->caller->thunk.thunk_p)
1861 struct cgraph_node *thunk = e->caller;
1864 assemble_thunks_and_aliases (thunk);
1865 assemble_thunk (thunk);
1869 for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list,
1871 if (ref->use == IPA_REF_ALIAS)
1873 struct cgraph_node *alias = ipa_ref_referring_node (ref);
1874 bool saved_written = TREE_ASM_WRITTEN (alias->thunk.alias);
1876 /* Force assemble_alias to really output the alias this time instead
1877 of buffering it in same alias pairs. */
1878 TREE_ASM_WRITTEN (alias->thunk.alias) = 1;
1879 assemble_alias (alias->symbol.decl,
1880 DECL_ASSEMBLER_NAME (alias->thunk.alias));
1881 assemble_thunks_and_aliases (alias);
1882 TREE_ASM_WRITTEN (alias->thunk.alias) = saved_written;
1886 /* Perform IPA transforms and all further optimizations and compilation
1890 tree_rest_of_compilation (struct cgraph_node *node)
1892 tree fndecl = node->symbol.decl;
1893 location_t saved_loc;
1895 timevar_push (TV_REST_OF_COMPILATION);
1897 gcc_assert (cgraph_global_info_ready);
1899 /* Initialize the default bitmap obstack. */
1900 bitmap_obstack_initialize (NULL);
1902 /* Initialize the RTL code for the function. */
1903 current_function_decl = fndecl;
1904 saved_loc = input_location;
1905 input_location = DECL_SOURCE_LOCATION (fndecl);
1906 init_function_start (fndecl);
1908 gimple_register_cfg_hooks ();
1910 bitmap_obstack_initialize (®_obstack); /* FIXME, only at RTL generation*/
1912 execute_all_ipa_transforms ();
1914 /* Perform all tree transforms and optimizations. */
1916 /* Signal the start of passes. */
1917 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START, NULL);
1919 execute_pass_list (all_passes);
1921 /* Signal the end of passes. */
1922 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END, NULL);
1924 bitmap_obstack_release (®_obstack);
1926 /* Release the default bitmap obstack. */
1927 bitmap_obstack_release (NULL);
1931 /* If requested, warn about function definitions where the function will
1932 return a value (usually of some struct or union type) which itself will
1933 take up a lot of stack space. */
1934 if (warn_larger_than && !DECL_EXTERNAL (fndecl) && TREE_TYPE (fndecl))
1936 tree ret_type = TREE_TYPE (TREE_TYPE (fndecl));
1938 if (ret_type && TYPE_SIZE_UNIT (ret_type)
1939 && TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST
1940 && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type),
1943 unsigned int size_as_int
1944 = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type));
1946 if (compare_tree_int (TYPE_SIZE_UNIT (ret_type), size_as_int) == 0)
1947 warning (OPT_Wlarger_than_, "size of return value of %q+D is %u bytes",
1948 fndecl, size_as_int);
1950 warning (OPT_Wlarger_than_, "size of return value of %q+D is larger than %wd bytes",
1951 fndecl, larger_than_size);
1955 gimple_set_body (fndecl, NULL);
1956 if (DECL_STRUCT_FUNCTION (fndecl) == 0
1957 && !cgraph_get_node (fndecl)->origin)
1959 /* Stop pointing to the local nodes about to be freed.
1960 But DECL_INITIAL must remain nonzero so we know this
1961 was an actual function definition.
1962 For a nested function, this is done in c_pop_function_context.
1963 If rest_of_compilation set this to 0, leave it 0. */
1964 if (DECL_INITIAL (fndecl) != 0)
1965 DECL_INITIAL (fndecl) = error_mark_node;
1968 input_location = saved_loc;
1971 timevar_pop (TV_REST_OF_COMPILATION);
1974 /* Expand function specified by NODE. */
1977 cgraph_expand_function (struct cgraph_node *node)
1979 tree decl = node->symbol.decl;
1981 /* We ought to not compile any inline clones. */
1982 gcc_assert (!node->global.inlined_to);
1984 announce_function (decl);
1986 gcc_assert (node->lowered);
1988 /* Generate RTL for the body of DECL. */
1989 tree_rest_of_compilation (node);
1991 /* Make sure that BE didn't give up on compiling. */
1992 gcc_assert (TREE_ASM_WRITTEN (decl));
1993 current_function_decl = NULL;
1994 gcc_assert (!cgraph_preserve_function_body_p (node));
1996 /* It would make a lot more sense to output thunks before function body to get more
1997 forward and lest backwarding jumps. This is however would need solving problem
1998 with comdats. See PR48668. Also aliases must come after function itself to
1999 make one pass assemblers, like one on AIX happy. See PR 50689.
2000 FIXME: Perhaps thunks should be move before function IFF they are not in comdat
2002 assemble_thunks_and_aliases (node);
2003 cgraph_release_function_body (node);
2004 /* Eliminate all call edges. This is important so the GIMPLE_CALL no longer
2005 points to the dead function body. */
2006 cgraph_node_remove_callees (node);
2009 /* Return true when CALLER_DECL should be inlined into CALLEE_DECL. */
2012 cgraph_inline_p (struct cgraph_edge *e, cgraph_inline_failed_t *reason)
2014 *reason = e->inline_failed;
2015 return !e->inline_failed;
2020 /* Expand all functions that must be output.
2022 Attempt to topologically sort the nodes so function is output when
2023 all called functions are already assembled to allow data to be
2024 propagated across the callgraph. Use a stack to get smaller distance
2025 between a function and its callees (later we may choose to use a more
2026 sophisticated algorithm for function reordering; we will likely want
2027 to use subsections to make the output functions appear in top-down
2031 cgraph_expand_all_functions (void)
2033 struct cgraph_node *node;
2034 struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
2035 int order_pos, new_order_pos = 0;
2038 order_pos = ipa_reverse_postorder (order);
2039 gcc_assert (order_pos == cgraph_n_nodes);
2041 /* Garbage collector may remove inline clones we eliminate during
2042 optimization. So we must be sure to not reference them. */
2043 for (i = 0; i < order_pos; i++)
2044 if (order[i]->process)
2045 order[new_order_pos++] = order[i];
2047 for (i = new_order_pos - 1; i >= 0; i--)
2053 cgraph_expand_function (node);
2056 cgraph_process_new_functions ();
2062 /* This is used to sort the node types by the cgraph order number. */
2064 enum cgraph_order_sort_kind
2066 ORDER_UNDEFINED = 0,
2072 struct cgraph_order_sort
2074 enum cgraph_order_sort_kind kind;
2077 struct cgraph_node *f;
2078 struct varpool_node *v;
2079 struct cgraph_asm_node *a;
2083 /* Output all functions, variables, and asm statements in the order
2084 according to their order fields, which is the order in which they
2085 appeared in the file. This implements -fno-toplevel-reorder. In
2086 this mode we may output functions and variables which don't really
2087 need to be output. */
2090 cgraph_output_in_order (void)
2093 struct cgraph_order_sort *nodes;
2095 struct cgraph_node *pf;
2096 struct varpool_node *pv;
2097 struct cgraph_asm_node *pa;
2100 nodes = XCNEWVEC (struct cgraph_order_sort, max);
2102 FOR_EACH_DEFINED_FUNCTION (pf)
2104 if (pf->process && !pf->thunk.thunk_p && !pf->alias)
2106 i = pf->symbol.order;
2107 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
2108 nodes[i].kind = ORDER_FUNCTION;
2113 FOR_EACH_DEFINED_VARIABLE (pv)
2115 i = pv->symbol.order;
2116 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
2117 nodes[i].kind = ORDER_VAR;
2121 for (pa = cgraph_asm_nodes; pa; pa = pa->next)
2124 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
2125 nodes[i].kind = ORDER_ASM;
2129 /* In toplevel reorder mode we output all statics; mark them as needed. */
2131 for (i = 0; i < max; ++i)
2132 if (nodes[i].kind == ORDER_VAR)
2133 varpool_finalize_named_section_flags (nodes[i].u.v);
2135 for (i = 0; i < max; ++i)
2137 switch (nodes[i].kind)
2139 case ORDER_FUNCTION:
2140 nodes[i].u.f->process = 0;
2141 cgraph_expand_function (nodes[i].u.f);
2145 varpool_assemble_decl (nodes[i].u.v);
2149 assemble_asm (nodes[i].u.a->asm_str);
2152 case ORDER_UNDEFINED:
2160 cgraph_asm_nodes = NULL;
2164 /* Return true when function body of DECL still needs to be kept around
2165 for later re-use. */
2167 cgraph_preserve_function_body_p (struct cgraph_node *node)
2169 gcc_assert (cgraph_global_info_ready);
2170 gcc_assert (!node->alias && !node->thunk.thunk_p);
2172 /* Look if there is any clone around. */
2182 current_function_decl = NULL;
2183 gimple_register_cfg_hooks ();
2184 bitmap_obstack_initialize (NULL);
2186 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START, NULL);
2190 execute_ipa_pass_list (all_small_ipa_passes);
2195 /* We never run removal of unreachable nodes after early passes. This is
2196 because TODO is run before the subpasses. It is important to remove
2197 the unreachable functions to save works at IPA level and to get LTO
2198 symbol tables right. */
2199 cgraph_remove_unreachable_nodes (true, cgraph_dump_file);
2201 /* If pass_all_early_optimizations was not scheduled, the state of
2202 the cgraph will not be properly updated. Update it now. */
2203 if (cgraph_state < CGRAPH_STATE_IPA_SSA)
2204 cgraph_state = CGRAPH_STATE_IPA_SSA;
2208 /* Generate coverage variables and constructors. */
2211 /* Process new functions added. */
2213 current_function_decl = NULL;
2214 cgraph_process_new_functions ();
2216 execute_ipa_summary_passes
2217 ((struct ipa_opt_pass_d *) all_regular_ipa_passes);
2220 /* Some targets need to handle LTO assembler output specially. */
2221 if (flag_generate_lto)
2222 targetm.asm_out.lto_start ();
2224 execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_lto_gen_passes);
2227 ipa_write_summaries ();
2229 if (flag_generate_lto)
2230 targetm.asm_out.lto_end ();
2232 if (!flag_ltrans && (in_lto_p || !flag_lto || flag_fat_lto_objects))
2233 execute_ipa_pass_list (all_regular_ipa_passes);
2234 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END, NULL);
2236 bitmap_obstack_release (NULL);
2240 /* Return string alias is alias of. */
2243 get_alias_symbol (tree decl)
2245 tree alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
2246 return get_identifier (TREE_STRING_POINTER
2247 (TREE_VALUE (TREE_VALUE (alias))));
2251 /* Weakrefs may be associated to external decls and thus not output
2252 at expansion time. Emit all neccesary aliases. */
2255 output_weakrefs (void)
2257 struct cgraph_node *node;
2258 struct varpool_node *vnode;
2259 FOR_EACH_FUNCTION (node)
2260 if (node->alias && DECL_EXTERNAL (node->symbol.decl)
2261 && !TREE_ASM_WRITTEN (node->symbol.decl)
2262 && lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
2263 assemble_alias (node->symbol.decl,
2264 node->thunk.alias ? DECL_ASSEMBLER_NAME (node->thunk.alias)
2265 : get_alias_symbol (node->symbol.decl));
2266 FOR_EACH_VARIABLE (vnode)
2267 if (vnode->alias && DECL_EXTERNAL (vnode->symbol.decl)
2268 && !TREE_ASM_WRITTEN (vnode->symbol.decl)
2269 && lookup_attribute ("weakref", DECL_ATTRIBUTES (vnode->symbol.decl)))
2270 assemble_alias (vnode->symbol.decl,
2271 vnode->alias_of ? DECL_ASSEMBLER_NAME (vnode->alias_of)
2272 : get_alias_symbol (vnode->symbol.decl));
2280 if (!cgraph_dump_file)
2281 cgraph_dump_file = dump_begin (TDI_cgraph, NULL);
2284 /* The edges representing the callers of the NEW_VERSION node were
2285 fixed by cgraph_function_versioning (), now the call_expr in their
2286 respective tree code should be updated to call the NEW_VERSION. */
2289 update_call_expr (struct cgraph_node *new_version)
2291 struct cgraph_edge *e;
2293 gcc_assert (new_version);
2295 /* Update the call expr on the edges to call the new version. */
2296 for (e = new_version->callers; e; e = e->next_caller)
2298 struct function *inner_function = DECL_STRUCT_FUNCTION (e->caller->symbol.decl);
2299 gimple_call_set_fndecl (e->call_stmt, new_version->symbol.decl);
2300 maybe_clean_eh_stmt_fn (inner_function, e->call_stmt);
2305 /* Create a new cgraph node which is the new version of
2306 OLD_VERSION node. REDIRECT_CALLERS holds the callers
2307 edges which should be redirected to point to
2308 NEW_VERSION. ALL the callees edges of OLD_VERSION
2309 are cloned to the new version node. Return the new
2312 If non-NULL BLOCK_TO_COPY determine what basic blocks
2313 was copied to prevent duplications of calls that are dead
2316 struct cgraph_node *
2317 cgraph_copy_node_for_versioning (struct cgraph_node *old_version,
2319 VEC(cgraph_edge_p,heap) *redirect_callers,
2322 struct cgraph_node *new_version;
2323 struct cgraph_edge *e;
2326 gcc_assert (old_version);
2328 new_version = cgraph_create_node (new_decl);
2330 new_version->analyzed = old_version->analyzed;
2331 new_version->local = old_version->local;
2332 new_version->symbol.externally_visible = false;
2333 new_version->local.local = old_version->analyzed;
2334 new_version->global = old_version->global;
2335 new_version->rtl = old_version->rtl;
2336 new_version->count = old_version->count;
2338 for (e = old_version->callees; e; e=e->next_callee)
2340 || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
2341 cgraph_clone_edge (e, new_version, e->call_stmt,
2342 e->lto_stmt_uid, REG_BR_PROB_BASE,
2345 for (e = old_version->indirect_calls; e; e=e->next_callee)
2347 || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
2348 cgraph_clone_edge (e, new_version, e->call_stmt,
2349 e->lto_stmt_uid, REG_BR_PROB_BASE,
2352 FOR_EACH_VEC_ELT (cgraph_edge_p, redirect_callers, i, e)
2354 /* Redirect calls to the old version node to point to its new
2356 cgraph_redirect_edge_callee (e, new_version);
2359 cgraph_call_node_duplication_hooks (old_version, new_version);
2364 /* Perform function versioning.
2365 Function versioning includes copying of the tree and
2366 a callgraph update (creating a new cgraph node and updating
2367 its callees and callers).
2369 REDIRECT_CALLERS varray includes the edges to be redirected
2372 TREE_MAP is a mapping of tree nodes we want to replace with
2373 new ones (according to results of prior analysis).
2374 OLD_VERSION_NODE is the node that is versioned.
2376 If non-NULL ARGS_TO_SKIP determine function parameters to remove
2378 If SKIP_RETURN is true, the new version will return void.
2379 If non-NULL BLOCK_TO_COPY determine what basic blocks to copy.
2380 If non_NULL NEW_ENTRY determine new entry BB of the clone.
2382 Return the new version's cgraph node. */
2384 struct cgraph_node *
2385 cgraph_function_versioning (struct cgraph_node *old_version_node,
2386 VEC(cgraph_edge_p,heap) *redirect_callers,
2387 VEC (ipa_replace_map_p,gc)* tree_map,
2388 bitmap args_to_skip,
2391 basic_block new_entry_block,
2392 const char *clone_name)
2394 tree old_decl = old_version_node->symbol.decl;
2395 struct cgraph_node *new_version_node = NULL;
2398 if (!tree_versionable_function_p (old_decl))
2401 gcc_assert (old_version_node->local.can_change_signature || !args_to_skip);
2403 /* Make a new FUNCTION_DECL tree node for the new version. */
2404 if (!args_to_skip && !skip_return)
2405 new_decl = copy_node (old_decl);
2408 = build_function_decl_skip_args (old_decl, args_to_skip, skip_return);
2410 /* Generate a new name for the new version. */
2411 DECL_NAME (new_decl) = clone_function_name (old_decl, clone_name);
2412 SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
2413 SET_DECL_RTL (new_decl, NULL);
2415 /* When the old decl was a con-/destructor make sure the clone isn't. */
2416 DECL_STATIC_CONSTRUCTOR(new_decl) = 0;
2417 DECL_STATIC_DESTRUCTOR(new_decl) = 0;
2419 /* Create the new version's call-graph node.
2420 and update the edges of the new node. */
2422 cgraph_copy_node_for_versioning (old_version_node, new_decl,
2423 redirect_callers, bbs_to_copy);
2425 /* Copy the OLD_VERSION_NODE function tree to the new version. */
2426 tree_function_versioning (old_decl, new_decl, tree_map, false, args_to_skip,
2427 skip_return, bbs_to_copy, new_entry_block);
2429 /* Update the new version's properties.
2430 Make The new version visible only within this translation unit. Make sure
2431 that is not weak also.
2432 ??? We cannot use COMDAT linkage because there is no
2433 ABI support for this. */
2434 cgraph_make_decl_local (new_version_node->symbol.decl);
2435 DECL_VIRTUAL_P (new_version_node->symbol.decl) = 0;
2436 new_version_node->symbol.externally_visible = 0;
2437 new_version_node->local.local = 1;
2438 new_version_node->lowered = true;
2440 /* Update the call_expr on the edges to call the new version node. */
2441 update_call_expr (new_version_node);
2443 cgraph_call_function_insertion_hooks (new_version_node);
2444 return new_version_node;
2447 /* Given virtual clone, turn it into actual clone. */
2449 cgraph_materialize_clone (struct cgraph_node *node)
2451 bitmap_obstack_initialize (NULL);
2452 node->former_clone_of = node->clone_of->symbol.decl;
2453 if (node->clone_of->former_clone_of)
2454 node->former_clone_of = node->clone_of->former_clone_of;
2455 /* Copy the OLD_VERSION_NODE function tree to the new version. */
2456 tree_function_versioning (node->clone_of->symbol.decl, node->symbol.decl,
2457 node->clone.tree_map, true,
2458 node->clone.args_to_skip, false,
2460 if (cgraph_dump_file)
2462 dump_function_to_file (node->clone_of->symbol.decl, cgraph_dump_file, dump_flags);
2463 dump_function_to_file (node->symbol.decl, cgraph_dump_file, dump_flags);
2466 /* Function is no longer clone. */
2467 if (node->next_sibling_clone)
2468 node->next_sibling_clone->prev_sibling_clone = node->prev_sibling_clone;
2469 if (node->prev_sibling_clone)
2470 node->prev_sibling_clone->next_sibling_clone = node->next_sibling_clone;
2472 node->clone_of->clones = node->next_sibling_clone;
2473 node->next_sibling_clone = NULL;
2474 node->prev_sibling_clone = NULL;
2475 if (!node->clone_of->analyzed && !node->clone_of->clones)
2477 cgraph_release_function_body (node->clone_of);
2478 cgraph_node_remove_callees (node->clone_of);
2479 ipa_remove_all_references (&node->clone_of->symbol.ref_list);
2481 node->clone_of = NULL;
2482 bitmap_obstack_release (NULL);
2485 /* If necessary, change the function declaration in the call statement
2486 associated with E so that it corresponds to the edge callee. */
2489 cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *e)
2491 tree decl = gimple_call_fndecl (e->call_stmt);
2493 gimple_stmt_iterator gsi;
2494 #ifdef ENABLE_CHECKING
2495 struct cgraph_node *node;
2498 if (e->indirect_unknown_callee
2499 || decl == e->callee->symbol.decl)
2500 return e->call_stmt;
2502 #ifdef ENABLE_CHECKING
2505 node = cgraph_get_node (decl);
2506 gcc_assert (!node || !node->clone.combined_args_to_skip);
2510 if (cgraph_dump_file)
2512 fprintf (cgraph_dump_file, "updating call of %s/%i -> %s/%i: ",
2513 cgraph_node_name (e->caller), e->caller->uid,
2514 cgraph_node_name (e->callee), e->callee->uid);
2515 print_gimple_stmt (cgraph_dump_file, e->call_stmt, 0, dump_flags);
2516 if (e->callee->clone.combined_args_to_skip)
2518 fprintf (cgraph_dump_file, " combined args to skip: ");
2519 dump_bitmap (cgraph_dump_file,
2520 e->callee->clone.combined_args_to_skip);
2524 if (e->callee->clone.combined_args_to_skip)
2529 = gimple_call_copy_skip_args (e->call_stmt,
2530 e->callee->clone.combined_args_to_skip);
2531 gimple_call_set_fndecl (new_stmt, e->callee->symbol.decl);
2533 if (gimple_vdef (new_stmt)
2534 && TREE_CODE (gimple_vdef (new_stmt)) == SSA_NAME)
2535 SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt;
2537 gsi = gsi_for_stmt (e->call_stmt);
2538 gsi_replace (&gsi, new_stmt, false);
2539 /* We need to defer cleaning EH info on the new statement to
2540 fixup-cfg. We may not have dominator information at this point
2541 and thus would end up with unreachable blocks and have no way
2542 to communicate that we need to run CFG cleanup then. */
2543 lp_nr = lookup_stmt_eh_lp (e->call_stmt);
2546 remove_stmt_from_eh_lp (e->call_stmt);
2547 add_stmt_to_eh_lp (new_stmt, lp_nr);
2552 new_stmt = e->call_stmt;
2553 gimple_call_set_fndecl (new_stmt, e->callee->symbol.decl);
2554 update_stmt (new_stmt);
2557 cgraph_set_call_stmt_including_clones (e->caller, e->call_stmt, new_stmt);
2559 if (cgraph_dump_file)
2561 fprintf (cgraph_dump_file, " updated to:");
2562 print_gimple_stmt (cgraph_dump_file, e->call_stmt, 0, dump_flags);
2567 /* Once all functions from compilation unit are in memory, produce all clones
2568 and update all calls. We might also do this on demand if we don't want to
2569 bring all functions to memory prior compilation, but current WHOPR
2570 implementation does that and it is is bit easier to keep everything right in
2573 cgraph_materialize_all_clones (void)
2575 struct cgraph_node *node;
2576 bool stabilized = false;
2578 if (cgraph_dump_file)
2579 fprintf (cgraph_dump_file, "Materializing clones\n");
2580 #ifdef ENABLE_CHECKING
2584 /* We can also do topological order, but number of iterations should be
2585 bounded by number of IPA passes since single IPA pass is probably not
2586 going to create clones of clones it created itself. */
2590 FOR_EACH_FUNCTION (node)
2592 if (node->clone_of && node->symbol.decl != node->clone_of->symbol.decl
2593 && !gimple_has_body_p (node->symbol.decl))
2595 if (gimple_has_body_p (node->clone_of->symbol.decl))
2597 if (cgraph_dump_file)
2599 fprintf (cgraph_dump_file, "cloning %s to %s\n",
2600 cgraph_node_name (node->clone_of),
2601 cgraph_node_name (node));
2602 if (node->clone.tree_map)
2605 fprintf (cgraph_dump_file, " replace map: ");
2606 for (i = 0; i < VEC_length (ipa_replace_map_p,
2607 node->clone.tree_map);
2610 struct ipa_replace_map *replace_info;
2611 replace_info = VEC_index (ipa_replace_map_p,
2612 node->clone.tree_map,
2614 print_generic_expr (cgraph_dump_file, replace_info->old_tree, 0);
2615 fprintf (cgraph_dump_file, " -> ");
2616 print_generic_expr (cgraph_dump_file, replace_info->new_tree, 0);
2617 fprintf (cgraph_dump_file, "%s%s;",
2618 replace_info->replace_p ? "(replace)":"",
2619 replace_info->ref_p ? "(ref)":"");
2621 fprintf (cgraph_dump_file, "\n");
2623 if (node->clone.args_to_skip)
2625 fprintf (cgraph_dump_file, " args_to_skip: ");
2626 dump_bitmap (cgraph_dump_file, node->clone.args_to_skip);
2628 if (node->clone.args_to_skip)
2630 fprintf (cgraph_dump_file, " combined_args_to_skip:");
2631 dump_bitmap (cgraph_dump_file, node->clone.combined_args_to_skip);
2634 cgraph_materialize_clone (node);
2640 FOR_EACH_FUNCTION (node)
2641 if (!node->analyzed && node->callees)
2642 cgraph_node_remove_callees (node);
2643 if (cgraph_dump_file)
2644 fprintf (cgraph_dump_file, "Materialization Call site updates done.\n");
2645 #ifdef ENABLE_CHECKING
2648 cgraph_remove_unreachable_nodes (false, cgraph_dump_file);
2652 /* Perform simple optimizations based on callgraph. */
2655 cgraph_optimize (void)
2660 #ifdef ENABLE_CHECKING
2664 timevar_push (TV_CGRAPHOPT);
2665 if (pre_ipa_mem_report)
2667 fprintf (stderr, "Memory consumption before IPA\n");
2668 dump_memory_report (false);
2671 fprintf (stderr, "Performing interprocedural optimizations\n");
2672 cgraph_state = CGRAPH_STATE_IPA;
2674 /* Don't run the IPA passes if there was any error or sorry messages. */
2678 /* Do nothing else if any IPA pass found errors or if we are just streaming LTO. */
2680 || (!in_lto_p && flag_lto && !flag_fat_lto_objects))
2682 timevar_pop (TV_CGRAPHOPT);
2686 /* This pass remove bodies of extern inline functions we never inlined.
2687 Do this later so other IPA passes see what is really going on. */
2688 cgraph_remove_unreachable_nodes (false, dump_file);
2689 cgraph_global_info_ready = true;
2690 if (cgraph_dump_file)
2692 fprintf (cgraph_dump_file, "Optimized ");
2693 dump_symtab (cgraph_dump_file);
2695 if (post_ipa_mem_report)
2697 fprintf (stderr, "Memory consumption after IPA\n");
2698 dump_memory_report (false);
2700 timevar_pop (TV_CGRAPHOPT);
2702 /* Output everything. */
2703 (*debug_hooks->assembly_start) ();
2705 fprintf (stderr, "Assembling functions:\n");
2706 #ifdef ENABLE_CHECKING
2710 cgraph_materialize_all_clones ();
2711 bitmap_obstack_initialize (NULL);
2712 execute_ipa_pass_list (all_late_ipa_passes);
2713 cgraph_remove_unreachable_nodes (true, dump_file);
2714 #ifdef ENABLE_CHECKING
2717 bitmap_obstack_release (NULL);
2718 cgraph_mark_functions_to_output ();
2721 cgraph_state = CGRAPH_STATE_EXPANSION;
2722 if (!flag_toplevel_reorder)
2723 cgraph_output_in_order ();
2726 cgraph_output_pending_asms ();
2728 cgraph_expand_all_functions ();
2729 varpool_remove_unreferenced_decls ();
2731 varpool_assemble_pending_decls ();
2734 cgraph_process_new_functions ();
2735 cgraph_state = CGRAPH_STATE_FINISHED;
2737 if (cgraph_dump_file)
2739 fprintf (cgraph_dump_file, "\nFinal ");
2740 dump_symtab (cgraph_dump_file);
2742 #ifdef ENABLE_CHECKING
2744 /* Double check that all inline clones are gone and that all
2745 function bodies have been released from memory. */
2748 struct cgraph_node *node;
2749 bool error_found = false;
2751 FOR_EACH_DEFINED_FUNCTION (node)
2752 if (node->global.inlined_to
2753 || gimple_has_body_p (node->symbol.decl))
2756 dump_cgraph_node (stderr, node);
2759 internal_error ("nodes with unreleased memory found");
2765 /* Analyze the whole compilation unit once it is parsed completely. */
2768 cgraph_finalize_compilation_unit (void)
2770 timevar_push (TV_CGRAPH);
2772 /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE. */
2774 lto_streamer_hooks_init ();
2776 /* If we're here there's no current function anymore. Some frontends
2777 are lazy in clearing these. */
2778 current_function_decl = NULL;
2781 /* Do not skip analyzing the functions if there were errors, we
2782 miss diagnostics for following functions otherwise. */
2784 /* Emit size functions we didn't inline. */
2785 finalize_size_functions ();
2787 /* Mark alias targets necessary and emit diagnostics. */
2788 finish_aliases_1 ();
2789 handle_alias_pairs ();
2793 fprintf (stderr, "\nAnalyzing compilation unit\n");
2797 if (flag_dump_passes)
2800 /* Gimplify and lower all functions, compute reachability and
2801 remove unreachable nodes. */
2802 cgraph_analyze_functions ();
2804 /* Mark alias targets necessary and emit diagnostics. */
2805 finish_aliases_1 ();
2806 handle_alias_pairs ();
2808 /* Gimplify and lower thunks. */
2809 cgraph_analyze_functions ();
2811 /* Finally drive the pass manager. */
2814 timevar_pop (TV_CGRAPH);
2818 #include "gt-cgraphunit.h"