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