OSDN Git Service

2012-10-08 Tobias Burnus <burnus@net-b.de>
[pf3gnuchains/gcc-fork.git] / gcc / cgraphclones.c
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
5
6 This file is part of GCC.
7
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.
12
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.
17
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/>.  */
21
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.
25
26    To allow whole program optimization without actual presence of function
27    bodies, an additional infrastructure is provided for so-called virtual
28    clones
29
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).
33
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.
39
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.
43
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.
51
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.
55
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.
62
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.  */
67
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"
98
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)
104 {
105   struct cgraph_edge *new_edge;
106   gcov_type count = e->count * count_scale / REG_BR_PROB_BASE;
107   gcov_type freq;
108
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;
115
116   if (e->indirect_unknown_callee)
117     {
118       tree decl;
119
120       if (call_stmt && (decl = gimple_call_fndecl (call_stmt)))
121         {
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);
125         }
126       else
127         {
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;
132         }
133     }
134   else
135     {
136       new_edge = cgraph_create_edge (n, e->callee, call_stmt, count, freq);
137       if (e->indirect_info)
138         {
139           new_edge->indirect_info
140             = ggc_alloc_cleared_cgraph_indirect_call_info ();
141           *new_edge->indirect_info = *e->indirect_info;
142         }
143     }
144
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)
152     {
153       e->count -= new_edge->count;
154       if (e->count < 0)
155         e->count = 0;
156     }
157   cgraph_call_edge_duplication_hooks (e, new_edge);
158   return new_edge;
159 }
160
161
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.
166
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.  */
172
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)
178 {
179   struct cgraph_node *new_node = cgraph_create_empty_node ();
180   struct cgraph_edge *e;
181   gcov_type count_scale;
182   unsigned i;
183
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)
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 = 0;
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 (cgraph_edge_p, 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,heap) *redirect_callers,
280                              VEC(ipa_replace_map_p,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_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)
327     {
328       tree var = map->new_tree;
329       symtab_node ref_node;
330
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;
340
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);
347     }
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)
351     {
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)
357         ;
358       for (arg = DECL_ARGUMENTS (orig_node->symbol.decl);
359            arg; arg = DECL_CHAIN (arg), oldi++)
360         {
361           if (bitmap_bit_p (old_node->clone.combined_args_to_skip, oldi))
362             {
363               bitmap_set_bit (new_args_to_skip, oldi);
364               continue;
365             }
366           if (bitmap_bit_p (args_to_skip, newi))
367             bitmap_set_bit (new_args_to_skip, oldi);
368           newi++;
369         }
370       new_node->clone.combined_args_to_skip = new_args_to_skip;
371     }
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;
377
378   cgraph_call_node_duplication_hooks (old_node, new_node);
379
380
381   return new_node;
382 }
383
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)
388 {
389   struct cgraph_node *next_inline_clone, *replacement;
390
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)
395     ;
396
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)
401     {
402       struct cgraph_node *n;
403       struct cgraph_node *new_clones;
404
405       replacement = next_inline_clone;
406
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)
412         {
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;
416         }
417       else
418         {
419           gcc_assert (node->clones == next_inline_clone);
420           node->clones = next_inline_clone->next_sibling_clone;
421         }
422
423       new_clones = node->clones;
424       node->clones = NULL;
425
426       /* Copy clone info.  */
427       next_inline_clone->clone = node->clone;
428
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)
434         {
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;
439         }
440
441       /* Merge the clone list.  */
442       if (new_clones)
443         {
444           if (!next_inline_clone->clones)
445             next_inline_clone->clones = new_clones;
446           else
447             {
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;
453             }
454         }
455
456       /* Update clone_of pointers.  */
457       n = new_clones;
458       while (n)
459         {
460           n->clone_of = next_inline_clone;
461           n = n->next_sibling_clone;
462         }
463       return replacement;
464     }
465   else
466     return NULL;
467 }
468
469 /* Like cgraph_set_call_stmt but walk the clone tree and update all
470    clones sharing the same function body.  */
471
472 void
473 cgraph_set_call_stmt_including_clones (struct cgraph_node *orig,
474                                        gimple old_stmt, gimple new_stmt)
475 {
476   struct cgraph_node *node;
477   struct cgraph_edge *edge = cgraph_edge (orig, old_stmt);
478
479   if (edge)
480     cgraph_set_call_stmt (edge, new_stmt);
481
482   node = orig->clones;
483   if (node)
484     while (node != orig)
485       {
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
494           {
495             while (node != orig && !node->next_sibling_clone)
496               node = node->clone_of;
497             if (node != orig)
498               node = node->next_sibling_clone;
499           }
500       }
501 }
502
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.
506
507    TODO: COUNT and LOOP_DEPTH should be properly distributed based on relative
508    frequencies of the clones.  */
509
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)
517 {
518   struct cgraph_node *node;
519   struct cgraph_edge *edge;
520
521   if (!cgraph_edge (orig, stmt))
522     {
523       edge = cgraph_create_edge (orig, callee, stmt, count, freq);
524       edge->inline_failed = reason;
525     }
526
527   node = orig->clones;
528   if (node)
529     while (node != orig)
530       {
531         struct cgraph_edge *edge = cgraph_edge (node, old_stmt);
532
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))
540           {
541             edge = cgraph_create_edge (node, callee, stmt, count,
542                                        freq);
543             edge->inline_failed = reason;
544           }
545
546         if (node->clones)
547           node = node->clones;
548         else if (node->next_sibling_clone)
549           node = node->next_sibling_clone;
550         else
551           {
552             while (node != orig && !node->next_sibling_clone)
553               node = node->clone_of;
554             if (node != orig)
555               node = node->next_sibling_clone;
556           }
557       }
558 }
559
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.  */
564
565 bool
566 cgraph_remove_node_and_inline_clones (struct cgraph_node *node, struct cgraph_node *forbidden_node)
567 {
568   struct cgraph_edge *e, *next;
569   bool found = false;
570
571   if (node == forbidden_node)
572     return true;
573   for (e = node->callees; e; e = next)
574     {
575       next = e->next_callee;
576       if (!e->inline_failed)
577         found |= cgraph_remove_node_and_inline_clones (e->callee, forbidden_node);
578     }
579   cgraph_remove_node (node);
580   return found;
581 }
582
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.  */
586
587 static void
588 update_call_expr (struct cgraph_node *new_version)
589 {
590   struct cgraph_edge *e;
591
592   gcc_assert (new_version);
593
594   /* Update the call expr on the edges to call the new version.  */
595   for (e = new_version->callers; e; e = e->next_caller)
596     {
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);
600     }
601 }
602
603
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. 
610
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.  */
614
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)
620  {
621    struct cgraph_node *new_version;
622    struct cgraph_edge *e;
623    unsigned i;
624
625    gcc_assert (old_version);
626
627    new_version = cgraph_create_node (new_decl);
628
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;
636
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)
652      {
653        /* Redirect calls to the old version node to point to its new
654           version.  */
655        cgraph_redirect_edge_callee (e, new_version);
656      }
657
658    cgraph_call_node_duplication_hooks (old_version, new_version);
659
660    return new_version;
661  }
662
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).
667
668    REDIRECT_CALLERS varray includes the edges to be redirected
669    to the new version.
670
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.
674
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.
680
681    Return the new version's cgraph node.  */
682
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)
692 {
693   tree old_decl = old_version_node->symbol.decl;
694   struct cgraph_node *new_version_node = NULL;
695   tree new_decl;
696
697   if (!tree_versionable_function_p (old_decl))
698     return NULL;
699
700   gcc_assert (old_version_node->local.can_change_signature || !args_to_skip);
701
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);
708
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);
713
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;
717
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);
723
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);
727
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;
738
739   /* Update the call_expr on the edges to call the new version node. */
740   update_call_expr (new_version_node);
741
742   cgraph_call_function_insertion_hooks (new_version_node);
743   return new_version_node;
744 }
745
746 /* Given virtual clone, turn it into actual clone.  */
747
748 static void
749 cgraph_materialize_clone (struct cgraph_node *node)
750 {
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)
761     {
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);
764     }
765
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)
776     {
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);
780     }
781   node->clone_of = NULL;
782   bitmap_obstack_release (NULL);
783 }
784
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.  */
790
791 void
792 cgraph_materialize_all_clones (void)
793 {
794   struct cgraph_node *node;
795   bool stabilized = false;
796
797   if (cgraph_dump_file)
798     fprintf (cgraph_dump_file, "Materializing clones\n");
799 #ifdef ENABLE_CHECKING
800   verify_cgraph ();
801 #endif
802
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)
807     {
808       stabilized = true;
809       FOR_EACH_FUNCTION (node)
810         {
811           if (node->clone_of && node->symbol.decl != node->clone_of->symbol.decl
812               && !gimple_has_body_p (node->symbol.decl))
813             {
814               if (gimple_has_body_p (node->clone_of->symbol.decl))
815                 {
816                   if (cgraph_dump_file)
817                     {
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)
822                         {
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++)
828                             {
829                               struct ipa_replace_map *replace_info;
830                               replace_info = VEC_index (ipa_replace_map_p,
831                                                         node->clone.tree_map,
832                                                         i);
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)":"");
839                             }
840                           fprintf (cgraph_dump_file, "\n");
841                         }
842                       if (node->clone.args_to_skip)
843                         {
844                           fprintf (cgraph_dump_file, "   args_to_skip: ");
845                           dump_bitmap (cgraph_dump_file, node->clone.args_to_skip);
846                         }
847                       if (node->clone.args_to_skip)
848                         {
849                           fprintf (cgraph_dump_file, "   combined_args_to_skip:");
850                           dump_bitmap (cgraph_dump_file, node->clone.combined_args_to_skip);
851                         }
852                     }
853                   cgraph_materialize_clone (node);
854                   stabilized = false;
855                 }
856             }
857         }
858     }
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);
868 }
869
870 #include "gt-cgraphclones.h"