PR other/53317
[official-gcc.git] / gcc / ipa.c
blob7c0d495695ba6cbc27b60aa270ef3107fef91d8b
1 /* Basic IPA optimizations and utilities.
2 Copyright (C) 2003-2013 Free Software Foundation, Inc.
4 This file is part of GCC.
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.
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.
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/>. */
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 #include "hash-table.h"
36 #include "tree-inline.h"
37 #include "profile.h"
38 #include "params.h"
39 #include "lto-streamer.h"
40 #include "data-streamer.h"
42 /* Return true when NODE can not be local. Worker for cgraph_local_node_p. */
44 static bool
45 cgraph_non_local_node_p_1 (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
47 /* FIXME: Aliases can be local, but i386 gets thunks wrong then. */
48 return !(cgraph_only_called_directly_or_aliased_p (node)
49 && !ipa_ref_has_aliases_p (&node->symbol.ref_list)
50 && node->symbol.definition
51 && !DECL_EXTERNAL (node->symbol.decl)
52 && !node->symbol.externally_visible
53 && !node->symbol.used_from_other_partition
54 && !node->symbol.in_other_partition);
57 /* Return true when function can be marked local. */
59 static bool
60 cgraph_local_node_p (struct cgraph_node *node)
62 struct cgraph_node *n = cgraph_function_or_thunk_node (node, NULL);
64 /* FIXME: thunks can be considered local, but we need prevent i386
65 from attempting to change calling convention of them. */
66 if (n->thunk.thunk_p)
67 return false;
68 return !cgraph_for_node_and_aliases (n,
69 cgraph_non_local_node_p_1, NULL, true);
73 /* Return true when NODE has ADDR reference. */
75 static bool
76 has_addr_references_p (struct cgraph_node *node,
77 void *data ATTRIBUTE_UNUSED)
79 int i;
80 struct ipa_ref *ref;
82 for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list,
83 i, ref); i++)
84 if (ref->use == IPA_REF_ADDR)
85 return true;
86 return false;
89 /* Look for all functions inlined to NODE and update their inlined_to pointers
90 to INLINED_TO. */
92 static void
93 update_inlined_to_pointer (struct cgraph_node *node, struct cgraph_node *inlined_to)
95 struct cgraph_edge *e;
96 for (e = node->callees; e; e = e->next_callee)
97 if (e->callee->global.inlined_to)
99 e->callee->global.inlined_to = inlined_to;
100 update_inlined_to_pointer (e->callee, inlined_to);
104 /* Add symtab NODE to queue starting at FIRST.
106 The queue is linked via AUX pointers and terminated by pointer to 1.
107 We enqueue nodes at two occasions: when we find them reachable or when we find
108 their bodies needed for further clonning. In the second case we mark them
109 by pointer to 2 after processing so they are re-queue when they become
110 reachable. */
112 static void
113 enqueue_node (symtab_node node, symtab_node *first,
114 struct pointer_set_t *reachable)
116 /* Node is still in queue; do nothing. */
117 if (node->symbol.aux && node->symbol.aux != (void *) 2)
118 return;
119 /* Node was already processed as unreachable, re-enqueue
120 only if it became reachable now. */
121 if (node->symbol.aux == (void *)2 && !pointer_set_contains (reachable, node))
122 return;
123 node->symbol.aux = *first;
124 *first = node;
127 /* Process references. */
129 static void
130 process_references (struct ipa_ref_list *list,
131 symtab_node *first,
132 bool before_inlining_p,
133 struct pointer_set_t *reachable)
135 int i;
136 struct ipa_ref *ref;
137 for (i = 0; ipa_ref_list_reference_iterate (list, i, ref); i++)
139 symtab_node node = ref->referred;
141 if (node->symbol.definition
142 && ((!DECL_EXTERNAL (node->symbol.decl) || node->symbol.alias)
143 || (before_inlining_p
144 /* We use variable constructors during late complation for
145 constant folding. Keep references alive so partitioning
146 knows about potential references. */
147 || (TREE_CODE (node->symbol.decl) == VAR_DECL
148 && flag_wpa
149 && ctor_for_folding (node->symbol.decl)
150 != error_mark_node))))
151 pointer_set_insert (reachable, node);
152 enqueue_node ((symtab_node) node, first, reachable);
157 /* Perform reachability analysis and reclaim all unreachable nodes.
159 The algorithm is basically mark&sweep but with some extra refinements:
161 - reachable extern inline functions needs special handling; the bodies needs
162 to stay in memory until inlining in hope that they will be inlined.
163 After inlining we release their bodies and turn them into unanalyzed
164 nodes even when they are reachable.
166 BEFORE_INLINING_P specify whether we are before or after inlining.
168 - virtual functions are kept in callgraph even if they seem unreachable in
169 hope calls to them will be devirtualized.
171 Again we remove them after inlining. In late optimization some
172 devirtualization may happen, but it is not importnat since we won't inline
173 the call. In theory early opts and IPA should work out all important cases.
175 - virtual clones needs bodies of their origins for later materialization;
176 this means that we want to keep the body even if the origin is unreachable
177 otherwise. To avoid origin from sitting in the callgraph and being
178 walked by IPA passes, we turn them into unanalyzed nodes with body
179 defined.
181 We maintain set of function declaration where body needs to stay in
182 body_needed_for_clonning
184 Inline clones represent special case: their declaration match the
185 declaration of origin and cgraph_remove_node already knows how to
186 reshape callgraph and preserve body when offline copy of function or
187 inline clone is being removed.
189 - C++ virtual tables keyed to other unit are represented as DECL_EXTERNAL
190 variables with DECL_INITIAL set. We finalize these and keep reachable
191 ones around for constant folding purposes. After inlining we however
192 stop walking their references to let everything static referneced by them
193 to be removed when it is otherwise unreachable.
195 We maintain queue of both reachable symbols (i.e. defined symbols that needs
196 to stay) and symbols that are in boundary (i.e. external symbols referenced
197 by reachable symbols or origins of clones). The queue is represented
198 as linked list by AUX pointer terminated by 1.
200 A the end we keep all reachable symbols. For symbols in boundary we always
201 turn definition into a declaration, but we may keep function body around
202 based on body_needed_for_clonning
204 All symbols that enter the queue have AUX pointer non-zero and are in the
205 boundary. Pointer set REACHABLE is used to track reachable symbols.
207 Every symbol can be visited twice - once as part of boundary and once
208 as real reachable symbol. enqueue_node needs to decide whether the
209 node needs to be re-queued for second processing. For this purpose
210 we set AUX pointer of processed symbols in the boundary to constant 2. */
212 bool
213 symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
215 symtab_node first = (symtab_node) (void *) 1;
216 struct cgraph_node *node, *next;
217 struct varpool_node *vnode, *vnext;
218 bool changed = false;
219 struct pointer_set_t *reachable = pointer_set_create ();
220 struct pointer_set_t *body_needed_for_clonning = pointer_set_create ();
222 #ifdef ENABLE_CHECKING
223 verify_symtab ();
224 #endif
225 if (file)
226 fprintf (file, "\nReclaiming functions:");
227 #ifdef ENABLE_CHECKING
228 FOR_EACH_FUNCTION (node)
229 gcc_assert (!node->symbol.aux);
230 FOR_EACH_VARIABLE (vnode)
231 gcc_assert (!vnode->symbol.aux);
232 #endif
233 /* Mark functions whose bodies are obviously needed.
234 This is mostly when they can be referenced externally. Inline clones
235 are special since their declarations are shared with master clone and thus
236 cgraph_can_remove_if_no_direct_calls_and_refs_p should not be called on them. */
237 FOR_EACH_DEFINED_FUNCTION (node)
238 if (!node->global.inlined_to
239 && (!cgraph_can_remove_if_no_direct_calls_and_refs_p (node)
240 /* Keep around virtual functions for possible devirtualization. */
241 || (before_inlining_p
242 && DECL_VIRTUAL_P (node->symbol.decl))))
244 gcc_assert (!node->global.inlined_to);
245 pointer_set_insert (reachable, node);
246 enqueue_node ((symtab_node)node, &first, reachable);
248 else
249 gcc_assert (!node->symbol.aux);
251 /* Mark variables that are obviously needed. */
252 FOR_EACH_DEFINED_VARIABLE (vnode)
253 if (!varpool_can_remove_if_no_refs (vnode))
255 pointer_set_insert (reachable, vnode);
256 enqueue_node ((symtab_node)vnode, &first, reachable);
259 /* Perform reachability analysis. */
260 while (first != (symtab_node) (void *) 1)
262 bool in_boundary_p = !pointer_set_contains (reachable, first);
263 symtab_node node = first;
265 first = (symtab_node)first->symbol.aux;
267 /* If we are processing symbol in boundary, mark its AUX pointer for
268 possible later re-processing in enqueue_node. */
269 if (in_boundary_p)
270 node->symbol.aux = (void *)2;
271 else
273 /* If any symbol in a comdat group is reachable, force
274 all other in the same comdat group to be also reachable. */
275 if (node->symbol.same_comdat_group)
277 symtab_node next;
278 for (next = node->symbol.same_comdat_group;
279 next != node;
280 next = next->symbol.same_comdat_group)
281 if (!pointer_set_insert (reachable, next))
282 enqueue_node ((symtab_node) next, &first, reachable);
284 /* Mark references as reachable. */
285 process_references (&node->symbol.ref_list, &first,
286 before_inlining_p, reachable);
289 if (cgraph_node *cnode = dyn_cast <cgraph_node> (node))
291 /* Mark the callees reachable unless they are direct calls to extern
292 inline functions we decided to not inline. */
293 if (!in_boundary_p)
295 struct cgraph_edge *e;
296 for (e = cnode->callees; e; e = e->next_callee)
298 if (e->callee->symbol.definition
299 && (!e->inline_failed
300 || !DECL_EXTERNAL (e->callee->symbol.decl)
301 || e->callee->symbol.alias
302 || before_inlining_p))
303 pointer_set_insert (reachable, e->callee);
304 enqueue_node ((symtab_node) e->callee, &first, reachable);
307 /* When inline clone exists, mark body to be preserved so when removing
308 offline copy of the function we don't kill it. */
309 if (!cnode->symbol.alias && cnode->global.inlined_to)
310 pointer_set_insert (body_needed_for_clonning, cnode->symbol.decl);
313 /* For non-inline clones, force their origins to the boundary and ensure
314 that body is not removed. */
315 while (cnode->clone_of
316 && !gimple_has_body_p (cnode->symbol.decl))
318 bool noninline = cnode->clone_of->symbol.decl != cnode->symbol.decl;
319 cnode = cnode->clone_of;
320 if (noninline)
322 pointer_set_insert (body_needed_for_clonning, cnode->symbol.decl);
323 enqueue_node ((symtab_node)cnode, &first, reachable);
324 break;
328 /* When we see constructor of external variable, keep referred nodes in the
329 boundary. This will also hold initializers of the external vars NODE
330 refers to. */
331 varpool_node *vnode = dyn_cast <varpool_node> (node);
332 if (vnode
333 && DECL_EXTERNAL (node->symbol.decl)
334 && !vnode->symbol.alias
335 && in_boundary_p)
337 struct ipa_ref *ref;
338 for (int i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list, i, ref); i++)
339 enqueue_node (ref->referred, &first, reachable);
343 /* Remove unreachable functions. */
344 for (node = cgraph_first_function (); node; node = next)
346 next = cgraph_next_function (node);
348 /* If node is not needed at all, remove it. */
349 if (!node->symbol.aux)
351 if (file)
352 fprintf (file, " %s", cgraph_node_name (node));
353 cgraph_remove_node (node);
354 changed = true;
356 /* If node is unreachable, remove its body. */
357 else if (!pointer_set_contains (reachable, node))
359 if (!pointer_set_contains (body_needed_for_clonning, node->symbol.decl))
360 cgraph_release_function_body (node);
361 if (node->symbol.definition)
363 if (file)
364 fprintf (file, " %s", cgraph_node_name (node));
365 cgraph_reset_node (node);
366 changed = true;
371 /* Inline clones might be kept around so their materializing allows further
372 cloning. If the function the clone is inlined into is removed, we need
373 to turn it into normal cone. */
374 FOR_EACH_FUNCTION (node)
376 if (node->global.inlined_to
377 && !node->callers)
379 gcc_assert (node->clones);
380 node->global.inlined_to = NULL;
381 update_inlined_to_pointer (node, node);
383 node->symbol.aux = NULL;
386 /* Remove unreachable variables. */
387 if (file)
388 fprintf (file, "\nReclaiming variables:");
389 for (vnode = varpool_first_variable (); vnode; vnode = vnext)
391 vnext = varpool_next_variable (vnode);
392 if (!vnode->symbol.aux
393 /* For can_refer_decl_in_current_unit_p we want to track for
394 all external variables if they are defined in other partition
395 or not. */
396 && (!flag_ltrans || !DECL_EXTERNAL (vnode->symbol.decl)))
398 if (file)
399 fprintf (file, " %s", varpool_node_name (vnode));
400 varpool_remove_node (vnode);
401 changed = true;
403 else if (!pointer_set_contains (reachable, vnode))
405 tree init;
406 if (vnode->symbol.definition)
408 if (file)
409 fprintf (file, " %s", varpool_node_name (vnode));
410 changed = true;
412 vnode->symbol.definition = false;
413 vnode->symbol.analyzed = false;
414 vnode->symbol.aux = NULL;
416 /* Keep body if it may be useful for constant folding. */
417 if ((init = ctor_for_folding (vnode->symbol.decl)) == error_mark_node)
418 varpool_remove_initializer (vnode);
419 else
420 DECL_INITIAL (vnode->symbol.decl) = init;
421 ipa_remove_all_references (&vnode->symbol.ref_list);
423 else
424 vnode->symbol.aux = NULL;
427 pointer_set_destroy (reachable);
428 pointer_set_destroy (body_needed_for_clonning);
430 /* Now update address_taken flags and try to promote functions to be local. */
431 if (file)
432 fprintf (file, "\nClearing address taken flags:");
433 FOR_EACH_DEFINED_FUNCTION (node)
434 if (node->symbol.address_taken
435 && !node->symbol.used_from_other_partition)
437 if (!cgraph_for_node_and_aliases (node, has_addr_references_p, NULL, true))
439 if (file)
440 fprintf (file, " %s", cgraph_node_name (node));
441 node->symbol.address_taken = false;
442 changed = true;
443 if (cgraph_local_node_p (node))
445 node->local.local = true;
446 if (file)
447 fprintf (file, " (local)");
451 if (file)
452 fprintf (file, "\n");
454 #ifdef ENABLE_CHECKING
455 verify_symtab ();
456 #endif
458 /* If we removed something, perhaps profile could be improved. */
459 if (changed && optimize && inline_edge_summary_vec.exists ())
460 FOR_EACH_DEFINED_FUNCTION (node)
461 cgraph_propagate_frequency (node);
463 return changed;
466 /* Discover variables that have no longer address taken or that are read only
467 and update their flags.
469 FIXME: This can not be done in between gimplify and omp_expand since
470 readonly flag plays role on what is shared and what is not. Currently we do
471 this transformation as part of whole program visibility and re-do at
472 ipa-reference pass (to take into account clonning), but it would
473 make sense to do it before early optimizations. */
475 void
476 ipa_discover_readonly_nonaddressable_vars (void)
478 struct varpool_node *vnode;
479 if (dump_file)
480 fprintf (dump_file, "Clearing variable flags:");
481 FOR_EACH_VARIABLE (vnode)
482 if (vnode->symbol.definition && varpool_all_refs_explicit_p (vnode)
483 && (TREE_ADDRESSABLE (vnode->symbol.decl)
484 || !TREE_READONLY (vnode->symbol.decl)))
486 bool written = false;
487 bool address_taken = false;
488 int i;
489 struct ipa_ref *ref;
490 for (i = 0; ipa_ref_list_referring_iterate (&vnode->symbol.ref_list,
491 i, ref)
492 && (!written || !address_taken); i++)
493 switch (ref->use)
495 case IPA_REF_ADDR:
496 address_taken = true;
497 break;
498 case IPA_REF_LOAD:
499 break;
500 case IPA_REF_STORE:
501 written = true;
502 break;
504 if (TREE_ADDRESSABLE (vnode->symbol.decl) && !address_taken)
506 if (dump_file)
507 fprintf (dump_file, " %s (addressable)", varpool_node_name (vnode));
508 TREE_ADDRESSABLE (vnode->symbol.decl) = 0;
510 if (!TREE_READONLY (vnode->symbol.decl) && !address_taken && !written
511 /* Making variable in explicit section readonly can cause section
512 type conflict.
513 See e.g. gcc.c-torture/compile/pr23237.c */
514 && DECL_SECTION_NAME (vnode->symbol.decl) == NULL)
516 if (dump_file)
517 fprintf (dump_file, " %s (read-only)", varpool_node_name (vnode));
518 TREE_READONLY (vnode->symbol.decl) = 1;
521 if (dump_file)
522 fprintf (dump_file, "\n");
525 /* Return true when there is a reference to node and it is not vtable. */
526 static bool
527 address_taken_from_non_vtable_p (symtab_node node)
529 int i;
530 struct ipa_ref *ref;
531 for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list,
532 i, ref); i++)
533 if (ref->use == IPA_REF_ADDR)
535 struct varpool_node *node;
536 if (is_a <cgraph_node> (ref->referring))
537 return true;
538 node = ipa_ref_referring_varpool_node (ref);
539 if (!DECL_VIRTUAL_P (node->symbol.decl))
540 return true;
542 return false;
545 /* A helper for comdat_can_be_unshared_p. */
547 static bool
548 comdat_can_be_unshared_p_1 (symtab_node node)
550 /* When address is taken, we don't know if equality comparison won't
551 break eventaully. Exception are virutal functions and vtables, where
552 this is not possible by language standard. */
553 if (!DECL_VIRTUAL_P (node->symbol.decl)
554 && address_taken_from_non_vtable_p (node))
555 return false;
557 /* If the symbol is used in some weird way, better to not touch it. */
558 if (node->symbol.force_output)
559 return false;
561 /* Explicit instantiations needs to be output when possibly
562 used externally. */
563 if (node->symbol.forced_by_abi
564 && TREE_PUBLIC (node->symbol.decl)
565 && (node->symbol.resolution != LDPR_PREVAILING_DEF_IRONLY
566 && !flag_whole_program))
567 return false;
569 /* Non-readonly and volatile variables can not be duplicated. */
570 if (is_a <varpool_node> (node)
571 && (!TREE_READONLY (node->symbol.decl)
572 || TREE_THIS_VOLATILE (node->symbol.decl)))
573 return false;
574 return true;
577 /* COMDAT functions must be shared only if they have address taken,
578 otherwise we can produce our own private implementation with
579 -fwhole-program.
580 Return true when turning COMDAT functoin static can not lead to wrong
581 code when the resulting object links with a library defining same COMDAT.
583 Virtual functions do have their addresses taken from the vtables,
584 but in C++ there is no way to compare their addresses for equality. */
586 static bool
587 comdat_can_be_unshared_p (symtab_node node)
589 if (!comdat_can_be_unshared_p_1 (node))
590 return false;
591 if (node->symbol.same_comdat_group)
593 symtab_node next;
595 /* If more than one function is in the same COMDAT group, it must
596 be shared even if just one function in the comdat group has
597 address taken. */
598 for (next = node->symbol.same_comdat_group;
599 next != node; next = next->symbol.same_comdat_group)
600 if (!comdat_can_be_unshared_p_1 (next))
601 return false;
603 return true;
606 /* Return true when function NODE should be considered externally visible. */
608 static bool
609 cgraph_externally_visible_p (struct cgraph_node *node,
610 bool whole_program)
612 if (!node->symbol.definition)
613 return false;
614 if (!TREE_PUBLIC (node->symbol.decl)
615 || DECL_EXTERNAL (node->symbol.decl))
616 return false;
618 /* Do not try to localize built-in functions yet. One of problems is that we
619 end up mangling their asm for WHOPR that makes it impossible to call them
620 using the implicit built-in declarations anymore. Similarly this enables
621 us to remove them as unreachable before actual calls may appear during
622 expansion or folding. */
623 if (DECL_BUILT_IN (node->symbol.decl))
624 return true;
626 /* If linker counts on us, we must preserve the function. */
627 if (symtab_used_from_object_file_p ((symtab_node) node))
628 return true;
629 if (DECL_PRESERVE_P (node->symbol.decl))
630 return true;
631 if (lookup_attribute ("externally_visible",
632 DECL_ATTRIBUTES (node->symbol.decl)))
633 return true;
634 if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
635 && lookup_attribute ("dllexport",
636 DECL_ATTRIBUTES (node->symbol.decl)))
637 return true;
638 if (node->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY)
639 return false;
640 /* When doing LTO or whole program, we can bring COMDAT functoins static.
641 This improves code quality and we know we will duplicate them at most twice
642 (in the case that we are not using plugin and link with object file
643 implementing same COMDAT) */
644 if ((in_lto_p || whole_program)
645 && DECL_COMDAT (node->symbol.decl)
646 && comdat_can_be_unshared_p ((symtab_node) node))
647 return false;
649 /* When doing link time optimizations, hidden symbols become local. */
650 if (in_lto_p
651 && (DECL_VISIBILITY (node->symbol.decl) == VISIBILITY_HIDDEN
652 || DECL_VISIBILITY (node->symbol.decl) == VISIBILITY_INTERNAL)
653 /* Be sure that node is defined in IR file, not in other object
654 file. In that case we don't set used_from_other_object_file. */
655 && node->symbol.definition)
657 else if (!whole_program)
658 return true;
660 if (MAIN_NAME_P (DECL_NAME (node->symbol.decl)))
661 return true;
663 return false;
666 /* Return true when variable VNODE should be considered externally visible. */
668 bool
669 varpool_externally_visible_p (struct varpool_node *vnode)
671 if (DECL_EXTERNAL (vnode->symbol.decl))
672 return true;
674 if (!TREE_PUBLIC (vnode->symbol.decl))
675 return false;
677 /* If linker counts on us, we must preserve the function. */
678 if (symtab_used_from_object_file_p ((symtab_node) vnode))
679 return true;
681 if (DECL_HARD_REGISTER (vnode->symbol.decl))
682 return true;
683 if (DECL_PRESERVE_P (vnode->symbol.decl))
684 return true;
685 if (lookup_attribute ("externally_visible",
686 DECL_ATTRIBUTES (vnode->symbol.decl)))
687 return true;
688 if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
689 && lookup_attribute ("dllexport",
690 DECL_ATTRIBUTES (vnode->symbol.decl)))
691 return true;
693 /* See if we have linker information about symbol not being used or
694 if we need to make guess based on the declaration.
696 Even if the linker clams the symbol is unused, never bring internal
697 symbols that are declared by user as used or externally visible.
698 This is needed for i.e. references from asm statements. */
699 if (symtab_used_from_object_file_p ((symtab_node) vnode))
700 return true;
701 if (vnode->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY)
702 return false;
704 /* As a special case, the COMDAT virtual tables can be unshared.
705 In LTO mode turn vtables into static variables. The variable is readonly,
706 so this does not enable more optimization, but referring static var
707 is faster for dynamic linking. Also this match logic hidding vtables
708 from LTO symbol tables. */
709 if ((in_lto_p || flag_whole_program)
710 && DECL_COMDAT (vnode->symbol.decl)
711 && comdat_can_be_unshared_p ((symtab_node) vnode))
712 return false;
714 /* When doing link time optimizations, hidden symbols become local. */
715 if (in_lto_p
716 && (DECL_VISIBILITY (vnode->symbol.decl) == VISIBILITY_HIDDEN
717 || DECL_VISIBILITY (vnode->symbol.decl) == VISIBILITY_INTERNAL)
718 /* Be sure that node is defined in IR file, not in other object
719 file. In that case we don't set used_from_other_object_file. */
720 && vnode->symbol.definition)
722 else if (!flag_whole_program)
723 return true;
725 /* Do not attempt to privatize COMDATS by default.
726 This would break linking with C++ libraries sharing
727 inline definitions.
729 FIXME: We can do so for readonly vars with no address taken and
730 possibly also for vtables since no direct pointer comparsion is done.
731 It might be interesting to do so to reduce linking overhead. */
732 if (DECL_COMDAT (vnode->symbol.decl) || DECL_WEAK (vnode->symbol.decl))
733 return true;
734 return false;
737 /* Mark visibility of all functions.
739 A local function is one whose calls can occur only in the current
740 compilation unit and all its calls are explicit, so we can change
741 its calling convention. We simply mark all static functions whose
742 address is not taken as local.
744 We also change the TREE_PUBLIC flag of all declarations that are public
745 in language point of view but we want to overwrite this default
746 via visibilities for the backend point of view. */
748 static unsigned int
749 function_and_variable_visibility (bool whole_program)
751 struct cgraph_node *node;
752 struct varpool_node *vnode;
754 /* All aliases should be procssed at this point. */
755 gcc_checking_assert (!alias_pairs || !alias_pairs->length());
757 FOR_EACH_FUNCTION (node)
759 int flags = flags_from_decl_or_type (node->symbol.decl);
761 /* Optimize away PURE and CONST constructors and destructors. */
762 if (optimize
763 && (flags & (ECF_CONST | ECF_PURE))
764 && !(flags & ECF_LOOPING_CONST_OR_PURE))
766 DECL_STATIC_CONSTRUCTOR (node->symbol.decl) = 0;
767 DECL_STATIC_DESTRUCTOR (node->symbol.decl) = 0;
770 /* Frontends and alias code marks nodes as needed before parsing is finished.
771 We may end up marking as node external nodes where this flag is meaningless
772 strip it. */
773 if (DECL_EXTERNAL (node->symbol.decl) || !node->symbol.definition)
775 node->symbol.force_output = 0;
776 node->symbol.forced_by_abi = 0;
779 /* C++ FE on lack of COMDAT support create local COMDAT functions
780 (that ought to be shared but can not due to object format
781 limitations). It is necessary to keep the flag to make rest of C++ FE
782 happy. Clear the flag here to avoid confusion in middle-end. */
783 if (DECL_COMDAT (node->symbol.decl) && !TREE_PUBLIC (node->symbol.decl))
784 DECL_COMDAT (node->symbol.decl) = 0;
786 /* For external decls stop tracking same_comdat_group. It doesn't matter
787 what comdat group they are in when they won't be emitted in this TU. */
788 if (node->symbol.same_comdat_group && DECL_EXTERNAL (node->symbol.decl))
790 #ifdef ENABLE_CHECKING
791 symtab_node n;
793 for (n = node->symbol.same_comdat_group;
794 n != (symtab_node)node;
795 n = n->symbol.same_comdat_group)
796 /* If at least one of same comdat group functions is external,
797 all of them have to be, otherwise it is a front-end bug. */
798 gcc_assert (DECL_EXTERNAL (n->symbol.decl));
799 #endif
800 symtab_dissolve_same_comdat_group_list ((symtab_node) node);
802 gcc_assert ((!DECL_WEAK (node->symbol.decl)
803 && !DECL_COMDAT (node->symbol.decl))
804 || TREE_PUBLIC (node->symbol.decl)
805 || node->symbol.weakref
806 || DECL_EXTERNAL (node->symbol.decl));
807 if (cgraph_externally_visible_p (node, whole_program))
809 gcc_assert (!node->global.inlined_to);
810 node->symbol.externally_visible = true;
812 else
814 node->symbol.externally_visible = false;
815 node->symbol.forced_by_abi = false;
817 if (!node->symbol.externally_visible
818 && node->symbol.definition && !node->symbol.weakref
819 && !DECL_EXTERNAL (node->symbol.decl))
821 gcc_assert (whole_program || in_lto_p
822 || !TREE_PUBLIC (node->symbol.decl));
823 node->symbol.unique_name = ((node->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY
824 || node->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
825 && TREE_PUBLIC (node->symbol.decl));
826 symtab_make_decl_local (node->symbol.decl);
827 node->symbol.resolution = LDPR_PREVAILING_DEF_IRONLY;
828 if (node->symbol.same_comdat_group)
829 /* cgraph_externally_visible_p has already checked all other nodes
830 in the group and they will all be made local. We need to
831 dissolve the group at once so that the predicate does not
832 segfault though. */
833 symtab_dissolve_same_comdat_group_list ((symtab_node) node);
836 if (node->thunk.thunk_p
837 && TREE_PUBLIC (node->symbol.decl))
839 struct cgraph_node *decl_node = node;
841 decl_node = cgraph_function_node (decl_node->callees->callee, NULL);
843 /* Thunks have the same visibility as function they are attached to.
844 Make sure the C++ front end set this up properly. */
845 if (DECL_ONE_ONLY (decl_node->symbol.decl))
847 gcc_checking_assert (DECL_COMDAT (node->symbol.decl)
848 == DECL_COMDAT (decl_node->symbol.decl));
849 gcc_checking_assert (DECL_COMDAT_GROUP (node->symbol.decl)
850 == DECL_COMDAT_GROUP (decl_node->symbol.decl));
851 gcc_checking_assert (node->symbol.same_comdat_group);
853 if (DECL_EXTERNAL (decl_node->symbol.decl))
854 DECL_EXTERNAL (node->symbol.decl) = 1;
857 FOR_EACH_DEFINED_FUNCTION (node)
858 node->local.local = cgraph_local_node_p (node);
859 FOR_EACH_VARIABLE (vnode)
861 /* weak flag makes no sense on local variables. */
862 gcc_assert (!DECL_WEAK (vnode->symbol.decl)
863 || vnode->symbol.weakref
864 || TREE_PUBLIC (vnode->symbol.decl)
865 || DECL_EXTERNAL (vnode->symbol.decl));
866 /* In several cases declarations can not be common:
868 - when declaration has initializer
869 - when it is in weak
870 - when it has specific section
871 - when it resides in non-generic address space.
872 - if declaration is local, it will get into .local common section
873 so common flag is not needed. Frontends still produce these in
874 certain cases, such as for:
876 static int a __attribute__ ((common))
878 Canonicalize things here and clear the redundant flag. */
879 if (DECL_COMMON (vnode->symbol.decl)
880 && (!(TREE_PUBLIC (vnode->symbol.decl)
881 || DECL_EXTERNAL (vnode->symbol.decl))
882 || (DECL_INITIAL (vnode->symbol.decl)
883 && DECL_INITIAL (vnode->symbol.decl) != error_mark_node)
884 || DECL_WEAK (vnode->symbol.decl)
885 || DECL_SECTION_NAME (vnode->symbol.decl) != NULL
886 || ! (ADDR_SPACE_GENERIC_P
887 (TYPE_ADDR_SPACE (TREE_TYPE (vnode->symbol.decl))))))
888 DECL_COMMON (vnode->symbol.decl) = 0;
890 FOR_EACH_DEFINED_VARIABLE (vnode)
892 if (!vnode->symbol.definition)
893 continue;
894 if (varpool_externally_visible_p (vnode))
895 vnode->symbol.externally_visible = true;
896 else
898 vnode->symbol.externally_visible = false;
899 vnode->symbol.forced_by_abi = false;
901 if (!vnode->symbol.externally_visible
902 && !vnode->symbol.weakref)
904 gcc_assert (in_lto_p || whole_program || !TREE_PUBLIC (vnode->symbol.decl));
905 symtab_make_decl_local (vnode->symbol.decl);
906 vnode->symbol.unique_name = ((vnode->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY
907 || vnode->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
908 && TREE_PUBLIC (vnode->symbol.decl));
909 if (vnode->symbol.same_comdat_group)
910 symtab_dissolve_same_comdat_group_list ((symtab_node) vnode);
911 vnode->symbol.resolution = LDPR_PREVAILING_DEF_IRONLY;
915 if (dump_file)
917 fprintf (dump_file, "\nMarking local functions:");
918 FOR_EACH_DEFINED_FUNCTION (node)
919 if (node->local.local)
920 fprintf (dump_file, " %s", cgraph_node_name (node));
921 fprintf (dump_file, "\n\n");
922 fprintf (dump_file, "\nMarking externally visible functions:");
923 FOR_EACH_DEFINED_FUNCTION (node)
924 if (node->symbol.externally_visible)
925 fprintf (dump_file, " %s", cgraph_node_name (node));
926 fprintf (dump_file, "\n\n");
927 fprintf (dump_file, "\nMarking externally visible variables:");
928 FOR_EACH_DEFINED_VARIABLE (vnode)
929 if (vnode->symbol.externally_visible)
930 fprintf (dump_file, " %s", varpool_node_name (vnode));
931 fprintf (dump_file, "\n\n");
933 cgraph_function_flags_ready = true;
934 return 0;
937 /* Local function pass handling visibilities. This happens before LTO streaming
938 so in particular -fwhole-program should be ignored at this level. */
940 static unsigned int
941 local_function_and_variable_visibility (void)
943 return function_and_variable_visibility (flag_whole_program && !flag_lto);
946 struct simple_ipa_opt_pass pass_ipa_function_and_variable_visibility =
949 SIMPLE_IPA_PASS,
950 "visibility", /* name */
951 OPTGROUP_NONE, /* optinfo_flags */
952 NULL, /* gate */
953 local_function_and_variable_visibility,/* execute */
954 NULL, /* sub */
955 NULL, /* next */
956 0, /* static_pass_number */
957 TV_CGRAPHOPT, /* tv_id */
958 0, /* properties_required */
959 0, /* properties_provided */
960 0, /* properties_destroyed */
961 0, /* todo_flags_start */
962 TODO_remove_functions | TODO_dump_symtab /* todo_flags_finish */
966 /* Free inline summary. */
968 static unsigned
969 free_inline_summary (void)
971 inline_free_summary ();
972 return 0;
975 struct simple_ipa_opt_pass pass_ipa_free_inline_summary =
978 SIMPLE_IPA_PASS,
979 "*free_inline_summary", /* name */
980 OPTGROUP_NONE, /* optinfo_flags */
981 NULL, /* gate */
982 free_inline_summary, /* execute */
983 NULL, /* sub */
984 NULL, /* next */
985 0, /* static_pass_number */
986 TV_IPA_FREE_INLINE_SUMMARY, /* tv_id */
987 0, /* properties_required */
988 0, /* properties_provided */
989 0, /* properties_destroyed */
990 0, /* todo_flags_start */
991 0 /* todo_flags_finish */
995 /* Do not re-run on ltrans stage. */
997 static bool
998 gate_whole_program_function_and_variable_visibility (void)
1000 return !flag_ltrans;
1003 /* Bring functionss local at LTO time with -fwhole-program. */
1005 static unsigned int
1006 whole_program_function_and_variable_visibility (void)
1008 function_and_variable_visibility (flag_whole_program);
1009 if (optimize)
1010 ipa_discover_readonly_nonaddressable_vars ();
1011 return 0;
1014 struct ipa_opt_pass_d pass_ipa_whole_program_visibility =
1017 IPA_PASS,
1018 "whole-program", /* name */
1019 OPTGROUP_NONE, /* optinfo_flags */
1020 gate_whole_program_function_and_variable_visibility,/* gate */
1021 whole_program_function_and_variable_visibility,/* execute */
1022 NULL, /* sub */
1023 NULL, /* next */
1024 0, /* static_pass_number */
1025 TV_CGRAPHOPT, /* tv_id */
1026 0, /* properties_required */
1027 0, /* properties_provided */
1028 0, /* properties_destroyed */
1029 0, /* todo_flags_start */
1030 TODO_remove_functions | TODO_dump_symtab /* todo_flags_finish */
1032 NULL, /* generate_summary */
1033 NULL, /* write_summary */
1034 NULL, /* read_summary */
1035 NULL, /* write_optimization_summary */
1036 NULL, /* read_optimization_summary */
1037 NULL, /* stmt_fixup */
1038 0, /* TODOs */
1039 NULL, /* function_transform */
1040 NULL, /* variable_transform */
1043 /* Entry in the histogram. */
1045 struct histogram_entry
1047 gcov_type count;
1048 int time;
1049 int size;
1052 /* Histogram of profile values.
1053 The histogram is represented as an ordered vector of entries allocated via
1054 histogram_pool. During construction a separate hashtable is kept to lookup
1055 duplicate entries. */
1057 vec<histogram_entry *> histogram;
1058 static alloc_pool histogram_pool;
1060 /* Hashtable support for storing SSA names hashed by their SSA_NAME_VAR. */
1062 struct histogram_hash : typed_noop_remove <histogram_entry>
1064 typedef histogram_entry value_type;
1065 typedef histogram_entry compare_type;
1066 static inline hashval_t hash (const value_type *);
1067 static inline int equal (const value_type *, const compare_type *);
1070 inline hashval_t
1071 histogram_hash::hash (const histogram_entry *val)
1073 return val->count;
1076 inline int
1077 histogram_hash::equal (const histogram_entry *val, const histogram_entry *val2)
1079 return val->count == val2->count;
1082 /* Account TIME and SIZE executed COUNT times into HISTOGRAM.
1083 HASHTABLE is the on-side hash kept to avoid duplicates. */
1085 static void
1086 account_time_size (hash_table <histogram_hash> hashtable,
1087 vec<histogram_entry *> &histogram,
1088 gcov_type count, int time, int size)
1090 histogram_entry key = {count, 0, 0};
1091 histogram_entry **val = hashtable.find_slot (&key, INSERT);
1093 if (!*val)
1095 *val = (histogram_entry *) pool_alloc (histogram_pool);
1096 **val = key;
1097 histogram.safe_push (*val);
1099 (*val)->time += time;
1100 (*val)->size += size;
1104 cmp_counts (const void *v1, const void *v2)
1106 const histogram_entry *h1 = *(const histogram_entry * const *)v1;
1107 const histogram_entry *h2 = *(const histogram_entry * const *)v2;
1108 if (h1->count < h2->count)
1109 return 1;
1110 if (h1->count > h2->count)
1111 return -1;
1112 return 0;
1115 /* Dump HISTOGRAM to FILE. */
1117 static void
1118 dump_histogram (FILE *file, vec<histogram_entry *> histogram)
1120 unsigned int i;
1121 gcov_type overall_time = 0, cumulated_time = 0, cumulated_size = 0, overall_size = 0;
1123 fprintf (dump_file, "Histogram:\n");
1124 for (i = 0; i < histogram.length (); i++)
1126 overall_time += histogram[i]->count * histogram[i]->time;
1127 overall_size += histogram[i]->size;
1129 if (!overall_time)
1130 overall_time = 1;
1131 if (!overall_size)
1132 overall_size = 1;
1133 for (i = 0; i < histogram.length (); i++)
1135 cumulated_time += histogram[i]->count * histogram[i]->time;
1136 cumulated_size += histogram[i]->size;
1137 fprintf (file, " "HOST_WIDEST_INT_PRINT_DEC": time:%i (%2.2f) size:%i (%2.2f)\n",
1138 (HOST_WIDEST_INT) histogram[i]->count,
1139 histogram[i]->time,
1140 cumulated_time * 100.0 / overall_time,
1141 histogram[i]->size,
1142 cumulated_size * 100.0 / overall_size);
1146 /* Collect histogram from CFG profiles. */
1148 static void
1149 ipa_profile_generate_summary (void)
1151 struct cgraph_node *node;
1152 gimple_stmt_iterator gsi;
1153 hash_table <histogram_hash> hashtable;
1154 basic_block bb;
1156 hashtable.create (10);
1157 histogram_pool = create_alloc_pool ("IPA histogram", sizeof (struct histogram_entry),
1158 10);
1160 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
1161 FOR_EACH_BB_FN (bb, DECL_STRUCT_FUNCTION (node->symbol.decl))
1163 int time = 0;
1164 int size = 0;
1165 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1167 time += estimate_num_insns (gsi_stmt (gsi), &eni_time_weights);
1168 size += estimate_num_insns (gsi_stmt (gsi), &eni_size_weights);
1170 account_time_size (hashtable, histogram, bb->count, time, size);
1172 hashtable.dispose ();
1173 histogram.qsort (cmp_counts);
1176 /* Serialize the ipa info for lto. */
1178 static void
1179 ipa_profile_write_summary (void)
1181 struct lto_simple_output_block *ob
1182 = lto_create_simple_output_block (LTO_section_ipa_profile);
1183 unsigned int i;
1185 streamer_write_uhwi_stream (ob->main_stream, histogram.length());
1186 for (i = 0; i < histogram.length (); i++)
1188 streamer_write_gcov_count_stream (ob->main_stream, histogram[i]->count);
1189 streamer_write_uhwi_stream (ob->main_stream, histogram[i]->time);
1190 streamer_write_uhwi_stream (ob->main_stream, histogram[i]->size);
1192 lto_destroy_simple_output_block (ob);
1195 /* Deserialize the ipa info for lto. */
1197 static void
1198 ipa_profile_read_summary (void)
1200 struct lto_file_decl_data ** file_data_vec
1201 = lto_get_file_decl_data ();
1202 struct lto_file_decl_data * file_data;
1203 hash_table <histogram_hash> hashtable;
1204 int j = 0;
1206 hashtable.create (10);
1207 histogram_pool = create_alloc_pool ("IPA histogram", sizeof (struct histogram_entry),
1208 10);
1210 while ((file_data = file_data_vec[j++]))
1212 const char *data;
1213 size_t len;
1214 struct lto_input_block *ib
1215 = lto_create_simple_input_block (file_data,
1216 LTO_section_ipa_profile,
1217 &data, &len);
1218 if (ib)
1220 unsigned int num = streamer_read_uhwi (ib);
1221 unsigned int n;
1222 for (n = 0; n < num; n++)
1224 gcov_type count = streamer_read_gcov_count (ib);
1225 int time = streamer_read_uhwi (ib);
1226 int size = streamer_read_uhwi (ib);
1227 account_time_size (hashtable, histogram,
1228 count, time, size);
1230 lto_destroy_simple_input_block (file_data,
1231 LTO_section_ipa_profile,
1232 ib, data, len);
1235 hashtable.dispose ();
1236 histogram.qsort (cmp_counts);
1239 /* Simple ipa profile pass propagating frequencies across the callgraph. */
1241 static unsigned int
1242 ipa_profile (void)
1244 struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
1245 struct cgraph_edge *e;
1246 int order_pos;
1247 bool something_changed = false;
1248 int i;
1249 gcov_type overall_time = 0, cutoff = 0, cumulated = 0, overall_size = 0;
1251 if (dump_file)
1252 dump_histogram (dump_file, histogram);
1253 for (i = 0; i < (int)histogram.length (); i++)
1255 overall_time += histogram[i]->count * histogram[i]->time;
1256 overall_size += histogram[i]->size;
1258 if (overall_time)
1260 gcov_type threshold;
1262 gcc_assert (overall_size);
1263 if (dump_file)
1265 gcov_type min, cumulated_time = 0, cumulated_size = 0;
1267 fprintf (dump_file, "Overall time: "HOST_WIDEST_INT_PRINT_DEC"\n",
1268 (HOST_WIDEST_INT)overall_time);
1269 min = get_hot_bb_threshold ();
1270 for (i = 0; i < (int)histogram.length () && histogram[i]->count >= min;
1271 i++)
1273 cumulated_time += histogram[i]->count * histogram[i]->time;
1274 cumulated_size += histogram[i]->size;
1276 fprintf (dump_file, "GCOV min count: "HOST_WIDEST_INT_PRINT_DEC
1277 " Time:%3.2f%% Size:%3.2f%%\n",
1278 (HOST_WIDEST_INT)min,
1279 cumulated_time * 100.0 / overall_time,
1280 cumulated_size * 100.0 / overall_size);
1282 cutoff = (overall_time * PARAM_VALUE (HOT_BB_COUNT_WS_PERMILLE) + 500) / 1000;
1283 threshold = 0;
1284 for (i = 0; cumulated < cutoff; i++)
1286 cumulated += histogram[i]->count * histogram[i]->time;
1287 threshold = histogram[i]->count;
1289 if (!threshold)
1290 threshold = 1;
1291 if (dump_file)
1293 gcov_type cumulated_time = 0, cumulated_size = 0;
1295 for (i = 0;
1296 i < (int)histogram.length () && histogram[i]->count >= threshold;
1297 i++)
1299 cumulated_time += histogram[i]->count * histogram[i]->time;
1300 cumulated_size += histogram[i]->size;
1302 fprintf (dump_file, "Determined min count: "HOST_WIDEST_INT_PRINT_DEC
1303 " Time:%3.2f%% Size:%3.2f%%\n",
1304 (HOST_WIDEST_INT)threshold,
1305 cumulated_time * 100.0 / overall_time,
1306 cumulated_size * 100.0 / overall_size);
1308 if (threshold > get_hot_bb_threshold ()
1309 || in_lto_p)
1311 if (dump_file)
1312 fprintf (dump_file, "Threshold updated.\n");
1313 set_hot_bb_threshold (threshold);
1316 histogram.release();
1317 free_alloc_pool (histogram_pool);
1319 order_pos = ipa_reverse_postorder (order);
1320 for (i = order_pos - 1; i >= 0; i--)
1322 if (order[i]->local.local && cgraph_propagate_frequency (order[i]))
1324 for (e = order[i]->callees; e; e = e->next_callee)
1325 if (e->callee->local.local && !e->callee->symbol.aux)
1327 something_changed = true;
1328 e->callee->symbol.aux = (void *)1;
1331 order[i]->symbol.aux = NULL;
1334 while (something_changed)
1336 something_changed = false;
1337 for (i = order_pos - 1; i >= 0; i--)
1339 if (order[i]->symbol.aux && cgraph_propagate_frequency (order[i]))
1341 for (e = order[i]->callees; e; e = e->next_callee)
1342 if (e->callee->local.local && !e->callee->symbol.aux)
1344 something_changed = true;
1345 e->callee->symbol.aux = (void *)1;
1348 order[i]->symbol.aux = NULL;
1351 free (order);
1352 return 0;
1355 static bool
1356 gate_ipa_profile (void)
1358 return flag_ipa_profile;
1361 struct ipa_opt_pass_d pass_ipa_profile =
1364 IPA_PASS,
1365 "profile_estimate", /* name */
1366 OPTGROUP_NONE, /* optinfo_flags */
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 */
1379 ipa_profile_generate_summary, /* generate_summary */
1380 ipa_profile_write_summary, /* write_summary */
1381 ipa_profile_read_summary, /* 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 */
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.
1395 FINAL specify whether the externally visible name for collect2 should
1396 be produced. */
1398 static void
1399 cgraph_build_static_cdtor_1 (char which, tree body, int priority, bool final)
1401 static int counter = 0;
1402 char which_buf[16];
1403 tree decl, name, resdecl;
1405 /* The priority is encoded in the constructor or destructor name.
1406 collect2 will sort the names and arrange that they are called at
1407 program startup. */
1408 if (final)
1409 sprintf (which_buf, "%c_%.5d_%d", which, priority, counter++);
1410 else
1411 /* Proudce sane name but one not recognizable by collect2, just for the
1412 case we fail to inline the function. */
1413 sprintf (which_buf, "sub_%c_%.5d_%d", which, priority, counter++);
1414 name = get_file_function_name (which_buf);
1416 decl = build_decl (input_location, FUNCTION_DECL, name,
1417 build_function_type_list (void_type_node, NULL_TREE));
1418 current_function_decl = decl;
1420 resdecl = build_decl (input_location,
1421 RESULT_DECL, NULL_TREE, void_type_node);
1422 DECL_ARTIFICIAL (resdecl) = 1;
1423 DECL_RESULT (decl) = resdecl;
1424 DECL_CONTEXT (resdecl) = decl;
1426 allocate_struct_function (decl, false);
1428 TREE_STATIC (decl) = 1;
1429 TREE_USED (decl) = 1;
1430 DECL_ARTIFICIAL (decl) = 1;
1431 DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;
1432 DECL_SAVED_TREE (decl) = body;
1433 if (!targetm.have_ctors_dtors && final)
1435 TREE_PUBLIC (decl) = 1;
1436 DECL_PRESERVE_P (decl) = 1;
1438 DECL_UNINLINABLE (decl) = 1;
1440 DECL_INITIAL (decl) = make_node (BLOCK);
1441 TREE_USED (DECL_INITIAL (decl)) = 1;
1443 DECL_SOURCE_LOCATION (decl) = input_location;
1444 cfun->function_end_locus = input_location;
1446 switch (which)
1448 case 'I':
1449 DECL_STATIC_CONSTRUCTOR (decl) = 1;
1450 decl_init_priority_insert (decl, priority);
1451 break;
1452 case 'D':
1453 DECL_STATIC_DESTRUCTOR (decl) = 1;
1454 decl_fini_priority_insert (decl, priority);
1455 break;
1456 default:
1457 gcc_unreachable ();
1460 gimplify_function_tree (decl);
1462 cgraph_add_new_function (decl, false);
1464 set_cfun (NULL);
1465 current_function_decl = NULL;
1468 /* Generate and emit a static constructor or destructor. WHICH must
1469 be one of 'I' (for a constructor) or 'D' (for a destructor). BODY
1470 is a STATEMENT_LIST containing GENERIC statements. PRIORITY is the
1471 initialization priority for this constructor or destructor. */
1473 void
1474 cgraph_build_static_cdtor (char which, tree body, int priority)
1476 cgraph_build_static_cdtor_1 (which, body, priority, false);
1479 /* A vector of FUNCTION_DECLs declared as static constructors. */
1480 static vec<tree> static_ctors;
1481 /* A vector of FUNCTION_DECLs declared as static destructors. */
1482 static vec<tree> static_dtors;
1484 /* When target does not have ctors and dtors, we call all constructor
1485 and destructor by special initialization/destruction function
1486 recognized by collect2.
1488 When we are going to build this function, collect all constructors and
1489 destructors and turn them into normal functions. */
1491 static void
1492 record_cdtor_fn (struct cgraph_node *node)
1494 if (DECL_STATIC_CONSTRUCTOR (node->symbol.decl))
1495 static_ctors.safe_push (node->symbol.decl);
1496 if (DECL_STATIC_DESTRUCTOR (node->symbol.decl))
1497 static_dtors.safe_push (node->symbol.decl);
1498 node = cgraph_get_node (node->symbol.decl);
1499 DECL_DISREGARD_INLINE_LIMITS (node->symbol.decl) = 1;
1502 /* Define global constructors/destructor functions for the CDTORS, of
1503 which they are LEN. The CDTORS are sorted by initialization
1504 priority. If CTOR_P is true, these are constructors; otherwise,
1505 they are destructors. */
1507 static void
1508 build_cdtor (bool ctor_p, vec<tree> cdtors)
1510 size_t i,j;
1511 size_t len = cdtors.length ();
1513 i = 0;
1514 while (i < len)
1516 tree body;
1517 tree fn;
1518 priority_type priority;
1520 priority = 0;
1521 body = NULL_TREE;
1522 j = i;
1525 priority_type p;
1526 fn = cdtors[j];
1527 p = ctor_p ? DECL_INIT_PRIORITY (fn) : DECL_FINI_PRIORITY (fn);
1528 if (j == i)
1529 priority = p;
1530 else if (p != priority)
1531 break;
1532 j++;
1534 while (j < len);
1536 /* When there is only one cdtor and target supports them, do nothing. */
1537 if (j == i + 1
1538 && targetm.have_ctors_dtors)
1540 i++;
1541 continue;
1543 /* Find the next batch of constructors/destructors with the same
1544 initialization priority. */
1545 for (;i < j; i++)
1547 tree call;
1548 fn = cdtors[i];
1549 call = build_call_expr (fn, 0);
1550 if (ctor_p)
1551 DECL_STATIC_CONSTRUCTOR (fn) = 0;
1552 else
1553 DECL_STATIC_DESTRUCTOR (fn) = 0;
1554 /* We do not want to optimize away pure/const calls here.
1555 When optimizing, these should be already removed, when not
1556 optimizing, we want user to be able to breakpoint in them. */
1557 TREE_SIDE_EFFECTS (call) = 1;
1558 append_to_statement_list (call, &body);
1560 gcc_assert (body != NULL_TREE);
1561 /* Generate a function to call all the function of like
1562 priority. */
1563 cgraph_build_static_cdtor_1 (ctor_p ? 'I' : 'D', body, priority, true);
1567 /* Comparison function for qsort. P1 and P2 are actually of type
1568 "tree *" and point to static constructors. DECL_INIT_PRIORITY is
1569 used to determine the sort order. */
1571 static int
1572 compare_ctor (const void *p1, const void *p2)
1574 tree f1;
1575 tree f2;
1576 int priority1;
1577 int priority2;
1579 f1 = *(const tree *)p1;
1580 f2 = *(const tree *)p2;
1581 priority1 = DECL_INIT_PRIORITY (f1);
1582 priority2 = DECL_INIT_PRIORITY (f2);
1584 if (priority1 < priority2)
1585 return -1;
1586 else if (priority1 > priority2)
1587 return 1;
1588 else
1589 /* Ensure a stable sort. Constructors are executed in backwarding
1590 order to make LTO initialize braries first. */
1591 return DECL_UID (f2) - DECL_UID (f1);
1594 /* Comparison function for qsort. P1 and P2 are actually of type
1595 "tree *" and point to static destructors. DECL_FINI_PRIORITY is
1596 used to determine the sort order. */
1598 static int
1599 compare_dtor (const void *p1, const void *p2)
1601 tree f1;
1602 tree f2;
1603 int priority1;
1604 int priority2;
1606 f1 = *(const tree *)p1;
1607 f2 = *(const tree *)p2;
1608 priority1 = DECL_FINI_PRIORITY (f1);
1609 priority2 = DECL_FINI_PRIORITY (f2);
1611 if (priority1 < priority2)
1612 return -1;
1613 else if (priority1 > priority2)
1614 return 1;
1615 else
1616 /* Ensure a stable sort. */
1617 return DECL_UID (f1) - DECL_UID (f2);
1620 /* Generate functions to call static constructors and destructors
1621 for targets that do not support .ctors/.dtors sections. These
1622 functions have magic names which are detected by collect2. */
1624 static void
1625 build_cdtor_fns (void)
1627 if (!static_ctors.is_empty ())
1629 gcc_assert (!targetm.have_ctors_dtors || in_lto_p);
1630 static_ctors.qsort (compare_ctor);
1631 build_cdtor (/*ctor_p=*/true, static_ctors);
1634 if (!static_dtors.is_empty ())
1636 gcc_assert (!targetm.have_ctors_dtors || in_lto_p);
1637 static_dtors.qsort (compare_dtor);
1638 build_cdtor (/*ctor_p=*/false, static_dtors);
1642 /* Look for constructors and destructors and produce function calling them.
1643 This is needed for targets not supporting ctors or dtors, but we perform the
1644 transformation also at linktime to merge possibly numerous
1645 constructors/destructors into single function to improve code locality and
1646 reduce size. */
1648 static unsigned int
1649 ipa_cdtor_merge (void)
1651 struct cgraph_node *node;
1652 FOR_EACH_DEFINED_FUNCTION (node)
1653 if (DECL_STATIC_CONSTRUCTOR (node->symbol.decl)
1654 || DECL_STATIC_DESTRUCTOR (node->symbol.decl))
1655 record_cdtor_fn (node);
1656 build_cdtor_fns ();
1657 static_ctors.release ();
1658 static_dtors.release ();
1659 return 0;
1662 /* Perform the pass when we have no ctors/dtors support
1663 or at LTO time to merge multiple constructors into single
1664 function. */
1666 static bool
1667 gate_ipa_cdtor_merge (void)
1669 return !targetm.have_ctors_dtors || (optimize && in_lto_p);
1672 struct ipa_opt_pass_d pass_ipa_cdtor_merge =
1675 IPA_PASS,
1676 "cdtor", /* name */
1677 OPTGROUP_NONE, /* optinfo_flags */
1678 gate_ipa_cdtor_merge, /* gate */
1679 ipa_cdtor_merge, /* execute */
1680 NULL, /* sub */
1681 NULL, /* next */
1682 0, /* static_pass_number */
1683 TV_CGRAPHOPT, /* tv_id */
1684 0, /* properties_required */
1685 0, /* properties_provided */
1686 0, /* properties_destroyed */
1687 0, /* todo_flags_start */
1688 0 /* todo_flags_finish */
1690 NULL, /* generate_summary */
1691 NULL, /* write_summary */
1692 NULL, /* read_summary */
1693 NULL, /* write_optimization_summary */
1694 NULL, /* read_optimization_summary */
1695 NULL, /* stmt_fixup */
1696 0, /* TODOs */
1697 NULL, /* function_transform */
1698 NULL /* variable_transform */