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
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
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
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
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. */
70 #include "coretypes.h"
74 #include "tree-flow.h"
75 #include "tree-inline.h"
76 #include "langhooks.h"
77 #include "pointer-set.h"
84 #include "diagnostic.h"
90 #include "tree-iterator.h"
91 #include "tree-dump.h"
92 #include "gimple-pretty-print.h"
94 #include "ipa-inline.h"
95 #include "ipa-utils.h"
96 #include "lto-streamer.h"
99 /* Create clone of E in the node N represented by CALL_EXPR the callgraph. */
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
;
109 /* We do not want to ignore loop nest after frequency drops to 0. */
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
)
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
);
128 new_edge
= cgraph_create_indirect_edge (n
, call_stmt
,
129 e
->indirect_info
->ecf_flags
,
131 *new_edge
->indirect_info
= *e
->indirect_info
;
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
;
153 e
->count
-= new_edge
->count
;
157 cgraph_call_edge_duplication_hooks (e
, 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
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
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. */
174 cgraph_clone_node (struct cgraph_node
*n
, tree decl
, gcov_type count
, int freq
,
175 bool update_original
,
176 vec
<cgraph_edge_p
> 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
;
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
= NULL
;
204 if (new_node
->count
> n
->count
)
205 count_scale
= REG_BR_PROB_BASE
;
207 count_scale
= new_node
->count
* REG_BR_PROB_BASE
/ n
->count
;
218 FOR_EACH_VEC_ELT (redirect_callers
, i
, e
)
220 /* Redirect calls to the old version node to point to its new
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
;
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
);
246 /* Create a new name for clone of DECL, add SUFFIX. Returns an identifier. */
248 static GTY(()) unsigned int clone_fn_id_num
;
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
262 #elif !defined NO_DOLLAR_IN_LABEL
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
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
,
284 tree old_decl
= old_node
->symbol
.decl
;
285 struct cgraph_node
*new_node
= NULL
;
288 struct ipa_replace_map
*map
;
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 */
297 new_decl
= copy_node (old_decl
);
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_SAFE_ELT (tree_map
, i
, map
)
328 tree var
= map
->new_tree
;
329 symtab_node ref_node
;
332 if (TREE_CODE (var
) != ADDR_EXPR
)
334 var
= get_base_var (var
);
337 if (TREE_CODE (var
) != FUNCTION_DECL
338 && TREE_CODE (var
) != VAR_DECL
)
341 /* Record references of the future statement initializing the constant
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
,
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;
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
);
366 if (bitmap_bit_p (args_to_skip
, newi
))
367 bitmap_set_bit (new_args_to_skip
, oldi
);
370 new_node
->clone
.combined_args_to_skip
= new_args_to_skip
;
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
);
384 /* NODE is being removed from symbol table; see if its entry can be replaced by
385 other inline clone. */
387 cgraph_find_replacement_node (struct cgraph_node
*node
)
389 struct cgraph_node
*next_inline_clone
, *replacement
;
391 for (next_inline_clone
= node
->clones
;
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
;
419 gcc_assert (node
->clones
== next_inline_clone
);
420 node
->clones
= next_inline_clone
->next_sibling_clone
;
423 new_clones
= node
->clones
;
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
;
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. */
444 if (!next_inline_clone
->clones
)
445 next_inline_clone
->clones
= new_clones
;
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. */
460 n
->clone_of
= next_inline_clone
;
461 n
= n
->next_sibling_clone
;
469 /* Like cgraph_set_call_stmt but walk the clone tree and update all
470 clones sharing the same function body. */
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
);
480 cgraph_set_call_stmt (edge
, new_stmt
);
486 struct cgraph_edge
*edge
= cgraph_edge (node
, old_stmt
);
488 cgraph_set_call_stmt (edge
, new_stmt
);
491 else if (node
->next_sibling_clone
)
492 node
= node
->next_sibling_clone
;
495 while (node
!= orig
&& !node
->next_sibling_clone
)
496 node
= node
->clone_of
;
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. */
511 cgraph_create_edge_including_clones (struct cgraph_node
*orig
,
512 struct cgraph_node
*callee
,
514 gimple stmt
, gcov_type count
,
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
;
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. */
538 cgraph_set_call_stmt (edge
, stmt
);
539 else if (!cgraph_edge (node
, stmt
))
541 edge
= cgraph_create_edge (node
, callee
, stmt
, count
,
543 edge
->inline_failed
= reason
;
548 else if (node
->next_sibling_clone
)
549 node
= node
->next_sibling_clone
;
552 while (node
!= orig
&& !node
->next_sibling_clone
)
553 node
= node
->clone_of
;
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
566 cgraph_remove_node_and_inline_clones (struct cgraph_node
*node
, struct cgraph_node
*forbidden_node
)
568 struct cgraph_edge
*e
, *next
;
571 if (node
== forbidden_node
)
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
);
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. */
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
611 If non-NULL BLOCK_TO_COPY determine what basic blocks
612 was copied to prevent duplications of calls that are dead
616 cgraph_copy_node_for_versioning (struct cgraph_node
*old_version
,
618 vec
<cgraph_edge_p
> redirect_callers
,
621 struct cgraph_node
*new_version
;
622 struct cgraph_edge
*e
;
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
)
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
,
644 for (e
= old_version
->indirect_calls
; e
; e
=e
->next_callee
)
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
,
651 FOR_EACH_VEC_ELT (redirect_callers
, i
, e
)
653 /* Redirect calls to the old version node to point to its new
655 cgraph_redirect_edge_callee (e
, new_version
);
658 cgraph_call_node_duplication_hooks (old_version
, 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
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
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. */
684 cgraph_function_versioning (struct cgraph_node
*old_version_node
,
685 vec
<cgraph_edge_p
> redirect_callers
,
686 vec
<ipa_replace_map_p
, va_gc
> *tree_map
,
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
;
697 if (!tree_versionable_function_p (old_decl
))
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
);
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. */
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. */
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,
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
;
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
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
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. */
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
)
824 fprintf (cgraph_dump_file
, " replace map: ");
826 i
< vec_safe_length (node
->clone
.tree_map
);
829 struct ipa_replace_map
*replace_info
;
830 replace_info
= (*node
->clone
.tree_map
)[i
];
831 print_generic_expr (cgraph_dump_file
, replace_info
->old_tree
, 0);
832 fprintf (cgraph_dump_file
, " -> ");
833 print_generic_expr (cgraph_dump_file
, replace_info
->new_tree
, 0);
834 fprintf (cgraph_dump_file
, "%s%s;",
835 replace_info
->replace_p
? "(replace)":"",
836 replace_info
->ref_p
? "(ref)":"");
838 fprintf (cgraph_dump_file
, "\n");
840 if (node
->clone
.args_to_skip
)
842 fprintf (cgraph_dump_file
, " args_to_skip: ");
843 dump_bitmap (cgraph_dump_file
, node
->clone
.args_to_skip
);
845 if (node
->clone
.args_to_skip
)
847 fprintf (cgraph_dump_file
, " combined_args_to_skip:");
848 dump_bitmap (cgraph_dump_file
, node
->clone
.combined_args_to_skip
);
851 cgraph_materialize_clone (node
);
857 FOR_EACH_FUNCTION (node
)
858 if (!node
->analyzed
&& node
->callees
)
859 cgraph_node_remove_callees (node
);
860 if (cgraph_dump_file
)
861 fprintf (cgraph_dump_file
, "Materialization Call site updates done.\n");
862 #ifdef ENABLE_CHECKING
865 symtab_remove_unreachable_nodes (false, cgraph_dump_file
);
868 #include "gt-cgraphclones.h"