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"
115 #include "tree-flow.h"
116 #include "tree-inline.h"
117 #include "langhooks.h"
118 #include "pointer-set.h"
125 #include "diagnostic.h"
126 #include "tree-pretty-print.h"
127 #include "gimple-pretty-print.h"
132 #include "function.h"
133 #include "ipa-prop.h"
135 #include "tree-iterator.h"
136 #include "tree-pass.h"
137 #include "tree-dump.h"
139 #include "coverage.h"
141 #include "ipa-inline.h"
142 #include "ipa-utils.h"
143 #include "lto-streamer.h"
145 static void cgraph_expand_all_functions (void);
146 static void cgraph_mark_functions_to_output (void);
147 static void cgraph_expand_function (struct cgraph_node *);
148 static void cgraph_output_pending_asms (void);
150 FILE *cgraph_dump_file;
152 /* Used for vtable lookup in thunk adjusting. */
153 static GTY (()) tree vtable_entry_type;
155 /* Determine if function DECL is needed. That is, visible to something
156 either outside this translation unit, something magic in the system
160 cgraph_decide_is_function_needed (struct cgraph_node *node, tree decl)
162 /* If the user told us it is used, then it must be so. */
163 if (node->local.externally_visible)
166 /* ??? If the assembler name is set by hand, it is possible to assemble
167 the name later after finalizing the function and the fact is noticed
168 in assemble_name then. This is arguably a bug. */
169 if (DECL_ASSEMBLER_NAME_SET_P (decl)
170 && (!node->thunk.thunk_p && !node->same_body_alias)
171 && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
174 /* With -fkeep-inline-functions we are keeping all inline functions except
175 for extern inline ones. */
176 if (flag_keep_inline_functions
177 && DECL_DECLARED_INLINE_P (decl)
178 && !DECL_EXTERNAL (decl)
179 && !DECL_DISREGARD_INLINE_LIMITS (decl))
182 /* If we decided it was needed before, but at the time we didn't have
183 the body of the function available, then it's still needed. We have
184 to go back and re-check its dependencies now. */
188 /* Externally visible functions must be output. The exception is
189 COMDAT functions that must be output only when they are needed.
191 When not optimizing, also output the static functions. (see
192 PR24561), but don't do so for always_inline functions, functions
193 declared inline and nested functions. These were optimized out
194 in the original implementation and it is unclear whether we want
195 to change the behavior here. */
196 if (((TREE_PUBLIC (decl)
198 && !node->same_body_alias
199 && !DECL_DISREGARD_INLINE_LIMITS (decl)
200 && !DECL_DECLARED_INLINE_P (decl)
201 && !(DECL_CONTEXT (decl)
202 && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL)))
203 && !flag_whole_program
205 && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
211 /* Process CGRAPH_NEW_FUNCTIONS and perform actions necessary to add these
212 functions into callgraph in a way so they look like ordinary reachable
213 functions inserted into callgraph already at construction time. */
216 cgraph_process_new_functions (void)
220 struct cgraph_node *node;
222 varpool_analyze_pending_decls ();
223 /* Note that this queue may grow as its being processed, as the new
224 functions may generate new ones. */
225 while (cgraph_new_nodes)
227 node = cgraph_new_nodes;
229 cgraph_new_nodes = cgraph_new_nodes->next_needed;
230 switch (cgraph_state)
232 case CGRAPH_STATE_CONSTRUCTION:
233 /* At construction time we just need to finalize function and move
234 it into reachable functions list. */
236 node->next_needed = NULL;
237 cgraph_finalize_function (fndecl, false);
238 cgraph_mark_reachable_node (node);
240 cgraph_call_function_insertion_hooks (node);
243 case CGRAPH_STATE_IPA:
244 case CGRAPH_STATE_IPA_SSA:
245 /* When IPA optimization already started, do all essential
246 transformations that has been already performed on the whole
247 cgraph but not on this function. */
249 gimple_register_cfg_hooks ();
251 cgraph_analyze_function (node);
252 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
253 current_function_decl = fndecl;
254 if ((cgraph_state == CGRAPH_STATE_IPA_SSA
255 && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
256 /* When not optimizing, be sure we run early local passes anyway
259 execute_pass_list (pass_early_local_passes.pass.sub);
261 compute_inline_parameters (node, true);
262 free_dominance_info (CDI_POST_DOMINATORS);
263 free_dominance_info (CDI_DOMINATORS);
265 current_function_decl = NULL;
266 cgraph_call_function_insertion_hooks (node);
269 case CGRAPH_STATE_EXPANSION:
270 /* Functions created during expansion shall be compiled
273 cgraph_call_function_insertion_hooks (node);
274 cgraph_expand_function (node);
281 varpool_analyze_pending_decls ();
286 /* As an GCC extension we allow redefinition of the function. The
287 semantics when both copies of bodies differ is not well defined.
288 We replace the old body with new body so in unit at a time mode
289 we always use new body, while in normal mode we may end up with
290 old body inlined into some functions and new body expanded and
293 ??? It may make more sense to use one body for inlining and other
294 body for expanding the function but this is difficult to do. */
297 cgraph_reset_node (struct cgraph_node *node)
299 /* If node->process is set, then we have already begun whole-unit analysis.
300 This is *not* testing for whether we've already emitted the function.
301 That case can be sort-of legitimately seen with real function redefinition
302 errors. I would argue that the front end should never present us with
303 such a case, but don't enforce that for now. */
304 gcc_assert (!node->process);
306 /* Reset our data structures so we can analyze the function again. */
307 memset (&node->local, 0, sizeof (node->local));
308 memset (&node->global, 0, sizeof (node->global));
309 memset (&node->rtl, 0, sizeof (node->rtl));
310 node->analyzed = false;
311 node->local.finalized = false;
313 cgraph_node_remove_callees (node);
317 cgraph_lower_function (struct cgraph_node *node)
323 lower_nested_functions (node->decl);
324 gcc_assert (!node->nested);
326 tree_lowering_passes (node->decl);
327 node->lowered = true;
330 /* DECL has been parsed. Take it, queue it, compile it at the whim of the
331 logic in effect. If NESTED is true, then our caller cannot stand to have
332 the garbage collector run at the moment. We would need to either create
333 a new GC context, or just not compile right now. */
336 cgraph_finalize_function (tree decl, bool nested)
338 struct cgraph_node *node = cgraph_get_create_node (decl);
340 if (node->local.finalized)
342 cgraph_reset_node (node);
343 node->local.redefined_extern_inline = true;
346 notice_global_symbol (decl);
347 node->local.finalized = true;
348 node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL;
350 if (cgraph_decide_is_function_needed (node, decl))
351 cgraph_mark_needed_node (node);
353 /* Since we reclaim unreachable nodes at the end of every language
354 level unit, we need to be conservative about possible entry points
356 if ((TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
357 || DECL_STATIC_CONSTRUCTOR (decl)
358 || DECL_STATIC_DESTRUCTOR (decl)
359 /* COMDAT virtual functions may be referenced by vtable from
360 other compilation unit. Still we want to devirtualize calls
361 to those so we need to analyze them.
362 FIXME: We should introduce may edges for this purpose and update
363 their handling in unreachable function removal and inliner too. */
364 || (DECL_VIRTUAL_P (decl)
365 && optimize && (DECL_COMDAT (decl) || DECL_EXTERNAL (decl))))
366 cgraph_mark_reachable_node (node);
368 /* If we've not yet emitted decl, tell the debug info about it. */
369 if (!TREE_ASM_WRITTEN (decl))
370 (*debug_hooks->deferred_inline_function) (decl);
372 /* Possibly warn about unused parameters. */
373 if (warn_unused_parameter)
374 do_warn_unused_parameter (decl);
380 /* C99 extern inline keywords allow changing of declaration after function
381 has been finalized. We need to re-decide if we want to mark the function as
385 cgraph_mark_if_needed (tree decl)
387 struct cgraph_node *node = cgraph_get_node (decl);
388 if (node->local.finalized && cgraph_decide_is_function_needed (node, decl))
389 cgraph_mark_needed_node (node);
392 /* Return TRUE if NODE2 is equivalent to NODE or its clone. */
394 clone_of_p (struct cgraph_node *node, struct cgraph_node *node2)
396 node = cgraph_function_or_thunk_node (node, NULL);
397 node2 = cgraph_function_or_thunk_node (node2, NULL);
398 while (node != node2 && node2)
399 node2 = node2->clone_of;
400 return node2 != NULL;
403 /* Verify edge E count and frequency. */
406 verify_edge_count_and_frequency (struct cgraph_edge *e)
408 bool error_found = false;
411 error ("caller edge count is negative");
414 if (e->frequency < 0)
416 error ("caller edge frequency is negative");
419 if (e->frequency > CGRAPH_FREQ_MAX)
421 error ("caller edge frequency is too large");
424 if (gimple_has_body_p (e->caller->decl)
425 && !e->caller->global.inlined_to
426 /* FIXME: Inline-analysis sets frequency to 0 when edge is optimized out.
427 Remove this once edges are actualy removed from the function at that time. */
429 || (inline_edge_summary_vec
430 && ((VEC_length(inline_edge_summary_t, inline_edge_summary_vec)
431 <= (unsigned) e->uid)
432 || !inline_edge_summary (e)->predicate)))
434 != compute_call_stmt_bb_frequency (e->caller->decl,
435 gimple_bb (e->call_stmt))))
437 error ("caller edge frequency %i does not match BB frequency %i",
439 compute_call_stmt_bb_frequency (e->caller->decl,
440 gimple_bb (e->call_stmt)));
446 /* Switch to THIS_CFUN if needed and print STMT to stderr. */
448 cgraph_debug_gimple_stmt (struct function *this_cfun, gimple stmt)
450 /* debug_gimple_stmt needs correct cfun */
451 if (cfun != this_cfun)
452 set_cfun (this_cfun);
453 debug_gimple_stmt (stmt);
456 /* Verify that call graph edge E corresponds to DECL from the associated
457 statement. Return true if the verification should fail. */
460 verify_edge_corresponds_to_fndecl (struct cgraph_edge *e, tree decl)
462 struct cgraph_node *node;
464 if (!decl || e->callee->global.inlined_to)
466 node = cgraph_get_node (decl);
468 /* We do not know if a node from a different partition is an alias or what it
469 aliases and therefore cannot do the former_clone_of check reliably. */
470 if (!node || node->in_other_partition)
472 node = cgraph_function_or_thunk_node (node, NULL);
474 if ((e->callee->former_clone_of != node->decl)
475 /* IPA-CP sometimes redirect edge to clone and then back to the former
476 function. This ping-pong has to go, eventaully. */
477 && (node != cgraph_function_or_thunk_node (e->callee, NULL))
478 && !clone_of_p (node, e->callee))
484 /* Verify cgraph nodes of given cgraph node. */
486 verify_cgraph_node (struct cgraph_node *node)
488 struct cgraph_edge *e;
489 struct function *this_cfun = DECL_STRUCT_FUNCTION (node->decl);
490 basic_block this_block;
491 gimple_stmt_iterator gsi;
492 bool error_found = false;
497 timevar_push (TV_CGRAPH_VERIFY);
498 for (e = node->callees; e; e = e->next_callee)
501 error ("aux field set for edge %s->%s",
502 identifier_to_locale (cgraph_node_name (e->caller)),
503 identifier_to_locale (cgraph_node_name (e->callee)));
508 error ("execution count is negative");
511 if (node->global.inlined_to && node->local.externally_visible)
513 error ("externally visible inline clone");
516 if (node->global.inlined_to && node->address_taken)
518 error ("inline clone with address taken");
521 if (node->global.inlined_to && node->needed)
523 error ("inline clone is needed");
526 for (e = node->indirect_calls; e; e = e->next_callee)
530 error ("aux field set for indirect edge from %s",
531 identifier_to_locale (cgraph_node_name (e->caller)));
534 if (!e->indirect_unknown_callee
535 || !e->indirect_info)
537 error ("An indirect edge from %s is not marked as indirect or has "
538 "associated indirect_info, the corresponding statement is: ",
539 identifier_to_locale (cgraph_node_name (e->caller)));
540 cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
544 for (e = node->callers; e; e = e->next_caller)
546 if (verify_edge_count_and_frequency (e))
548 if (!e->inline_failed)
550 if (node->global.inlined_to
551 != (e->caller->global.inlined_to
552 ? e->caller->global.inlined_to : e->caller))
554 error ("inlined_to pointer is wrong");
557 if (node->callers->next_caller)
559 error ("multiple inline callers");
564 if (node->global.inlined_to)
566 error ("inlined_to pointer set for noninline callers");
570 for (e = node->indirect_calls; e; e = e->next_callee)
571 if (verify_edge_count_and_frequency (e))
573 if (!node->callers && node->global.inlined_to)
575 error ("inlined_to pointer is set but no predecessors found");
578 if (node->global.inlined_to == node)
580 error ("inlined_to pointer refers to itself");
584 if (!cgraph_get_node (node->decl))
586 error ("node not found in cgraph_hash");
592 struct cgraph_node *n;
593 for (n = node->clone_of->clones; n; n = n->next_sibling_clone)
598 error ("node has wrong clone_of");
604 struct cgraph_node *n;
605 for (n = node->clones; n; n = n->next_sibling_clone)
606 if (n->clone_of != node)
610 error ("node has wrong clone list");
614 if ((node->prev_sibling_clone || node->next_sibling_clone) && !node->clone_of)
616 error ("node is in clone list but it is not clone");
619 if (!node->prev_sibling_clone && node->clone_of && node->clone_of->clones != node)
621 error ("node has wrong prev_clone pointer");
624 if (node->prev_sibling_clone && node->prev_sibling_clone->next_sibling_clone != node)
626 error ("double linked list of clones corrupted");
629 if (node->same_comdat_group)
631 struct cgraph_node *n = node->same_comdat_group;
633 if (!DECL_ONE_ONLY (node->decl))
635 error ("non-DECL_ONE_ONLY node in a same_comdat_group list");
640 error ("node is alone in a comdat group");
645 if (!n->same_comdat_group)
647 error ("same_comdat_group is not a circular list");
651 n = n->same_comdat_group;
656 if (node->analyzed && node->alias)
658 bool ref_found = false;
664 error ("Alias has call edges");
667 for (i = 0; ipa_ref_list_reference_iterate (&node->ref_list, i, ref); i++)
668 if (ref->use != IPA_REF_ALIAS)
670 error ("Alias has non-alias refernece");
675 error ("Alias has more than one alias reference");
682 error ("Analyzed alias has no reference");
686 if (node->analyzed && node->thunk.thunk_p)
690 error ("No edge out of thunk node");
693 else if (node->callees->next_callee)
695 error ("More than one edge out of thunk node");
698 if (gimple_has_body_p (node->decl))
700 error ("Thunk is not supposed to have body");
704 else if (node->analyzed && gimple_has_body_p (node->decl)
705 && !TREE_ASM_WRITTEN (node->decl)
706 && (!DECL_EXTERNAL (node->decl) || node->global.inlined_to)
711 /* The nodes we're interested in are never shared, so walk
712 the tree ignoring duplicates. */
713 struct pointer_set_t *visited_nodes = pointer_set_create ();
714 /* Reach the trees by walking over the CFG, and note the
715 enclosing basic-blocks in the call edges. */
716 FOR_EACH_BB_FN (this_block, this_cfun)
717 for (gsi = gsi_start_bb (this_block);
721 gimple stmt = gsi_stmt (gsi);
722 if (is_gimple_call (stmt))
724 struct cgraph_edge *e = cgraph_edge (node, stmt);
725 tree decl = gimple_call_fndecl (stmt);
730 error ("shared call_stmt:");
731 cgraph_debug_gimple_stmt (this_cfun, stmt);
734 if (!e->indirect_unknown_callee)
736 if (verify_edge_corresponds_to_fndecl (e, decl))
738 error ("edge points to wrong declaration:");
739 debug_tree (e->callee->decl);
740 fprintf (stderr," Instead of:");
747 error ("an indirect edge with unknown callee "
748 "corresponding to a call_stmt with "
749 "a known declaration:");
751 cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
757 error ("missing callgraph edge for call stmt:");
758 cgraph_debug_gimple_stmt (this_cfun, stmt);
763 pointer_set_destroy (visited_nodes);
766 /* No CFG available?! */
769 for (e = node->callees; e; e = e->next_callee)
773 error ("edge %s->%s has no corresponding call_stmt",
774 identifier_to_locale (cgraph_node_name (e->caller)),
775 identifier_to_locale (cgraph_node_name (e->callee)));
776 cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
781 for (e = node->indirect_calls; e; e = e->next_callee)
785 error ("an indirect edge from %s has no corresponding call_stmt",
786 identifier_to_locale (cgraph_node_name (e->caller)));
787 cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
795 dump_cgraph_node (stderr, node);
796 internal_error ("verify_cgraph_node failed");
798 timevar_pop (TV_CGRAPH_VERIFY);
801 /* Verify whole cgraph structure. */
805 struct cgraph_node *node;
810 for (node = cgraph_nodes; node; node = node->next)
811 verify_cgraph_node (node);
814 /* Output all asm statements we have stored up to be output. */
817 cgraph_output_pending_asms (void)
819 struct cgraph_asm_node *can;
824 for (can = cgraph_asm_nodes; can; can = can->next)
825 assemble_asm (can->asm_str);
826 cgraph_asm_nodes = NULL;
829 /* Analyze the function scheduled to be output. */
831 cgraph_analyze_function (struct cgraph_node *node)
833 tree save = current_function_decl;
834 tree decl = node->decl;
836 if (node->alias && node->thunk.alias)
838 struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias);
839 struct cgraph_node *n;
841 for (n = tgt; n && n->alias;
842 n = n->analyzed ? cgraph_alias_aliased_node (n) : NULL)
845 error ("function %q+D part of alias cycle", node->decl);
849 if (!VEC_length (ipa_ref_t, node->ref_list.references))
850 ipa_record_reference (node, NULL, tgt, NULL, IPA_REF_ALIAS, NULL);
851 if (node->same_body_alias)
853 DECL_VIRTUAL_P (node->decl) = DECL_VIRTUAL_P (node->thunk.alias);
854 DECL_DECLARED_INLINE_P (node->decl)
855 = DECL_DECLARED_INLINE_P (node->thunk.alias);
856 DECL_DISREGARD_INLINE_LIMITS (node->decl)
857 = DECL_DISREGARD_INLINE_LIMITS (node->thunk.alias);
860 /* Fixup visibility nonsences C++ frontend produce on same body aliases. */
861 if (TREE_PUBLIC (node->decl) && node->same_body_alias)
863 DECL_EXTERNAL (node->decl) = DECL_EXTERNAL (node->thunk.alias);
864 if (DECL_ONE_ONLY (node->thunk.alias))
866 DECL_COMDAT (node->decl) = DECL_COMDAT (node->thunk.alias);
867 DECL_COMDAT_GROUP (node->decl) = DECL_COMDAT_GROUP (node->thunk.alias);
868 if (DECL_ONE_ONLY (node->thunk.alias) && !node->same_comdat_group)
870 struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias);
871 node->same_comdat_group = tgt;
872 if (!tgt->same_comdat_group)
873 tgt->same_comdat_group = node;
876 struct cgraph_node *n;
877 for (n = tgt->same_comdat_group;
878 n->same_comdat_group != tgt;
879 n = n->same_comdat_group)
881 n->same_comdat_group = node;
886 cgraph_mark_reachable_node (cgraph_alias_aliased_node (node));
887 if (node->address_taken)
888 cgraph_mark_address_taken_node (cgraph_alias_aliased_node (node));
889 if (cgraph_decide_is_function_needed (node, node->decl))
890 cgraph_mark_needed_node (node);
892 else if (node->thunk.thunk_p)
894 cgraph_create_edge (node, cgraph_get_node (node->thunk.alias),
895 NULL, 0, CGRAPH_FREQ_BASE);
899 current_function_decl = decl;
900 push_cfun (DECL_STRUCT_FUNCTION (decl));
902 assign_assembler_name_if_neeeded (node->decl);
904 /* Make sure to gimplify bodies only once. During analyzing a
905 function we lower it, which will require gimplified nested
906 functions, so we can end up here with an already gimplified
908 if (!gimple_body (decl))
909 gimplify_function_tree (decl);
910 dump_function (TDI_generic, decl);
912 cgraph_lower_function (node);
915 node->analyzed = true;
917 current_function_decl = save;
920 /* C++ frontend produce same body aliases all over the place, even before PCH
921 gets streamed out. It relies on us linking the aliases with their function
922 in order to do the fixups, but ipa-ref is not PCH safe. Consequentely we
923 first produce aliases without links, but once C++ FE is sure he won't sream
924 PCH we build the links via this function. */
927 cgraph_process_same_body_aliases (void)
929 struct cgraph_node *node;
930 for (node = cgraph_nodes; node; node = node->next)
931 if (node->same_body_alias
932 && !VEC_length (ipa_ref_t, node->ref_list.references))
934 struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias);
935 ipa_record_reference (node, NULL, tgt, NULL, IPA_REF_ALIAS, NULL);
937 same_body_aliases_done = true;
940 /* Process attributes common for vars and functions. */
943 process_common_attributes (tree decl)
945 tree weakref = lookup_attribute ("weakref", DECL_ATTRIBUTES (decl));
947 if (weakref && !lookup_attribute ("alias", DECL_ATTRIBUTES (decl)))
949 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
950 "%<weakref%> attribute should be accompanied with"
951 " an %<alias%> attribute");
952 DECL_WEAK (decl) = 0;
953 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
954 DECL_ATTRIBUTES (decl));
958 /* Look for externally_visible and used attributes and mark cgraph nodes
961 We cannot mark the nodes at the point the attributes are processed (in
962 handle_*_attribute) because the copy of the declarations available at that
963 point may not be canonical. For example, in:
966 void f() __attribute__((used));
968 the declaration we see in handle_used_attribute will be the second
969 declaration -- but the front end will subsequently merge that declaration
970 with the original declaration and discard the second declaration.
972 Furthermore, we can't mark these nodes in cgraph_finalize_function because:
975 void f() __attribute__((externally_visible));
979 So, we walk the nodes at the end of the translation unit, applying the
980 attributes at that point. */
983 process_function_and_variable_attributes (struct cgraph_node *first,
984 struct varpool_node *first_var)
986 struct cgraph_node *node;
987 struct varpool_node *vnode;
989 for (node = cgraph_nodes; node != first; node = node->next)
991 tree decl = node->decl;
992 if (DECL_PRESERVE_P (decl))
993 cgraph_mark_needed_node (node);
994 if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
995 && lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl))
996 && TREE_PUBLIC (node->decl))
998 if (node->local.finalized)
999 cgraph_mark_needed_node (node);
1001 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
1003 if (! TREE_PUBLIC (node->decl))
1004 warning_at (DECL_SOURCE_LOCATION (node->decl), OPT_Wattributes,
1005 "%<externally_visible%>"
1006 " attribute have effect only on public objects");
1007 else if (node->local.finalized)
1008 cgraph_mark_needed_node (node);
1010 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
1011 && (node->local.finalized && !node->alias))
1013 warning_at (DECL_SOURCE_LOCATION (node->decl), OPT_Wattributes,
1014 "%<weakref%> attribute ignored"
1015 " because function is defined");
1016 DECL_WEAK (decl) = 0;
1017 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
1018 DECL_ATTRIBUTES (decl));
1021 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl))
1022 && !DECL_DECLARED_INLINE_P (decl)
1023 /* redefining extern inline function makes it DECL_UNINLINABLE. */
1024 && !DECL_UNINLINABLE (decl))
1025 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
1026 "always_inline function might not be inlinable");
1028 process_common_attributes (decl);
1030 for (vnode = varpool_nodes; vnode != first_var; vnode = vnode->next)
1032 tree decl = vnode->decl;
1033 if (DECL_PRESERVE_P (decl))
1035 vnode->force_output = true;
1036 if (vnode->finalized)
1037 varpool_mark_needed_node (vnode);
1039 if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
1040 && lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl))
1041 && TREE_PUBLIC (vnode->decl))
1043 if (vnode->finalized)
1044 varpool_mark_needed_node (vnode);
1046 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
1048 if (! TREE_PUBLIC (vnode->decl))
1049 warning_at (DECL_SOURCE_LOCATION (vnode->decl), OPT_Wattributes,
1050 "%<externally_visible%>"
1051 " attribute have effect only on public objects");
1052 else if (vnode->finalized)
1053 varpool_mark_needed_node (vnode);
1055 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
1057 && DECL_INITIAL (decl))
1059 warning_at (DECL_SOURCE_LOCATION (vnode->decl), OPT_Wattributes,
1060 "%<weakref%> attribute ignored"
1061 " because variable is initialized");
1062 DECL_WEAK (decl) = 0;
1063 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
1064 DECL_ATTRIBUTES (decl));
1066 process_common_attributes (decl);
1070 /* Process CGRAPH_NODES_NEEDED queue, analyze each function (and transitively
1071 each reachable functions) and build cgraph.
1072 The function can be called multiple times after inserting new nodes
1073 into beginning of queue. Just the new part of queue is re-scanned then. */
1076 cgraph_analyze_functions (void)
1078 /* Keep track of already processed nodes when called multiple times for
1079 intermodule optimization. */
1080 static struct cgraph_node *first_analyzed;
1081 struct cgraph_node *first_processed = first_analyzed;
1082 static struct varpool_node *first_analyzed_var;
1083 struct cgraph_node *node, *next;
1085 bitmap_obstack_initialize (NULL);
1086 process_function_and_variable_attributes (first_processed,
1087 first_analyzed_var);
1088 first_processed = cgraph_nodes;
1089 first_analyzed_var = varpool_nodes;
1090 varpool_analyze_pending_decls ();
1091 if (cgraph_dump_file)
1093 fprintf (cgraph_dump_file, "Initial entry points:");
1094 for (node = cgraph_nodes; node != first_analyzed; node = node->next)
1096 fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
1097 fprintf (cgraph_dump_file, "\n");
1099 cgraph_process_new_functions ();
1101 /* Propagate reachability flag and lower representation of all reachable
1102 functions. In the future, lowering will introduce new functions and
1103 new entry points on the way (by template instantiation and virtual
1104 method table generation for instance). */
1105 while (cgraph_nodes_queue)
1107 struct cgraph_edge *edge;
1108 tree decl = cgraph_nodes_queue->decl;
1110 node = cgraph_nodes_queue;
1111 cgraph_nodes_queue = cgraph_nodes_queue->next_needed;
1112 node->next_needed = NULL;
1114 /* ??? It is possible to create extern inline function and later using
1115 weak alias attribute to kill its body. See
1116 gcc.c-torture/compile/20011119-1.c */
1117 if (!DECL_STRUCT_FUNCTION (decl)
1118 && (!node->alias || !node->thunk.alias)
1119 && !node->thunk.thunk_p)
1121 cgraph_reset_node (node);
1122 node->local.redefined_extern_inline = true;
1126 if (!node->analyzed)
1127 cgraph_analyze_function (node);
1129 for (edge = node->callees; edge; edge = edge->next_callee)
1130 if (!edge->callee->reachable)
1131 cgraph_mark_reachable_node (edge->callee);
1132 for (edge = node->callers; edge; edge = edge->next_caller)
1133 if (!edge->caller->reachable && edge->caller->thunk.thunk_p)
1134 cgraph_mark_reachable_node (edge->caller);
1136 if (node->same_comdat_group)
1138 for (next = node->same_comdat_group;
1140 next = next->same_comdat_group)
1141 cgraph_mark_reachable_node (next);
1144 /* If decl is a clone of an abstract function, mark that abstract
1145 function so that we don't release its body. The DECL_INITIAL() of that
1146 abstract function declaration will be later needed to output debug
1148 if (DECL_ABSTRACT_ORIGIN (decl))
1150 struct cgraph_node *origin_node;
1151 origin_node = cgraph_get_node (DECL_ABSTRACT_ORIGIN (decl));
1152 origin_node->abstract_and_needed = true;
1155 /* We finalize local static variables during constructing callgraph
1156 edges. Process their attributes too. */
1157 process_function_and_variable_attributes (first_processed,
1158 first_analyzed_var);
1159 first_processed = cgraph_nodes;
1160 first_analyzed_var = varpool_nodes;
1161 varpool_analyze_pending_decls ();
1162 cgraph_process_new_functions ();
1165 /* Collect entry points to the unit. */
1166 if (cgraph_dump_file)
1168 fprintf (cgraph_dump_file, "Unit entry points:");
1169 for (node = cgraph_nodes; node != first_analyzed; node = node->next)
1171 fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
1172 fprintf (cgraph_dump_file, "\n\nInitial ");
1173 dump_cgraph (cgraph_dump_file);
1174 dump_varpool (cgraph_dump_file);
1177 if (cgraph_dump_file)
1178 fprintf (cgraph_dump_file, "\nReclaiming functions:");
1180 for (node = cgraph_nodes; node != first_analyzed; node = next)
1182 tree decl = node->decl;
1185 if (node->local.finalized && !gimple_has_body_p (decl)
1186 && (!node->alias || !node->thunk.alias)
1187 && !node->thunk.thunk_p)
1188 cgraph_reset_node (node);
1190 if (!node->reachable
1191 && (gimple_has_body_p (decl) || node->thunk.thunk_p
1192 || (node->alias && node->thunk.alias)))
1194 if (cgraph_dump_file)
1195 fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
1196 cgraph_remove_node (node);
1200 node->next_needed = NULL;
1201 gcc_assert (!node->local.finalized || node->thunk.thunk_p
1203 || gimple_has_body_p (decl));
1204 gcc_assert (node->analyzed == node->local.finalized);
1206 if (cgraph_dump_file)
1208 fprintf (cgraph_dump_file, "\n\nReclaimed ");
1209 dump_cgraph (cgraph_dump_file);
1210 dump_varpool (cgraph_dump_file);
1212 bitmap_obstack_release (NULL);
1213 first_analyzed = cgraph_nodes;
1217 /* Translate the ugly representation of aliases as alias pairs into nice
1218 representation in callgraph. We don't handle all cases yet,
1222 handle_alias_pairs (void)
1226 struct cgraph_node *target_node;
1227 struct cgraph_node *src_node;
1228 struct varpool_node *target_vnode;
1230 for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p);)
1232 if (TREE_CODE (p->decl) == FUNCTION_DECL
1233 && (target_node = cgraph_node_for_asm (p->target)) != NULL)
1235 src_node = cgraph_get_node (p->decl);
1236 if (src_node && src_node->local.finalized)
1237 cgraph_reset_node (src_node);
1238 /* Normally EXTERNAL flag is used to mark external inlines,
1239 however for aliases it seems to be allowed to use it w/o
1240 any meaning. See gcc.dg/attr-alias-3.c
1241 However for weakref we insist on EXTERNAL flag being set.
1242 See gcc.dg/attr-alias-5.c */
1243 if (DECL_EXTERNAL (p->decl))
1244 DECL_EXTERNAL (p->decl) = lookup_attribute ("weakref",
1245 DECL_ATTRIBUTES (p->decl)) != NULL;
1246 cgraph_create_function_alias (p->decl, target_node->decl);
1247 VEC_unordered_remove (alias_pair, alias_pairs, i);
1249 else if (TREE_CODE (p->decl) == VAR_DECL
1250 && (target_vnode = varpool_node_for_asm (p->target)) != NULL)
1252 /* Normally EXTERNAL flag is used to mark external inlines,
1253 however for aliases it seems to be allowed to use it w/o
1254 any meaning. See gcc.dg/attr-alias-3.c
1255 However for weakref we insist on EXTERNAL flag being set.
1256 See gcc.dg/attr-alias-5.c */
1257 if (DECL_EXTERNAL (p->decl))
1258 DECL_EXTERNAL (p->decl) = lookup_attribute ("weakref",
1259 DECL_ATTRIBUTES (p->decl)) != NULL;
1260 varpool_create_variable_alias (p->decl, target_vnode->decl);
1261 VEC_unordered_remove (alias_pair, alias_pairs, i);
1263 /* Weakrefs with target not defined in current unit are easy to handle; they
1264 behave just as external variables except we need to note the alias flag
1265 to later output the weakref pseudo op into asm file. */
1266 else if (lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL
1267 && (TREE_CODE (p->decl) == FUNCTION_DECL
1268 ? (varpool_node_for_asm (p->target) == NULL)
1269 : (cgraph_node_for_asm (p->target) == NULL)))
1271 if (TREE_CODE (p->decl) == FUNCTION_DECL)
1272 cgraph_get_create_node (p->decl)->alias = true;
1274 varpool_get_node (p->decl)->alias = true;
1275 DECL_EXTERNAL (p->decl) = 1;
1276 VEC_unordered_remove (alias_pair, alias_pairs, i);
1281 fprintf (dump_file, "Unhandled alias %s->%s\n",
1282 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (p->decl)),
1283 IDENTIFIER_POINTER (p->target));
1291 /* Analyze the whole compilation unit once it is parsed completely. */
1294 cgraph_finalize_compilation_unit (void)
1296 timevar_push (TV_CGRAPH);
1298 /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE. */
1300 lto_streamer_hooks_init ();
1302 /* If we're here there's no current function anymore. Some frontends
1303 are lazy in clearing these. */
1304 current_function_decl = NULL;
1307 /* Do not skip analyzing the functions if there were errors, we
1308 miss diagnostics for following functions otherwise. */
1310 /* Emit size functions we didn't inline. */
1311 finalize_size_functions ();
1313 /* Mark alias targets necessary and emit diagnostics. */
1314 finish_aliases_1 ();
1315 handle_alias_pairs ();
1319 fprintf (stderr, "\nAnalyzing compilation unit\n");
1323 if (flag_dump_passes)
1326 /* Gimplify and lower all functions, compute reachability and
1327 remove unreachable nodes. */
1328 cgraph_analyze_functions ();
1330 /* Mark alias targets necessary and emit diagnostics. */
1331 finish_aliases_1 ();
1332 handle_alias_pairs ();
1334 /* Gimplify and lower thunks. */
1335 cgraph_analyze_functions ();
1337 /* Finally drive the pass manager. */
1340 timevar_pop (TV_CGRAPH);
1344 /* Figure out what functions we want to assemble. */
1347 cgraph_mark_functions_to_output (void)
1349 struct cgraph_node *node;
1350 #ifdef ENABLE_CHECKING
1351 bool check_same_comdat_groups = false;
1353 for (node = cgraph_nodes; node; node = node->next)
1354 gcc_assert (!node->process);
1357 for (node = cgraph_nodes; node; node = node->next)
1359 tree decl = node->decl;
1360 struct cgraph_edge *e;
1362 gcc_assert (!node->process || node->same_comdat_group);
1366 for (e = node->callers; e; e = e->next_caller)
1367 if (e->inline_failed)
1370 /* We need to output all local functions that are used and not
1371 always inlined, as well as those that are reachable from
1372 outside the current compilation unit. */
1374 && !node->thunk.thunk_p
1376 && !node->global.inlined_to
1377 && (!cgraph_only_called_directly_p (node)
1378 || ((e || ipa_ref_has_aliases_p (&node->ref_list))
1379 && node->reachable))
1380 && !TREE_ASM_WRITTEN (decl)
1381 && !DECL_EXTERNAL (decl))
1384 if (node->same_comdat_group)
1386 struct cgraph_node *next;
1387 for (next = node->same_comdat_group;
1389 next = next->same_comdat_group)
1390 if (!next->thunk.thunk_p && !next->alias)
1394 else if (node->same_comdat_group)
1396 #ifdef ENABLE_CHECKING
1397 check_same_comdat_groups = true;
1402 /* We should've reclaimed all functions that are not needed. */
1403 #ifdef ENABLE_CHECKING
1404 if (!node->global.inlined_to
1405 && gimple_has_body_p (decl)
1406 /* FIXME: in ltrans unit when offline copy is outside partition but inline copies
1407 are inside partition, we can end up not removing the body since we no longer
1408 have analyzed node pointing to it. */
1409 && !node->in_other_partition
1411 && !DECL_EXTERNAL (decl))
1413 dump_cgraph_node (stderr, node);
1414 internal_error ("failed to reclaim unneeded function");
1417 gcc_assert (node->global.inlined_to
1418 || !gimple_has_body_p (decl)
1419 || node->in_other_partition
1420 || DECL_EXTERNAL (decl));
1425 #ifdef ENABLE_CHECKING
1426 if (check_same_comdat_groups)
1427 for (node = cgraph_nodes; node; node = node->next)
1428 if (node->same_comdat_group && !node->process)
1430 tree decl = node->decl;
1431 if (!node->global.inlined_to
1432 && gimple_has_body_p (decl)
1433 /* FIXME: in ltrans unit when offline copy is outside partition but inline copies
1434 are inside partition, we can end up not removing the body since we no longer
1435 have analyzed node pointing to it. */
1436 && !node->in_other_partition
1437 && !DECL_EXTERNAL (decl))
1439 dump_cgraph_node (stderr, node);
1440 internal_error ("failed to reclaim unneeded functionin same comdat group");
1446 /* DECL is FUNCTION_DECL. Initialize datastructures so DECL is a function
1447 in lowered gimple form.
1449 Set current_function_decl and cfun to newly constructed empty function body.
1450 return basic block in the function body. */
1453 init_lowered_empty_function (tree decl)
1457 current_function_decl = decl;
1458 allocate_struct_function (decl, false);
1459 gimple_register_cfg_hooks ();
1460 init_empty_tree_cfg ();
1461 init_tree_ssa (cfun);
1462 init_ssa_operands ();
1463 cfun->gimple_df->in_ssa_p = true;
1464 DECL_INITIAL (decl) = make_node (BLOCK);
1466 DECL_SAVED_TREE (decl) = error_mark_node;
1467 cfun->curr_properties |=
1468 (PROP_gimple_lcf | PROP_gimple_leh | PROP_cfg | PROP_referenced_vars |
1469 PROP_ssa | PROP_gimple_any);
1471 /* Create BB for body of the function and connect it properly. */
1472 bb = create_basic_block (NULL, (void *) 0, ENTRY_BLOCK_PTR);
1473 make_edge (ENTRY_BLOCK_PTR, bb, 0);
1474 make_edge (bb, EXIT_BLOCK_PTR, 0);
1479 /* Adjust PTR by the constant FIXED_OFFSET, and by the vtable
1480 offset indicated by VIRTUAL_OFFSET, if that is
1481 non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and
1482 zero for a result adjusting thunk. */
1485 thunk_adjust (gimple_stmt_iterator * bsi,
1486 tree ptr, bool this_adjusting,
1487 HOST_WIDE_INT fixed_offset, tree virtual_offset)
1493 && fixed_offset != 0)
1495 stmt = gimple_build_assign
1496 (ptr, fold_build_pointer_plus_hwi_loc (input_location,
1499 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1502 /* If there's a virtual offset, look up that value in the vtable and
1503 adjust the pointer again. */
1510 if (!vtable_entry_type)
1512 tree vfunc_type = make_node (FUNCTION_TYPE);
1513 TREE_TYPE (vfunc_type) = integer_type_node;
1514 TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
1515 layout_type (vfunc_type);
1517 vtable_entry_type = build_pointer_type (vfunc_type);
1521 create_tmp_var (build_pointer_type
1522 (build_pointer_type (vtable_entry_type)), "vptr");
1524 /* The vptr is always at offset zero in the object. */
1525 stmt = gimple_build_assign (vtabletmp,
1526 build1 (NOP_EXPR, TREE_TYPE (vtabletmp),
1528 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1529 mark_symbols_for_renaming (stmt);
1530 find_referenced_vars_in (stmt);
1532 /* Form the vtable address. */
1533 vtabletmp2 = create_tmp_var (TREE_TYPE (TREE_TYPE (vtabletmp)),
1535 stmt = gimple_build_assign (vtabletmp2,
1536 build_simple_mem_ref (vtabletmp));
1537 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1538 mark_symbols_for_renaming (stmt);
1539 find_referenced_vars_in (stmt);
1541 /* Find the entry with the vcall offset. */
1542 stmt = gimple_build_assign (vtabletmp2,
1543 fold_build_pointer_plus_loc (input_location,
1546 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1548 /* Get the offset itself. */
1549 vtabletmp3 = create_tmp_var (TREE_TYPE (TREE_TYPE (vtabletmp2)),
1551 stmt = gimple_build_assign (vtabletmp3,
1552 build_simple_mem_ref (vtabletmp2));
1553 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1554 mark_symbols_for_renaming (stmt);
1555 find_referenced_vars_in (stmt);
1557 /* Adjust the `this' pointer. */
1558 ptr = fold_build_pointer_plus_loc (input_location, ptr, vtabletmp3);
1559 ptr = force_gimple_operand_gsi (bsi, ptr, true, NULL_TREE, false,
1560 GSI_CONTINUE_LINKING);
1564 && fixed_offset != 0)
1565 /* Adjust the pointer by the constant. */
1569 if (TREE_CODE (ptr) == VAR_DECL)
1573 ptrtmp = create_tmp_var (TREE_TYPE (ptr), "ptr");
1574 stmt = gimple_build_assign (ptrtmp, ptr);
1575 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1576 mark_symbols_for_renaming (stmt);
1577 find_referenced_vars_in (stmt);
1579 ptr = fold_build_pointer_plus_hwi_loc (input_location,
1580 ptrtmp, fixed_offset);
1583 /* Emit the statement and gimplify the adjustment expression. */
1584 ret = create_tmp_var (TREE_TYPE (ptr), "adjusted_this");
1585 stmt = gimple_build_assign (ret, ptr);
1586 mark_symbols_for_renaming (stmt);
1587 find_referenced_vars_in (stmt);
1588 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1593 /* Produce assembler for thunk NODE. */
1596 assemble_thunk (struct cgraph_node *node)
1598 bool this_adjusting = node->thunk.this_adjusting;
1599 HOST_WIDE_INT fixed_offset = node->thunk.fixed_offset;
1600 HOST_WIDE_INT virtual_value = node->thunk.virtual_value;
1601 tree virtual_offset = NULL;
1602 tree alias = node->thunk.alias;
1603 tree thunk_fndecl = node->decl;
1604 tree a = DECL_ARGUMENTS (thunk_fndecl);
1606 current_function_decl = thunk_fndecl;
1608 /* Ensure thunks are emitted in their correct sections. */
1609 resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
1612 && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
1613 virtual_value, alias))
1617 tree restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1619 DECL_RESULT (thunk_fndecl)
1620 = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl),
1621 RESULT_DECL, 0, restype);
1622 fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
1624 /* The back end expects DECL_INITIAL to contain a BLOCK, so we
1626 fn_block = make_node (BLOCK);
1627 BLOCK_VARS (fn_block) = a;
1628 DECL_INITIAL (thunk_fndecl) = fn_block;
1629 init_function_start (thunk_fndecl);
1631 assemble_start_function (thunk_fndecl, fnname);
1633 targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl,
1634 fixed_offset, virtual_value, alias);
1636 assemble_end_function (thunk_fndecl, fnname);
1637 init_insn_lengths ();
1638 free_after_compilation (cfun);
1640 TREE_ASM_WRITTEN (thunk_fndecl) = 1;
1641 node->thunk.thunk_p = false;
1642 node->analyzed = false;
1647 basic_block bb, then_bb, else_bb, return_bb;
1648 gimple_stmt_iterator bsi;
1654 VEC(tree, heap) *vargs;
1659 DECL_IGNORED_P (thunk_fndecl) = 1;
1660 bitmap_obstack_initialize (NULL);
1662 if (node->thunk.virtual_offset_p)
1663 virtual_offset = size_int (virtual_value);
1665 /* Build the return declaration for the function. */
1666 restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1667 if (DECL_RESULT (thunk_fndecl) == NULL_TREE)
1669 resdecl = build_decl (input_location, RESULT_DECL, 0, restype);
1670 DECL_ARTIFICIAL (resdecl) = 1;
1671 DECL_IGNORED_P (resdecl) = 1;
1672 DECL_RESULT (thunk_fndecl) = resdecl;
1675 resdecl = DECL_RESULT (thunk_fndecl);
1677 bb = then_bb = else_bb = return_bb = init_lowered_empty_function (thunk_fndecl);
1679 bsi = gsi_start_bb (bb);
1681 /* Build call to the function being thunked. */
1682 if (!VOID_TYPE_P (restype))
1684 if (!is_gimple_reg_type (restype))
1687 add_local_decl (cfun, restmp);
1688 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp;
1691 restmp = create_tmp_var_raw (restype, "retval");
1694 for (arg = a; arg; arg = DECL_CHAIN (arg))
1696 vargs = VEC_alloc (tree, heap, nargs);
1698 VEC_quick_push (tree, vargs,
1703 VEC_quick_push (tree, vargs, a);
1704 for (i = 1, arg = DECL_CHAIN (a); i < nargs; i++, arg = DECL_CHAIN (arg))
1705 VEC_quick_push (tree, vargs, arg);
1706 call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs);
1707 VEC_free (tree, heap, vargs);
1708 gimple_call_set_from_thunk (call, true);
1710 gimple_call_set_lhs (call, restmp);
1711 gsi_insert_after (&bsi, call, GSI_NEW_STMT);
1712 mark_symbols_for_renaming (call);
1713 find_referenced_vars_in (call);
1716 if (restmp && !this_adjusting)
1718 tree true_label = NULL_TREE;
1720 if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE)
1723 /* If the return type is a pointer, we need to
1724 protect against NULL. We know there will be an
1725 adjustment, because that's why we're emitting a
1727 then_bb = create_basic_block (NULL, (void *) 0, bb);
1728 return_bb = create_basic_block (NULL, (void *) 0, then_bb);
1729 else_bb = create_basic_block (NULL, (void *) 0, else_bb);
1730 remove_edge (single_succ_edge (bb));
1731 true_label = gimple_block_label (then_bb);
1732 stmt = gimple_build_cond (NE_EXPR, restmp,
1733 build_zero_cst (TREE_TYPE (restmp)),
1734 NULL_TREE, NULL_TREE);
1735 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1736 make_edge (bb, then_bb, EDGE_TRUE_VALUE);
1737 make_edge (bb, else_bb, EDGE_FALSE_VALUE);
1738 make_edge (return_bb, EXIT_BLOCK_PTR, 0);
1739 make_edge (then_bb, return_bb, EDGE_FALLTHRU);
1740 make_edge (else_bb, return_bb, EDGE_FALLTHRU);
1741 bsi = gsi_last_bb (then_bb);
1744 restmp = thunk_adjust (&bsi, restmp, /*this_adjusting=*/0,
1745 fixed_offset, virtual_offset);
1749 bsi = gsi_last_bb (else_bb);
1750 stmt = gimple_build_assign (restmp,
1751 build_zero_cst (TREE_TYPE (restmp)));
1752 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1753 bsi = gsi_last_bb (return_bb);
1757 gimple_call_set_tail (call, true);
1759 /* Build return value. */
1760 ret = gimple_build_return (restmp);
1761 gsi_insert_after (&bsi, ret, GSI_NEW_STMT);
1763 delete_unreachable_blocks ();
1764 update_ssa (TODO_update_ssa);
1766 /* Since we want to emit the thunk, we explicitly mark its name as
1768 node->thunk.thunk_p = false;
1769 cgraph_node_remove_callees (node);
1770 cgraph_add_new_function (thunk_fndecl, true);
1771 bitmap_obstack_release (NULL);
1773 current_function_decl = NULL;
1778 /* Assemble thunks and aliases asociated to NODE. */
1781 assemble_thunks_and_aliases (struct cgraph_node *node)
1783 struct cgraph_edge *e;
1785 struct ipa_ref *ref;
1787 for (e = node->callers; e;)
1788 if (e->caller->thunk.thunk_p)
1790 struct cgraph_node *thunk = e->caller;
1793 assemble_thunks_and_aliases (thunk);
1794 assemble_thunk (thunk);
1798 for (i = 0; ipa_ref_list_refering_iterate (&node->ref_list, i, ref); i++)
1799 if (ref->use == IPA_REF_ALIAS)
1801 struct cgraph_node *alias = ipa_ref_refering_node (ref);
1802 bool saved_written = TREE_ASM_WRITTEN (alias->thunk.alias);
1804 /* Force assemble_alias to really output the alias this time instead
1805 of buffering it in same alias pairs. */
1806 TREE_ASM_WRITTEN (alias->thunk.alias) = 1;
1807 assemble_alias (alias->decl,
1808 DECL_ASSEMBLER_NAME (alias->thunk.alias));
1809 assemble_thunks_and_aliases (alias);
1810 TREE_ASM_WRITTEN (alias->thunk.alias) = saved_written;
1814 /* Expand function specified by NODE. */
1817 cgraph_expand_function (struct cgraph_node *node)
1819 tree decl = node->decl;
1821 /* We ought to not compile any inline clones. */
1822 gcc_assert (!node->global.inlined_to);
1824 announce_function (decl);
1826 gcc_assert (node->lowered);
1828 /* Generate RTL for the body of DECL. */
1829 tree_rest_of_compilation (decl);
1831 /* Make sure that BE didn't give up on compiling. */
1832 gcc_assert (TREE_ASM_WRITTEN (decl));
1833 current_function_decl = NULL;
1834 gcc_assert (!cgraph_preserve_function_body_p (node));
1836 /* It would make a lot more sense to output thunks before function body to get more
1837 forward and lest backwarding jumps. This is however would need solving problem
1838 with comdats. See PR48668. Also aliases must come after function itself to
1839 make one pass assemblers, like one on AIX happy. See PR 50689.
1840 FIXME: Perhaps thunks should be move before function IFF they are not in comdat
1842 assemble_thunks_and_aliases (node);
1843 cgraph_release_function_body (node);
1844 /* Eliminate all call edges. This is important so the GIMPLE_CALL no longer
1845 points to the dead function body. */
1846 cgraph_node_remove_callees (node);
1848 cgraph_function_flags_ready = true;
1851 /* Return true when CALLER_DECL should be inlined into CALLEE_DECL. */
1854 cgraph_inline_p (struct cgraph_edge *e, cgraph_inline_failed_t *reason)
1856 *reason = e->inline_failed;
1857 return !e->inline_failed;
1862 /* Expand all functions that must be output.
1864 Attempt to topologically sort the nodes so function is output when
1865 all called functions are already assembled to allow data to be
1866 propagated across the callgraph. Use a stack to get smaller distance
1867 between a function and its callees (later we may choose to use a more
1868 sophisticated algorithm for function reordering; we will likely want
1869 to use subsections to make the output functions appear in top-down
1873 cgraph_expand_all_functions (void)
1875 struct cgraph_node *node;
1876 struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
1877 int order_pos, new_order_pos = 0;
1880 order_pos = ipa_reverse_postorder (order);
1881 gcc_assert (order_pos == cgraph_n_nodes);
1883 /* Garbage collector may remove inline clones we eliminate during
1884 optimization. So we must be sure to not reference them. */
1885 for (i = 0; i < order_pos; i++)
1886 if (order[i]->process)
1887 order[new_order_pos++] = order[i];
1889 for (i = new_order_pos - 1; i >= 0; i--)
1894 gcc_assert (node->reachable);
1896 cgraph_expand_function (node);
1899 cgraph_process_new_functions ();
1905 /* This is used to sort the node types by the cgraph order number. */
1907 enum cgraph_order_sort_kind
1909 ORDER_UNDEFINED = 0,
1915 struct cgraph_order_sort
1917 enum cgraph_order_sort_kind kind;
1920 struct cgraph_node *f;
1921 struct varpool_node *v;
1922 struct cgraph_asm_node *a;
1926 /* Output all functions, variables, and asm statements in the order
1927 according to their order fields, which is the order in which they
1928 appeared in the file. This implements -fno-toplevel-reorder. In
1929 this mode we may output functions and variables which don't really
1930 need to be output. */
1933 cgraph_output_in_order (void)
1936 struct cgraph_order_sort *nodes;
1938 struct cgraph_node *pf;
1939 struct varpool_node *pv;
1940 struct cgraph_asm_node *pa;
1943 nodes = XCNEWVEC (struct cgraph_order_sort, max);
1945 varpool_analyze_pending_decls ();
1947 for (pf = cgraph_nodes; pf; pf = pf->next)
1949 if (pf->process && !pf->thunk.thunk_p && !pf->alias)
1952 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1953 nodes[i].kind = ORDER_FUNCTION;
1958 for (pv = varpool_nodes_queue; pv; pv = pv->next_needed)
1961 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1962 nodes[i].kind = ORDER_VAR;
1966 for (pa = cgraph_asm_nodes; pa; pa = pa->next)
1969 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1970 nodes[i].kind = ORDER_ASM;
1974 /* In toplevel reorder mode we output all statics; mark them as needed. */
1975 for (i = 0; i < max; ++i)
1977 if (nodes[i].kind == ORDER_VAR)
1979 varpool_mark_needed_node (nodes[i].u.v);
1982 varpool_empty_needed_queue ();
1984 for (i = 0; i < max; ++i)
1985 if (nodes[i].kind == ORDER_VAR)
1986 varpool_finalize_named_section_flags (nodes[i].u.v);
1988 for (i = 0; i < max; ++i)
1990 switch (nodes[i].kind)
1992 case ORDER_FUNCTION:
1993 nodes[i].u.f->process = 0;
1994 cgraph_expand_function (nodes[i].u.f);
1998 varpool_assemble_decl (nodes[i].u.v);
2002 assemble_asm (nodes[i].u.a->asm_str);
2005 case ORDER_UNDEFINED:
2013 cgraph_asm_nodes = NULL;
2017 /* Return true when function body of DECL still needs to be kept around
2018 for later re-use. */
2020 cgraph_preserve_function_body_p (struct cgraph_node *node)
2022 gcc_assert (cgraph_global_info_ready);
2023 gcc_assert (!node->alias && !node->thunk.thunk_p);
2025 /* Look if there is any clone around. */
2035 current_function_decl = NULL;
2036 gimple_register_cfg_hooks ();
2037 bitmap_obstack_initialize (NULL);
2039 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START, NULL);
2043 execute_ipa_pass_list (all_small_ipa_passes);
2048 /* We never run removal of unreachable nodes after early passes. This is
2049 because TODO is run before the subpasses. It is important to remove
2050 the unreachable functions to save works at IPA level and to get LTO
2051 symbol tables right. */
2052 cgraph_remove_unreachable_nodes (true, cgraph_dump_file);
2054 /* If pass_all_early_optimizations was not scheduled, the state of
2055 the cgraph will not be properly updated. Update it now. */
2056 if (cgraph_state < CGRAPH_STATE_IPA_SSA)
2057 cgraph_state = CGRAPH_STATE_IPA_SSA;
2061 /* Generate coverage variables and constructors. */
2064 /* Process new functions added. */
2066 current_function_decl = NULL;
2067 cgraph_process_new_functions ();
2069 execute_ipa_summary_passes
2070 ((struct ipa_opt_pass_d *) all_regular_ipa_passes);
2073 /* Some targets need to handle LTO assembler output specially. */
2074 if (flag_generate_lto)
2075 targetm.asm_out.lto_start ();
2077 execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_lto_gen_passes);
2080 ipa_write_summaries ();
2082 if (flag_generate_lto)
2083 targetm.asm_out.lto_end ();
2085 if (!flag_ltrans && (in_lto_p || !flag_lto || flag_fat_lto_objects))
2086 execute_ipa_pass_list (all_regular_ipa_passes);
2087 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END, NULL);
2089 bitmap_obstack_release (NULL);
2093 /* Return string alias is alias of. */
2096 get_alias_symbol (tree decl)
2098 tree alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
2099 return get_identifier (TREE_STRING_POINTER
2100 (TREE_VALUE (TREE_VALUE (alias))));
2104 /* Weakrefs may be associated to external decls and thus not output
2105 at expansion time. Emit all neccesary aliases. */
2108 output_weakrefs (void)
2110 struct cgraph_node *node;
2111 struct varpool_node *vnode;
2112 for (node = cgraph_nodes; node; node = node->next)
2113 if (node->alias && DECL_EXTERNAL (node->decl)
2114 && !TREE_ASM_WRITTEN (node->decl)
2115 && lookup_attribute ("weakref", DECL_ATTRIBUTES (node->decl)))
2116 assemble_alias (node->decl,
2117 node->thunk.alias ? DECL_ASSEMBLER_NAME (node->thunk.alias)
2118 : get_alias_symbol (node->decl));
2119 for (vnode = varpool_nodes; vnode; vnode = vnode->next)
2120 if (vnode->alias && DECL_EXTERNAL (vnode->decl)
2121 && !TREE_ASM_WRITTEN (vnode->decl)
2122 && lookup_attribute ("weakref", DECL_ATTRIBUTES (vnode->decl)))
2123 assemble_alias (vnode->decl,
2124 vnode->alias_of ? DECL_ASSEMBLER_NAME (vnode->alias_of)
2125 : get_alias_symbol (vnode->decl));
2129 /* Perform simple optimizations based on callgraph. */
2132 cgraph_optimize (void)
2137 #ifdef ENABLE_CHECKING
2141 /* Frontend may output common variables after the unit has been finalized.
2142 It is safe to deal with them here as they are always zero initialized. */
2143 varpool_analyze_pending_decls ();
2145 timevar_push (TV_CGRAPHOPT);
2146 if (pre_ipa_mem_report)
2148 fprintf (stderr, "Memory consumption before IPA\n");
2149 dump_memory_report (false);
2152 fprintf (stderr, "Performing interprocedural optimizations\n");
2153 cgraph_state = CGRAPH_STATE_IPA;
2155 /* Don't run the IPA passes if there was any error or sorry messages. */
2159 /* Do nothing else if any IPA pass found errors or if we are just streaming LTO. */
2161 || (!in_lto_p && flag_lto && !flag_fat_lto_objects))
2163 timevar_pop (TV_CGRAPHOPT);
2167 /* This pass remove bodies of extern inline functions we never inlined.
2168 Do this later so other IPA passes see what is really going on. */
2169 cgraph_remove_unreachable_nodes (false, dump_file);
2170 cgraph_global_info_ready = true;
2171 if (cgraph_dump_file)
2173 fprintf (cgraph_dump_file, "Optimized ");
2174 dump_cgraph (cgraph_dump_file);
2175 dump_varpool (cgraph_dump_file);
2177 if (post_ipa_mem_report)
2179 fprintf (stderr, "Memory consumption after IPA\n");
2180 dump_memory_report (false);
2182 timevar_pop (TV_CGRAPHOPT);
2184 /* Output everything. */
2185 (*debug_hooks->assembly_start) ();
2187 fprintf (stderr, "Assembling functions:\n");
2188 #ifdef ENABLE_CHECKING
2192 cgraph_materialize_all_clones ();
2193 bitmap_obstack_initialize (NULL);
2194 execute_ipa_pass_list (all_late_ipa_passes);
2195 cgraph_remove_unreachable_nodes (true, dump_file);
2196 #ifdef ENABLE_CHECKING
2199 bitmap_obstack_release (NULL);
2200 cgraph_mark_functions_to_output ();
2203 cgraph_state = CGRAPH_STATE_EXPANSION;
2204 if (!flag_toplevel_reorder)
2205 cgraph_output_in_order ();
2208 cgraph_output_pending_asms ();
2210 cgraph_expand_all_functions ();
2211 varpool_remove_unreferenced_decls ();
2213 varpool_assemble_pending_decls ();
2216 cgraph_process_new_functions ();
2217 cgraph_state = CGRAPH_STATE_FINISHED;
2219 if (cgraph_dump_file)
2221 fprintf (cgraph_dump_file, "\nFinal ");
2222 dump_cgraph (cgraph_dump_file);
2223 dump_varpool (cgraph_dump_file);
2225 #ifdef ENABLE_CHECKING
2227 /* Double check that all inline clones are gone and that all
2228 function bodies have been released from memory. */
2231 struct cgraph_node *node;
2232 bool error_found = false;
2234 for (node = cgraph_nodes; node; node = node->next)
2236 && (node->global.inlined_to
2237 || gimple_has_body_p (node->decl)))
2240 dump_cgraph_node (stderr, node);
2243 internal_error ("nodes with unreleased memory found");
2251 if (!cgraph_dump_file)
2252 cgraph_dump_file = dump_begin (TDI_cgraph, NULL);
2255 /* The edges representing the callers of the NEW_VERSION node were
2256 fixed by cgraph_function_versioning (), now the call_expr in their
2257 respective tree code should be updated to call the NEW_VERSION. */
2260 update_call_expr (struct cgraph_node *new_version)
2262 struct cgraph_edge *e;
2264 gcc_assert (new_version);
2266 /* Update the call expr on the edges to call the new version. */
2267 for (e = new_version->callers; e; e = e->next_caller)
2269 struct function *inner_function = DECL_STRUCT_FUNCTION (e->caller->decl);
2270 gimple_call_set_fndecl (e->call_stmt, new_version->decl);
2271 maybe_clean_eh_stmt_fn (inner_function, e->call_stmt);
2276 /* Create a new cgraph node which is the new version of
2277 OLD_VERSION node. REDIRECT_CALLERS holds the callers
2278 edges which should be redirected to point to
2279 NEW_VERSION. ALL the callees edges of OLD_VERSION
2280 are cloned to the new version node. Return the new
2283 If non-NULL BLOCK_TO_COPY determine what basic blocks
2284 was copied to prevent duplications of calls that are dead
2287 struct cgraph_node *
2288 cgraph_copy_node_for_versioning (struct cgraph_node *old_version,
2290 VEC(cgraph_edge_p,heap) *redirect_callers,
2293 struct cgraph_node *new_version;
2294 struct cgraph_edge *e;
2297 gcc_assert (old_version);
2299 new_version = cgraph_create_node (new_decl);
2301 new_version->analyzed = old_version->analyzed;
2302 new_version->local = old_version->local;
2303 new_version->local.externally_visible = false;
2304 new_version->local.local = true;
2305 new_version->global = old_version->global;
2306 new_version->rtl = old_version->rtl;
2307 new_version->reachable = true;
2308 new_version->count = old_version->count;
2310 for (e = old_version->callees; e; e=e->next_callee)
2312 || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
2313 cgraph_clone_edge (e, new_version, e->call_stmt,
2314 e->lto_stmt_uid, REG_BR_PROB_BASE,
2317 for (e = old_version->indirect_calls; e; e=e->next_callee)
2319 || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
2320 cgraph_clone_edge (e, new_version, e->call_stmt,
2321 e->lto_stmt_uid, REG_BR_PROB_BASE,
2324 FOR_EACH_VEC_ELT (cgraph_edge_p, redirect_callers, i, e)
2326 /* Redirect calls to the old version node to point to its new
2328 cgraph_redirect_edge_callee (e, new_version);
2331 cgraph_call_node_duplication_hooks (old_version, new_version);
2336 /* Perform function versioning.
2337 Function versioning includes copying of the tree and
2338 a callgraph update (creating a new cgraph node and updating
2339 its callees and callers).
2341 REDIRECT_CALLERS varray includes the edges to be redirected
2344 TREE_MAP is a mapping of tree nodes we want to replace with
2345 new ones (according to results of prior analysis).
2346 OLD_VERSION_NODE is the node that is versioned.
2348 If non-NULL ARGS_TO_SKIP determine function parameters to remove
2350 If SKIP_RETURN is true, the new version will return void.
2351 If non-NULL BLOCK_TO_COPY determine what basic blocks to copy.
2352 If non_NULL NEW_ENTRY determine new entry BB of the clone.
2354 Return the new version's cgraph node. */
2356 struct cgraph_node *
2357 cgraph_function_versioning (struct cgraph_node *old_version_node,
2358 VEC(cgraph_edge_p,heap) *redirect_callers,
2359 VEC (ipa_replace_map_p,gc)* tree_map,
2360 bitmap args_to_skip,
2363 basic_block new_entry_block,
2364 const char *clone_name)
2366 tree old_decl = old_version_node->decl;
2367 struct cgraph_node *new_version_node = NULL;
2370 if (!tree_versionable_function_p (old_decl))
2373 gcc_assert (old_version_node->local.can_change_signature || !args_to_skip);
2375 /* Make a new FUNCTION_DECL tree node for the new version. */
2376 if (!args_to_skip && !skip_return)
2377 new_decl = copy_node (old_decl);
2380 = build_function_decl_skip_args (old_decl, args_to_skip, skip_return);
2382 /* Generate a new name for the new version. */
2383 DECL_NAME (new_decl) = clone_function_name (old_decl, clone_name);
2384 SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
2385 SET_DECL_RTL (new_decl, NULL);
2387 /* When the old decl was a con-/destructor make sure the clone isn't. */
2388 DECL_STATIC_CONSTRUCTOR(new_decl) = 0;
2389 DECL_STATIC_DESTRUCTOR(new_decl) = 0;
2391 /* Create the new version's call-graph node.
2392 and update the edges of the new node. */
2394 cgraph_copy_node_for_versioning (old_version_node, new_decl,
2395 redirect_callers, bbs_to_copy);
2397 /* Copy the OLD_VERSION_NODE function tree to the new version. */
2398 tree_function_versioning (old_decl, new_decl, tree_map, false, args_to_skip,
2399 skip_return, bbs_to_copy, new_entry_block);
2401 /* Update the new version's properties.
2402 Make The new version visible only within this translation unit. Make sure
2403 that is not weak also.
2404 ??? We cannot use COMDAT linkage because there is no
2405 ABI support for this. */
2406 cgraph_make_decl_local (new_version_node->decl);
2407 DECL_VIRTUAL_P (new_version_node->decl) = 0;
2408 new_version_node->local.externally_visible = 0;
2409 new_version_node->local.local = 1;
2410 new_version_node->lowered = true;
2412 /* Update the call_expr on the edges to call the new version node. */
2413 update_call_expr (new_version_node);
2415 cgraph_call_function_insertion_hooks (new_version_node);
2416 return new_version_node;
2419 /* Given virtual clone, turn it into actual clone. */
2421 cgraph_materialize_clone (struct cgraph_node *node)
2423 bitmap_obstack_initialize (NULL);
2424 node->former_clone_of = node->clone_of->decl;
2425 if (node->clone_of->former_clone_of)
2426 node->former_clone_of = node->clone_of->former_clone_of;
2427 /* Copy the OLD_VERSION_NODE function tree to the new version. */
2428 tree_function_versioning (node->clone_of->decl, node->decl,
2429 node->clone.tree_map, true,
2430 node->clone.args_to_skip, false,
2432 if (cgraph_dump_file)
2434 dump_function_to_file (node->clone_of->decl, cgraph_dump_file, dump_flags);
2435 dump_function_to_file (node->decl, cgraph_dump_file, dump_flags);
2438 /* Function is no longer clone. */
2439 if (node->next_sibling_clone)
2440 node->next_sibling_clone->prev_sibling_clone = node->prev_sibling_clone;
2441 if (node->prev_sibling_clone)
2442 node->prev_sibling_clone->next_sibling_clone = node->next_sibling_clone;
2444 node->clone_of->clones = node->next_sibling_clone;
2445 node->next_sibling_clone = NULL;
2446 node->prev_sibling_clone = NULL;
2447 if (!node->clone_of->analyzed && !node->clone_of->clones)
2449 cgraph_release_function_body (node->clone_of);
2450 cgraph_node_remove_callees (node->clone_of);
2451 ipa_remove_all_references (&node->clone_of->ref_list);
2453 node->clone_of = NULL;
2454 bitmap_obstack_release (NULL);
2457 /* If necessary, change the function declaration in the call statement
2458 associated with E so that it corresponds to the edge callee. */
2461 cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *e)
2463 tree decl = gimple_call_fndecl (e->call_stmt);
2465 gimple_stmt_iterator gsi;
2466 #ifdef ENABLE_CHECKING
2467 struct cgraph_node *node;
2470 if (e->indirect_unknown_callee
2471 || decl == e->callee->decl)
2472 return e->call_stmt;
2474 #ifdef ENABLE_CHECKING
2477 node = cgraph_get_node (decl);
2478 gcc_assert (!node || !node->clone.combined_args_to_skip);
2482 if (cgraph_dump_file)
2484 fprintf (cgraph_dump_file, "updating call of %s/%i -> %s/%i: ",
2485 cgraph_node_name (e->caller), e->caller->uid,
2486 cgraph_node_name (e->callee), e->callee->uid);
2487 print_gimple_stmt (cgraph_dump_file, e->call_stmt, 0, dump_flags);
2488 if (e->callee->clone.combined_args_to_skip)
2490 fprintf (cgraph_dump_file, " combined args to skip: ");
2491 dump_bitmap (cgraph_dump_file,
2492 e->callee->clone.combined_args_to_skip);
2496 if (e->callee->clone.combined_args_to_skip)
2501 = gimple_call_copy_skip_args (e->call_stmt,
2502 e->callee->clone.combined_args_to_skip);
2503 gimple_call_set_fndecl (new_stmt, e->callee->decl);
2505 if (gimple_vdef (new_stmt)
2506 && TREE_CODE (gimple_vdef (new_stmt)) == SSA_NAME)
2507 SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt;
2509 gsi = gsi_for_stmt (e->call_stmt);
2510 gsi_replace (&gsi, new_stmt, false);
2511 /* We need to defer cleaning EH info on the new statement to
2512 fixup-cfg. We may not have dominator information at this point
2513 and thus would end up with unreachable blocks and have no way
2514 to communicate that we need to run CFG cleanup then. */
2515 lp_nr = lookup_stmt_eh_lp (e->call_stmt);
2518 remove_stmt_from_eh_lp (e->call_stmt);
2519 add_stmt_to_eh_lp (new_stmt, lp_nr);
2524 new_stmt = e->call_stmt;
2525 gimple_call_set_fndecl (new_stmt, e->callee->decl);
2526 update_stmt (new_stmt);
2529 cgraph_set_call_stmt_including_clones (e->caller, e->call_stmt, new_stmt);
2531 if (cgraph_dump_file)
2533 fprintf (cgraph_dump_file, " updated to:");
2534 print_gimple_stmt (cgraph_dump_file, e->call_stmt, 0, dump_flags);
2539 /* Once all functions from compilation unit are in memory, produce all clones
2540 and update all calls. We might also do this on demand if we don't want to
2541 bring all functions to memory prior compilation, but current WHOPR
2542 implementation does that and it is is bit easier to keep everything right in
2545 cgraph_materialize_all_clones (void)
2547 struct cgraph_node *node;
2548 bool stabilized = false;
2550 if (cgraph_dump_file)
2551 fprintf (cgraph_dump_file, "Materializing clones\n");
2552 #ifdef ENABLE_CHECKING
2556 /* We can also do topological order, but number of iterations should be
2557 bounded by number of IPA passes since single IPA pass is probably not
2558 going to create clones of clones it created itself. */
2562 for (node = cgraph_nodes; node; node = node->next)
2564 if (node->clone_of && node->decl != node->clone_of->decl
2565 && !gimple_has_body_p (node->decl))
2567 if (gimple_has_body_p (node->clone_of->decl))
2569 if (cgraph_dump_file)
2571 fprintf (cgraph_dump_file, "cloning %s to %s\n",
2572 cgraph_node_name (node->clone_of),
2573 cgraph_node_name (node));
2574 if (node->clone.tree_map)
2577 fprintf (cgraph_dump_file, " replace map: ");
2578 for (i = 0; i < VEC_length (ipa_replace_map_p,
2579 node->clone.tree_map);
2582 struct ipa_replace_map *replace_info;
2583 replace_info = VEC_index (ipa_replace_map_p,
2584 node->clone.tree_map,
2586 print_generic_expr (cgraph_dump_file, replace_info->old_tree, 0);
2587 fprintf (cgraph_dump_file, " -> ");
2588 print_generic_expr (cgraph_dump_file, replace_info->new_tree, 0);
2589 fprintf (cgraph_dump_file, "%s%s;",
2590 replace_info->replace_p ? "(replace)":"",
2591 replace_info->ref_p ? "(ref)":"");
2593 fprintf (cgraph_dump_file, "\n");
2595 if (node->clone.args_to_skip)
2597 fprintf (cgraph_dump_file, " args_to_skip: ");
2598 dump_bitmap (cgraph_dump_file, node->clone.args_to_skip);
2600 if (node->clone.args_to_skip)
2602 fprintf (cgraph_dump_file, " combined_args_to_skip:");
2603 dump_bitmap (cgraph_dump_file, node->clone.combined_args_to_skip);
2606 cgraph_materialize_clone (node);
2612 for (node = cgraph_nodes; node; node = node->next)
2613 if (!node->analyzed && node->callees)
2614 cgraph_node_remove_callees (node);
2615 if (cgraph_dump_file)
2616 fprintf (cgraph_dump_file, "Materialization Call site updates done.\n");
2617 #ifdef ENABLE_CHECKING
2620 cgraph_remove_unreachable_nodes (false, cgraph_dump_file);
2623 #include "gt-cgraphunit.h"