* gcc.dg/pr27095.c: For Epiphany, add -mshort-calls.
[official-gcc.git] / gcc / cgraphclones.c
blob04cb990cc86e635681f7b51538a89a4688d90728
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 "tree.h"
72 #include "rtl.h"
73 #include "tree-flow.h"
74 #include "tree-inline.h"
75 #include "langhooks.h"
76 #include "pointer-set.h"
77 #include "toplev.h"
78 #include "flags.h"
79 #include "ggc.h"
80 #include "debug.h"
81 #include "target.h"
82 #include "cgraph.h"
83 #include "diagnostic.h"
84 #include "params.h"
85 #include "intl.h"
86 #include "function.h"
87 #include "ipa-prop.h"
88 #include "gimple.h"
89 #include "tree-iterator.h"
90 #include "tree-dump.h"
91 #include "gimple-pretty-print.h"
92 #include "coverage.h"
93 #include "ipa-inline.h"
94 #include "ipa-utils.h"
95 #include "lto-streamer.h"
96 #include "except.h"
98 /* Create clone of E in the node N represented by CALL_EXPR the callgraph. */
99 struct cgraph_edge *
100 cgraph_clone_edge (struct cgraph_edge *e, struct cgraph_node *n,
101 gimple call_stmt, unsigned stmt_uid, gcov_type count_scale,
102 int freq_scale, bool update_original)
104 struct cgraph_edge *new_edge;
105 gcov_type count = apply_probability (e->count, count_scale);
106 gcov_type freq;
108 /* We do not want to ignore loop nest after frequency drops to 0. */
109 if (!freq_scale)
110 freq_scale = 1;
111 freq = e->frequency * (gcov_type) freq_scale / CGRAPH_FREQ_BASE;
112 if (freq > CGRAPH_FREQ_MAX)
113 freq = CGRAPH_FREQ_MAX;
115 if (e->indirect_unknown_callee)
117 tree decl;
119 if (call_stmt && (decl = gimple_call_fndecl (call_stmt)))
121 struct cgraph_node *callee = cgraph_get_node (decl);
122 gcc_checking_assert (callee);
123 new_edge = cgraph_create_edge (n, callee, call_stmt, count, freq);
125 else
127 new_edge = cgraph_create_indirect_edge (n, call_stmt,
128 e->indirect_info->ecf_flags,
129 count, freq);
130 *new_edge->indirect_info = *e->indirect_info;
133 else
135 new_edge = cgraph_create_edge (n, e->callee, call_stmt, count, freq);
136 if (e->indirect_info)
138 new_edge->indirect_info
139 = ggc_alloc_cleared_cgraph_indirect_call_info ();
140 *new_edge->indirect_info = *e->indirect_info;
144 new_edge->inline_failed = e->inline_failed;
145 new_edge->indirect_inlining_edge = e->indirect_inlining_edge;
146 new_edge->lto_stmt_uid = stmt_uid;
147 /* Clone flags that depend on call_stmt availability manually. */
148 new_edge->can_throw_external = e->can_throw_external;
149 new_edge->call_stmt_cannot_inline_p = e->call_stmt_cannot_inline_p;
150 if (update_original)
152 e->count -= new_edge->count;
153 if (e->count < 0)
154 e->count = 0;
156 cgraph_call_edge_duplication_hooks (e, new_edge);
157 return new_edge;
161 /* Create node representing clone of N executed COUNT times. Decrease
162 the execution counts from original node too.
163 The new clone will have decl set to DECL that may or may not be the same
164 as decl of N.
166 When UPDATE_ORIGINAL is true, the counts are subtracted from the original
167 function's profile to reflect the fact that part of execution is handled
168 by node.
169 When CALL_DUPLICATOIN_HOOK is true, the ipa passes are acknowledged about
170 the new clone. Otherwise the caller is responsible for doing so later.
172 If the new node is being inlined into another one, NEW_INLINED_TO should be
173 the outline function the new one is (even indirectly) inlined to. All hooks
174 will see this in node's global.inlined_to, when invoked. Can be NULL if the
175 node is not inlined. */
177 struct cgraph_node *
178 cgraph_clone_node (struct cgraph_node *n, tree decl, gcov_type count, int freq,
179 bool update_original,
180 vec<cgraph_edge_p> redirect_callers,
181 bool call_duplication_hook,
182 struct cgraph_node *new_inlined_to)
184 struct cgraph_node *new_node = cgraph_create_empty_node ();
185 struct cgraph_edge *e;
186 gcov_type count_scale;
187 unsigned i;
189 new_node->symbol.decl = decl;
190 symtab_register_node ((symtab_node)new_node);
191 new_node->origin = n->origin;
192 new_node->symbol.lto_file_data = n->symbol.lto_file_data;
193 if (new_node->origin)
195 new_node->next_nested = new_node->origin->nested;
196 new_node->origin->nested = new_node;
198 new_node->symbol.analyzed = n->symbol.analyzed;
199 new_node->symbol.definition = n->symbol.definition;
200 new_node->local = n->local;
201 new_node->symbol.externally_visible = false;
202 new_node->local.local = true;
203 new_node->global = n->global;
204 new_node->global.inlined_to = new_inlined_to;
205 new_node->rtl = n->rtl;
206 new_node->count = count;
207 new_node->frequency = n->frequency;
208 new_node->clone = n->clone;
209 new_node->clone.tree_map = NULL;
210 if (n->count)
212 if (new_node->count > n->count)
213 count_scale = REG_BR_PROB_BASE;
214 else
215 count_scale = GCOV_COMPUTE_SCALE (new_node->count, n->count);
217 else
218 count_scale = 0;
219 if (update_original)
221 n->count -= count;
222 if (n->count < 0)
223 n->count = 0;
226 FOR_EACH_VEC_ELT (redirect_callers, i, e)
228 /* Redirect calls to the old version node to point to its new
229 version. */
230 cgraph_redirect_edge_callee (e, new_node);
234 for (e = n->callees;e; e=e->next_callee)
235 cgraph_clone_edge (e, new_node, e->call_stmt, e->lto_stmt_uid,
236 count_scale, freq, update_original);
238 for (e = n->indirect_calls; e; e = e->next_callee)
239 cgraph_clone_edge (e, new_node, e->call_stmt, e->lto_stmt_uid,
240 count_scale, freq, update_original);
241 ipa_clone_references ((symtab_node)new_node, &n->symbol.ref_list);
243 new_node->next_sibling_clone = n->clones;
244 if (n->clones)
245 n->clones->prev_sibling_clone = new_node;
246 n->clones = new_node;
247 new_node->clone_of = n;
249 if (call_duplication_hook)
250 cgraph_call_node_duplication_hooks (n, new_node);
251 return new_node;
254 /* Create a new name for clone of DECL, add SUFFIX. Returns an identifier. */
256 static GTY(()) unsigned int clone_fn_id_num;
258 tree
259 clone_function_name (tree decl, const char *suffix)
261 tree name = DECL_ASSEMBLER_NAME (decl);
262 size_t len = IDENTIFIER_LENGTH (name);
263 char *tmp_name, *prefix;
265 prefix = XALLOCAVEC (char, len + strlen (suffix) + 2);
266 memcpy (prefix, IDENTIFIER_POINTER (name), len);
267 strcpy (prefix + len + 1, suffix);
268 #ifndef NO_DOT_IN_LABEL
269 prefix[len] = '.';
270 #elif !defined NO_DOLLAR_IN_LABEL
271 prefix[len] = '$';
272 #else
273 prefix[len] = '_';
274 #endif
275 ASM_FORMAT_PRIVATE_NAME (tmp_name, prefix, clone_fn_id_num++);
276 return get_identifier (tmp_name);
279 /* Create callgraph node clone with new declaration. The actual body will
280 be copied later at compilation stage.
282 TODO: after merging in ipa-sra use function call notes instead of args_to_skip
283 bitmap interface.
285 struct cgraph_node *
286 cgraph_create_virtual_clone (struct cgraph_node *old_node,
287 vec<cgraph_edge_p> redirect_callers,
288 vec<ipa_replace_map_p, va_gc> *tree_map,
289 bitmap args_to_skip,
290 const char * suffix)
292 tree old_decl = old_node->symbol.decl;
293 struct cgraph_node *new_node = NULL;
294 tree new_decl;
295 size_t i;
296 struct ipa_replace_map *map;
298 if (!flag_wpa)
299 gcc_checking_assert (tree_versionable_function_p (old_decl));
301 gcc_assert (old_node->local.can_change_signature || !args_to_skip);
303 /* Make a new FUNCTION_DECL tree node */
304 if (!args_to_skip)
305 new_decl = copy_node (old_decl);
306 else
307 new_decl = build_function_decl_skip_args (old_decl, args_to_skip, false);
309 /* These pointers represent function body and will be populated only when clone
310 is materialized. */
311 gcc_assert (new_decl != old_decl);
312 DECL_STRUCT_FUNCTION (new_decl) = NULL;
313 DECL_ARGUMENTS (new_decl) = NULL;
314 DECL_INITIAL (new_decl) = NULL;
315 DECL_RESULT (new_decl) = NULL;
316 /* We can not do DECL_RESULT (new_decl) = NULL; here because of LTO partitioning
317 sometimes storing only clone decl instead of original. */
319 /* Generate a new name for the new version. */
320 DECL_NAME (new_decl) = clone_function_name (old_decl, suffix);
321 SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
322 SET_DECL_RTL (new_decl, NULL);
324 new_node = cgraph_clone_node (old_node, new_decl, old_node->count,
325 CGRAPH_FREQ_BASE, false,
326 redirect_callers, false, NULL);
327 /* Update the properties.
328 Make clone visible only within this translation unit. Make sure
329 that is not weak also.
330 ??? We cannot use COMDAT linkage because there is no
331 ABI support for this. */
332 DECL_EXTERNAL (new_node->symbol.decl) = 0;
333 if (DECL_ONE_ONLY (old_decl))
334 DECL_SECTION_NAME (new_node->symbol.decl) = NULL;
335 DECL_COMDAT_GROUP (new_node->symbol.decl) = 0;
336 TREE_PUBLIC (new_node->symbol.decl) = 0;
337 DECL_COMDAT (new_node->symbol.decl) = 0;
338 DECL_WEAK (new_node->symbol.decl) = 0;
339 DECL_VIRTUAL_P (new_node->symbol.decl) = 0;
340 DECL_STATIC_CONSTRUCTOR (new_node->symbol.decl) = 0;
341 DECL_STATIC_DESTRUCTOR (new_node->symbol.decl) = 0;
342 new_node->clone.tree_map = tree_map;
343 new_node->clone.args_to_skip = args_to_skip;
345 /* Clones of global symbols or symbols with unique names are unique. */
346 if ((TREE_PUBLIC (old_decl)
347 && !DECL_EXTERNAL (old_decl)
348 && !DECL_WEAK (old_decl)
349 && !DECL_COMDAT (old_decl))
350 || in_lto_p)
351 new_node->symbol.unique_name = true;
352 FOR_EACH_VEC_SAFE_ELT (tree_map, i, map)
353 ipa_maybe_record_reference ((symtab_node) new_node, map->new_tree,
354 IPA_REF_ADDR, NULL);
355 if (!args_to_skip)
356 new_node->clone.combined_args_to_skip = old_node->clone.combined_args_to_skip;
357 else if (old_node->clone.combined_args_to_skip)
359 int newi = 0, oldi = 0;
360 tree arg;
361 bitmap new_args_to_skip = BITMAP_GGC_ALLOC ();
362 struct cgraph_node *orig_node;
363 for (orig_node = old_node; orig_node->clone_of; orig_node = orig_node->clone_of)
365 for (arg = DECL_ARGUMENTS (orig_node->symbol.decl);
366 arg; arg = DECL_CHAIN (arg), oldi++)
368 if (bitmap_bit_p (old_node->clone.combined_args_to_skip, oldi))
370 bitmap_set_bit (new_args_to_skip, oldi);
371 continue;
373 if (bitmap_bit_p (args_to_skip, newi))
374 bitmap_set_bit (new_args_to_skip, oldi);
375 newi++;
377 new_node->clone.combined_args_to_skip = new_args_to_skip;
379 else
380 new_node->clone.combined_args_to_skip = args_to_skip;
381 new_node->symbol.externally_visible = 0;
382 new_node->local.local = 1;
383 new_node->lowered = true;
385 cgraph_call_node_duplication_hooks (old_node, new_node);
388 return new_node;
391 /* NODE is being removed from symbol table; see if its entry can be replaced by
392 other inline clone. */
393 struct cgraph_node *
394 cgraph_find_replacement_node (struct cgraph_node *node)
396 struct cgraph_node *next_inline_clone, *replacement;
398 for (next_inline_clone = node->clones;
399 next_inline_clone
400 && next_inline_clone->symbol.decl != node->symbol.decl;
401 next_inline_clone = next_inline_clone->next_sibling_clone)
404 /* If there is inline clone of the node being removed, we need
405 to put it into the position of removed node and reorganize all
406 other clones to be based on it. */
407 if (next_inline_clone)
409 struct cgraph_node *n;
410 struct cgraph_node *new_clones;
412 replacement = next_inline_clone;
414 /* Unlink inline clone from the list of clones of removed node. */
415 if (next_inline_clone->next_sibling_clone)
416 next_inline_clone->next_sibling_clone->prev_sibling_clone
417 = next_inline_clone->prev_sibling_clone;
418 if (next_inline_clone->prev_sibling_clone)
420 gcc_assert (node->clones != next_inline_clone);
421 next_inline_clone->prev_sibling_clone->next_sibling_clone
422 = next_inline_clone->next_sibling_clone;
424 else
426 gcc_assert (node->clones == next_inline_clone);
427 node->clones = next_inline_clone->next_sibling_clone;
430 new_clones = node->clones;
431 node->clones = NULL;
433 /* Copy clone info. */
434 next_inline_clone->clone = node->clone;
436 /* Now place it into clone tree at same level at NODE. */
437 next_inline_clone->clone_of = node->clone_of;
438 next_inline_clone->prev_sibling_clone = NULL;
439 next_inline_clone->next_sibling_clone = NULL;
440 if (node->clone_of)
442 if (node->clone_of->clones)
443 node->clone_of->clones->prev_sibling_clone = next_inline_clone;
444 next_inline_clone->next_sibling_clone = node->clone_of->clones;
445 node->clone_of->clones = next_inline_clone;
448 /* Merge the clone list. */
449 if (new_clones)
451 if (!next_inline_clone->clones)
452 next_inline_clone->clones = new_clones;
453 else
455 n = next_inline_clone->clones;
456 while (n->next_sibling_clone)
457 n = n->next_sibling_clone;
458 n->next_sibling_clone = new_clones;
459 new_clones->prev_sibling_clone = n;
463 /* Update clone_of pointers. */
464 n = new_clones;
465 while (n)
467 n->clone_of = next_inline_clone;
468 n = n->next_sibling_clone;
470 return replacement;
472 else
473 return NULL;
476 /* Like cgraph_set_call_stmt but walk the clone tree and update all
477 clones sharing the same function body. */
479 void
480 cgraph_set_call_stmt_including_clones (struct cgraph_node *orig,
481 gimple old_stmt, gimple new_stmt)
483 struct cgraph_node *node;
484 struct cgraph_edge *edge = cgraph_edge (orig, old_stmt);
486 if (edge)
487 cgraph_set_call_stmt (edge, new_stmt);
489 node = orig->clones;
490 if (node)
491 while (node != orig)
493 struct cgraph_edge *edge = cgraph_edge (node, old_stmt);
494 if (edge)
495 cgraph_set_call_stmt (edge, new_stmt);
496 if (node->clones)
497 node = node->clones;
498 else if (node->next_sibling_clone)
499 node = node->next_sibling_clone;
500 else
502 while (node != orig && !node->next_sibling_clone)
503 node = node->clone_of;
504 if (node != orig)
505 node = node->next_sibling_clone;
510 /* Like cgraph_create_edge walk the clone tree and update all clones sharing
511 same function body. If clones already have edge for OLD_STMT; only
512 update the edge same way as cgraph_set_call_stmt_including_clones does.
514 TODO: COUNT and LOOP_DEPTH should be properly distributed based on relative
515 frequencies of the clones. */
517 void
518 cgraph_create_edge_including_clones (struct cgraph_node *orig,
519 struct cgraph_node *callee,
520 gimple old_stmt,
521 gimple stmt, gcov_type count,
522 int freq,
523 cgraph_inline_failed_t reason)
525 struct cgraph_node *node;
526 struct cgraph_edge *edge;
528 if (!cgraph_edge (orig, stmt))
530 edge = cgraph_create_edge (orig, callee, stmt, count, freq);
531 edge->inline_failed = reason;
534 node = orig->clones;
535 if (node)
536 while (node != orig)
538 struct cgraph_edge *edge = cgraph_edge (node, old_stmt);
540 /* It is possible that clones already contain the edge while
541 master didn't. Either we promoted indirect call into direct
542 call in the clone or we are processing clones of unreachable
543 master where edges has been removed. */
544 if (edge)
545 cgraph_set_call_stmt (edge, stmt);
546 else if (!cgraph_edge (node, stmt))
548 edge = cgraph_create_edge (node, callee, stmt, count,
549 freq);
550 edge->inline_failed = reason;
553 if (node->clones)
554 node = node->clones;
555 else if (node->next_sibling_clone)
556 node = node->next_sibling_clone;
557 else
559 while (node != orig && !node->next_sibling_clone)
560 node = node->clone_of;
561 if (node != orig)
562 node = node->next_sibling_clone;
567 /* Remove the node from cgraph and all inline clones inlined into it.
568 Skip however removal of FORBIDDEN_NODE and return true if it needs to be
569 removed. This allows to call the function from outer loop walking clone
570 tree. */
572 bool
573 cgraph_remove_node_and_inline_clones (struct cgraph_node *node, struct cgraph_node *forbidden_node)
575 struct cgraph_edge *e, *next;
576 bool found = false;
578 if (node == forbidden_node)
580 cgraph_remove_edge (node->callers);
581 return true;
583 for (e = node->callees; e; e = next)
585 next = e->next_callee;
586 if (!e->inline_failed)
587 found |= cgraph_remove_node_and_inline_clones (e->callee, forbidden_node);
589 cgraph_remove_node (node);
590 return found;
593 /* The edges representing the callers of the NEW_VERSION node were
594 fixed by cgraph_function_versioning (), now the call_expr in their
595 respective tree code should be updated to call the NEW_VERSION. */
597 static void
598 update_call_expr (struct cgraph_node *new_version)
600 struct cgraph_edge *e;
602 gcc_assert (new_version);
604 /* Update the call expr on the edges to call the new version. */
605 for (e = new_version->callers; e; e = e->next_caller)
607 struct function *inner_function = DECL_STRUCT_FUNCTION (e->caller->symbol.decl);
608 gimple_call_set_fndecl (e->call_stmt, new_version->symbol.decl);
609 maybe_clean_eh_stmt_fn (inner_function, e->call_stmt);
614 /* Create a new cgraph node which is the new version of
615 OLD_VERSION node. REDIRECT_CALLERS holds the callers
616 edges which should be redirected to point to
617 NEW_VERSION. ALL the callees edges of OLD_VERSION
618 are cloned to the new version node. Return the new
619 version node.
621 If non-NULL BLOCK_TO_COPY determine what basic blocks
622 was copied to prevent duplications of calls that are dead
623 in the clone. */
625 struct cgraph_node *
626 cgraph_copy_node_for_versioning (struct cgraph_node *old_version,
627 tree new_decl,
628 vec<cgraph_edge_p> redirect_callers,
629 bitmap bbs_to_copy)
631 struct cgraph_node *new_version;
632 struct cgraph_edge *e;
633 unsigned i;
635 gcc_assert (old_version);
637 new_version = cgraph_create_node (new_decl);
639 new_version->symbol.analyzed = old_version->symbol.analyzed;
640 new_version->symbol.definition = old_version->symbol.definition;
641 new_version->local = old_version->local;
642 new_version->symbol.externally_visible = false;
643 new_version->local.local = new_version->symbol.definition;
644 new_version->global = old_version->global;
645 new_version->rtl = old_version->rtl;
646 new_version->count = old_version->count;
648 for (e = old_version->callees; e; e=e->next_callee)
649 if (!bbs_to_copy
650 || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
651 cgraph_clone_edge (e, new_version, e->call_stmt,
652 e->lto_stmt_uid, REG_BR_PROB_BASE,
653 CGRAPH_FREQ_BASE,
654 true);
655 for (e = old_version->indirect_calls; e; e=e->next_callee)
656 if (!bbs_to_copy
657 || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
658 cgraph_clone_edge (e, new_version, e->call_stmt,
659 e->lto_stmt_uid, REG_BR_PROB_BASE,
660 CGRAPH_FREQ_BASE,
661 true);
662 FOR_EACH_VEC_ELT (redirect_callers, i, e)
664 /* Redirect calls to the old version node to point to its new
665 version. */
666 cgraph_redirect_edge_callee (e, new_version);
669 cgraph_call_node_duplication_hooks (old_version, new_version);
671 return new_version;
674 /* Perform function versioning.
675 Function versioning includes copying of the tree and
676 a callgraph update (creating a new cgraph node and updating
677 its callees and callers).
679 REDIRECT_CALLERS varray includes the edges to be redirected
680 to the new version.
682 TREE_MAP is a mapping of tree nodes we want to replace with
683 new ones (according to results of prior analysis).
684 OLD_VERSION_NODE is the node that is versioned.
686 If non-NULL ARGS_TO_SKIP determine function parameters to remove
687 from new version.
688 If SKIP_RETURN is true, the new version will return void.
689 If non-NULL BLOCK_TO_COPY determine what basic blocks to copy.
690 If non_NULL NEW_ENTRY determine new entry BB of the clone.
692 Return the new version's cgraph node. */
694 struct cgraph_node *
695 cgraph_function_versioning (struct cgraph_node *old_version_node,
696 vec<cgraph_edge_p> redirect_callers,
697 vec<ipa_replace_map_p, va_gc> *tree_map,
698 bitmap args_to_skip,
699 bool skip_return,
700 bitmap bbs_to_copy,
701 basic_block new_entry_block,
702 const char *clone_name)
704 tree old_decl = old_version_node->symbol.decl;
705 struct cgraph_node *new_version_node = NULL;
706 tree new_decl;
708 if (!tree_versionable_function_p (old_decl))
709 return NULL;
711 gcc_assert (old_version_node->local.can_change_signature || !args_to_skip);
713 /* Make a new FUNCTION_DECL tree node for the new version. */
714 if (!args_to_skip && !skip_return)
715 new_decl = copy_node (old_decl);
716 else
717 new_decl
718 = build_function_decl_skip_args (old_decl, args_to_skip, skip_return);
720 /* Generate a new name for the new version. */
721 DECL_NAME (new_decl) = clone_function_name (old_decl, clone_name);
722 SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
723 SET_DECL_RTL (new_decl, NULL);
725 /* When the old decl was a con-/destructor make sure the clone isn't. */
726 DECL_STATIC_CONSTRUCTOR(new_decl) = 0;
727 DECL_STATIC_DESTRUCTOR(new_decl) = 0;
729 /* Create the new version's call-graph node.
730 and update the edges of the new node. */
731 new_version_node =
732 cgraph_copy_node_for_versioning (old_version_node, new_decl,
733 redirect_callers, bbs_to_copy);
735 /* Copy the OLD_VERSION_NODE function tree to the new version. */
736 tree_function_versioning (old_decl, new_decl, tree_map, false, args_to_skip,
737 skip_return, bbs_to_copy, new_entry_block);
739 /* Update the new version's properties.
740 Make The new version visible only within this translation unit. Make sure
741 that is not weak also.
742 ??? We cannot use COMDAT linkage because there is no
743 ABI support for this. */
744 symtab_make_decl_local (new_version_node->symbol.decl);
745 DECL_VIRTUAL_P (new_version_node->symbol.decl) = 0;
746 new_version_node->symbol.externally_visible = 0;
747 new_version_node->local.local = 1;
748 new_version_node->lowered = true;
749 /* Clones of global symbols or symbols with unique names are unique. */
750 if ((TREE_PUBLIC (old_decl)
751 && !DECL_EXTERNAL (old_decl)
752 && !DECL_WEAK (old_decl)
753 && !DECL_COMDAT (old_decl))
754 || in_lto_p)
755 new_version_node->symbol.unique_name = true;
757 /* Update the call_expr on the edges to call the new version node. */
758 update_call_expr (new_version_node);
760 cgraph_call_function_insertion_hooks (new_version_node);
761 return new_version_node;
764 /* Given virtual clone, turn it into actual clone. */
766 static void
767 cgraph_materialize_clone (struct cgraph_node *node)
769 bitmap_obstack_initialize (NULL);
770 node->former_clone_of = node->clone_of->symbol.decl;
771 if (node->clone_of->former_clone_of)
772 node->former_clone_of = node->clone_of->former_clone_of;
773 /* Copy the OLD_VERSION_NODE function tree to the new version. */
774 tree_function_versioning (node->clone_of->symbol.decl, node->symbol.decl,
775 node->clone.tree_map, true,
776 node->clone.args_to_skip, false,
777 NULL, NULL);
778 if (cgraph_dump_file)
780 dump_function_to_file (node->clone_of->symbol.decl, cgraph_dump_file, dump_flags);
781 dump_function_to_file (node->symbol.decl, cgraph_dump_file, dump_flags);
784 /* Function is no longer clone. */
785 if (node->next_sibling_clone)
786 node->next_sibling_clone->prev_sibling_clone = node->prev_sibling_clone;
787 if (node->prev_sibling_clone)
788 node->prev_sibling_clone->next_sibling_clone = node->next_sibling_clone;
789 else
790 node->clone_of->clones = node->next_sibling_clone;
791 node->next_sibling_clone = NULL;
792 node->prev_sibling_clone = NULL;
793 if (!node->clone_of->symbol.analyzed && !node->clone_of->clones)
795 cgraph_release_function_body (node->clone_of);
796 cgraph_node_remove_callees (node->clone_of);
797 ipa_remove_all_references (&node->clone_of->symbol.ref_list);
799 node->clone_of = NULL;
800 bitmap_obstack_release (NULL);
803 /* Once all functions from compilation unit are in memory, produce all clones
804 and update all calls. We might also do this on demand if we don't want to
805 bring all functions to memory prior compilation, but current WHOPR
806 implementation does that and it is is bit easier to keep everything right in
807 this order. */
809 void
810 cgraph_materialize_all_clones (void)
812 struct cgraph_node *node;
813 bool stabilized = false;
815 if (cgraph_dump_file)
816 fprintf (cgraph_dump_file, "Materializing clones\n");
817 #ifdef ENABLE_CHECKING
818 verify_cgraph ();
819 #endif
821 /* We can also do topological order, but number of iterations should be
822 bounded by number of IPA passes since single IPA pass is probably not
823 going to create clones of clones it created itself. */
824 while (!stabilized)
826 stabilized = true;
827 FOR_EACH_FUNCTION (node)
829 if (node->clone_of && node->symbol.decl != node->clone_of->symbol.decl
830 && !gimple_has_body_p (node->symbol.decl))
832 if (gimple_has_body_p (node->clone_of->symbol.decl))
834 if (cgraph_dump_file)
836 fprintf (cgraph_dump_file, "cloning %s to %s\n",
837 xstrdup (cgraph_node_name (node->clone_of)),
838 xstrdup (cgraph_node_name (node)));
839 if (node->clone.tree_map)
841 unsigned int i;
842 fprintf (cgraph_dump_file, " replace map: ");
843 for (i = 0;
844 i < vec_safe_length (node->clone.tree_map);
845 i++)
847 struct ipa_replace_map *replace_info;
848 replace_info = (*node->clone.tree_map)[i];
849 print_generic_expr (cgraph_dump_file, replace_info->old_tree, 0);
850 fprintf (cgraph_dump_file, " -> ");
851 print_generic_expr (cgraph_dump_file, replace_info->new_tree, 0);
852 fprintf (cgraph_dump_file, "%s%s;",
853 replace_info->replace_p ? "(replace)":"",
854 replace_info->ref_p ? "(ref)":"");
856 fprintf (cgraph_dump_file, "\n");
858 if (node->clone.args_to_skip)
860 fprintf (cgraph_dump_file, " args_to_skip: ");
861 dump_bitmap (cgraph_dump_file, node->clone.args_to_skip);
863 if (node->clone.args_to_skip)
865 fprintf (cgraph_dump_file, " combined_args_to_skip:");
866 dump_bitmap (cgraph_dump_file, node->clone.combined_args_to_skip);
869 cgraph_materialize_clone (node);
870 stabilized = false;
875 FOR_EACH_FUNCTION (node)
876 if (!node->symbol.analyzed && node->callees)
877 cgraph_node_remove_callees (node);
878 if (cgraph_dump_file)
879 fprintf (cgraph_dump_file, "Materialization Call site updates done.\n");
880 #ifdef ENABLE_CHECKING
881 verify_cgraph ();
882 #endif
883 symtab_remove_unreachable_nodes (false, cgraph_dump_file);
886 #include "gt-cgraphclones.h"