OSDN Git Service

2012-10-08 Tobias Burnus <burnus@net-b.de>
[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 "gimple.h"
28 #include "ggc.h"
29 #include "flags.h"
30 #include "pointer-set.h"
31 #include "target.h"
32 #include "tree-iterator.h"
33 #include "ipa-utils.h"
34 #include "pointer-set.h"
35 #include "ipa-inline.h"
36
37 /* Look for all functions inlined to NODE and update their inlined_to pointers
38    to INLINED_TO.  */
39
40 static void
41 update_inlined_to_pointer (struct cgraph_node *node, struct cgraph_node *inlined_to)
42 {
43   struct cgraph_edge *e;
44   for (e = node->callees; e; e = e->next_callee)
45     if (e->callee->global.inlined_to)
46       {
47         e->callee->global.inlined_to = inlined_to;
48         update_inlined_to_pointer (e->callee, inlined_to);
49       }
50 }
51
52 /* Add symtab NODE to queue starting at FIRST.
53
54    The queue is linked via AUX pointers and terminated by pointer to 1.
55    We enqueue nodes at two occasions: when we find them reachable or when we find
56    their bodies needed for further clonning.  In the second case we mark them
57    by pointer to 2 after processing so they are re-queue when they become
58    reachable.  */
59
60 static void
61 enqueue_node (symtab_node node, symtab_node *first,
62               struct pointer_set_t *reachable)
63 {
64   /* Node is still in queue; do nothing.  */
65   if (node->symbol.aux && node->symbol.aux != (void *) 2)
66     return;
67   /* Node was already processed as unreachable, re-enqueue
68      only if it became reachable now.  */
69   if (node->symbol.aux == (void *)2 && !pointer_set_contains (reachable, node))
70     return;
71   node->symbol.aux = *first;
72   *first = node;
73 }
74
75 /* Process references.  */
76
77 static void
78 process_references (struct ipa_ref_list *list,
79                     symtab_node *first,
80                     bool before_inlining_p,
81                     struct pointer_set_t *reachable)
82 {
83   int i;
84   struct ipa_ref *ref;
85   for (i = 0; ipa_ref_list_reference_iterate (list, i, ref); i++)
86     {
87       if (symtab_function_p (ref->referred))
88         {
89           struct cgraph_node *node = ipa_ref_node (ref);
90
91           if (node->analyzed
92               && (!DECL_EXTERNAL (node->symbol.decl)
93                   || node->alias
94                   || before_inlining_p))
95             pointer_set_insert (reachable, node);
96           enqueue_node ((symtab_node) node, first, reachable);
97         }
98       else
99         {
100           struct varpool_node *node = ipa_ref_varpool_node (ref);
101
102           if (node->analyzed
103               && (!DECL_EXTERNAL (node->symbol.decl)
104                   || node->alias
105                   || before_inlining_p))
106             pointer_set_insert (reachable, node);
107           enqueue_node ((symtab_node) node, first, reachable);
108         }
109     }
110 }
111
112
113 /* Return true when NODE can not be local. Worker for cgraph_local_node_p.  */
114
115 static bool
116 cgraph_non_local_node_p_1 (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
117 {
118    /* FIXME: Aliases can be local, but i386 gets thunks wrong then.  */
119    return !(cgraph_only_called_directly_or_aliased_p (node)
120             && !ipa_ref_has_aliases_p (&node->symbol.ref_list)
121             && node->analyzed
122             && !DECL_EXTERNAL (node->symbol.decl)
123             && !node->symbol.externally_visible
124             && !node->symbol.used_from_other_partition
125             && !node->symbol.in_other_partition);
126 }
127
128 /* Return true when function can be marked local.  */
129
130 static bool
131 cgraph_local_node_p (struct cgraph_node *node)
132 {
133    struct cgraph_node *n = cgraph_function_or_thunk_node (node, NULL);
134
135    /* FIXME: thunks can be considered local, but we need prevent i386
136       from attempting to change calling convention of them.  */
137    if (n->thunk.thunk_p)
138      return false;
139    return !cgraph_for_node_and_aliases (n,
140                                         cgraph_non_local_node_p_1, NULL, true);
141                                         
142 }
143
144 /* Return true when NODE has ADDR reference.  */
145
146 static bool
147 has_addr_references_p (struct cgraph_node *node,
148                        void *data ATTRIBUTE_UNUSED)
149 {
150   int i;
151   struct ipa_ref *ref;
152
153   for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list,
154                                              i, ref); i++)
155     if (ref->use == IPA_REF_ADDR)
156       return true;
157   return false;
158 }
159
160 /* Perform reachability analysis and reclaim all unreachable nodes.
161
162    The algorithm is basically mark&sweep but with some extra refinements:
163
164    - reachable extern inline functions needs special handling; the bodies needs
165      to stay in memory until inlining in hope that they will be inlined.
166      After inlining we release their bodies and turn them into unanalyzed
167      nodes even when they are reachable.
168
169      BEFORE_INLINING_P specify whether we are before or after inlining.
170
171    - virtual functions are kept in callgraph even if they seem unreachable in
172      hope calls to them will be devirtualized. 
173
174      Again we remove them after inlining.  In late optimization some
175      devirtualization may happen, but it is not importnat since we won't inline
176      the call. In theory early opts and IPA should work out all important cases.
177
178    - virtual clones needs bodies of their origins for later materialization;
179      this means that we want to keep the body even if the origin is unreachable
180      otherwise.  To avoid origin from sitting in the callgraph and being
181      walked by IPA passes, we turn them into unanalyzed nodes with body
182      defined.
183
184      We maintain set of function declaration where body needs to stay in
185      body_needed_for_clonning
186
187      Inline clones represent special case: their declaration match the
188      declaration of origin and cgraph_remove_node already knows how to
189      reshape callgraph and preserve body when offline copy of function or
190      inline clone is being removed.
191
192    - C++ virtual tables keyed to other unit are represented as DECL_EXTERNAL
193      variables with DECL_INITIAL set.  We finalize these and keep reachable
194      ones around for constant folding purposes.  After inlining we however
195      stop walking their references to let everything static referneced by them
196      to be removed when it is otherwise unreachable.
197
198    We maintain queue of both reachable symbols (i.e. defined symbols that needs
199    to stay) and symbols that are in boundary (i.e. external symbols referenced
200    by reachable symbols or origins of clones).  The queue is represented
201    as linked list by AUX pointer terminated by 1.
202
203    A the end we keep all reachable symbols. For symbols in boundary we always
204    turn definition into a declaration, but we may keep function body around
205    based on body_needed_for_clonning
206
207    All symbols that enter the queue have AUX pointer non-zero and are in the
208    boundary.  Pointer set REACHABLE is used to track reachable symbols.
209
210    Every symbol can be visited twice - once as part of boundary and once
211    as real reachable symbol. enqueue_node needs to decide whether the
212    node needs to be re-queued for second processing.  For this purpose
213    we set AUX pointer of processed symbols in the boundary to constant 2.  */
214
215 bool
216 symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
217 {
218   symtab_node first = (symtab_node) (void *) 1;
219   struct cgraph_node *node, *next;
220   struct varpool_node *vnode, *vnext;
221   bool changed = false;
222   struct pointer_set_t *reachable = pointer_set_create ();
223   struct pointer_set_t *body_needed_for_clonning = pointer_set_create ();
224
225 #ifdef ENABLE_CHECKING
226   verify_symtab ();
227 #endif
228   if (file)
229     fprintf (file, "\nReclaiming functions:");
230 #ifdef ENABLE_CHECKING
231   FOR_EACH_FUNCTION (node)
232     gcc_assert (!node->symbol.aux);
233   FOR_EACH_VARIABLE (vnode)
234     gcc_assert (!vnode->symbol.aux);
235 #endif
236   /* Mark functions whose bodies are obviously needed.
237      This is mostly when they can be referenced externally.  Inline clones
238      are special since their declarations are shared with master clone and thus
239      cgraph_can_remove_if_no_direct_calls_and_refs_p should not be called on them.  */
240   FOR_EACH_DEFINED_FUNCTION (node)
241     if (!node->global.inlined_to
242         && (!cgraph_can_remove_if_no_direct_calls_and_refs_p (node)
243             /* Keep around virtual functions for possible devirtualization.  */
244             || (before_inlining_p
245                 && DECL_VIRTUAL_P (node->symbol.decl)
246                 && (DECL_COMDAT (node->symbol.decl) || DECL_EXTERNAL (node->symbol.decl)))))
247       {
248         gcc_assert (!node->global.inlined_to);
249         pointer_set_insert (reachable, node);
250         enqueue_node ((symtab_node)node, &first, reachable);
251       }
252     else
253       gcc_assert (!node->symbol.aux);
254
255   /* Mark variables that are obviously needed.  */
256   FOR_EACH_DEFINED_VARIABLE (vnode)
257     if (!varpool_can_remove_if_no_refs (vnode))
258       {
259         pointer_set_insert (reachable, vnode);
260         enqueue_node ((symtab_node)vnode, &first, reachable);
261       }
262
263   /* Perform reachability analysis.  */
264   while (first != (symtab_node) (void *) 1)
265     {
266       bool in_boundary_p = !pointer_set_contains (reachable, first);
267       symtab_node node = first;
268
269       first = (symtab_node)first->symbol.aux;
270
271       /* If we are processing symbol in boundary, mark its AUX pointer for
272          possible later re-processing in enqueue_node.  */
273       if (in_boundary_p)
274         node->symbol.aux = (void *)2;
275       else
276         {
277           /* If any symbol in a comdat group is reachable, force
278              all other in the same comdat group to be also reachable.  */
279           if (node->symbol.same_comdat_group)
280             {
281               symtab_node next;
282               for (next = node->symbol.same_comdat_group;
283                    next != node;
284                    next = next->symbol.same_comdat_group)
285                 if (!pointer_set_insert (reachable, next))
286                   enqueue_node ((symtab_node) next, &first, reachable);
287             }
288           /* Mark references as reachable.  */
289           process_references (&node->symbol.ref_list, &first,
290                               before_inlining_p, reachable);
291         }
292
293       if (symtab_function_p (node))
294         {
295           struct cgraph_node *cnode = cgraph (node);
296
297           /* Mark the callees reachable unless they are direct calls to extern
298              inline functions we decided to not inline.  */
299           if (!in_boundary_p)
300             {
301               struct cgraph_edge *e;
302               for (e = cnode->callees; e; e = e->next_callee)
303                 {
304                   if (e->callee->analyzed
305                       && (!e->inline_failed
306                           || !DECL_EXTERNAL (e->callee->symbol.decl)
307                           || cnode->alias
308                           || before_inlining_p))
309                     pointer_set_insert (reachable, e->callee);
310                   enqueue_node ((symtab_node) e->callee, &first, reachable);
311                 }
312
313               /* When inline clone exists, mark body to be preserved so when removing
314                  offline copy of the function we don't kill it.  */
315               if (!cnode->alias && cnode->global.inlined_to)
316                 pointer_set_insert (body_needed_for_clonning, cnode->symbol.decl);
317             }
318
319           /* For non-inline clones, force their origins to the boundary and ensure
320              that body is not removed.  */
321           while (cnode->clone_of
322                  && !gimple_has_body_p (cnode->symbol.decl))
323             {
324               bool noninline = cnode->clone_of->symbol.decl != cnode->symbol.decl;
325               cnode = cnode->clone_of;
326               if (noninline)
327                 {
328                   pointer_set_insert (body_needed_for_clonning, cnode->symbol.decl);
329                   enqueue_node ((symtab_node)cnode, &first, reachable);
330                   break;
331                 }
332             }
333         }
334       /* When we see constructor of external variable, keep referred nodes in the
335          boundary.  This will also hold initializers of the external vars NODE
336          reffers to.  */
337       if (symtab_variable_p (node)
338           && DECL_EXTERNAL (node->symbol.decl)
339           && !varpool (node)->alias
340           && in_boundary_p)
341         {
342           int i;
343           struct ipa_ref *ref;
344           for (i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list, i, ref); i++)
345             enqueue_node (ref->referred, &first, reachable);
346         }
347     }
348
349   /* Remove unreachable functions.   */
350   for (node = cgraph_first_function (); node; node = next)
351     {
352       next = cgraph_next_function (node);
353       if (!node->symbol.aux)
354         {
355           if (file)
356             fprintf (file, " %s", cgraph_node_name (node));
357           cgraph_remove_node (node);
358           changed = true;
359         }
360       else if (!pointer_set_contains (reachable, node))
361         {
362           if (node->analyzed)
363             {
364               if (file)
365                 fprintf (file, " %s", cgraph_node_name (node));
366               cgraph_node_remove_callees (node);
367               ipa_remove_all_references (&node->symbol.ref_list);
368               changed = true;
369             }
370           if (!pointer_set_contains (body_needed_for_clonning, node->symbol.decl)
371               && (node->local.finalized || !DECL_ARTIFICIAL (node->symbol.decl)))
372             cgraph_release_function_body (node);
373           node->analyzed = false;
374         }
375     }
376
377   /* Inline clones might be kept around so their materializing allows further
378      cloning.  If the function the clone is inlined into is removed, we need
379      to turn it into normal cone.  */
380   FOR_EACH_FUNCTION (node)
381     {
382       if (node->global.inlined_to
383           && !node->callers)
384         {
385           gcc_assert (node->clones);
386           node->global.inlined_to = NULL;
387           update_inlined_to_pointer (node, node);
388         }
389       node->symbol.aux = NULL;
390     }
391
392   /* Remove unreachable variables.  */
393   if (file)
394     fprintf (file, "\nReclaiming variables:");
395   for (vnode = varpool_first_variable (); vnode; vnode = vnext)
396     {
397       vnext = varpool_next_variable (vnode);
398       if (!vnode->symbol.aux)
399         {
400           if (file)
401             fprintf (file, " %s", varpool_node_name (vnode));
402           varpool_remove_node (vnode);
403           changed = true;
404         }
405       else if (!pointer_set_contains (reachable, vnode))
406         {
407           if (vnode->analyzed)
408             {
409               if (file)
410                 fprintf (file, " %s", varpool_node_name (vnode));
411               changed = true;
412             }
413           vnode->analyzed = false;
414           vnode->symbol.aux = NULL;
415         }
416       else
417         vnode->symbol.aux = NULL;
418     }
419
420   pointer_set_destroy (reachable);
421   pointer_set_destroy (body_needed_for_clonning);
422
423   /* Now update address_taken flags and try to promote functions to be local.  */
424   if (file)
425     fprintf (file, "\nClearing address taken flags:");
426   FOR_EACH_DEFINED_FUNCTION (node)
427     if (node->symbol.address_taken
428         && !node->symbol.used_from_other_partition)
429       {
430         if (!cgraph_for_node_and_aliases (node, has_addr_references_p, NULL, true))
431           {
432             if (file)
433               fprintf (file, " %s", cgraph_node_name (node));
434             node->symbol.address_taken = false;
435             changed = true;
436             if (cgraph_local_node_p (node))
437               {
438                 node->local.local = true;
439                 if (file)
440                   fprintf (file, " (local)");
441               }
442           }
443       }
444   if (file)
445     fprintf (file, "\n");
446
447 #ifdef ENABLE_CHECKING
448   verify_symtab ();
449 #endif
450
451   /* If we removed something, perhaps profile could be improved.  */
452   if (changed && optimize && inline_edge_summary_vec)
453     FOR_EACH_DEFINED_FUNCTION (node)
454       cgraph_propagate_frequency (node);
455
456   return changed;
457 }
458
459 /* Discover variables that have no longer address taken or that are read only
460    and update their flags.
461
462    FIXME: This can not be done in between gimplify and omp_expand since
463    readonly flag plays role on what is shared and what is not.  Currently we do
464    this transformation as part of whole program visibility and re-do at
465    ipa-reference pass (to take into account clonning), but it would
466    make sense to do it before early optimizations.  */
467
468 void
469 ipa_discover_readonly_nonaddressable_vars (void)
470 {
471   struct varpool_node *vnode;
472   if (dump_file)
473     fprintf (dump_file, "Clearing variable flags:");
474   FOR_EACH_VARIABLE (vnode)
475     if (vnode->finalized && varpool_all_refs_explicit_p (vnode)
476         && (TREE_ADDRESSABLE (vnode->symbol.decl)
477             || !TREE_READONLY (vnode->symbol.decl)))
478       {
479         bool written = false;
480         bool address_taken = false;
481         int i;
482         struct ipa_ref *ref;
483         for (i = 0; ipa_ref_list_referring_iterate (&vnode->symbol.ref_list,
484                                                    i, ref)
485                     && (!written || !address_taken); i++)
486           switch (ref->use)
487             {
488             case IPA_REF_ADDR:
489               address_taken = true;
490               break;
491             case IPA_REF_LOAD:
492               break;
493             case IPA_REF_STORE:
494               written = true;
495               break;
496             }
497         if (TREE_ADDRESSABLE (vnode->symbol.decl) && !address_taken)
498           {
499             if (dump_file)
500               fprintf (dump_file, " %s (addressable)", varpool_node_name (vnode));
501             TREE_ADDRESSABLE (vnode->symbol.decl) = 0;
502           }
503         if (!TREE_READONLY (vnode->symbol.decl) && !address_taken && !written
504             /* Making variable in explicit section readonly can cause section
505                type conflict. 
506                See e.g. gcc.c-torture/compile/pr23237.c */
507             && DECL_SECTION_NAME (vnode->symbol.decl) == NULL)
508           {
509             if (dump_file)
510               fprintf (dump_file, " %s (read-only)", varpool_node_name (vnode));
511             TREE_READONLY (vnode->symbol.decl) = 1;
512           }
513       }
514   if (dump_file)
515     fprintf (dump_file, "\n");
516 }
517
518 /* Return true when there is a reference to node and it is not vtable.  */
519 static bool
520 cgraph_address_taken_from_non_vtable_p (struct cgraph_node *node)
521 {
522   int i;
523   struct ipa_ref *ref;
524   for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list,
525                                              i, ref); i++)
526     if (ref->use == IPA_REF_ADDR)
527       {
528         struct varpool_node *node;
529         if (symtab_function_p (ref->referring))
530           return true;
531         node = ipa_ref_referring_varpool_node (ref);
532         if (!DECL_VIRTUAL_P (node->symbol.decl))
533           return true;
534       }
535   return false;
536 }
537
538 /* COMDAT functions must be shared only if they have address taken,
539    otherwise we can produce our own private implementation with
540    -fwhole-program.  
541    Return true when turning COMDAT functoin static can not lead to wrong
542    code when the resulting object links with a library defining same COMDAT.
543
544    Virtual functions do have their addresses taken from the vtables,
545    but in C++ there is no way to compare their addresses for equality.  */
546
547 bool
548 cgraph_comdat_can_be_unshared_p (struct cgraph_node *node)
549 {
550   if ((cgraph_address_taken_from_non_vtable_p (node)
551        && !DECL_VIRTUAL_P (node->symbol.decl))
552       || !node->analyzed)
553     return false;
554   if (node->symbol.same_comdat_group)
555     {
556       struct cgraph_node *next;
557
558       /* If more than one function is in the same COMDAT group, it must
559          be shared even if just one function in the comdat group has
560          address taken.  */
561       for (next = cgraph (node->symbol.same_comdat_group);
562            next != node; next = cgraph (next->symbol.same_comdat_group))
563         if (cgraph_address_taken_from_non_vtable_p (next)
564             && !DECL_VIRTUAL_P (next->symbol.decl))
565           return false;
566     }
567   return true;
568 }
569
570 /* Return true when function NODE should be considered externally visible.  */
571
572 static bool
573 cgraph_externally_visible_p (struct cgraph_node *node,
574                              bool whole_program, bool aliased)
575 {
576   if (!node->local.finalized)
577     return false;
578   if (!DECL_COMDAT (node->symbol.decl)
579       && (!TREE_PUBLIC (node->symbol.decl)
580           || DECL_EXTERNAL (node->symbol.decl)))
581     return false;
582
583   /* Do not even try to be smart about aliased nodes.  Until we properly
584      represent everything by same body alias, these are just evil.  */
585   if (aliased)
586     return true;
587
588   /* Do not try to localize built-in functions yet.  One of problems is that we
589      end up mangling their asm for WHOPR that makes it impossible to call them
590      using the implicit built-in declarations anymore.  Similarly this enables
591      us to remove them as unreachable before actual calls may appear during
592      expansion or folding.  */
593   if (DECL_BUILT_IN (node->symbol.decl))
594     return true;
595
596   /* If linker counts on us, we must preserve the function.  */
597   if (symtab_used_from_object_file_p ((symtab_node) node))
598     return true;
599   if (DECL_PRESERVE_P (node->symbol.decl))
600     return true;
601   if (lookup_attribute ("externally_visible",
602                         DECL_ATTRIBUTES (node->symbol.decl)))
603     return true;
604   if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
605       && lookup_attribute ("dllexport",
606                            DECL_ATTRIBUTES (node->symbol.decl)))
607     return true;
608   if (node->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY)
609     return false;
610   /* When doing LTO or whole program, we can bring COMDAT functoins static.
611      This improves code quality and we know we will duplicate them at most twice
612      (in the case that we are not using plugin and link with object file
613       implementing same COMDAT)  */
614   if ((in_lto_p || whole_program)
615       && DECL_COMDAT (node->symbol.decl)
616       && cgraph_comdat_can_be_unshared_p (node))
617     return false;
618
619   /* When doing link time optimizations, hidden symbols become local.  */
620   if (in_lto_p
621       && (DECL_VISIBILITY (node->symbol.decl) == VISIBILITY_HIDDEN
622           || DECL_VISIBILITY (node->symbol.decl) == VISIBILITY_INTERNAL)
623       /* Be sure that node is defined in IR file, not in other object
624          file.  In that case we don't set used_from_other_object_file.  */
625       && node->analyzed)
626     ;
627   else if (!whole_program)
628     return true;
629
630   if (MAIN_NAME_P (DECL_NAME (node->symbol.decl)))
631     return true;
632
633   return false;
634 }
635
636 /* Return true when variable VNODE should be considered externally visible.  */
637
638 bool
639 varpool_externally_visible_p (struct varpool_node *vnode, bool aliased)
640 {
641   /* Do not touch weakrefs; while they are not externally visible,
642      dropping their DECL_EXTERNAL flags confuse most
643      of code handling them.  */
644   if (vnode->alias && DECL_EXTERNAL (vnode->symbol.decl))
645     return true;
646
647   if (DECL_EXTERNAL (vnode->symbol.decl))
648     return true;
649
650   if (!DECL_COMDAT (vnode->symbol.decl) && !TREE_PUBLIC (vnode->symbol.decl))
651     return false;
652
653   /* Do not even try to be smart about aliased nodes.  Until we properly
654      represent everything by same body alias, these are just evil.  */
655   if (aliased)
656     return true;
657
658   /* If linker counts on us, we must preserve the function.  */
659   if (symtab_used_from_object_file_p ((symtab_node) vnode))
660     return true;
661
662   if (DECL_HARD_REGISTER (vnode->symbol.decl))
663     return true;
664   if (DECL_PRESERVE_P (vnode->symbol.decl))
665     return true;
666   if (lookup_attribute ("externally_visible",
667                         DECL_ATTRIBUTES (vnode->symbol.decl)))
668     return true;
669   if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
670       && lookup_attribute ("dllexport",
671                            DECL_ATTRIBUTES (vnode->symbol.decl)))
672     return true;
673
674   /* See if we have linker information about symbol not being used or
675      if we need to make guess based on the declaration.
676
677      Even if the linker clams the symbol is unused, never bring internal
678      symbols that are declared by user as used or externally visible.
679      This is needed for i.e. references from asm statements.   */
680   if (symtab_used_from_object_file_p ((symtab_node) vnode))
681     return true;
682   if (vnode->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY)
683     return false;
684
685   /* As a special case, the COMDAT virtual tables can be unshared.
686      In LTO mode turn vtables into static variables.  The variable is readonly,
687      so this does not enable more optimization, but referring static var
688      is faster for dynamic linking.  Also this match logic hidding vtables
689      from LTO symbol tables.  */
690   if ((in_lto_p || flag_whole_program)
691       && !vnode->symbol.force_output
692       && DECL_COMDAT (vnode->symbol.decl) && DECL_VIRTUAL_P (vnode->symbol.decl))
693     return false;
694
695   /* When doing link time optimizations, hidden symbols become local.  */
696   if (in_lto_p
697       && (DECL_VISIBILITY (vnode->symbol.decl) == VISIBILITY_HIDDEN
698           || DECL_VISIBILITY (vnode->symbol.decl) == VISIBILITY_INTERNAL)
699       /* Be sure that node is defined in IR file, not in other object
700          file.  In that case we don't set used_from_other_object_file.  */
701       && vnode->finalized)
702     ;
703   else if (!flag_whole_program)
704     return true;
705
706   /* Do not attempt to privatize COMDATS by default.
707      This would break linking with C++ libraries sharing
708      inline definitions.
709
710      FIXME: We can do so for readonly vars with no address taken and
711      possibly also for vtables since no direct pointer comparsion is done.
712      It might be interesting to do so to reduce linking overhead.  */
713   if (DECL_COMDAT (vnode->symbol.decl) || DECL_WEAK (vnode->symbol.decl))
714     return true;
715   return false;
716 }
717
718 /* Mark visibility of all functions.
719
720    A local function is one whose calls can occur only in the current
721    compilation unit and all its calls are explicit, so we can change
722    its calling convention.  We simply mark all static functions whose
723    address is not taken as local.
724
725    We also change the TREE_PUBLIC flag of all declarations that are public
726    in language point of view but we want to overwrite this default
727    via visibilities for the backend point of view.  */
728
729 static unsigned int
730 function_and_variable_visibility (bool whole_program)
731 {
732   struct cgraph_node *node;
733   struct varpool_node *vnode;
734   struct pointer_set_t *aliased_nodes = pointer_set_create ();
735   struct pointer_set_t *aliased_vnodes = pointer_set_create ();
736   unsigned i;
737   alias_pair *p;
738
739   /* Discover aliased nodes.  */
740   FOR_EACH_VEC_ELT (alias_pair, alias_pairs, i, p)
741     {
742       if (dump_file)
743        fprintf (dump_file, "Alias %s->%s",
744                 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (p->decl)),
745                 IDENTIFIER_POINTER (p->target));
746                 
747       if ((node = cgraph_node_for_asm (p->target)) != NULL
748           && !DECL_EXTERNAL (node->symbol.decl))
749         {
750           if (!node->analyzed)
751             continue;
752           cgraph_mark_force_output_node (node);
753           pointer_set_insert (aliased_nodes, node);
754           if (dump_file)
755             fprintf (dump_file, "  node %s/%i",
756                      cgraph_node_name (node), node->uid);
757         }
758       else if ((vnode = varpool_node_for_asm (p->target)) != NULL
759                && !DECL_EXTERNAL (vnode->symbol.decl))
760         {
761           vnode->symbol.force_output = 1;
762           pointer_set_insert (aliased_vnodes, vnode);
763           if (dump_file)
764             fprintf (dump_file, "  varpool node %s",
765                      varpool_node_name (vnode));
766         }
767       if (dump_file)
768        fprintf (dump_file, "\n");
769     }
770
771   FOR_EACH_FUNCTION (node)
772     {
773       int flags = flags_from_decl_or_type (node->symbol.decl);
774
775       /* Optimize away PURE and CONST constructors and destructors.  */
776       if (optimize
777           && (flags & (ECF_CONST | ECF_PURE))
778           && !(flags & ECF_LOOPING_CONST_OR_PURE))
779         {
780           DECL_STATIC_CONSTRUCTOR (node->symbol.decl) = 0;
781           DECL_STATIC_DESTRUCTOR (node->symbol.decl) = 0;
782         }
783
784       /* Frontends and alias code marks nodes as needed before parsing is finished.
785          We may end up marking as node external nodes where this flag is meaningless
786          strip it.  */
787       if (node->symbol.force_output
788           && (DECL_EXTERNAL (node->symbol.decl) || !node->analyzed))
789         node->symbol.force_output = 0;
790
791       /* C++ FE on lack of COMDAT support create local COMDAT functions
792          (that ought to be shared but can not due to object format
793          limitations).  It is necessary to keep the flag to make rest of C++ FE
794          happy.  Clear the flag here to avoid confusion in middle-end.  */
795       if (DECL_COMDAT (node->symbol.decl) && !TREE_PUBLIC (node->symbol.decl))
796         DECL_COMDAT (node->symbol.decl) = 0;
797       /* For external decls stop tracking same_comdat_group, it doesn't matter
798          what comdat group they are in when they won't be emitted in this TU,
799          and simplifies later passes.  */
800       if (node->symbol.same_comdat_group && DECL_EXTERNAL (node->symbol.decl))
801         {
802 #ifdef ENABLE_CHECKING
803           symtab_node n;
804
805           for (n = node->symbol.same_comdat_group;
806                n != (symtab_node)node;
807                n = n->symbol.same_comdat_group)
808               /* If at least one of same comdat group functions is external,
809                  all of them have to be, otherwise it is a front-end bug.  */
810               gcc_assert (DECL_EXTERNAL (n->symbol.decl));
811 #endif
812           symtab_dissolve_same_comdat_group_list ((symtab_node) node);
813         }
814       gcc_assert ((!DECL_WEAK (node->symbol.decl)
815                   && !DECL_COMDAT (node->symbol.decl))
816                   || TREE_PUBLIC (node->symbol.decl)
817                   || DECL_EXTERNAL (node->symbol.decl));
818       if (cgraph_externally_visible_p (node, whole_program,
819                                        pointer_set_contains (aliased_nodes,
820                                                              node)))
821         {
822           gcc_assert (!node->global.inlined_to);
823           node->symbol.externally_visible = true;
824         }
825       else
826         node->symbol.externally_visible = false;
827       if (!node->symbol.externally_visible && node->analyzed
828           && !DECL_EXTERNAL (node->symbol.decl))
829         {
830           gcc_assert (whole_program || in_lto_p
831                       || !TREE_PUBLIC (node->symbol.decl));
832           symtab_make_decl_local (node->symbol.decl);
833           node->symbol.resolution = LDPR_PREVAILING_DEF_IRONLY;
834           if (node->symbol.same_comdat_group)
835             /* cgraph_externally_visible_p has already checked all other nodes
836                in the group and they will all be made local.  We need to
837                dissolve the group at once so that the predicate does not
838                segfault though. */
839             symtab_dissolve_same_comdat_group_list ((symtab_node) node);
840         }
841
842       if (node->thunk.thunk_p
843           && TREE_PUBLIC (node->symbol.decl))
844         {
845           struct cgraph_node *decl_node = node;
846
847           decl_node = cgraph_function_node (decl_node->callees->callee, NULL);
848
849           /* Thunks have the same visibility as function they are attached to.
850              Make sure the C++ front end set this up properly.  */
851           if (DECL_ONE_ONLY (decl_node->symbol.decl))
852             {
853               gcc_checking_assert (DECL_COMDAT (node->symbol.decl)
854                                    == DECL_COMDAT (decl_node->symbol.decl));
855               gcc_checking_assert (DECL_COMDAT_GROUP (node->symbol.decl)
856                                    == DECL_COMDAT_GROUP (decl_node->symbol.decl));
857               gcc_checking_assert (node->symbol.same_comdat_group);
858             }
859           if (DECL_EXTERNAL (decl_node->symbol.decl))
860             DECL_EXTERNAL (node->symbol.decl) = 1;
861         }
862     }
863   FOR_EACH_DEFINED_FUNCTION (node)
864     node->local.local = cgraph_local_node_p (node);
865   FOR_EACH_VARIABLE (vnode)
866     {
867       /* weak flag makes no sense on local variables.  */
868       gcc_assert (!DECL_WEAK (vnode->symbol.decl)
869                   || TREE_PUBLIC (vnode->symbol.decl)
870                   || DECL_EXTERNAL (vnode->symbol.decl));
871       /* In several cases declarations can not be common:
872
873          - when declaration has initializer
874          - when it is in weak
875          - when it has specific section
876          - when it resides in non-generic address space.
877          - if declaration is local, it will get into .local common section
878            so common flag is not needed.  Frontends still produce these in
879            certain cases, such as for:
880
881              static int a __attribute__ ((common))
882
883          Canonicalize things here and clear the redundant flag.  */
884       if (DECL_COMMON (vnode->symbol.decl)
885           && (!(TREE_PUBLIC (vnode->symbol.decl)
886               || DECL_EXTERNAL (vnode->symbol.decl))
887               || (DECL_INITIAL (vnode->symbol.decl)
888                   && DECL_INITIAL (vnode->symbol.decl) != error_mark_node)
889               || DECL_WEAK (vnode->symbol.decl)
890               || DECL_SECTION_NAME (vnode->symbol.decl) != NULL
891               || ! (ADDR_SPACE_GENERIC_P
892                     (TYPE_ADDR_SPACE (TREE_TYPE (vnode->symbol.decl))))))
893         DECL_COMMON (vnode->symbol.decl) = 0;
894     }
895   FOR_EACH_DEFINED_VARIABLE (vnode)
896     {
897       if (!vnode->finalized)
898         continue;
899       if (varpool_externally_visible_p
900             (vnode, 
901              pointer_set_contains (aliased_vnodes, vnode)))
902         vnode->symbol.externally_visible = true;
903       else
904         vnode->symbol.externally_visible = false;
905       if (!vnode->symbol.externally_visible)
906         {
907           gcc_assert (in_lto_p || whole_program || !TREE_PUBLIC (vnode->symbol.decl));
908           symtab_make_decl_local (vnode->symbol.decl);
909           if (vnode->symbol.same_comdat_group)
910             symtab_dissolve_same_comdat_group_list ((symtab_node) vnode);
911           vnode->symbol.resolution = LDPR_PREVAILING_DEF_IRONLY;
912         }
913     }
914   pointer_set_destroy (aliased_nodes);
915   pointer_set_destroy (aliased_vnodes);
916
917   if (dump_file)
918     {
919       fprintf (dump_file, "\nMarking local functions:");
920       FOR_EACH_DEFINED_FUNCTION (node)
921         if (node->local.local)
922           fprintf (dump_file, " %s", cgraph_node_name (node));
923       fprintf (dump_file, "\n\n");
924       fprintf (dump_file, "\nMarking externally visible functions:");
925       FOR_EACH_DEFINED_FUNCTION (node)
926         if (node->symbol.externally_visible)
927           fprintf (dump_file, " %s", cgraph_node_name (node));
928       fprintf (dump_file, "\n\n");
929       fprintf (dump_file, "\nMarking externally visible variables:");
930       FOR_EACH_DEFINED_VARIABLE (vnode)
931         if (vnode->symbol.externally_visible)
932           fprintf (dump_file, " %s", varpool_node_name (vnode));
933       fprintf (dump_file, "\n\n");
934     }
935   cgraph_function_flags_ready = true;
936   return 0;
937 }
938
939 /* Local function pass handling visibilities.  This happens before LTO streaming
940    so in particular -fwhole-program should be ignored at this level.  */
941
942 static unsigned int
943 local_function_and_variable_visibility (void)
944 {
945   return function_and_variable_visibility (flag_whole_program && !flag_lto);
946 }
947
948 struct simple_ipa_opt_pass pass_ipa_function_and_variable_visibility =
949 {
950  {
951   SIMPLE_IPA_PASS,
952   "visibility",                         /* name */
953   NULL,                                 /* gate */
954   local_function_and_variable_visibility,/* execute */
955   NULL,                                 /* sub */
956   NULL,                                 /* next */
957   0,                                    /* static_pass_number */
958   TV_CGRAPHOPT,                         /* tv_id */
959   0,                                    /* properties_required */
960   0,                                    /* properties_provided */
961   0,                                    /* properties_destroyed */
962   0,                                    /* todo_flags_start */
963   TODO_remove_functions | TODO_dump_symtab
964   | TODO_ggc_collect                    /* todo_flags_finish */
965  }
966 };
967
968 /* Free inline summary.  */
969
970 static unsigned
971 free_inline_summary (void)
972 {
973   inline_free_summary ();
974   return 0;
975 }
976
977 struct simple_ipa_opt_pass pass_ipa_free_inline_summary =
978 {
979  {
980   SIMPLE_IPA_PASS,
981   "*free_inline_summary",               /* name */
982   NULL,                                 /* gate */
983   free_inline_summary,                  /* execute */
984   NULL,                                 /* sub */
985   NULL,                                 /* next */
986   0,                                    /* static_pass_number */
987   TV_IPA_FREE_INLINE_SUMMARY,           /* tv_id */
988   0,                                    /* properties_required */
989   0,                                    /* properties_provided */
990   0,                                    /* properties_destroyed */
991   0,                                    /* todo_flags_start */
992   TODO_ggc_collect                      /* todo_flags_finish */
993  }
994 };
995
996 /* Do not re-run on ltrans stage.  */
997
998 static bool
999 gate_whole_program_function_and_variable_visibility (void)
1000 {
1001   return !flag_ltrans;
1002 }
1003
1004 /* Bring functionss local at LTO time with -fwhole-program.  */
1005
1006 static unsigned int
1007 whole_program_function_and_variable_visibility (void)
1008 {
1009   function_and_variable_visibility (flag_whole_program);
1010   if (optimize)
1011     ipa_discover_readonly_nonaddressable_vars ();
1012   return 0;
1013 }
1014
1015 struct ipa_opt_pass_d pass_ipa_whole_program_visibility =
1016 {
1017  {
1018   IPA_PASS,
1019   "whole-program",                      /* name */
1020   gate_whole_program_function_and_variable_visibility,/* gate */
1021   whole_program_function_and_variable_visibility,/* execute */
1022   NULL,                                 /* sub */
1023   NULL,                                 /* next */
1024   0,                                    /* static_pass_number */
1025   TV_CGRAPHOPT,                         /* tv_id */
1026   0,                                    /* properties_required */
1027   0,                                    /* properties_provided */
1028   0,                                    /* properties_destroyed */
1029   0,                                    /* todo_flags_start */
1030   TODO_remove_functions | TODO_dump_symtab
1031   | TODO_ggc_collect                    /* todo_flags_finish */
1032  },
1033  NULL,                                  /* generate_summary */
1034  NULL,                                  /* write_summary */
1035  NULL,                                  /* read_summary */
1036  NULL,                                  /* write_optimization_summary */
1037  NULL,                                  /* read_optimization_summary */
1038  NULL,                                  /* stmt_fixup */
1039  0,                                     /* TODOs */
1040  NULL,                                  /* function_transform */
1041  NULL,                                  /* variable_transform */
1042 };
1043
1044
1045 /* Simple ipa profile pass propagating frequencies across the callgraph.  */
1046
1047 static unsigned int
1048 ipa_profile (void)
1049 {
1050   struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
1051   struct cgraph_edge *e;
1052   int order_pos;
1053   bool something_changed = false;
1054   int i;
1055
1056   order_pos = ipa_reverse_postorder (order);
1057   for (i = order_pos - 1; i >= 0; i--)
1058     {
1059       if (order[i]->local.local && cgraph_propagate_frequency (order[i]))
1060         {
1061           for (e = order[i]->callees; e; e = e->next_callee)
1062             if (e->callee->local.local && !e->callee->symbol.aux)
1063               {
1064                 something_changed = true;
1065                 e->callee->symbol.aux = (void *)1;
1066               }
1067         }
1068       order[i]->symbol.aux = NULL;
1069     }
1070
1071   while (something_changed)
1072     {
1073       something_changed = false;
1074       for (i = order_pos - 1; i >= 0; i--)
1075         {
1076           if (order[i]->symbol.aux && cgraph_propagate_frequency (order[i]))
1077             {
1078               for (e = order[i]->callees; e; e = e->next_callee)
1079                 if (e->callee->local.local && !e->callee->symbol.aux)
1080                   {
1081                     something_changed = true;
1082                     e->callee->symbol.aux = (void *)1;
1083                   }
1084             }
1085           order[i]->symbol.aux = NULL;
1086         }
1087     }
1088   free (order);
1089   return 0;
1090 }
1091
1092 static bool
1093 gate_ipa_profile (void)
1094 {
1095   return flag_ipa_profile;
1096 }
1097
1098 struct ipa_opt_pass_d pass_ipa_profile =
1099 {
1100  {
1101   IPA_PASS,
1102   "profile_estimate",                   /* name */
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, heap) *static_ctors;
1217 /* A vector of FUNCTION_DECLs declared as static destructors.  */
1218 static VEC(tree, heap) *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     VEC_safe_push (tree, heap, static_ctors, node->symbol.decl);
1232   if (DECL_STATIC_DESTRUCTOR (node->symbol.decl))
1233     VEC_safe_push (tree, heap, static_dtors, 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, heap) *cdtors)
1245 {
1246   size_t i,j;
1247   size_t len = VEC_length (tree, cdtors);
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 = VEC_index (tree, 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 = VEC_index (tree, 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 (!VEC_empty (tree, static_ctors))
1364     {
1365       gcc_assert (!targetm.have_ctors_dtors || in_lto_p);
1366       VEC_qsort (tree, static_ctors, compare_ctor);
1367       build_cdtor (/*ctor_p=*/true, static_ctors);
1368     }
1369
1370   if (!VEC_empty (tree, static_dtors))
1371     {
1372       gcc_assert (!targetm.have_ctors_dtors || in_lto_p);
1373       VEC_qsort (tree, static_dtors, 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   VEC_free (tree, heap, static_ctors);
1394   VEC_free (tree, heap, static_dtors);
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   gate_ipa_cdtor_merge,                 /* gate */
1414   ipa_cdtor_merge,                      /* execute */
1415   NULL,                                 /* sub */
1416   NULL,                                 /* next */
1417   0,                                    /* static_pass_number */
1418   TV_CGRAPHOPT,                         /* tv_id */
1419   0,                                    /* properties_required */
1420   0,                                    /* properties_provided */
1421   0,                                    /* properties_destroyed */
1422   0,                                    /* todo_flags_start */
1423   0                                     /* todo_flags_finish */
1424  },
1425  NULL,                                  /* generate_summary */
1426  NULL,                                  /* write_summary */
1427  NULL,                                  /* read_summary */
1428  NULL,                                  /* write_optimization_summary */
1429  NULL,                                  /* read_optimization_summary */
1430  NULL,                                  /* stmt_fixup */
1431  0,                                     /* TODOs */
1432  NULL,                                  /* function_transform */
1433  NULL                                   /* variable_transform */
1434 };