PR debug/54693
[official-gcc.git] / gcc / cgraphclones.c
blob730e70b08e01adac2ba2aa5066b6e7096e7c6358
1 /* Callgraph clones
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
3 2011, 2012 Free Software Foundation, Inc.
4 Contributed by Jan Hubicka
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
22 /* This module provide facilities for clonning functions. I.e. creating
23 new functions based on existing functions with simple modifications,
24 such as replacement of parameters.
26 To allow whole program optimization without actual presence of function
27 bodies, an additional infrastructure is provided for so-called virtual
28 clones
30 A virtual clone in the callgraph is a function that has no
31 associated body, just a description of how to create its body based
32 on a different function (which itself may be a virtual clone).
34 The description of function modifications includes adjustments to
35 the function's signature (which allows, for example, removing or
36 adding function arguments), substitutions to perform on the
37 function body, and, for inlined functions, a pointer to the
38 function that it will be inlined into.
40 It is also possible to redirect any edge of the callgraph from a
41 function to its virtual clone. This implies updating of the call
42 site to adjust for the new function signature.
44 Most of the transformations performed by inter-procedural
45 optimizations can be represented via virtual clones. For
46 instance, a constant propagation pass can produce a virtual clone
47 of the function which replaces one of its arguments by a
48 constant. The inliner can represent its decisions by producing a
49 clone of a function whose body will be later integrated into
50 a given function.
52 Using virtual clones, the program can be easily updated
53 during the Execute stage, solving most of pass interactions
54 problems that would otherwise occur during Transform.
56 Virtual clones are later materialized in the LTRANS stage and
57 turned into real functions. Passes executed after the virtual
58 clone were introduced also perform their Transform stage
59 on new functions, so for a pass there is no significant
60 difference between operating on a real function or a virtual
61 clone introduced before its Execute stage.
63 Optimization passes then work on virtual clones introduced before
64 their Execute stage as if they were real functions. The
65 only difference is that clones are not visible during the
66 Generate Summary stage. */
68 #include "config.h"
69 #include "system.h"
70 #include "coretypes.h"
71 #include "tm.h"
72 #include "tree.h"
73 #include "rtl.h"
74 #include "tree-flow.h"
75 #include "tree-inline.h"
76 #include "langhooks.h"
77 #include "pointer-set.h"
78 #include "toplev.h"
79 #include "flags.h"
80 #include "ggc.h"
81 #include "debug.h"
82 #include "target.h"
83 #include "cgraph.h"
84 #include "diagnostic.h"
85 #include "params.h"
86 #include "intl.h"
87 #include "function.h"
88 #include "ipa-prop.h"
89 #include "gimple.h"
90 #include "tree-iterator.h"
91 #include "tree-dump.h"
92 #include "gimple-pretty-print.h"
93 #include "coverage.h"
94 #include "ipa-inline.h"
95 #include "ipa-utils.h"
96 #include "lto-streamer.h"
97 #include "except.h"
99 /* Create clone of E in the node N represented by CALL_EXPR the callgraph. */
100 struct cgraph_edge *
101 cgraph_clone_edge (struct cgraph_edge *e, struct cgraph_node *n,
102 gimple call_stmt, unsigned stmt_uid, gcov_type count_scale,
103 int freq_scale, bool update_original)
105 struct cgraph_edge *new_edge;
106 gcov_type count = e->count * count_scale / REG_BR_PROB_BASE;
107 gcov_type freq;
109 /* We do not want to ignore loop nest after frequency drops to 0. */
110 if (!freq_scale)
111 freq_scale = 1;
112 freq = e->frequency * (gcov_type) freq_scale / CGRAPH_FREQ_BASE;
113 if (freq > CGRAPH_FREQ_MAX)
114 freq = CGRAPH_FREQ_MAX;
116 if (e->indirect_unknown_callee)
118 tree decl;
120 if (call_stmt && (decl = gimple_call_fndecl (call_stmt)))
122 struct cgraph_node *callee = cgraph_get_node (decl);
123 gcc_checking_assert (callee);
124 new_edge = cgraph_create_edge (n, callee, call_stmt, count, freq);
126 else
128 new_edge = cgraph_create_indirect_edge (n, call_stmt,
129 e->indirect_info->ecf_flags,
130 count, freq);
131 *new_edge->indirect_info = *e->indirect_info;
134 else
136 new_edge = cgraph_create_edge (n, e->callee, call_stmt, count, freq);
137 if (e->indirect_info)
139 new_edge->indirect_info
140 = ggc_alloc_cleared_cgraph_indirect_call_info ();
141 *new_edge->indirect_info = *e->indirect_info;
145 new_edge->inline_failed = e->inline_failed;
146 new_edge->indirect_inlining_edge = e->indirect_inlining_edge;
147 new_edge->lto_stmt_uid = stmt_uid;
148 /* Clone flags that depend on call_stmt availability manually. */
149 new_edge->can_throw_external = e->can_throw_external;
150 new_edge->call_stmt_cannot_inline_p = e->call_stmt_cannot_inline_p;
151 if (update_original)
153 e->count -= new_edge->count;
154 if (e->count < 0)
155 e->count = 0;
157 cgraph_call_edge_duplication_hooks (e, new_edge);
158 return new_edge;
162 /* Create node representing clone of N executed COUNT times. Decrease
163 the execution counts from original node too.
164 The new clone will have decl set to DECL that may or may not be the same
165 as decl of N.
167 When UPDATE_ORIGINAL is true, the counts are subtracted from the original
168 function's profile to reflect the fact that part of execution is handled
169 by node.
170 When CALL_DUPLICATOIN_HOOK is true, the ipa passes are acknowledged about
171 the new clone. Otherwise the caller is responsible for doing so later. */
173 struct cgraph_node *
174 cgraph_clone_node (struct cgraph_node *n, tree decl, gcov_type count, int freq,
175 bool update_original,
176 VEC(cgraph_edge_p,heap) *redirect_callers,
177 bool call_duplication_hook)
179 struct cgraph_node *new_node = cgraph_create_empty_node ();
180 struct cgraph_edge *e;
181 gcov_type count_scale;
182 unsigned i;
184 new_node->symbol.decl = decl;
185 symtab_register_node ((symtab_node)new_node);
186 new_node->origin = n->origin;
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 = 0;
202 if (n->count)
204 if (new_node->count > n->count)
205 count_scale = REG_BR_PROB_BASE;
206 else
207 count_scale = new_node->count * REG_BR_PROB_BASE / 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 (cgraph_edge_p, 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,heap) *redirect_callers,
280 VEC(ipa_replace_map_p,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_STATIC_CONSTRUCTOR (new_node->symbol.decl) = 0;
323 DECL_STATIC_DESTRUCTOR (new_node->symbol.decl) = 0;
324 new_node->clone.tree_map = tree_map;
325 new_node->clone.args_to_skip = args_to_skip;
326 FOR_EACH_VEC_ELT (ipa_replace_map_p, tree_map, i, map)
328 tree var = map->new_tree;
329 symtab_node ref_node;
331 STRIP_NOPS (var);
332 if (TREE_CODE (var) != ADDR_EXPR)
333 continue;
334 var = get_base_var (var);
335 if (!var)
336 continue;
337 if (TREE_CODE (var) != FUNCTION_DECL
338 && TREE_CODE (var) != VAR_DECL)
339 continue;
341 /* Record references of the future statement initializing the constant
342 argument. */
343 ref_node = symtab_get_node (var);
344 gcc_checking_assert (ref_node);
345 ipa_record_reference ((symtab_node)new_node, (symtab_node)ref_node,
346 IPA_REF_ADDR, NULL);
348 if (!args_to_skip)
349 new_node->clone.combined_args_to_skip = old_node->clone.combined_args_to_skip;
350 else if (old_node->clone.combined_args_to_skip)
352 int newi = 0, oldi = 0;
353 tree arg;
354 bitmap new_args_to_skip = BITMAP_GGC_ALLOC ();
355 struct cgraph_node *orig_node;
356 for (orig_node = old_node; orig_node->clone_of; orig_node = orig_node->clone_of)
358 for (arg = DECL_ARGUMENTS (orig_node->symbol.decl);
359 arg; arg = DECL_CHAIN (arg), oldi++)
361 if (bitmap_bit_p (old_node->clone.combined_args_to_skip, oldi))
363 bitmap_set_bit (new_args_to_skip, oldi);
364 continue;
366 if (bitmap_bit_p (args_to_skip, newi))
367 bitmap_set_bit (new_args_to_skip, oldi);
368 newi++;
370 new_node->clone.combined_args_to_skip = new_args_to_skip;
372 else
373 new_node->clone.combined_args_to_skip = args_to_skip;
374 new_node->symbol.externally_visible = 0;
375 new_node->local.local = 1;
376 new_node->lowered = true;
378 cgraph_call_node_duplication_hooks (old_node, new_node);
381 return new_node;
384 /* NODE is being removed from symbol table; see if its entry can be replaced by
385 other inline clone. */
386 struct cgraph_node *
387 cgraph_find_replacement_node (struct cgraph_node *node)
389 struct cgraph_node *next_inline_clone, *replacement;
391 for (next_inline_clone = node->clones;
392 next_inline_clone
393 && next_inline_clone->symbol.decl != node->symbol.decl;
394 next_inline_clone = next_inline_clone->next_sibling_clone)
397 /* If there is inline clone of the node being removed, we need
398 to put it into the position of removed node and reorganize all
399 other clones to be based on it. */
400 if (next_inline_clone)
402 struct cgraph_node *n;
403 struct cgraph_node *new_clones;
405 replacement = next_inline_clone;
407 /* Unlink inline clone from the list of clones of removed node. */
408 if (next_inline_clone->next_sibling_clone)
409 next_inline_clone->next_sibling_clone->prev_sibling_clone
410 = next_inline_clone->prev_sibling_clone;
411 if (next_inline_clone->prev_sibling_clone)
413 gcc_assert (node->clones != next_inline_clone);
414 next_inline_clone->prev_sibling_clone->next_sibling_clone
415 = next_inline_clone->next_sibling_clone;
417 else
419 gcc_assert (node->clones == next_inline_clone);
420 node->clones = next_inline_clone->next_sibling_clone;
423 new_clones = node->clones;
424 node->clones = NULL;
426 /* Copy clone info. */
427 next_inline_clone->clone = node->clone;
429 /* Now place it into clone tree at same level at NODE. */
430 next_inline_clone->clone_of = node->clone_of;
431 next_inline_clone->prev_sibling_clone = NULL;
432 next_inline_clone->next_sibling_clone = NULL;
433 if (node->clone_of)
435 if (node->clone_of->clones)
436 node->clone_of->clones->prev_sibling_clone = next_inline_clone;
437 next_inline_clone->next_sibling_clone = node->clone_of->clones;
438 node->clone_of->clones = next_inline_clone;
441 /* Merge the clone list. */
442 if (new_clones)
444 if (!next_inline_clone->clones)
445 next_inline_clone->clones = new_clones;
446 else
448 n = next_inline_clone->clones;
449 while (n->next_sibling_clone)
450 n = n->next_sibling_clone;
451 n->next_sibling_clone = new_clones;
452 new_clones->prev_sibling_clone = n;
456 /* Update clone_of pointers. */
457 n = new_clones;
458 while (n)
460 n->clone_of = next_inline_clone;
461 n = n->next_sibling_clone;
463 return replacement;
465 else
466 return NULL;
469 /* Like cgraph_set_call_stmt but walk the clone tree and update all
470 clones sharing the same function body. */
472 void
473 cgraph_set_call_stmt_including_clones (struct cgraph_node *orig,
474 gimple old_stmt, gimple new_stmt)
476 struct cgraph_node *node;
477 struct cgraph_edge *edge = cgraph_edge (orig, old_stmt);
479 if (edge)
480 cgraph_set_call_stmt (edge, new_stmt);
482 node = orig->clones;
483 if (node)
484 while (node != orig)
486 struct cgraph_edge *edge = cgraph_edge (node, old_stmt);
487 if (edge)
488 cgraph_set_call_stmt (edge, new_stmt);
489 if (node->clones)
490 node = node->clones;
491 else if (node->next_sibling_clone)
492 node = node->next_sibling_clone;
493 else
495 while (node != orig && !node->next_sibling_clone)
496 node = node->clone_of;
497 if (node != orig)
498 node = node->next_sibling_clone;
503 /* Like cgraph_create_edge walk the clone tree and update all clones sharing
504 same function body. If clones already have edge for OLD_STMT; only
505 update the edge same way as cgraph_set_call_stmt_including_clones does.
507 TODO: COUNT and LOOP_DEPTH should be properly distributed based on relative
508 frequencies of the clones. */
510 void
511 cgraph_create_edge_including_clones (struct cgraph_node *orig,
512 struct cgraph_node *callee,
513 gimple old_stmt,
514 gimple stmt, gcov_type count,
515 int freq,
516 cgraph_inline_failed_t reason)
518 struct cgraph_node *node;
519 struct cgraph_edge *edge;
521 if (!cgraph_edge (orig, stmt))
523 edge = cgraph_create_edge (orig, callee, stmt, count, freq);
524 edge->inline_failed = reason;
527 node = orig->clones;
528 if (node)
529 while (node != orig)
531 struct cgraph_edge *edge = cgraph_edge (node, old_stmt);
533 /* It is possible that clones already contain the edge while
534 master didn't. Either we promoted indirect call into direct
535 call in the clone or we are processing clones of unreachable
536 master where edges has been removed. */
537 if (edge)
538 cgraph_set_call_stmt (edge, stmt);
539 else if (!cgraph_edge (node, stmt))
541 edge = cgraph_create_edge (node, callee, stmt, count,
542 freq);
543 edge->inline_failed = reason;
546 if (node->clones)
547 node = node->clones;
548 else if (node->next_sibling_clone)
549 node = node->next_sibling_clone;
550 else
552 while (node != orig && !node->next_sibling_clone)
553 node = node->clone_of;
554 if (node != orig)
555 node = node->next_sibling_clone;
560 /* Remove the node from cgraph and all inline clones inlined into it.
561 Skip however removal of FORBIDDEN_NODE and return true if it needs to be
562 removed. This allows to call the function from outer loop walking clone
563 tree. */
565 bool
566 cgraph_remove_node_and_inline_clones (struct cgraph_node *node, struct cgraph_node *forbidden_node)
568 struct cgraph_edge *e, *next;
569 bool found = false;
571 if (node == forbidden_node)
572 return true;
573 for (e = node->callees; e; e = next)
575 next = e->next_callee;
576 if (!e->inline_failed)
577 found |= cgraph_remove_node_and_inline_clones (e->callee, forbidden_node);
579 cgraph_remove_node (node);
580 return found;
583 /* The edges representing the callers of the NEW_VERSION node were
584 fixed by cgraph_function_versioning (), now the call_expr in their
585 respective tree code should be updated to call the NEW_VERSION. */
587 static void
588 update_call_expr (struct cgraph_node *new_version)
590 struct cgraph_edge *e;
592 gcc_assert (new_version);
594 /* Update the call expr on the edges to call the new version. */
595 for (e = new_version->callers; e; e = e->next_caller)
597 struct function *inner_function = DECL_STRUCT_FUNCTION (e->caller->symbol.decl);
598 gimple_call_set_fndecl (e->call_stmt, new_version->symbol.decl);
599 maybe_clean_eh_stmt_fn (inner_function, e->call_stmt);
604 /* Create a new cgraph node which is the new version of
605 OLD_VERSION node. REDIRECT_CALLERS holds the callers
606 edges which should be redirected to point to
607 NEW_VERSION. ALL the callees edges of OLD_VERSION
608 are cloned to the new version node. Return the new
609 version node.
611 If non-NULL BLOCK_TO_COPY determine what basic blocks
612 was copied to prevent duplications of calls that are dead
613 in the clone. */
615 struct cgraph_node *
616 cgraph_copy_node_for_versioning (struct cgraph_node *old_version,
617 tree new_decl,
618 VEC(cgraph_edge_p,heap) *redirect_callers,
619 bitmap bbs_to_copy)
621 struct cgraph_node *new_version;
622 struct cgraph_edge *e;
623 unsigned i;
625 gcc_assert (old_version);
627 new_version = cgraph_create_node (new_decl);
629 new_version->analyzed = old_version->analyzed;
630 new_version->local = old_version->local;
631 new_version->symbol.externally_visible = false;
632 new_version->local.local = old_version->analyzed;
633 new_version->global = old_version->global;
634 new_version->rtl = old_version->rtl;
635 new_version->count = old_version->count;
637 for (e = old_version->callees; e; e=e->next_callee)
638 if (!bbs_to_copy
639 || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
640 cgraph_clone_edge (e, new_version, e->call_stmt,
641 e->lto_stmt_uid, REG_BR_PROB_BASE,
642 CGRAPH_FREQ_BASE,
643 true);
644 for (e = old_version->indirect_calls; e; e=e->next_callee)
645 if (!bbs_to_copy
646 || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
647 cgraph_clone_edge (e, new_version, e->call_stmt,
648 e->lto_stmt_uid, REG_BR_PROB_BASE,
649 CGRAPH_FREQ_BASE,
650 true);
651 FOR_EACH_VEC_ELT (cgraph_edge_p, redirect_callers, i, e)
653 /* Redirect calls to the old version node to point to its new
654 version. */
655 cgraph_redirect_edge_callee (e, new_version);
658 cgraph_call_node_duplication_hooks (old_version, new_version);
660 return new_version;
663 /* Perform function versioning.
664 Function versioning includes copying of the tree and
665 a callgraph update (creating a new cgraph node and updating
666 its callees and callers).
668 REDIRECT_CALLERS varray includes the edges to be redirected
669 to the new version.
671 TREE_MAP is a mapping of tree nodes we want to replace with
672 new ones (according to results of prior analysis).
673 OLD_VERSION_NODE is the node that is versioned.
675 If non-NULL ARGS_TO_SKIP determine function parameters to remove
676 from new version.
677 If SKIP_RETURN is true, the new version will return void.
678 If non-NULL BLOCK_TO_COPY determine what basic blocks to copy.
679 If non_NULL NEW_ENTRY determine new entry BB of the clone.
681 Return the new version's cgraph node. */
683 struct cgraph_node *
684 cgraph_function_versioning (struct cgraph_node *old_version_node,
685 VEC(cgraph_edge_p,heap) *redirect_callers,
686 VEC (ipa_replace_map_p,gc)* tree_map,
687 bitmap args_to_skip,
688 bool skip_return,
689 bitmap bbs_to_copy,
690 basic_block new_entry_block,
691 const char *clone_name)
693 tree old_decl = old_version_node->symbol.decl;
694 struct cgraph_node *new_version_node = NULL;
695 tree new_decl;
697 if (!tree_versionable_function_p (old_decl))
698 return NULL;
700 gcc_assert (old_version_node->local.can_change_signature || !args_to_skip);
702 /* Make a new FUNCTION_DECL tree node for the new version. */
703 if (!args_to_skip && !skip_return)
704 new_decl = copy_node (old_decl);
705 else
706 new_decl
707 = build_function_decl_skip_args (old_decl, args_to_skip, skip_return);
709 /* Generate a new name for the new version. */
710 DECL_NAME (new_decl) = clone_function_name (old_decl, clone_name);
711 SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
712 SET_DECL_RTL (new_decl, NULL);
714 /* When the old decl was a con-/destructor make sure the clone isn't. */
715 DECL_STATIC_CONSTRUCTOR(new_decl) = 0;
716 DECL_STATIC_DESTRUCTOR(new_decl) = 0;
718 /* Create the new version's call-graph node.
719 and update the edges of the new node. */
720 new_version_node =
721 cgraph_copy_node_for_versioning (old_version_node, new_decl,
722 redirect_callers, bbs_to_copy);
724 /* Copy the OLD_VERSION_NODE function tree to the new version. */
725 tree_function_versioning (old_decl, new_decl, tree_map, false, args_to_skip,
726 skip_return, bbs_to_copy, new_entry_block);
728 /* Update the new version's properties.
729 Make The new version visible only within this translation unit. Make sure
730 that is not weak also.
731 ??? We cannot use COMDAT linkage because there is no
732 ABI support for this. */
733 symtab_make_decl_local (new_version_node->symbol.decl);
734 DECL_VIRTUAL_P (new_version_node->symbol.decl) = 0;
735 new_version_node->symbol.externally_visible = 0;
736 new_version_node->local.local = 1;
737 new_version_node->lowered = true;
739 /* Update the call_expr on the edges to call the new version node. */
740 update_call_expr (new_version_node);
742 cgraph_call_function_insertion_hooks (new_version_node);
743 return new_version_node;
746 /* Given virtual clone, turn it into actual clone. */
748 static void
749 cgraph_materialize_clone (struct cgraph_node *node)
751 bitmap_obstack_initialize (NULL);
752 node->former_clone_of = node->clone_of->symbol.decl;
753 if (node->clone_of->former_clone_of)
754 node->former_clone_of = node->clone_of->former_clone_of;
755 /* Copy the OLD_VERSION_NODE function tree to the new version. */
756 tree_function_versioning (node->clone_of->symbol.decl, node->symbol.decl,
757 node->clone.tree_map, true,
758 node->clone.args_to_skip, false,
759 NULL, NULL);
760 if (cgraph_dump_file)
762 dump_function_to_file (node->clone_of->symbol.decl, cgraph_dump_file, dump_flags);
763 dump_function_to_file (node->symbol.decl, cgraph_dump_file, dump_flags);
766 /* Function is no longer clone. */
767 if (node->next_sibling_clone)
768 node->next_sibling_clone->prev_sibling_clone = node->prev_sibling_clone;
769 if (node->prev_sibling_clone)
770 node->prev_sibling_clone->next_sibling_clone = node->next_sibling_clone;
771 else
772 node->clone_of->clones = node->next_sibling_clone;
773 node->next_sibling_clone = NULL;
774 node->prev_sibling_clone = NULL;
775 if (!node->clone_of->analyzed && !node->clone_of->clones)
777 cgraph_release_function_body (node->clone_of);
778 cgraph_node_remove_callees (node->clone_of);
779 ipa_remove_all_references (&node->clone_of->symbol.ref_list);
781 node->clone_of = NULL;
782 bitmap_obstack_release (NULL);
785 /* Once all functions from compilation unit are in memory, produce all clones
786 and update all calls. We might also do this on demand if we don't want to
787 bring all functions to memory prior compilation, but current WHOPR
788 implementation does that and it is is bit easier to keep everything right in
789 this order. */
791 void
792 cgraph_materialize_all_clones (void)
794 struct cgraph_node *node;
795 bool stabilized = false;
797 if (cgraph_dump_file)
798 fprintf (cgraph_dump_file, "Materializing clones\n");
799 #ifdef ENABLE_CHECKING
800 verify_cgraph ();
801 #endif
803 /* We can also do topological order, but number of iterations should be
804 bounded by number of IPA passes since single IPA pass is probably not
805 going to create clones of clones it created itself. */
806 while (!stabilized)
808 stabilized = true;
809 FOR_EACH_FUNCTION (node)
811 if (node->clone_of && node->symbol.decl != node->clone_of->symbol.decl
812 && !gimple_has_body_p (node->symbol.decl))
814 if (gimple_has_body_p (node->clone_of->symbol.decl))
816 if (cgraph_dump_file)
818 fprintf (cgraph_dump_file, "cloning %s to %s\n",
819 xstrdup (cgraph_node_name (node->clone_of)),
820 xstrdup (cgraph_node_name (node)));
821 if (node->clone.tree_map)
823 unsigned int i;
824 fprintf (cgraph_dump_file, " replace map: ");
825 for (i = 0; i < VEC_length (ipa_replace_map_p,
826 node->clone.tree_map);
827 i++)
829 struct ipa_replace_map *replace_info;
830 replace_info = VEC_index (ipa_replace_map_p,
831 node->clone.tree_map,
833 print_generic_expr (cgraph_dump_file, replace_info->old_tree, 0);
834 fprintf (cgraph_dump_file, " -> ");
835 print_generic_expr (cgraph_dump_file, replace_info->new_tree, 0);
836 fprintf (cgraph_dump_file, "%s%s;",
837 replace_info->replace_p ? "(replace)":"",
838 replace_info->ref_p ? "(ref)":"");
840 fprintf (cgraph_dump_file, "\n");
842 if (node->clone.args_to_skip)
844 fprintf (cgraph_dump_file, " args_to_skip: ");
845 dump_bitmap (cgraph_dump_file, node->clone.args_to_skip);
847 if (node->clone.args_to_skip)
849 fprintf (cgraph_dump_file, " combined_args_to_skip:");
850 dump_bitmap (cgraph_dump_file, node->clone.combined_args_to_skip);
853 cgraph_materialize_clone (node);
854 stabilized = false;
859 FOR_EACH_FUNCTION (node)
860 if (!node->analyzed && node->callees)
861 cgraph_node_remove_callees (node);
862 if (cgraph_dump_file)
863 fprintf (cgraph_dump_file, "Materialization Call site updates done.\n");
864 #ifdef ENABLE_CHECKING
865 verify_cgraph ();
866 #endif
867 symtab_remove_unreachable_nodes (false, cgraph_dump_file);
870 #include "gt-cgraphclones.h"