OSDN Git Service

* ipa.c (cgraph_comdat_can_be_unshared_p): Fix pasto.
[pf3gnuchains/gcc-fork.git] / gcc / ipa.c
1 /* Basic IPA optimizations and utilities.
2    Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
3    Free Software Foundation, Inc.
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 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "cgraph.h"
26 #include "tree-pass.h"
27 #include "timevar.h"
28 #include "gimple.h"
29 #include "ggc.h"
30 #include "flags.h"
31 #include "pointer-set.h"
32 #include "target.h"
33 #include "tree-iterator.h"
34 #include "ipa-utils.h"
35
36 /* Look for all functions inlined to NODE and update their inlined_to pointers
37    to INLINED_TO.  */
38
39 static void
40 update_inlined_to_pointer (struct cgraph_node *node, struct cgraph_node *inlined_to)
41 {
42   struct cgraph_edge *e;
43   for (e = node->callees; e; e = e->next_callee)
44     if (e->callee->global.inlined_to)
45       {
46         e->callee->global.inlined_to = inlined_to;
47         update_inlined_to_pointer (e->callee, inlined_to);
48       }
49 }
50
51 /* Add cgraph NODE to queue starting at FIRST.
52
53    The queue is linked via AUX pointers and terminated by pointer to 1.
54    We enqueue nodes at two occasions: when we find them reachable or when we find
55    their bodies needed for further clonning.  In the second case we mark them
56    by pointer to 2 after processing so they are re-queue when they become
57    reachable.  */
58
59 static void
60 enqueue_cgraph_node (struct cgraph_node *node, struct cgraph_node **first)
61 {
62   /* Node is still in queue; do nothing.  */
63   if (node->aux && node->aux != (void *) 2)
64     return;
65   /* Node was already processed as unreachable, re-enqueue
66      only if it became reachable now.  */
67   if (node->aux == (void *)2 && !node->reachable)
68     return;
69   node->aux = *first;
70   *first = node;
71 }
72
73 /* Add varpool NODE to queue starting at FIRST.  */
74
75 static void
76 enqueue_varpool_node (struct varpool_node *node, struct varpool_node **first)
77 {
78   node->aux = *first;
79   *first = node;
80 }
81
82 /* Process references.  */
83
84 static void
85 process_references (struct ipa_ref_list *list,
86                     struct cgraph_node **first,
87                     struct varpool_node **first_varpool,
88                     bool before_inlining_p)
89 {
90   int i;
91   struct ipa_ref *ref;
92   for (i = 0; ipa_ref_list_reference_iterate (list, i, ref); i++)
93     {
94       if (ref->refered_type == IPA_REF_CGRAPH)
95         {
96           struct cgraph_node *node = ipa_ref_node (ref);
97           if (!node->reachable
98               && node->analyzed
99               && (!DECL_EXTERNAL (node->decl)
100                   || before_inlining_p))
101             node->reachable = true;
102           enqueue_cgraph_node (node, first);
103         }
104       else
105         {
106           struct varpool_node *node = ipa_ref_varpool_node (ref);
107           if (!node->needed)
108             {
109               varpool_mark_needed_node (node);
110               enqueue_varpool_node (node, first_varpool);
111             }
112         }
113     }
114 }
115
116
117 /* Return true when NODE can not be local. Worker for cgraph_local_node_p.  */
118
119 static bool
120 cgraph_non_local_node_p_1 (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
121 {
122    return !(cgraph_only_called_directly_or_aliased_p (node)
123             && node->analyzed
124             && !DECL_EXTERNAL (node->decl)
125             && !node->local.externally_visible
126             && !node->reachable_from_other_partition
127             && !node->in_other_partition);
128 }
129
130 /* Return true when function can be marked local.  */
131
132 static bool
133 cgraph_local_node_p (struct cgraph_node *node)
134 {
135    return !cgraph_for_node_and_aliases (cgraph_function_or_thunk_node (node, NULL),
136                                         cgraph_non_local_node_p_1, NULL, true);
137                                         
138 }
139
140 /* Return true when NODE has ADDR reference.  */
141
142 static bool
143 has_addr_references_p (struct cgraph_node *node,
144                        void *data ATTRIBUTE_UNUSED)
145 {
146   int i;
147   struct ipa_ref *ref;
148
149   for (i = 0; ipa_ref_list_refering_iterate (&node->ref_list, i, ref); i++)
150     if (ref->use == IPA_REF_ADDR)
151       return true;
152   return false;
153 }
154
155 /* Perform reachability analysis and reclaim all unreachable nodes.
156    If BEFORE_INLINING_P is true this function is called before inlining
157    decisions has been made.  If BEFORE_INLINING_P is false this function also
158    removes unneeded bodies of extern inline functions.  */
159
160 bool
161 cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
162 {
163   struct cgraph_node *first = (struct cgraph_node *) (void *) 1;
164   struct varpool_node *first_varpool = (struct varpool_node *) (void *) 1;
165   struct cgraph_node *node, *next;
166   struct varpool_node *vnode, *vnext;
167   bool changed = false;
168
169 #ifdef ENABLE_CHECKING
170   verify_cgraph ();
171 #endif
172   if (file)
173     fprintf (file, "\nReclaiming functions:");
174 #ifdef ENABLE_CHECKING
175   for (node = cgraph_nodes; node; node = node->next)
176     gcc_assert (!node->aux);
177   for (vnode = varpool_nodes; vnode; vnode = vnode->next)
178     gcc_assert (!vnode->aux);
179 #endif
180   varpool_reset_queue ();
181   /* Mark functions whose bodies are obviously needed.
182      This is mostly when they can be referenced externally.  Inline clones
183      are special since their declarations are shared with master clone and thus
184      cgraph_can_remove_if_no_direct_calls_and_refs_p should not be called on them.  */
185   for (node = cgraph_nodes; node; node = node->next)
186     if (node->analyzed && !node->global.inlined_to
187         && (!cgraph_can_remove_if_no_direct_calls_and_refs_p (node)
188             /* Keep around virtual functions for possible devirtualization.  */
189             || (before_inlining_p
190                 && DECL_VIRTUAL_P (node->decl)
191                 && (DECL_COMDAT (node->decl) || DECL_EXTERNAL (node->decl)))
192             /* Also external functions with address taken are better to stay
193                for indirect inlining.  */
194             || (before_inlining_p
195                 && DECL_EXTERNAL (node->decl)
196                 && node->address_taken)))
197       {
198         gcc_assert (!node->global.inlined_to);
199         enqueue_cgraph_node (node, &first);
200         node->reachable = true;
201       }
202     else
203       {
204         gcc_assert (!node->aux);
205         node->reachable = false;
206       }
207
208   /* Mark variables that are obviously needed.  */
209   for (vnode = varpool_nodes; vnode; vnode = vnode->next)
210     {
211       vnode->next_needed = NULL;
212       vnode->prev_needed = NULL;
213       if ((vnode->analyzed || vnode->force_output)
214           && !varpool_can_remove_if_no_refs (vnode))
215         {
216           vnode->needed = false;
217           varpool_mark_needed_node (vnode);
218           enqueue_varpool_node (vnode, &first_varpool);
219         }
220       else
221         vnode->needed = false;
222     }
223
224   /* Perform reachability analysis.  As a special case do not consider
225      extern inline functions not inlined as live because we won't output
226      them at all. 
227
228      We maintain two worklist, one for cgraph nodes other for varpools and
229      are finished once both are empty.  */
230
231   while (first != (struct cgraph_node *) (void *) 1
232          || first_varpool != (struct varpool_node *) (void *) 1)
233     {
234       if (first != (struct cgraph_node *) (void *) 1)
235         {
236           struct cgraph_edge *e;
237           node = first;
238           first = (struct cgraph_node *) first->aux;
239           if (!node->reachable)
240             node->aux = (void *)2;
241
242           /* If we found this node reachable, first mark on the callees
243              reachable too, unless they are direct calls to extern inline functions
244              we decided to not inline.  */
245           if (node->reachable)
246             {
247               for (e = node->callees; e; e = e->next_callee)
248                 {
249                   if (!e->callee->reachable
250                       && node->analyzed
251                       && (!e->inline_failed
252                           || !DECL_EXTERNAL (e->callee->decl)
253                           || before_inlining_p))
254                     e->callee->reachable = true;
255                   enqueue_cgraph_node (e->callee, &first);
256                 }
257               process_references (&node->ref_list, &first, &first_varpool, before_inlining_p);
258             }
259
260           /* If any function in a comdat group is reachable, force
261              all other functions in the same comdat group to be
262              also reachable.  */
263           if (node->same_comdat_group
264               && node->reachable
265               && !node->global.inlined_to)
266             {
267               for (next = node->same_comdat_group;
268                    next != node;
269                    next = next->same_comdat_group)
270                 if (!next->reachable)
271                   {
272                     next->reachable = true;
273                     enqueue_cgraph_node (next, &first);
274                   }
275             }
276
277           /* We can freely remove inline clones even if they are cloned, however if
278              function is clone of real clone, we must keep it around in order to
279              make materialize_clones produce function body with the changes
280              applied.  */
281           while (node->clone_of && !node->clone_of->aux
282                  && !gimple_has_body_p (node->decl))
283             {
284               bool noninline = node->clone_of->decl != node->decl;
285               node = node->clone_of;
286               if (noninline && !node->reachable && !node->aux)
287                 {
288                   enqueue_cgraph_node (node, &first);
289                   break;
290                 }
291             }
292         }
293       if (first_varpool != (struct varpool_node *) (void *) 1)
294         {
295           vnode = first_varpool;
296           first_varpool = (struct varpool_node *)first_varpool->aux;
297           vnode->aux = NULL;
298           process_references (&vnode->ref_list, &first, &first_varpool, before_inlining_p);
299           /* If any function in a comdat group is reachable, force
300              all other functions in the same comdat group to be
301              also reachable.  */
302           if (vnode->same_comdat_group)
303             {
304               struct varpool_node *next;
305               for (next = vnode->same_comdat_group;
306                    next != vnode;
307                    next = next->same_comdat_group)
308                 if (!next->needed)
309                   {
310                     varpool_mark_needed_node (next);
311                     enqueue_varpool_node (next, &first_varpool);
312                   }
313             }
314         }
315     }
316
317   /* Remove unreachable nodes. 
318
319      Completely unreachable functions can be fully removed from the callgraph.
320      Extern inline functions that we decided to not inline need to become unanalyzed nodes of
321      callgraph (so we still have edges to them).  We remove function body then.
322
323      Also we need to care functions that are unreachable but we need to keep them around
324      for later clonning.  In this case we also turn them to unanalyzed nodes, but
325      keep the body around.  */
326   for (node = cgraph_nodes; node; node = next)
327     {
328       next = node->next;
329       if (node->aux && !node->reachable)
330         {
331           cgraph_node_remove_callees (node);
332           ipa_remove_all_references (&node->ref_list);
333           node->analyzed = false;
334         }
335       if (!node->aux)
336         {
337           struct cgraph_edge *e;
338           bool found = false;
339           int i;
340           struct ipa_ref *ref;
341
342           node->global.inlined_to = NULL;
343           if (file)
344             fprintf (file, " %s", cgraph_node_name (node));
345           /* See if there is reachable caller.  */
346           for (e = node->callers; e && !found; e = e->next_caller)
347             if (e->caller->reachable)
348               found = true;
349           for (i = 0; (ipa_ref_list_refering_iterate (&node->ref_list, i, ref)
350                        && !found); i++)
351             if (ref->refering_type == IPA_REF_CGRAPH
352                 && ipa_ref_refering_node (ref)->reachable)
353               found = true;
354             else if (ref->refering_type == IPA_REF_VARPOOL
355                      && ipa_ref_refering_varpool_node (ref)->needed)
356               found = true;
357
358           /* If so, we need to keep node in the callgraph.  */
359           if (found)
360             {
361               if (node->analyzed)
362                 {
363                   struct cgraph_node *clone;
364
365                   /* If there are still clones, we must keep body around.
366                      Otherwise we can just remove the body but keep the clone.  */
367                   for (clone = node->clones; clone;
368                        clone = clone->next_sibling_clone)
369                     if (clone->aux)
370                       break;
371                   if (!clone)
372                     {
373                       cgraph_release_function_body (node);
374                       if (node->prev_sibling_clone)
375                         node->prev_sibling_clone->next_sibling_clone = node->next_sibling_clone;
376                       else if (node->clone_of)
377                         node->clone_of->clones = node->next_sibling_clone;
378                       if (node->next_sibling_clone)
379                         node->next_sibling_clone->prev_sibling_clone = node->prev_sibling_clone;
380                       if (node->clone_of)
381                         node->former_clone_of = node->clone_of->decl;
382                       node->clone_of = NULL;
383                       node->next_sibling_clone = NULL;
384                       node->prev_sibling_clone = NULL;
385                     }
386                   else
387                     gcc_assert (!clone->in_other_partition);
388                   node->analyzed = false;
389                   changed = true;
390                   cgraph_node_remove_callees (node);
391                   ipa_remove_all_references (&node->ref_list);
392                 }
393             }
394           else
395             {
396               cgraph_remove_node (node);
397               changed = true;
398             }
399         }
400     }
401   for (node = cgraph_nodes; node; node = node->next)
402     {
403       /* Inline clones might be kept around so their materializing allows further
404          cloning.  If the function the clone is inlined into is removed, we need
405          to turn it into normal cone.  */
406       if (node->global.inlined_to
407           && !node->callers)
408         {
409           gcc_assert (node->clones);
410           node->global.inlined_to = NULL;
411           update_inlined_to_pointer (node, node);
412         }
413       node->aux = NULL;
414     }
415
416   if (file)
417     fprintf (file, "\n");
418
419   /* We must release unused extern inlines or sanity checking will fail.  Rest of transformations
420      are undesirable at -O0 since we do not want to remove anything.  */
421   if (!optimize)
422     return changed;
423
424   if (file)
425     fprintf (file, "Reclaiming variables:");
426   for (vnode = varpool_nodes; vnode; vnode = vnext)
427     {
428       vnext = vnode->next;
429       if (!vnode->needed)
430         {
431           if (file)
432             fprintf (file, " %s", varpool_node_name (vnode));
433           varpool_remove_node (vnode);
434           changed = true;
435         }
436     }
437
438   /* Now update address_taken flags and try to promote functions to be local.  */
439
440   if (file)
441     fprintf (file, "\nClearing address taken flags:");
442   for (node = cgraph_nodes; node; node = node->next)
443     if (node->address_taken
444         && !node->reachable_from_other_partition)
445       {
446         if (!cgraph_for_node_and_aliases (node, has_addr_references_p, NULL, true))
447           {
448             if (file)
449               fprintf (file, " %s", cgraph_node_name (node));
450             node->address_taken = false;
451             changed = true;
452             if (cgraph_local_node_p (node))
453               {
454                 node->local.local = true;
455                 if (file)
456                   fprintf (file, " (local)");
457               }
458           }
459       }
460   if (file)
461     fprintf (file, "\n");
462
463 #ifdef ENABLE_CHECKING
464   verify_cgraph ();
465 #endif
466
467   /* Reclaim alias pairs for functions that have disappeared from the
468      call graph.  */
469   remove_unreachable_alias_pairs ();
470
471   return changed;
472 }
473
474 /* Discover variables that have no longer address taken or that are read only
475    and update their flags.
476
477    FIXME: This can not be done in between gimplify and omp_expand since
478    readonly flag plays role on what is shared and what is not.  Currently we do
479    this transformation as part of whole program visibility and re-do at
480    ipa-reference pass (to take into account clonning), but it would
481    make sense to do it before early optimizations.  */
482
483 void
484 ipa_discover_readonly_nonaddressable_vars (void)
485 {
486   struct varpool_node *vnode;
487   if (dump_file)
488     fprintf (dump_file, "Clearing variable flags:");
489   for (vnode = varpool_nodes; vnode; vnode = vnode->next)
490     if (vnode->finalized && varpool_all_refs_explicit_p (vnode)
491         && (TREE_ADDRESSABLE (vnode->decl) || !TREE_READONLY (vnode->decl)))
492       {
493         bool written = false;
494         bool address_taken = false;
495         int i;
496         struct ipa_ref *ref;
497         for (i = 0; ipa_ref_list_refering_iterate (&vnode->ref_list, i, ref)
498                     && (!written || !address_taken); i++)
499           switch (ref->use)
500             {
501             case IPA_REF_ADDR:
502               address_taken = true;
503               break;
504             case IPA_REF_LOAD:
505               break;
506             case IPA_REF_STORE:
507               written = true;
508               break;
509             }
510         if (TREE_ADDRESSABLE (vnode->decl) && !address_taken)
511           {
512             if (dump_file)
513               fprintf (dump_file, " %s (addressable)", varpool_node_name (vnode));
514             TREE_ADDRESSABLE (vnode->decl) = 0;
515           }
516         if (!TREE_READONLY (vnode->decl) && !address_taken && !written
517             /* Making variable in explicit section readonly can cause section
518                type conflict. 
519                See e.g. gcc.c-torture/compile/pr23237.c */
520             && DECL_SECTION_NAME (vnode->decl) == NULL)
521           {
522             if (dump_file)
523               fprintf (dump_file, " %s (read-only)", varpool_node_name (vnode));
524             TREE_READONLY (vnode->decl) = 1;
525           }
526       }
527   if (dump_file)
528     fprintf (dump_file, "\n");
529 }
530
531 /* Return true when there is a reference to node and it is not vtable.  */
532 static bool
533 cgraph_address_taken_from_non_vtable_p (struct cgraph_node *node)
534 {
535   int i;
536   struct ipa_ref *ref;
537   for (i = 0; ipa_ref_list_reference_iterate (&node->ref_list, i, ref); i++)
538     {
539       struct varpool_node *node;
540       if (ref->refered_type == IPA_REF_CGRAPH)
541         return true;
542       node = ipa_ref_varpool_node (ref);
543       if (!DECL_VIRTUAL_P (node->decl))
544         return true;
545     }
546   return false;
547 }
548
549 /* COMDAT functions must be shared only if they have address taken,
550    otherwise we can produce our own private implementation with
551    -fwhole-program.  
552    Return true when turning COMDAT functoin static can not lead to wrong
553    code when the resulting object links with a library defining same COMDAT.
554
555    Virtual functions do have their addresses taken from the vtables,
556    but in C++ there is no way to compare their addresses for equality.  */
557
558 bool
559 cgraph_comdat_can_be_unshared_p (struct cgraph_node *node)
560 {
561   if ((cgraph_address_taken_from_non_vtable_p (node)
562        && !DECL_VIRTUAL_P (node->decl))
563       || !node->analyzed)
564     return false;
565   if (node->same_comdat_group)
566     {
567       struct cgraph_node *next;
568
569       /* If more than one function is in the same COMDAT group, it must
570          be shared even if just one function in the comdat group has
571          address taken.  */
572       for (next = node->same_comdat_group;
573            next != node; next = next->same_comdat_group)
574         if (cgraph_address_taken_from_non_vtable_p (next)
575             && !DECL_VIRTUAL_P (next->decl))
576           return false;
577     }
578   return true;
579 }
580
581 /* Return true when function NODE should be considered externally visible.  */
582
583 static bool
584 cgraph_externally_visible_p (struct cgraph_node *node,
585                              bool whole_program, bool aliased)
586 {
587   if (!node->local.finalized)
588     return false;
589   if (!DECL_COMDAT (node->decl)
590       && (!TREE_PUBLIC (node->decl) || DECL_EXTERNAL (node->decl)))
591     return false;
592
593   /* Do not even try to be smart about aliased nodes.  Until we properly
594      represent everything by same body alias, these are just evil.  */
595   if (aliased)
596     return true;
597
598   /* Do not try to localize built-in functions yet.  One of problems is that we
599      end up mangling their asm for WHOPR that makes it impossible to call them
600      using the implicit built-in declarations anymore.  Similarly this enables
601      us to remove them as unreachable before actual calls may appear during
602      expansion or folding.  */
603   if (DECL_BUILT_IN (node->decl))
604     return true;
605
606   /* FIXME: We get wrong symbols with asm aliases in callgraph and LTO.
607      This is because very little of code knows that assembler name needs to
608      mangled.  Avoid touching declarations with user asm name set to mask
609      some of the problems.  */
610   if (DECL_ASSEMBLER_NAME_SET_P (node->decl)
611       && IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->decl))[0]=='*')
612     return true;
613
614   /* If linker counts on us, we must preserve the function.  */
615   if (cgraph_used_from_object_file_p (node))
616     return true;
617   if (DECL_PRESERVE_P (node->decl))
618     return true;
619   if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (node->decl)))
620     return true;
621   if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
622       && lookup_attribute ("dllexport", DECL_ATTRIBUTES (node->decl)))
623     return true;
624   /* When doing LTO or whole program, we can bring COMDAT functoins static.
625      This improves code quality and we know we will duplicate them at most twice
626      (in the case that we are not using plugin and link with object file
627       implementing same COMDAT)  */
628   if ((in_lto_p || whole_program)
629       && DECL_COMDAT (node->decl)
630       && cgraph_comdat_can_be_unshared_p (node))
631     return false;
632
633   /* When doing link time optimizations, hidden symbols become local.  */
634   if (in_lto_p
635       && (DECL_VISIBILITY (node->decl) == VISIBILITY_HIDDEN
636           || DECL_VISIBILITY (node->decl) == VISIBILITY_INTERNAL)
637       /* Be sure that node is defined in IR file, not in other object
638          file.  In that case we don't set used_from_other_object_file.  */
639       && node->analyzed)
640     ;
641   else if (!whole_program)
642     return true;
643
644   if (MAIN_NAME_P (DECL_NAME (node->decl)))
645     return true;
646
647   return false;
648 }
649
650 /* Return true when variable VNODE should be considered externally visible.  */
651
652 static bool
653 varpool_externally_visible_p (struct varpool_node *vnode, bool aliased)
654 {
655   struct varpool_node *alias;
656   if (!DECL_COMDAT (vnode->decl) && !TREE_PUBLIC (vnode->decl))
657     return false;
658
659   /* Do not even try to be smart about aliased nodes.  Until we properly
660      represent everything by same body alias, these are just evil.  */
661   if (aliased)
662     return true;
663
664   /* If linker counts on us, we must preserve the function.  */
665   if (varpool_used_from_object_file_p (vnode))
666     return true;
667
668   /* FIXME: We get wrong symbols with asm aliases in callgraph and LTO.
669      This is because very little of code knows that assembler name needs to
670      mangled.  Avoid touching declarations with user asm name set to mask
671      some of the problems.  */
672   if (DECL_ASSEMBLER_NAME_SET_P (vnode->decl)
673       && IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (vnode->decl))[0]=='*')
674     return true;
675
676   if (DECL_PRESERVE_P (vnode->decl))
677     return true;
678   if (lookup_attribute ("externally_visible",
679                         DECL_ATTRIBUTES (vnode->decl)))
680     return true;
681   if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
682       && lookup_attribute ("dllexport",
683                            DECL_ATTRIBUTES (vnode->decl)))
684     return true;
685
686   /* See if we have linker information about symbol not being used or
687      if we need to make guess based on the declaration.
688
689      Even if the linker clams the symbol is unused, never bring internal
690      symbols that are declared by user as used or externally visible.
691      This is needed for i.e. references from asm statements.   */
692   if (varpool_used_from_object_file_p (vnode))
693     return true;
694   for (alias = vnode->extra_name; alias; alias = alias->next)
695     if (alias->resolution != LDPR_PREVAILING_DEF_IRONLY)
696       break;
697   if (!alias && vnode->resolution == LDPR_PREVAILING_DEF_IRONLY)
698     return false;
699
700   /* As a special case, the COMDAT virutal tables can be unshared.
701      In LTO mode turn vtables into static variables.  The variable is readonly,
702      so this does not enable more optimization, but referring static var
703      is faster for dynamic linking.  Also this match logic hidding vtables
704      from LTO symbol tables.  */
705   if ((in_lto_p || flag_whole_program)
706       && !vnode->force_output
707       && DECL_COMDAT (vnode->decl) && DECL_VIRTUAL_P (vnode->decl))
708     return false;
709
710   /* When doing link time optimizations, hidden symbols become local.  */
711   if (in_lto_p
712       && (DECL_VISIBILITY (vnode->decl) == VISIBILITY_HIDDEN
713           || DECL_VISIBILITY (vnode->decl) == VISIBILITY_INTERNAL)
714       /* Be sure that node is defined in IR file, not in other object
715          file.  In that case we don't set used_from_other_object_file.  */
716       && vnode->finalized)
717     ;
718   else if (!flag_whole_program)
719     return true;
720
721   /* Do not attempt to privatize COMDATS by default.
722      This would break linking with C++ libraries sharing
723      inline definitions.
724
725      FIXME: We can do so for readonly vars with no address taken and
726      possibly also for vtables since no direct pointer comparsion is done.
727      It might be interesting to do so to reduce linking overhead.  */
728   if (DECL_COMDAT (vnode->decl) || DECL_WEAK (vnode->decl))
729     return true;
730   return false;
731 }
732
733 /* Dissolve the same_comdat_group list in which NODE resides.  */
734
735 static void
736 dissolve_same_comdat_group_list (struct cgraph_node *node)
737 {
738   struct cgraph_node *n = node, *next;
739   do
740     {
741       next = n->same_comdat_group;
742       n->same_comdat_group = NULL;
743       n = next;
744     }
745   while (n != node);
746 }
747
748 /* Mark visibility of all functions.
749
750    A local function is one whose calls can occur only in the current
751    compilation unit and all its calls are explicit, so we can change
752    its calling convention.  We simply mark all static functions whose
753    address is not taken as local.
754
755    We also change the TREE_PUBLIC flag of all declarations that are public
756    in language point of view but we want to overwrite this default
757    via visibilities for the backend point of view.  */
758
759 static unsigned int
760 function_and_variable_visibility (bool whole_program)
761 {
762   struct cgraph_node *node;
763   struct varpool_node *vnode;
764   struct pointer_set_t *aliased_nodes = pointer_set_create ();
765   struct pointer_set_t *aliased_vnodes = pointer_set_create ();
766   unsigned i;
767   alias_pair *p;
768
769   /* Discover aliased nodes.  */
770   FOR_EACH_VEC_ELT (alias_pair, alias_pairs, i, p)
771     {
772       if (dump_file)
773        fprintf (dump_file, "Alias %s->%s",
774                 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (p->decl)),
775                 IDENTIFIER_POINTER (p->target));
776                 
777       if ((node = cgraph_node_for_asm (p->target)) != NULL
778           && !DECL_EXTERNAL (node->decl))
779         {
780           if (!node->analyzed)
781             continue;
782           /* Weakrefs alias symbols from other compilation unit.  In the case
783              the destination of weakref became available because of LTO, we must
784              mark it as needed.  */
785           if (in_lto_p
786               && lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl))
787               && !node->needed)
788             cgraph_mark_needed_node (node);
789           gcc_assert (node->needed);
790           pointer_set_insert (aliased_nodes, node);
791           if (dump_file)
792             fprintf (dump_file, "  node %s/%i",
793                      cgraph_node_name (node), node->uid);
794         }
795       else if ((vnode = varpool_node_for_asm (p->target)) != NULL
796                && !DECL_EXTERNAL (vnode->decl))
797         {
798           /* Weakrefs alias symbols from other compilation unit.  In the case
799              the destination of weakref became available because of LTO, we must
800              mark it as needed.  */
801           if (in_lto_p
802               && lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl))
803               && !vnode->needed)
804             varpool_mark_needed_node (vnode);
805           gcc_assert (vnode->needed);
806           pointer_set_insert (aliased_vnodes, vnode);
807           if (dump_file)
808             fprintf (dump_file, "  varpool node %s",
809                      varpool_node_name (vnode));
810         }
811       if (dump_file)
812        fprintf (dump_file, "\n");
813     }
814
815   for (node = cgraph_nodes; node; node = node->next)
816     {
817       int flags = flags_from_decl_or_type (node->decl);
818
819       /* Optimize away PURE and CONST constructors and destructors.  */
820       if (optimize
821           && (flags & (ECF_CONST | ECF_PURE))
822           && !(flags & ECF_LOOPING_CONST_OR_PURE))
823         {
824           DECL_STATIC_CONSTRUCTOR (node->decl) = 0;
825           DECL_STATIC_DESTRUCTOR (node->decl) = 0;
826         }
827
828       /* Frontends and alias code marks nodes as needed before parsing is finished.
829          We may end up marking as node external nodes where this flag is meaningless
830          strip it.  */
831       if (node->needed
832           && (DECL_EXTERNAL (node->decl) || !node->analyzed))
833         node->needed = 0;
834
835       /* C++ FE on lack of COMDAT support create local COMDAT functions
836          (that ought to be shared but can not due to object format
837          limitations).  It is neccesary to keep the flag to make rest of C++ FE
838          happy.  Clear the flag here to avoid confusion in middle-end.  */
839       if (DECL_COMDAT (node->decl) && !TREE_PUBLIC (node->decl))
840         DECL_COMDAT (node->decl) = 0;
841       /* For external decls stop tracking same_comdat_group, it doesn't matter
842          what comdat group they are in when they won't be emitted in this TU,
843          and simplifies later passes.  */
844       if (node->same_comdat_group && DECL_EXTERNAL (node->decl))
845         {
846 #ifdef ENABLE_CHECKING
847           struct cgraph_node *n;
848
849           for (n = node->same_comdat_group;
850                n != node;
851                n = n->same_comdat_group)
852               /* If at least one of same comdat group functions is external,
853                  all of them have to be, otherwise it is a front-end bug.  */
854               gcc_assert (DECL_EXTERNAL (n->decl));
855 #endif
856           dissolve_same_comdat_group_list (node);
857         }
858       gcc_assert ((!DECL_WEAK (node->decl) && !DECL_COMDAT (node->decl))
859                   || TREE_PUBLIC (node->decl) || DECL_EXTERNAL (node->decl));
860       if (cgraph_externally_visible_p (node, whole_program,
861                                        pointer_set_contains (aliased_nodes,
862                                                              node)))
863         {
864           gcc_assert (!node->global.inlined_to);
865           node->local.externally_visible = true;
866         }
867       else
868         node->local.externally_visible = false;
869       if (!node->local.externally_visible && node->analyzed
870           && !DECL_EXTERNAL (node->decl))
871         {
872           gcc_assert (whole_program || in_lto_p || !TREE_PUBLIC (node->decl));
873           cgraph_make_decl_local (node->decl);
874           node->resolution = LDPR_PREVAILING_DEF_IRONLY;
875           if (node->same_comdat_group)
876             /* cgraph_externally_visible_p has already checked all other nodes
877                in the group and they will all be made local.  We need to
878                dissolve the group at once so that the predicate does not
879                segfault though. */
880             dissolve_same_comdat_group_list (node);
881         }
882
883       if (node->thunk.thunk_p
884           && TREE_PUBLIC (node->decl))
885         {
886           struct cgraph_node *decl_node = node;
887
888           decl_node = cgraph_function_node (decl_node->callees->callee, NULL);
889
890           /* Thunks have the same visibility as function they are attached to.
891              For some reason C++ frontend don't seem to care. I.e. in 
892              g++.dg/torture/pr41257-2.C the thunk is not comdat while function
893              it is attached to is.
894
895              We also need to arrange the thunk into the same comdat group as
896              the function it reffers to.  */
897           if (DECL_COMDAT (decl_node->decl))
898             {
899               DECL_COMDAT (node->decl) = 1;
900               DECL_COMDAT_GROUP (node->decl) = DECL_COMDAT_GROUP (decl_node->decl);
901               if (DECL_ONE_ONLY (decl_node->decl) && !node->same_comdat_group)
902                 {
903                   node->same_comdat_group = decl_node;
904                   if (!decl_node->same_comdat_group)
905                     decl_node->same_comdat_group = node;
906                   else
907                     {
908                       struct cgraph_node *n;
909                       for (n = decl_node->same_comdat_group;
910                            n->same_comdat_group != decl_node;
911                            n = n->same_comdat_group)
912                         ;
913                       n->same_comdat_group = node;
914                     }
915                 }
916             }
917           if (DECL_EXTERNAL (decl_node->decl))
918             DECL_EXTERNAL (node->decl) = 1;
919         }
920     }
921   for (node = cgraph_nodes; node; node = node->next)
922     node->local.local = cgraph_local_node_p (node);
923   for (vnode = varpool_nodes; vnode; vnode = vnode->next)
924     {
925       /* weak flag makes no sense on local variables.  */
926       gcc_assert (!DECL_WEAK (vnode->decl)
927                   || TREE_PUBLIC (vnode->decl) || DECL_EXTERNAL (vnode->decl));
928       /* In several cases declarations can not be common:
929
930          - when declaration has initializer
931          - when it is in weak
932          - when it has specific section
933          - when it resides in non-generic address space.
934          - if declaration is local, it will get into .local common section
935            so common flag is not needed.  Frontends still produce these in
936            certain cases, such as for:
937
938              static int a __attribute__ ((common))
939
940          Canonicalize things here and clear the redundant flag.  */
941       if (DECL_COMMON (vnode->decl)
942           && (!(TREE_PUBLIC (vnode->decl) || DECL_EXTERNAL (vnode->decl))
943               || (DECL_INITIAL (vnode->decl)
944                   && DECL_INITIAL (vnode->decl) != error_mark_node)
945               || DECL_WEAK (vnode->decl)
946               || DECL_SECTION_NAME (vnode->decl) != NULL
947               || ! (ADDR_SPACE_GENERIC_P
948                     (TYPE_ADDR_SPACE (TREE_TYPE (vnode->decl))))))
949         DECL_COMMON (vnode->decl) = 0;
950     }
951   for (vnode = varpool_nodes_queue; vnode; vnode = vnode->next_needed)
952     {
953       if (!vnode->finalized)
954         continue;
955       if (vnode->needed
956           && varpool_externally_visible_p
957               (vnode, 
958                pointer_set_contains (aliased_vnodes, vnode)))
959         vnode->externally_visible = true;
960       else
961         vnode->externally_visible = false;
962       if (!vnode->externally_visible)
963         {
964           gcc_assert (in_lto_p || whole_program || !TREE_PUBLIC (vnode->decl));
965           cgraph_make_decl_local (vnode->decl);
966           vnode->resolution = LDPR_PREVAILING_DEF_IRONLY;
967         }
968      gcc_assert (TREE_STATIC (vnode->decl));
969     }
970   pointer_set_destroy (aliased_nodes);
971   pointer_set_destroy (aliased_vnodes);
972
973   if (dump_file)
974     {
975       fprintf (dump_file, "\nMarking local functions:");
976       for (node = cgraph_nodes; node; node = node->next)
977         if (node->local.local)
978           fprintf (dump_file, " %s", cgraph_node_name (node));
979       fprintf (dump_file, "\n\n");
980       fprintf (dump_file, "\nMarking externally visible functions:");
981       for (node = cgraph_nodes; node; node = node->next)
982         if (node->local.externally_visible)
983           fprintf (dump_file, " %s", cgraph_node_name (node));
984       fprintf (dump_file, "\n\n");
985       fprintf (dump_file, "\nMarking externally visible variables:");
986       for (vnode = varpool_nodes_queue; vnode; vnode = vnode->next_needed)
987         if (vnode->externally_visible)
988           fprintf (dump_file, " %s", varpool_node_name (vnode));
989       fprintf (dump_file, "\n\n");
990     }
991   cgraph_function_flags_ready = true;
992   return 0;
993 }
994
995 /* Local function pass handling visibilities.  This happens before LTO streaming
996    so in particular -fwhole-program should be ignored at this level.  */
997
998 static unsigned int
999 local_function_and_variable_visibility (void)
1000 {
1001   return function_and_variable_visibility (flag_whole_program && !flag_lto);
1002 }
1003
1004 struct simple_ipa_opt_pass pass_ipa_function_and_variable_visibility =
1005 {
1006  {
1007   SIMPLE_IPA_PASS,
1008   "visibility",                         /* name */
1009   NULL,                                 /* gate */
1010   local_function_and_variable_visibility,/* execute */
1011   NULL,                                 /* sub */
1012   NULL,                                 /* next */
1013   0,                                    /* static_pass_number */
1014   TV_CGRAPHOPT,                         /* tv_id */
1015   0,                                    /* properties_required */
1016   0,                                    /* properties_provided */
1017   0,                                    /* properties_destroyed */
1018   0,                                    /* todo_flags_start */
1019   TODO_remove_functions | TODO_dump_cgraph
1020   | TODO_ggc_collect                    /* todo_flags_finish */
1021  }
1022 };
1023
1024 /* Do not re-run on ltrans stage.  */
1025
1026 static bool
1027 gate_whole_program_function_and_variable_visibility (void)
1028 {
1029   return !flag_ltrans;
1030 }
1031
1032 /* Bring functionss local at LTO time whith -fwhole-program.  */
1033
1034 static unsigned int
1035 whole_program_function_and_variable_visibility (void)
1036 {
1037   struct cgraph_node *node;
1038   struct varpool_node *vnode;
1039
1040   function_and_variable_visibility (flag_whole_program);
1041
1042   for (node = cgraph_nodes; node; node = node->next)
1043     if ((node->local.externally_visible && !DECL_COMDAT (node->decl))
1044         && node->local.finalized)
1045       cgraph_mark_needed_node (node);
1046   for (vnode = varpool_nodes_queue; vnode; vnode = vnode->next_needed)
1047     if (vnode->externally_visible && !DECL_COMDAT (vnode->decl))
1048       varpool_mark_needed_node (vnode);
1049   if (dump_file)
1050     {
1051       fprintf (dump_file, "\nNeeded variables:");
1052       for (vnode = varpool_nodes_queue; vnode; vnode = vnode->next_needed)
1053         if (vnode->needed)
1054           fprintf (dump_file, " %s", varpool_node_name (vnode));
1055       fprintf (dump_file, "\n\n");
1056     }
1057   if (optimize)
1058     ipa_discover_readonly_nonaddressable_vars ();
1059   return 0;
1060 }
1061
1062 struct ipa_opt_pass_d pass_ipa_whole_program_visibility =
1063 {
1064  {
1065   IPA_PASS,
1066   "whole-program",                      /* name */
1067   gate_whole_program_function_and_variable_visibility,/* gate */
1068   whole_program_function_and_variable_visibility,/* execute */
1069   NULL,                                 /* sub */
1070   NULL,                                 /* next */
1071   0,                                    /* static_pass_number */
1072   TV_CGRAPHOPT,                         /* tv_id */
1073   0,                                    /* properties_required */
1074   0,                                    /* properties_provided */
1075   0,                                    /* properties_destroyed */
1076   0,                                    /* todo_flags_start */
1077   TODO_remove_functions | TODO_dump_cgraph
1078   | TODO_ggc_collect                    /* todo_flags_finish */
1079  },
1080  NULL,                                  /* generate_summary */
1081  NULL,                                  /* write_summary */
1082  NULL,                                  /* read_summary */
1083  NULL,                                  /* write_optimization_summary */
1084  NULL,                                  /* read_optimization_summary */
1085  NULL,                                  /* stmt_fixup */
1086  0,                                     /* TODOs */
1087  NULL,                                  /* function_transform */
1088  NULL,                                  /* variable_transform */
1089 };
1090
1091
1092 /* Simple ipa profile pass propagating frequencies across the callgraph.  */
1093
1094 static unsigned int
1095 ipa_profile (void)
1096 {
1097   struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
1098   struct cgraph_edge *e;
1099   int order_pos;
1100   bool something_changed = false;
1101   int i;
1102
1103   order_pos = ipa_reverse_postorder (order);
1104   for (i = order_pos - 1; i >= 0; i--)
1105     {
1106       if (order[i]->local.local && cgraph_propagate_frequency (order[i]))
1107         {
1108           for (e = order[i]->callees; e; e = e->next_callee)
1109             if (e->callee->local.local && !e->callee->aux)
1110               {
1111                 something_changed = true;
1112                 e->callee->aux = (void *)1;
1113               }
1114         }
1115       order[i]->aux = NULL;
1116     }
1117
1118   while (something_changed)
1119     {
1120       something_changed = false;
1121       for (i = order_pos - 1; i >= 0; i--)
1122         {
1123           if (order[i]->aux && cgraph_propagate_frequency (order[i]))
1124             {
1125               for (e = order[i]->callees; e; e = e->next_callee)
1126                 if (e->callee->local.local && !e->callee->aux)
1127                   {
1128                     something_changed = true;
1129                     e->callee->aux = (void *)1;
1130                   }
1131             }
1132           order[i]->aux = NULL;
1133         }
1134     }
1135   free (order);
1136   return 0;
1137 }
1138
1139 static bool
1140 gate_ipa_profile (void)
1141 {
1142   return flag_ipa_profile;
1143 }
1144
1145 struct ipa_opt_pass_d pass_ipa_profile =
1146 {
1147  {
1148   IPA_PASS,
1149   "profile_estimate",                   /* name */
1150   gate_ipa_profile,                     /* gate */
1151   ipa_profile,                          /* execute */
1152   NULL,                                 /* sub */
1153   NULL,                                 /* next */
1154   0,                                    /* static_pass_number */
1155   TV_IPA_PROFILE,                       /* tv_id */
1156   0,                                    /* properties_required */
1157   0,                                    /* properties_provided */
1158   0,                                    /* properties_destroyed */
1159   0,                                    /* todo_flags_start */
1160   0                                     /* todo_flags_finish */
1161  },
1162  NULL,                                  /* generate_summary */
1163  NULL,                                  /* write_summary */
1164  NULL,                                  /* read_summary */
1165  NULL,                                  /* write_optimization_summary */
1166  NULL,                                  /* read_optimization_summary */
1167  NULL,                                  /* stmt_fixup */
1168  0,                                     /* TODOs */
1169  NULL,                                  /* function_transform */
1170  NULL                                   /* variable_transform */
1171 };
1172
1173 /* Generate and emit a static constructor or destructor.  WHICH must
1174    be one of 'I' (for a constructor) or 'D' (for a destructor).  BODY
1175    is a STATEMENT_LIST containing GENERIC statements.  PRIORITY is the
1176    initialization priority for this constructor or destructor. 
1177
1178    FINAL specify whether the externally visible name for collect2 should
1179    be produced. */
1180
1181 static void
1182 cgraph_build_static_cdtor_1 (char which, tree body, int priority, bool final)
1183 {
1184   static int counter = 0;
1185   char which_buf[16];
1186   tree decl, name, resdecl;
1187
1188   /* The priority is encoded in the constructor or destructor name.
1189      collect2 will sort the names and arrange that they are called at
1190      program startup.  */
1191   if (final)
1192     sprintf (which_buf, "%c_%.5d_%d", which, priority, counter++);
1193   else
1194   /* Proudce sane name but one not recognizable by collect2, just for the
1195      case we fail to inline the function.  */
1196     sprintf (which_buf, "sub_%c_%.5d_%d", which, priority, counter++);
1197   name = get_file_function_name (which_buf);
1198
1199   decl = build_decl (input_location, FUNCTION_DECL, name,
1200                      build_function_type_list (void_type_node, NULL_TREE));
1201   current_function_decl = decl;
1202
1203   resdecl = build_decl (input_location,
1204                         RESULT_DECL, NULL_TREE, void_type_node);
1205   DECL_ARTIFICIAL (resdecl) = 1;
1206   DECL_RESULT (decl) = resdecl;
1207   DECL_CONTEXT (resdecl) = decl;
1208
1209   allocate_struct_function (decl, false);
1210
1211   TREE_STATIC (decl) = 1;
1212   TREE_USED (decl) = 1;
1213   DECL_ARTIFICIAL (decl) = 1;
1214   DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;
1215   DECL_SAVED_TREE (decl) = body;
1216   if (!targetm.have_ctors_dtors && final)
1217     {
1218       TREE_PUBLIC (decl) = 1;
1219       DECL_PRESERVE_P (decl) = 1;
1220     }
1221   DECL_UNINLINABLE (decl) = 1;
1222
1223   DECL_INITIAL (decl) = make_node (BLOCK);
1224   TREE_USED (DECL_INITIAL (decl)) = 1;
1225
1226   DECL_SOURCE_LOCATION (decl) = input_location;
1227   cfun->function_end_locus = input_location;
1228
1229   switch (which)
1230     {
1231     case 'I':
1232       DECL_STATIC_CONSTRUCTOR (decl) = 1;
1233       decl_init_priority_insert (decl, priority);
1234       break;
1235     case 'D':
1236       DECL_STATIC_DESTRUCTOR (decl) = 1;
1237       decl_fini_priority_insert (decl, priority);
1238       break;
1239     default:
1240       gcc_unreachable ();
1241     }
1242
1243   gimplify_function_tree (decl);
1244
1245   cgraph_add_new_function (decl, false);
1246
1247   set_cfun (NULL);
1248   current_function_decl = NULL;
1249 }
1250
1251 /* Generate and emit a static constructor or destructor.  WHICH must
1252    be one of 'I' (for a constructor) or 'D' (for a destructor).  BODY
1253    is a STATEMENT_LIST containing GENERIC statements.  PRIORITY is the
1254    initialization priority for this constructor or destructor.  */
1255
1256 void
1257 cgraph_build_static_cdtor (char which, tree body, int priority)
1258 {
1259   cgraph_build_static_cdtor_1 (which, body, priority, false);
1260 }
1261
1262 /* A vector of FUNCTION_DECLs declared as static constructors.  */
1263 static VEC(tree, heap) *static_ctors;
1264 /* A vector of FUNCTION_DECLs declared as static destructors.  */
1265 static VEC(tree, heap) *static_dtors;
1266
1267 /* When target does not have ctors and dtors, we call all constructor
1268    and destructor by special initialization/destruction function
1269    recognized by collect2.
1270
1271    When we are going to build this function, collect all constructors and
1272    destructors and turn them into normal functions.  */
1273
1274 static void
1275 record_cdtor_fn (struct cgraph_node *node)
1276 {
1277   if (DECL_STATIC_CONSTRUCTOR (node->decl))
1278     VEC_safe_push (tree, heap, static_ctors, node->decl);
1279   if (DECL_STATIC_DESTRUCTOR (node->decl))
1280     VEC_safe_push (tree, heap, static_dtors, node->decl);
1281   node = cgraph_get_node (node->decl);
1282   DECL_DISREGARD_INLINE_LIMITS (node->decl) = 1;
1283 }
1284
1285 /* Define global constructors/destructor functions for the CDTORS, of
1286    which they are LEN.  The CDTORS are sorted by initialization
1287    priority.  If CTOR_P is true, these are constructors; otherwise,
1288    they are destructors.  */
1289
1290 static void
1291 build_cdtor (bool ctor_p, VEC (tree, heap) *cdtors)
1292 {
1293   size_t i,j;
1294   size_t len = VEC_length (tree, cdtors);
1295
1296   i = 0;
1297   while (i < len)
1298     {
1299       tree body;
1300       tree fn;
1301       priority_type priority;
1302
1303       priority = 0;
1304       body = NULL_TREE;
1305       j = i;
1306       do
1307         {
1308           priority_type p;
1309           fn = VEC_index (tree, cdtors, j);
1310           p = ctor_p ? DECL_INIT_PRIORITY (fn) : DECL_FINI_PRIORITY (fn);
1311           if (j == i)
1312             priority = p;
1313           else if (p != priority)
1314             break;
1315           j++;
1316         }
1317       while (j < len);
1318
1319       /* When there is only one cdtor and target supports them, do nothing.  */
1320       if (j == i + 1
1321           && targetm.have_ctors_dtors)
1322         {
1323           i++;
1324           continue;
1325         }
1326       /* Find the next batch of constructors/destructors with the same
1327          initialization priority.  */
1328       for (;i < j; i++)
1329         {
1330           tree call;
1331           fn = VEC_index (tree, cdtors, i);
1332           call = build_call_expr (fn, 0);
1333           if (ctor_p)
1334             DECL_STATIC_CONSTRUCTOR (fn) = 0;
1335           else
1336             DECL_STATIC_DESTRUCTOR (fn) = 0;
1337           /* We do not want to optimize away pure/const calls here.
1338              When optimizing, these should be already removed, when not
1339              optimizing, we want user to be able to breakpoint in them.  */
1340           TREE_SIDE_EFFECTS (call) = 1;
1341           append_to_statement_list (call, &body);
1342         }
1343       gcc_assert (body != NULL_TREE);
1344       /* Generate a function to call all the function of like
1345          priority.  */
1346       cgraph_build_static_cdtor_1 (ctor_p ? 'I' : 'D', body, priority, true);
1347     }
1348 }
1349
1350 /* Comparison function for qsort.  P1 and P2 are actually of type
1351    "tree *" and point to static constructors.  DECL_INIT_PRIORITY is
1352    used to determine the sort order.  */
1353
1354 static int
1355 compare_ctor (const void *p1, const void *p2)
1356 {
1357   tree f1;
1358   tree f2;
1359   int priority1;
1360   int priority2;
1361
1362   f1 = *(const tree *)p1;
1363   f2 = *(const tree *)p2;
1364   priority1 = DECL_INIT_PRIORITY (f1);
1365   priority2 = DECL_INIT_PRIORITY (f2);
1366
1367   if (priority1 < priority2)
1368     return -1;
1369   else if (priority1 > priority2)
1370     return 1;
1371   else
1372     /* Ensure a stable sort.  Constructors are executed in backwarding
1373        order to make LTO initialize braries first.  */
1374     return DECL_UID (f2) - DECL_UID (f1);
1375 }
1376
1377 /* Comparison function for qsort.  P1 and P2 are actually of type
1378    "tree *" and point to static destructors.  DECL_FINI_PRIORITY is
1379    used to determine the sort order.  */
1380
1381 static int
1382 compare_dtor (const void *p1, const void *p2)
1383 {
1384   tree f1;
1385   tree f2;
1386   int priority1;
1387   int priority2;
1388
1389   f1 = *(const tree *)p1;
1390   f2 = *(const tree *)p2;
1391   priority1 = DECL_FINI_PRIORITY (f1);
1392   priority2 = DECL_FINI_PRIORITY (f2);
1393
1394   if (priority1 < priority2)
1395     return -1;
1396   else if (priority1 > priority2)
1397     return 1;
1398   else
1399     /* Ensure a stable sort.  */
1400     return DECL_UID (f1) - DECL_UID (f2);
1401 }
1402
1403 /* Generate functions to call static constructors and destructors
1404    for targets that do not support .ctors/.dtors sections.  These
1405    functions have magic names which are detected by collect2.  */
1406
1407 static void
1408 build_cdtor_fns (void)
1409 {
1410   if (!VEC_empty (tree, static_ctors))
1411     {
1412       gcc_assert (!targetm.have_ctors_dtors || in_lto_p);
1413       VEC_qsort (tree, static_ctors, compare_ctor);
1414       build_cdtor (/*ctor_p=*/true, static_ctors);
1415     }
1416
1417   if (!VEC_empty (tree, static_dtors))
1418     {
1419       gcc_assert (!targetm.have_ctors_dtors || in_lto_p);
1420       VEC_qsort (tree, static_dtors, compare_dtor);
1421       build_cdtor (/*ctor_p=*/false, static_dtors);
1422     }
1423 }
1424
1425 /* Look for constructors and destructors and produce function calling them.
1426    This is needed for targets not supporting ctors or dtors, but we perform the
1427    transformation also at linktime to merge possibly numberous
1428    constructors/destructors into single function to improve code locality and
1429    reduce size.  */
1430
1431 static unsigned int
1432 ipa_cdtor_merge (void)
1433 {
1434   struct cgraph_node *node;
1435   for (node = cgraph_nodes; node; node = node->next)
1436     if (node->analyzed
1437         && (DECL_STATIC_CONSTRUCTOR (node->decl)
1438             || DECL_STATIC_DESTRUCTOR (node->decl)))
1439        record_cdtor_fn (node);
1440   build_cdtor_fns ();
1441   VEC_free (tree, heap, static_ctors);
1442   VEC_free (tree, heap, static_dtors);
1443   return 0;
1444 }
1445
1446 /* Perform the pass when we have no ctors/dtors support
1447    or at LTO time to merge multiple constructors into single
1448    function.  */
1449
1450 static bool
1451 gate_ipa_cdtor_merge (void)
1452 {
1453   return !targetm.have_ctors_dtors || (optimize && in_lto_p);
1454 }
1455
1456 struct ipa_opt_pass_d pass_ipa_cdtor_merge =
1457 {
1458  {
1459   IPA_PASS,
1460   "cdtor",                              /* name */
1461   gate_ipa_cdtor_merge,                 /* gate */
1462   ipa_cdtor_merge,                      /* execute */
1463   NULL,                                 /* sub */
1464   NULL,                                 /* next */
1465   0,                                    /* static_pass_number */
1466   TV_CGRAPHOPT,                         /* tv_id */
1467   0,                                    /* properties_required */
1468   0,                                    /* properties_provided */
1469   0,                                    /* properties_destroyed */
1470   0,                                    /* todo_flags_start */
1471   0                                     /* todo_flags_finish */
1472  },
1473  NULL,                                  /* generate_summary */
1474  NULL,                                  /* write_summary */
1475  NULL,                                  /* read_summary */
1476  NULL,                                  /* write_optimization_summary */
1477  NULL,                                  /* read_optimization_summary */
1478  NULL,                                  /* stmt_fixup */
1479  0,                                     /* TODOs */
1480  NULL,                                  /* function_transform */
1481  NULL                                   /* variable_transform */
1482 };