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
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
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/>. */
22 #include "coretypes.h"
25 #include "tree-pass.h"
29 #include "pointer-set.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"
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. */
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. */
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. */
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. */
76 has_addr_references_p (struct cgraph_node
*node
,
77 void *data ATTRIBUTE_UNUSED
)
82 for (i
= 0; ipa_ref_list_referring_iterate (&node
->symbol
.ref_list
,
84 if (ref
->use
== IPA_REF_ADDR
)
89 /* Look for all functions inlined to NODE and update their inlined_to pointers
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
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)
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
))
123 node
->symbol
.aux
= *first
;
127 /* Process references. */
130 process_references (struct ipa_ref_list
*list
,
132 bool before_inlining_p
,
133 struct pointer_set_t
*reachable
)
137 for (i
= 0; ipa_ref_list_reference_iterate (list
, i
, ref
); i
++)
139 symtab_node node
= ref
->referred
;
141 if (node
->symbol
.definition
&& !node
->symbol
.in_other_partition
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
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
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. */
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
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
);
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_FUNCTION (node
)
239 node
->used_as_abstract_origin
= false;
240 if (node
->symbol
.definition
241 && !node
->global
.inlined_to
242 && !node
->symbol
.in_other_partition
243 && (!cgraph_can_remove_if_no_direct_calls_and_refs_p (node
)
244 /* Keep around virtual functions for possible devirtualization. */
245 || (before_inlining_p
246 && DECL_VIRTUAL_P (node
->symbol
.decl
))))
248 gcc_assert (!node
->global
.inlined_to
);
249 pointer_set_insert (reachable
, node
);
250 enqueue_node ((symtab_node
)node
, &first
, reachable
);
253 gcc_assert (!node
->symbol
.aux
);
256 /* Mark variables that are obviously needed. */
257 FOR_EACH_DEFINED_VARIABLE (vnode
)
258 if (!varpool_can_remove_if_no_refs (vnode
)
259 && !vnode
->symbol
.in_other_partition
)
261 pointer_set_insert (reachable
, vnode
);
262 enqueue_node ((symtab_node
)vnode
, &first
, reachable
);
265 /* Perform reachability analysis. */
266 while (first
!= (symtab_node
) (void *) 1)
268 bool in_boundary_p
= !pointer_set_contains (reachable
, first
);
269 symtab_node node
= first
;
271 first
= (symtab_node
)first
->symbol
.aux
;
273 /* If we are processing symbol in boundary, mark its AUX pointer for
274 possible later re-processing in enqueue_node. */
276 node
->symbol
.aux
= (void *)2;
279 if (DECL_ABSTRACT_ORIGIN (node
->symbol
.decl
))
281 struct cgraph_node
*origin_node
282 = cgraph_get_create_real_symbol_node (DECL_ABSTRACT_ORIGIN (node
->symbol
.decl
));
283 origin_node
->used_as_abstract_origin
= true;
284 enqueue_node ((symtab_node
) origin_node
, &first
, reachable
);
286 /* If any symbol in a comdat group is reachable, force
287 all other in the same comdat group to be also reachable. */
288 if (node
->symbol
.same_comdat_group
)
291 for (next
= node
->symbol
.same_comdat_group
;
293 next
= next
->symbol
.same_comdat_group
)
294 if (!pointer_set_insert (reachable
, next
))
295 enqueue_node ((symtab_node
) next
, &first
, reachable
);
297 /* Mark references as reachable. */
298 process_references (&node
->symbol
.ref_list
, &first
,
299 before_inlining_p
, reachable
);
302 if (cgraph_node
*cnode
= dyn_cast
<cgraph_node
> (node
))
304 /* Mark the callees reachable unless they are direct calls to extern
305 inline functions we decided to not inline. */
308 struct cgraph_edge
*e
;
309 for (e
= cnode
->callees
; e
; e
= e
->next_callee
)
311 if (e
->callee
->symbol
.definition
312 && !e
->callee
->symbol
.in_other_partition
313 && (!e
->inline_failed
314 || !DECL_EXTERNAL (e
->callee
->symbol
.decl
)
315 || e
->callee
->symbol
.alias
316 || before_inlining_p
))
317 pointer_set_insert (reachable
, e
->callee
);
318 enqueue_node ((symtab_node
) e
->callee
, &first
, reachable
);
321 /* When inline clone exists, mark body to be preserved so when removing
322 offline copy of the function we don't kill it. */
323 if (cnode
->global
.inlined_to
)
324 pointer_set_insert (body_needed_for_clonning
, cnode
->symbol
.decl
);
326 /* For non-inline clones, force their origins to the boundary and ensure
327 that body is not removed. */
328 while (cnode
->clone_of
)
330 bool noninline
= cnode
->clone_of
->symbol
.decl
!= cnode
->symbol
.decl
;
331 cnode
= cnode
->clone_of
;
334 pointer_set_insert (body_needed_for_clonning
, cnode
->symbol
.decl
);
335 enqueue_node ((symtab_node
)cnode
, &first
, reachable
);
340 /* When we see constructor of external variable, keep referred nodes in the
341 boundary. This will also hold initializers of the external vars NODE
343 varpool_node
*vnode
= dyn_cast
<varpool_node
> (node
);
345 && DECL_EXTERNAL (node
->symbol
.decl
)
346 && !vnode
->symbol
.alias
350 for (int i
= 0; ipa_ref_list_reference_iterate (&node
->symbol
.ref_list
, i
, ref
); i
++)
351 enqueue_node (ref
->referred
, &first
, reachable
);
355 /* Remove unreachable functions. */
356 for (node
= cgraph_first_function (); node
; node
= next
)
358 next
= cgraph_next_function (node
);
360 /* If node is not needed at all, remove it. */
361 if (!node
->symbol
.aux
)
364 fprintf (file
, " %s", cgraph_node_name (node
));
365 cgraph_remove_node (node
);
368 /* If node is unreachable, remove its body. */
369 else if (!pointer_set_contains (reachable
, node
))
371 if (!pointer_set_contains (body_needed_for_clonning
, node
->symbol
.decl
))
372 cgraph_release_function_body (node
);
373 else if (!node
->clone_of
)
374 gcc_assert (DECL_RESULT (node
->symbol
.decl
));
375 if (node
->symbol
.definition
)
378 fprintf (file
, " %s", cgraph_node_name (node
));
379 cgraph_reset_node (node
);
384 gcc_assert (node
->clone_of
|| !cgraph_function_with_gimple_body_p (node
)
385 || DECL_RESULT (node
->symbol
.decl
));
388 /* Inline clones might be kept around so their materializing allows further
389 cloning. If the function the clone is inlined into is removed, we need
390 to turn it into normal cone. */
391 FOR_EACH_FUNCTION (node
)
393 if (node
->global
.inlined_to
396 gcc_assert (node
->clones
);
397 node
->global
.inlined_to
= NULL
;
398 update_inlined_to_pointer (node
, node
);
400 node
->symbol
.aux
= NULL
;
403 /* Remove unreachable variables. */
405 fprintf (file
, "\nReclaiming variables:");
406 for (vnode
= varpool_first_variable (); vnode
; vnode
= vnext
)
408 vnext
= varpool_next_variable (vnode
);
409 if (!vnode
->symbol
.aux
410 /* For can_refer_decl_in_current_unit_p we want to track for
411 all external variables if they are defined in other partition
413 && (!flag_ltrans
|| !DECL_EXTERNAL (vnode
->symbol
.decl
)))
416 fprintf (file
, " %s", varpool_node_name (vnode
));
417 varpool_remove_node (vnode
);
420 else if (!pointer_set_contains (reachable
, vnode
))
423 if (vnode
->symbol
.definition
)
426 fprintf (file
, " %s", varpool_node_name (vnode
));
429 vnode
->symbol
.definition
= false;
430 vnode
->symbol
.analyzed
= false;
431 vnode
->symbol
.aux
= NULL
;
433 /* Keep body if it may be useful for constant folding. */
434 if ((init
= ctor_for_folding (vnode
->symbol
.decl
)) == error_mark_node
)
435 varpool_remove_initializer (vnode
);
437 DECL_INITIAL (vnode
->symbol
.decl
) = init
;
438 ipa_remove_all_references (&vnode
->symbol
.ref_list
);
441 vnode
->symbol
.aux
= NULL
;
444 pointer_set_destroy (reachable
);
445 pointer_set_destroy (body_needed_for_clonning
);
447 /* Now update address_taken flags and try to promote functions to be local. */
449 fprintf (file
, "\nClearing address taken flags:");
450 FOR_EACH_DEFINED_FUNCTION (node
)
451 if (node
->symbol
.address_taken
452 && !node
->symbol
.used_from_other_partition
)
454 if (!cgraph_for_node_and_aliases (node
, has_addr_references_p
, NULL
, true))
457 fprintf (file
, " %s", cgraph_node_name (node
));
458 node
->symbol
.address_taken
= false;
460 if (cgraph_local_node_p (node
))
462 node
->local
.local
= true;
464 fprintf (file
, " (local)");
469 fprintf (file
, "\n");
471 #ifdef ENABLE_CHECKING
475 /* If we removed something, perhaps profile could be improved. */
476 if (changed
&& optimize
&& inline_edge_summary_vec
.exists ())
477 FOR_EACH_DEFINED_FUNCTION (node
)
478 cgraph_propagate_frequency (node
);
483 /* Discover variables that have no longer address taken or that are read only
484 and update their flags.
486 FIXME: This can not be done in between gimplify and omp_expand since
487 readonly flag plays role on what is shared and what is not. Currently we do
488 this transformation as part of whole program visibility and re-do at
489 ipa-reference pass (to take into account clonning), but it would
490 make sense to do it before early optimizations. */
493 ipa_discover_readonly_nonaddressable_vars (void)
495 struct varpool_node
*vnode
;
497 fprintf (dump_file
, "Clearing variable flags:");
498 FOR_EACH_VARIABLE (vnode
)
499 if (vnode
->symbol
.definition
&& varpool_all_refs_explicit_p (vnode
)
500 && (TREE_ADDRESSABLE (vnode
->symbol
.decl
)
501 || !TREE_READONLY (vnode
->symbol
.decl
)))
503 bool written
= false;
504 bool address_taken
= false;
507 for (i
= 0; ipa_ref_list_referring_iterate (&vnode
->symbol
.ref_list
,
509 && (!written
|| !address_taken
); i
++)
513 address_taken
= true;
521 if (TREE_ADDRESSABLE (vnode
->symbol
.decl
) && !address_taken
)
524 fprintf (dump_file
, " %s (addressable)", varpool_node_name (vnode
));
525 TREE_ADDRESSABLE (vnode
->symbol
.decl
) = 0;
527 if (!TREE_READONLY (vnode
->symbol
.decl
) && !address_taken
&& !written
528 /* Making variable in explicit section readonly can cause section
530 See e.g. gcc.c-torture/compile/pr23237.c */
531 && DECL_SECTION_NAME (vnode
->symbol
.decl
) == NULL
)
534 fprintf (dump_file
, " %s (read-only)", varpool_node_name (vnode
));
535 TREE_READONLY (vnode
->symbol
.decl
) = 1;
539 fprintf (dump_file
, "\n");
542 /* Return true when there is a reference to node and it is not vtable. */
544 address_taken_from_non_vtable_p (symtab_node node
)
548 for (i
= 0; ipa_ref_list_referring_iterate (&node
->symbol
.ref_list
,
550 if (ref
->use
== IPA_REF_ADDR
)
552 struct varpool_node
*node
;
553 if (is_a
<cgraph_node
> (ref
->referring
))
555 node
= ipa_ref_referring_varpool_node (ref
);
556 if (!DECL_VIRTUAL_P (node
->symbol
.decl
))
562 /* A helper for comdat_can_be_unshared_p. */
565 comdat_can_be_unshared_p_1 (symtab_node node
)
567 /* When address is taken, we don't know if equality comparison won't
568 break eventually. Exception are virutal functions and vtables,
569 where this is not possible by language standard. */
570 if (!DECL_VIRTUAL_P (node
->symbol
.decl
)
571 && address_taken_from_non_vtable_p (node
))
574 /* If the symbol is used in some weird way, better to not touch it. */
575 if (node
->symbol
.force_output
)
578 /* Explicit instantiations needs to be output when possibly
580 if (node
->symbol
.forced_by_abi
581 && TREE_PUBLIC (node
->symbol
.decl
)
582 && (node
->symbol
.resolution
!= LDPR_PREVAILING_DEF_IRONLY
583 && !flag_whole_program
))
586 /* Non-readonly and volatile variables can not be duplicated. */
587 if (is_a
<varpool_node
> (node
)
588 && (!TREE_READONLY (node
->symbol
.decl
)
589 || TREE_THIS_VOLATILE (node
->symbol
.decl
)))
594 /* COMDAT functions must be shared only if they have address taken,
595 otherwise we can produce our own private implementation with
597 Return true when turning COMDAT functoin static can not lead to wrong
598 code when the resulting object links with a library defining same COMDAT.
600 Virtual functions do have their addresses taken from the vtables,
601 but in C++ there is no way to compare their addresses for equality. */
604 comdat_can_be_unshared_p (symtab_node node
)
606 if (!comdat_can_be_unshared_p_1 (node
))
608 if (node
->symbol
.same_comdat_group
)
612 /* If more than one function is in the same COMDAT group, it must
613 be shared even if just one function in the comdat group has
615 for (next
= node
->symbol
.same_comdat_group
;
616 next
!= node
; next
= next
->symbol
.same_comdat_group
)
617 if (!comdat_can_be_unshared_p_1 (next
))
623 /* Return true when function NODE should be considered externally visible. */
626 cgraph_externally_visible_p (struct cgraph_node
*node
,
629 if (!node
->symbol
.definition
)
631 if (!TREE_PUBLIC (node
->symbol
.decl
)
632 || DECL_EXTERNAL (node
->symbol
.decl
))
635 /* Do not try to localize built-in functions yet. One of problems is that we
636 end up mangling their asm for WHOPR that makes it impossible to call them
637 using the implicit built-in declarations anymore. Similarly this enables
638 us to remove them as unreachable before actual calls may appear during
639 expansion or folding. */
640 if (DECL_BUILT_IN (node
->symbol
.decl
))
643 /* If linker counts on us, we must preserve the function. */
644 if (symtab_used_from_object_file_p ((symtab_node
) node
))
646 if (DECL_PRESERVE_P (node
->symbol
.decl
))
648 if (lookup_attribute ("externally_visible",
649 DECL_ATTRIBUTES (node
->symbol
.decl
)))
651 if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
652 && lookup_attribute ("dllexport",
653 DECL_ATTRIBUTES (node
->symbol
.decl
)))
655 if (node
->symbol
.resolution
== LDPR_PREVAILING_DEF_IRONLY
)
657 /* When doing LTO or whole program, we can bring COMDAT functoins static.
658 This improves code quality and we know we will duplicate them at most twice
659 (in the case that we are not using plugin and link with object file
660 implementing same COMDAT) */
661 if ((in_lto_p
|| whole_program
)
662 && DECL_COMDAT (node
->symbol
.decl
)
663 && comdat_can_be_unshared_p ((symtab_node
) node
))
666 /* When doing link time optimizations, hidden symbols become local. */
668 && (DECL_VISIBILITY (node
->symbol
.decl
) == VISIBILITY_HIDDEN
669 || DECL_VISIBILITY (node
->symbol
.decl
) == VISIBILITY_INTERNAL
)
670 /* Be sure that node is defined in IR file, not in other object
671 file. In that case we don't set used_from_other_object_file. */
672 && node
->symbol
.definition
)
674 else if (!whole_program
)
677 if (MAIN_NAME_P (DECL_NAME (node
->symbol
.decl
)))
683 /* Return true when variable VNODE should be considered externally visible. */
686 varpool_externally_visible_p (struct varpool_node
*vnode
)
688 if (DECL_EXTERNAL (vnode
->symbol
.decl
))
691 if (!TREE_PUBLIC (vnode
->symbol
.decl
))
694 /* If linker counts on us, we must preserve the function. */
695 if (symtab_used_from_object_file_p ((symtab_node
) vnode
))
698 if (DECL_HARD_REGISTER (vnode
->symbol
.decl
))
700 if (DECL_PRESERVE_P (vnode
->symbol
.decl
))
702 if (lookup_attribute ("externally_visible",
703 DECL_ATTRIBUTES (vnode
->symbol
.decl
)))
705 if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
706 && lookup_attribute ("dllexport",
707 DECL_ATTRIBUTES (vnode
->symbol
.decl
)))
710 /* See if we have linker information about symbol not being used or
711 if we need to make guess based on the declaration.
713 Even if the linker clams the symbol is unused, never bring internal
714 symbols that are declared by user as used or externally visible.
715 This is needed for i.e. references from asm statements. */
716 if (symtab_used_from_object_file_p ((symtab_node
) vnode
))
718 if (vnode
->symbol
.resolution
== LDPR_PREVAILING_DEF_IRONLY
)
721 /* As a special case, the COMDAT virtual tables can be unshared.
722 In LTO mode turn vtables into static variables. The variable is readonly,
723 so this does not enable more optimization, but referring static var
724 is faster for dynamic linking. Also this match logic hidding vtables
725 from LTO symbol tables. */
726 if ((in_lto_p
|| flag_whole_program
)
727 && DECL_COMDAT (vnode
->symbol
.decl
)
728 && comdat_can_be_unshared_p ((symtab_node
) vnode
))
731 /* When doing link time optimizations, hidden symbols become local. */
733 && (DECL_VISIBILITY (vnode
->symbol
.decl
) == VISIBILITY_HIDDEN
734 || DECL_VISIBILITY (vnode
->symbol
.decl
) == VISIBILITY_INTERNAL
)
735 /* Be sure that node is defined in IR file, not in other object
736 file. In that case we don't set used_from_other_object_file. */
737 && vnode
->symbol
.definition
)
739 else if (!flag_whole_program
)
742 /* Do not attempt to privatize COMDATS by default.
743 This would break linking with C++ libraries sharing
746 FIXME: We can do so for readonly vars with no address taken and
747 possibly also for vtables since no direct pointer comparsion is done.
748 It might be interesting to do so to reduce linking overhead. */
749 if (DECL_COMDAT (vnode
->symbol
.decl
) || DECL_WEAK (vnode
->symbol
.decl
))
754 /* Return true if reference to NODE can be replaced by a local alias.
755 Local aliases save dynamic linking overhead and enable more optimizations.
759 can_replace_by_local_alias (symtab_node node
)
761 return (symtab_node_availability (node
) > AVAIL_OVERWRITABLE
762 && !DECL_EXTERNAL (node
->symbol
.decl
)
763 && (!DECL_ONE_ONLY (node
->symbol
.decl
)
764 || node
->symbol
.resolution
== LDPR_PREVAILING_DEF
765 || node
->symbol
.resolution
== LDPR_PREVAILING_DEF_IRONLY
766 || node
->symbol
.resolution
== LDPR_PREVAILING_DEF_IRONLY_EXP
));
769 /* Mark visibility of all functions.
771 A local function is one whose calls can occur only in the current
772 compilation unit and all its calls are explicit, so we can change
773 its calling convention. We simply mark all static functions whose
774 address is not taken as local.
776 We also change the TREE_PUBLIC flag of all declarations that are public
777 in language point of view but we want to overwrite this default
778 via visibilities for the backend point of view. */
781 function_and_variable_visibility (bool whole_program
)
783 struct cgraph_node
*node
;
784 struct varpool_node
*vnode
;
786 /* All aliases should be procssed at this point. */
787 gcc_checking_assert (!alias_pairs
|| !alias_pairs
->length());
789 FOR_EACH_FUNCTION (node
)
791 int flags
= flags_from_decl_or_type (node
->symbol
.decl
);
793 /* Optimize away PURE and CONST constructors and destructors. */
795 && (flags
& (ECF_CONST
| ECF_PURE
))
796 && !(flags
& ECF_LOOPING_CONST_OR_PURE
))
798 DECL_STATIC_CONSTRUCTOR (node
->symbol
.decl
) = 0;
799 DECL_STATIC_DESTRUCTOR (node
->symbol
.decl
) = 0;
802 /* Frontends and alias code marks nodes as needed before parsing is finished.
803 We may end up marking as node external nodes where this flag is meaningless
805 if (DECL_EXTERNAL (node
->symbol
.decl
) || !node
->symbol
.definition
)
807 node
->symbol
.force_output
= 0;
808 node
->symbol
.forced_by_abi
= 0;
811 /* C++ FE on lack of COMDAT support create local COMDAT functions
812 (that ought to be shared but can not due to object format
813 limitations). It is necessary to keep the flag to make rest of C++ FE
814 happy. Clear the flag here to avoid confusion in middle-end. */
815 if (DECL_COMDAT (node
->symbol
.decl
) && !TREE_PUBLIC (node
->symbol
.decl
))
816 DECL_COMDAT (node
->symbol
.decl
) = 0;
818 /* For external decls stop tracking same_comdat_group. It doesn't matter
819 what comdat group they are in when they won't be emitted in this TU. */
820 if (node
->symbol
.same_comdat_group
&& DECL_EXTERNAL (node
->symbol
.decl
))
822 #ifdef ENABLE_CHECKING
825 for (n
= node
->symbol
.same_comdat_group
;
826 n
!= (symtab_node
)node
;
827 n
= n
->symbol
.same_comdat_group
)
828 /* If at least one of same comdat group functions is external,
829 all of them have to be, otherwise it is a front-end bug. */
830 gcc_assert (DECL_EXTERNAL (n
->symbol
.decl
));
832 symtab_dissolve_same_comdat_group_list ((symtab_node
) node
);
834 gcc_assert ((!DECL_WEAK (node
->symbol
.decl
)
835 && !DECL_COMDAT (node
->symbol
.decl
))
836 || TREE_PUBLIC (node
->symbol
.decl
)
837 || node
->symbol
.weakref
838 || DECL_EXTERNAL (node
->symbol
.decl
));
839 if (cgraph_externally_visible_p (node
, whole_program
))
841 gcc_assert (!node
->global
.inlined_to
);
842 node
->symbol
.externally_visible
= true;
846 node
->symbol
.externally_visible
= false;
847 node
->symbol
.forced_by_abi
= false;
849 if (!node
->symbol
.externally_visible
850 && node
->symbol
.definition
&& !node
->symbol
.weakref
851 && !DECL_EXTERNAL (node
->symbol
.decl
))
853 gcc_assert (whole_program
|| in_lto_p
854 || !TREE_PUBLIC (node
->symbol
.decl
));
855 node
->symbol
.unique_name
= ((node
->symbol
.resolution
== LDPR_PREVAILING_DEF_IRONLY
856 || node
->symbol
.resolution
== LDPR_PREVAILING_DEF_IRONLY_EXP
)
857 && TREE_PUBLIC (node
->symbol
.decl
));
858 symtab_make_decl_local (node
->symbol
.decl
);
859 node
->symbol
.resolution
= LDPR_PREVAILING_DEF_IRONLY
;
860 if (node
->symbol
.same_comdat_group
)
861 /* cgraph_externally_visible_p has already checked all other nodes
862 in the group and they will all be made local. We need to
863 dissolve the group at once so that the predicate does not
865 symtab_dissolve_same_comdat_group_list ((symtab_node
) node
);
868 if (node
->thunk
.thunk_p
869 && TREE_PUBLIC (node
->symbol
.decl
))
871 struct cgraph_node
*decl_node
= node
;
873 decl_node
= cgraph_function_node (decl_node
->callees
->callee
, NULL
);
875 /* Thunks have the same visibility as function they are attached to.
876 Make sure the C++ front end set this up properly. */
877 if (DECL_ONE_ONLY (decl_node
->symbol
.decl
))
879 gcc_checking_assert (DECL_COMDAT (node
->symbol
.decl
)
880 == DECL_COMDAT (decl_node
->symbol
.decl
));
881 gcc_checking_assert (DECL_COMDAT_GROUP (node
->symbol
.decl
)
882 == DECL_COMDAT_GROUP (decl_node
->symbol
.decl
));
883 gcc_checking_assert (node
->symbol
.same_comdat_group
);
885 if (DECL_EXTERNAL (decl_node
->symbol
.decl
))
886 DECL_EXTERNAL (node
->symbol
.decl
) = 1;
889 FOR_EACH_DEFINED_FUNCTION (node
)
891 node
->local
.local
= cgraph_local_node_p (node
);
893 /* If we know that function can not be overwritten by a different semantics
894 and moreover its section can not be discarded, replace all direct calls
895 by calls to an nonoverwritable alias. This make dynamic linking
896 cheaper and enable more optimization.
898 TODO: We can also update virtual tables. */
899 if (node
->callers
&& can_replace_by_local_alias ((symtab_node
)node
))
901 struct cgraph_node
*alias
= cgraph (symtab_nonoverwritable_alias ((symtab_node
) node
));
905 while (node
->callers
)
907 struct cgraph_edge
*e
= node
->callers
;
909 cgraph_redirect_edge_callee (e
, alias
);
912 push_cfun (DECL_STRUCT_FUNCTION (e
->caller
->symbol
.decl
));
913 cgraph_redirect_edge_call_stmt_to_callee (e
);
920 FOR_EACH_VARIABLE (vnode
)
922 /* weak flag makes no sense on local variables. */
923 gcc_assert (!DECL_WEAK (vnode
->symbol
.decl
)
924 || vnode
->symbol
.weakref
925 || TREE_PUBLIC (vnode
->symbol
.decl
)
926 || DECL_EXTERNAL (vnode
->symbol
.decl
));
927 /* In several cases declarations can not be common:
929 - when declaration has initializer
931 - when it has specific section
932 - when it resides in non-generic address space.
933 - if declaration is local, it will get into .local common section
934 so common flag is not needed. Frontends still produce these in
935 certain cases, such as for:
937 static int a __attribute__ ((common))
939 Canonicalize things here and clear the redundant flag. */
940 if (DECL_COMMON (vnode
->symbol
.decl
)
941 && (!(TREE_PUBLIC (vnode
->symbol
.decl
)
942 || DECL_EXTERNAL (vnode
->symbol
.decl
))
943 || (DECL_INITIAL (vnode
->symbol
.decl
)
944 && DECL_INITIAL (vnode
->symbol
.decl
) != error_mark_node
)
945 || DECL_WEAK (vnode
->symbol
.decl
)
946 || DECL_SECTION_NAME (vnode
->symbol
.decl
) != NULL
947 || ! (ADDR_SPACE_GENERIC_P
948 (TYPE_ADDR_SPACE (TREE_TYPE (vnode
->symbol
.decl
))))))
949 DECL_COMMON (vnode
->symbol
.decl
) = 0;
951 FOR_EACH_DEFINED_VARIABLE (vnode
)
953 if (!vnode
->symbol
.definition
)
955 if (varpool_externally_visible_p (vnode
))
956 vnode
->symbol
.externally_visible
= true;
959 vnode
->symbol
.externally_visible
= false;
960 vnode
->symbol
.forced_by_abi
= false;
962 if (!vnode
->symbol
.externally_visible
963 && !vnode
->symbol
.weakref
)
965 gcc_assert (in_lto_p
|| whole_program
|| !TREE_PUBLIC (vnode
->symbol
.decl
));
966 symtab_make_decl_local (vnode
->symbol
.decl
);
967 vnode
->symbol
.unique_name
= ((vnode
->symbol
.resolution
== LDPR_PREVAILING_DEF_IRONLY
968 || vnode
->symbol
.resolution
== LDPR_PREVAILING_DEF_IRONLY_EXP
)
969 && TREE_PUBLIC (vnode
->symbol
.decl
));
970 if (vnode
->symbol
.same_comdat_group
)
971 symtab_dissolve_same_comdat_group_list ((symtab_node
) vnode
);
972 vnode
->symbol
.resolution
= LDPR_PREVAILING_DEF_IRONLY
;
978 fprintf (dump_file
, "\nMarking local functions:");
979 FOR_EACH_DEFINED_FUNCTION (node
)
980 if (node
->local
.local
)
981 fprintf (dump_file
, " %s", cgraph_node_name (node
));
982 fprintf (dump_file
, "\n\n");
983 fprintf (dump_file
, "\nMarking externally visible functions:");
984 FOR_EACH_DEFINED_FUNCTION (node
)
985 if (node
->symbol
.externally_visible
)
986 fprintf (dump_file
, " %s", cgraph_node_name (node
));
987 fprintf (dump_file
, "\n\n");
988 fprintf (dump_file
, "\nMarking externally visible variables:");
989 FOR_EACH_DEFINED_VARIABLE (vnode
)
990 if (vnode
->symbol
.externally_visible
)
991 fprintf (dump_file
, " %s", varpool_node_name (vnode
));
992 fprintf (dump_file
, "\n\n");
994 cgraph_function_flags_ready
= true;
998 /* Local function pass handling visibilities. This happens before LTO streaming
999 so in particular -fwhole-program should be ignored at this level. */
1002 local_function_and_variable_visibility (void)
1004 return function_and_variable_visibility (flag_whole_program
&& !flag_lto
);
1007 struct simple_ipa_opt_pass pass_ipa_function_and_variable_visibility
=
1011 "visibility", /* name */
1012 OPTGROUP_NONE
, /* optinfo_flags */
1014 local_function_and_variable_visibility
,/* execute */
1017 0, /* static_pass_number */
1018 TV_CGRAPHOPT
, /* tv_id */
1019 0, /* properties_required */
1020 0, /* properties_provided */
1021 0, /* properties_destroyed */
1022 0, /* todo_flags_start */
1023 TODO_remove_functions
| TODO_dump_symtab
/* todo_flags_finish */
1027 /* Free inline summary. */
1030 free_inline_summary (void)
1032 inline_free_summary ();
1036 struct simple_ipa_opt_pass pass_ipa_free_inline_summary
=
1040 "*free_inline_summary", /* name */
1041 OPTGROUP_NONE
, /* optinfo_flags */
1043 free_inline_summary
, /* execute */
1046 0, /* static_pass_number */
1047 TV_IPA_FREE_INLINE_SUMMARY
, /* tv_id */
1048 0, /* properties_required */
1049 0, /* properties_provided */
1050 0, /* properties_destroyed */
1051 0, /* todo_flags_start */
1052 0 /* todo_flags_finish */
1056 /* Do not re-run on ltrans stage. */
1059 gate_whole_program_function_and_variable_visibility (void)
1061 return !flag_ltrans
;
1064 /* Bring functionss local at LTO time with -fwhole-program. */
1067 whole_program_function_and_variable_visibility (void)
1069 function_and_variable_visibility (flag_whole_program
);
1071 ipa_discover_readonly_nonaddressable_vars ();
1075 struct ipa_opt_pass_d pass_ipa_whole_program_visibility
=
1079 "whole-program", /* name */
1080 OPTGROUP_NONE
, /* optinfo_flags */
1081 gate_whole_program_function_and_variable_visibility
,/* gate */
1082 whole_program_function_and_variable_visibility
,/* execute */
1085 0, /* static_pass_number */
1086 TV_CGRAPHOPT
, /* tv_id */
1087 0, /* properties_required */
1088 0, /* properties_provided */
1089 0, /* properties_destroyed */
1090 0, /* todo_flags_start */
1091 TODO_remove_functions
| TODO_dump_symtab
/* todo_flags_finish */
1093 NULL
, /* generate_summary */
1094 NULL
, /* write_summary */
1095 NULL
, /* read_summary */
1096 NULL
, /* write_optimization_summary */
1097 NULL
, /* read_optimization_summary */
1098 NULL
, /* stmt_fixup */
1100 NULL
, /* function_transform */
1101 NULL
, /* variable_transform */
1104 /* Entry in the histogram. */
1106 struct histogram_entry
1113 /* Histogram of profile values.
1114 The histogram is represented as an ordered vector of entries allocated via
1115 histogram_pool. During construction a separate hashtable is kept to lookup
1116 duplicate entries. */
1118 vec
<histogram_entry
*> histogram
;
1119 static alloc_pool histogram_pool
;
1121 /* Hashtable support for storing SSA names hashed by their SSA_NAME_VAR. */
1123 struct histogram_hash
: typed_noop_remove
<histogram_entry
>
1125 typedef histogram_entry value_type
;
1126 typedef histogram_entry compare_type
;
1127 static inline hashval_t
hash (const value_type
*);
1128 static inline int equal (const value_type
*, const compare_type
*);
1132 histogram_hash::hash (const histogram_entry
*val
)
1138 histogram_hash::equal (const histogram_entry
*val
, const histogram_entry
*val2
)
1140 return val
->count
== val2
->count
;
1143 /* Account TIME and SIZE executed COUNT times into HISTOGRAM.
1144 HASHTABLE is the on-side hash kept to avoid duplicates. */
1147 account_time_size (hash_table
<histogram_hash
> hashtable
,
1148 vec
<histogram_entry
*> &histogram
,
1149 gcov_type count
, int time
, int size
)
1151 histogram_entry key
= {count
, 0, 0};
1152 histogram_entry
**val
= hashtable
.find_slot (&key
, INSERT
);
1156 *val
= (histogram_entry
*) pool_alloc (histogram_pool
);
1158 histogram
.safe_push (*val
);
1160 (*val
)->time
+= time
;
1161 (*val
)->size
+= size
;
1165 cmp_counts (const void *v1
, const void *v2
)
1167 const histogram_entry
*h1
= *(const histogram_entry
* const *)v1
;
1168 const histogram_entry
*h2
= *(const histogram_entry
* const *)v2
;
1169 if (h1
->count
< h2
->count
)
1171 if (h1
->count
> h2
->count
)
1176 /* Dump HISTOGRAM to FILE. */
1179 dump_histogram (FILE *file
, vec
<histogram_entry
*> histogram
)
1182 gcov_type overall_time
= 0, cumulated_time
= 0, cumulated_size
= 0, overall_size
= 0;
1184 fprintf (dump_file
, "Histogram:\n");
1185 for (i
= 0; i
< histogram
.length (); i
++)
1187 overall_time
+= histogram
[i
]->count
* histogram
[i
]->time
;
1188 overall_size
+= histogram
[i
]->size
;
1194 for (i
= 0; i
< histogram
.length (); i
++)
1196 cumulated_time
+= histogram
[i
]->count
* histogram
[i
]->time
;
1197 cumulated_size
+= histogram
[i
]->size
;
1198 fprintf (file
, " "HOST_WIDEST_INT_PRINT_DEC
": time:%i (%2.2f) size:%i (%2.2f)\n",
1199 (HOST_WIDEST_INT
) histogram
[i
]->count
,
1201 cumulated_time
* 100.0 / overall_time
,
1203 cumulated_size
* 100.0 / overall_size
);
1207 /* Collect histogram from CFG profiles. */
1210 ipa_profile_generate_summary (void)
1212 struct cgraph_node
*node
;
1213 gimple_stmt_iterator gsi
;
1214 hash_table
<histogram_hash
> hashtable
;
1217 hashtable
.create (10);
1218 histogram_pool
= create_alloc_pool ("IPA histogram", sizeof (struct histogram_entry
),
1221 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node
)
1222 FOR_EACH_BB_FN (bb
, DECL_STRUCT_FUNCTION (node
->symbol
.decl
))
1226 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
1228 time
+= estimate_num_insns (gsi_stmt (gsi
), &eni_time_weights
);
1229 size
+= estimate_num_insns (gsi_stmt (gsi
), &eni_size_weights
);
1231 account_time_size (hashtable
, histogram
, bb
->count
, time
, size
);
1233 hashtable
.dispose ();
1234 histogram
.qsort (cmp_counts
);
1237 /* Serialize the ipa info for lto. */
1240 ipa_profile_write_summary (void)
1242 struct lto_simple_output_block
*ob
1243 = lto_create_simple_output_block (LTO_section_ipa_profile
);
1246 streamer_write_uhwi_stream (ob
->main_stream
, histogram
.length());
1247 for (i
= 0; i
< histogram
.length (); i
++)
1249 streamer_write_gcov_count_stream (ob
->main_stream
, histogram
[i
]->count
);
1250 streamer_write_uhwi_stream (ob
->main_stream
, histogram
[i
]->time
);
1251 streamer_write_uhwi_stream (ob
->main_stream
, histogram
[i
]->size
);
1253 lto_destroy_simple_output_block (ob
);
1256 /* Deserialize the ipa info for lto. */
1259 ipa_profile_read_summary (void)
1261 struct lto_file_decl_data
** file_data_vec
1262 = lto_get_file_decl_data ();
1263 struct lto_file_decl_data
* file_data
;
1264 hash_table
<histogram_hash
> hashtable
;
1267 hashtable
.create (10);
1268 histogram_pool
= create_alloc_pool ("IPA histogram", sizeof (struct histogram_entry
),
1271 while ((file_data
= file_data_vec
[j
++]))
1275 struct lto_input_block
*ib
1276 = lto_create_simple_input_block (file_data
,
1277 LTO_section_ipa_profile
,
1281 unsigned int num
= streamer_read_uhwi (ib
);
1283 for (n
= 0; n
< num
; n
++)
1285 gcov_type count
= streamer_read_gcov_count (ib
);
1286 int time
= streamer_read_uhwi (ib
);
1287 int size
= streamer_read_uhwi (ib
);
1288 account_time_size (hashtable
, histogram
,
1291 lto_destroy_simple_input_block (file_data
,
1292 LTO_section_ipa_profile
,
1296 hashtable
.dispose ();
1297 histogram
.qsort (cmp_counts
);
1300 /* Simple ipa profile pass propagating frequencies across the callgraph. */
1305 struct cgraph_node
**order
= XCNEWVEC (struct cgraph_node
*, cgraph_n_nodes
);
1306 struct cgraph_edge
*e
;
1308 bool something_changed
= false;
1310 gcov_type overall_time
= 0, cutoff
= 0, cumulated
= 0, overall_size
= 0;
1313 dump_histogram (dump_file
, histogram
);
1314 for (i
= 0; i
< (int)histogram
.length (); i
++)
1316 overall_time
+= histogram
[i
]->count
* histogram
[i
]->time
;
1317 overall_size
+= histogram
[i
]->size
;
1321 gcov_type threshold
;
1323 gcc_assert (overall_size
);
1326 gcov_type min
, cumulated_time
= 0, cumulated_size
= 0;
1328 fprintf (dump_file
, "Overall time: "HOST_WIDEST_INT_PRINT_DEC
"\n",
1329 (HOST_WIDEST_INT
)overall_time
);
1330 min
= get_hot_bb_threshold ();
1331 for (i
= 0; i
< (int)histogram
.length () && histogram
[i
]->count
>= min
;
1334 cumulated_time
+= histogram
[i
]->count
* histogram
[i
]->time
;
1335 cumulated_size
+= histogram
[i
]->size
;
1337 fprintf (dump_file
, "GCOV min count: "HOST_WIDEST_INT_PRINT_DEC
1338 " Time:%3.2f%% Size:%3.2f%%\n",
1339 (HOST_WIDEST_INT
)min
,
1340 cumulated_time
* 100.0 / overall_time
,
1341 cumulated_size
* 100.0 / overall_size
);
1343 cutoff
= (overall_time
* PARAM_VALUE (HOT_BB_COUNT_WS_PERMILLE
) + 500) / 1000;
1345 for (i
= 0; cumulated
< cutoff
; i
++)
1347 cumulated
+= histogram
[i
]->count
* histogram
[i
]->time
;
1348 threshold
= histogram
[i
]->count
;
1354 gcov_type cumulated_time
= 0, cumulated_size
= 0;
1357 i
< (int)histogram
.length () && histogram
[i
]->count
>= threshold
;
1360 cumulated_time
+= histogram
[i
]->count
* histogram
[i
]->time
;
1361 cumulated_size
+= histogram
[i
]->size
;
1363 fprintf (dump_file
, "Determined min count: "HOST_WIDEST_INT_PRINT_DEC
1364 " Time:%3.2f%% Size:%3.2f%%\n",
1365 (HOST_WIDEST_INT
)threshold
,
1366 cumulated_time
* 100.0 / overall_time
,
1367 cumulated_size
* 100.0 / overall_size
);
1369 if (threshold
> get_hot_bb_threshold ()
1373 fprintf (dump_file
, "Threshold updated.\n");
1374 set_hot_bb_threshold (threshold
);
1377 histogram
.release();
1378 free_alloc_pool (histogram_pool
);
1380 order_pos
= ipa_reverse_postorder (order
);
1381 for (i
= order_pos
- 1; i
>= 0; i
--)
1383 if (order
[i
]->local
.local
&& cgraph_propagate_frequency (order
[i
]))
1385 for (e
= order
[i
]->callees
; e
; e
= e
->next_callee
)
1386 if (e
->callee
->local
.local
&& !e
->callee
->symbol
.aux
)
1388 something_changed
= true;
1389 e
->callee
->symbol
.aux
= (void *)1;
1392 order
[i
]->symbol
.aux
= NULL
;
1395 while (something_changed
)
1397 something_changed
= false;
1398 for (i
= order_pos
- 1; i
>= 0; i
--)
1400 if (order
[i
]->symbol
.aux
&& cgraph_propagate_frequency (order
[i
]))
1402 for (e
= order
[i
]->callees
; e
; e
= e
->next_callee
)
1403 if (e
->callee
->local
.local
&& !e
->callee
->symbol
.aux
)
1405 something_changed
= true;
1406 e
->callee
->symbol
.aux
= (void *)1;
1409 order
[i
]->symbol
.aux
= NULL
;
1417 gate_ipa_profile (void)
1419 return flag_ipa_profile
;
1422 struct ipa_opt_pass_d pass_ipa_profile
=
1426 "profile_estimate", /* name */
1427 OPTGROUP_NONE
, /* optinfo_flags */
1428 gate_ipa_profile
, /* gate */
1429 ipa_profile
, /* execute */
1432 0, /* static_pass_number */
1433 TV_IPA_PROFILE
, /* tv_id */
1434 0, /* properties_required */
1435 0, /* properties_provided */
1436 0, /* properties_destroyed */
1437 0, /* todo_flags_start */
1438 0 /* todo_flags_finish */
1440 ipa_profile_generate_summary
, /* generate_summary */
1441 ipa_profile_write_summary
, /* write_summary */
1442 ipa_profile_read_summary
, /* read_summary */
1443 NULL
, /* write_optimization_summary */
1444 NULL
, /* read_optimization_summary */
1445 NULL
, /* stmt_fixup */
1447 NULL
, /* function_transform */
1448 NULL
/* variable_transform */
1451 /* Generate and emit a static constructor or destructor. WHICH must
1452 be one of 'I' (for a constructor) or 'D' (for a destructor). BODY
1453 is a STATEMENT_LIST containing GENERIC statements. PRIORITY is the
1454 initialization priority for this constructor or destructor.
1456 FINAL specify whether the externally visible name for collect2 should
1460 cgraph_build_static_cdtor_1 (char which
, tree body
, int priority
, bool final
)
1462 static int counter
= 0;
1464 tree decl
, name
, resdecl
;
1466 /* The priority is encoded in the constructor or destructor name.
1467 collect2 will sort the names and arrange that they are called at
1470 sprintf (which_buf
, "%c_%.5d_%d", which
, priority
, counter
++);
1472 /* Proudce sane name but one not recognizable by collect2, just for the
1473 case we fail to inline the function. */
1474 sprintf (which_buf
, "sub_%c_%.5d_%d", which
, priority
, counter
++);
1475 name
= get_file_function_name (which_buf
);
1477 decl
= build_decl (input_location
, FUNCTION_DECL
, name
,
1478 build_function_type_list (void_type_node
, NULL_TREE
));
1479 current_function_decl
= decl
;
1481 resdecl
= build_decl (input_location
,
1482 RESULT_DECL
, NULL_TREE
, void_type_node
);
1483 DECL_ARTIFICIAL (resdecl
) = 1;
1484 DECL_RESULT (decl
) = resdecl
;
1485 DECL_CONTEXT (resdecl
) = decl
;
1487 allocate_struct_function (decl
, false);
1489 TREE_STATIC (decl
) = 1;
1490 TREE_USED (decl
) = 1;
1491 DECL_ARTIFICIAL (decl
) = 1;
1492 DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl
) = 1;
1493 DECL_SAVED_TREE (decl
) = body
;
1494 if (!targetm
.have_ctors_dtors
&& final
)
1496 TREE_PUBLIC (decl
) = 1;
1497 DECL_PRESERVE_P (decl
) = 1;
1499 DECL_UNINLINABLE (decl
) = 1;
1501 DECL_INITIAL (decl
) = make_node (BLOCK
);
1502 TREE_USED (DECL_INITIAL (decl
)) = 1;
1504 DECL_SOURCE_LOCATION (decl
) = input_location
;
1505 cfun
->function_end_locus
= input_location
;
1510 DECL_STATIC_CONSTRUCTOR (decl
) = 1;
1511 decl_init_priority_insert (decl
, priority
);
1514 DECL_STATIC_DESTRUCTOR (decl
) = 1;
1515 decl_fini_priority_insert (decl
, priority
);
1521 gimplify_function_tree (decl
);
1523 cgraph_add_new_function (decl
, false);
1526 current_function_decl
= NULL
;
1529 /* Generate and emit a static constructor or destructor. WHICH must
1530 be one of 'I' (for a constructor) or 'D' (for a destructor). BODY
1531 is a STATEMENT_LIST containing GENERIC statements. PRIORITY is the
1532 initialization priority for this constructor or destructor. */
1535 cgraph_build_static_cdtor (char which
, tree body
, int priority
)
1537 cgraph_build_static_cdtor_1 (which
, body
, priority
, false);
1540 /* A vector of FUNCTION_DECLs declared as static constructors. */
1541 static vec
<tree
> static_ctors
;
1542 /* A vector of FUNCTION_DECLs declared as static destructors. */
1543 static vec
<tree
> static_dtors
;
1545 /* When target does not have ctors and dtors, we call all constructor
1546 and destructor by special initialization/destruction function
1547 recognized by collect2.
1549 When we are going to build this function, collect all constructors and
1550 destructors and turn them into normal functions. */
1553 record_cdtor_fn (struct cgraph_node
*node
)
1555 if (DECL_STATIC_CONSTRUCTOR (node
->symbol
.decl
))
1556 static_ctors
.safe_push (node
->symbol
.decl
);
1557 if (DECL_STATIC_DESTRUCTOR (node
->symbol
.decl
))
1558 static_dtors
.safe_push (node
->symbol
.decl
);
1559 node
= cgraph_get_node (node
->symbol
.decl
);
1560 DECL_DISREGARD_INLINE_LIMITS (node
->symbol
.decl
) = 1;
1563 /* Define global constructors/destructor functions for the CDTORS, of
1564 which they are LEN. The CDTORS are sorted by initialization
1565 priority. If CTOR_P is true, these are constructors; otherwise,
1566 they are destructors. */
1569 build_cdtor (bool ctor_p
, vec
<tree
> cdtors
)
1572 size_t len
= cdtors
.length ();
1579 priority_type priority
;
1588 p
= ctor_p
? DECL_INIT_PRIORITY (fn
) : DECL_FINI_PRIORITY (fn
);
1591 else if (p
!= priority
)
1597 /* When there is only one cdtor and target supports them, do nothing. */
1599 && targetm
.have_ctors_dtors
)
1604 /* Find the next batch of constructors/destructors with the same
1605 initialization priority. */
1610 call
= build_call_expr (fn
, 0);
1612 DECL_STATIC_CONSTRUCTOR (fn
) = 0;
1614 DECL_STATIC_DESTRUCTOR (fn
) = 0;
1615 /* We do not want to optimize away pure/const calls here.
1616 When optimizing, these should be already removed, when not
1617 optimizing, we want user to be able to breakpoint in them. */
1618 TREE_SIDE_EFFECTS (call
) = 1;
1619 append_to_statement_list (call
, &body
);
1621 gcc_assert (body
!= NULL_TREE
);
1622 /* Generate a function to call all the function of like
1624 cgraph_build_static_cdtor_1 (ctor_p
? 'I' : 'D', body
, priority
, true);
1628 /* Comparison function for qsort. P1 and P2 are actually of type
1629 "tree *" and point to static constructors. DECL_INIT_PRIORITY is
1630 used to determine the sort order. */
1633 compare_ctor (const void *p1
, const void *p2
)
1640 f1
= *(const tree
*)p1
;
1641 f2
= *(const tree
*)p2
;
1642 priority1
= DECL_INIT_PRIORITY (f1
);
1643 priority2
= DECL_INIT_PRIORITY (f2
);
1645 if (priority1
< priority2
)
1647 else if (priority1
> priority2
)
1650 /* Ensure a stable sort. Constructors are executed in backwarding
1651 order to make LTO initialize braries first. */
1652 return DECL_UID (f2
) - DECL_UID (f1
);
1655 /* Comparison function for qsort. P1 and P2 are actually of type
1656 "tree *" and point to static destructors. DECL_FINI_PRIORITY is
1657 used to determine the sort order. */
1660 compare_dtor (const void *p1
, const void *p2
)
1667 f1
= *(const tree
*)p1
;
1668 f2
= *(const tree
*)p2
;
1669 priority1
= DECL_FINI_PRIORITY (f1
);
1670 priority2
= DECL_FINI_PRIORITY (f2
);
1672 if (priority1
< priority2
)
1674 else if (priority1
> priority2
)
1677 /* Ensure a stable sort. */
1678 return DECL_UID (f1
) - DECL_UID (f2
);
1681 /* Generate functions to call static constructors and destructors
1682 for targets that do not support .ctors/.dtors sections. These
1683 functions have magic names which are detected by collect2. */
1686 build_cdtor_fns (void)
1688 if (!static_ctors
.is_empty ())
1690 gcc_assert (!targetm
.have_ctors_dtors
|| in_lto_p
);
1691 static_ctors
.qsort (compare_ctor
);
1692 build_cdtor (/*ctor_p=*/true, static_ctors
);
1695 if (!static_dtors
.is_empty ())
1697 gcc_assert (!targetm
.have_ctors_dtors
|| in_lto_p
);
1698 static_dtors
.qsort (compare_dtor
);
1699 build_cdtor (/*ctor_p=*/false, static_dtors
);
1703 /* Look for constructors and destructors and produce function calling them.
1704 This is needed for targets not supporting ctors or dtors, but we perform the
1705 transformation also at linktime to merge possibly numerous
1706 constructors/destructors into single function to improve code locality and
1710 ipa_cdtor_merge (void)
1712 struct cgraph_node
*node
;
1713 FOR_EACH_DEFINED_FUNCTION (node
)
1714 if (DECL_STATIC_CONSTRUCTOR (node
->symbol
.decl
)
1715 || DECL_STATIC_DESTRUCTOR (node
->symbol
.decl
))
1716 record_cdtor_fn (node
);
1718 static_ctors
.release ();
1719 static_dtors
.release ();
1723 /* Perform the pass when we have no ctors/dtors support
1724 or at LTO time to merge multiple constructors into single
1728 gate_ipa_cdtor_merge (void)
1730 return !targetm
.have_ctors_dtors
|| (optimize
&& in_lto_p
);
1733 struct ipa_opt_pass_d pass_ipa_cdtor_merge
=
1738 OPTGROUP_NONE
, /* optinfo_flags */
1739 gate_ipa_cdtor_merge
, /* gate */
1740 ipa_cdtor_merge
, /* execute */
1743 0, /* static_pass_number */
1744 TV_CGRAPHOPT
, /* tv_id */
1745 0, /* properties_required */
1746 0, /* properties_provided */
1747 0, /* properties_destroyed */
1748 0, /* todo_flags_start */
1749 0 /* todo_flags_finish */
1751 NULL
, /* generate_summary */
1752 NULL
, /* write_summary */
1753 NULL
, /* read_summary */
1754 NULL
, /* write_optimization_summary */
1755 NULL
, /* read_optimization_summary */
1756 NULL
, /* stmt_fixup */
1758 NULL
, /* function_transform */
1759 NULL
/* variable_transform */