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