* charset.c (convert_using_iconv): Close out any shift states,
[official-gcc.git] / gcc / cgraphunit.c
blob7215f1a10f85670c4ce729196928d2bd89b4a7f2
1 /* Callgraph based interprocedural optimizations.
2 Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
3 Contributed by Jan Hubicka
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 /* This module implements main driver of compilation process as well as
22 few basic interprocedural optimizers.
24 The main scope of this file is to act as an interface in between
25 tree based frontends and the backend (and middle end)
27 The front-end is supposed to use following functionality:
29 - cgraph_finalize_function
31 This function is called once front-end has parsed whole body of function
32 and it is certain that the function body nor the declaration will change.
34 (There is one exception needed for implementing GCC extern inline
35 function.)
37 - varpool_finalize_variable
39 This function has same behavior as the above but is used for static
40 variables.
42 - cgraph_finalize_compilation_unit
44 This function is called once (source level) compilation unit is finalized
45 and it will no longer change.
47 In the unit-at-a-time the call-graph construction and local function
48 analysis takes place here. Bodies of unreachable functions are released
49 to conserve memory usage.
51 The function can be called multiple times when multiple source level
52 compilation units are combined (such as in C frontend)
54 - cgraph_optimize
56 In this unit-at-a-time compilation the intra procedural analysis takes
57 place here. In particular the static functions whose address is never
58 taken are marked as local. Backend can then use this information to
59 modify calling conventions, do better inlining or similar optimizations.
61 - cgraph_mark_needed_node
62 - varpool_mark_needed_node
64 When function or variable is referenced by some hidden way the call-graph
65 data structure must be updated accordingly by this function.
66 There should be little need to call this function and all the references
67 should be made explicit to cgraph code. At present these functions are
68 used by C++ frontend to explicitly mark the keyed methods.
70 - analyze_expr callback
72 This function is responsible for lowering tree nodes not understood by
73 generic code into understandable ones or alternatively marking
74 callgraph and varpool nodes referenced by the as needed.
76 ??? On the tree-ssa genericizing should take place here and we will avoid
77 need for these hooks (replacing them by genericizing hook)
79 We implement two compilation modes.
81 - unit-at-a-time: In this mode analyzing of all functions is deferred
82 to cgraph_finalize_compilation_unit and expansion into cgraph_optimize.
84 In cgraph_finalize_compilation_unit the reachable functions are
85 analyzed. During analysis the call-graph edges from reachable
86 functions are constructed and their destinations are marked as
87 reachable. References to functions and variables are discovered too
88 and variables found to be needed output to the assembly file. Via
89 mark_referenced call in assemble_variable functions referenced by
90 static variables are noticed too.
92 The intra-procedural information is produced and its existence
93 indicated by global_info_ready. Once this flag is set it is impossible
94 to change function from !reachable to reachable and thus
95 assemble_variable no longer call mark_referenced.
97 Finally the call-graph is topologically sorted and all reachable functions
98 that has not been completely inlined or are not external are output.
100 ??? It is possible that reference to function or variable is optimized
101 out. We can not deal with this nicely because topological order is not
102 suitable for it. For tree-ssa we may consider another pass doing
103 optimization and re-discovering reachable functions.
105 ??? Reorganize code so variables are output very last and only if they
106 really has been referenced by produced code, so we catch more cases
107 where reference has been optimized out.
109 - non-unit-at-a-time
111 All functions are variables are output as early as possible to conserve
112 memory consumption. This may or may not result in less memory used but
113 it is still needed for some legacy code that rely on particular ordering
114 of things output from the compiler.
116 Varpool data structures are not used and variables are output directly.
118 Functions are output early using call of
119 cgraph_assemble_pending_function from cgraph_finalize_function. The
120 decision on whether function is needed is made more conservative so
121 uninlininable static functions are needed too. During the call-graph
122 construction the edge destinations are not marked as reachable and it
123 is completely relied upn assemble_variable to mark them. */
126 #include "config.h"
127 #include "system.h"
128 #include "coretypes.h"
129 #include "tm.h"
130 #include "tree.h"
131 #include "rtl.h"
132 #include "tree-flow.h"
133 #include "tree-inline.h"
134 #include "langhooks.h"
135 #include "pointer-set.h"
136 #include "toplev.h"
137 #include "flags.h"
138 #include "ggc.h"
139 #include "debug.h"
140 #include "target.h"
141 #include "cgraph.h"
142 #include "diagnostic.h"
143 #include "timevar.h"
144 #include "params.h"
145 #include "fibheap.h"
146 #include "c-common.h"
147 #include "intl.h"
148 #include "function.h"
149 #include "ipa-prop.h"
150 #include "tree-gimple.h"
151 #include "tree-pass.h"
152 #include "output.h"
154 static void cgraph_expand_all_functions (void);
155 static void cgraph_mark_functions_to_output (void);
156 static void cgraph_expand_function (struct cgraph_node *);
157 static void cgraph_output_pending_asms (void);
159 static FILE *cgraph_dump_file;
161 /* A vector of FUNCTION_DECLs declared as static constructors. */
162 static GTY (()) VEC(tree, gc) *static_ctors;
163 /* A vector of FUNCTION_DECLs declared as static destructors. */
164 static GTY (()) VEC(tree, gc) *static_dtors;
166 /* When target does not have ctors and dtors, we call all constructor
167 and destructor by special initialization/destruction function
168 recognized by collect2.
170 When we are going to build this function, collect all constructors and
171 destructors and turn them into normal functions. */
173 static void
174 record_cdtor_fn (tree fndecl)
176 struct cgraph_node *node;
177 if (targetm.have_ctors_dtors
178 || (!DECL_STATIC_CONSTRUCTOR (fndecl)
179 && !DECL_STATIC_DESTRUCTOR (fndecl)))
180 return;
182 if (DECL_STATIC_CONSTRUCTOR (fndecl))
184 VEC_safe_push (tree, gc, static_ctors, fndecl);
185 DECL_STATIC_CONSTRUCTOR (fndecl) = 0;
187 if (DECL_STATIC_DESTRUCTOR (fndecl))
189 VEC_safe_push (tree, gc, static_dtors, fndecl);
190 DECL_STATIC_DESTRUCTOR (fndecl) = 0;
192 DECL_INLINE (fndecl) = 1;
193 node = cgraph_node (fndecl);
194 node->local.disregard_inline_limits = 1;
195 cgraph_mark_reachable_node (node);
198 /* Define global constructors/destructor functions for the CDTORS, of
199 which they are LEN. The CDTORS are sorted by initialization
200 priority. If CTOR_P is true, these are constructors; otherwise,
201 they are destructors. */
203 static void
204 build_cdtor (bool ctor_p, tree *cdtors, size_t len)
206 size_t i;
208 i = 0;
209 while (i < len)
211 tree body;
212 tree fn;
213 priority_type priority;
215 priority = 0;
216 body = NULL_TREE;
217 /* Find the next batch of constructors/destructors with the same
218 initialization priority. */
221 priority_type p;
222 fn = cdtors[i];
223 p = ctor_p ? DECL_INIT_PRIORITY (fn) : DECL_FINI_PRIORITY (fn);
224 if (!body)
225 priority = p;
226 else if (p != priority)
227 break;
228 append_to_statement_list (build_function_call_expr (fn, 0),
229 &body);
230 ++i;
232 while (i < len);
233 gcc_assert (body != NULL_TREE);
234 /* Generate a function to call all the function of like
235 priority. */
236 cgraph_build_static_cdtor (ctor_p ? 'I' : 'D', body, priority);
240 /* Comparison function for qsort. P1 and P2 are actually of type
241 "tree *" and point to static constructors. DECL_INIT_PRIORITY is
242 used to determine the sort order. */
244 static int
245 compare_ctor (const void *p1, const void *p2)
247 tree f1;
248 tree f2;
249 int priority1;
250 int priority2;
252 f1 = *(const tree *)p1;
253 f2 = *(const tree *)p2;
254 priority1 = DECL_INIT_PRIORITY (f1);
255 priority2 = DECL_INIT_PRIORITY (f2);
257 if (priority1 < priority2)
258 return -1;
259 else if (priority1 > priority2)
260 return 1;
261 else
262 /* Ensure a stable sort. */
263 return (const tree *)p1 - (const tree *)p2;
266 /* Comparison function for qsort. P1 and P2 are actually of type
267 "tree *" and point to static destructors. DECL_FINI_PRIORITY is
268 used to determine the sort order. */
270 static int
271 compare_dtor (const void *p1, const void *p2)
273 tree f1;
274 tree f2;
275 int priority1;
276 int priority2;
278 f1 = *(const tree *)p1;
279 f2 = *(const tree *)p2;
280 priority1 = DECL_FINI_PRIORITY (f1);
281 priority2 = DECL_FINI_PRIORITY (f2);
283 if (priority1 < priority2)
284 return -1;
285 else if (priority1 > priority2)
286 return 1;
287 else
288 /* Ensure a stable sort. */
289 return (const tree *)p1 - (const tree *)p2;
292 /* Generate functions to call static constructors and destructors
293 for targets that do not support .ctors/.dtors sections. These
294 functions have magic names which are detected by collect2. */
296 static void
297 cgraph_build_cdtor_fns (void)
299 if (!VEC_empty (tree, static_ctors))
301 gcc_assert (!targetm.have_ctors_dtors);
302 qsort (VEC_address (tree, static_ctors),
303 VEC_length (tree, static_ctors),
304 sizeof (tree),
305 compare_ctor);
306 build_cdtor (/*ctor_p=*/true,
307 VEC_address (tree, static_ctors),
308 VEC_length (tree, static_ctors));
309 VEC_truncate (tree, static_ctors, 0);
312 if (!VEC_empty (tree, static_dtors))
314 gcc_assert (!targetm.have_ctors_dtors);
315 qsort (VEC_address (tree, static_dtors),
316 VEC_length (tree, static_dtors),
317 sizeof (tree),
318 compare_dtor);
319 build_cdtor (/*ctor_p=*/false,
320 VEC_address (tree, static_dtors),
321 VEC_length (tree, static_dtors));
322 VEC_truncate (tree, static_dtors, 0);
326 /* Determine if function DECL is needed. That is, visible to something
327 either outside this translation unit, something magic in the system
328 configury, or (if not doing unit-at-a-time) to something we havn't
329 seen yet. */
331 static bool
332 decide_is_function_needed (struct cgraph_node *node, tree decl)
334 tree origin;
335 if (MAIN_NAME_P (DECL_NAME (decl))
336 && TREE_PUBLIC (decl))
338 node->local.externally_visible = true;
339 return true;
342 /* If the user told us it is used, then it must be so. */
343 if (node->local.externally_visible)
344 return true;
346 if (!flag_unit_at_a_time && lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
347 return true;
349 /* ??? If the assembler name is set by hand, it is possible to assemble
350 the name later after finalizing the function and the fact is noticed
351 in assemble_name then. This is arguably a bug. */
352 if (DECL_ASSEMBLER_NAME_SET_P (decl)
353 && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
354 return true;
356 /* With -fkeep-inline-functions we are keeping all inline functions except
357 for extern inline ones. */
358 if (flag_keep_inline_functions
359 && DECL_DECLARED_INLINE_P (decl)
360 && !DECL_EXTERNAL (decl)
361 && !lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl)))
362 return true;
364 /* If we decided it was needed before, but at the time we didn't have
365 the body of the function available, then it's still needed. We have
366 to go back and re-check its dependencies now. */
367 if (node->needed)
368 return true;
370 /* Externally visible functions must be output. The exception is
371 COMDAT functions that must be output only when they are needed.
373 When not optimizing, also output the static functions. (see
374 PR24561), but don't do so for always_inline functions, functions
375 declared inline and nested functions. These was optimized out
376 in the original implementation and it is unclear whether we want
377 to change the behavior here. */
378 if (((TREE_PUBLIC (decl)
379 || (!optimize && !node->local.disregard_inline_limits
380 && !DECL_DECLARED_INLINE_P (decl)
381 && !node->origin))
382 && !flag_whole_program)
383 && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
384 return true;
386 /* Constructors and destructors are reachable from the runtime by
387 some mechanism. */
388 if (DECL_STATIC_CONSTRUCTOR (decl) || DECL_STATIC_DESTRUCTOR (decl))
389 return true;
391 if (flag_unit_at_a_time)
392 return false;
394 /* If not doing unit at a time, then we'll only defer this function
395 if its marked for inlining. Otherwise we want to emit it now. */
397 /* "extern inline" functions are never output locally. */
398 if (DECL_EXTERNAL (decl))
399 return false;
400 /* Nested functions of extern inline function shall not be emit unless
401 we inlined the origin. */
402 for (origin = decl_function_context (decl); origin;
403 origin = decl_function_context (origin))
404 if (DECL_EXTERNAL (origin))
405 return false;
406 /* We want to emit COMDAT functions only when absolutely necessary. */
407 if (DECL_COMDAT (decl))
408 return false;
409 if (!DECL_INLINE (decl)
410 || (!node->local.disregard_inline_limits
411 /* When declared inline, defer even the uninlinable functions.
412 This allows them to be eliminated when unused. */
413 && !DECL_DECLARED_INLINE_P (decl)
414 && (!node->local.inlinable || !cgraph_default_inline_p (node, NULL))))
415 return true;
417 return false;
420 /* Process CGRAPH_NEW_FUNCTIONS and perform actions necessary to add these
421 functions into callgraph in a way so they look like ordinary reachable
422 functions inserted into callgraph already at construction time. */
424 bool
425 cgraph_process_new_functions (void)
427 bool output = false;
428 tree fndecl;
429 struct cgraph_node *node;
431 /* Note that this queue may grow as its being processed, as the new
432 functions may generate new ones. */
433 while (cgraph_new_nodes)
435 node = cgraph_new_nodes;
436 fndecl = node->decl;
437 cgraph_new_nodes = cgraph_new_nodes->next_needed;
438 switch (cgraph_state)
440 case CGRAPH_STATE_CONSTRUCTION:
441 /* At construction time we just need to finalize function and move
442 it into reachable functions list. */
444 node->next_needed = NULL;
445 node->needed = node->reachable = false;
446 cgraph_finalize_function (fndecl, false);
447 cgraph_mark_reachable_node (node);
448 output = true;
449 break;
451 case CGRAPH_STATE_IPA:
452 case CGRAPH_STATE_IPA_SSA:
453 /* When IPA optimization already started, do all essential
454 transformations that has been already performed on the whole
455 cgraph but not on this function. */
457 tree_register_cfg_hooks ();
458 if (!node->analyzed)
459 cgraph_analyze_function (node);
460 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
461 current_function_decl = fndecl;
462 node->local.inlinable = tree_inlinable_function_p (fndecl);
463 node->local.self_insns = estimate_num_insns (fndecl,
464 &eni_inlining_weights);
465 node->local.disregard_inline_limits
466 |= DECL_DISREGARD_INLINE_LIMITS (fndecl);
467 /* Inlining characteristics are maintained by the
468 cgraph_mark_inline. */
469 node->global.insns = node->local.self_insns;
470 if (flag_really_no_inline && !node->local.disregard_inline_limits)
471 node->local.inlinable = 0;
472 if ((cgraph_state == CGRAPH_STATE_IPA_SSA
473 && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
474 /* When not optimizing, be sure we run early local passes anyway
475 to expand OMP. */
476 || !optimize)
477 execute_pass_list (pass_early_local_passes.sub);
478 free_dominance_info (CDI_POST_DOMINATORS);
479 free_dominance_info (CDI_DOMINATORS);
480 pop_cfun ();
481 current_function_decl = NULL;
482 break;
484 case CGRAPH_STATE_EXPANSION:
485 /* Functions created during expansion shall be compiled
486 directly. */
487 node->output = 0;
488 cgraph_expand_function (node);
489 break;
491 default:
492 gcc_unreachable ();
493 break;
496 return output;
499 /* When not doing unit-at-a-time, output all functions enqueued.
500 Return true when such a functions were found. */
502 static bool
503 cgraph_assemble_pending_functions (void)
505 bool output = false;
507 if (flag_unit_at_a_time)
508 return false;
510 cgraph_output_pending_asms ();
512 while (cgraph_nodes_queue)
514 struct cgraph_node *n = cgraph_nodes_queue;
516 cgraph_nodes_queue = cgraph_nodes_queue->next_needed;
517 n->next_needed = NULL;
518 if (!n->global.inlined_to
519 && !n->alias
520 && !DECL_EXTERNAL (n->decl))
522 cgraph_expand_function (n);
523 output = true;
525 output |= cgraph_process_new_functions ();
528 return output;
532 /* As an GCC extension we allow redefinition of the function. The
533 semantics when both copies of bodies differ is not well defined.
534 We replace the old body with new body so in unit at a time mode
535 we always use new body, while in normal mode we may end up with
536 old body inlined into some functions and new body expanded and
537 inlined in others.
539 ??? It may make more sense to use one body for inlining and other
540 body for expanding the function but this is difficult to do. */
542 static void
543 cgraph_reset_node (struct cgraph_node *node)
545 /* If node->output is set, then this is a unit-at-a-time compilation
546 and we have already begun whole-unit analysis. This is *not*
547 testing for whether we've already emitted the function. That
548 case can be sort-of legitimately seen with real function
549 redefinition errors. I would argue that the front end should
550 never present us with such a case, but don't enforce that for now. */
551 gcc_assert (!node->output);
553 /* Reset our data structures so we can analyze the function again. */
554 memset (&node->local, 0, sizeof (node->local));
555 memset (&node->global, 0, sizeof (node->global));
556 memset (&node->rtl, 0, sizeof (node->rtl));
557 node->analyzed = false;
558 node->local.redefined_extern_inline = true;
559 node->local.finalized = false;
561 if (!flag_unit_at_a_time)
563 struct cgraph_node *n, *next;
565 for (n = cgraph_nodes; n; n = next)
567 next = n->next;
568 if (n->global.inlined_to == node)
569 cgraph_remove_node (n);
573 cgraph_node_remove_callees (node);
575 /* We may need to re-queue the node for assembling in case
576 we already proceeded it and ignored as not needed. */
577 if (node->reachable && !flag_unit_at_a_time)
579 struct cgraph_node *n;
581 for (n = cgraph_nodes_queue; n; n = n->next_needed)
582 if (n == node)
583 break;
584 if (!n)
585 node->reachable = 0;
589 static void
590 cgraph_lower_function (struct cgraph_node *node)
592 if (node->lowered)
593 return;
594 tree_lowering_passes (node->decl);
595 node->lowered = true;
598 /* DECL has been parsed. Take it, queue it, compile it at the whim of the
599 logic in effect. If NESTED is true, then our caller cannot stand to have
600 the garbage collector run at the moment. We would need to either create
601 a new GC context, or just not compile right now. */
603 void
604 cgraph_finalize_function (tree decl, bool nested)
606 struct cgraph_node *node = cgraph_node (decl);
608 if (node->local.finalized)
609 cgraph_reset_node (node);
611 node->pid = cgraph_max_pid ++;
612 notice_global_symbol (decl);
613 node->decl = decl;
614 node->local.finalized = true;
615 node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL;
616 record_cdtor_fn (node->decl);
617 if (node->nested)
618 lower_nested_functions (decl);
619 gcc_assert (!node->nested);
621 /* If not unit at a time, then we need to create the call graph
622 now, so that called functions can be queued and emitted now. */
623 if (!flag_unit_at_a_time)
624 cgraph_analyze_function (node);
626 if (decide_is_function_needed (node, decl))
627 cgraph_mark_needed_node (node);
629 /* Since we reclaim unreachable nodes at the end of every language
630 level unit, we need to be conservative about possible entry points
631 there. */
632 if ((TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl)))
633 cgraph_mark_reachable_node (node);
635 /* If not unit at a time, go ahead and emit everything we've found
636 to be reachable at this time. */
637 if (!nested)
639 if (!cgraph_assemble_pending_functions ())
640 ggc_collect ();
643 /* If we've not yet emitted decl, tell the debug info about it. */
644 if (!TREE_ASM_WRITTEN (decl))
645 (*debug_hooks->deferred_inline_function) (decl);
647 /* Possibly warn about unused parameters. */
648 if (warn_unused_parameter)
649 do_warn_unused_parameter (decl);
652 /* Verify cgraph nodes of given cgraph node. */
653 void
654 verify_cgraph_node (struct cgraph_node *node)
656 struct cgraph_edge *e;
657 struct cgraph_node *main_clone;
658 struct function *this_cfun = DECL_STRUCT_FUNCTION (node->decl);
659 basic_block this_block;
660 block_stmt_iterator bsi;
661 bool error_found = false;
663 if (errorcount || sorrycount)
664 return;
666 timevar_push (TV_CGRAPH_VERIFY);
667 for (e = node->callees; e; e = e->next_callee)
668 if (e->aux)
670 error ("aux field set for edge %s->%s",
671 cgraph_node_name (e->caller), cgraph_node_name (e->callee));
672 error_found = true;
674 if (node->count < 0)
676 error ("Execution count is negative");
677 error_found = true;
679 for (e = node->callers; e; e = e->next_caller)
681 if (e->count < 0)
683 error ("caller edge count is negative");
684 error_found = true;
686 if (e->frequency < 0)
688 error ("caller edge frequency is negative");
689 error_found = true;
691 if (e->frequency > CGRAPH_FREQ_MAX)
693 error ("caller edge frequency is too large");
694 error_found = true;
696 if (!e->inline_failed)
698 if (node->global.inlined_to
699 != (e->caller->global.inlined_to
700 ? e->caller->global.inlined_to : e->caller))
702 error ("inlined_to pointer is wrong");
703 error_found = true;
705 if (node->callers->next_caller)
707 error ("multiple inline callers");
708 error_found = true;
711 else
712 if (node->global.inlined_to)
714 error ("inlined_to pointer set for noninline callers");
715 error_found = true;
718 if (!node->callers && node->global.inlined_to)
720 error ("inlined_to pointer is set but no predecessors found");
721 error_found = true;
723 if (node->global.inlined_to == node)
725 error ("inlined_to pointer refers to itself");
726 error_found = true;
729 for (main_clone = cgraph_node (node->decl); main_clone;
730 main_clone = main_clone->next_clone)
731 if (main_clone == node)
732 break;
733 if (!cgraph_node (node->decl))
735 error ("node not found in cgraph_hash");
736 error_found = true;
739 if (node->analyzed
740 && DECL_SAVED_TREE (node->decl) && !TREE_ASM_WRITTEN (node->decl)
741 && (!DECL_EXTERNAL (node->decl) || node->global.inlined_to))
743 if (this_cfun->cfg)
745 /* The nodes we're interested in are never shared, so walk
746 the tree ignoring duplicates. */
747 struct pointer_set_t *visited_nodes = pointer_set_create ();
748 /* Reach the trees by walking over the CFG, and note the
749 enclosing basic-blocks in the call edges. */
750 FOR_EACH_BB_FN (this_block, this_cfun)
751 for (bsi = bsi_start (this_block); !bsi_end_p (bsi); bsi_next (&bsi))
753 tree stmt = bsi_stmt (bsi);
754 tree call = get_call_expr_in (stmt);
755 tree decl;
756 if (call && (decl = get_callee_fndecl (call)))
758 struct cgraph_edge *e = cgraph_edge (node, stmt);
759 if (e)
761 if (e->aux)
763 error ("shared call_stmt:");
764 debug_generic_stmt (stmt);
765 error_found = true;
767 if (e->callee->decl != cgraph_node (decl)->decl
768 && e->inline_failed)
770 error ("edge points to wrong declaration:");
771 debug_tree (e->callee->decl);
772 fprintf (stderr," Instead of:");
773 debug_tree (decl);
775 e->aux = (void *)1;
777 else
779 error ("missing callgraph edge for call stmt:");
780 debug_generic_stmt (stmt);
781 error_found = true;
785 pointer_set_destroy (visited_nodes);
787 else
788 /* No CFG available?! */
789 gcc_unreachable ();
791 for (e = node->callees; e; e = e->next_callee)
793 if (!e->aux)
795 error ("edge %s->%s has no corresponding call_stmt",
796 cgraph_node_name (e->caller),
797 cgraph_node_name (e->callee));
798 debug_generic_stmt (e->call_stmt);
799 error_found = true;
801 e->aux = 0;
804 if (error_found)
806 dump_cgraph_node (stderr, node);
807 internal_error ("verify_cgraph_node failed");
809 timevar_pop (TV_CGRAPH_VERIFY);
812 /* Verify whole cgraph structure. */
813 void
814 verify_cgraph (void)
816 struct cgraph_node *node;
818 if (sorrycount || errorcount)
819 return;
821 for (node = cgraph_nodes; node; node = node->next)
822 verify_cgraph_node (node);
825 /* Output all asm statements we have stored up to be output. */
827 static void
828 cgraph_output_pending_asms (void)
830 struct cgraph_asm_node *can;
832 if (errorcount || sorrycount)
833 return;
835 for (can = cgraph_asm_nodes; can; can = can->next)
836 assemble_asm (can->asm_str);
837 cgraph_asm_nodes = NULL;
840 /* Analyze the function scheduled to be output. */
841 void
842 cgraph_analyze_function (struct cgraph_node *node)
844 tree decl = node->decl;
846 current_function_decl = decl;
847 push_cfun (DECL_STRUCT_FUNCTION (decl));
848 cgraph_lower_function (node);
849 node->analyzed = true;
851 if (!flag_unit_at_a_time)
853 bitmap_obstack_initialize (NULL);
854 tree_register_cfg_hooks ();
855 execute_pass_list (pass_early_local_passes.sub);
856 free_dominance_info (CDI_POST_DOMINATORS);
857 free_dominance_info (CDI_DOMINATORS);
858 bitmap_obstack_release (NULL);
861 pop_cfun ();
862 current_function_decl = NULL;
865 /* Look for externally_visible and used attributes and mark cgraph nodes
866 accordingly.
868 We cannot mark the nodes at the point the attributes are processed (in
869 handle_*_attribute) because the copy of the declarations available at that
870 point may not be canonical. For example, in:
872 void f();
873 void f() __attribute__((used));
875 the declaration we see in handle_used_attribute will be the second
876 declaration -- but the front end will subsequently merge that declaration
877 with the original declaration and discard the second declaration.
879 Furthermore, we can't mark these nodes in cgraph_finalize_function because:
881 void f() {}
882 void f() __attribute__((externally_visible));
884 is valid.
886 So, we walk the nodes at the end of the translation unit, applying the
887 attributes at that point. */
889 static void
890 process_function_and_variable_attributes (struct cgraph_node *first,
891 struct varpool_node *first_var)
893 struct cgraph_node *node;
894 struct varpool_node *vnode;
896 for (node = cgraph_nodes; node != first; node = node->next)
898 tree decl = node->decl;
899 if (lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
901 mark_decl_referenced (decl);
902 if (node->local.finalized)
903 cgraph_mark_needed_node (node);
905 if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
907 if (! TREE_PUBLIC (node->decl))
908 warning (OPT_Wattributes,
909 "%J%<externally_visible%> attribute have effect only on public objects",
910 node->decl);
911 else
913 if (node->local.finalized)
914 cgraph_mark_needed_node (node);
915 node->local.externally_visible = true;
919 for (vnode = varpool_nodes; vnode != first_var; vnode = vnode->next)
921 tree decl = vnode->decl;
922 if (lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
924 mark_decl_referenced (decl);
925 if (vnode->finalized)
926 varpool_mark_needed_node (vnode);
928 if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
930 if (! TREE_PUBLIC (vnode->decl))
931 warning (OPT_Wattributes,
932 "%J%<externally_visible%> attribute have effect only on public objects",
933 vnode->decl);
934 else
936 if (vnode->finalized)
937 varpool_mark_needed_node (vnode);
938 vnode->externally_visible = true;
944 /* Process CGRAPH_NODES_NEEDED queue, analyze each function (and transitively
945 each reachable functions) and build cgraph.
946 The function can be called multiple times after inserting new nodes
947 into beginning of queue. Just the new part of queue is re-scanned then. */
949 static void
950 cgraph_analyze_functions (void)
952 /* Keep track of already processed nodes when called multiple times for
953 intermodule optimization. */
954 static struct cgraph_node *first_analyzed;
955 struct cgraph_node *first_processed = first_analyzed;
956 static struct varpool_node *first_analyzed_var;
957 struct cgraph_node *node, *next;
959 process_function_and_variable_attributes (first_processed,
960 first_analyzed_var);
961 first_processed = cgraph_nodes;
962 first_analyzed_var = varpool_nodes;
963 varpool_analyze_pending_decls ();
964 if (cgraph_dump_file)
966 fprintf (cgraph_dump_file, "Initial entry points:");
967 for (node = cgraph_nodes; node != first_analyzed; node = node->next)
968 if (node->needed && DECL_SAVED_TREE (node->decl))
969 fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
970 fprintf (cgraph_dump_file, "\n");
972 cgraph_process_new_functions ();
974 /* Propagate reachability flag and lower representation of all reachable
975 functions. In the future, lowering will introduce new functions and
976 new entry points on the way (by template instantiation and virtual
977 method table generation for instance). */
978 while (cgraph_nodes_queue)
980 struct cgraph_edge *edge;
981 tree decl = cgraph_nodes_queue->decl;
983 node = cgraph_nodes_queue;
984 cgraph_nodes_queue = cgraph_nodes_queue->next_needed;
985 node->next_needed = NULL;
987 /* ??? It is possible to create extern inline function and later using
988 weak alias attribute to kill its body. See
989 gcc.c-torture/compile/20011119-1.c */
990 if (!DECL_SAVED_TREE (decl))
992 cgraph_reset_node (node);
993 continue;
996 gcc_assert (!node->analyzed && node->reachable);
997 gcc_assert (DECL_SAVED_TREE (decl));
999 cgraph_analyze_function (node);
1001 for (edge = node->callees; edge; edge = edge->next_callee)
1002 if (!edge->callee->reachable)
1003 cgraph_mark_reachable_node (edge->callee);
1005 /* We finalize local static variables during constructing callgraph
1006 edges. Process their attributes too. */
1007 process_function_and_variable_attributes (first_processed,
1008 first_analyzed_var);
1009 first_processed = cgraph_nodes;
1010 first_analyzed_var = varpool_nodes;
1011 varpool_analyze_pending_decls ();
1012 cgraph_process_new_functions ();
1015 /* Collect entry points to the unit. */
1016 if (cgraph_dump_file)
1018 fprintf (cgraph_dump_file, "Unit entry points:");
1019 for (node = cgraph_nodes; node != first_analyzed; node = node->next)
1020 if (node->needed && DECL_SAVED_TREE (node->decl))
1021 fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
1022 fprintf (cgraph_dump_file, "\n\nInitial ");
1023 dump_cgraph (cgraph_dump_file);
1026 if (cgraph_dump_file)
1027 fprintf (cgraph_dump_file, "\nReclaiming functions:");
1029 for (node = cgraph_nodes; node != first_analyzed; node = next)
1031 tree decl = node->decl;
1032 next = node->next;
1034 if (node->local.finalized && !DECL_SAVED_TREE (decl))
1035 cgraph_reset_node (node);
1037 if (!node->reachable && DECL_SAVED_TREE (decl))
1039 if (cgraph_dump_file)
1040 fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
1041 cgraph_remove_node (node);
1042 continue;
1044 else
1045 node->next_needed = NULL;
1046 gcc_assert (!node->local.finalized || DECL_SAVED_TREE (decl));
1047 gcc_assert (node->analyzed == node->local.finalized);
1049 if (cgraph_dump_file)
1051 fprintf (cgraph_dump_file, "\n\nReclaimed ");
1052 dump_cgraph (cgraph_dump_file);
1054 first_analyzed = cgraph_nodes;
1055 ggc_collect ();
1058 /* Analyze the whole compilation unit once it is parsed completely. */
1060 void
1061 cgraph_finalize_compilation_unit (void)
1063 if (errorcount || sorrycount)
1064 return;
1066 finish_aliases_1 ();
1068 if (!flag_unit_at_a_time)
1070 cgraph_output_pending_asms ();
1071 cgraph_assemble_pending_functions ();
1072 varpool_output_debug_info ();
1073 return;
1076 if (!quiet_flag)
1078 fprintf (stderr, "\nAnalyzing compilation unit\n");
1079 fflush (stderr);
1082 timevar_push (TV_CGRAPH);
1083 cgraph_analyze_functions ();
1084 timevar_pop (TV_CGRAPH);
1086 /* Figure out what functions we want to assemble. */
1088 static void
1089 cgraph_mark_functions_to_output (void)
1091 struct cgraph_node *node;
1093 for (node = cgraph_nodes; node; node = node->next)
1095 tree decl = node->decl;
1096 struct cgraph_edge *e;
1098 gcc_assert (!node->output);
1100 for (e = node->callers; e; e = e->next_caller)
1101 if (e->inline_failed)
1102 break;
1104 /* We need to output all local functions that are used and not
1105 always inlined, as well as those that are reachable from
1106 outside the current compilation unit. */
1107 if (DECL_SAVED_TREE (decl)
1108 && !node->global.inlined_to
1109 && (node->needed
1110 || (e && node->reachable))
1111 && !TREE_ASM_WRITTEN (decl)
1112 && !DECL_EXTERNAL (decl))
1113 node->output = 1;
1114 else
1116 /* We should've reclaimed all functions that are not needed. */
1117 #ifdef ENABLE_CHECKING
1118 if (!node->global.inlined_to && DECL_SAVED_TREE (decl)
1119 && !DECL_EXTERNAL (decl))
1121 dump_cgraph_node (stderr, node);
1122 internal_error ("failed to reclaim unneeded function");
1124 #endif
1125 gcc_assert (node->global.inlined_to || !DECL_SAVED_TREE (decl)
1126 || DECL_EXTERNAL (decl));
1133 /* Expand function specified by NODE. */
1135 static void
1136 cgraph_expand_function (struct cgraph_node *node)
1138 tree decl = node->decl;
1140 /* We ought to not compile any inline clones. */
1141 gcc_assert (!node->global.inlined_to);
1143 if (flag_unit_at_a_time)
1144 announce_function (decl);
1146 gcc_assert (node->lowered);
1148 /* Generate RTL for the body of DECL. */
1149 if (lang_hooks.callgraph.emit_associated_thunks)
1150 lang_hooks.callgraph.emit_associated_thunks (decl);
1151 tree_rest_of_compilation (decl);
1153 /* Make sure that BE didn't give up on compiling. */
1154 /* ??? Can happen with nested function of extern inline. */
1155 gcc_assert (TREE_ASM_WRITTEN (node->decl));
1157 current_function_decl = NULL;
1158 if (!cgraph_preserve_function_body_p (node->decl))
1160 cgraph_release_function_body (node);
1161 /* Eliminate all call edges. This is important so the call_expr no longer
1162 points to the dead function body. */
1163 cgraph_node_remove_callees (node);
1166 cgraph_function_flags_ready = true;
1169 /* Return true when CALLER_DECL should be inlined into CALLEE_DECL. */
1171 bool
1172 cgraph_inline_p (struct cgraph_edge *e, const char **reason)
1174 *reason = e->inline_failed;
1175 return !e->inline_failed;
1180 /* Expand all functions that must be output.
1182 Attempt to topologically sort the nodes so function is output when
1183 all called functions are already assembled to allow data to be
1184 propagated across the callgraph. Use a stack to get smaller distance
1185 between a function and its callees (later we may choose to use a more
1186 sophisticated algorithm for function reordering; we will likely want
1187 to use subsections to make the output functions appear in top-down
1188 order). */
1190 static void
1191 cgraph_expand_all_functions (void)
1193 struct cgraph_node *node;
1194 struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
1195 int order_pos = 0, new_order_pos = 0;
1196 int i;
1198 order_pos = cgraph_postorder (order);
1199 gcc_assert (order_pos == cgraph_n_nodes);
1201 /* Garbage collector may remove inline clones we eliminate during
1202 optimization. So we must be sure to not reference them. */
1203 for (i = 0; i < order_pos; i++)
1204 if (order[i]->output)
1205 order[new_order_pos++] = order[i];
1207 for (i = new_order_pos - 1; i >= 0; i--)
1209 node = order[i];
1210 if (node->output)
1212 gcc_assert (node->reachable);
1213 node->output = 0;
1214 cgraph_expand_function (node);
1217 cgraph_process_new_functions ();
1219 free (order);
1223 /* This is used to sort the node types by the cgraph order number. */
1225 struct cgraph_order_sort
1227 enum { ORDER_UNDEFINED = 0, ORDER_FUNCTION, ORDER_VAR, ORDER_ASM } kind;
1228 union
1230 struct cgraph_node *f;
1231 struct varpool_node *v;
1232 struct cgraph_asm_node *a;
1233 } u;
1236 /* Output all functions, variables, and asm statements in the order
1237 according to their order fields, which is the order in which they
1238 appeared in the file. This implements -fno-toplevel-reorder. In
1239 this mode we may output functions and variables which don't really
1240 need to be output. */
1242 static void
1243 cgraph_output_in_order (void)
1245 int max;
1246 size_t size;
1247 struct cgraph_order_sort *nodes;
1248 int i;
1249 struct cgraph_node *pf;
1250 struct varpool_node *pv;
1251 struct cgraph_asm_node *pa;
1253 max = cgraph_order;
1254 size = max * sizeof (struct cgraph_order_sort);
1255 nodes = (struct cgraph_order_sort *) alloca (size);
1256 memset (nodes, 0, size);
1258 varpool_analyze_pending_decls ();
1260 for (pf = cgraph_nodes; pf; pf = pf->next)
1262 if (pf->output)
1264 i = pf->order;
1265 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1266 nodes[i].kind = ORDER_FUNCTION;
1267 nodes[i].u.f = pf;
1271 for (pv = varpool_nodes_queue; pv; pv = pv->next_needed)
1273 i = pv->order;
1274 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1275 nodes[i].kind = ORDER_VAR;
1276 nodes[i].u.v = pv;
1279 for (pa = cgraph_asm_nodes; pa; pa = pa->next)
1281 i = pa->order;
1282 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1283 nodes[i].kind = ORDER_ASM;
1284 nodes[i].u.a = pa;
1287 for (i = 0; i < max; ++i)
1289 switch (nodes[i].kind)
1291 case ORDER_FUNCTION:
1292 nodes[i].u.f->output = 0;
1293 cgraph_expand_function (nodes[i].u.f);
1294 break;
1296 case ORDER_VAR:
1297 varpool_assemble_decl (nodes[i].u.v);
1298 break;
1300 case ORDER_ASM:
1301 assemble_asm (nodes[i].u.a->asm_str);
1302 break;
1304 case ORDER_UNDEFINED:
1305 break;
1307 default:
1308 gcc_unreachable ();
1312 cgraph_asm_nodes = NULL;
1315 /* Return true when function body of DECL still needs to be kept around
1316 for later re-use. */
1317 bool
1318 cgraph_preserve_function_body_p (tree decl)
1320 struct cgraph_node *node;
1321 if (!cgraph_global_info_ready)
1322 return (flag_really_no_inline
1323 ? DECL_DISREGARD_INLINE_LIMITS (decl)
1324 : DECL_INLINE (decl));
1325 /* Look if there is any clone around. */
1326 for (node = cgraph_node (decl); node; node = node->next_clone)
1327 if (node->global.inlined_to)
1328 return true;
1329 return false;
1332 static void
1333 ipa_passes (void)
1335 set_cfun (NULL);
1336 current_function_decl = NULL;
1337 tree_register_cfg_hooks ();
1338 bitmap_obstack_initialize (NULL);
1339 execute_ipa_pass_list (all_ipa_passes);
1340 bitmap_obstack_release (NULL);
1343 /* Perform simple optimizations based on callgraph. */
1345 void
1346 cgraph_optimize (void)
1348 if (errorcount || sorrycount)
1349 return;
1351 #ifdef ENABLE_CHECKING
1352 verify_cgraph ();
1353 #endif
1355 /* Call functions declared with the "constructor" or "destructor"
1356 attribute. */
1357 cgraph_build_cdtor_fns ();
1358 if (!flag_unit_at_a_time)
1360 cgraph_assemble_pending_functions ();
1361 cgraph_process_new_functions ();
1362 cgraph_state = CGRAPH_STATE_FINISHED;
1363 cgraph_output_pending_asms ();
1364 varpool_assemble_pending_decls ();
1365 varpool_output_debug_info ();
1366 return;
1369 /* Frontend may output common variables after the unit has been finalized.
1370 It is safe to deal with them here as they are always zero initialized. */
1371 varpool_analyze_pending_decls ();
1372 cgraph_analyze_functions ();
1374 timevar_push (TV_CGRAPHOPT);
1375 if (pre_ipa_mem_report)
1377 fprintf (stderr, "Memory consumption before IPA\n");
1378 dump_memory_report (false);
1380 if (!quiet_flag)
1381 fprintf (stderr, "Performing interprocedural optimizations\n");
1382 cgraph_state = CGRAPH_STATE_IPA;
1384 /* Don't run the IPA passes if there was any error or sorry messages. */
1385 if (errorcount == 0 && sorrycount == 0)
1386 ipa_passes ();
1388 /* This pass remove bodies of extern inline functions we never inlined.
1389 Do this later so other IPA passes see what is really going on. */
1390 cgraph_remove_unreachable_nodes (false, dump_file);
1391 cgraph_global_info_ready = true;
1392 if (cgraph_dump_file)
1394 fprintf (cgraph_dump_file, "Optimized ");
1395 dump_cgraph (cgraph_dump_file);
1396 dump_varpool (cgraph_dump_file);
1398 if (post_ipa_mem_report)
1400 fprintf (stderr, "Memory consumption after IPA\n");
1401 dump_memory_report (false);
1403 timevar_pop (TV_CGRAPHOPT);
1405 /* Output everything. */
1406 if (!quiet_flag)
1407 fprintf (stderr, "Assembling functions:\n");
1408 #ifdef ENABLE_CHECKING
1409 verify_cgraph ();
1410 #endif
1412 cgraph_mark_functions_to_output ();
1414 cgraph_state = CGRAPH_STATE_EXPANSION;
1415 if (!flag_toplevel_reorder)
1416 cgraph_output_in_order ();
1417 else
1419 cgraph_output_pending_asms ();
1421 cgraph_expand_all_functions ();
1422 varpool_remove_unreferenced_decls ();
1424 varpool_assemble_pending_decls ();
1425 varpool_output_debug_info ();
1427 cgraph_process_new_functions ();
1428 cgraph_state = CGRAPH_STATE_FINISHED;
1430 if (cgraph_dump_file)
1432 fprintf (cgraph_dump_file, "\nFinal ");
1433 dump_cgraph (cgraph_dump_file);
1435 #ifdef ENABLE_CHECKING
1436 verify_cgraph ();
1437 /* Double check that all inline clones are gone and that all
1438 function bodies have been released from memory. */
1439 if (flag_unit_at_a_time
1440 && !(sorrycount || errorcount))
1442 struct cgraph_node *node;
1443 bool error_found = false;
1445 for (node = cgraph_nodes; node; node = node->next)
1446 if (node->analyzed
1447 && (node->global.inlined_to
1448 || DECL_SAVED_TREE (node->decl)))
1450 error_found = true;
1451 dump_cgraph_node (stderr, node);
1453 if (error_found)
1454 internal_error ("nodes with no released memory found");
1456 #endif
1458 /* Generate and emit a static constructor or destructor. WHICH must
1459 be one of 'I' (for a constructor) or 'D' (for a destructor). BODY
1460 is a STATEMENT_LIST containing GENERIC statements. PRIORITY is the
1461 initialization priority fot this constructor or destructor. */
1463 void
1464 cgraph_build_static_cdtor (char which, tree body, int priority)
1466 static int counter = 0;
1467 char which_buf[16];
1468 tree decl, name, resdecl;
1470 /* The priority is encoded in the constructor or destructor name.
1471 collect2 will sort the names and arrange that they are called at
1472 program startup. */
1473 sprintf (which_buf, "%c_%.5d_%d", which, priority, counter++);
1474 name = get_file_function_name (which_buf);
1476 decl = build_decl (FUNCTION_DECL, name,
1477 build_function_type (void_type_node, void_list_node));
1478 current_function_decl = decl;
1480 resdecl = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
1481 DECL_ARTIFICIAL (resdecl) = 1;
1482 DECL_RESULT (decl) = resdecl;
1484 allocate_struct_function (decl, false);
1486 TREE_STATIC (decl) = 1;
1487 TREE_USED (decl) = 1;
1488 DECL_ARTIFICIAL (decl) = 1;
1489 DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;
1490 DECL_SAVED_TREE (decl) = body;
1491 TREE_PUBLIC (decl) = ! targetm.have_ctors_dtors;
1492 DECL_UNINLINABLE (decl) = 1;
1494 DECL_INITIAL (decl) = make_node (BLOCK);
1495 TREE_USED (DECL_INITIAL (decl)) = 1;
1497 DECL_SOURCE_LOCATION (decl) = input_location;
1498 cfun->function_end_locus = input_location;
1500 switch (which)
1502 case 'I':
1503 DECL_STATIC_CONSTRUCTOR (decl) = 1;
1504 decl_init_priority_insert (decl, priority);
1505 break;
1506 case 'D':
1507 DECL_STATIC_DESTRUCTOR (decl) = 1;
1508 decl_fini_priority_insert (decl, priority);
1509 break;
1510 default:
1511 gcc_unreachable ();
1514 gimplify_function_tree (decl);
1516 cgraph_add_new_function (decl, false);
1517 cgraph_mark_needed_node (cgraph_node (decl));
1520 void
1521 init_cgraph (void)
1523 cgraph_dump_file = dump_begin (TDI_cgraph, NULL);
1526 /* The edges representing the callers of the NEW_VERSION node were
1527 fixed by cgraph_function_versioning (), now the call_expr in their
1528 respective tree code should be updated to call the NEW_VERSION. */
1530 static void
1531 update_call_expr (struct cgraph_node *new_version)
1533 struct cgraph_edge *e;
1535 gcc_assert (new_version);
1536 for (e = new_version->callers; e; e = e->next_caller)
1537 /* Update the call expr on the edges
1538 to call the new version. */
1539 TREE_OPERAND (CALL_EXPR_FN (get_call_expr_in (e->call_stmt)), 0) = new_version->decl;
1543 /* Create a new cgraph node which is the new version of
1544 OLD_VERSION node. REDIRECT_CALLERS holds the callers
1545 edges which should be redirected to point to
1546 NEW_VERSION. ALL the callees edges of OLD_VERSION
1547 are cloned to the new version node. Return the new
1548 version node. */
1550 static struct cgraph_node *
1551 cgraph_copy_node_for_versioning (struct cgraph_node *old_version,
1552 tree new_decl,
1553 VEC(cgraph_edge_p,heap) *redirect_callers)
1555 struct cgraph_node *new_version;
1556 struct cgraph_edge *e, *new_e;
1557 struct cgraph_edge *next_callee;
1558 unsigned i;
1560 gcc_assert (old_version);
1562 new_version = cgraph_node (new_decl);
1564 new_version->analyzed = true;
1565 new_version->local = old_version->local;
1566 new_version->global = old_version->global;
1567 new_version->rtl = new_version->rtl;
1568 new_version->reachable = true;
1569 new_version->count = old_version->count;
1571 /* Clone the old node callees. Recursive calls are
1572 also cloned. */
1573 for (e = old_version->callees;e; e=e->next_callee)
1575 new_e = cgraph_clone_edge (e, new_version, e->call_stmt, 0, e->frequency,
1576 e->loop_nest, true);
1577 new_e->count = e->count;
1579 /* Fix recursive calls.
1580 If OLD_VERSION has a recursive call after the
1581 previous edge cloning, the new version will have an edge
1582 pointing to the old version, which is wrong;
1583 Redirect it to point to the new version. */
1584 for (e = new_version->callees ; e; e = next_callee)
1586 next_callee = e->next_callee;
1587 if (e->callee == old_version)
1588 cgraph_redirect_edge_callee (e, new_version);
1590 if (!next_callee)
1591 break;
1593 for (i = 0; VEC_iterate (cgraph_edge_p, redirect_callers, i, e); i++)
1595 /* Redirect calls to the old version node to point to its new
1596 version. */
1597 cgraph_redirect_edge_callee (e, new_version);
1600 return new_version;
1603 /* Perform function versioning.
1604 Function versioning includes copying of the tree and
1605 a callgraph update (creating a new cgraph node and updating
1606 its callees and callers).
1608 REDIRECT_CALLERS varray includes the edges to be redirected
1609 to the new version.
1611 TREE_MAP is a mapping of tree nodes we want to replace with
1612 new ones (according to results of prior analysis).
1613 OLD_VERSION_NODE is the node that is versioned.
1614 It returns the new version's cgraph node. */
1616 struct cgraph_node *
1617 cgraph_function_versioning (struct cgraph_node *old_version_node,
1618 VEC(cgraph_edge_p,heap) *redirect_callers,
1619 varray_type tree_map)
1621 tree old_decl = old_version_node->decl;
1622 struct cgraph_node *new_version_node = NULL;
1623 tree new_decl;
1625 if (!tree_versionable_function_p (old_decl))
1626 return NULL;
1628 /* Make a new FUNCTION_DECL tree node for the
1629 new version. */
1630 new_decl = copy_node (old_decl);
1632 /* Create the new version's call-graph node.
1633 and update the edges of the new node. */
1634 new_version_node =
1635 cgraph_copy_node_for_versioning (old_version_node, new_decl,
1636 redirect_callers);
1638 /* Copy the OLD_VERSION_NODE function tree to the new version. */
1639 tree_function_versioning (old_decl, new_decl, tree_map, false);
1640 /* Update the call_expr on the edges to call the new version node. */
1641 update_call_expr (new_version_node);
1643 /* Update the new version's properties.
1644 Make The new version visible only within this translation unit.
1645 ??? We cannot use COMDAT linkage because there is no
1646 ABI support for this. */
1647 DECL_EXTERNAL (new_version_node->decl) = 0;
1648 DECL_ONE_ONLY (new_version_node->decl) = 0;
1649 TREE_PUBLIC (new_version_node->decl) = 0;
1650 DECL_COMDAT (new_version_node->decl) = 0;
1651 new_version_node->local.externally_visible = 0;
1652 new_version_node->local.local = 1;
1653 new_version_node->lowered = true;
1654 return new_version_node;
1657 /* Produce separate function body for inline clones so the offline copy can be
1658 modified without affecting them. */
1659 struct cgraph_node *
1660 save_inline_function_body (struct cgraph_node *node)
1662 struct cgraph_node *first_clone;
1664 gcc_assert (node == cgraph_node (node->decl));
1666 cgraph_lower_function (node);
1668 /* In non-unit-at-a-time we construct full fledged clone we never output to
1669 assembly file. This clone is pointed out by inline_decl of original function
1670 and inlining infrastructure knows how to deal with this. */
1671 if (!flag_unit_at_a_time)
1673 struct cgraph_edge *e;
1675 first_clone = cgraph_clone_node (node, node->count, 0, CGRAPH_FREQ_BASE,
1676 false);
1677 first_clone->needed = 0;
1678 first_clone->reachable = 1;
1679 /* Recursively clone all bodies. */
1680 for (e = first_clone->callees; e; e = e->next_callee)
1681 if (!e->inline_failed)
1682 cgraph_clone_inlined_nodes (e, true, false);
1684 else
1685 first_clone = node->next_clone;
1687 first_clone->decl = copy_node (node->decl);
1688 node->next_clone = NULL;
1689 if (!flag_unit_at_a_time)
1690 node->inline_decl = first_clone->decl;
1691 first_clone->prev_clone = NULL;
1692 cgraph_insert_node_to_hashtable (first_clone);
1693 gcc_assert (first_clone == cgraph_node (first_clone->decl));
1695 /* Copy the OLD_VERSION_NODE function tree to the new version. */
1696 tree_function_versioning (node->decl, first_clone->decl, NULL, true);
1698 DECL_EXTERNAL (first_clone->decl) = 0;
1699 DECL_ONE_ONLY (first_clone->decl) = 0;
1700 TREE_PUBLIC (first_clone->decl) = 0;
1701 DECL_COMDAT (first_clone->decl) = 0;
1703 for (node = first_clone->next_clone; node; node = node->next_clone)
1704 node->decl = first_clone->decl;
1705 #ifdef ENABLE_CHECKING
1706 verify_cgraph_node (first_clone);
1707 #endif
1708 return first_clone;
1711 #include "gt-cgraphunit.h"