Update change log
[platform/upstream/gcc48.git] / gcc / cgraphclones.c
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"