Fix a bug where weak decls could be multiply emitted, and another which caused bogus...
[official-gcc.git] / gcc / cgraphunit.c
blobacd50f5ae347e057da771d10f179c5bfbedda394
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 "timevar.h"
127 #include "params.h"
128 #include "fibheap.h"
129 #include "intl.h"
130 #include "function.h"
131 #include "ipa-prop.h"
132 #include "gimple.h"
133 #include "gcov-io.h"
134 #include "tree-iterator.h"
135 #include "tree-pass.h"
136 #include "tree-dump.h"
137 #include "output.h"
138 #include "coverage.h"
139 #include "plugin.h"
141 static void cgraph_expand_all_functions (void);
142 static void cgraph_mark_functions_to_output (void);
143 static void cgraph_expand_function (struct cgraph_node *);
144 static void cgraph_output_pending_asms (void);
145 static void cgraph_analyze_function (struct cgraph_node *);
147 static FILE *cgraph_dump_file;
149 /* A vector of FUNCTION_DECLs declared as static constructors. */
150 static GTY (()) VEC(tree, gc) *static_ctors;
151 /* A vector of FUNCTION_DECLs declared as static destructors. */
152 static GTY (()) VEC(tree, gc) *static_dtors;
154 /* Used for vtable lookup in thunk adjusting. */
155 static GTY (()) tree vtable_entry_type;
157 /* When target does not have ctors and dtors, we call all constructor
158 and destructor by special initialization/destruction function
159 recognized by collect2.
161 When we are going to build this function, collect all constructors and
162 destructors and turn them into normal functions. */
164 static void
165 record_cdtor_fn (tree fndecl)
167 struct cgraph_node *node;
168 if (targetm.have_ctors_dtors
169 || (!DECL_STATIC_CONSTRUCTOR (fndecl)
170 && !DECL_STATIC_DESTRUCTOR (fndecl)))
171 return;
173 if (DECL_STATIC_CONSTRUCTOR (fndecl))
175 VEC_safe_push (tree, gc, static_ctors, fndecl);
176 DECL_STATIC_CONSTRUCTOR (fndecl) = 0;
178 if (DECL_STATIC_DESTRUCTOR (fndecl))
180 VEC_safe_push (tree, gc, static_dtors, fndecl);
181 DECL_STATIC_DESTRUCTOR (fndecl) = 0;
183 node = cgraph_node (fndecl);
184 node->local.disregard_inline_limits = 1;
185 cgraph_mark_reachable_node (node);
188 /* Define global constructors/destructor functions for the CDTORS, of
189 which they are LEN. The CDTORS are sorted by initialization
190 priority. If CTOR_P is true, these are constructors; otherwise,
191 they are destructors. */
193 static void
194 build_cdtor (bool ctor_p, tree *cdtors, size_t len)
196 size_t i;
198 i = 0;
199 while (i < len)
201 tree body;
202 tree fn;
203 priority_type priority;
205 priority = 0;
206 body = NULL_TREE;
207 /* Find the next batch of constructors/destructors with the same
208 initialization priority. */
211 priority_type p;
212 fn = cdtors[i];
213 p = ctor_p ? DECL_INIT_PRIORITY (fn) : DECL_FINI_PRIORITY (fn);
214 if (!body)
215 priority = p;
216 else if (p != priority)
217 break;
218 append_to_statement_list (build_function_call_expr (UNKNOWN_LOCATION,
219 fn, 0),
220 &body);
221 ++i;
223 while (i < len);
224 gcc_assert (body != NULL_TREE);
225 /* Generate a function to call all the function of like
226 priority. */
227 cgraph_build_static_cdtor (ctor_p ? 'I' : 'D', body, priority);
231 /* Comparison function for qsort. P1 and P2 are actually of type
232 "tree *" and point to static constructors. DECL_INIT_PRIORITY is
233 used to determine the sort order. */
235 static int
236 compare_ctor (const void *p1, const void *p2)
238 tree f1;
239 tree f2;
240 int priority1;
241 int priority2;
243 f1 = *(const tree *)p1;
244 f2 = *(const tree *)p2;
245 priority1 = DECL_INIT_PRIORITY (f1);
246 priority2 = DECL_INIT_PRIORITY (f2);
248 if (priority1 < priority2)
249 return -1;
250 else if (priority1 > priority2)
251 return 1;
252 else
253 /* Ensure a stable sort. */
254 return (const tree *)p1 - (const tree *)p2;
257 /* Comparison function for qsort. P1 and P2 are actually of type
258 "tree *" and point to static destructors. DECL_FINI_PRIORITY is
259 used to determine the sort order. */
261 static int
262 compare_dtor (const void *p1, const void *p2)
264 tree f1;
265 tree f2;
266 int priority1;
267 int priority2;
269 f1 = *(const tree *)p1;
270 f2 = *(const tree *)p2;
271 priority1 = DECL_FINI_PRIORITY (f1);
272 priority2 = DECL_FINI_PRIORITY (f2);
274 if (priority1 < priority2)
275 return -1;
276 else if (priority1 > priority2)
277 return 1;
278 else
279 /* Ensure a stable sort. */
280 return (const tree *)p1 - (const tree *)p2;
283 /* Generate functions to call static constructors and destructors
284 for targets that do not support .ctors/.dtors sections. These
285 functions have magic names which are detected by collect2. */
287 static void
288 cgraph_build_cdtor_fns (void)
290 if (!VEC_empty (tree, static_ctors))
292 gcc_assert (!targetm.have_ctors_dtors);
293 qsort (VEC_address (tree, static_ctors),
294 VEC_length (tree, static_ctors),
295 sizeof (tree),
296 compare_ctor);
297 build_cdtor (/*ctor_p=*/true,
298 VEC_address (tree, static_ctors),
299 VEC_length (tree, static_ctors));
300 VEC_truncate (tree, static_ctors, 0);
303 if (!VEC_empty (tree, static_dtors))
305 gcc_assert (!targetm.have_ctors_dtors);
306 qsort (VEC_address (tree, static_dtors),
307 VEC_length (tree, static_dtors),
308 sizeof (tree),
309 compare_dtor);
310 build_cdtor (/*ctor_p=*/false,
311 VEC_address (tree, static_dtors),
312 VEC_length (tree, static_dtors));
313 VEC_truncate (tree, static_dtors, 0);
317 /* Determine if function DECL is needed. That is, visible to something
318 either outside this translation unit, something magic in the system
319 configury. */
321 bool
322 cgraph_decide_is_function_needed (struct cgraph_node *node, tree decl)
324 /* Auxiliary functions are only needed for inlining purpose. */
325 if (L_IPO_COMP_MODE && cgraph_is_auxiliary (decl))
326 return false;
328 /* If the user told us it is used, then it must be so. */
329 if (node->local.externally_visible)
330 return true;
332 /* ??? If the assembler name is set by hand, it is possible to assemble
333 the name later after finalizing the function and the fact is noticed
334 in assemble_name then. This is arguably a bug. */
335 if (DECL_ASSEMBLER_NAME_SET_P (decl)
336 && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
337 return true;
339 /* With -fkeep-inline-functions we are keeping all inline functions except
340 for extern inline ones. */
341 if (flag_keep_inline_functions
342 && DECL_DECLARED_INLINE_P (decl)
343 && !DECL_EXTERNAL (decl)
344 && !lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl)))
345 return true;
347 /* If we decided it was needed before, but at the time we didn't have
348 the body of the function available, then it's still needed. We have
349 to go back and re-check its dependencies now. */
350 if (node->needed)
351 return true;
353 /* Externally visible functions must be output. The exception is
354 COMDAT functions that must be output only when they are needed.
356 When not optimizing, also output the static functions. (see
357 PR24561), but don't do so for always_inline functions, functions
358 declared inline and nested functions. These was optimized out
359 in the original implementation and it is unclear whether we want
360 to change the behavior here. */
361 if (((TREE_PUBLIC (decl)
362 || (!optimize && !node->local.disregard_inline_limits
363 && !DECL_DECLARED_INLINE_P (decl)
364 && !node->origin))
365 && !flag_whole_program
366 && !flag_lto
367 && !flag_whopr)
368 && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
369 return true;
371 /* Constructors and destructors are reachable from the runtime by
372 some mechanism. */
373 if (DECL_STATIC_CONSTRUCTOR (decl) || DECL_STATIC_DESTRUCTOR (decl))
374 return true;
376 return false;
379 /* Process CGRAPH_NEW_FUNCTIONS and perform actions necessary to add these
380 functions into callgraph in a way so they look like ordinary reachable
381 functions inserted into callgraph already at construction time. */
383 bool
384 cgraph_process_new_functions (void)
386 bool output = false;
387 tree fndecl;
388 struct cgraph_node *node;
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);
446 return output;
449 /* As an GCC extension we allow redefinition of the function. The
450 semantics when both copies of bodies differ is not well defined.
451 We replace the old body with new body so in unit at a time mode
452 we always use new body, while in normal mode we may end up with
453 old body inlined into some functions and new body expanded and
454 inlined in others.
456 ??? It may make more sense to use one body for inlining and other
457 body for expanding the function but this is difficult to do. */
459 static void
460 cgraph_reset_node (struct cgraph_node *node)
462 /* If node->process is set, then we have already begun whole-unit analysis.
463 This is *not* testing for whether we've already emitted the function.
464 That case can be sort-of legitimately seen with real function redefinition
465 errors. I would argue that the front end should never present us with
466 such a case, but don't enforce that for now. */
467 gcc_assert (!node->process);
469 /* Reset our data structures so we can analyze the function again. */
470 memset (&node->local, 0, sizeof (node->local));
471 memset (&node->global, 0, sizeof (node->global));
472 memset (&node->rtl, 0, sizeof (node->rtl));
473 node->analyzed = false;
474 node->local.redefined_extern_inline = true;
475 node->local.finalized = false;
477 cgraph_node_remove_callees (node);
479 /* We may need to re-queue the node for assembling in case
480 we already proceeded it and ignored as not needed or got
481 a re-declaration in IMA mode. */
482 if (node->reachable)
484 struct cgraph_node *n;
486 for (n = cgraph_nodes_queue; n; n = n->next_needed)
487 if (n == node)
488 break;
489 if (!n)
490 node->reachable = 0;
494 static void
495 cgraph_lower_function (struct cgraph_node *node)
497 if (node->lowered)
498 return;
500 if (node->nested)
501 lower_nested_functions (node->decl);
502 gcc_assert (!node->nested);
504 tree_lowering_passes (node->decl);
505 node->lowered = true;
508 /* DECL has been parsed. Take it, queue it, compile it at the whim of the
509 logic in effect. If NESTED is true, then our caller cannot stand to have
510 the garbage collector run at the moment. We would need to either create
511 a new GC context, or just not compile right now. */
513 void
514 cgraph_finalize_function (tree decl, bool nested)
516 struct cgraph_node *node = cgraph_node (decl);
517 bool reset_needed = node->local.finalized;
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 /* For multi-module compilation, an inline function may be multiply
539 defined if it is a built-in. In one file, The decl may be marked
540 as needed (e.g., referenced), and analyzed (including inline parameter
541 computation) during function lowering invoked at the end of the file scope.
542 In the following scope, it may not be needed, thus won't be put into
543 the cgraph nodes queue for further analysis. Do it here. */
545 if (reset_needed
546 && L_IPO_IS_AUXILIARY_MODULE
547 && DECL_DECLARED_INLINE_P (node->decl))
548 cgraph_mark_reachable_node (node);
550 /* If we've not yet emitted decl, tell the debug info about it. */
551 if (!TREE_ASM_WRITTEN (decl))
552 (*debug_hooks->deferred_inline_function) (decl);
554 /* Possibly warn about unused parameters. */
555 if (warn_unused_parameter)
556 do_warn_unused_parameter (decl);
558 if (!nested)
559 ggc_collect ();
562 /* C99 extern inline keywords allow changing of declaration after function
563 has been finalized. We need to re-decide if we want to mark the function as
564 needed then. */
566 void
567 cgraph_mark_if_needed (tree decl)
569 struct cgraph_node *node = cgraph_node (decl);
570 if (node->local.finalized && cgraph_decide_is_function_needed (node, decl))
571 cgraph_mark_needed_node (node);
574 /* Return TRUE if NODE2 is equivalent to NODE or its clone. */
575 static bool
576 clone_of_p (struct cgraph_node *node, struct cgraph_node *node2)
578 while (node != node2 && node2)
579 node2 = node2->clone_of;
580 return node2 != NULL;
583 /* Verify cgraph nodes of given cgraph node. */
584 void
585 verify_cgraph_node (struct cgraph_node *node)
587 struct cgraph_edge *e;
588 struct function *this_cfun = DECL_STRUCT_FUNCTION (node->decl);
589 struct function *saved_cfun = cfun;
590 basic_block this_block;
591 gimple_stmt_iterator gsi;
592 bool error_found = false;
594 if (errorcount || sorrycount)
595 return;
597 timevar_push (TV_CGRAPH_VERIFY);
598 /* debug_generic_stmt needs correct cfun */
599 set_cfun (this_cfun);
600 for (e = node->callees; e; e = e->next_callee)
601 if (e->aux)
603 error ("aux field set for edge %s->%s",
604 identifier_to_locale (cgraph_node_name (e->caller)),
605 identifier_to_locale (cgraph_node_name (e->callee)));
606 error_found = true;
608 if (node->count < 0)
610 error ("Execution count is negative");
611 error_found = true;
613 if (node->global.inlined_to && node->local.externally_visible)
615 error ("Externally visible inline clone");
616 error_found = true;
618 if (node->global.inlined_to && node->address_taken)
620 error ("Inline clone with address taken");
621 error_found = true;
623 if (node->global.inlined_to && node->needed)
625 error ("Inline clone is needed");
626 error_found = true;
628 for (e = node->callers; e; e = e->next_caller)
630 if (e->count < 0)
632 error ("caller edge count is negative");
633 error_found = true;
635 if (e->frequency < 0)
637 error ("caller edge frequency is negative");
638 error_found = true;
640 if (e->frequency > CGRAPH_FREQ_MAX)
642 error ("caller edge frequency is too large");
643 error_found = true;
645 if (gimple_has_body_p (e->caller->decl)
646 && !e->caller->global.inlined_to
647 && e->call_stmt
648 && (e->frequency
649 != compute_call_stmt_bb_frequency (e->caller->decl,
650 gimple_bb (e->call_stmt)))
651 && !e->caller->clone_of)
653 error ("caller edge frequency %i does not match BB freqency %i",
654 e->frequency,
655 compute_call_stmt_bb_frequency (e->caller->decl,
656 gimple_bb (e->call_stmt)));
657 error_found = true;
659 if (!e->inline_failed)
661 if (node->global.inlined_to
662 != (e->caller->global.inlined_to
663 ? e->caller->global.inlined_to : e->caller))
665 error ("inlined_to pointer is wrong");
666 error_found = true;
668 if (node->callers->next_caller)
670 error ("multiple inline callers");
671 error_found = true;
674 else
675 if (node->global.inlined_to)
677 error ("inlined_to pointer set for noninline callers");
678 error_found = true;
681 if (!node->callers && node->global.inlined_to)
683 error ("inlined_to pointer is set but no predecessors found");
684 error_found = true;
686 if (node->global.inlined_to == node)
688 error ("inlined_to pointer refers to itself");
689 error_found = true;
692 if (!cgraph_node (node->decl))
694 error ("node not found in cgraph_hash");
695 error_found = true;
698 if (node->clone_of)
700 struct cgraph_node *n;
701 for (n = node->clone_of->clones; n; n = n->next_sibling_clone)
702 if (n == node)
703 break;
704 if (!n)
706 error ("node has wrong clone_of");
707 error_found = true;
710 if (node->clones)
712 struct cgraph_node *n;
713 for (n = node->clones; n; n = n->next_sibling_clone)
714 if (n->clone_of != node)
715 break;
716 if (n)
718 error ("node has wrong clone list");
719 error_found = true;
722 if ((node->prev_sibling_clone || node->next_sibling_clone) && !node->clone_of)
724 error ("node is in clone list but it is not clone");
725 error_found = true;
727 if (!node->prev_sibling_clone && node->clone_of && node->clone_of->clones != node)
729 error ("node has wrong prev_clone pointer");
730 error_found = true;
732 if (node->prev_sibling_clone && node->prev_sibling_clone->next_sibling_clone != node)
734 error ("double linked list of clones corrupted");
735 error_found = true;
737 if (node->same_comdat_group)
739 struct cgraph_node *n = node->same_comdat_group;
741 if (!DECL_ONE_ONLY (node->decl))
743 error ("non-DECL_ONE_ONLY node in a same_comdat_group list");
744 error_found = true;
746 if (n == node)
748 error ("node is alone in a comdat group");
749 error_found = true;
753 if (!n->same_comdat_group)
755 error ("same_comdat_group is not a circular list");
756 error_found = true;
757 break;
759 n = n->same_comdat_group;
761 while (n != node);
764 if (node->analyzed && gimple_has_body_p (node->decl)
765 && !cgraph_is_auxiliary (node->decl)
766 && !TREE_ASM_WRITTEN (node->decl)
767 && (!DECL_EXTERNAL (node->decl) || node->global.inlined_to)
768 && !flag_wpa)
770 if (this_cfun->cfg)
772 /* The nodes we're interested in are never shared, so walk
773 the tree ignoring duplicates. */
774 struct pointer_set_t *visited_nodes = pointer_set_create ();
775 /* Reach the trees by walking over the CFG, and note the
776 enclosing basic-blocks in the call edges. */
777 FOR_EACH_BB_FN (this_block, this_cfun)
778 for (gsi = gsi_start_bb (this_block);
779 !gsi_end_p (gsi);
780 gsi_next (&gsi))
782 gimple stmt = gsi_stmt (gsi);
783 tree decl;
784 if (is_gimple_call (stmt) && (decl = gimple_call_fndecl (stmt)))
786 struct cgraph_edge *e = cgraph_edge (node, stmt);
787 if (e)
789 if (e->aux)
791 error ("shared call_stmt:");
792 debug_gimple_stmt (stmt);
793 error_found = true;
795 if (e->callee->same_body_alias)
797 error ("edge points to same body alias:");
798 debug_tree (e->callee->decl);
799 error_found = true;
801 else if (!node->global.inlined_to
802 && !e->callee->global.inlined_to
803 && !clone_of_p (cgraph_node (decl), e->callee)
804 && (!L_IPO_COMP_MODE
805 || !clone_of_p (cgraph_lipo_get_resolved_node (decl),
806 e->callee)))
808 error ("edge points to wrong declaration:");
809 debug_tree (e->callee->decl);
810 fprintf (stderr," Instead of:");
811 debug_tree (decl);
812 error_found = true;
814 e->aux = (void *)1;
816 else
818 error ("missing callgraph edge for call stmt:");
819 debug_gimple_stmt (stmt);
820 error_found = true;
824 pointer_set_destroy (visited_nodes);
826 else
827 /* No CFG available?! */
828 gcc_unreachable ();
830 for (e = node->callees; e; e = e->next_callee)
832 if (!e->aux && !e->indirect_call)
834 error ("edge %s->%s has no corresponding call_stmt",
835 identifier_to_locale (cgraph_node_name (e->caller)),
836 identifier_to_locale (cgraph_node_name (e->callee)));
837 debug_gimple_stmt (e->call_stmt);
838 error_found = true;
840 e->aux = 0;
843 if (error_found)
845 dump_cgraph_node (stderr, node);
846 internal_error ("verify_cgraph_node failed");
848 set_cfun (saved_cfun);
849 timevar_pop (TV_CGRAPH_VERIFY);
852 /* Verify whole cgraph structure. */
853 void
854 verify_cgraph (void)
856 struct cgraph_node *node;
858 if (sorrycount || errorcount)
859 return;
861 for (node = cgraph_nodes; node; node = node->next)
862 verify_cgraph_node (node);
865 /* Output all asm statements we have stored up to be output. */
867 static void
868 cgraph_output_pending_asms (void)
870 struct cgraph_asm_node *can;
872 if (errorcount || sorrycount)
873 return;
875 for (can = cgraph_asm_nodes; can; can = can->next)
876 assemble_asm (can->asm_str);
877 cgraph_asm_nodes = NULL;
880 /* Analyze the function scheduled to be output. */
881 static void
882 cgraph_analyze_function (struct cgraph_node *node)
884 tree save = current_function_decl;
885 tree decl = node->decl;
887 current_function_decl = decl;
888 push_cfun (DECL_STRUCT_FUNCTION (decl));
890 assign_assembler_name_if_neeeded (node->decl);
892 /* Make sure to gimplify bodies only once. During analyzing a
893 function we lower it, which will require gimplified nested
894 functions, so we can end up here with an already gimplified
895 body. */
896 if (!gimple_body (decl))
897 gimplify_function_tree (decl);
898 dump_function (TDI_generic, decl);
900 cgraph_lower_function (node);
901 node->analyzed = true;
903 pop_cfun ();
904 current_function_decl = save;
907 /* Look for externally_visible and used attributes and mark cgraph nodes
908 accordingly.
910 We cannot mark the nodes at the point the attributes are processed (in
911 handle_*_attribute) because the copy of the declarations available at that
912 point may not be canonical. For example, in:
914 void f();
915 void f() __attribute__((used));
917 the declaration we see in handle_used_attribute will be the second
918 declaration -- but the front end will subsequently merge that declaration
919 with the original declaration and discard the second declaration.
921 Furthermore, we can't mark these nodes in cgraph_finalize_function because:
923 void f() {}
924 void f() __attribute__((externally_visible));
926 is valid.
928 So, we walk the nodes at the end of the translation unit, applying the
929 attributes at that point. */
931 static void
932 process_function_and_variable_attributes (struct cgraph_node *first,
933 struct varpool_node *first_var)
935 struct cgraph_node *node;
936 struct varpool_node *vnode;
938 for (node = cgraph_nodes; node != first; node = node->next)
940 tree decl = node->decl;
941 if (DECL_PRESERVE_P (decl))
943 mark_decl_referenced (decl);
944 if (node->local.finalized)
945 cgraph_mark_needed_node (node);
947 if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
949 if (! TREE_PUBLIC (node->decl))
950 warning_at (DECL_SOURCE_LOCATION (node->decl), OPT_Wattributes,
951 "%<externally_visible%>"
952 " attribute have effect only on public objects");
953 else if (node->local.finalized)
954 cgraph_mark_needed_node (node);
957 for (vnode = varpool_nodes; vnode != first_var; vnode = vnode->next)
959 tree decl = vnode->decl;
960 if (DECL_PRESERVE_P (decl))
962 mark_decl_referenced (decl);
963 vnode->force_output = true;
964 if (vnode->finalized)
965 varpool_mark_needed_node (vnode);
967 if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
969 if (! TREE_PUBLIC (vnode->decl))
970 warning_at (DECL_SOURCE_LOCATION (vnode->decl), OPT_Wattributes,
971 "%<externally_visible%>"
972 " attribute have effect only on public objects");
973 else if (vnode->finalized)
974 varpool_mark_needed_node (vnode);
979 /* Process CGRAPH_NODES_NEEDED queue, analyze each function (and transitively
980 each reachable functions) and build cgraph.
981 The function can be called multiple times after inserting new nodes
982 into beginning of queue. Just the new part of queue is re-scanned then. */
984 static void
985 cgraph_analyze_functions (void)
987 /* Keep track of already processed nodes when called multiple times for
988 intermodule optimization. */
989 static struct cgraph_node *first_analyzed;
990 struct cgraph_node *first_processed = first_analyzed;
991 static struct varpool_node *first_analyzed_var;
992 struct cgraph_node *node, *next;
994 process_function_and_variable_attributes (first_processed,
995 first_analyzed_var);
996 first_processed = cgraph_nodes;
997 first_analyzed_var = varpool_nodes;
998 varpool_analyze_pending_decls ();
999 if (cgraph_dump_file)
1001 fprintf (cgraph_dump_file, "Initial entry points:");
1002 for (node = cgraph_nodes; node != first_analyzed; node = node->next)
1003 if (node->needed)
1004 fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
1005 fprintf (cgraph_dump_file, "\n");
1007 cgraph_process_new_functions ();
1009 /* Propagate reachability flag and lower representation of all reachable
1010 functions. In the future, lowering will introduce new functions and
1011 new entry points on the way (by template instantiation and virtual
1012 method table generation for instance). */
1013 while (cgraph_nodes_queue)
1015 struct cgraph_edge *edge;
1016 tree decl = cgraph_nodes_queue->decl;
1018 node = cgraph_nodes_queue;
1019 cgraph_nodes_queue = cgraph_nodes_queue->next_needed;
1020 node->next_needed = NULL;
1022 /* ??? It is possible to create extern inline function and later using
1023 weak alias attribute to kill its body. See
1024 gcc.c-torture/compile/20011119-1.c */
1025 if (!DECL_STRUCT_FUNCTION (decl))
1027 cgraph_reset_node (node);
1028 continue;
1031 if (!node->analyzed)
1032 cgraph_analyze_function (node);
1034 for (edge = node->callees; edge; edge = edge->next_callee)
1035 if (!edge->callee->reachable)
1036 cgraph_mark_reachable_node (edge->callee);
1038 if (node->same_comdat_group)
1040 for (next = node->same_comdat_group;
1041 next != node;
1042 next = next->same_comdat_group)
1043 cgraph_mark_reachable_node (next);
1046 /* If decl is a clone of an abstract function, mark that abstract
1047 function so that we don't release its body. The DECL_INITIAL() of that
1048 abstract function declaration will be later needed to output debug info. */
1049 if (DECL_ABSTRACT_ORIGIN (decl))
1051 struct cgraph_node *origin_node = cgraph_node (DECL_ABSTRACT_ORIGIN (decl));
1052 origin_node->abstract_and_needed = true;
1055 /* We finalize local static variables during constructing callgraph
1056 edges. Process their attributes too. */
1057 process_function_and_variable_attributes (first_processed,
1058 first_analyzed_var);
1059 first_processed = cgraph_nodes;
1060 first_analyzed_var = varpool_nodes;
1061 varpool_analyze_pending_decls ();
1062 cgraph_process_new_functions ();
1065 /* Collect entry points to the unit. */
1066 if (cgraph_dump_file)
1068 fprintf (cgraph_dump_file, "Unit entry points:");
1069 for (node = cgraph_nodes; node != first_analyzed; node = node->next)
1070 if (node->needed)
1071 fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
1072 fprintf (cgraph_dump_file, "\n\nInitial ");
1073 dump_cgraph (cgraph_dump_file);
1076 if (cgraph_dump_file)
1077 fprintf (cgraph_dump_file, "\nReclaiming functions:");
1079 for (node = cgraph_nodes; node != first_analyzed; node = next)
1081 tree decl = node->decl;
1082 next = node->next;
1084 if (node->local.finalized && !gimple_has_body_p (decl))
1085 cgraph_reset_node (node);
1087 if (!node->reachable && gimple_has_body_p (decl))
1089 if (cgraph_dump_file)
1090 fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
1091 cgraph_remove_node (node);
1092 continue;
1094 else
1095 node->next_needed = NULL;
1096 gcc_assert (!node->local.finalized || gimple_has_body_p (decl));
1097 gcc_assert (node->analyzed == node->local.finalized);
1099 if (cgraph_dump_file)
1101 fprintf (cgraph_dump_file, "\n\nReclaimed ");
1102 dump_cgraph (cgraph_dump_file);
1104 first_analyzed = cgraph_nodes;
1105 ggc_collect ();
1109 /* Analyze the whole compilation unit once it is parsed completely. */
1111 void
1112 cgraph_finalize_compilation_unit (void)
1114 timevar_push (TV_CGRAPH);
1116 /* Do not skip analyzing the functions if there were errors, we
1117 miss diagnostics for following functions otherwise. */
1119 /* Emit size functions we didn't inline. */
1120 finalize_size_functions ();
1122 /* Call functions declared with the "constructor" or "destructor"
1123 attribute. */
1124 cgraph_build_cdtor_fns ();
1126 /* Mark alias targets necessary and emit diagnostics. */
1127 finish_aliases_1 ();
1129 if (!quiet_flag)
1131 fprintf (stderr, "\nAnalyzing compilation unit\n");
1132 fflush (stderr);
1135 /* Gimplify and lower all functions, compute reachability and
1136 remove unreachable nodes. */
1137 cgraph_analyze_functions ();
1139 /* Mark alias targets necessary and emit diagnostics. */
1140 finish_aliases_1 ();
1142 /* Gimplify and lower thunks. */
1143 cgraph_analyze_functions ();
1145 /* LIPO support */
1146 varpool_do_link ();
1147 /* Recognize equivalent types across modules and
1148 merge their alias sets. */
1149 cgraph_unify_type_alias_sets ();
1151 /* Finally drive the pass manager. */
1152 cgraph_optimize ();
1154 timevar_pop (TV_CGRAPH);
1157 /* Hash function for symbol (function) resolution. */
1159 static hashval_t
1160 hash_node_by_assembler_name (const void *p)
1162 const struct cgraph_node *n = (const struct cgraph_node *) p;
1163 return (hashval_t) decl_assembler_name_hash (DECL_ASSEMBLER_NAME (n->decl));
1166 /* Equality function for cgraph_node table. */
1168 static int
1169 eq_node_assembler_name (const void *p1, const void *p2)
1171 const struct cgraph_node *n1 = (const struct cgraph_node *) p1;
1172 const_tree name = (const_tree)p2;
1173 return (decl_assembler_name_equal (n1->decl, name));
1176 /* In l-ipo mode compilation (light weight IPO), multiple bodies may
1177 be available for the same inline declared function. cgraph linking
1178 does not really merge them in order to keep the context (module info)
1179 of each body. After inlining, the linkage of the function may require
1180 them to be output (even if it is defined in an auxiliary module). This
1181 in term may result in duplicate emission. */
1183 static GTY((param_is (struct cgraph_node))) htab_t output_node_hash = NULL;
1185 /* Add NODE that is expanded into the hashtable. */
1187 static struct cgraph_node *
1188 cgraph_add_output_node (struct cgraph_node *node)
1190 void **aslot;
1191 tree name;
1193 if (!L_IPO_COMP_MODE)
1194 return node;
1196 if (!TREE_PUBLIC (node->decl))
1197 return node;
1199 if (!output_node_hash)
1200 output_node_hash =
1201 htab_create_ggc (10, hash_node_by_assembler_name,
1202 eq_node_assembler_name, NULL);
1204 name = DECL_ASSEMBLER_NAME (node->decl);
1206 aslot = htab_find_slot_with_hash (output_node_hash, name,
1207 decl_assembler_name_hash (name),
1208 INSERT);
1209 if (*aslot == NULL)
1211 *aslot = node;
1212 return node;
1214 else
1215 return (struct cgraph_node *)(*aslot);
1218 /* Return the cgraph_node if the function symbol for NODE is
1219 expanded in the output. Returns NULL otherwise. */
1221 static struct cgraph_node *
1222 cgraph_find_output_node (struct cgraph_node *node)
1224 void **aslot;
1225 tree name;
1227 if (!L_IPO_COMP_MODE)
1228 return node;
1230 /* We do not track non-public functions. */
1231 if (!TREE_PUBLIC (node->decl))
1232 return NULL;
1234 /* Never addedd. */
1235 if (!output_node_hash)
1236 return NULL;
1238 name = DECL_ASSEMBLER_NAME (node->decl);
1240 aslot = htab_find_slot_with_hash (output_node_hash, name,
1241 decl_assembler_name_hash (name),
1242 NO_INSERT);
1243 if (!aslot)
1244 return NULL;
1246 return (struct cgraph_node *)(*aslot);
1250 /* A function used in validation. Return true if NODE was
1251 not expanded and its body was not reclaimed. */
1253 static bool
1254 cgraph_node_expansion_skipped (struct cgraph_node *node)
1256 struct cgraph_node *output_node;
1258 if (!L_IPO_COMP_MODE)
1259 return false;
1261 output_node = cgraph_find_output_node (node);
1263 if (output_node == node)
1264 return false;
1266 if (output_node)
1267 return true;
1269 /* No output, no duplicate being output, and the node is not
1270 inlined (and reclaimed) either -- check if the caller node
1271 is output/expanded or not. */
1272 if (node->global.inlined_to)
1273 return cgraph_node_expansion_skipped (node->global.inlined_to);
1275 /* External functions not marked for output. */
1276 return true;
1279 /* Figure out what functions we want to assemble. */
1281 static void
1282 cgraph_mark_functions_to_output (void)
1284 struct cgraph_node *node;
1285 #ifdef ENABLE_CHECKING
1286 bool check_same_comdat_groups = false;
1288 for (node = cgraph_nodes; node; node = node->next)
1289 gcc_assert (!node->process);
1290 #endif
1292 for (node = cgraph_nodes; node; node = node->next)
1294 tree decl = node->decl;
1295 struct cgraph_edge *e;
1297 gcc_assert (!node->process || node->same_comdat_group);
1298 if (node->process)
1299 continue;
1301 for (e = node->callers; e; e = e->next_caller)
1302 if (e->inline_failed)
1303 break;
1305 /* We need to output all local functions that are used and not
1306 always inlined, as well as those that are reachable from
1307 outside the current compilation unit. */
1308 if (node->analyzed
1309 && !node->global.inlined_to
1310 && (node->needed
1311 || (e && node->reachable))
1312 && !TREE_ASM_WRITTEN (decl)
1313 && !(DECL_EXTERNAL (decl) || cgraph_is_aux_decl_external (node)))
1315 if (cgraph_add_output_node (node) == node)
1317 node->process = 1;
1318 if (node->same_comdat_group)
1320 struct cgraph_node *next;
1321 for (next = node->same_comdat_group;
1322 next != node;
1323 next = next->same_comdat_group)
1324 next->process = 1;
1328 else if (node->same_comdat_group)
1330 #ifdef ENABLE_CHECKING
1331 check_same_comdat_groups = true;
1332 #endif
1334 else
1336 /* We should've reclaimed all functions that are not needed. */
1337 #ifdef ENABLE_CHECKING
1338 if (!node->global.inlined_to
1339 && gimple_has_body_p (decl)
1340 && !(DECL_EXTERNAL (decl) || cgraph_is_aux_decl_external (node)))
1342 dump_cgraph_node (stderr, node);
1343 internal_error ("failed to reclaim unneeded function");
1345 #endif
1346 gcc_assert (node->global.inlined_to
1347 || !gimple_has_body_p (decl)
1348 || (DECL_EXTERNAL (decl)
1349 || cgraph_is_aux_decl_external (node))
1350 || cgraph_is_auxiliary (node->decl));
1355 #ifdef ENABLE_CHECKING
1356 if (check_same_comdat_groups)
1357 for (node = cgraph_nodes; node; node = node->next)
1358 if (node->same_comdat_group && !node->process)
1360 tree decl = node->decl;
1361 if (!node->global.inlined_to
1362 && gimple_has_body_p (decl)
1363 && !DECL_EXTERNAL (decl))
1365 dump_cgraph_node (stderr, node);
1366 internal_error ("failed to reclaim unneeded function");
1369 #endif
1372 /* DECL is FUNCTION_DECL. Initialize datastructures so DECL is a function
1373 in lowered gimple form.
1375 Set current_function_decl and cfun to newly constructed empty function body.
1376 return basic block in the function body. */
1378 static basic_block
1379 init_lowered_empty_function (tree decl)
1381 basic_block bb;
1383 current_function_decl = decl;
1384 allocate_struct_function (decl, false);
1385 gimple_register_cfg_hooks ();
1386 init_empty_tree_cfg ();
1387 init_tree_ssa (cfun);
1388 init_ssa_operands ();
1389 cfun->gimple_df->in_ssa_p = true;
1390 DECL_INITIAL (decl) = make_node (BLOCK);
1392 DECL_SAVED_TREE (decl) = error_mark_node;
1393 cfun->curr_properties |=
1394 (PROP_gimple_lcf | PROP_gimple_leh | PROP_cfg | PROP_referenced_vars |
1395 PROP_ssa);
1397 /* Create BB for body of the function and connect it properly. */
1398 bb = create_basic_block (NULL, (void *) 0, ENTRY_BLOCK_PTR);
1399 make_edge (ENTRY_BLOCK_PTR, bb, 0);
1400 make_edge (bb, EXIT_BLOCK_PTR, 0);
1402 return bb;
1405 /* Adjust PTR by the constant FIXED_OFFSET, and by the vtable
1406 offset indicated by VIRTUAL_OFFSET, if that is
1407 non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and
1408 zero for a result adjusting thunk. */
1410 static tree
1411 thunk_adjust (gimple_stmt_iterator * bsi,
1412 tree ptr, bool this_adjusting,
1413 HOST_WIDE_INT fixed_offset, tree virtual_offset)
1415 gimple stmt;
1416 tree ret;
1418 if (this_adjusting
1419 && fixed_offset != 0)
1421 stmt = gimple_build_assign (ptr,
1422 fold_build2_loc (input_location,
1423 POINTER_PLUS_EXPR,
1424 TREE_TYPE (ptr), ptr,
1425 size_int (fixed_offset)));
1426 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1429 /* If there's a virtual offset, look up that value in the vtable and
1430 adjust the pointer again. */
1431 if (virtual_offset)
1433 tree vtabletmp;
1434 tree vtabletmp2;
1435 tree vtabletmp3;
1436 tree offsettmp;
1438 if (!vtable_entry_type)
1440 tree vfunc_type = make_node (FUNCTION_TYPE);
1441 TREE_TYPE (vfunc_type) = integer_type_node;
1442 TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
1443 layout_type (vfunc_type);
1445 vtable_entry_type = build_pointer_type (vfunc_type);
1448 vtabletmp =
1449 create_tmp_var (build_pointer_type
1450 (build_pointer_type (vtable_entry_type)), "vptr");
1452 /* The vptr is always at offset zero in the object. */
1453 stmt = gimple_build_assign (vtabletmp,
1454 build1 (NOP_EXPR, TREE_TYPE (vtabletmp),
1455 ptr));
1456 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1457 mark_symbols_for_renaming (stmt);
1458 find_referenced_vars_in (stmt);
1460 /* Form the vtable address. */
1461 vtabletmp2 = create_tmp_var (TREE_TYPE (TREE_TYPE (vtabletmp)),
1462 "vtableaddr");
1463 stmt = gimple_build_assign (vtabletmp2,
1464 build1 (INDIRECT_REF,
1465 TREE_TYPE (vtabletmp2), vtabletmp));
1466 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1467 mark_symbols_for_renaming (stmt);
1468 find_referenced_vars_in (stmt);
1470 /* Find the entry with the vcall offset. */
1471 stmt = gimple_build_assign (vtabletmp2,
1472 fold_build2_loc (input_location,
1473 POINTER_PLUS_EXPR,
1474 TREE_TYPE (vtabletmp2),
1475 vtabletmp2,
1476 fold_convert (sizetype,
1477 virtual_offset)));
1478 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1480 /* Get the offset itself. */
1481 vtabletmp3 = create_tmp_var (TREE_TYPE (TREE_TYPE (vtabletmp2)),
1482 "vcalloffset");
1483 stmt = gimple_build_assign (vtabletmp3,
1484 build1 (INDIRECT_REF,
1485 TREE_TYPE (vtabletmp3),
1486 vtabletmp2));
1487 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1488 mark_symbols_for_renaming (stmt);
1489 find_referenced_vars_in (stmt);
1491 /* Cast to sizetype. */
1492 offsettmp = create_tmp_var (sizetype, "offset");
1493 stmt = gimple_build_assign (offsettmp, fold_convert (sizetype, vtabletmp3));
1494 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1495 mark_symbols_for_renaming (stmt);
1496 find_referenced_vars_in (stmt);
1498 /* Adjust the `this' pointer. */
1499 ptr = fold_build2_loc (input_location,
1500 POINTER_PLUS_EXPR, TREE_TYPE (ptr), ptr,
1501 offsettmp);
1504 if (!this_adjusting
1505 && fixed_offset != 0)
1506 /* Adjust the pointer by the constant. */
1508 tree ptrtmp;
1510 if (TREE_CODE (ptr) == VAR_DECL)
1511 ptrtmp = ptr;
1512 else
1514 ptrtmp = create_tmp_var (TREE_TYPE (ptr), "ptr");
1515 stmt = gimple_build_assign (ptrtmp, ptr);
1516 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1517 mark_symbols_for_renaming (stmt);
1518 find_referenced_vars_in (stmt);
1520 ptr = fold_build2_loc (input_location,
1521 POINTER_PLUS_EXPR, TREE_TYPE (ptrtmp), ptrtmp,
1522 size_int (fixed_offset));
1525 /* Emit the statement and gimplify the adjustment expression. */
1526 ret = create_tmp_var (TREE_TYPE (ptr), "adjusted_this");
1527 stmt = gimple_build_assign (ret, ptr);
1528 mark_symbols_for_renaming (stmt);
1529 find_referenced_vars_in (stmt);
1530 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1532 return ret;
1535 /* Produce assembler for thunk NODE. */
1537 static void
1538 assemble_thunk (struct cgraph_node *node)
1540 bool this_adjusting = node->thunk.this_adjusting;
1541 HOST_WIDE_INT fixed_offset = node->thunk.fixed_offset;
1542 HOST_WIDE_INT virtual_value = node->thunk.virtual_value;
1543 tree virtual_offset = NULL;
1544 tree alias = node->thunk.alias;
1545 tree thunk_fndecl = node->decl;
1546 tree a = DECL_ARGUMENTS (thunk_fndecl);
1548 current_function_decl = thunk_fndecl;
1550 if (this_adjusting
1551 && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
1552 virtual_value, alias))
1554 const char *fnname;
1555 tree fn_block;
1557 DECL_RESULT (thunk_fndecl)
1558 = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl),
1559 RESULT_DECL, 0, integer_type_node);
1560 fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
1562 /* The back end expects DECL_INITIAL to contain a BLOCK, so we
1563 create one. */
1564 fn_block = make_node (BLOCK);
1565 BLOCK_VARS (fn_block) = a;
1566 DECL_INITIAL (thunk_fndecl) = fn_block;
1567 init_function_start (thunk_fndecl);
1568 cfun->is_thunk = 1;
1569 assemble_start_function (thunk_fndecl, fnname);
1571 targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl,
1572 fixed_offset, virtual_value, alias);
1574 assemble_end_function (thunk_fndecl, fnname);
1575 init_insn_lengths ();
1576 free_after_compilation (cfun);
1577 set_cfun (NULL);
1578 TREE_ASM_WRITTEN (thunk_fndecl) = 1;
1580 else
1582 tree restype;
1583 basic_block bb, then_bb, else_bb, return_bb;
1584 gimple_stmt_iterator bsi;
1585 int nargs = 0;
1586 tree arg;
1587 int i;
1588 tree resdecl;
1589 tree restmp = NULL;
1590 VEC(tree, heap) *vargs;
1592 gimple call;
1593 gimple ret;
1595 DECL_IGNORED_P (thunk_fndecl) = 1;
1596 bitmap_obstack_initialize (NULL);
1598 if (node->thunk.virtual_offset_p)
1599 virtual_offset = size_int (virtual_value);
1601 /* Build the return declaration for the function. */
1602 restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1603 if (DECL_RESULT (thunk_fndecl) == NULL_TREE)
1605 resdecl = build_decl (input_location, RESULT_DECL, 0, restype);
1606 DECL_ARTIFICIAL (resdecl) = 1;
1607 DECL_IGNORED_P (resdecl) = 1;
1608 DECL_RESULT (thunk_fndecl) = resdecl;
1610 else
1611 resdecl = DECL_RESULT (thunk_fndecl);
1613 bb = then_bb = else_bb = return_bb = init_lowered_empty_function (thunk_fndecl);
1615 bsi = gsi_start_bb (bb);
1617 /* Build call to the function being thunked. */
1618 if (!VOID_TYPE_P (restype))
1620 if (!is_gimple_reg_type (restype))
1622 restmp = resdecl;
1623 cfun->local_decls = tree_cons (NULL_TREE, restmp, cfun->local_decls);
1624 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp;
1626 else
1627 restmp = create_tmp_var_raw (restype, "retval");
1630 for (arg = a; arg; arg = TREE_CHAIN (arg))
1631 nargs++;
1632 vargs = VEC_alloc (tree, heap, nargs);
1633 if (this_adjusting)
1634 VEC_quick_push (tree, vargs,
1635 thunk_adjust (&bsi,
1636 a, 1, fixed_offset,
1637 virtual_offset));
1638 else
1639 VEC_quick_push (tree, vargs, a);
1640 for (i = 1, arg = TREE_CHAIN (a); i < nargs; i++, arg = TREE_CHAIN (arg))
1641 VEC_quick_push (tree, vargs, arg);
1642 call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs);
1643 VEC_free (tree, heap, vargs);
1644 gimple_call_set_cannot_inline (call, true);
1645 gimple_call_set_from_thunk (call, true);
1646 if (restmp)
1647 gimple_call_set_lhs (call, restmp);
1648 gsi_insert_after (&bsi, call, GSI_NEW_STMT);
1649 mark_symbols_for_renaming (call);
1650 find_referenced_vars_in (call);
1651 update_stmt (call);
1653 if (restmp && !this_adjusting)
1655 tree true_label = NULL_TREE;
1657 if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE)
1659 gimple stmt;
1660 /* If the return type is a pointer, we need to
1661 protect against NULL. We know there will be an
1662 adjustment, because that's why we're emitting a
1663 thunk. */
1664 then_bb = create_basic_block (NULL, (void *) 0, bb);
1665 return_bb = create_basic_block (NULL, (void *) 0, then_bb);
1666 else_bb = create_basic_block (NULL, (void *) 0, else_bb);
1667 remove_edge (single_succ_edge (bb));
1668 true_label = gimple_block_label (then_bb);
1669 stmt = gimple_build_cond (NE_EXPR, restmp,
1670 fold_convert (TREE_TYPE (restmp),
1671 integer_zero_node),
1672 NULL_TREE, NULL_TREE);
1673 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1674 make_edge (bb, then_bb, EDGE_TRUE_VALUE);
1675 make_edge (bb, else_bb, EDGE_FALSE_VALUE);
1676 make_edge (return_bb, EXIT_BLOCK_PTR, 0);
1677 make_edge (then_bb, return_bb, EDGE_FALLTHRU);
1678 make_edge (else_bb, return_bb, EDGE_FALLTHRU);
1679 bsi = gsi_last_bb (then_bb);
1682 restmp = thunk_adjust (&bsi, restmp, /*this_adjusting=*/0,
1683 fixed_offset, virtual_offset);
1684 if (true_label)
1686 gimple stmt;
1687 bsi = gsi_last_bb (else_bb);
1688 stmt = gimple_build_assign (restmp, fold_convert (TREE_TYPE (restmp),
1689 integer_zero_node));
1690 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1691 bsi = gsi_last_bb (return_bb);
1694 else
1695 gimple_call_set_tail (call, true);
1697 /* Build return value. */
1698 ret = gimple_build_return (restmp);
1699 gsi_insert_after (&bsi, ret, GSI_NEW_STMT);
1701 delete_unreachable_blocks ();
1702 update_ssa (TODO_update_ssa);
1704 cgraph_remove_same_body_alias (node);
1705 /* Since we want to emit the thunk, we explicitly mark its name as
1706 referenced. */
1707 mark_decl_referenced (thunk_fndecl);
1708 cgraph_add_new_function (thunk_fndecl, true);
1709 bitmap_obstack_release (NULL);
1711 current_function_decl = NULL;
1714 /* Expand function specified by NODE. */
1716 static void
1717 cgraph_expand_function (struct cgraph_node *node)
1719 tree decl = node->decl;
1721 /* We ought to not compile any inline clones. */
1722 gcc_assert (!node->global.inlined_to);
1724 announce_function (decl);
1725 node->process = 0;
1727 gcc_assert (node->lowered);
1729 /* Generate RTL for the body of DECL. */
1730 tree_rest_of_compilation (decl);
1732 /* Make sure that BE didn't give up on compiling. */
1733 gcc_assert (TREE_ASM_WRITTEN (decl));
1734 current_function_decl = NULL;
1735 if (node->same_body)
1737 struct cgraph_node *alias, *next;
1738 bool saved_alias = node->alias;
1739 for (alias = node->same_body;
1740 alias && alias->next; alias = alias->next)
1742 /* Walk aliases in the order they were created; it is possible that
1743 thunks reffers to the aliases made earlier. */
1744 for (; alias; alias = next)
1746 next = alias->previous;
1747 if (!alias->thunk.thunk_p)
1748 assemble_alias (alias->decl,
1749 DECL_ASSEMBLER_NAME (alias->thunk.alias));
1750 else
1751 assemble_thunk (alias);
1753 node->alias = saved_alias;
1755 gcc_assert (!cgraph_preserve_function_body_p (decl));
1756 cgraph_release_function_body (node);
1757 /* Eliminate all call edges. This is important so the GIMPLE_CALL no longer
1758 points to the dead function body. */
1759 cgraph_node_remove_callees (node);
1761 cgraph_function_flags_ready = true;
1764 /* Return true when CALLER_DECL should be inlined into CALLEE_DECL. */
1766 bool
1767 cgraph_inline_p (struct cgraph_edge *e, cgraph_inline_failed_t *reason)
1769 *reason = e->inline_failed;
1770 return !e->inline_failed;
1775 /* Expand all functions that must be output.
1777 Attempt to topologically sort the nodes so function is output when
1778 all called functions are already assembled to allow data to be
1779 propagated across the callgraph. Use a stack to get smaller distance
1780 between a function and its callees (later we may choose to use a more
1781 sophisticated algorithm for function reordering; we will likely want
1782 to use subsections to make the output functions appear in top-down
1783 order). */
1785 static void
1786 cgraph_expand_all_functions (void)
1788 struct cgraph_node *node;
1789 struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
1790 int order_pos, new_order_pos = 0;
1791 int i;
1793 order_pos = cgraph_postorder (order);
1794 gcc_assert (order_pos == cgraph_n_nodes);
1796 /* Garbage collector may remove inline clones we eliminate during
1797 optimization. So we must be sure to not reference them. */
1798 for (i = 0; i < order_pos; i++)
1799 if (order[i]->process)
1800 order[new_order_pos++] = order[i];
1802 for (i = new_order_pos - 1; i >= 0; i--)
1804 node = order[i];
1805 if (node->process)
1807 gcc_assert (node->reachable);
1808 node->process = 0;
1809 cgraph_expand_function (node);
1812 cgraph_process_new_functions ();
1814 free (order);
1818 /* This is used to sort the node types by the cgraph order number. */
1820 enum cgraph_order_sort_kind
1822 ORDER_UNDEFINED = 0,
1823 ORDER_FUNCTION,
1824 ORDER_VAR,
1825 ORDER_ASM
1828 struct cgraph_order_sort
1830 enum cgraph_order_sort_kind kind;
1831 union
1833 struct cgraph_node *f;
1834 struct varpool_node *v;
1835 struct cgraph_asm_node *a;
1836 } u;
1839 /* Output all functions, variables, and asm statements in the order
1840 according to their order fields, which is the order in which they
1841 appeared in the file. This implements -fno-toplevel-reorder. In
1842 this mode we may output functions and variables which don't really
1843 need to be output. */
1845 static void
1846 cgraph_output_in_order (void)
1848 int max;
1849 struct cgraph_order_sort *nodes;
1850 int i;
1851 struct cgraph_node *pf;
1852 struct varpool_node *pv;
1853 struct cgraph_asm_node *pa;
1855 max = cgraph_order;
1856 nodes = XCNEWVEC (struct cgraph_order_sort, max);
1858 varpool_analyze_pending_decls ();
1859 varpool_remove_duplicate_weak_decls ();
1861 for (pf = cgraph_nodes; pf; pf = pf->next)
1863 if (pf->process)
1865 i = pf->order;
1866 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1867 nodes[i].kind = ORDER_FUNCTION;
1868 nodes[i].u.f = pf;
1872 for (pv = varpool_nodes_queue; pv; pv = pv->next_needed)
1874 i = pv->order;
1875 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1876 nodes[i].kind = ORDER_VAR;
1877 nodes[i].u.v = pv;
1880 for (pa = cgraph_asm_nodes; pa; pa = pa->next)
1882 i = pa->order;
1883 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1884 nodes[i].kind = ORDER_ASM;
1885 nodes[i].u.a = pa;
1888 /* In toplevel reorder mode we output all statics; mark them as needed. */
1889 for (i = 0; i < max; ++i)
1891 if (nodes[i].kind == ORDER_VAR)
1893 varpool_mark_needed_node (nodes[i].u.v);
1896 varpool_empty_needed_queue ();
1898 for (i = 0; i < max; ++i)
1900 switch (nodes[i].kind)
1902 case ORDER_FUNCTION:
1903 nodes[i].u.f->process = 0;
1904 cgraph_expand_function (nodes[i].u.f);
1905 break;
1907 case ORDER_VAR:
1908 varpool_assemble_decl (nodes[i].u.v);
1909 break;
1911 case ORDER_ASM:
1912 assemble_asm (nodes[i].u.a->asm_str);
1913 break;
1915 case ORDER_UNDEFINED:
1916 break;
1918 default:
1919 gcc_unreachable ();
1923 cgraph_asm_nodes = NULL;
1924 free (nodes);
1927 /* Return true when function body of DECL still needs to be kept around
1928 for later re-use. */
1929 bool
1930 cgraph_preserve_function_body_p (tree decl)
1932 struct cgraph_node *node;
1934 gcc_assert (cgraph_global_info_ready);
1935 /* Look if there is any clone around. */
1936 node = cgraph_node (decl);
1937 if (node->clones)
1938 return true;
1939 return false;
1942 static void
1943 ipa_passes (void)
1945 set_cfun (NULL);
1946 current_function_decl = NULL;
1947 gimple_register_cfg_hooks ();
1948 bitmap_obstack_initialize (NULL);
1950 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START, NULL);
1952 if (!in_lto_p)
1953 execute_ipa_pass_list (all_small_ipa_passes);
1955 /* If pass_all_early_optimizations was not scheduled, the state of
1956 the cgraph will not be properly updated. Update it now. */
1957 if (cgraph_state < CGRAPH_STATE_IPA_SSA)
1958 cgraph_state = CGRAPH_STATE_IPA_SSA;
1960 if (!in_lto_p)
1962 /* Generate coverage variables and constructors.
1963 In LIPO mode, delay this until direct call profiling
1964 is done. */
1965 if (!flag_dyn_ipa)
1966 coverage_finish ();
1968 /* Process new functions added. */
1969 set_cfun (NULL);
1970 current_function_decl = NULL;
1971 cgraph_process_new_functions ();
1973 execute_ipa_summary_passes
1974 ((struct ipa_opt_pass_d *) all_regular_ipa_passes);
1976 execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_lto_gen_passes);
1978 if (!in_lto_p)
1979 ipa_write_summaries ();
1981 if (!flag_ltrans)
1982 execute_ipa_pass_list (all_regular_ipa_passes);
1983 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END, NULL);
1985 bitmap_obstack_release (NULL);
1989 /* Perform simple optimizations based on callgraph. */
1991 void
1992 cgraph_optimize (void)
1994 if (errorcount || sorrycount)
1995 return;
1997 #ifdef ENABLE_CHECKING
1998 verify_cgraph ();
1999 #endif
2001 /* Frontend may output common variables after the unit has been finalized.
2002 It is safe to deal with them here as they are always zero initialized. */
2003 varpool_analyze_pending_decls ();
2005 timevar_push (TV_CGRAPHOPT);
2006 if (pre_ipa_mem_report)
2008 fprintf (stderr, "Memory consumption before IPA\n");
2009 dump_memory_report (false);
2011 if (!quiet_flag)
2012 fprintf (stderr, "Performing interprocedural optimizations\n");
2013 cgraph_state = CGRAPH_STATE_IPA;
2015 if (L_IPO_COMP_MODE)
2017 cgraph_init_gid_map ();
2018 cgraph_add_fake_indirect_call_edges ();
2019 /* Perform static promotion before IPA passes to avoid
2020 needed static functions being deleted. */
2021 cgraph_process_module_scope_statics ();
2024 /* Don't run the IPA passes if there was any error or sorry messages. */
2025 if (errorcount == 0 && sorrycount == 0)
2026 ipa_passes ();
2028 /* Do nothing else if any IPA pass found errors. */
2029 if (errorcount || sorrycount)
2031 timevar_pop (TV_CGRAPHOPT);
2032 return;
2035 /* This pass remove bodies of extern inline functions we never inlined.
2036 Do this later so other IPA passes see what is really going on. */
2037 cgraph_remove_unreachable_nodes (false, dump_file);
2038 cgraph_global_info_ready = true;
2039 if (cgraph_dump_file)
2041 fprintf (cgraph_dump_file, "Optimized ");
2042 dump_cgraph (cgraph_dump_file);
2043 dump_varpool (cgraph_dump_file);
2045 if (post_ipa_mem_report)
2047 fprintf (stderr, "Memory consumption after IPA\n");
2048 dump_memory_report (false);
2050 timevar_pop (TV_CGRAPHOPT);
2052 /* Output everything. */
2053 (*debug_hooks->assembly_start) ();
2054 if (!quiet_flag)
2055 fprintf (stderr, "Assembling functions:\n");
2056 #ifdef ENABLE_CHECKING
2057 verify_cgraph ();
2058 #endif
2060 cgraph_materialize_all_clones ();
2061 cgraph_mark_functions_to_output ();
2063 cgraph_state = CGRAPH_STATE_EXPANSION;
2064 if (!flag_toplevel_reorder)
2065 cgraph_output_in_order ();
2066 else
2068 cgraph_output_pending_asms ();
2070 cgraph_expand_all_functions ();
2071 varpool_remove_unreferenced_decls ();
2072 varpool_remove_duplicate_weak_decls ();
2074 varpool_assemble_pending_decls ();
2076 cgraph_process_new_functions ();
2077 cgraph_state = CGRAPH_STATE_FINISHED;
2079 if (cgraph_dump_file)
2081 fprintf (cgraph_dump_file, "\nFinal ");
2082 dump_cgraph (cgraph_dump_file);
2084 #ifdef ENABLE_CHECKING
2085 verify_cgraph ();
2086 /* Double check that all inline clones are gone and that all
2087 function bodies have been released from memory.
2088 As an exception, allow inline clones in the callgraph if
2089 they are auxiliary functions. This is because we don't
2090 expand any of the auxiliary functions, which may result
2091 in inline clones of some auxiliary functions to be left
2092 in the callgraph. */
2093 if (!(sorrycount || errorcount))
2095 struct cgraph_node *node;
2096 bool error_found = false;
2098 for (node = cgraph_nodes; node; node = node->next)
2099 if (node->analyzed
2100 && ((node->global.inlined_to && !cgraph_is_auxiliary (node->decl))
2101 || gimple_has_body_p (node->decl))
2102 && !cgraph_node_expansion_skipped (node))
2104 error_found = true;
2105 dump_cgraph_node (stderr, node);
2107 if (error_found)
2108 internal_error ("nodes with unreleased memory found");
2110 #endif
2114 /* Generate and emit a static constructor or destructor. WHICH must
2115 be one of 'I' (for a constructor) or 'D' (for a destructor). BODY
2116 is a STATEMENT_LIST containing GENERIC statements. PRIORITY is the
2117 initialization priority for this constructor or destructor. */
2119 void
2120 cgraph_build_static_cdtor (char which, tree body, int priority)
2122 static int counter = 0;
2123 char which_buf[16];
2124 tree decl, name, resdecl;
2126 /* The priority is encoded in the constructor or destructor name.
2127 collect2 will sort the names and arrange that they are called at
2128 program startup. */
2129 sprintf (which_buf, "%c_%.5d_%d", which, priority, counter++);
2130 name = get_file_function_name (which_buf);
2132 decl = build_decl (input_location, FUNCTION_DECL, name,
2133 build_function_type (void_type_node, void_list_node));
2134 current_function_decl = decl;
2136 resdecl = build_decl (input_location,
2137 RESULT_DECL, NULL_TREE, void_type_node);
2138 DECL_ARTIFICIAL (resdecl) = 1;
2139 DECL_RESULT (decl) = resdecl;
2140 DECL_CONTEXT (resdecl) = decl;
2142 allocate_struct_function (decl, false);
2144 TREE_STATIC (decl) = 1;
2145 TREE_USED (decl) = 1;
2146 DECL_ARTIFICIAL (decl) = 1;
2147 DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;
2148 DECL_SAVED_TREE (decl) = body;
2149 if (!targetm.have_ctors_dtors)
2151 TREE_PUBLIC (decl) = 1;
2152 DECL_PRESERVE_P (decl) = 1;
2154 DECL_UNINLINABLE (decl) = 1;
2156 DECL_INITIAL (decl) = make_node (BLOCK);
2157 TREE_USED (DECL_INITIAL (decl)) = 1;
2159 DECL_SOURCE_LOCATION (decl) = input_location;
2160 cfun->function_end_locus = input_location;
2162 switch (which)
2164 case 'I':
2165 DECL_STATIC_CONSTRUCTOR (decl) = 1;
2166 decl_init_priority_insert (decl, priority);
2167 break;
2168 case 'D':
2169 DECL_STATIC_DESTRUCTOR (decl) = 1;
2170 decl_fini_priority_insert (decl, priority);
2171 break;
2172 default:
2173 gcc_unreachable ();
2176 gimplify_function_tree (decl);
2178 cgraph_add_new_function (decl, false);
2179 cgraph_mark_needed_node (cgraph_node (decl));
2180 set_cfun (NULL);
2183 void
2184 init_cgraph (void)
2186 cgraph_dump_file = dump_begin (TDI_cgraph, NULL);
2189 /* The edges representing the callers of the NEW_VERSION node were
2190 fixed by cgraph_function_versioning (), now the call_expr in their
2191 respective tree code should be updated to call the NEW_VERSION. */
2193 static void
2194 update_call_expr (struct cgraph_node *new_version)
2196 struct cgraph_edge *e;
2198 gcc_assert (new_version);
2200 /* Update the call expr on the edges to call the new version. */
2201 for (e = new_version->callers; e; e = e->next_caller)
2203 struct function *inner_function = DECL_STRUCT_FUNCTION (e->caller->decl);
2204 gimple_call_set_fndecl (e->call_stmt, new_version->decl);
2205 maybe_clean_eh_stmt_fn (inner_function, e->call_stmt);
2210 /* Create a new cgraph node which is the new version of
2211 OLD_VERSION node. REDIRECT_CALLERS holds the callers
2212 edges which should be redirected to point to
2213 NEW_VERSION. ALL the callees edges of OLD_VERSION
2214 are cloned to the new version node. Return the new
2215 version node. */
2217 static struct cgraph_node *
2218 cgraph_copy_node_for_versioning (struct cgraph_node *old_version,
2219 tree new_decl,
2220 VEC(cgraph_edge_p,heap) *redirect_callers)
2222 struct cgraph_node *new_version;
2223 struct cgraph_edge *e, *new_e;
2224 struct cgraph_edge *next_callee;
2225 unsigned i;
2227 gcc_assert (old_version);
2229 new_version = cgraph_node (new_decl);
2231 new_version->analyzed = true;
2232 new_version->local = old_version->local;
2233 new_version->global = old_version->global;
2234 new_version->rtl = new_version->rtl;
2235 new_version->reachable = true;
2236 new_version->count = old_version->count;
2237 new_version->is_versioned_clone = true;
2239 /* Clone the old node callees. Recursive calls are
2240 also cloned. */
2241 for (e = old_version->callees;e; e=e->next_callee)
2243 new_e = cgraph_clone_edge (e, new_version, e->call_stmt,
2244 e->lto_stmt_uid, 0, e->frequency,
2245 e->loop_nest, true);
2246 new_e->count = e->count;
2248 /* Fix recursive calls.
2249 If OLD_VERSION has a recursive call after the
2250 previous edge cloning, the new version will have an edge
2251 pointing to the old version, which is wrong;
2252 Redirect it to point to the new version. */
2253 for (e = new_version->callees ; e; e = next_callee)
2255 next_callee = e->next_callee;
2256 if (e->callee == old_version)
2257 cgraph_redirect_edge_callee (e, new_version);
2259 if (!next_callee)
2260 break;
2262 for (i = 0; VEC_iterate (cgraph_edge_p, redirect_callers, i, e); i++)
2264 /* Redirect calls to the old version node to point to its new
2265 version. */
2266 cgraph_redirect_edge_callee (e, new_version);
2269 return new_version;
2272 /* Perform function versioning.
2273 Function versioning includes copying of the tree and
2274 a callgraph update (creating a new cgraph node and updating
2275 its callees and callers).
2277 REDIRECT_CALLERS varray includes the edges to be redirected
2278 to the new version.
2280 TREE_MAP is a mapping of tree nodes we want to replace with
2281 new ones (according to results of prior analysis).
2282 OLD_VERSION_NODE is the node that is versioned.
2283 It returns the new version's cgraph node.
2284 ARGS_TO_SKIP lists arguments to be omitted from functions
2287 struct cgraph_node *
2288 cgraph_function_versioning (struct cgraph_node *old_version_node,
2289 VEC(cgraph_edge_p,heap) *redirect_callers,
2290 VEC (ipa_replace_map_p,gc)* tree_map,
2291 bitmap args_to_skip)
2293 tree old_decl = old_version_node->decl;
2294 struct cgraph_node *new_version_node = NULL;
2295 tree new_decl;
2297 if (!tree_versionable_function_p (old_decl))
2298 return NULL;
2300 /* Make a new FUNCTION_DECL tree node for the
2301 new version. */
2302 if (!args_to_skip)
2303 new_decl = copy_node (old_decl);
2304 else
2305 new_decl = build_function_decl_skip_args (old_decl, args_to_skip);
2307 /* Create the new version's call-graph node.
2308 and update the edges of the new node. */
2309 new_version_node =
2310 cgraph_copy_node_for_versioning (old_version_node, new_decl,
2311 redirect_callers);
2313 /* Copy the OLD_VERSION_NODE function tree to the new version. */
2314 tree_function_versioning (old_decl, new_decl, tree_map, false, args_to_skip);
2316 /* Update the new version's properties.
2317 Make The new version visible only within this translation unit. Make sure
2318 that is not weak also.
2319 ??? We cannot use COMDAT linkage because there is no
2320 ABI support for this. */
2321 cgraph_make_decl_local (new_version_node->decl);
2322 DECL_VIRTUAL_P (new_version_node->decl) = 0;
2323 new_version_node->local.externally_visible = 0;
2324 new_version_node->local.local = 1;
2325 new_version_node->lowered = true;
2327 /* Update the call_expr on the edges to call the new version node. */
2328 update_call_expr (new_version_node);
2330 cgraph_call_function_insertion_hooks (new_version_node);
2331 return new_version_node;
2334 /* Produce separate function body for inline clones so the offline copy can be
2335 modified without affecting them. */
2336 struct cgraph_node *
2337 save_inline_function_body (struct cgraph_node *node)
2339 struct cgraph_node *first_clone, *n;
2341 gcc_assert (node == cgraph_node (node->decl));
2343 cgraph_lower_function (node);
2345 first_clone = node->clones;
2347 first_clone->decl = copy_node (node->decl);
2348 cgraph_insert_node_to_hashtable (first_clone);
2349 gcc_assert (first_clone == cgraph_node (first_clone->decl));
2350 if (first_clone->next_sibling_clone)
2352 for (n = first_clone->next_sibling_clone; n->next_sibling_clone; n = n->next_sibling_clone)
2353 n->clone_of = first_clone;
2354 n->clone_of = first_clone;
2355 n->next_sibling_clone = first_clone->clones;
2356 if (first_clone->clones)
2357 first_clone->clones->prev_sibling_clone = n;
2358 first_clone->clones = first_clone->next_sibling_clone;
2359 first_clone->next_sibling_clone->prev_sibling_clone = NULL;
2360 first_clone->next_sibling_clone = NULL;
2361 gcc_assert (!first_clone->prev_sibling_clone);
2363 first_clone->clone_of = NULL;
2364 node->clones = NULL;
2366 if (first_clone->clones)
2367 for (n = first_clone->clones; n != first_clone;)
2369 gcc_assert (n->decl == node->decl);
2370 n->decl = first_clone->decl;
2371 if (n->clones)
2372 n = n->clones;
2373 else if (n->next_sibling_clone)
2374 n = n->next_sibling_clone;
2375 else
2377 while (n != first_clone && !n->next_sibling_clone)
2378 n = n->clone_of;
2379 if (n != first_clone)
2380 n = n->next_sibling_clone;
2384 /* Copy the OLD_VERSION_NODE function tree to the new version. */
2385 tree_function_versioning (node->decl, first_clone->decl, NULL, true, NULL);
2387 DECL_EXTERNAL (first_clone->decl) = 0;
2388 DECL_COMDAT_GROUP (first_clone->decl) = NULL_TREE;
2389 TREE_PUBLIC (first_clone->decl) = 0;
2390 DECL_COMDAT (first_clone->decl) = 0;
2391 VEC_free (ipa_opt_pass, heap,
2392 first_clone->ipa_transforms_to_apply);
2393 first_clone->ipa_transforms_to_apply = NULL;
2395 #ifdef ENABLE_CHECKING
2396 verify_cgraph_node (first_clone);
2397 #endif
2398 return first_clone;
2401 /* Given virtual clone, turn it into actual clone. */
2402 static void
2403 cgraph_materialize_clone (struct cgraph_node *node)
2405 bitmap_obstack_initialize (NULL);
2406 /* Copy the OLD_VERSION_NODE function tree to the new version. */
2407 tree_function_versioning (node->clone_of->decl, node->decl,
2408 node->clone.tree_map, true,
2409 node->clone.args_to_skip);
2410 if (cgraph_dump_file)
2412 dump_function_to_file (node->clone_of->decl, cgraph_dump_file, dump_flags);
2413 dump_function_to_file (node->decl, cgraph_dump_file, dump_flags);
2416 /* Function is no longer clone. */
2417 if (node->next_sibling_clone)
2418 node->next_sibling_clone->prev_sibling_clone = node->prev_sibling_clone;
2419 if (node->prev_sibling_clone)
2420 node->prev_sibling_clone->next_sibling_clone = node->next_sibling_clone;
2421 else
2422 node->clone_of->clones = node->next_sibling_clone;
2423 node->next_sibling_clone = NULL;
2424 node->prev_sibling_clone = NULL;
2425 if (!node->clone_of->analyzed && !node->clone_of->clones)
2426 cgraph_remove_node (node->clone_of);
2427 node->clone_of = NULL;
2428 bitmap_obstack_release (NULL);
2431 /* Return the root node of clone tree. */
2433 static inline struct cgraph_node *
2434 get_clone_orig_node (struct cgraph_node *node)
2436 while (node->clone_of
2437 && node->decl == node->clone_of->decl)
2438 node = node->clone_of;
2439 return node;
2442 /* If necessary, change the function declaration in the call statement
2443 associated with E so that it corresponds to the edge callee. */
2445 gimple
2446 cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *e)
2448 tree decl = gimple_call_fndecl (e->call_stmt);
2449 gimple new_stmt;
2450 gimple_stmt_iterator gsi;
2452 if (!decl || decl == e->callee->decl
2453 /* Don't update call from same body alias to the real function. */
2454 || cgraph_get_node (decl) == cgraph_get_node (e->callee->decl)
2455 || (L_IPO_COMP_MODE
2456 && (cgraph_lipo_get_resolved_node (decl)
2457 == cgraph_lipo_get_resolved_node (e->callee->decl))))
2458 return e->call_stmt;
2460 if (cgraph_dump_file)
2462 fprintf (cgraph_dump_file, "updating call of %s/%i -> %s/%i: ",
2463 cgraph_node_name (e->caller), e->caller->uid,
2464 cgraph_node_name (e->callee), e->callee->uid);
2465 print_gimple_stmt (cgraph_dump_file, e->call_stmt, 0, dump_flags);
2468 if (e->callee->clone.combined_args_to_skip)
2469 new_stmt = gimple_call_copy_skip_args (e->call_stmt,
2470 e->callee->clone.combined_args_to_skip);
2471 else
2472 new_stmt = e->call_stmt;
2473 if (gimple_vdef (new_stmt)
2474 && TREE_CODE (gimple_vdef (new_stmt)) == SSA_NAME)
2475 SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt;
2476 gimple_call_set_fndecl (new_stmt, e->callee->decl);
2478 gsi = gsi_for_stmt (e->call_stmt);
2479 gsi_replace (&gsi, new_stmt, true);
2481 /* Update EH information too, just in case. */
2482 maybe_clean_or_replace_eh_stmt (e->call_stmt, new_stmt);
2484 cgraph_set_call_stmt_including_clones (get_clone_orig_node (e->caller),
2485 e->call_stmt, new_stmt);
2487 if (cgraph_dump_file)
2489 fprintf (cgraph_dump_file, " updated to:");
2490 print_gimple_stmt (cgraph_dump_file, e->call_stmt, 0, dump_flags);
2492 return new_stmt;
2495 /* Once all functions from compilation unit are in memory, produce all clones
2496 and update all calls. We might also do this on demand if we don't want to
2497 bring all functions to memory prior compilation, but current WHOPR
2498 implementation does that and it is is bit easier to keep everything right in
2499 this order. */
2500 void
2501 cgraph_materialize_all_clones (void)
2503 struct cgraph_node *node;
2504 bool stabilized = false;
2506 if (cgraph_dump_file)
2507 fprintf (cgraph_dump_file, "Materializing clones\n");
2508 #ifdef ENABLE_CHECKING
2509 verify_cgraph ();
2510 #endif
2512 /* We can also do topological order, but number of iterations should be
2513 bounded by number of IPA passes since single IPA pass is probably not
2514 going to create clones of clones it created itself. */
2515 while (!stabilized)
2517 stabilized = true;
2518 for (node = cgraph_nodes; node; node = node->next)
2520 if (node->clone_of && node->decl != node->clone_of->decl
2521 && !gimple_has_body_p (node->decl))
2523 if (gimple_has_body_p (node->clone_of->decl))
2525 if (cgraph_dump_file)
2527 fprintf (cgraph_dump_file, "clonning %s to %s\n",
2528 cgraph_node_name (node->clone_of),
2529 cgraph_node_name (node));
2530 if (node->clone.tree_map)
2532 unsigned int i;
2533 fprintf (cgraph_dump_file, " replace map: ");
2534 for (i = 0; i < VEC_length (ipa_replace_map_p,
2535 node->clone.tree_map);
2536 i++)
2538 struct ipa_replace_map *replace_info;
2539 replace_info = VEC_index (ipa_replace_map_p,
2540 node->clone.tree_map,
2542 print_generic_expr (cgraph_dump_file, replace_info->old_tree, 0);
2543 fprintf (cgraph_dump_file, " -> ");
2544 print_generic_expr (cgraph_dump_file, replace_info->new_tree, 0);
2545 fprintf (cgraph_dump_file, "%s%s;",
2546 replace_info->replace_p ? "(replace)":"",
2547 replace_info->ref_p ? "(ref)":"");
2549 fprintf (cgraph_dump_file, "\n");
2551 if (node->clone.args_to_skip)
2553 fprintf (cgraph_dump_file, " args_to_skip: ");
2554 dump_bitmap (cgraph_dump_file, node->clone.args_to_skip);
2556 if (node->clone.args_to_skip)
2558 fprintf (cgraph_dump_file, " combined_args_to_skip:");
2559 dump_bitmap (cgraph_dump_file, node->clone.combined_args_to_skip);
2562 cgraph_materialize_clone (node);
2564 else
2565 stabilized = false;
2569 for (node = cgraph_nodes; node; node = node->next)
2570 if (!node->analyzed && node->callees)
2571 cgraph_node_remove_callees (node);
2572 if (cgraph_dump_file)
2573 fprintf (cgraph_dump_file, "Updating call sites\n");
2574 for (node = cgraph_nodes; node; node = node->next)
2575 if (node->analyzed && gimple_has_body_p (node->decl)
2576 && (!node->clone_of
2577 /* A clone node may be unreachable (and not needed) and
2578 the node will be removed in unreachable node removal.
2579 However its caller node which is external (inline extern,
2580 or node from aux module) may still be reachable. Such
2581 node (the caller) will need to be kept in the callgraph.
2582 As a result, we will have a live caller node with the callee
2583 edge to the cloned node be removed. This will lead to a missing
2584 call edge fixup. */
2585 || L_IPO_COMP_MODE))
2587 struct cgraph_edge *e;
2589 current_function_decl = node->decl;
2590 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
2591 for (e = node->callees; e; e = e->next_callee)
2592 cgraph_redirect_edge_call_stmt_to_callee (e);
2593 pop_cfun ();
2594 current_function_decl = NULL;
2595 #ifdef ENABLE_CHECKING
2596 verify_cgraph_node (node);
2597 #endif
2599 if (cgraph_dump_file)
2600 fprintf (cgraph_dump_file, "Materialization Call site updates done.\n");
2601 /* All changes to parameters have been performed. In order not to
2602 incorrectly repeat them, we simply dispose of the bitmaps that drive the
2603 changes. */
2604 for (node = cgraph_nodes; node; node = node->next)
2605 node->clone.combined_args_to_skip = NULL;
2606 #ifdef ENABLE_CHECKING
2607 verify_cgraph ();
2608 #endif
2609 cgraph_remove_unreachable_nodes (false, cgraph_dump_file);
2612 #include "gt-cgraphunit.h"