Merged with trunk at revision 162480.
[official-gcc.git] / gcc / cgraphunit.c
blobe306b226115fd916cbe9260abb97b5d2d98c4afc
1 /* Callgraph based interprocedural optimizations.
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
3 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
11 version.
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
16 for more details.
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
36 function.)
38 - varpool_finalize_variable
40 This function has same behavior as the above but is used for static
41 variables.
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 the call-graph construction and local function
49 analysis takes place here. Bodies of unreachable functions are released
50 to 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)
55 - cgraph_optimize
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. */
109 #include "config.h"
110 #include "system.h"
111 #include "coretypes.h"
112 #include "tm.h"
113 #include "tree.h"
114 #include "rtl.h"
115 #include "tree-flow.h"
116 #include "tree-inline.h"
117 #include "langhooks.h"
118 #include "pointer-set.h"
119 #include "toplev.h"
120 #include "flags.h"
121 #include "ggc.h"
122 #include "debug.h"
123 #include "target.h"
124 #include "cgraph.h"
125 #include "diagnostic.h"
126 #include "tree-pretty-print.h"
127 #include "gimple-pretty-print.h"
128 #include "timevar.h"
129 #include "params.h"
130 #include "fibheap.h"
131 #include "intl.h"
132 #include "function.h"
133 #include "ipa-prop.h"
134 #include "gimple.h"
135 #include "tree-iterator.h"
136 #include "tree-pass.h"
137 #include "tree-dump.h"
138 #include "output.h"
139 #include "coverage.h"
140 #include "plugin.h"
142 static void cgraph_expand_all_functions (void);
143 static void cgraph_mark_functions_to_output (void);
144 static void cgraph_expand_function (struct cgraph_node *);
145 static void cgraph_output_pending_asms (void);
146 static void cgraph_analyze_function (struct cgraph_node *);
148 FILE *cgraph_dump_file;
150 /* A vector of FUNCTION_DECLs declared as static constructors. */
151 static GTY (()) VEC(tree, gc) *static_ctors;
152 /* A vector of FUNCTION_DECLs declared as static destructors. */
153 static GTY (()) VEC(tree, gc) *static_dtors;
155 /* Used for vtable lookup in thunk adjusting. */
156 static GTY (()) tree vtable_entry_type;
158 /* When target does not have ctors and dtors, we call all constructor
159 and destructor by special initialization/destruction function
160 recognized by collect2.
162 When we are going to build this function, collect all constructors and
163 destructors and turn them into normal functions. */
165 static void
166 record_cdtor_fn (tree fndecl)
168 struct cgraph_node *node;
169 if (targetm.have_ctors_dtors
170 || (!DECL_STATIC_CONSTRUCTOR (fndecl)
171 && !DECL_STATIC_DESTRUCTOR (fndecl)))
172 return;
174 if (DECL_STATIC_CONSTRUCTOR (fndecl))
176 VEC_safe_push (tree, gc, static_ctors, fndecl);
177 DECL_STATIC_CONSTRUCTOR (fndecl) = 0;
179 if (DECL_STATIC_DESTRUCTOR (fndecl))
181 VEC_safe_push (tree, gc, static_dtors, fndecl);
182 DECL_STATIC_DESTRUCTOR (fndecl) = 0;
184 node = cgraph_node (fndecl);
185 node->local.disregard_inline_limits = 1;
186 cgraph_mark_reachable_node (node);
189 /* Define global constructors/destructor functions for the CDTORS, of
190 which they are LEN. The CDTORS are sorted by initialization
191 priority. If CTOR_P is true, these are constructors; otherwise,
192 they are destructors. */
194 static void
195 build_cdtor (bool ctor_p, tree *cdtors, size_t len)
197 size_t i;
199 i = 0;
200 while (i < len)
202 tree body;
203 tree fn;
204 priority_type priority;
206 priority = 0;
207 body = NULL_TREE;
208 /* Find the next batch of constructors/destructors with the same
209 initialization priority. */
212 priority_type p;
213 tree call;
214 fn = cdtors[i];
215 p = ctor_p ? DECL_INIT_PRIORITY (fn) : DECL_FINI_PRIORITY (fn);
216 if (!body)
217 priority = p;
218 else if (p != priority)
219 break;
220 call = build_call_expr (fn, 0);
221 append_to_statement_list (call, &body);
222 ++i;
224 while (i < len);
225 gcc_assert (body != NULL_TREE);
226 /* Generate a function to call all the function of like
227 priority. */
228 cgraph_build_static_cdtor (ctor_p ? 'I' : 'D', body, priority);
232 /* Comparison function for qsort. P1 and P2 are actually of type
233 "tree *" and point to static constructors. DECL_INIT_PRIORITY is
234 used to determine the sort order. */
236 static int
237 compare_ctor (const void *p1, const void *p2)
239 tree f1;
240 tree f2;
241 int priority1;
242 int priority2;
244 f1 = *(const tree *)p1;
245 f2 = *(const tree *)p2;
246 priority1 = DECL_INIT_PRIORITY (f1);
247 priority2 = DECL_INIT_PRIORITY (f2);
249 if (priority1 < priority2)
250 return -1;
251 else if (priority1 > priority2)
252 return 1;
253 else
254 /* Ensure a stable sort. */
255 return (const tree *)p1 - (const tree *)p2;
258 /* Comparison function for qsort. P1 and P2 are actually of type
259 "tree *" and point to static destructors. DECL_FINI_PRIORITY is
260 used to determine the sort order. */
262 static int
263 compare_dtor (const void *p1, const void *p2)
265 tree f1;
266 tree f2;
267 int priority1;
268 int priority2;
270 f1 = *(const tree *)p1;
271 f2 = *(const tree *)p2;
272 priority1 = DECL_FINI_PRIORITY (f1);
273 priority2 = DECL_FINI_PRIORITY (f2);
275 if (priority1 < priority2)
276 return -1;
277 else if (priority1 > priority2)
278 return 1;
279 else
280 /* Ensure a stable sort. */
281 return (const tree *)p1 - (const tree *)p2;
284 /* Generate functions to call static constructors and destructors
285 for targets that do not support .ctors/.dtors sections. These
286 functions have magic names which are detected by collect2. */
288 static void
289 cgraph_build_cdtor_fns (void)
291 if (!VEC_empty (tree, static_ctors))
293 gcc_assert (!targetm.have_ctors_dtors);
294 qsort (VEC_address (tree, static_ctors),
295 VEC_length (tree, static_ctors),
296 sizeof (tree),
297 compare_ctor);
298 build_cdtor (/*ctor_p=*/true,
299 VEC_address (tree, static_ctors),
300 VEC_length (tree, static_ctors));
301 VEC_truncate (tree, static_ctors, 0);
304 if (!VEC_empty (tree, static_dtors))
306 gcc_assert (!targetm.have_ctors_dtors);
307 qsort (VEC_address (tree, static_dtors),
308 VEC_length (tree, static_dtors),
309 sizeof (tree),
310 compare_dtor);
311 build_cdtor (/*ctor_p=*/false,
312 VEC_address (tree, static_dtors),
313 VEC_length (tree, static_dtors));
314 VEC_truncate (tree, static_dtors, 0);
318 /* Determine if function DECL is needed. That is, visible to something
319 either outside this translation unit, something magic in the system
320 configury. */
322 bool
323 cgraph_decide_is_function_needed (struct cgraph_node *node, tree decl)
325 /* If the user told us it is used, then it must be so. */
326 if (node->local.externally_visible)
327 return true;
329 /* ??? If the assembler name is set by hand, it is possible to assemble
330 the name later after finalizing the function and the fact is noticed
331 in assemble_name then. This is arguably a bug. */
332 if (DECL_ASSEMBLER_NAME_SET_P (decl)
333 && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
334 return true;
336 /* With -fkeep-inline-functions we are keeping all inline functions except
337 for extern inline ones. */
338 if (flag_keep_inline_functions
339 && DECL_DECLARED_INLINE_P (decl)
340 && !DECL_EXTERNAL (decl)
341 && !lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl)))
342 return true;
344 /* If we decided it was needed before, but at the time we didn't have
345 the body of the function available, then it's still needed. We have
346 to go back and re-check its dependencies now. */
347 if (node->needed)
348 return true;
350 /* Externally visible functions must be output. The exception is
351 COMDAT functions that must be output only when they are needed.
353 When not optimizing, also output the static functions. (see
354 PR24561), but don't do so for always_inline functions, functions
355 declared inline and nested functions. These were optimized out
356 in the original implementation and it is unclear whether we want
357 to change the behavior here. */
358 if (((TREE_PUBLIC (decl)
359 || (!optimize
360 && !node->local.disregard_inline_limits
361 && !DECL_DECLARED_INLINE_P (decl)
362 && !(DECL_CONTEXT (decl)
363 && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL)))
364 && !flag_whole_program
365 && !flag_lto
366 && !flag_whopr)
367 && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
368 return true;
370 /* Constructors and destructors are reachable from the runtime by
371 some mechanism. */
372 if (DECL_STATIC_CONSTRUCTOR (decl) || DECL_STATIC_DESTRUCTOR (decl))
373 return true;
375 return false;
378 /* Process CGRAPH_NEW_FUNCTIONS and perform actions necessary to add these
379 functions into callgraph in a way so they look like ordinary reachable
380 functions inserted into callgraph already at construction time. */
382 bool
383 cgraph_process_new_functions (void)
385 bool output = false;
386 tree fndecl;
387 struct cgraph_node *node;
389 varpool_analyze_pending_decls ();
390 /* Note that this queue may grow as its being processed, as the new
391 functions may generate new ones. */
392 while (cgraph_new_nodes)
394 node = cgraph_new_nodes;
395 fndecl = node->decl;
396 cgraph_new_nodes = cgraph_new_nodes->next_needed;
397 switch (cgraph_state)
399 case CGRAPH_STATE_CONSTRUCTION:
400 /* At construction time we just need to finalize function and move
401 it into reachable functions list. */
403 node->next_needed = NULL;
404 cgraph_finalize_function (fndecl, false);
405 cgraph_mark_reachable_node (node);
406 output = true;
407 break;
409 case CGRAPH_STATE_IPA:
410 case CGRAPH_STATE_IPA_SSA:
411 /* When IPA optimization already started, do all essential
412 transformations that has been already performed on the whole
413 cgraph but not on this function. */
415 gimple_register_cfg_hooks ();
416 if (!node->analyzed)
417 cgraph_analyze_function (node);
418 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
419 current_function_decl = fndecl;
420 compute_inline_parameters (node);
421 if ((cgraph_state == CGRAPH_STATE_IPA_SSA
422 && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
423 /* When not optimizing, be sure we run early local passes anyway
424 to expand OMP. */
425 || !optimize)
426 execute_pass_list (pass_early_local_passes.pass.sub);
427 free_dominance_info (CDI_POST_DOMINATORS);
428 free_dominance_info (CDI_DOMINATORS);
429 pop_cfun ();
430 current_function_decl = NULL;
431 break;
433 case CGRAPH_STATE_EXPANSION:
434 /* Functions created during expansion shall be compiled
435 directly. */
436 node->process = 0;
437 cgraph_expand_function (node);
438 break;
440 default:
441 gcc_unreachable ();
442 break;
444 cgraph_call_function_insertion_hooks (node);
445 varpool_analyze_pending_decls ();
447 return output;
450 /* As an GCC extension we allow redefinition of the function. The
451 semantics when both copies of bodies differ is not well defined.
452 We replace the old body with new body so in unit at a time mode
453 we always use new body, while in normal mode we may end up with
454 old body inlined into some functions and new body expanded and
455 inlined in others.
457 ??? It may make more sense to use one body for inlining and other
458 body for expanding the function but this is difficult to do. */
460 static void
461 cgraph_reset_node (struct cgraph_node *node)
463 /* If node->process is set, then we have already begun whole-unit analysis.
464 This is *not* testing for whether we've already emitted the function.
465 That case can be sort-of legitimately seen with real function redefinition
466 errors. I would argue that the front end should never present us with
467 such a case, but don't enforce that for now. */
468 gcc_assert (!node->process);
470 /* Reset our data structures so we can analyze the function again. */
471 memset (&node->local, 0, sizeof (node->local));
472 memset (&node->global, 0, sizeof (node->global));
473 memset (&node->rtl, 0, sizeof (node->rtl));
474 node->analyzed = false;
475 node->local.redefined_extern_inline = true;
476 node->local.finalized = false;
478 cgraph_node_remove_callees (node);
480 /* We may need to re-queue the node for assembling in case
481 we already proceeded it and ignored as not needed or got
482 a re-declaration in IMA mode. */
483 if (node->reachable)
485 struct cgraph_node *n;
487 for (n = cgraph_nodes_queue; n; n = n->next_needed)
488 if (n == node)
489 break;
490 if (!n)
491 node->reachable = 0;
495 static void
496 cgraph_lower_function (struct cgraph_node *node)
498 if (node->lowered)
499 return;
501 if (node->nested)
502 lower_nested_functions (node->decl);
503 gcc_assert (!node->nested);
505 tree_lowering_passes (node->decl);
506 node->lowered = true;
509 /* DECL has been parsed. Take it, queue it, compile it at the whim of the
510 logic in effect. If NESTED is true, then our caller cannot stand to have
511 the garbage collector run at the moment. We would need to either create
512 a new GC context, or just not compile right now. */
514 void
515 cgraph_finalize_function (tree decl, bool nested)
517 struct cgraph_node *node = cgraph_node (decl);
519 if (node->local.finalized)
520 cgraph_reset_node (node);
522 node->pid = cgraph_max_pid ++;
523 notice_global_symbol (decl);
524 node->local.finalized = true;
525 node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL;
526 node->finalized_by_frontend = true;
527 record_cdtor_fn (node->decl);
529 if (cgraph_decide_is_function_needed (node, decl))
530 cgraph_mark_needed_node (node);
532 /* Since we reclaim unreachable nodes at the end of every language
533 level unit, we need to be conservative about possible entry points
534 there. */
535 if ((TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl)))
536 cgraph_mark_reachable_node (node);
538 /* If we've not yet emitted decl, tell the debug info about it. */
539 if (!TREE_ASM_WRITTEN (decl))
540 (*debug_hooks->deferred_inline_function) (decl);
542 /* Parameters in IFUNC function should never be used. */
543 if (DECL_IS_IFUNC (decl))
545 tree parm;
547 for (parm = DECL_ARGUMENTS (decl);
548 parm; parm = TREE_CHAIN (parm))
550 if (TREE_USED (parm)
551 && TREE_CODE (parm) == PARM_DECL
552 && DECL_NAME (parm))
553 error ("parameter %q+D used in indirect function %q+F",
554 parm, decl);
558 /* Possibly warn about unused parameters. */
559 else if (warn_unused_parameter)
560 do_warn_unused_parameter (decl);
562 if (!nested)
563 ggc_collect ();
566 /* C99 extern inline keywords allow changing of declaration after function
567 has been finalized. We need to re-decide if we want to mark the function as
568 needed then. */
570 void
571 cgraph_mark_if_needed (tree decl)
573 struct cgraph_node *node = cgraph_node (decl);
574 if (node->local.finalized && cgraph_decide_is_function_needed (node, decl))
575 cgraph_mark_needed_node (node);
578 #ifdef ENABLE_CHECKING
579 /* Return TRUE if NODE2 is equivalent to NODE or its clone. */
580 static bool
581 clone_of_p (struct cgraph_node *node, struct cgraph_node *node2)
583 while (node != node2 && node2)
584 node2 = node2->clone_of;
585 return node2 != NULL;
587 #endif
589 /* Verify edge E count and frequency. */
591 static bool
592 verify_edge_count_and_frequency (struct cgraph_edge *e)
594 bool error_found = false;
595 if (e->count < 0)
597 error ("caller edge count is negative");
598 error_found = true;
600 if (e->frequency < 0)
602 error ("caller edge frequency is negative");
603 error_found = true;
605 if (e->frequency > CGRAPH_FREQ_MAX)
607 error ("caller edge frequency is too large");
608 error_found = true;
610 if (gimple_has_body_p (e->caller->decl)
611 && !e->caller->global.inlined_to
612 && (e->frequency
613 != compute_call_stmt_bb_frequency (e->caller->decl,
614 gimple_bb (e->call_stmt))))
616 error ("caller edge frequency %i does not match BB freqency %i",
617 e->frequency,
618 compute_call_stmt_bb_frequency (e->caller->decl,
619 gimple_bb (e->call_stmt)));
620 error_found = true;
622 return error_found;
625 /* Verify cgraph nodes of given cgraph node. */
626 DEBUG_FUNCTION void
627 verify_cgraph_node (struct cgraph_node *node)
629 struct cgraph_edge *e;
630 struct function *this_cfun = DECL_STRUCT_FUNCTION (node->decl);
631 struct function *saved_cfun = cfun;
632 basic_block this_block;
633 gimple_stmt_iterator gsi;
634 bool error_found = false;
636 if (seen_error ())
637 return;
639 timevar_push (TV_CGRAPH_VERIFY);
640 /* debug_generic_stmt needs correct cfun */
641 set_cfun (this_cfun);
642 for (e = node->callees; e; e = e->next_callee)
643 if (e->aux)
645 error ("aux field set for edge %s->%s",
646 identifier_to_locale (cgraph_node_name (e->caller)),
647 identifier_to_locale (cgraph_node_name (e->callee)));
648 error_found = true;
650 if (node->count < 0)
652 error ("Execution count is negative");
653 error_found = true;
655 if (node->global.inlined_to && node->local.externally_visible)
657 error ("Externally visible inline clone");
658 error_found = true;
660 if (node->global.inlined_to && node->address_taken)
662 error ("Inline clone with address taken");
663 error_found = true;
665 if (node->global.inlined_to && node->needed)
667 error ("Inline clone is needed");
668 error_found = true;
670 for (e = node->indirect_calls; e; e = e->next_callee)
672 if (e->aux)
674 error ("aux field set for indirect edge from %s",
675 identifier_to_locale (cgraph_node_name (e->caller)));
676 error_found = true;
678 if (!e->indirect_unknown_callee
679 || !e->indirect_info)
681 error ("An indirect edge from %s is not marked as indirect or has "
682 "associated indirect_info, the corresponding statement is: ",
683 identifier_to_locale (cgraph_node_name (e->caller)));
684 debug_gimple_stmt (e->call_stmt);
685 error_found = true;
688 for (e = node->callers; e; e = e->next_caller)
690 if (verify_edge_count_and_frequency (e))
691 error_found = true;
692 if (!e->inline_failed)
694 if (node->global.inlined_to
695 != (e->caller->global.inlined_to
696 ? e->caller->global.inlined_to : e->caller))
698 error ("inlined_to pointer is wrong");
699 error_found = true;
701 if (node->callers->next_caller)
703 error ("multiple inline callers");
704 error_found = true;
707 else
708 if (node->global.inlined_to)
710 error ("inlined_to pointer set for noninline callers");
711 error_found = true;
714 for (e = node->indirect_calls; e; e = e->next_callee)
715 if (verify_edge_count_and_frequency (e))
716 error_found = true;
717 if (!node->callers && node->global.inlined_to)
719 error ("inlined_to pointer is set but no predecessors found");
720 error_found = true;
722 if (node->global.inlined_to == node)
724 error ("inlined_to pointer refers to itself");
725 error_found = true;
728 if (!cgraph_node (node->decl))
730 error ("node not found in cgraph_hash");
731 error_found = true;
734 if (node->clone_of)
736 struct cgraph_node *n;
737 for (n = node->clone_of->clones; n; n = n->next_sibling_clone)
738 if (n == node)
739 break;
740 if (!n)
742 error ("node has wrong clone_of");
743 error_found = true;
746 if (node->clones)
748 struct cgraph_node *n;
749 for (n = node->clones; n; n = n->next_sibling_clone)
750 if (n->clone_of != node)
751 break;
752 if (n)
754 error ("node has wrong clone list");
755 error_found = true;
758 if ((node->prev_sibling_clone || node->next_sibling_clone) && !node->clone_of)
760 error ("node is in clone list but it is not clone");
761 error_found = true;
763 if (!node->prev_sibling_clone && node->clone_of && node->clone_of->clones != node)
765 error ("node has wrong prev_clone pointer");
766 error_found = true;
768 if (node->prev_sibling_clone && node->prev_sibling_clone->next_sibling_clone != node)
770 error ("double linked list of clones corrupted");
771 error_found = true;
773 if (node->same_comdat_group)
775 struct cgraph_node *n = node->same_comdat_group;
777 if (!DECL_ONE_ONLY (node->decl))
779 error ("non-DECL_ONE_ONLY node in a same_comdat_group list");
780 error_found = true;
782 if (n == node)
784 error ("node is alone in a comdat group");
785 error_found = true;
789 if (!n->same_comdat_group)
791 error ("same_comdat_group is not a circular list");
792 error_found = true;
793 break;
795 n = n->same_comdat_group;
797 while (n != node);
800 if (node->analyzed && gimple_has_body_p (node->decl)
801 && !TREE_ASM_WRITTEN (node->decl)
802 && (!DECL_EXTERNAL (node->decl) || node->global.inlined_to)
803 && !flag_wpa)
805 if (this_cfun->cfg)
807 /* The nodes we're interested in are never shared, so walk
808 the tree ignoring duplicates. */
809 struct pointer_set_t *visited_nodes = pointer_set_create ();
810 /* Reach the trees by walking over the CFG, and note the
811 enclosing basic-blocks in the call edges. */
812 FOR_EACH_BB_FN (this_block, this_cfun)
813 for (gsi = gsi_start_bb (this_block);
814 !gsi_end_p (gsi);
815 gsi_next (&gsi))
817 gimple stmt = gsi_stmt (gsi);
818 if (is_gimple_call (stmt))
820 struct cgraph_edge *e = cgraph_edge (node, stmt);
821 tree decl = gimple_call_fndecl (stmt);
822 if (e)
824 if (e->aux)
826 error ("shared call_stmt:");
827 debug_gimple_stmt (stmt);
828 error_found = true;
830 if (!e->indirect_unknown_callee)
832 if (e->callee->same_body_alias)
834 error ("edge points to same body alias:");
835 debug_tree (e->callee->decl);
836 error_found = true;
838 #ifdef ENABLE_CHECKING
839 else if (!e->callee->global.inlined_to
840 && decl
841 && cgraph_get_node (decl)
842 && (e->callee->former_clone_of
843 != cgraph_get_node (decl)->decl)
844 && !clone_of_p (cgraph_node (decl),
845 e->callee))
847 error ("edge points to wrong declaration:");
848 debug_tree (e->callee->decl);
849 fprintf (stderr," Instead of:");
850 debug_tree (decl);
851 error_found = true;
853 #endif
855 else if (decl)
857 error ("an indirect edge with unknown callee "
858 "corresponding to a call_stmt with "
859 "a known declaration:");
860 error_found = true;
861 debug_gimple_stmt (e->call_stmt);
863 e->aux = (void *)1;
865 else if (decl)
867 error ("missing callgraph edge for call stmt:");
868 debug_gimple_stmt (stmt);
869 error_found = true;
873 pointer_set_destroy (visited_nodes);
875 else
876 /* No CFG available?! */
877 gcc_unreachable ();
879 for (e = node->callees; e; e = e->next_callee)
881 if (!e->aux)
883 error ("edge %s->%s has no corresponding call_stmt",
884 identifier_to_locale (cgraph_node_name (e->caller)),
885 identifier_to_locale (cgraph_node_name (e->callee)));
886 debug_gimple_stmt (e->call_stmt);
887 error_found = true;
889 e->aux = 0;
891 for (e = node->indirect_calls; e; e = e->next_callee)
893 if (!e->aux)
895 error ("an indirect edge from %s has no corresponding call_stmt",
896 identifier_to_locale (cgraph_node_name (e->caller)));
897 debug_gimple_stmt (e->call_stmt);
898 error_found = true;
900 e->aux = 0;
903 if (error_found)
905 dump_cgraph_node (stderr, node);
906 internal_error ("verify_cgraph_node failed");
908 set_cfun (saved_cfun);
909 timevar_pop (TV_CGRAPH_VERIFY);
912 /* Verify whole cgraph structure. */
913 DEBUG_FUNCTION void
914 verify_cgraph (void)
916 struct cgraph_node *node;
918 if (seen_error ())
919 return;
921 for (node = cgraph_nodes; node; node = node->next)
922 verify_cgraph_node (node);
925 /* Output all asm statements we have stored up to be output. */
927 static void
928 cgraph_output_pending_asms (void)
930 struct cgraph_asm_node *can;
932 if (seen_error ())
933 return;
935 for (can = cgraph_asm_nodes; can; can = can->next)
936 assemble_asm (can->asm_str);
937 cgraph_asm_nodes = NULL;
940 /* Analyze the function scheduled to be output. */
941 static void
942 cgraph_analyze_function (struct cgraph_node *node)
944 tree save = current_function_decl;
945 tree decl = node->decl;
947 current_function_decl = decl;
948 push_cfun (DECL_STRUCT_FUNCTION (decl));
950 assign_assembler_name_if_neeeded (node->decl);
952 /* Make sure to gimplify bodies only once. During analyzing a
953 function we lower it, which will require gimplified nested
954 functions, so we can end up here with an already gimplified
955 body. */
956 if (!gimple_body (decl))
957 gimplify_function_tree (decl);
958 dump_function (TDI_generic, decl);
960 cgraph_lower_function (node);
961 node->analyzed = true;
963 pop_cfun ();
964 current_function_decl = save;
967 /* Look for externally_visible and used attributes and mark cgraph nodes
968 accordingly.
970 We cannot mark the nodes at the point the attributes are processed (in
971 handle_*_attribute) because the copy of the declarations available at that
972 point may not be canonical. For example, in:
974 void f();
975 void f() __attribute__((used));
977 the declaration we see in handle_used_attribute will be the second
978 declaration -- but the front end will subsequently merge that declaration
979 with the original declaration and discard the second declaration.
981 Furthermore, we can't mark these nodes in cgraph_finalize_function because:
983 void f() {}
984 void f() __attribute__((externally_visible));
986 is valid.
988 So, we walk the nodes at the end of the translation unit, applying the
989 attributes at that point. */
991 static void
992 process_function_and_variable_attributes (struct cgraph_node *first,
993 struct varpool_node *first_var)
995 struct cgraph_node *node;
996 struct varpool_node *vnode;
998 for (node = cgraph_nodes; node != first; node = node->next)
1000 tree decl = node->decl;
1001 if (DECL_PRESERVE_P (decl))
1002 cgraph_mark_needed_node (node);
1003 if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
1005 if (! TREE_PUBLIC (node->decl))
1006 warning_at (DECL_SOURCE_LOCATION (node->decl), OPT_Wattributes,
1007 "%<externally_visible%>"
1008 " attribute have effect only on public objects");
1009 else if (node->local.finalized)
1010 cgraph_mark_needed_node (node);
1013 for (vnode = varpool_nodes; vnode != first_var; vnode = vnode->next)
1015 tree decl = vnode->decl;
1016 if (DECL_PRESERVE_P (decl))
1018 vnode->force_output = true;
1019 if (vnode->finalized)
1020 varpool_mark_needed_node (vnode);
1022 if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
1024 if (! TREE_PUBLIC (vnode->decl))
1025 warning_at (DECL_SOURCE_LOCATION (vnode->decl), OPT_Wattributes,
1026 "%<externally_visible%>"
1027 " attribute have effect only on public objects");
1028 else if (vnode->finalized)
1029 varpool_mark_needed_node (vnode);
1034 /* Process CGRAPH_NODES_NEEDED queue, analyze each function (and transitively
1035 each reachable functions) and build cgraph.
1036 The function can be called multiple times after inserting new nodes
1037 into beginning of queue. Just the new part of queue is re-scanned then. */
1039 static void
1040 cgraph_analyze_functions (void)
1042 /* Keep track of already processed nodes when called multiple times for
1043 intermodule optimization. */
1044 static struct cgraph_node *first_analyzed;
1045 struct cgraph_node *first_processed = first_analyzed;
1046 static struct varpool_node *first_analyzed_var;
1047 struct cgraph_node *node, *next;
1049 process_function_and_variable_attributes (first_processed,
1050 first_analyzed_var);
1051 first_processed = cgraph_nodes;
1052 first_analyzed_var = varpool_nodes;
1053 varpool_analyze_pending_decls ();
1054 if (cgraph_dump_file)
1056 fprintf (cgraph_dump_file, "Initial entry points:");
1057 for (node = cgraph_nodes; node != first_analyzed; node = node->next)
1058 if (node->needed)
1059 fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
1060 fprintf (cgraph_dump_file, "\n");
1062 cgraph_process_new_functions ();
1064 /* Propagate reachability flag and lower representation of all reachable
1065 functions. In the future, lowering will introduce new functions and
1066 new entry points on the way (by template instantiation and virtual
1067 method table generation for instance). */
1068 while (cgraph_nodes_queue)
1070 struct cgraph_edge *edge;
1071 tree decl = cgraph_nodes_queue->decl;
1073 node = cgraph_nodes_queue;
1074 cgraph_nodes_queue = cgraph_nodes_queue->next_needed;
1075 node->next_needed = NULL;
1077 /* ??? It is possible to create extern inline function and later using
1078 weak alias attribute to kill its body. See
1079 gcc.c-torture/compile/20011119-1.c */
1080 if (!DECL_STRUCT_FUNCTION (decl))
1082 cgraph_reset_node (node);
1083 continue;
1086 if (!node->analyzed)
1087 cgraph_analyze_function (node);
1089 for (edge = node->callees; edge; edge = edge->next_callee)
1090 if (!edge->callee->reachable)
1091 cgraph_mark_reachable_node (edge->callee);
1093 if (node->same_comdat_group)
1095 for (next = node->same_comdat_group;
1096 next != node;
1097 next = next->same_comdat_group)
1098 cgraph_mark_reachable_node (next);
1101 /* If decl is a clone of an abstract function, mark that abstract
1102 function so that we don't release its body. The DECL_INITIAL() of that
1103 abstract function declaration will be later needed to output debug info. */
1104 if (DECL_ABSTRACT_ORIGIN (decl))
1106 struct cgraph_node *origin_node = cgraph_node (DECL_ABSTRACT_ORIGIN (decl));
1107 origin_node->abstract_and_needed = true;
1110 /* We finalize local static variables during constructing callgraph
1111 edges. Process their attributes too. */
1112 process_function_and_variable_attributes (first_processed,
1113 first_analyzed_var);
1114 first_processed = cgraph_nodes;
1115 first_analyzed_var = varpool_nodes;
1116 varpool_analyze_pending_decls ();
1117 cgraph_process_new_functions ();
1120 /* Collect entry points to the unit. */
1121 if (cgraph_dump_file)
1123 fprintf (cgraph_dump_file, "Unit entry points:");
1124 for (node = cgraph_nodes; node != first_analyzed; node = node->next)
1125 if (node->needed)
1126 fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
1127 fprintf (cgraph_dump_file, "\n\nInitial ");
1128 dump_cgraph (cgraph_dump_file);
1131 if (cgraph_dump_file)
1132 fprintf (cgraph_dump_file, "\nReclaiming functions:");
1134 for (node = cgraph_nodes; node != first_analyzed; node = next)
1136 tree decl = node->decl;
1137 next = node->next;
1139 if (node->local.finalized && !gimple_has_body_p (decl))
1140 cgraph_reset_node (node);
1142 if (!node->reachable && gimple_has_body_p (decl))
1144 if (cgraph_dump_file)
1145 fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
1146 cgraph_remove_node (node);
1147 continue;
1149 else
1150 node->next_needed = NULL;
1151 gcc_assert (!node->local.finalized || gimple_has_body_p (decl));
1152 gcc_assert (node->analyzed == node->local.finalized);
1154 if (cgraph_dump_file)
1156 fprintf (cgraph_dump_file, "\n\nReclaimed ");
1157 dump_cgraph (cgraph_dump_file);
1159 first_analyzed = cgraph_nodes;
1160 ggc_collect ();
1164 /* Analyze the whole compilation unit once it is parsed completely. */
1166 void
1167 cgraph_finalize_compilation_unit (void)
1169 timevar_push (TV_CGRAPH);
1171 /* Do not skip analyzing the functions if there were errors, we
1172 miss diagnostics for following functions otherwise. */
1174 /* Emit size functions we didn't inline. */
1175 finalize_size_functions ();
1177 /* Call functions declared with the "constructor" or "destructor"
1178 attribute. */
1179 cgraph_build_cdtor_fns ();
1181 /* Mark alias targets necessary and emit diagnostics. */
1182 finish_aliases_1 ();
1184 if (!quiet_flag)
1186 fprintf (stderr, "\nAnalyzing compilation unit\n");
1187 fflush (stderr);
1190 /* Gimplify and lower all functions, compute reachability and
1191 remove unreachable nodes. */
1192 cgraph_analyze_functions ();
1194 /* Mark alias targets necessary and emit diagnostics. */
1195 finish_aliases_1 ();
1197 /* Gimplify and lower thunks. */
1198 cgraph_analyze_functions ();
1200 /* Finally drive the pass manager. */
1201 cgraph_optimize ();
1203 timevar_pop (TV_CGRAPH);
1207 /* Figure out what functions we want to assemble. */
1209 static void
1210 cgraph_mark_functions_to_output (void)
1212 struct cgraph_node *node;
1213 #ifdef ENABLE_CHECKING
1214 bool check_same_comdat_groups = false;
1216 for (node = cgraph_nodes; node; node = node->next)
1217 gcc_assert (!node->process);
1218 #endif
1220 for (node = cgraph_nodes; node; node = node->next)
1222 tree decl = node->decl;
1223 struct cgraph_edge *e;
1225 gcc_assert (!node->process || node->same_comdat_group);
1226 if (node->process)
1227 continue;
1229 for (e = node->callers; e; e = e->next_caller)
1230 if (e->inline_failed)
1231 break;
1233 /* We need to output all local functions that are used and not
1234 always inlined, as well as those that are reachable from
1235 outside the current compilation unit. */
1236 if (node->analyzed
1237 && !node->global.inlined_to
1238 && (node->needed || node->reachable_from_other_partition
1239 || node->address_taken
1240 || (e && node->reachable))
1241 && !TREE_ASM_WRITTEN (decl)
1242 && !DECL_EXTERNAL (decl))
1244 node->process = 1;
1245 if (node->same_comdat_group)
1247 struct cgraph_node *next;
1248 for (next = node->same_comdat_group;
1249 next != node;
1250 next = next->same_comdat_group)
1251 next->process = 1;
1254 else if (node->same_comdat_group)
1256 #ifdef ENABLE_CHECKING
1257 check_same_comdat_groups = true;
1258 #endif
1260 else
1262 /* We should've reclaimed all functions that are not needed. */
1263 #ifdef ENABLE_CHECKING
1264 if (!node->global.inlined_to
1265 && gimple_has_body_p (decl)
1266 /* FIXME: in ltrans unit when offline copy is outside partition but inline copies
1267 are inside partition, we can end up not removing the body since we no longer
1268 have analyzed node pointing to it. */
1269 && !node->in_other_partition
1270 && !DECL_EXTERNAL (decl))
1272 dump_cgraph_node (stderr, node);
1273 internal_error ("failed to reclaim unneeded function");
1275 #endif
1276 gcc_assert (node->global.inlined_to
1277 || !gimple_has_body_p (decl)
1278 || node->in_other_partition
1279 || DECL_EXTERNAL (decl));
1284 #ifdef ENABLE_CHECKING
1285 if (check_same_comdat_groups)
1286 for (node = cgraph_nodes; node; node = node->next)
1287 if (node->same_comdat_group && !node->process)
1289 tree decl = node->decl;
1290 if (!node->global.inlined_to
1291 && gimple_has_body_p (decl)
1292 /* FIXME: in ltrans unit when offline copy is outside partition but inline copies
1293 are inside partition, we can end up not removing the body since we no longer
1294 have analyzed node pointing to it. */
1295 && !node->in_other_partition
1296 && !DECL_EXTERNAL (decl))
1298 dump_cgraph_node (stderr, node);
1299 internal_error ("failed to reclaim unneeded function");
1302 #endif
1305 /* DECL is FUNCTION_DECL. Initialize datastructures so DECL is a function
1306 in lowered gimple form.
1308 Set current_function_decl and cfun to newly constructed empty function body.
1309 return basic block in the function body. */
1311 static basic_block
1312 init_lowered_empty_function (tree decl)
1314 basic_block bb;
1316 current_function_decl = decl;
1317 allocate_struct_function (decl, false);
1318 gimple_register_cfg_hooks ();
1319 init_empty_tree_cfg ();
1320 init_tree_ssa (cfun);
1321 init_ssa_operands ();
1322 cfun->gimple_df->in_ssa_p = true;
1323 DECL_INITIAL (decl) = make_node (BLOCK);
1325 DECL_SAVED_TREE (decl) = error_mark_node;
1326 cfun->curr_properties |=
1327 (PROP_gimple_lcf | PROP_gimple_leh | PROP_cfg | PROP_referenced_vars |
1328 PROP_ssa);
1330 /* Create BB for body of the function and connect it properly. */
1331 bb = create_basic_block (NULL, (void *) 0, ENTRY_BLOCK_PTR);
1332 make_edge (ENTRY_BLOCK_PTR, bb, 0);
1333 make_edge (bb, EXIT_BLOCK_PTR, 0);
1335 return bb;
1338 /* Adjust PTR by the constant FIXED_OFFSET, and by the vtable
1339 offset indicated by VIRTUAL_OFFSET, if that is
1340 non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and
1341 zero for a result adjusting thunk. */
1343 static tree
1344 thunk_adjust (gimple_stmt_iterator * bsi,
1345 tree ptr, bool this_adjusting,
1346 HOST_WIDE_INT fixed_offset, tree virtual_offset)
1348 gimple stmt;
1349 tree ret;
1351 if (this_adjusting
1352 && fixed_offset != 0)
1354 stmt = gimple_build_assign (ptr,
1355 fold_build2_loc (input_location,
1356 POINTER_PLUS_EXPR,
1357 TREE_TYPE (ptr), ptr,
1358 size_int (fixed_offset)));
1359 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1362 /* If there's a virtual offset, look up that value in the vtable and
1363 adjust the pointer again. */
1364 if (virtual_offset)
1366 tree vtabletmp;
1367 tree vtabletmp2;
1368 tree vtabletmp3;
1369 tree offsettmp;
1371 if (!vtable_entry_type)
1373 tree vfunc_type = make_node (FUNCTION_TYPE);
1374 TREE_TYPE (vfunc_type) = integer_type_node;
1375 TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
1376 layout_type (vfunc_type);
1378 vtable_entry_type = build_pointer_type (vfunc_type);
1381 vtabletmp =
1382 create_tmp_var (build_pointer_type
1383 (build_pointer_type (vtable_entry_type)), "vptr");
1385 /* The vptr is always at offset zero in the object. */
1386 stmt = gimple_build_assign (vtabletmp,
1387 build1 (NOP_EXPR, TREE_TYPE (vtabletmp),
1388 ptr));
1389 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1390 mark_symbols_for_renaming (stmt);
1391 find_referenced_vars_in (stmt);
1393 /* Form the vtable address. */
1394 vtabletmp2 = create_tmp_var (TREE_TYPE (TREE_TYPE (vtabletmp)),
1395 "vtableaddr");
1396 stmt = gimple_build_assign (vtabletmp2,
1397 build_simple_mem_ref (vtabletmp));
1398 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1399 mark_symbols_for_renaming (stmt);
1400 find_referenced_vars_in (stmt);
1402 /* Find the entry with the vcall offset. */
1403 stmt = gimple_build_assign (vtabletmp2,
1404 fold_build2_loc (input_location,
1405 POINTER_PLUS_EXPR,
1406 TREE_TYPE (vtabletmp2),
1407 vtabletmp2,
1408 fold_convert (sizetype,
1409 virtual_offset)));
1410 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1412 /* Get the offset itself. */
1413 vtabletmp3 = create_tmp_var (TREE_TYPE (TREE_TYPE (vtabletmp2)),
1414 "vcalloffset");
1415 stmt = gimple_build_assign (vtabletmp3,
1416 build_simple_mem_ref (vtabletmp2));
1417 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1418 mark_symbols_for_renaming (stmt);
1419 find_referenced_vars_in (stmt);
1421 /* Cast to sizetype. */
1422 offsettmp = create_tmp_var (sizetype, "offset");
1423 stmt = gimple_build_assign (offsettmp, fold_convert (sizetype, vtabletmp3));
1424 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1425 mark_symbols_for_renaming (stmt);
1426 find_referenced_vars_in (stmt);
1428 /* Adjust the `this' pointer. */
1429 ptr = fold_build2_loc (input_location,
1430 POINTER_PLUS_EXPR, TREE_TYPE (ptr), ptr,
1431 offsettmp);
1434 if (!this_adjusting
1435 && fixed_offset != 0)
1436 /* Adjust the pointer by the constant. */
1438 tree ptrtmp;
1440 if (TREE_CODE (ptr) == VAR_DECL)
1441 ptrtmp = ptr;
1442 else
1444 ptrtmp = create_tmp_var (TREE_TYPE (ptr), "ptr");
1445 stmt = gimple_build_assign (ptrtmp, ptr);
1446 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1447 mark_symbols_for_renaming (stmt);
1448 find_referenced_vars_in (stmt);
1450 ptr = fold_build2_loc (input_location,
1451 POINTER_PLUS_EXPR, TREE_TYPE (ptrtmp), ptrtmp,
1452 size_int (fixed_offset));
1455 /* Emit the statement and gimplify the adjustment expression. */
1456 ret = create_tmp_var (TREE_TYPE (ptr), "adjusted_this");
1457 stmt = gimple_build_assign (ret, ptr);
1458 mark_symbols_for_renaming (stmt);
1459 find_referenced_vars_in (stmt);
1460 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1462 return ret;
1465 /* Produce assembler for thunk NODE. */
1467 static void
1468 assemble_thunk (struct cgraph_node *node)
1470 bool this_adjusting = node->thunk.this_adjusting;
1471 HOST_WIDE_INT fixed_offset = node->thunk.fixed_offset;
1472 HOST_WIDE_INT virtual_value = node->thunk.virtual_value;
1473 tree virtual_offset = NULL;
1474 tree alias = node->thunk.alias;
1475 tree thunk_fndecl = node->decl;
1476 tree a = DECL_ARGUMENTS (thunk_fndecl);
1478 current_function_decl = thunk_fndecl;
1480 if (this_adjusting
1481 && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
1482 virtual_value, alias))
1484 const char *fnname;
1485 tree fn_block;
1487 DECL_RESULT (thunk_fndecl)
1488 = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl),
1489 RESULT_DECL, 0, integer_type_node);
1490 fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
1492 /* The back end expects DECL_INITIAL to contain a BLOCK, so we
1493 create one. */
1494 fn_block = make_node (BLOCK);
1495 BLOCK_VARS (fn_block) = a;
1496 DECL_INITIAL (thunk_fndecl) = fn_block;
1497 init_function_start (thunk_fndecl);
1498 cfun->is_thunk = 1;
1499 assemble_start_function (thunk_fndecl, fnname);
1501 targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl,
1502 fixed_offset, virtual_value, alias);
1504 assemble_end_function (thunk_fndecl, fnname);
1505 init_insn_lengths ();
1506 free_after_compilation (cfun);
1507 set_cfun (NULL);
1508 TREE_ASM_WRITTEN (thunk_fndecl) = 1;
1510 else
1512 tree restype;
1513 basic_block bb, then_bb, else_bb, return_bb;
1514 gimple_stmt_iterator bsi;
1515 int nargs = 0;
1516 tree arg;
1517 int i;
1518 tree resdecl;
1519 tree restmp = NULL;
1520 VEC(tree, heap) *vargs;
1522 gimple call;
1523 gimple ret;
1525 DECL_IGNORED_P (thunk_fndecl) = 1;
1526 bitmap_obstack_initialize (NULL);
1528 if (node->thunk.virtual_offset_p)
1529 virtual_offset = size_int (virtual_value);
1531 /* Build the return declaration for the function. */
1532 restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1533 if (DECL_RESULT (thunk_fndecl) == NULL_TREE)
1535 resdecl = build_decl (input_location, RESULT_DECL, 0, restype);
1536 DECL_ARTIFICIAL (resdecl) = 1;
1537 DECL_IGNORED_P (resdecl) = 1;
1538 DECL_RESULT (thunk_fndecl) = resdecl;
1540 else
1541 resdecl = DECL_RESULT (thunk_fndecl);
1543 bb = then_bb = else_bb = return_bb = init_lowered_empty_function (thunk_fndecl);
1545 bsi = gsi_start_bb (bb);
1547 /* Build call to the function being thunked. */
1548 if (!VOID_TYPE_P (restype))
1550 if (!is_gimple_reg_type (restype))
1552 restmp = resdecl;
1553 add_local_decl (cfun, restmp);
1554 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp;
1556 else
1557 restmp = create_tmp_var_raw (restype, "retval");
1560 for (arg = a; arg; arg = DECL_CHAIN (arg))
1561 nargs++;
1562 vargs = VEC_alloc (tree, heap, nargs);
1563 if (this_adjusting)
1564 VEC_quick_push (tree, vargs,
1565 thunk_adjust (&bsi,
1566 a, 1, fixed_offset,
1567 virtual_offset));
1568 else
1569 VEC_quick_push (tree, vargs, a);
1570 for (i = 1, arg = DECL_CHAIN (a); i < nargs; i++, arg = DECL_CHAIN (arg))
1571 VEC_quick_push (tree, vargs, arg);
1572 call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs);
1573 VEC_free (tree, heap, vargs);
1574 gimple_call_set_cannot_inline (call, true);
1575 gimple_call_set_from_thunk (call, true);
1576 if (restmp)
1577 gimple_call_set_lhs (call, restmp);
1578 gsi_insert_after (&bsi, call, GSI_NEW_STMT);
1579 mark_symbols_for_renaming (call);
1580 find_referenced_vars_in (call);
1581 update_stmt (call);
1583 if (restmp && !this_adjusting)
1585 tree true_label = NULL_TREE;
1587 if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE)
1589 gimple stmt;
1590 /* If the return type is a pointer, we need to
1591 protect against NULL. We know there will be an
1592 adjustment, because that's why we're emitting a
1593 thunk. */
1594 then_bb = create_basic_block (NULL, (void *) 0, bb);
1595 return_bb = create_basic_block (NULL, (void *) 0, then_bb);
1596 else_bb = create_basic_block (NULL, (void *) 0, else_bb);
1597 remove_edge (single_succ_edge (bb));
1598 true_label = gimple_block_label (then_bb);
1599 stmt = gimple_build_cond (NE_EXPR, restmp,
1600 fold_convert (TREE_TYPE (restmp),
1601 integer_zero_node),
1602 NULL_TREE, NULL_TREE);
1603 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1604 make_edge (bb, then_bb, EDGE_TRUE_VALUE);
1605 make_edge (bb, else_bb, EDGE_FALSE_VALUE);
1606 make_edge (return_bb, EXIT_BLOCK_PTR, 0);
1607 make_edge (then_bb, return_bb, EDGE_FALLTHRU);
1608 make_edge (else_bb, return_bb, EDGE_FALLTHRU);
1609 bsi = gsi_last_bb (then_bb);
1612 restmp = thunk_adjust (&bsi, restmp, /*this_adjusting=*/0,
1613 fixed_offset, virtual_offset);
1614 if (true_label)
1616 gimple stmt;
1617 bsi = gsi_last_bb (else_bb);
1618 stmt = gimple_build_assign (restmp, fold_convert (TREE_TYPE (restmp),
1619 integer_zero_node));
1620 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1621 bsi = gsi_last_bb (return_bb);
1624 else
1625 gimple_call_set_tail (call, true);
1627 /* Build return value. */
1628 ret = gimple_build_return (restmp);
1629 gsi_insert_after (&bsi, ret, GSI_NEW_STMT);
1631 delete_unreachable_blocks ();
1632 update_ssa (TODO_update_ssa);
1634 cgraph_remove_same_body_alias (node);
1635 /* Since we want to emit the thunk, we explicitly mark its name as
1636 referenced. */
1637 cgraph_add_new_function (thunk_fndecl, true);
1638 bitmap_obstack_release (NULL);
1640 current_function_decl = NULL;
1643 /* Expand function specified by NODE. */
1645 static void
1646 cgraph_expand_function (struct cgraph_node *node)
1648 tree decl = node->decl;
1650 /* We ought to not compile any inline clones. */
1651 gcc_assert (!node->global.inlined_to);
1653 announce_function (decl);
1654 node->process = 0;
1656 gcc_assert (node->lowered);
1658 /* Generate RTL for the body of DECL. */
1659 tree_rest_of_compilation (decl);
1661 /* Make sure that BE didn't give up on compiling. */
1662 gcc_assert (TREE_ASM_WRITTEN (decl));
1663 current_function_decl = NULL;
1664 if (node->same_body)
1666 struct cgraph_node *alias, *next;
1667 bool saved_alias = node->alias;
1668 for (alias = node->same_body;
1669 alias && alias->next; alias = alias->next)
1671 /* Walk aliases in the order they were created; it is possible that
1672 thunks reffers to the aliases made earlier. */
1673 for (; alias; alias = next)
1675 next = alias->previous;
1676 if (!alias->thunk.thunk_p)
1677 assemble_alias (alias->decl,
1678 DECL_ASSEMBLER_NAME (alias->thunk.alias));
1679 else
1680 assemble_thunk (alias);
1682 node->alias = saved_alias;
1684 gcc_assert (!cgraph_preserve_function_body_p (decl));
1685 cgraph_release_function_body (node);
1686 /* Eliminate all call edges. This is important so the GIMPLE_CALL no longer
1687 points to the dead function body. */
1688 cgraph_node_remove_callees (node);
1690 cgraph_function_flags_ready = true;
1693 /* Return true when CALLER_DECL should be inlined into CALLEE_DECL. */
1695 bool
1696 cgraph_inline_p (struct cgraph_edge *e, cgraph_inline_failed_t *reason)
1698 *reason = e->inline_failed;
1699 return !e->inline_failed;
1704 /* Expand all functions that must be output.
1706 Attempt to topologically sort the nodes so function is output when
1707 all called functions are already assembled to allow data to be
1708 propagated across the callgraph. Use a stack to get smaller distance
1709 between a function and its callees (later we may choose to use a more
1710 sophisticated algorithm for function reordering; we will likely want
1711 to use subsections to make the output functions appear in top-down
1712 order). */
1714 static void
1715 cgraph_expand_all_functions (void)
1717 struct cgraph_node *node;
1718 struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
1719 int order_pos, new_order_pos = 0;
1720 int i;
1722 order_pos = cgraph_postorder (order);
1723 gcc_assert (order_pos == cgraph_n_nodes);
1725 /* Garbage collector may remove inline clones we eliminate during
1726 optimization. So we must be sure to not reference them. */
1727 for (i = 0; i < order_pos; i++)
1728 if (order[i]->process)
1729 order[new_order_pos++] = order[i];
1731 for (i = new_order_pos - 1; i >= 0; i--)
1733 node = order[i];
1734 if (node->process)
1736 gcc_assert (node->reachable);
1737 node->process = 0;
1738 cgraph_expand_function (node);
1741 cgraph_process_new_functions ();
1743 free (order);
1747 /* This is used to sort the node types by the cgraph order number. */
1749 enum cgraph_order_sort_kind
1751 ORDER_UNDEFINED = 0,
1752 ORDER_FUNCTION,
1753 ORDER_VAR,
1754 ORDER_ASM
1757 struct cgraph_order_sort
1759 enum cgraph_order_sort_kind kind;
1760 union
1762 struct cgraph_node *f;
1763 struct varpool_node *v;
1764 struct cgraph_asm_node *a;
1765 } u;
1768 /* Output all functions, variables, and asm statements in the order
1769 according to their order fields, which is the order in which they
1770 appeared in the file. This implements -fno-toplevel-reorder. In
1771 this mode we may output functions and variables which don't really
1772 need to be output. */
1774 static void
1775 cgraph_output_in_order (void)
1777 int max;
1778 struct cgraph_order_sort *nodes;
1779 int i;
1780 struct cgraph_node *pf;
1781 struct varpool_node *pv;
1782 struct cgraph_asm_node *pa;
1784 max = cgraph_order;
1785 nodes = XCNEWVEC (struct cgraph_order_sort, max);
1787 varpool_analyze_pending_decls ();
1789 for (pf = cgraph_nodes; pf; pf = pf->next)
1791 if (pf->process)
1793 i = pf->order;
1794 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1795 nodes[i].kind = ORDER_FUNCTION;
1796 nodes[i].u.f = pf;
1800 for (pv = varpool_nodes_queue; pv; pv = pv->next_needed)
1802 i = pv->order;
1803 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1804 nodes[i].kind = ORDER_VAR;
1805 nodes[i].u.v = pv;
1808 for (pa = cgraph_asm_nodes; pa; pa = pa->next)
1810 i = pa->order;
1811 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1812 nodes[i].kind = ORDER_ASM;
1813 nodes[i].u.a = pa;
1816 /* In toplevel reorder mode we output all statics; mark them as needed. */
1817 for (i = 0; i < max; ++i)
1819 if (nodes[i].kind == ORDER_VAR)
1821 varpool_mark_needed_node (nodes[i].u.v);
1824 varpool_empty_needed_queue ();
1826 for (i = 0; i < max; ++i)
1828 switch (nodes[i].kind)
1830 case ORDER_FUNCTION:
1831 nodes[i].u.f->process = 0;
1832 cgraph_expand_function (nodes[i].u.f);
1833 break;
1835 case ORDER_VAR:
1836 varpool_assemble_decl (nodes[i].u.v);
1837 break;
1839 case ORDER_ASM:
1840 assemble_asm (nodes[i].u.a->asm_str);
1841 break;
1843 case ORDER_UNDEFINED:
1844 break;
1846 default:
1847 gcc_unreachable ();
1851 cgraph_asm_nodes = NULL;
1852 free (nodes);
1855 /* Return true when function body of DECL still needs to be kept around
1856 for later re-use. */
1857 bool
1858 cgraph_preserve_function_body_p (tree decl)
1860 struct cgraph_node *node;
1862 gcc_assert (cgraph_global_info_ready);
1863 /* Look if there is any clone around. */
1864 node = cgraph_node (decl);
1865 if (node->clones)
1866 return true;
1867 return false;
1870 static void
1871 ipa_passes (void)
1873 set_cfun (NULL);
1874 current_function_decl = NULL;
1875 gimple_register_cfg_hooks ();
1876 bitmap_obstack_initialize (NULL);
1878 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START, NULL);
1880 if (!in_lto_p)
1881 execute_ipa_pass_list (all_small_ipa_passes);
1883 /* If pass_all_early_optimizations was not scheduled, the state of
1884 the cgraph will not be properly updated. Update it now. */
1885 if (cgraph_state < CGRAPH_STATE_IPA_SSA)
1886 cgraph_state = CGRAPH_STATE_IPA_SSA;
1888 if (!in_lto_p)
1890 /* Generate coverage variables and constructors. */
1891 coverage_finish ();
1893 /* Process new functions added. */
1894 set_cfun (NULL);
1895 current_function_decl = NULL;
1896 cgraph_process_new_functions ();
1898 execute_ipa_summary_passes
1899 ((struct ipa_opt_pass_d *) all_regular_ipa_passes);
1902 /* Some targets need to handle LTO assembler output specially. */
1903 if (flag_generate_lto)
1904 targetm.asm_out.lto_start ();
1906 execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_lto_gen_passes);
1908 if (!in_lto_p)
1909 ipa_write_summaries ();
1911 if (flag_generate_lto)
1912 targetm.asm_out.lto_end ();
1914 if (!flag_ltrans)
1915 execute_ipa_pass_list (all_regular_ipa_passes);
1916 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END, NULL);
1918 bitmap_obstack_release (NULL);
1922 /* Perform simple optimizations based on callgraph. */
1924 void
1925 cgraph_optimize (void)
1927 if (seen_error ())
1928 return;
1930 #ifdef ENABLE_CHECKING
1931 verify_cgraph ();
1932 #endif
1934 /* Frontend may output common variables after the unit has been finalized.
1935 It is safe to deal with them here as they are always zero initialized. */
1936 varpool_analyze_pending_decls ();
1938 timevar_push (TV_CGRAPHOPT);
1939 if (pre_ipa_mem_report)
1941 fprintf (stderr, "Memory consumption before IPA\n");
1942 dump_memory_report (false);
1944 if (!quiet_flag)
1945 fprintf (stderr, "Performing interprocedural optimizations\n");
1946 cgraph_state = CGRAPH_STATE_IPA;
1948 /* Don't run the IPA passes if there was any error or sorry messages. */
1949 if (!seen_error ())
1950 ipa_passes ();
1952 /* Do nothing else if any IPA pass found errors. */
1953 if (seen_error ())
1955 timevar_pop (TV_CGRAPHOPT);
1956 return;
1959 /* This pass remove bodies of extern inline functions we never inlined.
1960 Do this later so other IPA passes see what is really going on. */
1961 cgraph_remove_unreachable_nodes (false, dump_file);
1962 cgraph_global_info_ready = true;
1963 if (cgraph_dump_file)
1965 fprintf (cgraph_dump_file, "Optimized ");
1966 dump_cgraph (cgraph_dump_file);
1967 dump_varpool (cgraph_dump_file);
1969 if (post_ipa_mem_report)
1971 fprintf (stderr, "Memory consumption after IPA\n");
1972 dump_memory_report (false);
1974 timevar_pop (TV_CGRAPHOPT);
1976 /* Output everything. */
1977 (*debug_hooks->assembly_start) ();
1978 if (!quiet_flag)
1979 fprintf (stderr, "Assembling functions:\n");
1980 #ifdef ENABLE_CHECKING
1981 verify_cgraph ();
1982 #endif
1984 cgraph_materialize_all_clones ();
1985 cgraph_mark_functions_to_output ();
1987 cgraph_state = CGRAPH_STATE_EXPANSION;
1988 if (!flag_toplevel_reorder)
1989 cgraph_output_in_order ();
1990 else
1992 cgraph_output_pending_asms ();
1994 cgraph_expand_all_functions ();
1995 varpool_remove_unreferenced_decls ();
1997 varpool_assemble_pending_decls ();
1999 cgraph_process_new_functions ();
2000 cgraph_state = CGRAPH_STATE_FINISHED;
2002 if (cgraph_dump_file)
2004 fprintf (cgraph_dump_file, "\nFinal ");
2005 dump_cgraph (cgraph_dump_file);
2007 #ifdef ENABLE_CHECKING
2008 verify_cgraph ();
2009 /* Double check that all inline clones are gone and that all
2010 function bodies have been released from memory. */
2011 if (!seen_error ())
2013 struct cgraph_node *node;
2014 bool error_found = false;
2016 for (node = cgraph_nodes; node; node = node->next)
2017 if (node->analyzed
2018 && (node->global.inlined_to
2019 || gimple_has_body_p (node->decl)))
2021 error_found = true;
2022 dump_cgraph_node (stderr, node);
2024 if (error_found)
2025 internal_error ("nodes with unreleased memory found");
2027 #endif
2031 /* Generate and emit a static constructor or destructor. WHICH must
2032 be one of 'I' (for a constructor) or 'D' (for a destructor). BODY
2033 is a STATEMENT_LIST containing GENERIC statements. PRIORITY is the
2034 initialization priority for this constructor or destructor. */
2036 void
2037 cgraph_build_static_cdtor (char which, tree body, int priority)
2039 static int counter = 0;
2040 char which_buf[16];
2041 tree decl, name, resdecl;
2043 /* The priority is encoded in the constructor or destructor name.
2044 collect2 will sort the names and arrange that they are called at
2045 program startup. */
2046 sprintf (which_buf, "%c_%.5d_%d", which, priority, counter++);
2047 name = get_file_function_name (which_buf);
2049 decl = build_decl (input_location, FUNCTION_DECL, name,
2050 build_function_type_list (void_type_node, NULL_TREE));
2051 current_function_decl = decl;
2053 resdecl = build_decl (input_location,
2054 RESULT_DECL, NULL_TREE, void_type_node);
2055 DECL_ARTIFICIAL (resdecl) = 1;
2056 DECL_RESULT (decl) = resdecl;
2057 DECL_CONTEXT (resdecl) = decl;
2059 allocate_struct_function (decl, false);
2061 TREE_STATIC (decl) = 1;
2062 TREE_USED (decl) = 1;
2063 DECL_ARTIFICIAL (decl) = 1;
2064 DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;
2065 DECL_SAVED_TREE (decl) = body;
2066 if (!targetm.have_ctors_dtors)
2068 TREE_PUBLIC (decl) = 1;
2069 DECL_PRESERVE_P (decl) = 1;
2071 DECL_UNINLINABLE (decl) = 1;
2073 DECL_INITIAL (decl) = make_node (BLOCK);
2074 TREE_USED (DECL_INITIAL (decl)) = 1;
2076 DECL_SOURCE_LOCATION (decl) = input_location;
2077 cfun->function_end_locus = input_location;
2079 switch (which)
2081 case 'I':
2082 DECL_STATIC_CONSTRUCTOR (decl) = 1;
2083 decl_init_priority_insert (decl, priority);
2084 break;
2085 case 'D':
2086 DECL_STATIC_DESTRUCTOR (decl) = 1;
2087 decl_fini_priority_insert (decl, priority);
2088 break;
2089 default:
2090 gcc_unreachable ();
2093 gimplify_function_tree (decl);
2095 cgraph_add_new_function (decl, false);
2096 cgraph_mark_needed_node (cgraph_node (decl));
2098 set_cfun (NULL);
2099 current_function_decl = NULL;
2102 void
2103 init_cgraph (void)
2105 if (!cgraph_dump_file)
2106 cgraph_dump_file = dump_begin (TDI_cgraph, NULL);
2109 /* The edges representing the callers of the NEW_VERSION node were
2110 fixed by cgraph_function_versioning (), now the call_expr in their
2111 respective tree code should be updated to call the NEW_VERSION. */
2113 static void
2114 update_call_expr (struct cgraph_node *new_version)
2116 struct cgraph_edge *e;
2118 gcc_assert (new_version);
2120 /* Update the call expr on the edges to call the new version. */
2121 for (e = new_version->callers; e; e = e->next_caller)
2123 struct function *inner_function = DECL_STRUCT_FUNCTION (e->caller->decl);
2124 gimple_call_set_fndecl (e->call_stmt, new_version->decl);
2125 maybe_clean_eh_stmt_fn (inner_function, e->call_stmt);
2130 /* Create a new cgraph node which is the new version of
2131 OLD_VERSION node. REDIRECT_CALLERS holds the callers
2132 edges which should be redirected to point to
2133 NEW_VERSION. ALL the callees edges of OLD_VERSION
2134 are cloned to the new version node. Return the new
2135 version node.
2137 If non-NULL BLOCK_TO_COPY determine what basic blocks
2138 was copied to prevent duplications of calls that are dead
2139 in the clone. */
2141 static struct cgraph_node *
2142 cgraph_copy_node_for_versioning (struct cgraph_node *old_version,
2143 tree new_decl,
2144 VEC(cgraph_edge_p,heap) *redirect_callers,
2145 bitmap bbs_to_copy)
2147 struct cgraph_node *new_version;
2148 struct cgraph_edge *e;
2149 unsigned i;
2151 gcc_assert (old_version);
2153 new_version = cgraph_node (new_decl);
2155 new_version->analyzed = true;
2156 new_version->local = old_version->local;
2157 new_version->local.externally_visible = false;
2158 new_version->local.local = true;
2159 new_version->local.vtable_method = false;
2160 new_version->global = old_version->global;
2161 new_version->rtl = old_version->rtl;
2162 new_version->reachable = true;
2163 new_version->count = old_version->count;
2165 for (e = old_version->callees; e; e=e->next_callee)
2166 if (!bbs_to_copy
2167 || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
2168 cgraph_clone_edge (e, new_version, e->call_stmt,
2169 e->lto_stmt_uid, REG_BR_PROB_BASE,
2170 CGRAPH_FREQ_BASE,
2171 e->loop_nest, true);
2172 for (e = old_version->indirect_calls; e; e=e->next_callee)
2173 if (!bbs_to_copy
2174 || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
2175 cgraph_clone_edge (e, new_version, e->call_stmt,
2176 e->lto_stmt_uid, REG_BR_PROB_BASE,
2177 CGRAPH_FREQ_BASE,
2178 e->loop_nest, true);
2179 for (i = 0; VEC_iterate (cgraph_edge_p, redirect_callers, i, e); i++)
2181 /* Redirect calls to the old version node to point to its new
2182 version. */
2183 cgraph_redirect_edge_callee (e, new_version);
2186 return new_version;
2189 /* Perform function versioning.
2190 Function versioning includes copying of the tree and
2191 a callgraph update (creating a new cgraph node and updating
2192 its callees and callers).
2194 REDIRECT_CALLERS varray includes the edges to be redirected
2195 to the new version.
2197 TREE_MAP is a mapping of tree nodes we want to replace with
2198 new ones (according to results of prior analysis).
2199 OLD_VERSION_NODE is the node that is versioned.
2200 It returns the new version's cgraph node.
2201 If non-NULL ARGS_TO_SKIP determine function parameters to remove
2202 from new version.
2203 If non-NULL BLOCK_TO_COPY determine what basic blocks to copy.
2204 If non_NULL NEW_ENTRY determine new entry BB of the clone. */
2206 struct cgraph_node *
2207 cgraph_function_versioning (struct cgraph_node *old_version_node,
2208 VEC(cgraph_edge_p,heap) *redirect_callers,
2209 VEC (ipa_replace_map_p,gc)* tree_map,
2210 bitmap args_to_skip,
2211 bitmap bbs_to_copy,
2212 basic_block new_entry_block,
2213 const char *clone_name)
2215 tree old_decl = old_version_node->decl;
2216 struct cgraph_node *new_version_node = NULL;
2217 tree new_decl;
2219 if (!tree_versionable_function_p (old_decl))
2220 return NULL;
2222 /* Make a new FUNCTION_DECL tree node for the
2223 new version. */
2224 if (!args_to_skip)
2225 new_decl = copy_node (old_decl);
2226 else
2227 new_decl = build_function_decl_skip_args (old_decl, args_to_skip);
2229 /* Generate a new name for the new version. */
2230 DECL_NAME (new_decl) = clone_function_name (old_decl, clone_name);
2231 SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
2232 SET_DECL_RTL (new_decl, NULL);
2234 /* Create the new version's call-graph node.
2235 and update the edges of the new node. */
2236 new_version_node =
2237 cgraph_copy_node_for_versioning (old_version_node, new_decl,
2238 redirect_callers, bbs_to_copy);
2240 /* Copy the OLD_VERSION_NODE function tree to the new version. */
2241 tree_function_versioning (old_decl, new_decl, tree_map, false, args_to_skip,
2242 bbs_to_copy, new_entry_block);
2244 /* Update the new version's properties.
2245 Make The new version visible only within this translation unit. Make sure
2246 that is not weak also.
2247 ??? We cannot use COMDAT linkage because there is no
2248 ABI support for this. */
2249 cgraph_make_decl_local (new_version_node->decl);
2250 DECL_VIRTUAL_P (new_version_node->decl) = 0;
2251 new_version_node->local.externally_visible = 0;
2252 new_version_node->local.local = 1;
2253 new_version_node->lowered = true;
2255 /* Update the call_expr on the edges to call the new version node. */
2256 update_call_expr (new_version_node);
2258 cgraph_call_function_insertion_hooks (new_version_node);
2259 return new_version_node;
2262 /* Produce separate function body for inline clones so the offline copy can be
2263 modified without affecting them. */
2264 struct cgraph_node *
2265 save_inline_function_body (struct cgraph_node *node)
2267 struct cgraph_node *first_clone, *n;
2269 gcc_assert (node == cgraph_node (node->decl));
2271 cgraph_lower_function (node);
2273 first_clone = node->clones;
2275 first_clone->decl = copy_node (node->decl);
2276 cgraph_insert_node_to_hashtable (first_clone);
2277 gcc_assert (first_clone == cgraph_node (first_clone->decl));
2278 if (first_clone->next_sibling_clone)
2280 for (n = first_clone->next_sibling_clone; n->next_sibling_clone; n = n->next_sibling_clone)
2281 n->clone_of = first_clone;
2282 n->clone_of = first_clone;
2283 n->next_sibling_clone = first_clone->clones;
2284 if (first_clone->clones)
2285 first_clone->clones->prev_sibling_clone = n;
2286 first_clone->clones = first_clone->next_sibling_clone;
2287 first_clone->next_sibling_clone->prev_sibling_clone = NULL;
2288 first_clone->next_sibling_clone = NULL;
2289 gcc_assert (!first_clone->prev_sibling_clone);
2291 first_clone->clone_of = NULL;
2292 node->clones = NULL;
2294 if (first_clone->clones)
2295 for (n = first_clone->clones; n != first_clone;)
2297 gcc_assert (n->decl == node->decl);
2298 n->decl = first_clone->decl;
2299 if (n->clones)
2300 n = n->clones;
2301 else if (n->next_sibling_clone)
2302 n = n->next_sibling_clone;
2303 else
2305 while (n != first_clone && !n->next_sibling_clone)
2306 n = n->clone_of;
2307 if (n != first_clone)
2308 n = n->next_sibling_clone;
2312 /* Copy the OLD_VERSION_NODE function tree to the new version. */
2313 tree_function_versioning (node->decl, first_clone->decl, NULL, true, NULL,
2314 NULL, NULL);
2316 DECL_EXTERNAL (first_clone->decl) = 0;
2317 DECL_COMDAT_GROUP (first_clone->decl) = NULL_TREE;
2318 TREE_PUBLIC (first_clone->decl) = 0;
2319 DECL_COMDAT (first_clone->decl) = 0;
2320 VEC_free (ipa_opt_pass, heap,
2321 first_clone->ipa_transforms_to_apply);
2322 first_clone->ipa_transforms_to_apply = NULL;
2324 #ifdef ENABLE_CHECKING
2325 verify_cgraph_node (first_clone);
2326 #endif
2327 return first_clone;
2330 /* Given virtual clone, turn it into actual clone. */
2331 static void
2332 cgraph_materialize_clone (struct cgraph_node *node)
2334 bitmap_obstack_initialize (NULL);
2335 #ifdef ENABLE_CHECKING
2336 node->former_clone_of = node->clone_of->decl;
2337 if (node->clone_of->former_clone_of)
2338 node->former_clone_of = node->clone_of->former_clone_of;
2339 #endif
2340 /* Copy the OLD_VERSION_NODE function tree to the new version. */
2341 tree_function_versioning (node->clone_of->decl, node->decl,
2342 node->clone.tree_map, true,
2343 node->clone.args_to_skip, NULL, NULL);
2344 if (cgraph_dump_file)
2346 dump_function_to_file (node->clone_of->decl, cgraph_dump_file, dump_flags);
2347 dump_function_to_file (node->decl, cgraph_dump_file, dump_flags);
2350 /* Function is no longer clone. */
2351 if (node->next_sibling_clone)
2352 node->next_sibling_clone->prev_sibling_clone = node->prev_sibling_clone;
2353 if (node->prev_sibling_clone)
2354 node->prev_sibling_clone->next_sibling_clone = node->next_sibling_clone;
2355 else
2356 node->clone_of->clones = node->next_sibling_clone;
2357 node->next_sibling_clone = NULL;
2358 node->prev_sibling_clone = NULL;
2359 if (!node->clone_of->analyzed && !node->clone_of->clones)
2361 cgraph_release_function_body (node->clone_of);
2362 cgraph_node_remove_callees (node->clone_of);
2363 ipa_remove_all_references (&node->clone_of->ref_list);
2365 node->clone_of = NULL;
2366 bitmap_obstack_release (NULL);
2369 /* If necessary, change the function declaration in the call statement
2370 associated with E so that it corresponds to the edge callee. */
2372 gimple
2373 cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *e)
2375 tree decl = gimple_call_fndecl (e->call_stmt);
2376 gimple new_stmt;
2377 #ifdef ENABLE_CHECKING
2378 struct cgraph_node *node;
2379 #endif
2381 if (!decl || decl == e->callee->decl
2382 /* Don't update call from same body alias to the real function. */
2383 || cgraph_get_node (decl) == cgraph_get_node (e->callee->decl))
2384 return e->call_stmt;
2386 #ifdef ENABLE_CHECKING
2387 node = cgraph_get_node (decl);
2388 gcc_assert (!node || !node->clone.combined_args_to_skip);
2389 #endif
2391 if (cgraph_dump_file)
2393 fprintf (cgraph_dump_file, "updating call of %s/%i -> %s/%i: ",
2394 cgraph_node_name (e->caller), e->caller->uid,
2395 cgraph_node_name (e->callee), e->callee->uid);
2396 print_gimple_stmt (cgraph_dump_file, e->call_stmt, 0, dump_flags);
2397 if (e->callee->clone.combined_args_to_skip)
2399 fprintf (cgraph_dump_file, " combined args to skip: ");
2400 dump_bitmap (cgraph_dump_file,
2401 e->callee->clone.combined_args_to_skip);
2405 if (e->callee->clone.combined_args_to_skip)
2407 gimple_stmt_iterator gsi;
2409 new_stmt
2410 = gimple_call_copy_skip_args (e->call_stmt,
2411 e->callee->clone.combined_args_to_skip);
2413 if (gimple_vdef (new_stmt)
2414 && TREE_CODE (gimple_vdef (new_stmt)) == SSA_NAME)
2415 SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt;
2417 gsi = gsi_for_stmt (e->call_stmt);
2418 gsi_replace (&gsi, new_stmt, true);
2420 else
2421 new_stmt = e->call_stmt;
2423 gimple_call_set_fndecl (new_stmt, e->callee->decl);
2424 update_stmt (new_stmt);
2426 cgraph_set_call_stmt_including_clones (e->caller, e->call_stmt, new_stmt);
2428 if (cgraph_dump_file)
2430 fprintf (cgraph_dump_file, " updated to:");
2431 print_gimple_stmt (cgraph_dump_file, e->call_stmt, 0, dump_flags);
2433 return new_stmt;
2436 /* Once all functions from compilation unit are in memory, produce all clones
2437 and update all calls. We might also do this on demand if we don't want to
2438 bring all functions to memory prior compilation, but current WHOPR
2439 implementation does that and it is is bit easier to keep everything right in
2440 this order. */
2441 void
2442 cgraph_materialize_all_clones (void)
2444 struct cgraph_node *node;
2445 bool stabilized = false;
2447 if (cgraph_dump_file)
2448 fprintf (cgraph_dump_file, "Materializing clones\n");
2449 #ifdef ENABLE_CHECKING
2450 verify_cgraph ();
2451 #endif
2453 /* We can also do topological order, but number of iterations should be
2454 bounded by number of IPA passes since single IPA pass is probably not
2455 going to create clones of clones it created itself. */
2456 while (!stabilized)
2458 stabilized = true;
2459 for (node = cgraph_nodes; node; node = node->next)
2461 if (node->clone_of && node->decl != node->clone_of->decl
2462 && !gimple_has_body_p (node->decl))
2464 if (gimple_has_body_p (node->clone_of->decl))
2466 if (cgraph_dump_file)
2468 fprintf (cgraph_dump_file, "clonning %s to %s\n",
2469 cgraph_node_name (node->clone_of),
2470 cgraph_node_name (node));
2471 if (node->clone.tree_map)
2473 unsigned int i;
2474 fprintf (cgraph_dump_file, " replace map: ");
2475 for (i = 0; i < VEC_length (ipa_replace_map_p,
2476 node->clone.tree_map);
2477 i++)
2479 struct ipa_replace_map *replace_info;
2480 replace_info = VEC_index (ipa_replace_map_p,
2481 node->clone.tree_map,
2483 print_generic_expr (cgraph_dump_file, replace_info->old_tree, 0);
2484 fprintf (cgraph_dump_file, " -> ");
2485 print_generic_expr (cgraph_dump_file, replace_info->new_tree, 0);
2486 fprintf (cgraph_dump_file, "%s%s;",
2487 replace_info->replace_p ? "(replace)":"",
2488 replace_info->ref_p ? "(ref)":"");
2490 fprintf (cgraph_dump_file, "\n");
2492 if (node->clone.args_to_skip)
2494 fprintf (cgraph_dump_file, " args_to_skip: ");
2495 dump_bitmap (cgraph_dump_file, node->clone.args_to_skip);
2497 if (node->clone.args_to_skip)
2499 fprintf (cgraph_dump_file, " combined_args_to_skip:");
2500 dump_bitmap (cgraph_dump_file, node->clone.combined_args_to_skip);
2503 cgraph_materialize_clone (node);
2504 stabilized = false;
2509 for (node = cgraph_nodes; node; node = node->next)
2510 if (!node->analyzed && node->callees)
2511 cgraph_node_remove_callees (node);
2512 if (cgraph_dump_file)
2513 fprintf (cgraph_dump_file, "Materialization Call site updates done.\n");
2514 #ifdef ENABLE_CHECKING
2515 verify_cgraph ();
2516 #endif
2517 cgraph_remove_unreachable_nodes (false, cgraph_dump_file);
2520 #include "gt-cgraphunit.h"