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 an ltrans unit when the offline copy is outside a
1434 partition but inline copies are inside a partition, we can
1435 end up not removing the body since we no longer have an
1436 analyzed node pointing to it. */
1437 && !node->in_other_partition
1438 && !DECL_EXTERNAL (decl))
1440 dump_cgraph_node (stderr, node);
1441 internal_error ("failed to reclaim unneeded function in same "
1448 /* DECL is FUNCTION_DECL. Initialize datastructures so DECL is a function
1449 in lowered gimple form.
1451 Set current_function_decl and cfun to newly constructed empty function body.
1452 return basic block in the function body. */
1455 init_lowered_empty_function (tree decl)
1459 current_function_decl = decl;
1460 allocate_struct_function (decl, false);
1461 gimple_register_cfg_hooks ();
1462 init_empty_tree_cfg ();
1463 init_tree_ssa (cfun);
1464 init_ssa_operands ();
1465 cfun->gimple_df->in_ssa_p = true;
1466 DECL_INITIAL (decl) = make_node (BLOCK);
1468 DECL_SAVED_TREE (decl) = error_mark_node;
1469 cfun->curr_properties |=
1470 (PROP_gimple_lcf | PROP_gimple_leh | PROP_cfg | PROP_referenced_vars |
1471 PROP_ssa | PROP_gimple_any);
1473 /* Create BB for body of the function and connect it properly. */
1474 bb = create_basic_block (NULL, (void *) 0, ENTRY_BLOCK_PTR);
1475 make_edge (ENTRY_BLOCK_PTR, bb, 0);
1476 make_edge (bb, EXIT_BLOCK_PTR, 0);
1481 /* Adjust PTR by the constant FIXED_OFFSET, and by the vtable
1482 offset indicated by VIRTUAL_OFFSET, if that is
1483 non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and
1484 zero for a result adjusting thunk. */
1487 thunk_adjust (gimple_stmt_iterator * bsi,
1488 tree ptr, bool this_adjusting,
1489 HOST_WIDE_INT fixed_offset, tree virtual_offset)
1495 && fixed_offset != 0)
1497 stmt = gimple_build_assign
1498 (ptr, fold_build_pointer_plus_hwi_loc (input_location,
1501 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1504 /* If there's a virtual offset, look up that value in the vtable and
1505 adjust the pointer again. */
1512 if (!vtable_entry_type)
1514 tree vfunc_type = make_node (FUNCTION_TYPE);
1515 TREE_TYPE (vfunc_type) = integer_type_node;
1516 TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
1517 layout_type (vfunc_type);
1519 vtable_entry_type = build_pointer_type (vfunc_type);
1523 create_tmp_var (build_pointer_type
1524 (build_pointer_type (vtable_entry_type)), "vptr");
1526 /* The vptr is always at offset zero in the object. */
1527 stmt = gimple_build_assign (vtabletmp,
1528 build1 (NOP_EXPR, TREE_TYPE (vtabletmp),
1530 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1531 mark_symbols_for_renaming (stmt);
1532 find_referenced_vars_in (stmt);
1534 /* Form the vtable address. */
1535 vtabletmp2 = create_tmp_var (TREE_TYPE (TREE_TYPE (vtabletmp)),
1537 stmt = gimple_build_assign (vtabletmp2,
1538 build_simple_mem_ref (vtabletmp));
1539 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1540 mark_symbols_for_renaming (stmt);
1541 find_referenced_vars_in (stmt);
1543 /* Find the entry with the vcall offset. */
1544 stmt = gimple_build_assign (vtabletmp2,
1545 fold_build_pointer_plus_loc (input_location,
1548 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1550 /* Get the offset itself. */
1551 vtabletmp3 = create_tmp_var (TREE_TYPE (TREE_TYPE (vtabletmp2)),
1553 stmt = gimple_build_assign (vtabletmp3,
1554 build_simple_mem_ref (vtabletmp2));
1555 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1556 mark_symbols_for_renaming (stmt);
1557 find_referenced_vars_in (stmt);
1559 /* Adjust the `this' pointer. */
1560 ptr = fold_build_pointer_plus_loc (input_location, ptr, vtabletmp3);
1561 ptr = force_gimple_operand_gsi (bsi, ptr, true, NULL_TREE, false,
1562 GSI_CONTINUE_LINKING);
1566 && fixed_offset != 0)
1567 /* Adjust the pointer by the constant. */
1571 if (TREE_CODE (ptr) == VAR_DECL)
1575 ptrtmp = create_tmp_var (TREE_TYPE (ptr), "ptr");
1576 stmt = gimple_build_assign (ptrtmp, ptr);
1577 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1578 mark_symbols_for_renaming (stmt);
1579 find_referenced_vars_in (stmt);
1581 ptr = fold_build_pointer_plus_hwi_loc (input_location,
1582 ptrtmp, fixed_offset);
1585 /* Emit the statement and gimplify the adjustment expression. */
1586 ret = create_tmp_var (TREE_TYPE (ptr), "adjusted_this");
1587 stmt = gimple_build_assign (ret, ptr);
1588 mark_symbols_for_renaming (stmt);
1589 find_referenced_vars_in (stmt);
1590 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1595 /* Produce assembler for thunk NODE. */
1598 assemble_thunk (struct cgraph_node *node)
1600 bool this_adjusting = node->thunk.this_adjusting;
1601 HOST_WIDE_INT fixed_offset = node->thunk.fixed_offset;
1602 HOST_WIDE_INT virtual_value = node->thunk.virtual_value;
1603 tree virtual_offset = NULL;
1604 tree alias = node->thunk.alias;
1605 tree thunk_fndecl = node->decl;
1606 tree a = DECL_ARGUMENTS (thunk_fndecl);
1608 current_function_decl = thunk_fndecl;
1610 /* Ensure thunks are emitted in their correct sections. */
1611 resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
1614 && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
1615 virtual_value, alias))
1619 tree restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1621 DECL_RESULT (thunk_fndecl)
1622 = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl),
1623 RESULT_DECL, 0, restype);
1624 fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
1626 /* The back end expects DECL_INITIAL to contain a BLOCK, so we
1628 fn_block = make_node (BLOCK);
1629 BLOCK_VARS (fn_block) = a;
1630 DECL_INITIAL (thunk_fndecl) = fn_block;
1631 init_function_start (thunk_fndecl);
1633 assemble_start_function (thunk_fndecl, fnname);
1635 targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl,
1636 fixed_offset, virtual_value, alias);
1638 assemble_end_function (thunk_fndecl, fnname);
1639 init_insn_lengths ();
1640 free_after_compilation (cfun);
1642 TREE_ASM_WRITTEN (thunk_fndecl) = 1;
1643 node->thunk.thunk_p = false;
1644 node->analyzed = false;
1649 basic_block bb, then_bb, else_bb, return_bb;
1650 gimple_stmt_iterator bsi;
1656 VEC(tree, heap) *vargs;
1661 DECL_IGNORED_P (thunk_fndecl) = 1;
1662 bitmap_obstack_initialize (NULL);
1664 if (node->thunk.virtual_offset_p)
1665 virtual_offset = size_int (virtual_value);
1667 /* Build the return declaration for the function. */
1668 restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1669 if (DECL_RESULT (thunk_fndecl) == NULL_TREE)
1671 resdecl = build_decl (input_location, RESULT_DECL, 0, restype);
1672 DECL_ARTIFICIAL (resdecl) = 1;
1673 DECL_IGNORED_P (resdecl) = 1;
1674 DECL_RESULT (thunk_fndecl) = resdecl;
1677 resdecl = DECL_RESULT (thunk_fndecl);
1679 bb = then_bb = else_bb = return_bb = init_lowered_empty_function (thunk_fndecl);
1681 bsi = gsi_start_bb (bb);
1683 /* Build call to the function being thunked. */
1684 if (!VOID_TYPE_P (restype))
1686 if (!is_gimple_reg_type (restype))
1689 add_local_decl (cfun, restmp);
1690 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp;
1693 restmp = create_tmp_var_raw (restype, "retval");
1696 for (arg = a; arg; arg = DECL_CHAIN (arg))
1698 vargs = VEC_alloc (tree, heap, nargs);
1700 VEC_quick_push (tree, vargs,
1705 VEC_quick_push (tree, vargs, a);
1706 for (i = 1, arg = DECL_CHAIN (a); i < nargs; i++, arg = DECL_CHAIN (arg))
1707 VEC_quick_push (tree, vargs, arg);
1708 call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs);
1709 VEC_free (tree, heap, vargs);
1710 gimple_call_set_from_thunk (call, true);
1712 gimple_call_set_lhs (call, restmp);
1713 gsi_insert_after (&bsi, call, GSI_NEW_STMT);
1714 mark_symbols_for_renaming (call);
1715 find_referenced_vars_in (call);
1718 if (restmp && !this_adjusting)
1720 tree true_label = NULL_TREE;
1722 if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE)
1725 /* If the return type is a pointer, we need to
1726 protect against NULL. We know there will be an
1727 adjustment, because that's why we're emitting a
1729 then_bb = create_basic_block (NULL, (void *) 0, bb);
1730 return_bb = create_basic_block (NULL, (void *) 0, then_bb);
1731 else_bb = create_basic_block (NULL, (void *) 0, else_bb);
1732 remove_edge (single_succ_edge (bb));
1733 true_label = gimple_block_label (then_bb);
1734 stmt = gimple_build_cond (NE_EXPR, restmp,
1735 build_zero_cst (TREE_TYPE (restmp)),
1736 NULL_TREE, NULL_TREE);
1737 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1738 make_edge (bb, then_bb, EDGE_TRUE_VALUE);
1739 make_edge (bb, else_bb, EDGE_FALSE_VALUE);
1740 make_edge (return_bb, EXIT_BLOCK_PTR, 0);
1741 make_edge (then_bb, return_bb, EDGE_FALLTHRU);
1742 make_edge (else_bb, return_bb, EDGE_FALLTHRU);
1743 bsi = gsi_last_bb (then_bb);
1746 restmp = thunk_adjust (&bsi, restmp, /*this_adjusting=*/0,
1747 fixed_offset, virtual_offset);
1751 bsi = gsi_last_bb (else_bb);
1752 stmt = gimple_build_assign (restmp,
1753 build_zero_cst (TREE_TYPE (restmp)));
1754 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1755 bsi = gsi_last_bb (return_bb);
1759 gimple_call_set_tail (call, true);
1761 /* Build return value. */
1762 ret = gimple_build_return (restmp);
1763 gsi_insert_after (&bsi, ret, GSI_NEW_STMT);
1765 delete_unreachable_blocks ();
1766 update_ssa (TODO_update_ssa);
1768 /* Since we want to emit the thunk, we explicitly mark its name as
1770 node->thunk.thunk_p = false;
1771 cgraph_node_remove_callees (node);
1772 cgraph_add_new_function (thunk_fndecl, true);
1773 bitmap_obstack_release (NULL);
1775 current_function_decl = NULL;
1780 /* Assemble thunks and aliases asociated to NODE. */
1783 assemble_thunks_and_aliases (struct cgraph_node *node)
1785 struct cgraph_edge *e;
1787 struct ipa_ref *ref;
1789 for (e = node->callers; e;)
1790 if (e->caller->thunk.thunk_p)
1792 struct cgraph_node *thunk = e->caller;
1795 assemble_thunks_and_aliases (thunk);
1796 assemble_thunk (thunk);
1800 for (i = 0; ipa_ref_list_refering_iterate (&node->ref_list, i, ref); i++)
1801 if (ref->use == IPA_REF_ALIAS)
1803 struct cgraph_node *alias = ipa_ref_refering_node (ref);
1804 bool saved_written = TREE_ASM_WRITTEN (alias->thunk.alias);
1806 /* Force assemble_alias to really output the alias this time instead
1807 of buffering it in same alias pairs. */
1808 TREE_ASM_WRITTEN (alias->thunk.alias) = 1;
1809 assemble_alias (alias->decl,
1810 DECL_ASSEMBLER_NAME (alias->thunk.alias));
1811 assemble_thunks_and_aliases (alias);
1812 TREE_ASM_WRITTEN (alias->thunk.alias) = saved_written;
1816 /* Expand function specified by NODE. */
1819 cgraph_expand_function (struct cgraph_node *node)
1821 tree decl = node->decl;
1823 /* We ought to not compile any inline clones. */
1824 gcc_assert (!node->global.inlined_to);
1826 announce_function (decl);
1828 gcc_assert (node->lowered);
1830 /* Generate RTL for the body of DECL. */
1831 tree_rest_of_compilation (decl);
1833 /* Make sure that BE didn't give up on compiling. */
1834 gcc_assert (TREE_ASM_WRITTEN (decl));
1835 current_function_decl = NULL;
1836 gcc_assert (!cgraph_preserve_function_body_p (node));
1838 /* It would make a lot more sense to output thunks before function body to get more
1839 forward and lest backwarding jumps. This is however would need solving problem
1840 with comdats. See PR48668. Also aliases must come after function itself to
1841 make one pass assemblers, like one on AIX happy. See PR 50689.
1842 FIXME: Perhaps thunks should be move before function IFF they are not in comdat
1844 assemble_thunks_and_aliases (node);
1845 cgraph_release_function_body (node);
1846 /* Eliminate all call edges. This is important so the GIMPLE_CALL no longer
1847 points to the dead function body. */
1848 cgraph_node_remove_callees (node);
1850 cgraph_function_flags_ready = true;
1853 /* Return true when CALLER_DECL should be inlined into CALLEE_DECL. */
1856 cgraph_inline_p (struct cgraph_edge *e, cgraph_inline_failed_t *reason)
1858 *reason = e->inline_failed;
1859 return !e->inline_failed;
1864 /* Expand all functions that must be output.
1866 Attempt to topologically sort the nodes so function is output when
1867 all called functions are already assembled to allow data to be
1868 propagated across the callgraph. Use a stack to get smaller distance
1869 between a function and its callees (later we may choose to use a more
1870 sophisticated algorithm for function reordering; we will likely want
1871 to use subsections to make the output functions appear in top-down
1875 cgraph_expand_all_functions (void)
1877 struct cgraph_node *node;
1878 struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
1879 int order_pos, new_order_pos = 0;
1882 order_pos = ipa_reverse_postorder (order);
1883 gcc_assert (order_pos == cgraph_n_nodes);
1885 /* Garbage collector may remove inline clones we eliminate during
1886 optimization. So we must be sure to not reference them. */
1887 for (i = 0; i < order_pos; i++)
1888 if (order[i]->process)
1889 order[new_order_pos++] = order[i];
1891 for (i = new_order_pos - 1; i >= 0; i--)
1896 gcc_assert (node->reachable);
1898 cgraph_expand_function (node);
1901 cgraph_process_new_functions ();
1907 /* This is used to sort the node types by the cgraph order number. */
1909 enum cgraph_order_sort_kind
1911 ORDER_UNDEFINED = 0,
1917 struct cgraph_order_sort
1919 enum cgraph_order_sort_kind kind;
1922 struct cgraph_node *f;
1923 struct varpool_node *v;
1924 struct cgraph_asm_node *a;
1928 /* Output all functions, variables, and asm statements in the order
1929 according to their order fields, which is the order in which they
1930 appeared in the file. This implements -fno-toplevel-reorder. In
1931 this mode we may output functions and variables which don't really
1932 need to be output. */
1935 cgraph_output_in_order (void)
1938 struct cgraph_order_sort *nodes;
1940 struct cgraph_node *pf;
1941 struct varpool_node *pv;
1942 struct cgraph_asm_node *pa;
1945 nodes = XCNEWVEC (struct cgraph_order_sort, max);
1947 varpool_analyze_pending_decls ();
1949 for (pf = cgraph_nodes; pf; pf = pf->next)
1951 if (pf->process && !pf->thunk.thunk_p && !pf->alias)
1954 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1955 nodes[i].kind = ORDER_FUNCTION;
1960 for (pv = varpool_nodes_queue; pv; pv = pv->next_needed)
1963 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1964 nodes[i].kind = ORDER_VAR;
1968 for (pa = cgraph_asm_nodes; pa; pa = pa->next)
1971 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1972 nodes[i].kind = ORDER_ASM;
1976 /* In toplevel reorder mode we output all statics; mark them as needed. */
1977 for (i = 0; i < max; ++i)
1979 if (nodes[i].kind == ORDER_VAR)
1981 varpool_mark_needed_node (nodes[i].u.v);
1984 varpool_empty_needed_queue ();
1986 for (i = 0; i < max; ++i)
1987 if (nodes[i].kind == ORDER_VAR)
1988 varpool_finalize_named_section_flags (nodes[i].u.v);
1990 for (i = 0; i < max; ++i)
1992 switch (nodes[i].kind)
1994 case ORDER_FUNCTION:
1995 nodes[i].u.f->process = 0;
1996 cgraph_expand_function (nodes[i].u.f);
2000 varpool_assemble_decl (nodes[i].u.v);
2004 assemble_asm (nodes[i].u.a->asm_str);
2007 case ORDER_UNDEFINED:
2015 cgraph_asm_nodes = NULL;
2019 /* Return true when function body of DECL still needs to be kept around
2020 for later re-use. */
2022 cgraph_preserve_function_body_p (struct cgraph_node *node)
2024 gcc_assert (cgraph_global_info_ready);
2025 gcc_assert (!node->alias && !node->thunk.thunk_p);
2027 /* Look if there is any clone around. */
2037 current_function_decl = NULL;
2038 gimple_register_cfg_hooks ();
2039 bitmap_obstack_initialize (NULL);
2041 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START, NULL);
2045 execute_ipa_pass_list (all_small_ipa_passes);
2050 /* We never run removal of unreachable nodes after early passes. This is
2051 because TODO is run before the subpasses. It is important to remove
2052 the unreachable functions to save works at IPA level and to get LTO
2053 symbol tables right. */
2054 cgraph_remove_unreachable_nodes (true, cgraph_dump_file);
2056 /* If pass_all_early_optimizations was not scheduled, the state of
2057 the cgraph will not be properly updated. Update it now. */
2058 if (cgraph_state < CGRAPH_STATE_IPA_SSA)
2059 cgraph_state = CGRAPH_STATE_IPA_SSA;
2063 /* Generate coverage variables and constructors. */
2066 /* Process new functions added. */
2068 current_function_decl = NULL;
2069 cgraph_process_new_functions ();
2071 execute_ipa_summary_passes
2072 ((struct ipa_opt_pass_d *) all_regular_ipa_passes);
2075 /* Some targets need to handle LTO assembler output specially. */
2076 if (flag_generate_lto)
2077 targetm.asm_out.lto_start ();
2079 execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_lto_gen_passes);
2082 ipa_write_summaries ();
2084 if (flag_generate_lto)
2085 targetm.asm_out.lto_end ();
2087 if (!flag_ltrans && (in_lto_p || !flag_lto || flag_fat_lto_objects))
2088 execute_ipa_pass_list (all_regular_ipa_passes);
2089 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END, NULL);
2091 bitmap_obstack_release (NULL);
2095 /* Return string alias is alias of. */
2098 get_alias_symbol (tree decl)
2100 tree alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
2101 return get_identifier (TREE_STRING_POINTER
2102 (TREE_VALUE (TREE_VALUE (alias))));
2106 /* Weakrefs may be associated to external decls and thus not output
2107 at expansion time. Emit all neccesary aliases. */
2110 output_weakrefs (void)
2112 struct cgraph_node *node;
2113 struct varpool_node *vnode;
2114 for (node = cgraph_nodes; node; node = node->next)
2115 if (node->alias && DECL_EXTERNAL (node->decl)
2116 && !TREE_ASM_WRITTEN (node->decl)
2117 && lookup_attribute ("weakref", DECL_ATTRIBUTES (node->decl)))
2118 assemble_alias (node->decl,
2119 node->thunk.alias ? DECL_ASSEMBLER_NAME (node->thunk.alias)
2120 : get_alias_symbol (node->decl));
2121 for (vnode = varpool_nodes; vnode; vnode = vnode->next)
2122 if (vnode->alias && DECL_EXTERNAL (vnode->decl)
2123 && !TREE_ASM_WRITTEN (vnode->decl)
2124 && lookup_attribute ("weakref", DECL_ATTRIBUTES (vnode->decl)))
2125 assemble_alias (vnode->decl,
2126 vnode->alias_of ? DECL_ASSEMBLER_NAME (vnode->alias_of)
2127 : get_alias_symbol (vnode->decl));
2131 /* Perform simple optimizations based on callgraph. */
2134 cgraph_optimize (void)
2139 #ifdef ENABLE_CHECKING
2143 /* Frontend may output common variables after the unit has been finalized.
2144 It is safe to deal with them here as they are always zero initialized. */
2145 varpool_analyze_pending_decls ();
2147 timevar_push (TV_CGRAPHOPT);
2148 if (pre_ipa_mem_report)
2150 fprintf (stderr, "Memory consumption before IPA\n");
2151 dump_memory_report (false);
2154 fprintf (stderr, "Performing interprocedural optimizations\n");
2155 cgraph_state = CGRAPH_STATE_IPA;
2157 /* Don't run the IPA passes if there was any error or sorry messages. */
2161 /* Do nothing else if any IPA pass found errors or if we are just streaming LTO. */
2163 || (!in_lto_p && flag_lto && !flag_fat_lto_objects))
2165 timevar_pop (TV_CGRAPHOPT);
2169 /* This pass remove bodies of extern inline functions we never inlined.
2170 Do this later so other IPA passes see what is really going on. */
2171 cgraph_remove_unreachable_nodes (false, dump_file);
2172 cgraph_global_info_ready = true;
2173 if (cgraph_dump_file)
2175 fprintf (cgraph_dump_file, "Optimized ");
2176 dump_cgraph (cgraph_dump_file);
2177 dump_varpool (cgraph_dump_file);
2179 if (post_ipa_mem_report)
2181 fprintf (stderr, "Memory consumption after IPA\n");
2182 dump_memory_report (false);
2184 timevar_pop (TV_CGRAPHOPT);
2186 /* Output everything. */
2187 (*debug_hooks->assembly_start) ();
2189 fprintf (stderr, "Assembling functions:\n");
2190 #ifdef ENABLE_CHECKING
2194 cgraph_materialize_all_clones ();
2195 bitmap_obstack_initialize (NULL);
2196 execute_ipa_pass_list (all_late_ipa_passes);
2197 cgraph_remove_unreachable_nodes (true, dump_file);
2198 #ifdef ENABLE_CHECKING
2201 bitmap_obstack_release (NULL);
2202 cgraph_mark_functions_to_output ();
2205 cgraph_state = CGRAPH_STATE_EXPANSION;
2206 if (!flag_toplevel_reorder)
2207 cgraph_output_in_order ();
2210 cgraph_output_pending_asms ();
2212 cgraph_expand_all_functions ();
2213 varpool_remove_unreferenced_decls ();
2215 varpool_assemble_pending_decls ();
2218 cgraph_process_new_functions ();
2219 cgraph_state = CGRAPH_STATE_FINISHED;
2221 if (cgraph_dump_file)
2223 fprintf (cgraph_dump_file, "\nFinal ");
2224 dump_cgraph (cgraph_dump_file);
2225 dump_varpool (cgraph_dump_file);
2227 #ifdef ENABLE_CHECKING
2229 /* Double check that all inline clones are gone and that all
2230 function bodies have been released from memory. */
2233 struct cgraph_node *node;
2234 bool error_found = false;
2236 for (node = cgraph_nodes; node; node = node->next)
2238 && (node->global.inlined_to
2239 || gimple_has_body_p (node->decl)))
2242 dump_cgraph_node (stderr, node);
2245 internal_error ("nodes with unreleased memory found");
2253 if (!cgraph_dump_file)
2254 cgraph_dump_file = dump_begin (TDI_cgraph, NULL);
2257 /* The edges representing the callers of the NEW_VERSION node were
2258 fixed by cgraph_function_versioning (), now the call_expr in their
2259 respective tree code should be updated to call the NEW_VERSION. */
2262 update_call_expr (struct cgraph_node *new_version)
2264 struct cgraph_edge *e;
2266 gcc_assert (new_version);
2268 /* Update the call expr on the edges to call the new version. */
2269 for (e = new_version->callers; e; e = e->next_caller)
2271 struct function *inner_function = DECL_STRUCT_FUNCTION (e->caller->decl);
2272 gimple_call_set_fndecl (e->call_stmt, new_version->decl);
2273 maybe_clean_eh_stmt_fn (inner_function, e->call_stmt);
2278 /* Create a new cgraph node which is the new version of
2279 OLD_VERSION node. REDIRECT_CALLERS holds the callers
2280 edges which should be redirected to point to
2281 NEW_VERSION. ALL the callees edges of OLD_VERSION
2282 are cloned to the new version node. Return the new
2285 If non-NULL BLOCK_TO_COPY determine what basic blocks
2286 was copied to prevent duplications of calls that are dead
2289 struct cgraph_node *
2290 cgraph_copy_node_for_versioning (struct cgraph_node *old_version,
2292 VEC(cgraph_edge_p,heap) *redirect_callers,
2295 struct cgraph_node *new_version;
2296 struct cgraph_edge *e;
2299 gcc_assert (old_version);
2301 new_version = cgraph_create_node (new_decl);
2303 new_version->analyzed = old_version->analyzed;
2304 new_version->local = old_version->local;
2305 new_version->local.externally_visible = false;
2306 new_version->local.local = true;
2307 new_version->global = old_version->global;
2308 new_version->rtl = old_version->rtl;
2309 new_version->reachable = true;
2310 new_version->count = old_version->count;
2312 for (e = old_version->callees; e; e=e->next_callee)
2314 || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
2315 cgraph_clone_edge (e, new_version, e->call_stmt,
2316 e->lto_stmt_uid, REG_BR_PROB_BASE,
2319 for (e = old_version->indirect_calls; e; e=e->next_callee)
2321 || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
2322 cgraph_clone_edge (e, new_version, e->call_stmt,
2323 e->lto_stmt_uid, REG_BR_PROB_BASE,
2326 FOR_EACH_VEC_ELT (cgraph_edge_p, redirect_callers, i, e)
2328 /* Redirect calls to the old version node to point to its new
2330 cgraph_redirect_edge_callee (e, new_version);
2333 cgraph_call_node_duplication_hooks (old_version, new_version);
2338 /* Perform function versioning.
2339 Function versioning includes copying of the tree and
2340 a callgraph update (creating a new cgraph node and updating
2341 its callees and callers).
2343 REDIRECT_CALLERS varray includes the edges to be redirected
2346 TREE_MAP is a mapping of tree nodes we want to replace with
2347 new ones (according to results of prior analysis).
2348 OLD_VERSION_NODE is the node that is versioned.
2350 If non-NULL ARGS_TO_SKIP determine function parameters to remove
2352 If SKIP_RETURN is true, the new version will return void.
2353 If non-NULL BLOCK_TO_COPY determine what basic blocks to copy.
2354 If non_NULL NEW_ENTRY determine new entry BB of the clone.
2356 Return the new version's cgraph node. */
2358 struct cgraph_node *
2359 cgraph_function_versioning (struct cgraph_node *old_version_node,
2360 VEC(cgraph_edge_p,heap) *redirect_callers,
2361 VEC (ipa_replace_map_p,gc)* tree_map,
2362 bitmap args_to_skip,
2365 basic_block new_entry_block,
2366 const char *clone_name)
2368 tree old_decl = old_version_node->decl;
2369 struct cgraph_node *new_version_node = NULL;
2372 if (!tree_versionable_function_p (old_decl))
2375 gcc_assert (old_version_node->local.can_change_signature || !args_to_skip);
2377 /* Make a new FUNCTION_DECL tree node for the new version. */
2378 if (!args_to_skip && !skip_return)
2379 new_decl = copy_node (old_decl);
2382 = build_function_decl_skip_args (old_decl, args_to_skip, skip_return);
2384 /* Generate a new name for the new version. */
2385 DECL_NAME (new_decl) = clone_function_name (old_decl, clone_name);
2386 SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
2387 SET_DECL_RTL (new_decl, NULL);
2389 /* When the old decl was a con-/destructor make sure the clone isn't. */
2390 DECL_STATIC_CONSTRUCTOR(new_decl) = 0;
2391 DECL_STATIC_DESTRUCTOR(new_decl) = 0;
2393 /* Create the new version's call-graph node.
2394 and update the edges of the new node. */
2396 cgraph_copy_node_for_versioning (old_version_node, new_decl,
2397 redirect_callers, bbs_to_copy);
2399 /* Copy the OLD_VERSION_NODE function tree to the new version. */
2400 tree_function_versioning (old_decl, new_decl, tree_map, false, args_to_skip,
2401 skip_return, bbs_to_copy, new_entry_block);
2403 /* Update the new version's properties.
2404 Make The new version visible only within this translation unit. Make sure
2405 that is not weak also.
2406 ??? We cannot use COMDAT linkage because there is no
2407 ABI support for this. */
2408 cgraph_make_decl_local (new_version_node->decl);
2409 DECL_VIRTUAL_P (new_version_node->decl) = 0;
2410 new_version_node->local.externally_visible = 0;
2411 new_version_node->local.local = 1;
2412 new_version_node->lowered = true;
2414 /* Update the call_expr on the edges to call the new version node. */
2415 update_call_expr (new_version_node);
2417 cgraph_call_function_insertion_hooks (new_version_node);
2418 return new_version_node;
2421 /* Given virtual clone, turn it into actual clone. */
2423 cgraph_materialize_clone (struct cgraph_node *node)
2425 bitmap_obstack_initialize (NULL);
2426 node->former_clone_of = node->clone_of->decl;
2427 if (node->clone_of->former_clone_of)
2428 node->former_clone_of = node->clone_of->former_clone_of;
2429 /* Copy the OLD_VERSION_NODE function tree to the new version. */
2430 tree_function_versioning (node->clone_of->decl, node->decl,
2431 node->clone.tree_map, true,
2432 node->clone.args_to_skip, false,
2434 if (cgraph_dump_file)
2436 dump_function_to_file (node->clone_of->decl, cgraph_dump_file, dump_flags);
2437 dump_function_to_file (node->decl, cgraph_dump_file, dump_flags);
2440 /* Function is no longer clone. */
2441 if (node->next_sibling_clone)
2442 node->next_sibling_clone->prev_sibling_clone = node->prev_sibling_clone;
2443 if (node->prev_sibling_clone)
2444 node->prev_sibling_clone->next_sibling_clone = node->next_sibling_clone;
2446 node->clone_of->clones = node->next_sibling_clone;
2447 node->next_sibling_clone = NULL;
2448 node->prev_sibling_clone = NULL;
2449 if (!node->clone_of->analyzed && !node->clone_of->clones)
2451 cgraph_release_function_body (node->clone_of);
2452 cgraph_node_remove_callees (node->clone_of);
2453 ipa_remove_all_references (&node->clone_of->ref_list);
2455 node->clone_of = NULL;
2456 bitmap_obstack_release (NULL);
2459 /* If necessary, change the function declaration in the call statement
2460 associated with E so that it corresponds to the edge callee. */
2463 cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *e)
2465 tree decl = gimple_call_fndecl (e->call_stmt);
2467 gimple_stmt_iterator gsi;
2468 #ifdef ENABLE_CHECKING
2469 struct cgraph_node *node;
2472 if (e->indirect_unknown_callee
2473 || decl == e->callee->decl)
2474 return e->call_stmt;
2476 #ifdef ENABLE_CHECKING
2479 node = cgraph_get_node (decl);
2480 gcc_assert (!node || !node->clone.combined_args_to_skip);
2484 if (cgraph_dump_file)
2486 fprintf (cgraph_dump_file, "updating call of %s/%i -> %s/%i: ",
2487 cgraph_node_name (e->caller), e->caller->uid,
2488 cgraph_node_name (e->callee), e->callee->uid);
2489 print_gimple_stmt (cgraph_dump_file, e->call_stmt, 0, dump_flags);
2490 if (e->callee->clone.combined_args_to_skip)
2492 fprintf (cgraph_dump_file, " combined args to skip: ");
2493 dump_bitmap (cgraph_dump_file,
2494 e->callee->clone.combined_args_to_skip);
2498 if (e->callee->clone.combined_args_to_skip)
2503 = gimple_call_copy_skip_args (e->call_stmt,
2504 e->callee->clone.combined_args_to_skip);
2505 gimple_call_set_fndecl (new_stmt, e->callee->decl);
2507 if (gimple_vdef (new_stmt)
2508 && TREE_CODE (gimple_vdef (new_stmt)) == SSA_NAME)
2509 SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt;
2511 gsi = gsi_for_stmt (e->call_stmt);
2512 gsi_replace (&gsi, new_stmt, false);
2513 /* We need to defer cleaning EH info on the new statement to
2514 fixup-cfg. We may not have dominator information at this point
2515 and thus would end up with unreachable blocks and have no way
2516 to communicate that we need to run CFG cleanup then. */
2517 lp_nr = lookup_stmt_eh_lp (e->call_stmt);
2520 remove_stmt_from_eh_lp (e->call_stmt);
2521 add_stmt_to_eh_lp (new_stmt, lp_nr);
2526 new_stmt = e->call_stmt;
2527 gimple_call_set_fndecl (new_stmt, e->callee->decl);
2528 update_stmt (new_stmt);
2531 cgraph_set_call_stmt_including_clones (e->caller, e->call_stmt, new_stmt);
2533 if (cgraph_dump_file)
2535 fprintf (cgraph_dump_file, " updated to:");
2536 print_gimple_stmt (cgraph_dump_file, e->call_stmt, 0, dump_flags);
2541 /* Once all functions from compilation unit are in memory, produce all clones
2542 and update all calls. We might also do this on demand if we don't want to
2543 bring all functions to memory prior compilation, but current WHOPR
2544 implementation does that and it is is bit easier to keep everything right in
2547 cgraph_materialize_all_clones (void)
2549 struct cgraph_node *node;
2550 bool stabilized = false;
2552 if (cgraph_dump_file)
2553 fprintf (cgraph_dump_file, "Materializing clones\n");
2554 #ifdef ENABLE_CHECKING
2558 /* We can also do topological order, but number of iterations should be
2559 bounded by number of IPA passes since single IPA pass is probably not
2560 going to create clones of clones it created itself. */
2564 for (node = cgraph_nodes; node; node = node->next)
2566 if (node->clone_of && node->decl != node->clone_of->decl
2567 && !gimple_has_body_p (node->decl))
2569 if (gimple_has_body_p (node->clone_of->decl))
2571 if (cgraph_dump_file)
2573 fprintf (cgraph_dump_file, "cloning %s to %s\n",
2574 cgraph_node_name (node->clone_of),
2575 cgraph_node_name (node));
2576 if (node->clone.tree_map)
2579 fprintf (cgraph_dump_file, " replace map: ");
2580 for (i = 0; i < VEC_length (ipa_replace_map_p,
2581 node->clone.tree_map);
2584 struct ipa_replace_map *replace_info;
2585 replace_info = VEC_index (ipa_replace_map_p,
2586 node->clone.tree_map,
2588 print_generic_expr (cgraph_dump_file, replace_info->old_tree, 0);
2589 fprintf (cgraph_dump_file, " -> ");
2590 print_generic_expr (cgraph_dump_file, replace_info->new_tree, 0);
2591 fprintf (cgraph_dump_file, "%s%s;",
2592 replace_info->replace_p ? "(replace)":"",
2593 replace_info->ref_p ? "(ref)":"");
2595 fprintf (cgraph_dump_file, "\n");
2597 if (node->clone.args_to_skip)
2599 fprintf (cgraph_dump_file, " args_to_skip: ");
2600 dump_bitmap (cgraph_dump_file, node->clone.args_to_skip);
2602 if (node->clone.args_to_skip)
2604 fprintf (cgraph_dump_file, " combined_args_to_skip:");
2605 dump_bitmap (cgraph_dump_file, node->clone.combined_args_to_skip);
2608 cgraph_materialize_clone (node);
2614 for (node = cgraph_nodes; node; node = node->next)
2615 if (!node->analyzed && node->callees)
2616 cgraph_node_remove_callees (node);
2617 if (cgraph_dump_file)
2618 fprintf (cgraph_dump_file, "Materialization Call site updates done.\n");
2619 #ifdef ENABLE_CHECKING
2622 cgraph_remove_unreachable_nodes (false, cgraph_dump_file);
2625 #include "gt-cgraphunit.h"