gcc/ChangeLog
[official-gcc.git] / gcc / cgraphclones.c
bloba002c689db952d67592dbe08b93d5e2b3412e65e
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 struct cgraph_node *
173 cgraph_clone_node (struct cgraph_node *n, tree decl, gcov_type count, int freq,
174 bool update_original,
175 vec<cgraph_edge_p> redirect_callers,
176 bool call_duplication_hook)
178 struct cgraph_node *new_node = cgraph_create_empty_node ();
179 struct cgraph_edge *e;
180 gcov_type count_scale;
181 unsigned i;
183 new_node->symbol.decl = decl;
184 symtab_register_node ((symtab_node)new_node);
185 new_node->origin = n->origin;
186 new_node->symbol.lto_file_data = n->symbol.lto_file_data;
187 if (new_node->origin)
189 new_node->next_nested = new_node->origin->nested;
190 new_node->origin->nested = new_node;
192 new_node->analyzed = n->analyzed;
193 new_node->local = n->local;
194 new_node->symbol.externally_visible = false;
195 new_node->local.local = true;
196 new_node->global = n->global;
197 new_node->rtl = n->rtl;
198 new_node->count = count;
199 new_node->frequency = n->frequency;
200 new_node->clone = n->clone;
201 new_node->clone.tree_map = NULL;
202 if (n->count)
204 if (new_node->count > n->count)
205 count_scale = REG_BR_PROB_BASE;
206 else
207 count_scale = GCOV_COMPUTE_SCALE (new_node->count, n->count);
209 else
210 count_scale = 0;
211 if (update_original)
213 n->count -= count;
214 if (n->count < 0)
215 n->count = 0;
218 FOR_EACH_VEC_ELT (redirect_callers, i, e)
220 /* Redirect calls to the old version node to point to its new
221 version. */
222 cgraph_redirect_edge_callee (e, new_node);
226 for (e = n->callees;e; e=e->next_callee)
227 cgraph_clone_edge (e, new_node, e->call_stmt, e->lto_stmt_uid,
228 count_scale, freq, update_original);
230 for (e = n->indirect_calls; e; e = e->next_callee)
231 cgraph_clone_edge (e, new_node, e->call_stmt, e->lto_stmt_uid,
232 count_scale, freq, update_original);
233 ipa_clone_references ((symtab_node)new_node, &n->symbol.ref_list);
235 new_node->next_sibling_clone = n->clones;
236 if (n->clones)
237 n->clones->prev_sibling_clone = new_node;
238 n->clones = new_node;
239 new_node->clone_of = n;
241 if (call_duplication_hook)
242 cgraph_call_node_duplication_hooks (n, new_node);
243 return new_node;
246 /* Create a new name for clone of DECL, add SUFFIX. Returns an identifier. */
248 static GTY(()) unsigned int clone_fn_id_num;
250 tree
251 clone_function_name (tree decl, const char *suffix)
253 tree name = DECL_ASSEMBLER_NAME (decl);
254 size_t len = IDENTIFIER_LENGTH (name);
255 char *tmp_name, *prefix;
257 prefix = XALLOCAVEC (char, len + strlen (suffix) + 2);
258 memcpy (prefix, IDENTIFIER_POINTER (name), len);
259 strcpy (prefix + len + 1, suffix);
260 #ifndef NO_DOT_IN_LABEL
261 prefix[len] = '.';
262 #elif !defined NO_DOLLAR_IN_LABEL
263 prefix[len] = '$';
264 #else
265 prefix[len] = '_';
266 #endif
267 ASM_FORMAT_PRIVATE_NAME (tmp_name, prefix, clone_fn_id_num++);
268 return get_identifier (tmp_name);
271 /* Create callgraph node clone with new declaration. The actual body will
272 be copied later at compilation stage.
274 TODO: after merging in ipa-sra use function call notes instead of args_to_skip
275 bitmap interface.
277 struct cgraph_node *
278 cgraph_create_virtual_clone (struct cgraph_node *old_node,
279 vec<cgraph_edge_p> redirect_callers,
280 vec<ipa_replace_map_p, va_gc> *tree_map,
281 bitmap args_to_skip,
282 const char * suffix)
284 tree old_decl = old_node->symbol.decl;
285 struct cgraph_node *new_node = NULL;
286 tree new_decl;
287 size_t i;
288 struct ipa_replace_map *map;
290 if (!flag_wpa)
291 gcc_checking_assert (tree_versionable_function_p (old_decl));
293 gcc_assert (old_node->local.can_change_signature || !args_to_skip);
295 /* Make a new FUNCTION_DECL tree node */
296 if (!args_to_skip)
297 new_decl = copy_node (old_decl);
298 else
299 new_decl = build_function_decl_skip_args (old_decl, args_to_skip, false);
300 DECL_STRUCT_FUNCTION (new_decl) = NULL;
302 /* Generate a new name for the new version. */
303 DECL_NAME (new_decl) = clone_function_name (old_decl, suffix);
304 SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
305 SET_DECL_RTL (new_decl, NULL);
307 new_node = cgraph_clone_node (old_node, new_decl, old_node->count,
308 CGRAPH_FREQ_BASE, false,
309 redirect_callers, false);
310 /* Update the properties.
311 Make clone visible only within this translation unit. Make sure
312 that is not weak also.
313 ??? We cannot use COMDAT linkage because there is no
314 ABI support for this. */
315 DECL_EXTERNAL (new_node->symbol.decl) = 0;
316 if (DECL_ONE_ONLY (old_decl))
317 DECL_SECTION_NAME (new_node->symbol.decl) = NULL;
318 DECL_COMDAT_GROUP (new_node->symbol.decl) = 0;
319 TREE_PUBLIC (new_node->symbol.decl) = 0;
320 DECL_COMDAT (new_node->symbol.decl) = 0;
321 DECL_WEAK (new_node->symbol.decl) = 0;
322 DECL_VIRTUAL_P (new_node->symbol.decl) = 0;
323 DECL_STATIC_CONSTRUCTOR (new_node->symbol.decl) = 0;
324 DECL_STATIC_DESTRUCTOR (new_node->symbol.decl) = 0;
325 new_node->clone.tree_map = tree_map;
326 new_node->clone.args_to_skip = args_to_skip;
328 /* Clones of global symbols or symbols with unique names are unique. */
329 if ((TREE_PUBLIC (old_decl)
330 && !DECL_EXTERNAL (old_decl)
331 && !DECL_WEAK (old_decl)
332 && !DECL_COMDAT (old_decl))
333 || in_lto_p)
334 new_node->symbol.unique_name = true;
335 FOR_EACH_VEC_SAFE_ELT (tree_map, i, map)
337 tree var = map->new_tree;
338 symtab_node ref_node;
340 STRIP_NOPS (var);
341 if (TREE_CODE (var) != ADDR_EXPR)
342 continue;
343 var = get_base_var (var);
344 if (!var)
345 continue;
346 if (TREE_CODE (var) != FUNCTION_DECL
347 && TREE_CODE (var) != VAR_DECL)
348 continue;
350 /* Record references of the future statement initializing the constant
351 argument. */
352 ref_node = symtab_get_node (var);
353 gcc_checking_assert (ref_node);
354 ipa_record_reference ((symtab_node)new_node, (symtab_node)ref_node,
355 IPA_REF_ADDR, NULL);
357 if (!args_to_skip)
358 new_node->clone.combined_args_to_skip = old_node->clone.combined_args_to_skip;
359 else if (old_node->clone.combined_args_to_skip)
361 int newi = 0, oldi = 0;
362 tree arg;
363 bitmap new_args_to_skip = BITMAP_GGC_ALLOC ();
364 struct cgraph_node *orig_node;
365 for (orig_node = old_node; orig_node->clone_of; orig_node = orig_node->clone_of)
367 for (arg = DECL_ARGUMENTS (orig_node->symbol.decl);
368 arg; arg = DECL_CHAIN (arg), oldi++)
370 if (bitmap_bit_p (old_node->clone.combined_args_to_skip, oldi))
372 bitmap_set_bit (new_args_to_skip, oldi);
373 continue;
375 if (bitmap_bit_p (args_to_skip, newi))
376 bitmap_set_bit (new_args_to_skip, oldi);
377 newi++;
379 new_node->clone.combined_args_to_skip = new_args_to_skip;
381 else
382 new_node->clone.combined_args_to_skip = args_to_skip;
383 new_node->symbol.externally_visible = 0;
384 new_node->local.local = 1;
385 new_node->lowered = true;
387 cgraph_call_node_duplication_hooks (old_node, new_node);
390 return new_node;
393 /* NODE is being removed from symbol table; see if its entry can be replaced by
394 other inline clone. */
395 struct cgraph_node *
396 cgraph_find_replacement_node (struct cgraph_node *node)
398 struct cgraph_node *next_inline_clone, *replacement;
400 for (next_inline_clone = node->clones;
401 next_inline_clone
402 && next_inline_clone->symbol.decl != node->symbol.decl;
403 next_inline_clone = next_inline_clone->next_sibling_clone)
406 /* If there is inline clone of the node being removed, we need
407 to put it into the position of removed node and reorganize all
408 other clones to be based on it. */
409 if (next_inline_clone)
411 struct cgraph_node *n;
412 struct cgraph_node *new_clones;
414 replacement = next_inline_clone;
416 /* Unlink inline clone from the list of clones of removed node. */
417 if (next_inline_clone->next_sibling_clone)
418 next_inline_clone->next_sibling_clone->prev_sibling_clone
419 = next_inline_clone->prev_sibling_clone;
420 if (next_inline_clone->prev_sibling_clone)
422 gcc_assert (node->clones != next_inline_clone);
423 next_inline_clone->prev_sibling_clone->next_sibling_clone
424 = next_inline_clone->next_sibling_clone;
426 else
428 gcc_assert (node->clones == next_inline_clone);
429 node->clones = next_inline_clone->next_sibling_clone;
432 new_clones = node->clones;
433 node->clones = NULL;
435 /* Copy clone info. */
436 next_inline_clone->clone = node->clone;
438 /* Now place it into clone tree at same level at NODE. */
439 next_inline_clone->clone_of = node->clone_of;
440 next_inline_clone->prev_sibling_clone = NULL;
441 next_inline_clone->next_sibling_clone = NULL;
442 if (node->clone_of)
444 if (node->clone_of->clones)
445 node->clone_of->clones->prev_sibling_clone = next_inline_clone;
446 next_inline_clone->next_sibling_clone = node->clone_of->clones;
447 node->clone_of->clones = next_inline_clone;
450 /* Merge the clone list. */
451 if (new_clones)
453 if (!next_inline_clone->clones)
454 next_inline_clone->clones = new_clones;
455 else
457 n = next_inline_clone->clones;
458 while (n->next_sibling_clone)
459 n = n->next_sibling_clone;
460 n->next_sibling_clone = new_clones;
461 new_clones->prev_sibling_clone = n;
465 /* Update clone_of pointers. */
466 n = new_clones;
467 while (n)
469 n->clone_of = next_inline_clone;
470 n = n->next_sibling_clone;
472 return replacement;
474 else
475 return NULL;
478 /* Like cgraph_set_call_stmt but walk the clone tree and update all
479 clones sharing the same function body. */
481 void
482 cgraph_set_call_stmt_including_clones (struct cgraph_node *orig,
483 gimple old_stmt, gimple new_stmt)
485 struct cgraph_node *node;
486 struct cgraph_edge *edge = cgraph_edge (orig, old_stmt);
488 if (edge)
489 cgraph_set_call_stmt (edge, new_stmt);
491 node = orig->clones;
492 if (node)
493 while (node != orig)
495 struct cgraph_edge *edge = cgraph_edge (node, old_stmt);
496 if (edge)
497 cgraph_set_call_stmt (edge, new_stmt);
498 if (node->clones)
499 node = node->clones;
500 else if (node->next_sibling_clone)
501 node = node->next_sibling_clone;
502 else
504 while (node != orig && !node->next_sibling_clone)
505 node = node->clone_of;
506 if (node != orig)
507 node = node->next_sibling_clone;
512 /* Like cgraph_create_edge walk the clone tree and update all clones sharing
513 same function body. If clones already have edge for OLD_STMT; only
514 update the edge same way as cgraph_set_call_stmt_including_clones does.
516 TODO: COUNT and LOOP_DEPTH should be properly distributed based on relative
517 frequencies of the clones. */
519 void
520 cgraph_create_edge_including_clones (struct cgraph_node *orig,
521 struct cgraph_node *callee,
522 gimple old_stmt,
523 gimple stmt, gcov_type count,
524 int freq,
525 cgraph_inline_failed_t reason)
527 struct cgraph_node *node;
528 struct cgraph_edge *edge;
530 if (!cgraph_edge (orig, stmt))
532 edge = cgraph_create_edge (orig, callee, stmt, count, freq);
533 edge->inline_failed = reason;
536 node = orig->clones;
537 if (node)
538 while (node != orig)
540 struct cgraph_edge *edge = cgraph_edge (node, old_stmt);
542 /* It is possible that clones already contain the edge while
543 master didn't. Either we promoted indirect call into direct
544 call in the clone or we are processing clones of unreachable
545 master where edges has been removed. */
546 if (edge)
547 cgraph_set_call_stmt (edge, stmt);
548 else if (!cgraph_edge (node, stmt))
550 edge = cgraph_create_edge (node, callee, stmt, count,
551 freq);
552 edge->inline_failed = reason;
555 if (node->clones)
556 node = node->clones;
557 else if (node->next_sibling_clone)
558 node = node->next_sibling_clone;
559 else
561 while (node != orig && !node->next_sibling_clone)
562 node = node->clone_of;
563 if (node != orig)
564 node = node->next_sibling_clone;
569 /* Remove the node from cgraph and all inline clones inlined into it.
570 Skip however removal of FORBIDDEN_NODE and return true if it needs to be
571 removed. This allows to call the function from outer loop walking clone
572 tree. */
574 bool
575 cgraph_remove_node_and_inline_clones (struct cgraph_node *node, struct cgraph_node *forbidden_node)
577 struct cgraph_edge *e, *next;
578 bool found = false;
580 if (node == forbidden_node)
582 cgraph_remove_edge (node->callers);
583 return true;
585 for (e = node->callees; e; e = next)
587 next = e->next_callee;
588 if (!e->inline_failed)
589 found |= cgraph_remove_node_and_inline_clones (e->callee, forbidden_node);
591 cgraph_remove_node (node);
592 return found;
595 /* The edges representing the callers of the NEW_VERSION node were
596 fixed by cgraph_function_versioning (), now the call_expr in their
597 respective tree code should be updated to call the NEW_VERSION. */
599 static void
600 update_call_expr (struct cgraph_node *new_version)
602 struct cgraph_edge *e;
604 gcc_assert (new_version);
606 /* Update the call expr on the edges to call the new version. */
607 for (e = new_version->callers; e; e = e->next_caller)
609 struct function *inner_function = DECL_STRUCT_FUNCTION (e->caller->symbol.decl);
610 gimple_call_set_fndecl (e->call_stmt, new_version->symbol.decl);
611 maybe_clean_eh_stmt_fn (inner_function, e->call_stmt);
616 /* Create a new cgraph node which is the new version of
617 OLD_VERSION node. REDIRECT_CALLERS holds the callers
618 edges which should be redirected to point to
619 NEW_VERSION. ALL the callees edges of OLD_VERSION
620 are cloned to the new version node. Return the new
621 version node.
623 If non-NULL BLOCK_TO_COPY determine what basic blocks
624 was copied to prevent duplications of calls that are dead
625 in the clone. */
627 struct cgraph_node *
628 cgraph_copy_node_for_versioning (struct cgraph_node *old_version,
629 tree new_decl,
630 vec<cgraph_edge_p> redirect_callers,
631 bitmap bbs_to_copy)
633 struct cgraph_node *new_version;
634 struct cgraph_edge *e;
635 unsigned i;
637 gcc_assert (old_version);
639 new_version = cgraph_create_node (new_decl);
641 new_version->analyzed = old_version->analyzed;
642 new_version->local = old_version->local;
643 new_version->symbol.externally_visible = false;
644 new_version->local.local = old_version->analyzed;
645 new_version->global = old_version->global;
646 new_version->rtl = old_version->rtl;
647 new_version->count = old_version->count;
649 for (e = old_version->callees; e; e=e->next_callee)
650 if (!bbs_to_copy
651 || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
652 cgraph_clone_edge (e, new_version, e->call_stmt,
653 e->lto_stmt_uid, REG_BR_PROB_BASE,
654 CGRAPH_FREQ_BASE,
655 true);
656 for (e = old_version->indirect_calls; e; e=e->next_callee)
657 if (!bbs_to_copy
658 || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
659 cgraph_clone_edge (e, new_version, e->call_stmt,
660 e->lto_stmt_uid, REG_BR_PROB_BASE,
661 CGRAPH_FREQ_BASE,
662 true);
663 FOR_EACH_VEC_ELT (redirect_callers, i, e)
665 /* Redirect calls to the old version node to point to its new
666 version. */
667 cgraph_redirect_edge_callee (e, new_version);
670 cgraph_call_node_duplication_hooks (old_version, new_version);
672 return new_version;
675 /* Perform function versioning.
676 Function versioning includes copying of the tree and
677 a callgraph update (creating a new cgraph node and updating
678 its callees and callers).
680 REDIRECT_CALLERS varray includes the edges to be redirected
681 to the new version.
683 TREE_MAP is a mapping of tree nodes we want to replace with
684 new ones (according to results of prior analysis).
685 OLD_VERSION_NODE is the node that is versioned.
687 If non-NULL ARGS_TO_SKIP determine function parameters to remove
688 from new version.
689 If SKIP_RETURN is true, the new version will return void.
690 If non-NULL BLOCK_TO_COPY determine what basic blocks to copy.
691 If non_NULL NEW_ENTRY determine new entry BB of the clone.
693 Return the new version's cgraph node. */
695 struct cgraph_node *
696 cgraph_function_versioning (struct cgraph_node *old_version_node,
697 vec<cgraph_edge_p> redirect_callers,
698 vec<ipa_replace_map_p, va_gc> *tree_map,
699 bitmap args_to_skip,
700 bool skip_return,
701 bitmap bbs_to_copy,
702 basic_block new_entry_block,
703 const char *clone_name)
705 tree old_decl = old_version_node->symbol.decl;
706 struct cgraph_node *new_version_node = NULL;
707 tree new_decl;
709 if (!tree_versionable_function_p (old_decl))
710 return NULL;
712 gcc_assert (old_version_node->local.can_change_signature || !args_to_skip);
714 /* Make a new FUNCTION_DECL tree node for the new version. */
715 if (!args_to_skip && !skip_return)
716 new_decl = copy_node (old_decl);
717 else
718 new_decl
719 = build_function_decl_skip_args (old_decl, args_to_skip, skip_return);
721 /* Generate a new name for the new version. */
722 DECL_NAME (new_decl) = clone_function_name (old_decl, clone_name);
723 SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
724 SET_DECL_RTL (new_decl, NULL);
726 /* When the old decl was a con-/destructor make sure the clone isn't. */
727 DECL_STATIC_CONSTRUCTOR(new_decl) = 0;
728 DECL_STATIC_DESTRUCTOR(new_decl) = 0;
730 /* Create the new version's call-graph node.
731 and update the edges of the new node. */
732 new_version_node =
733 cgraph_copy_node_for_versioning (old_version_node, new_decl,
734 redirect_callers, bbs_to_copy);
736 /* Copy the OLD_VERSION_NODE function tree to the new version. */
737 tree_function_versioning (old_decl, new_decl, tree_map, false, args_to_skip,
738 skip_return, bbs_to_copy, new_entry_block);
740 /* Update the new version's properties.
741 Make The new version visible only within this translation unit. Make sure
742 that is not weak also.
743 ??? We cannot use COMDAT linkage because there is no
744 ABI support for this. */
745 symtab_make_decl_local (new_version_node->symbol.decl);
746 DECL_VIRTUAL_P (new_version_node->symbol.decl) = 0;
747 new_version_node->symbol.externally_visible = 0;
748 new_version_node->local.local = 1;
749 new_version_node->lowered = true;
750 /* Clones of global symbols or symbols with unique names are unique. */
751 if ((TREE_PUBLIC (old_decl)
752 && !DECL_EXTERNAL (old_decl)
753 && !DECL_WEAK (old_decl)
754 && !DECL_COMDAT (old_decl))
755 || in_lto_p)
756 new_version_node->symbol.unique_name = true;
758 /* Update the call_expr on the edges to call the new version node. */
759 update_call_expr (new_version_node);
761 cgraph_call_function_insertion_hooks (new_version_node);
762 return new_version_node;
765 /* Given virtual clone, turn it into actual clone. */
767 static void
768 cgraph_materialize_clone (struct cgraph_node *node)
770 bitmap_obstack_initialize (NULL);
771 node->former_clone_of = node->clone_of->symbol.decl;
772 if (node->clone_of->former_clone_of)
773 node->former_clone_of = node->clone_of->former_clone_of;
774 /* Copy the OLD_VERSION_NODE function tree to the new version. */
775 tree_function_versioning (node->clone_of->symbol.decl, node->symbol.decl,
776 node->clone.tree_map, true,
777 node->clone.args_to_skip, false,
778 NULL, NULL);
779 if (cgraph_dump_file)
781 dump_function_to_file (node->clone_of->symbol.decl, cgraph_dump_file, dump_flags);
782 dump_function_to_file (node->symbol.decl, cgraph_dump_file, dump_flags);
785 /* Function is no longer clone. */
786 if (node->next_sibling_clone)
787 node->next_sibling_clone->prev_sibling_clone = node->prev_sibling_clone;
788 if (node->prev_sibling_clone)
789 node->prev_sibling_clone->next_sibling_clone = node->next_sibling_clone;
790 else
791 node->clone_of->clones = node->next_sibling_clone;
792 node->next_sibling_clone = NULL;
793 node->prev_sibling_clone = NULL;
794 if (!node->clone_of->analyzed && !node->clone_of->clones)
796 cgraph_release_function_body (node->clone_of);
797 cgraph_node_remove_callees (node->clone_of);
798 ipa_remove_all_references (&node->clone_of->symbol.ref_list);
800 node->clone_of = NULL;
801 bitmap_obstack_release (NULL);
804 /* Once all functions from compilation unit are in memory, produce all clones
805 and update all calls. We might also do this on demand if we don't want to
806 bring all functions to memory prior compilation, but current WHOPR
807 implementation does that and it is is bit easier to keep everything right in
808 this order. */
810 void
811 cgraph_materialize_all_clones (void)
813 struct cgraph_node *node;
814 bool stabilized = false;
816 if (cgraph_dump_file)
817 fprintf (cgraph_dump_file, "Materializing clones\n");
818 #ifdef ENABLE_CHECKING
819 verify_cgraph ();
820 #endif
822 /* We can also do topological order, but number of iterations should be
823 bounded by number of IPA passes since single IPA pass is probably not
824 going to create clones of clones it created itself. */
825 while (!stabilized)
827 stabilized = true;
828 FOR_EACH_FUNCTION (node)
830 if (node->clone_of && node->symbol.decl != node->clone_of->symbol.decl
831 && !gimple_has_body_p (node->symbol.decl))
833 if (gimple_has_body_p (node->clone_of->symbol.decl))
835 if (cgraph_dump_file)
837 fprintf (cgraph_dump_file, "cloning %s to %s\n",
838 xstrdup (cgraph_node_name (node->clone_of)),
839 xstrdup (cgraph_node_name (node)));
840 if (node->clone.tree_map)
842 unsigned int i;
843 fprintf (cgraph_dump_file, " replace map: ");
844 for (i = 0;
845 i < vec_safe_length (node->clone.tree_map);
846 i++)
848 struct ipa_replace_map *replace_info;
849 replace_info = (*node->clone.tree_map)[i];
850 print_generic_expr (cgraph_dump_file, replace_info->old_tree, 0);
851 fprintf (cgraph_dump_file, " -> ");
852 print_generic_expr (cgraph_dump_file, replace_info->new_tree, 0);
853 fprintf (cgraph_dump_file, "%s%s;",
854 replace_info->replace_p ? "(replace)":"",
855 replace_info->ref_p ? "(ref)":"");
857 fprintf (cgraph_dump_file, "\n");
859 if (node->clone.args_to_skip)
861 fprintf (cgraph_dump_file, " args_to_skip: ");
862 dump_bitmap (cgraph_dump_file, node->clone.args_to_skip);
864 if (node->clone.args_to_skip)
866 fprintf (cgraph_dump_file, " combined_args_to_skip:");
867 dump_bitmap (cgraph_dump_file, node->clone.combined_args_to_skip);
870 cgraph_materialize_clone (node);
871 stabilized = false;
876 FOR_EACH_FUNCTION (node)
877 if (!node->analyzed && node->callees)
878 cgraph_node_remove_callees (node);
879 if (cgraph_dump_file)
880 fprintf (cgraph_dump_file, "Materialization Call site updates done.\n");
881 #ifdef ENABLE_CHECKING
882 verify_cgraph ();
883 #endif
884 symtab_remove_unreachable_nodes (false, cgraph_dump_file);
887 #include "gt-cgraphclones.h"