OSDN Git Service

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