2013-12-14 Janus Weil <janus@gcc.gnu.org>
[official-gcc.git] / gcc / cgraphclones.c
blob90ef90183b4616d6ea45401ba17000a185ed6521
1 /* Callgraph clones
2 Copyright (C) 2003-2013 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 provide facilities for clonning functions. I.e. creating
22 new functions based on existing functions with simple modifications,
23 such as replacement of parameters.
25 To allow whole program optimization without actual presence of function
26 bodies, an additional infrastructure is provided for so-called virtual
27 clones
29 A virtual clone in the callgraph is a function that has no
30 associated body, just a description of how to create its body based
31 on a different function (which itself may be a virtual clone).
33 The description of function modifications includes adjustments to
34 the function's signature (which allows, for example, removing or
35 adding function arguments), substitutions to perform on the
36 function body, and, for inlined functions, a pointer to the
37 function that it will be inlined into.
39 It is also possible to redirect any edge of the callgraph from a
40 function to its virtual clone. This implies updating of the call
41 site to adjust for the new function signature.
43 Most of the transformations performed by inter-procedural
44 optimizations can be represented via virtual clones. For
45 instance, a constant propagation pass can produce a virtual clone
46 of the function which replaces one of its arguments by a
47 constant. The inliner can represent its decisions by producing a
48 clone of a function whose body will be later integrated into
49 a given function.
51 Using virtual clones, the program can be easily updated
52 during the Execute stage, solving most of pass interactions
53 problems that would otherwise occur during Transform.
55 Virtual clones are later materialized in the LTRANS stage and
56 turned into real functions. Passes executed after the virtual
57 clone were introduced also perform their Transform stage
58 on new functions, so for a pass there is no significant
59 difference between operating on a real function or a virtual
60 clone introduced before its Execute stage.
62 Optimization passes then work on virtual clones introduced before
63 their Execute stage as if they were real functions. The
64 only difference is that clones are not visible during the
65 Generate Summary stage. */
67 #include "config.h"
68 #include "system.h"
69 #include "coretypes.h"
70 #include "tm.h"
71 #include "rtl.h"
72 #include "tree.h"
73 #include "stringpool.h"
74 #include "function.h"
75 #include "emit-rtl.h"
76 #include "basic-block.h"
77 #include "tree-ssa-alias.h"
78 #include "internal-fn.h"
79 #include "tree-eh.h"
80 #include "gimple-expr.h"
81 #include "is-a.h"
82 #include "gimple.h"
83 #include "bitmap.h"
84 #include "tree-cfg.h"
85 #include "tree-inline.h"
86 #include "langhooks.h"
87 #include "toplev.h"
88 #include "flags.h"
89 #include "debug.h"
90 #include "target.h"
91 #include "diagnostic.h"
92 #include "params.h"
93 #include "intl.h"
94 #include "function.h"
95 #include "ipa-prop.h"
96 #include "tree-iterator.h"
97 #include "tree-dump.h"
98 #include "gimple-pretty-print.h"
99 #include "coverage.h"
100 #include "ipa-inline.h"
101 #include "ipa-utils.h"
102 #include "lto-streamer.h"
103 #include "except.h"
105 /* Create clone of E in the node N represented by CALL_EXPR the callgraph. */
106 struct cgraph_edge *
107 cgraph_clone_edge (struct cgraph_edge *e, struct cgraph_node *n,
108 gimple call_stmt, unsigned stmt_uid, gcov_type count_scale,
109 int freq_scale, bool update_original)
111 struct cgraph_edge *new_edge;
112 gcov_type count = apply_probability (e->count, count_scale);
113 gcov_type freq;
115 /* We do not want to ignore loop nest after frequency drops to 0. */
116 if (!freq_scale)
117 freq_scale = 1;
118 freq = e->frequency * (gcov_type) freq_scale / CGRAPH_FREQ_BASE;
119 if (freq > CGRAPH_FREQ_MAX)
120 freq = CGRAPH_FREQ_MAX;
122 if (e->indirect_unknown_callee)
124 tree decl;
126 if (call_stmt && (decl = gimple_call_fndecl (call_stmt)))
128 struct cgraph_node *callee = cgraph_get_node (decl);
129 gcc_checking_assert (callee);
130 new_edge = cgraph_create_edge (n, callee, call_stmt, count, freq);
132 else
134 new_edge = cgraph_create_indirect_edge (n, call_stmt,
135 e->indirect_info->ecf_flags,
136 count, freq);
137 *new_edge->indirect_info = *e->indirect_info;
140 else
142 new_edge = cgraph_create_edge (n, e->callee, call_stmt, count, freq);
143 if (e->indirect_info)
145 new_edge->indirect_info
146 = ggc_alloc_cleared_cgraph_indirect_call_info ();
147 *new_edge->indirect_info = *e->indirect_info;
151 new_edge->inline_failed = e->inline_failed;
152 new_edge->indirect_inlining_edge = e->indirect_inlining_edge;
153 new_edge->lto_stmt_uid = stmt_uid;
154 /* Clone flags that depend on call_stmt availability manually. */
155 new_edge->can_throw_external = e->can_throw_external;
156 new_edge->call_stmt_cannot_inline_p = e->call_stmt_cannot_inline_p;
157 new_edge->speculative = e->speculative;
158 if (update_original)
160 e->count -= new_edge->count;
161 if (e->count < 0)
162 e->count = 0;
164 cgraph_call_edge_duplication_hooks (e, new_edge);
165 return new_edge;
169 /* Create node representing clone of N executed COUNT times. Decrease
170 the execution counts from original node too.
171 The new clone will have decl set to DECL that may or may not be the same
172 as decl of N.
174 When UPDATE_ORIGINAL is true, the counts are subtracted from the original
175 function's profile to reflect the fact that part of execution is handled
176 by node.
177 When CALL_DUPLICATOIN_HOOK is true, the ipa passes are acknowledged about
178 the new clone. Otherwise the caller is responsible for doing so later.
180 If the new node is being inlined into another one, NEW_INLINED_TO should be
181 the outline function the new one is (even indirectly) inlined to. All hooks
182 will see this in node's global.inlined_to, when invoked. Can be NULL if the
183 node is not inlined. */
185 struct cgraph_node *
186 cgraph_clone_node (struct cgraph_node *n, tree decl, gcov_type count, int freq,
187 bool update_original,
188 vec<cgraph_edge_p> redirect_callers,
189 bool call_duplication_hook,
190 struct cgraph_node *new_inlined_to)
192 struct cgraph_node *new_node = cgraph_create_empty_node ();
193 struct cgraph_edge *e;
194 gcov_type count_scale;
195 unsigned i;
197 new_node->decl = decl;
198 symtab_register_node (new_node);
199 new_node->origin = n->origin;
200 new_node->lto_file_data = n->lto_file_data;
201 if (new_node->origin)
203 new_node->next_nested = new_node->origin->nested;
204 new_node->origin->nested = new_node;
206 new_node->analyzed = n->analyzed;
207 new_node->definition = n->definition;
208 new_node->local = n->local;
209 new_node->externally_visible = false;
210 new_node->local.local = true;
211 new_node->global = n->global;
212 new_node->global.inlined_to = new_inlined_to;
213 new_node->rtl = n->rtl;
214 new_node->count = count;
215 new_node->frequency = n->frequency;
216 new_node->clone = n->clone;
217 new_node->clone.tree_map = NULL;
218 new_node->tp_first_run = n->tp_first_run;
219 if (n->count)
221 if (new_node->count > n->count)
222 count_scale = REG_BR_PROB_BASE;
223 else
224 count_scale = GCOV_COMPUTE_SCALE (new_node->count, n->count);
226 else
227 count_scale = 0;
228 if (update_original)
230 n->count -= count;
231 if (n->count < 0)
232 n->count = 0;
235 FOR_EACH_VEC_ELT (redirect_callers, i, e)
237 /* Redirect calls to the old version node to point to its new
238 version. */
239 cgraph_redirect_edge_callee (e, new_node);
243 for (e = n->callees;e; e=e->next_callee)
244 cgraph_clone_edge (e, new_node, e->call_stmt, e->lto_stmt_uid,
245 count_scale, freq, update_original);
247 for (e = n->indirect_calls; e; e = e->next_callee)
248 cgraph_clone_edge (e, new_node, e->call_stmt, e->lto_stmt_uid,
249 count_scale, freq, update_original);
250 ipa_clone_references (new_node, &n->ref_list);
252 new_node->next_sibling_clone = n->clones;
253 if (n->clones)
254 n->clones->prev_sibling_clone = new_node;
255 n->clones = new_node;
256 new_node->clone_of = n;
258 if (call_duplication_hook)
259 cgraph_call_node_duplication_hooks (n, new_node);
260 return new_node;
263 /* Return a new assembler name for a clone of DECL with SUFFIX. */
265 static GTY(()) unsigned int clone_fn_id_num;
267 tree
268 clone_function_name (tree decl, const char *suffix)
270 tree name = DECL_ASSEMBLER_NAME (decl);
271 size_t len = IDENTIFIER_LENGTH (name);
272 char *tmp_name, *prefix;
274 prefix = XALLOCAVEC (char, len + strlen (suffix) + 2);
275 memcpy (prefix, IDENTIFIER_POINTER (name), len);
276 strcpy (prefix + len + 1, suffix);
277 #ifndef NO_DOT_IN_LABEL
278 prefix[len] = '.';
279 #elif !defined NO_DOLLAR_IN_LABEL
280 prefix[len] = '$';
281 #else
282 prefix[len] = '_';
283 #endif
284 ASM_FORMAT_PRIVATE_NAME (tmp_name, prefix, clone_fn_id_num++);
285 return get_identifier (tmp_name);
288 /* Build variant of function type ORIG_TYPE skipping ARGS_TO_SKIP and the
289 return value if SKIP_RETURN is true. */
291 static tree
292 build_function_type_skip_args (tree orig_type, bitmap args_to_skip,
293 bool skip_return)
295 tree new_type = NULL;
296 tree args, new_args = NULL, t;
297 tree new_reversed;
298 int i = 0;
300 for (args = TYPE_ARG_TYPES (orig_type); args && args != void_list_node;
301 args = TREE_CHAIN (args), i++)
302 if (!args_to_skip || !bitmap_bit_p (args_to_skip, i))
303 new_args = tree_cons (NULL_TREE, TREE_VALUE (args), new_args);
305 new_reversed = nreverse (new_args);
306 if (args)
308 if (new_reversed)
309 TREE_CHAIN (new_args) = void_list_node;
310 else
311 new_reversed = void_list_node;
314 /* Use copy_node to preserve as much as possible from original type
315 (debug info, attribute lists etc.)
316 Exception is METHOD_TYPEs must have THIS argument.
317 When we are asked to remove it, we need to build new FUNCTION_TYPE
318 instead. */
319 if (TREE_CODE (orig_type) != METHOD_TYPE
320 || !args_to_skip
321 || !bitmap_bit_p (args_to_skip, 0))
323 new_type = build_distinct_type_copy (orig_type);
324 TYPE_ARG_TYPES (new_type) = new_reversed;
326 else
328 new_type
329 = build_distinct_type_copy (build_function_type (TREE_TYPE (orig_type),
330 new_reversed));
331 TYPE_CONTEXT (new_type) = TYPE_CONTEXT (orig_type);
334 if (skip_return)
335 TREE_TYPE (new_type) = void_type_node;
337 /* This is a new type, not a copy of an old type. Need to reassociate
338 variants. We can handle everything except the main variant lazily. */
339 t = TYPE_MAIN_VARIANT (orig_type);
340 if (t != orig_type)
342 t = build_function_type_skip_args (t, args_to_skip, skip_return);
343 TYPE_MAIN_VARIANT (new_type) = t;
344 TYPE_NEXT_VARIANT (new_type) = TYPE_NEXT_VARIANT (t);
345 TYPE_NEXT_VARIANT (t) = new_type;
347 else
349 TYPE_MAIN_VARIANT (new_type) = new_type;
350 TYPE_NEXT_VARIANT (new_type) = NULL;
353 return new_type;
356 /* Build variant of function decl ORIG_DECL skipping ARGS_TO_SKIP and the
357 return value if SKIP_RETURN is true.
359 Arguments from DECL_ARGUMENTS list can't be removed now, since they are
360 linked by TREE_CHAIN directly. The caller is responsible for eliminating
361 them when they are being duplicated (i.e. copy_arguments_for_versioning). */
363 static tree
364 build_function_decl_skip_args (tree orig_decl, bitmap args_to_skip,
365 bool skip_return)
367 tree new_decl = copy_node (orig_decl);
368 tree new_type;
370 new_type = TREE_TYPE (orig_decl);
371 if (prototype_p (new_type)
372 || (skip_return && !VOID_TYPE_P (TREE_TYPE (new_type))))
373 new_type
374 = build_function_type_skip_args (new_type, args_to_skip, skip_return);
375 TREE_TYPE (new_decl) = new_type;
377 /* For declarations setting DECL_VINDEX (i.e. methods)
378 we expect first argument to be THIS pointer. */
379 if (args_to_skip && bitmap_bit_p (args_to_skip, 0))
380 DECL_VINDEX (new_decl) = NULL_TREE;
382 /* When signature changes, we need to clear builtin info. */
383 if (DECL_BUILT_IN (new_decl)
384 && args_to_skip
385 && !bitmap_empty_p (args_to_skip))
387 DECL_BUILT_IN_CLASS (new_decl) = NOT_BUILT_IN;
388 DECL_FUNCTION_CODE (new_decl) = (enum built_in_function) 0;
390 return new_decl;
393 /* Create callgraph node clone with new declaration. The actual body will
394 be copied later at compilation stage.
396 TODO: after merging in ipa-sra use function call notes instead of args_to_skip
397 bitmap interface.
399 struct cgraph_node *
400 cgraph_create_virtual_clone (struct cgraph_node *old_node,
401 vec<cgraph_edge_p> redirect_callers,
402 vec<ipa_replace_map_p, va_gc> *tree_map,
403 bitmap args_to_skip,
404 const char * suffix)
406 tree old_decl = old_node->decl;
407 struct cgraph_node *new_node = NULL;
408 tree new_decl;
409 size_t len, i;
410 struct ipa_replace_map *map;
411 char *name;
413 if (!in_lto_p)
414 gcc_checking_assert (tree_versionable_function_p (old_decl));
416 gcc_assert (old_node->local.can_change_signature || !args_to_skip);
418 /* Make a new FUNCTION_DECL tree node */
419 if (!args_to_skip)
420 new_decl = copy_node (old_decl);
421 else
422 new_decl = build_function_decl_skip_args (old_decl, args_to_skip, false);
424 /* These pointers represent function body and will be populated only when clone
425 is materialized. */
426 gcc_assert (new_decl != old_decl);
427 DECL_STRUCT_FUNCTION (new_decl) = NULL;
428 DECL_ARGUMENTS (new_decl) = NULL;
429 DECL_INITIAL (new_decl) = NULL;
430 DECL_RESULT (new_decl) = NULL;
431 /* We can not do DECL_RESULT (new_decl) = NULL; here because of LTO partitioning
432 sometimes storing only clone decl instead of original. */
434 /* Generate a new name for the new version. */
435 len = IDENTIFIER_LENGTH (DECL_NAME (old_decl));
436 name = XALLOCAVEC (char, len + strlen (suffix) + 2);
437 memcpy (name, IDENTIFIER_POINTER (DECL_NAME (old_decl)), len);
438 strcpy (name + len + 1, suffix);
439 name[len] = '.';
440 DECL_NAME (new_decl) = get_identifier (name);
441 SET_DECL_ASSEMBLER_NAME (new_decl, clone_function_name (old_decl, suffix));
442 SET_DECL_RTL (new_decl, NULL);
444 new_node = cgraph_clone_node (old_node, new_decl, old_node->count,
445 CGRAPH_FREQ_BASE, false,
446 redirect_callers, false, NULL);
447 /* Update the properties.
448 Make clone visible only within this translation unit. Make sure
449 that is not weak also.
450 ??? We cannot use COMDAT linkage because there is no
451 ABI support for this. */
452 DECL_EXTERNAL (new_node->decl) = 0;
453 if (DECL_ONE_ONLY (old_decl))
454 DECL_SECTION_NAME (new_node->decl) = NULL;
455 DECL_COMDAT_GROUP (new_node->decl) = 0;
456 TREE_PUBLIC (new_node->decl) = 0;
457 DECL_COMDAT (new_node->decl) = 0;
458 DECL_WEAK (new_node->decl) = 0;
459 DECL_VIRTUAL_P (new_node->decl) = 0;
460 DECL_STATIC_CONSTRUCTOR (new_node->decl) = 0;
461 DECL_STATIC_DESTRUCTOR (new_node->decl) = 0;
462 new_node->clone.tree_map = tree_map;
463 new_node->clone.args_to_skip = args_to_skip;
465 /* Clones of global symbols or symbols with unique names are unique. */
466 if ((TREE_PUBLIC (old_decl)
467 && !DECL_EXTERNAL (old_decl)
468 && !DECL_WEAK (old_decl)
469 && !DECL_COMDAT (old_decl))
470 || in_lto_p)
471 new_node->unique_name = true;
472 FOR_EACH_VEC_SAFE_ELT (tree_map, i, map)
473 ipa_maybe_record_reference (new_node, map->new_tree,
474 IPA_REF_ADDR, NULL);
475 if (!args_to_skip)
476 new_node->clone.combined_args_to_skip = old_node->clone.combined_args_to_skip;
477 else if (old_node->clone.combined_args_to_skip)
479 int newi = 0, oldi = 0;
480 tree arg;
481 bitmap new_args_to_skip = BITMAP_GGC_ALLOC ();
482 struct cgraph_node *orig_node;
483 for (orig_node = old_node; orig_node->clone_of; orig_node = orig_node->clone_of)
485 for (arg = DECL_ARGUMENTS (orig_node->decl);
486 arg; arg = DECL_CHAIN (arg), oldi++)
488 if (bitmap_bit_p (old_node->clone.combined_args_to_skip, oldi))
490 bitmap_set_bit (new_args_to_skip, oldi);
491 continue;
493 if (bitmap_bit_p (args_to_skip, newi))
494 bitmap_set_bit (new_args_to_skip, oldi);
495 newi++;
497 new_node->clone.combined_args_to_skip = new_args_to_skip;
499 else
500 new_node->clone.combined_args_to_skip = args_to_skip;
501 new_node->externally_visible = 0;
502 new_node->local.local = 1;
503 new_node->lowered = true;
505 cgraph_call_node_duplication_hooks (old_node, new_node);
508 return new_node;
511 /* NODE is being removed from symbol table; see if its entry can be replaced by
512 other inline clone. */
513 struct cgraph_node *
514 cgraph_find_replacement_node (struct cgraph_node *node)
516 struct cgraph_node *next_inline_clone, *replacement;
518 for (next_inline_clone = node->clones;
519 next_inline_clone
520 && next_inline_clone->decl != node->decl;
521 next_inline_clone = next_inline_clone->next_sibling_clone)
524 /* If there is inline clone of the node being removed, we need
525 to put it into the position of removed node and reorganize all
526 other clones to be based on it. */
527 if (next_inline_clone)
529 struct cgraph_node *n;
530 struct cgraph_node *new_clones;
532 replacement = next_inline_clone;
534 /* Unlink inline clone from the list of clones of removed node. */
535 if (next_inline_clone->next_sibling_clone)
536 next_inline_clone->next_sibling_clone->prev_sibling_clone
537 = next_inline_clone->prev_sibling_clone;
538 if (next_inline_clone->prev_sibling_clone)
540 gcc_assert (node->clones != next_inline_clone);
541 next_inline_clone->prev_sibling_clone->next_sibling_clone
542 = next_inline_clone->next_sibling_clone;
544 else
546 gcc_assert (node->clones == next_inline_clone);
547 node->clones = next_inline_clone->next_sibling_clone;
550 new_clones = node->clones;
551 node->clones = NULL;
553 /* Copy clone info. */
554 next_inline_clone->clone = node->clone;
556 /* Now place it into clone tree at same level at NODE. */
557 next_inline_clone->clone_of = node->clone_of;
558 next_inline_clone->prev_sibling_clone = NULL;
559 next_inline_clone->next_sibling_clone = NULL;
560 if (node->clone_of)
562 if (node->clone_of->clones)
563 node->clone_of->clones->prev_sibling_clone = next_inline_clone;
564 next_inline_clone->next_sibling_clone = node->clone_of->clones;
565 node->clone_of->clones = next_inline_clone;
568 /* Merge the clone list. */
569 if (new_clones)
571 if (!next_inline_clone->clones)
572 next_inline_clone->clones = new_clones;
573 else
575 n = next_inline_clone->clones;
576 while (n->next_sibling_clone)
577 n = n->next_sibling_clone;
578 n->next_sibling_clone = new_clones;
579 new_clones->prev_sibling_clone = n;
583 /* Update clone_of pointers. */
584 n = new_clones;
585 while (n)
587 n->clone_of = next_inline_clone;
588 n = n->next_sibling_clone;
590 return replacement;
592 else
593 return NULL;
596 /* Like cgraph_set_call_stmt but walk the clone tree and update all
597 clones sharing the same function body.
598 When WHOLE_SPECULATIVE_EDGES is true, all three components of
599 speculative edge gets updated. Otherwise we update only direct
600 call. */
602 void
603 cgraph_set_call_stmt_including_clones (struct cgraph_node *orig,
604 gimple old_stmt, gimple new_stmt,
605 bool update_speculative)
607 struct cgraph_node *node;
608 struct cgraph_edge *edge = cgraph_edge (orig, old_stmt);
610 if (edge)
611 cgraph_set_call_stmt (edge, new_stmt, update_speculative);
613 node = orig->clones;
614 if (node)
615 while (node != orig)
617 struct cgraph_edge *edge = cgraph_edge (node, old_stmt);
618 if (edge)
620 cgraph_set_call_stmt (edge, new_stmt, update_speculative);
621 /* If UPDATE_SPECULATIVE is false, it means that we are turning
622 speculative call into a real code sequence. Update the
623 callgraph edges. */
624 if (edge->speculative && !update_speculative)
626 struct cgraph_edge *direct, *indirect;
627 struct ipa_ref *ref;
629 gcc_assert (!edge->indirect_unknown_callee);
630 cgraph_speculative_call_info (edge, direct, indirect, ref);
631 direct->speculative = false;
632 indirect->speculative = false;
633 ref->speculative = false;
636 if (node->clones)
637 node = node->clones;
638 else if (node->next_sibling_clone)
639 node = node->next_sibling_clone;
640 else
642 while (node != orig && !node->next_sibling_clone)
643 node = node->clone_of;
644 if (node != orig)
645 node = node->next_sibling_clone;
650 /* Like cgraph_create_edge walk the clone tree and update all clones sharing
651 same function body. If clones already have edge for OLD_STMT; only
652 update the edge same way as cgraph_set_call_stmt_including_clones does.
654 TODO: COUNT and LOOP_DEPTH should be properly distributed based on relative
655 frequencies of the clones. */
657 void
658 cgraph_create_edge_including_clones (struct cgraph_node *orig,
659 struct cgraph_node *callee,
660 gimple old_stmt,
661 gimple stmt, gcov_type count,
662 int freq,
663 cgraph_inline_failed_t reason)
665 struct cgraph_node *node;
666 struct cgraph_edge *edge;
668 if (!cgraph_edge (orig, stmt))
670 edge = cgraph_create_edge (orig, callee, stmt, count, freq);
671 edge->inline_failed = reason;
674 node = orig->clones;
675 if (node)
676 while (node != orig)
678 struct cgraph_edge *edge = cgraph_edge (node, old_stmt);
680 /* It is possible that clones already contain the edge while
681 master didn't. Either we promoted indirect call into direct
682 call in the clone or we are processing clones of unreachable
683 master where edges has been removed. */
684 if (edge)
685 cgraph_set_call_stmt (edge, stmt);
686 else if (!cgraph_edge (node, stmt))
688 edge = cgraph_create_edge (node, callee, stmt, count,
689 freq);
690 edge->inline_failed = reason;
693 if (node->clones)
694 node = node->clones;
695 else if (node->next_sibling_clone)
696 node = node->next_sibling_clone;
697 else
699 while (node != orig && !node->next_sibling_clone)
700 node = node->clone_of;
701 if (node != orig)
702 node = node->next_sibling_clone;
707 /* Remove the node from cgraph and all inline clones inlined into it.
708 Skip however removal of FORBIDDEN_NODE and return true if it needs to be
709 removed. This allows to call the function from outer loop walking clone
710 tree. */
712 bool
713 cgraph_remove_node_and_inline_clones (struct cgraph_node *node, struct cgraph_node *forbidden_node)
715 struct cgraph_edge *e, *next;
716 bool found = false;
718 if (node == forbidden_node)
720 cgraph_remove_edge (node->callers);
721 return true;
723 for (e = node->callees; e; e = next)
725 next = e->next_callee;
726 if (!e->inline_failed)
727 found |= cgraph_remove_node_and_inline_clones (e->callee, forbidden_node);
729 cgraph_remove_node (node);
730 return found;
733 /* The edges representing the callers of the NEW_VERSION node were
734 fixed by cgraph_function_versioning (), now the call_expr in their
735 respective tree code should be updated to call the NEW_VERSION. */
737 static void
738 update_call_expr (struct cgraph_node *new_version)
740 struct cgraph_edge *e;
742 gcc_assert (new_version);
744 /* Update the call expr on the edges to call the new version. */
745 for (e = new_version->callers; e; e = e->next_caller)
747 struct function *inner_function = DECL_STRUCT_FUNCTION (e->caller->decl);
748 gimple_call_set_fndecl (e->call_stmt, new_version->decl);
749 maybe_clean_eh_stmt_fn (inner_function, e->call_stmt);
754 /* Create a new cgraph node which is the new version of
755 OLD_VERSION node. REDIRECT_CALLERS holds the callers
756 edges which should be redirected to point to
757 NEW_VERSION. ALL the callees edges of OLD_VERSION
758 are cloned to the new version node. Return the new
759 version node.
761 If non-NULL BLOCK_TO_COPY determine what basic blocks
762 was copied to prevent duplications of calls that are dead
763 in the clone. */
765 struct cgraph_node *
766 cgraph_copy_node_for_versioning (struct cgraph_node *old_version,
767 tree new_decl,
768 vec<cgraph_edge_p> redirect_callers,
769 bitmap bbs_to_copy)
771 struct cgraph_node *new_version;
772 struct cgraph_edge *e;
773 unsigned i;
775 gcc_assert (old_version);
777 new_version = cgraph_create_node (new_decl);
779 new_version->analyzed = old_version->analyzed;
780 new_version->definition = old_version->definition;
781 new_version->local = old_version->local;
782 new_version->externally_visible = false;
783 new_version->local.local = new_version->definition;
784 new_version->global = old_version->global;
785 new_version->rtl = old_version->rtl;
786 new_version->count = old_version->count;
788 for (e = old_version->callees; e; e=e->next_callee)
789 if (!bbs_to_copy
790 || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
791 cgraph_clone_edge (e, new_version, e->call_stmt,
792 e->lto_stmt_uid, REG_BR_PROB_BASE,
793 CGRAPH_FREQ_BASE,
794 true);
795 for (e = old_version->indirect_calls; e; e=e->next_callee)
796 if (!bbs_to_copy
797 || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
798 cgraph_clone_edge (e, new_version, e->call_stmt,
799 e->lto_stmt_uid, REG_BR_PROB_BASE,
800 CGRAPH_FREQ_BASE,
801 true);
802 FOR_EACH_VEC_ELT (redirect_callers, i, e)
804 /* Redirect calls to the old version node to point to its new
805 version. */
806 cgraph_redirect_edge_callee (e, new_version);
809 cgraph_call_node_duplication_hooks (old_version, new_version);
811 return new_version;
814 /* Perform function versioning.
815 Function versioning includes copying of the tree and
816 a callgraph update (creating a new cgraph node and updating
817 its callees and callers).
819 REDIRECT_CALLERS varray includes the edges to be redirected
820 to the new version.
822 TREE_MAP is a mapping of tree nodes we want to replace with
823 new ones (according to results of prior analysis).
824 OLD_VERSION_NODE is the node that is versioned.
826 If non-NULL ARGS_TO_SKIP determine function parameters to remove
827 from new version.
828 If SKIP_RETURN is true, the new version will return void.
829 If non-NULL BLOCK_TO_COPY determine what basic blocks to copy.
830 If non_NULL NEW_ENTRY determine new entry BB of the clone.
832 Return the new version's cgraph node. */
834 struct cgraph_node *
835 cgraph_function_versioning (struct cgraph_node *old_version_node,
836 vec<cgraph_edge_p> redirect_callers,
837 vec<ipa_replace_map_p, va_gc> *tree_map,
838 bitmap args_to_skip,
839 bool skip_return,
840 bitmap bbs_to_copy,
841 basic_block new_entry_block,
842 const char *clone_name)
844 tree old_decl = old_version_node->decl;
845 struct cgraph_node *new_version_node = NULL;
846 tree new_decl;
848 if (!tree_versionable_function_p (old_decl))
849 return NULL;
851 gcc_assert (old_version_node->local.can_change_signature || !args_to_skip);
853 /* Make a new FUNCTION_DECL tree node for the new version. */
854 if (!args_to_skip && !skip_return)
855 new_decl = copy_node (old_decl);
856 else
857 new_decl
858 = build_function_decl_skip_args (old_decl, args_to_skip, skip_return);
860 /* Generate a new name for the new version. */
861 DECL_NAME (new_decl) = clone_function_name (old_decl, clone_name);
862 SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
863 SET_DECL_RTL (new_decl, NULL);
865 /* When the old decl was a con-/destructor make sure the clone isn't. */
866 DECL_STATIC_CONSTRUCTOR (new_decl) = 0;
867 DECL_STATIC_DESTRUCTOR (new_decl) = 0;
869 /* Create the new version's call-graph node.
870 and update the edges of the new node. */
871 new_version_node =
872 cgraph_copy_node_for_versioning (old_version_node, new_decl,
873 redirect_callers, bbs_to_copy);
875 /* Copy the OLD_VERSION_NODE function tree to the new version. */
876 tree_function_versioning (old_decl, new_decl, tree_map, false, args_to_skip,
877 skip_return, bbs_to_copy, new_entry_block);
879 /* Update the new version's properties.
880 Make The new version visible only within this translation unit. Make sure
881 that is not weak also.
882 ??? We cannot use COMDAT linkage because there is no
883 ABI support for this. */
884 symtab_make_decl_local (new_version_node->decl);
885 DECL_VIRTUAL_P (new_version_node->decl) = 0;
886 new_version_node->externally_visible = 0;
887 new_version_node->local.local = 1;
888 new_version_node->lowered = true;
889 /* Clones of global symbols or symbols with unique names are unique. */
890 if ((TREE_PUBLIC (old_decl)
891 && !DECL_EXTERNAL (old_decl)
892 && !DECL_WEAK (old_decl)
893 && !DECL_COMDAT (old_decl))
894 || in_lto_p)
895 new_version_node->unique_name = true;
897 /* Update the call_expr on the edges to call the new version node. */
898 update_call_expr (new_version_node);
900 cgraph_call_function_insertion_hooks (new_version_node);
901 return new_version_node;
904 /* Given virtual clone, turn it into actual clone. */
906 static void
907 cgraph_materialize_clone (struct cgraph_node *node)
909 bitmap_obstack_initialize (NULL);
910 node->former_clone_of = node->clone_of->decl;
911 if (node->clone_of->former_clone_of)
912 node->former_clone_of = node->clone_of->former_clone_of;
913 /* Copy the OLD_VERSION_NODE function tree to the new version. */
914 tree_function_versioning (node->clone_of->decl, node->decl,
915 node->clone.tree_map, true,
916 node->clone.args_to_skip, false,
917 NULL, NULL);
918 if (cgraph_dump_file)
920 dump_function_to_file (node->clone_of->decl, cgraph_dump_file, dump_flags);
921 dump_function_to_file (node->decl, cgraph_dump_file, dump_flags);
924 /* Function is no longer clone. */
925 if (node->next_sibling_clone)
926 node->next_sibling_clone->prev_sibling_clone = node->prev_sibling_clone;
927 if (node->prev_sibling_clone)
928 node->prev_sibling_clone->next_sibling_clone = node->next_sibling_clone;
929 else
930 node->clone_of->clones = node->next_sibling_clone;
931 node->next_sibling_clone = NULL;
932 node->prev_sibling_clone = NULL;
933 if (!node->clone_of->analyzed && !node->clone_of->clones)
935 cgraph_release_function_body (node->clone_of);
936 cgraph_node_remove_callees (node->clone_of);
937 ipa_remove_all_references (&node->clone_of->ref_list);
939 node->clone_of = NULL;
940 bitmap_obstack_release (NULL);
943 /* Once all functions from compilation unit are in memory, produce all clones
944 and update all calls. We might also do this on demand if we don't want to
945 bring all functions to memory prior compilation, but current WHOPR
946 implementation does that and it is is bit easier to keep everything right in
947 this order. */
949 void
950 cgraph_materialize_all_clones (void)
952 struct cgraph_node *node;
953 bool stabilized = false;
956 if (cgraph_dump_file)
957 fprintf (cgraph_dump_file, "Materializing clones\n");
958 #ifdef ENABLE_CHECKING
959 verify_cgraph ();
960 #endif
962 /* We can also do topological order, but number of iterations should be
963 bounded by number of IPA passes since single IPA pass is probably not
964 going to create clones of clones it created itself. */
965 while (!stabilized)
967 stabilized = true;
968 FOR_EACH_FUNCTION (node)
970 if (node->clone_of && node->decl != node->clone_of->decl
971 && !gimple_has_body_p (node->decl))
973 if (!node->clone_of->clone_of)
974 cgraph_get_body (node->clone_of);
975 if (gimple_has_body_p (node->clone_of->decl))
977 if (cgraph_dump_file)
979 fprintf (cgraph_dump_file, "cloning %s to %s\n",
980 xstrdup (node->clone_of->name ()),
981 xstrdup (node->name ()));
982 if (node->clone.tree_map)
984 unsigned int i;
985 fprintf (cgraph_dump_file, " replace map: ");
986 for (i = 0;
987 i < vec_safe_length (node->clone.tree_map);
988 i++)
990 struct ipa_replace_map *replace_info;
991 replace_info = (*node->clone.tree_map)[i];
992 print_generic_expr (cgraph_dump_file, replace_info->old_tree, 0);
993 fprintf (cgraph_dump_file, " -> ");
994 print_generic_expr (cgraph_dump_file, replace_info->new_tree, 0);
995 fprintf (cgraph_dump_file, "%s%s;",
996 replace_info->replace_p ? "(replace)":"",
997 replace_info->ref_p ? "(ref)":"");
999 fprintf (cgraph_dump_file, "\n");
1001 if (node->clone.args_to_skip)
1003 fprintf (cgraph_dump_file, " args_to_skip: ");
1004 dump_bitmap (cgraph_dump_file, node->clone.args_to_skip);
1006 if (node->clone.args_to_skip)
1008 fprintf (cgraph_dump_file, " combined_args_to_skip:");
1009 dump_bitmap (cgraph_dump_file, node->clone.combined_args_to_skip);
1012 cgraph_materialize_clone (node);
1013 stabilized = false;
1018 FOR_EACH_FUNCTION (node)
1019 if (!node->analyzed && node->callees)
1021 cgraph_node_remove_callees (node);
1022 ipa_remove_all_references (&node->ref_list);
1024 else
1025 ipa_clear_stmts_in_references (node);
1026 if (cgraph_dump_file)
1027 fprintf (cgraph_dump_file, "Materialization Call site updates done.\n");
1028 #ifdef ENABLE_CHECKING
1029 verify_cgraph ();
1030 #endif
1031 symtab_remove_unreachable_nodes (false, cgraph_dump_file);
1034 #include "gt-cgraphclones.h"