xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/cgraphclones.c (revision d909946ca08dceb44d7d0f22ec9488679695d976)
1 /* Callgraph clones
2    Copyright (C) 2003-2013 Free Software Foundation, Inc.
3    Contributed by Jan Hubicka
4 
5 This file is part of GCC.
6 
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.
11 
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.
16 
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/>.  */
20 
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.
24 
25    To allow whole program optimization without actual presence of function
26    bodies, an additional infrastructure is provided for so-called virtual
27    clones
28 
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).
32 
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.
38 
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.
42 
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.
50 
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.
54 
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.
61 
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.  */
66 
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"
97 
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)
103 {
104   struct cgraph_edge *new_edge;
105   gcov_type count = e->count * count_scale / REG_BR_PROB_BASE;
106   gcov_type freq;
107 
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;
114 
115   if (e->indirect_unknown_callee)
116     {
117       tree decl;
118 
119       if (call_stmt && (decl = gimple_call_fndecl (call_stmt)))
120 	{
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);
124 	}
125       else
126 	{
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;
131 	}
132     }
133   else
134     {
135       new_edge = cgraph_create_edge (n, e->callee, call_stmt, count, freq);
136       if (e->indirect_info)
137 	{
138 	  new_edge->indirect_info
139 	    = ggc_alloc_cleared_cgraph_indirect_call_info ();
140 	  *new_edge->indirect_info = *e->indirect_info;
141 	}
142     }
143 
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)
151     {
152       e->count -= new_edge->count;
153       if (e->count < 0)
154 	e->count = 0;
155     }
156   cgraph_call_edge_duplication_hooks (e, new_edge);
157   return new_edge;
158 }
159 
160 
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.
165 
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.  */
171 
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)
177 {
178   struct cgraph_node *new_node = cgraph_create_empty_node ();
179   struct cgraph_edge *e;
180   gcov_type count_scale;
181   unsigned i;
182 
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)
188     {
189       new_node->next_nested = new_node->origin->nested;
190       new_node->origin->nested = new_node;
191     }
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)
203     {
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;
208     }
209   else
210     count_scale = 0;
211   if (update_original)
212     {
213       n->count -= count;
214       if (n->count < 0)
215 	n->count = 0;
216     }
217 
218   FOR_EACH_VEC_ELT (redirect_callers, i, e)
219     {
220       /* Redirect calls to the old version node to point to its new
221 	 version.  */
222       cgraph_redirect_edge_callee (e, new_node);
223     }
224 
225 
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);
229 
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);
234 
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;
240 
241   if (call_duplication_hook)
242     cgraph_call_node_duplication_hooks (n, new_node);
243   return new_node;
244 }
245 
246 /* Create a new name for clone of DECL, add SUFFIX.  Returns an identifier.  */
247 
248 static GTY(()) unsigned int clone_fn_id_num;
249 
250 tree
251 clone_function_name (tree decl, const char *suffix)
252 {
253   tree name = DECL_ASSEMBLER_NAME (decl);
254   size_t len = IDENTIFIER_LENGTH (name);
255   char *tmp_name, *prefix;
256 
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);
269 }
270 
271 /* Create callgraph node clone with new declaration.  The actual body will
272    be copied later at compilation stage.
273 
274    TODO: after merging in ipa-sra use function call notes instead of args_to_skip
275    bitmap interface.
276    */
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)
283 {
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;
289 
290   if (!flag_wpa)
291     gcc_checking_assert  (tree_versionable_function_p (old_decl));
292 
293   gcc_assert (old_node->local.can_change_signature || !args_to_skip);
294 
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;
301 
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);
306 
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;
327   FOR_EACH_VEC_SAFE_ELT (tree_map, i, map)
328     {
329       tree var = map->new_tree;
330       symtab_node ref_node;
331 
332       STRIP_NOPS (var);
333       if (TREE_CODE (var) != ADDR_EXPR)
334 	continue;
335       var = get_base_var (var);
336       if (!var)
337 	continue;
338       if (TREE_CODE (var) != FUNCTION_DECL
339 	  && TREE_CODE (var) != VAR_DECL)
340 	continue;
341 
342       /* Record references of the future statement initializing the constant
343 	 argument.  */
344       ref_node = symtab_get_node (var);
345       gcc_checking_assert (ref_node);
346       ipa_record_reference ((symtab_node)new_node, (symtab_node)ref_node,
347 			    IPA_REF_ADDR, NULL);
348     }
349   if (!args_to_skip)
350     new_node->clone.combined_args_to_skip = old_node->clone.combined_args_to_skip;
351   else if (old_node->clone.combined_args_to_skip)
352     {
353       int newi = 0, oldi = 0;
354       tree arg;
355       bitmap new_args_to_skip = BITMAP_GGC_ALLOC ();
356       struct cgraph_node *orig_node;
357       for (orig_node = old_node; orig_node->clone_of; orig_node = orig_node->clone_of)
358         ;
359       for (arg = DECL_ARGUMENTS (orig_node->symbol.decl);
360 	   arg; arg = DECL_CHAIN (arg), oldi++)
361 	{
362 	  if (bitmap_bit_p (old_node->clone.combined_args_to_skip, oldi))
363 	    {
364 	      bitmap_set_bit (new_args_to_skip, oldi);
365 	      continue;
366 	    }
367 	  if (bitmap_bit_p (args_to_skip, newi))
368 	    bitmap_set_bit (new_args_to_skip, oldi);
369 	  newi++;
370 	}
371       new_node->clone.combined_args_to_skip = new_args_to_skip;
372     }
373   else
374     new_node->clone.combined_args_to_skip = args_to_skip;
375   new_node->symbol.externally_visible = 0;
376   new_node->local.local = 1;
377   new_node->lowered = true;
378 
379   cgraph_call_node_duplication_hooks (old_node, new_node);
380 
381 
382   return new_node;
383 }
384 
385 /* NODE is being removed from symbol table; see if its entry can be replaced by
386    other inline clone.  */
387 struct cgraph_node *
388 cgraph_find_replacement_node (struct cgraph_node *node)
389 {
390   struct cgraph_node *next_inline_clone, *replacement;
391 
392   for (next_inline_clone = node->clones;
393        next_inline_clone
394        && next_inline_clone->symbol.decl != node->symbol.decl;
395        next_inline_clone = next_inline_clone->next_sibling_clone)
396     ;
397 
398   /* If there is inline clone of the node being removed, we need
399      to put it into the position of removed node and reorganize all
400      other clones to be based on it.  */
401   if (next_inline_clone)
402     {
403       struct cgraph_node *n;
404       struct cgraph_node *new_clones;
405 
406       replacement = next_inline_clone;
407 
408       /* Unlink inline clone from the list of clones of removed node.  */
409       if (next_inline_clone->next_sibling_clone)
410 	next_inline_clone->next_sibling_clone->prev_sibling_clone
411 	  = next_inline_clone->prev_sibling_clone;
412       if (next_inline_clone->prev_sibling_clone)
413 	{
414 	  gcc_assert (node->clones != next_inline_clone);
415 	  next_inline_clone->prev_sibling_clone->next_sibling_clone
416 	    = next_inline_clone->next_sibling_clone;
417 	}
418       else
419 	{
420 	  gcc_assert (node->clones == next_inline_clone);
421 	  node->clones = next_inline_clone->next_sibling_clone;
422 	}
423 
424       new_clones = node->clones;
425       node->clones = NULL;
426 
427       /* Copy clone info.  */
428       next_inline_clone->clone = node->clone;
429 
430       /* Now place it into clone tree at same level at NODE.  */
431       next_inline_clone->clone_of = node->clone_of;
432       next_inline_clone->prev_sibling_clone = NULL;
433       next_inline_clone->next_sibling_clone = NULL;
434       if (node->clone_of)
435 	{
436 	  if (node->clone_of->clones)
437 	    node->clone_of->clones->prev_sibling_clone = next_inline_clone;
438 	  next_inline_clone->next_sibling_clone = node->clone_of->clones;
439 	  node->clone_of->clones = next_inline_clone;
440 	}
441 
442       /* Merge the clone list.  */
443       if (new_clones)
444 	{
445 	  if (!next_inline_clone->clones)
446 	    next_inline_clone->clones = new_clones;
447 	  else
448 	    {
449 	      n = next_inline_clone->clones;
450 	      while (n->next_sibling_clone)
451 		n =  n->next_sibling_clone;
452 	      n->next_sibling_clone = new_clones;
453 	      new_clones->prev_sibling_clone = n;
454 	    }
455 	}
456 
457       /* Update clone_of pointers.  */
458       n = new_clones;
459       while (n)
460 	{
461 	  n->clone_of = next_inline_clone;
462 	  n = n->next_sibling_clone;
463 	}
464       return replacement;
465     }
466   else
467     return NULL;
468 }
469 
470 /* Like cgraph_set_call_stmt but walk the clone tree and update all
471    clones sharing the same function body.  */
472 
473 void
474 cgraph_set_call_stmt_including_clones (struct cgraph_node *orig,
475 				       gimple old_stmt, gimple new_stmt)
476 {
477   struct cgraph_node *node;
478   struct cgraph_edge *edge = cgraph_edge (orig, old_stmt);
479 
480   if (edge)
481     cgraph_set_call_stmt (edge, new_stmt);
482 
483   node = orig->clones;
484   if (node)
485     while (node != orig)
486       {
487 	struct cgraph_edge *edge = cgraph_edge (node, old_stmt);
488 	if (edge)
489 	  cgraph_set_call_stmt (edge, new_stmt);
490 	if (node->clones)
491 	  node = node->clones;
492 	else if (node->next_sibling_clone)
493 	  node = node->next_sibling_clone;
494 	else
495 	  {
496 	    while (node != orig && !node->next_sibling_clone)
497 	      node = node->clone_of;
498 	    if (node != orig)
499 	      node = node->next_sibling_clone;
500 	  }
501       }
502 }
503 
504 /* Like cgraph_create_edge walk the clone tree and update all clones sharing
505    same function body.  If clones already have edge for OLD_STMT; only
506    update the edge same way as cgraph_set_call_stmt_including_clones does.
507 
508    TODO: COUNT and LOOP_DEPTH should be properly distributed based on relative
509    frequencies of the clones.  */
510 
511 void
512 cgraph_create_edge_including_clones (struct cgraph_node *orig,
513 				     struct cgraph_node *callee,
514 				     gimple old_stmt,
515 				     gimple stmt, gcov_type count,
516 				     int freq,
517 				     cgraph_inline_failed_t reason)
518 {
519   struct cgraph_node *node;
520   struct cgraph_edge *edge;
521 
522   if (!cgraph_edge (orig, stmt))
523     {
524       edge = cgraph_create_edge (orig, callee, stmt, count, freq);
525       edge->inline_failed = reason;
526     }
527 
528   node = orig->clones;
529   if (node)
530     while (node != orig)
531       {
532 	struct cgraph_edge *edge = cgraph_edge (node, old_stmt);
533 
534         /* It is possible that clones already contain the edge while
535 	   master didn't.  Either we promoted indirect call into direct
536 	   call in the clone or we are processing clones of unreachable
537 	   master where edges has been removed.  */
538 	if (edge)
539 	  cgraph_set_call_stmt (edge, stmt);
540 	else if (!cgraph_edge (node, stmt))
541 	  {
542 	    edge = cgraph_create_edge (node, callee, stmt, count,
543 				       freq);
544 	    edge->inline_failed = reason;
545 	  }
546 
547 	if (node->clones)
548 	  node = node->clones;
549 	else if (node->next_sibling_clone)
550 	  node = node->next_sibling_clone;
551 	else
552 	  {
553 	    while (node != orig && !node->next_sibling_clone)
554 	      node = node->clone_of;
555 	    if (node != orig)
556 	      node = node->next_sibling_clone;
557 	  }
558       }
559 }
560 
561 /* Remove the node from cgraph and all inline clones inlined into it.
562    Skip however removal of FORBIDDEN_NODE and return true if it needs to be
563    removed.  This allows to call the function from outer loop walking clone
564    tree.  */
565 
566 bool
567 cgraph_remove_node_and_inline_clones (struct cgraph_node *node, struct cgraph_node *forbidden_node)
568 {
569   struct cgraph_edge *e, *next;
570   bool found = false;
571 
572   if (node == forbidden_node)
573     {
574       cgraph_remove_edge (node->callers);
575       return true;
576     }
577   for (e = node->callees; e; e = next)
578     {
579       next = e->next_callee;
580       if (!e->inline_failed)
581         found |= cgraph_remove_node_and_inline_clones (e->callee, forbidden_node);
582     }
583   cgraph_remove_node (node);
584   return found;
585 }
586 
587 /* The edges representing the callers of the NEW_VERSION node were
588    fixed by cgraph_function_versioning (), now the call_expr in their
589    respective tree code should be updated to call the NEW_VERSION.  */
590 
591 static void
592 update_call_expr (struct cgraph_node *new_version)
593 {
594   struct cgraph_edge *e;
595 
596   gcc_assert (new_version);
597 
598   /* Update the call expr on the edges to call the new version.  */
599   for (e = new_version->callers; e; e = e->next_caller)
600     {
601       struct function *inner_function = DECL_STRUCT_FUNCTION (e->caller->symbol.decl);
602       gimple_call_set_fndecl (e->call_stmt, new_version->symbol.decl);
603       maybe_clean_eh_stmt_fn (inner_function, e->call_stmt);
604     }
605 }
606 
607 
608 /* Create a new cgraph node which is the new version of
609    OLD_VERSION node.  REDIRECT_CALLERS holds the callers
610    edges which should be redirected to point to
611    NEW_VERSION.  ALL the callees edges of OLD_VERSION
612    are cloned to the new version node.  Return the new
613    version node.
614 
615    If non-NULL BLOCK_TO_COPY determine what basic blocks
616    was copied to prevent duplications of calls that are dead
617    in the clone.  */
618 
619 struct cgraph_node *
620 cgraph_copy_node_for_versioning (struct cgraph_node *old_version,
621 				 tree new_decl,
622 				 vec<cgraph_edge_p> redirect_callers,
623 				 bitmap bbs_to_copy)
624  {
625    struct cgraph_node *new_version;
626    struct cgraph_edge *e;
627    unsigned i;
628 
629    gcc_assert (old_version);
630 
631    new_version = cgraph_create_node (new_decl);
632 
633    new_version->analyzed = old_version->analyzed;
634    new_version->local = old_version->local;
635    new_version->symbol.externally_visible = false;
636    new_version->local.local = old_version->analyzed;
637    new_version->global = old_version->global;
638    new_version->rtl = old_version->rtl;
639    new_version->count = old_version->count;
640 
641    for (e = old_version->callees; e; e=e->next_callee)
642      if (!bbs_to_copy
643 	 || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
644        cgraph_clone_edge (e, new_version, e->call_stmt,
645 			  e->lto_stmt_uid, REG_BR_PROB_BASE,
646 			  CGRAPH_FREQ_BASE,
647 			  true);
648    for (e = old_version->indirect_calls; 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_EACH_VEC_ELT (redirect_callers, i, e)
656      {
657        /* Redirect calls to the old version node to point to its new
658 	  version.  */
659        cgraph_redirect_edge_callee (e, new_version);
660      }
661 
662    cgraph_call_node_duplication_hooks (old_version, new_version);
663 
664    return new_version;
665  }
666 
667 /* Perform function versioning.
668    Function versioning includes copying of the tree and
669    a callgraph update (creating a new cgraph node and updating
670    its callees and callers).
671 
672    REDIRECT_CALLERS varray includes the edges to be redirected
673    to the new version.
674 
675    TREE_MAP is a mapping of tree nodes we want to replace with
676    new ones (according to results of prior analysis).
677    OLD_VERSION_NODE is the node that is versioned.
678 
679    If non-NULL ARGS_TO_SKIP determine function parameters to remove
680    from new version.
681    If SKIP_RETURN is true, the new version will return void.
682    If non-NULL BLOCK_TO_COPY determine what basic blocks to copy.
683    If non_NULL NEW_ENTRY determine new entry BB of the clone.
684 
685    Return the new version's cgraph node.  */
686 
687 struct cgraph_node *
688 cgraph_function_versioning (struct cgraph_node *old_version_node,
689 			    vec<cgraph_edge_p> redirect_callers,
690 			    vec<ipa_replace_map_p, va_gc> *tree_map,
691 			    bitmap args_to_skip,
692 			    bool skip_return,
693 			    bitmap bbs_to_copy,
694 			    basic_block new_entry_block,
695 			    const char *clone_name)
696 {
697   tree old_decl = old_version_node->symbol.decl;
698   struct cgraph_node *new_version_node = NULL;
699   tree new_decl;
700 
701   if (!tree_versionable_function_p (old_decl))
702     return NULL;
703 
704   gcc_assert (old_version_node->local.can_change_signature || !args_to_skip);
705 
706   /* Make a new FUNCTION_DECL tree node for the new version. */
707   if (!args_to_skip && !skip_return)
708     new_decl = copy_node (old_decl);
709   else
710     new_decl
711       = build_function_decl_skip_args (old_decl, args_to_skip, skip_return);
712 
713   /* Generate a new name for the new version. */
714   DECL_NAME (new_decl) = clone_function_name (old_decl, clone_name);
715   SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
716   SET_DECL_RTL (new_decl, NULL);
717 
718   /* When the old decl was a con-/destructor make sure the clone isn't.  */
719   DECL_STATIC_CONSTRUCTOR(new_decl) = 0;
720   DECL_STATIC_DESTRUCTOR(new_decl) = 0;
721 
722   /* Create the new version's call-graph node.
723      and update the edges of the new node. */
724   new_version_node =
725     cgraph_copy_node_for_versioning (old_version_node, new_decl,
726 				     redirect_callers, bbs_to_copy);
727 
728   /* Copy the OLD_VERSION_NODE function tree to the new version.  */
729   tree_function_versioning (old_decl, new_decl, tree_map, false, args_to_skip,
730 			    skip_return, bbs_to_copy, new_entry_block);
731 
732   /* Update the new version's properties.
733      Make The new version visible only within this translation unit.  Make sure
734      that is not weak also.
735      ??? We cannot use COMDAT linkage because there is no
736      ABI support for this.  */
737   symtab_make_decl_local (new_version_node->symbol.decl);
738   DECL_VIRTUAL_P (new_version_node->symbol.decl) = 0;
739   new_version_node->symbol.externally_visible = 0;
740   new_version_node->local.local = 1;
741   new_version_node->lowered = true;
742 
743   /* Update the call_expr on the edges to call the new version node. */
744   update_call_expr (new_version_node);
745 
746   cgraph_call_function_insertion_hooks (new_version_node);
747   return new_version_node;
748 }
749 
750 /* Given virtual clone, turn it into actual clone.  */
751 
752 static void
753 cgraph_materialize_clone (struct cgraph_node *node)
754 {
755   bitmap_obstack_initialize (NULL);
756   node->former_clone_of = node->clone_of->symbol.decl;
757   if (node->clone_of->former_clone_of)
758     node->former_clone_of = node->clone_of->former_clone_of;
759   /* Copy the OLD_VERSION_NODE function tree to the new version.  */
760   tree_function_versioning (node->clone_of->symbol.decl, node->symbol.decl,
761   			    node->clone.tree_map, true,
762 			    node->clone.args_to_skip, false,
763 			    NULL, NULL);
764   if (cgraph_dump_file)
765     {
766       dump_function_to_file (node->clone_of->symbol.decl, cgraph_dump_file, dump_flags);
767       dump_function_to_file (node->symbol.decl, cgraph_dump_file, dump_flags);
768     }
769 
770   /* Function is no longer clone.  */
771   if (node->next_sibling_clone)
772     node->next_sibling_clone->prev_sibling_clone = node->prev_sibling_clone;
773   if (node->prev_sibling_clone)
774     node->prev_sibling_clone->next_sibling_clone = node->next_sibling_clone;
775   else
776     node->clone_of->clones = node->next_sibling_clone;
777   node->next_sibling_clone = NULL;
778   node->prev_sibling_clone = NULL;
779   if (!node->clone_of->analyzed && !node->clone_of->clones)
780     {
781       cgraph_release_function_body (node->clone_of);
782       cgraph_node_remove_callees (node->clone_of);
783       ipa_remove_all_references (&node->clone_of->symbol.ref_list);
784     }
785   node->clone_of = NULL;
786   bitmap_obstack_release (NULL);
787 }
788 
789 /* Once all functions from compilation unit are in memory, produce all clones
790    and update all calls.  We might also do this on demand if we don't want to
791    bring all functions to memory prior compilation, but current WHOPR
792    implementation does that and it is is bit easier to keep everything right in
793    this order.  */
794 
795 void
796 cgraph_materialize_all_clones (void)
797 {
798   struct cgraph_node *node;
799   bool stabilized = false;
800 
801   if (cgraph_dump_file)
802     fprintf (cgraph_dump_file, "Materializing clones\n");
803 #ifdef ENABLE_CHECKING
804   verify_cgraph ();
805 #endif
806 
807   /* We can also do topological order, but number of iterations should be
808      bounded by number of IPA passes since single IPA pass is probably not
809      going to create clones of clones it created itself.  */
810   while (!stabilized)
811     {
812       stabilized = true;
813       FOR_EACH_FUNCTION (node)
814         {
815 	  if (node->clone_of && node->symbol.decl != node->clone_of->symbol.decl
816 	      && !gimple_has_body_p (node->symbol.decl))
817 	    {
818 	      if (gimple_has_body_p (node->clone_of->symbol.decl))
819 	        {
820 		  if (cgraph_dump_file)
821 		    {
822 		      fprintf (cgraph_dump_file, "cloning %s to %s\n",
823 			       xstrdup (cgraph_node_name (node->clone_of)),
824 			       xstrdup (cgraph_node_name (node)));
825 		      if (node->clone.tree_map)
826 		        {
827 			  unsigned int i;
828 		          fprintf (cgraph_dump_file, "   replace map: ");
829 			  for (i = 0;
830 			       i < vec_safe_length (node->clone.tree_map);
831 			       i++)
832 			    {
833 			      struct ipa_replace_map *replace_info;
834 			      replace_info = (*node->clone.tree_map)[i];
835 			      print_generic_expr (cgraph_dump_file, replace_info->old_tree, 0);
836 			      fprintf (cgraph_dump_file, " -> ");
837 			      print_generic_expr (cgraph_dump_file, replace_info->new_tree, 0);
838 			      fprintf (cgraph_dump_file, "%s%s;",
839 			      	       replace_info->replace_p ? "(replace)":"",
840 				       replace_info->ref_p ? "(ref)":"");
841 			    }
842 			  fprintf (cgraph_dump_file, "\n");
843 			}
844 		      if (node->clone.args_to_skip)
845 			{
846 		          fprintf (cgraph_dump_file, "   args_to_skip: ");
847 		          dump_bitmap (cgraph_dump_file, node->clone.args_to_skip);
848 			}
849 		      if (node->clone.args_to_skip)
850 			{
851 		          fprintf (cgraph_dump_file, "   combined_args_to_skip:");
852 		          dump_bitmap (cgraph_dump_file, node->clone.combined_args_to_skip);
853 			}
854 		    }
855 		  cgraph_materialize_clone (node);
856 		  stabilized = false;
857 	        }
858 	    }
859 	}
860     }
861   FOR_EACH_FUNCTION (node)
862     if (!node->analyzed && node->callees)
863       cgraph_node_remove_callees (node);
864   if (cgraph_dump_file)
865     fprintf (cgraph_dump_file, "Materialization Call site updates done.\n");
866 #ifdef ENABLE_CHECKING
867   verify_cgraph ();
868 #endif
869   symtab_remove_unreachable_nodes (false, cgraph_dump_file);
870 }
871 
872 #include "gt-cgraphclones.h"
873