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 && (!cgraph_can_remove_if_no_direct_calls_and_refs_p (node
)
243 /* Keep around virtual functions for possible devirtualization. */
244 || (before_inlining_p
245 && DECL_VIRTUAL_P (node
->symbol
.decl
))))
247 gcc_assert (!node
->global
.inlined_to
);
248 pointer_set_insert (reachable
, node
);
249 enqueue_node ((symtab_node
)node
, &first
, reachable
);
252 gcc_assert (!node
->symbol
.aux
);
255 /* Mark variables that are obviously needed. */
256 FOR_EACH_DEFINED_VARIABLE (vnode
)
257 if (!varpool_can_remove_if_no_refs (vnode
)
258 && !vnode
->symbol
.in_other_partition
)
260 pointer_set_insert (reachable
, vnode
);
261 enqueue_node ((symtab_node
)vnode
, &first
, reachable
);
264 /* Perform reachability analysis. */
265 while (first
!= (symtab_node
) (void *) 1)
267 bool in_boundary_p
= !pointer_set_contains (reachable
, first
);
268 symtab_node node
= first
;
270 first
= (symtab_node
)first
->symbol
.aux
;
272 /* If we are processing symbol in boundary, mark its AUX pointer for
273 possible later re-processing in enqueue_node. */
275 node
->symbol
.aux
= (void *)2;
278 if (DECL_ABSTRACT_ORIGIN (node
->symbol
.decl
))
280 struct cgraph_node
*origin_node
281 = cgraph_get_create_real_symbol_node (DECL_ABSTRACT_ORIGIN (node
->symbol
.decl
));
282 origin_node
->used_as_abstract_origin
= true;
283 enqueue_node ((symtab_node
) origin_node
, &first
, reachable
);
285 /* If any symbol in a comdat group is reachable, force
286 all other in the same comdat group to be also reachable. */
287 if (node
->symbol
.same_comdat_group
)
290 for (next
= node
->symbol
.same_comdat_group
;
292 next
= next
->symbol
.same_comdat_group
)
293 if (!pointer_set_insert (reachable
, next
))
294 enqueue_node ((symtab_node
) next
, &first
, reachable
);
296 /* Mark references as reachable. */
297 process_references (&node
->symbol
.ref_list
, &first
,
298 before_inlining_p
, reachable
);
301 if (cgraph_node
*cnode
= dyn_cast
<cgraph_node
> (node
))
303 /* Mark the callees reachable unless they are direct calls to extern
304 inline functions we decided to not inline. */
307 struct cgraph_edge
*e
;
308 for (e
= cnode
->callees
; e
; e
= e
->next_callee
)
310 if (e
->callee
->symbol
.definition
311 && !e
->callee
->symbol
.in_other_partition
312 && (!e
->inline_failed
313 || !DECL_EXTERNAL (e
->callee
->symbol
.decl
)
314 || e
->callee
->symbol
.alias
315 || before_inlining_p
))
316 pointer_set_insert (reachable
, e
->callee
);
317 enqueue_node ((symtab_node
) e
->callee
, &first
, reachable
);
320 /* When inline clone exists, mark body to be preserved so when removing
321 offline copy of the function we don't kill it. */
322 if (cnode
->global
.inlined_to
)
323 pointer_set_insert (body_needed_for_clonning
, cnode
->symbol
.decl
);
325 /* For non-inline clones, force their origins to the boundary and ensure
326 that body is not removed. */
327 while (cnode
->clone_of
)
329 bool noninline
= cnode
->clone_of
->symbol
.decl
!= cnode
->symbol
.decl
;
330 cnode
= cnode
->clone_of
;
333 pointer_set_insert (body_needed_for_clonning
, cnode
->symbol
.decl
);
334 enqueue_node ((symtab_node
)cnode
, &first
, reachable
);
339 /* When we see constructor of external variable, keep referred nodes in the
340 boundary. This will also hold initializers of the external vars NODE
342 varpool_node
*vnode
= dyn_cast
<varpool_node
> (node
);
344 && DECL_EXTERNAL (node
->symbol
.decl
)
345 && !vnode
->symbol
.alias
349 for (int i
= 0; ipa_ref_list_reference_iterate (&node
->symbol
.ref_list
, i
, ref
); i
++)
350 enqueue_node (ref
->referred
, &first
, reachable
);
354 /* Remove unreachable functions. */
355 for (node
= cgraph_first_function (); node
; node
= next
)
357 next
= cgraph_next_function (node
);
359 /* If node is not needed at all, remove it. */
360 if (!node
->symbol
.aux
)
363 fprintf (file
, " %s", cgraph_node_name (node
));
364 cgraph_remove_node (node
);
367 /* If node is unreachable, remove its body. */
368 else if (!pointer_set_contains (reachable
, node
))
370 if (!pointer_set_contains (body_needed_for_clonning
, node
->symbol
.decl
))
371 cgraph_release_function_body (node
);
372 else if (!node
->clone_of
)
373 gcc_assert (DECL_RESULT (node
->symbol
.decl
));
374 if (node
->symbol
.definition
)
377 fprintf (file
, " %s", cgraph_node_name (node
));
378 cgraph_reset_node (node
);
383 gcc_assert (node
->clone_of
|| !cgraph_function_with_gimple_body_p (node
)
384 || DECL_RESULT (node
->symbol
.decl
));
387 /* Inline clones might be kept around so their materializing allows further
388 cloning. If the function the clone is inlined into is removed, we need
389 to turn it into normal cone. */
390 FOR_EACH_FUNCTION (node
)
392 if (node
->global
.inlined_to
395 gcc_assert (node
->clones
);
396 node
->global
.inlined_to
= NULL
;
397 update_inlined_to_pointer (node
, node
);
399 node
->symbol
.aux
= NULL
;
402 /* Remove unreachable variables. */
404 fprintf (file
, "\nReclaiming variables:");
405 for (vnode
= varpool_first_variable (); vnode
; vnode
= vnext
)
407 vnext
= varpool_next_variable (vnode
);
408 if (!vnode
->symbol
.aux
409 /* For can_refer_decl_in_current_unit_p we want to track for
410 all external variables if they are defined in other partition
412 && (!flag_ltrans
|| !DECL_EXTERNAL (vnode
->symbol
.decl
)))
415 fprintf (file
, " %s", varpool_node_name (vnode
));
416 varpool_remove_node (vnode
);
419 else if (!pointer_set_contains (reachable
, vnode
))
422 if (vnode
->symbol
.definition
)
425 fprintf (file
, " %s", varpool_node_name (vnode
));
428 vnode
->symbol
.definition
= false;
429 vnode
->symbol
.analyzed
= false;
430 vnode
->symbol
.aux
= NULL
;
432 /* Keep body if it may be useful for constant folding. */
433 if ((init
= ctor_for_folding (vnode
->symbol
.decl
)) == error_mark_node
)
434 varpool_remove_initializer (vnode
);
436 DECL_INITIAL (vnode
->symbol
.decl
) = init
;
437 ipa_remove_all_references (&vnode
->symbol
.ref_list
);
440 vnode
->symbol
.aux
= NULL
;
443 pointer_set_destroy (reachable
);
444 pointer_set_destroy (body_needed_for_clonning
);
446 /* Now update address_taken flags and try to promote functions to be local. */
448 fprintf (file
, "\nClearing address taken flags:");
449 FOR_EACH_DEFINED_FUNCTION (node
)
450 if (node
->symbol
.address_taken
451 && !node
->symbol
.used_from_other_partition
)
453 if (!cgraph_for_node_and_aliases (node
, has_addr_references_p
, NULL
, true))
456 fprintf (file
, " %s", cgraph_node_name (node
));
457 node
->symbol
.address_taken
= false;
459 if (cgraph_local_node_p (node
))
461 node
->local
.local
= true;
463 fprintf (file
, " (local)");
468 fprintf (file
, "\n");
470 #ifdef ENABLE_CHECKING
474 /* If we removed something, perhaps profile could be improved. */
475 if (changed
&& optimize
&& inline_edge_summary_vec
.exists ())
476 FOR_EACH_DEFINED_FUNCTION (node
)
477 cgraph_propagate_frequency (node
);
482 /* Discover variables that have no longer address taken or that are read only
483 and update their flags.
485 FIXME: This can not be done in between gimplify and omp_expand since
486 readonly flag plays role on what is shared and what is not. Currently we do
487 this transformation as part of whole program visibility and re-do at
488 ipa-reference pass (to take into account clonning), but it would
489 make sense to do it before early optimizations. */
492 ipa_discover_readonly_nonaddressable_vars (void)
494 struct varpool_node
*vnode
;
496 fprintf (dump_file
, "Clearing variable flags:");
497 FOR_EACH_VARIABLE (vnode
)
498 if (vnode
->symbol
.definition
&& varpool_all_refs_explicit_p (vnode
)
499 && (TREE_ADDRESSABLE (vnode
->symbol
.decl
)
500 || !TREE_READONLY (vnode
->symbol
.decl
)))
502 bool written
= false;
503 bool address_taken
= false;
506 for (i
= 0; ipa_ref_list_referring_iterate (&vnode
->symbol
.ref_list
,
508 && (!written
|| !address_taken
); i
++)
512 address_taken
= true;
520 if (TREE_ADDRESSABLE (vnode
->symbol
.decl
) && !address_taken
)
523 fprintf (dump_file
, " %s (addressable)", varpool_node_name (vnode
));
524 TREE_ADDRESSABLE (vnode
->symbol
.decl
) = 0;
526 if (!TREE_READONLY (vnode
->symbol
.decl
) && !address_taken
&& !written
527 /* Making variable in explicit section readonly can cause section
529 See e.g. gcc.c-torture/compile/pr23237.c */
530 && DECL_SECTION_NAME (vnode
->symbol
.decl
) == NULL
)
533 fprintf (dump_file
, " %s (read-only)", varpool_node_name (vnode
));
534 TREE_READONLY (vnode
->symbol
.decl
) = 1;
538 fprintf (dump_file
, "\n");
541 /* Return true when there is a reference to node and it is not vtable. */
543 address_taken_from_non_vtable_p (symtab_node node
)
547 for (i
= 0; ipa_ref_list_referring_iterate (&node
->symbol
.ref_list
,
549 if (ref
->use
== IPA_REF_ADDR
)
551 struct varpool_node
*node
;
552 if (is_a
<cgraph_node
> (ref
->referring
))
554 node
= ipa_ref_referring_varpool_node (ref
);
555 if (!DECL_VIRTUAL_P (node
->symbol
.decl
))
561 /* A helper for comdat_can_be_unshared_p. */
564 comdat_can_be_unshared_p_1 (symtab_node node
)
566 /* When address is taken, we don't know if equality comparison won't
567 break eventually. Exception are virutal functions and vtables,
568 where this is not possible by language standard. */
569 if (!DECL_VIRTUAL_P (node
->symbol
.decl
)
570 && address_taken_from_non_vtable_p (node
))
573 /* If the symbol is used in some weird way, better to not touch it. */
574 if (node
->symbol
.force_output
)
577 /* Explicit instantiations needs to be output when possibly
579 if (node
->symbol
.forced_by_abi
580 && TREE_PUBLIC (node
->symbol
.decl
)
581 && (node
->symbol
.resolution
!= LDPR_PREVAILING_DEF_IRONLY
582 && !flag_whole_program
))
585 /* Non-readonly and volatile variables can not be duplicated. */
586 if (is_a
<varpool_node
> (node
)
587 && (!TREE_READONLY (node
->symbol
.decl
)
588 || TREE_THIS_VOLATILE (node
->symbol
.decl
)))
593 /* COMDAT functions must be shared only if they have address taken,
594 otherwise we can produce our own private implementation with
596 Return true when turning COMDAT functoin static can not lead to wrong
597 code when the resulting object links with a library defining same COMDAT.
599 Virtual functions do have their addresses taken from the vtables,
600 but in C++ there is no way to compare their addresses for equality. */
603 comdat_can_be_unshared_p (symtab_node node
)
605 if (!comdat_can_be_unshared_p_1 (node
))
607 if (node
->symbol
.same_comdat_group
)
611 /* If more than one function is in the same COMDAT group, it must
612 be shared even if just one function in the comdat group has
614 for (next
= node
->symbol
.same_comdat_group
;
615 next
!= node
; next
= next
->symbol
.same_comdat_group
)
616 if (!comdat_can_be_unshared_p_1 (next
))
622 /* Return true when function NODE should be considered externally visible. */
625 cgraph_externally_visible_p (struct cgraph_node
*node
,
628 if (!node
->symbol
.definition
)
630 if (!TREE_PUBLIC (node
->symbol
.decl
)
631 || DECL_EXTERNAL (node
->symbol
.decl
))
634 /* Do not try to localize built-in functions yet. One of problems is that we
635 end up mangling their asm for WHOPR that makes it impossible to call them
636 using the implicit built-in declarations anymore. Similarly this enables
637 us to remove them as unreachable before actual calls may appear during
638 expansion or folding. */
639 if (DECL_BUILT_IN (node
->symbol
.decl
))
642 /* If linker counts on us, we must preserve the function. */
643 if (symtab_used_from_object_file_p ((symtab_node
) node
))
645 if (DECL_PRESERVE_P (node
->symbol
.decl
))
647 if (lookup_attribute ("externally_visible",
648 DECL_ATTRIBUTES (node
->symbol
.decl
)))
650 if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
651 && lookup_attribute ("dllexport",
652 DECL_ATTRIBUTES (node
->symbol
.decl
)))
654 if (node
->symbol
.resolution
== LDPR_PREVAILING_DEF_IRONLY
)
656 /* When doing LTO or whole program, we can bring COMDAT functoins static.
657 This improves code quality and we know we will duplicate them at most twice
658 (in the case that we are not using plugin and link with object file
659 implementing same COMDAT) */
660 if ((in_lto_p
|| whole_program
)
661 && DECL_COMDAT (node
->symbol
.decl
)
662 && comdat_can_be_unshared_p ((symtab_node
) node
))
665 /* When doing link time optimizations, hidden symbols become local. */
667 && (DECL_VISIBILITY (node
->symbol
.decl
) == VISIBILITY_HIDDEN
668 || DECL_VISIBILITY (node
->symbol
.decl
) == VISIBILITY_INTERNAL
)
669 /* Be sure that node is defined in IR file, not in other object
670 file. In that case we don't set used_from_other_object_file. */
671 && node
->symbol
.definition
)
673 else if (!whole_program
)
676 if (MAIN_NAME_P (DECL_NAME (node
->symbol
.decl
)))
682 /* Return true when variable VNODE should be considered externally visible. */
685 varpool_externally_visible_p (struct varpool_node
*vnode
)
687 if (DECL_EXTERNAL (vnode
->symbol
.decl
))
690 if (!TREE_PUBLIC (vnode
->symbol
.decl
))
693 /* If linker counts on us, we must preserve the function. */
694 if (symtab_used_from_object_file_p ((symtab_node
) vnode
))
697 if (DECL_HARD_REGISTER (vnode
->symbol
.decl
))
699 if (DECL_PRESERVE_P (vnode
->symbol
.decl
))
701 if (lookup_attribute ("externally_visible",
702 DECL_ATTRIBUTES (vnode
->symbol
.decl
)))
704 if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
705 && lookup_attribute ("dllexport",
706 DECL_ATTRIBUTES (vnode
->symbol
.decl
)))
709 /* See if we have linker information about symbol not being used or
710 if we need to make guess based on the declaration.
712 Even if the linker clams the symbol is unused, never bring internal
713 symbols that are declared by user as used or externally visible.
714 This is needed for i.e. references from asm statements. */
715 if (symtab_used_from_object_file_p ((symtab_node
) vnode
))
717 if (vnode
->symbol
.resolution
== LDPR_PREVAILING_DEF_IRONLY
)
720 /* As a special case, the COMDAT virtual tables can be unshared.
721 In LTO mode turn vtables into static variables. The variable is readonly,
722 so this does not enable more optimization, but referring static var
723 is faster for dynamic linking. Also this match logic hidding vtables
724 from LTO symbol tables. */
725 if ((in_lto_p
|| flag_whole_program
)
726 && DECL_COMDAT (vnode
->symbol
.decl
)
727 && comdat_can_be_unshared_p ((symtab_node
) vnode
))
730 /* When doing link time optimizations, hidden symbols become local. */
732 && (DECL_VISIBILITY (vnode
->symbol
.decl
) == VISIBILITY_HIDDEN
733 || DECL_VISIBILITY (vnode
->symbol
.decl
) == VISIBILITY_INTERNAL
)
734 /* Be sure that node is defined in IR file, not in other object
735 file. In that case we don't set used_from_other_object_file. */
736 && vnode
->symbol
.definition
)
738 else if (!flag_whole_program
)
741 /* Do not attempt to privatize COMDATS by default.
742 This would break linking with C++ libraries sharing
745 FIXME: We can do so for readonly vars with no address taken and
746 possibly also for vtables since no direct pointer comparsion is done.
747 It might be interesting to do so to reduce linking overhead. */
748 if (DECL_COMDAT (vnode
->symbol
.decl
) || DECL_WEAK (vnode
->symbol
.decl
))
753 /* Mark visibility of all functions.
755 A local function is one whose calls can occur only in the current
756 compilation unit and all its calls are explicit, so we can change
757 its calling convention. We simply mark all static functions whose
758 address is not taken as local.
760 We also change the TREE_PUBLIC flag of all declarations that are public
761 in language point of view but we want to overwrite this default
762 via visibilities for the backend point of view. */
765 function_and_variable_visibility (bool whole_program
)
767 struct cgraph_node
*node
;
768 struct varpool_node
*vnode
;
770 /* All aliases should be procssed at this point. */
771 gcc_checking_assert (!alias_pairs
|| !alias_pairs
->length());
773 FOR_EACH_FUNCTION (node
)
775 int flags
= flags_from_decl_or_type (node
->symbol
.decl
);
777 /* Optimize away PURE and CONST constructors and destructors. */
779 && (flags
& (ECF_CONST
| ECF_PURE
))
780 && !(flags
& ECF_LOOPING_CONST_OR_PURE
))
782 DECL_STATIC_CONSTRUCTOR (node
->symbol
.decl
) = 0;
783 DECL_STATIC_DESTRUCTOR (node
->symbol
.decl
) = 0;
786 /* Frontends and alias code marks nodes as needed before parsing is finished.
787 We may end up marking as node external nodes where this flag is meaningless
789 if (DECL_EXTERNAL (node
->symbol
.decl
) || !node
->symbol
.definition
)
791 node
->symbol
.force_output
= 0;
792 node
->symbol
.forced_by_abi
= 0;
795 /* C++ FE on lack of COMDAT support create local COMDAT functions
796 (that ought to be shared but can not due to object format
797 limitations). It is necessary to keep the flag to make rest of C++ FE
798 happy. Clear the flag here to avoid confusion in middle-end. */
799 if (DECL_COMDAT (node
->symbol
.decl
) && !TREE_PUBLIC (node
->symbol
.decl
))
800 DECL_COMDAT (node
->symbol
.decl
) = 0;
802 /* For external decls stop tracking same_comdat_group. It doesn't matter
803 what comdat group they are in when they won't be emitted in this TU. */
804 if (node
->symbol
.same_comdat_group
&& DECL_EXTERNAL (node
->symbol
.decl
))
806 #ifdef ENABLE_CHECKING
809 for (n
= node
->symbol
.same_comdat_group
;
810 n
!= (symtab_node
)node
;
811 n
= n
->symbol
.same_comdat_group
)
812 /* If at least one of same comdat group functions is external,
813 all of them have to be, otherwise it is a front-end bug. */
814 gcc_assert (DECL_EXTERNAL (n
->symbol
.decl
));
816 symtab_dissolve_same_comdat_group_list ((symtab_node
) node
);
818 gcc_assert ((!DECL_WEAK (node
->symbol
.decl
)
819 && !DECL_COMDAT (node
->symbol
.decl
))
820 || TREE_PUBLIC (node
->symbol
.decl
)
821 || node
->symbol
.weakref
822 || DECL_EXTERNAL (node
->symbol
.decl
));
823 if (cgraph_externally_visible_p (node
, whole_program
))
825 gcc_assert (!node
->global
.inlined_to
);
826 node
->symbol
.externally_visible
= true;
830 node
->symbol
.externally_visible
= false;
831 node
->symbol
.forced_by_abi
= false;
833 if (!node
->symbol
.externally_visible
834 && node
->symbol
.definition
&& !node
->symbol
.weakref
835 && !DECL_EXTERNAL (node
->symbol
.decl
))
837 gcc_assert (whole_program
|| in_lto_p
838 || !TREE_PUBLIC (node
->symbol
.decl
));
839 node
->symbol
.unique_name
= ((node
->symbol
.resolution
== LDPR_PREVAILING_DEF_IRONLY
840 || node
->symbol
.resolution
== LDPR_PREVAILING_DEF_IRONLY_EXP
)
841 && TREE_PUBLIC (node
->symbol
.decl
));
842 symtab_make_decl_local (node
->symbol
.decl
);
843 node
->symbol
.resolution
= LDPR_PREVAILING_DEF_IRONLY
;
844 if (node
->symbol
.same_comdat_group
)
845 /* cgraph_externally_visible_p has already checked all other nodes
846 in the group and they will all be made local. We need to
847 dissolve the group at once so that the predicate does not
849 symtab_dissolve_same_comdat_group_list ((symtab_node
) node
);
852 if (node
->thunk
.thunk_p
853 && TREE_PUBLIC (node
->symbol
.decl
))
855 struct cgraph_node
*decl_node
= node
;
857 decl_node
= cgraph_function_node (decl_node
->callees
->callee
, NULL
);
859 /* Thunks have the same visibility as function they are attached to.
860 Make sure the C++ front end set this up properly. */
861 if (DECL_ONE_ONLY (decl_node
->symbol
.decl
))
863 gcc_checking_assert (DECL_COMDAT (node
->symbol
.decl
)
864 == DECL_COMDAT (decl_node
->symbol
.decl
));
865 gcc_checking_assert (DECL_COMDAT_GROUP (node
->symbol
.decl
)
866 == DECL_COMDAT_GROUP (decl_node
->symbol
.decl
));
867 gcc_checking_assert (node
->symbol
.same_comdat_group
);
869 if (DECL_EXTERNAL (decl_node
->symbol
.decl
))
870 DECL_EXTERNAL (node
->symbol
.decl
) = 1;
873 FOR_EACH_DEFINED_FUNCTION (node
)
874 node
->local
.local
= cgraph_local_node_p (node
);
875 FOR_EACH_VARIABLE (vnode
)
877 /* weak flag makes no sense on local variables. */
878 gcc_assert (!DECL_WEAK (vnode
->symbol
.decl
)
879 || vnode
->symbol
.weakref
880 || TREE_PUBLIC (vnode
->symbol
.decl
)
881 || DECL_EXTERNAL (vnode
->symbol
.decl
));
882 /* In several cases declarations can not be common:
884 - when declaration has initializer
886 - when it has specific section
887 - when it resides in non-generic address space.
888 - if declaration is local, it will get into .local common section
889 so common flag is not needed. Frontends still produce these in
890 certain cases, such as for:
892 static int a __attribute__ ((common))
894 Canonicalize things here and clear the redundant flag. */
895 if (DECL_COMMON (vnode
->symbol
.decl
)
896 && (!(TREE_PUBLIC (vnode
->symbol
.decl
)
897 || DECL_EXTERNAL (vnode
->symbol
.decl
))
898 || (DECL_INITIAL (vnode
->symbol
.decl
)
899 && DECL_INITIAL (vnode
->symbol
.decl
) != error_mark_node
)
900 || DECL_WEAK (vnode
->symbol
.decl
)
901 || DECL_SECTION_NAME (vnode
->symbol
.decl
) != NULL
902 || ! (ADDR_SPACE_GENERIC_P
903 (TYPE_ADDR_SPACE (TREE_TYPE (vnode
->symbol
.decl
))))))
904 DECL_COMMON (vnode
->symbol
.decl
) = 0;
906 FOR_EACH_DEFINED_VARIABLE (vnode
)
908 if (!vnode
->symbol
.definition
)
910 if (varpool_externally_visible_p (vnode
))
911 vnode
->symbol
.externally_visible
= true;
914 vnode
->symbol
.externally_visible
= false;
915 vnode
->symbol
.forced_by_abi
= false;
917 if (!vnode
->symbol
.externally_visible
918 && !vnode
->symbol
.weakref
)
920 gcc_assert (in_lto_p
|| whole_program
|| !TREE_PUBLIC (vnode
->symbol
.decl
));
921 symtab_make_decl_local (vnode
->symbol
.decl
);
922 vnode
->symbol
.unique_name
= ((vnode
->symbol
.resolution
== LDPR_PREVAILING_DEF_IRONLY
923 || vnode
->symbol
.resolution
== LDPR_PREVAILING_DEF_IRONLY_EXP
)
924 && TREE_PUBLIC (vnode
->symbol
.decl
));
925 if (vnode
->symbol
.same_comdat_group
)
926 symtab_dissolve_same_comdat_group_list ((symtab_node
) vnode
);
927 vnode
->symbol
.resolution
= LDPR_PREVAILING_DEF_IRONLY
;
933 fprintf (dump_file
, "\nMarking local functions:");
934 FOR_EACH_DEFINED_FUNCTION (node
)
935 if (node
->local
.local
)
936 fprintf (dump_file
, " %s", cgraph_node_name (node
));
937 fprintf (dump_file
, "\n\n");
938 fprintf (dump_file
, "\nMarking externally visible functions:");
939 FOR_EACH_DEFINED_FUNCTION (node
)
940 if (node
->symbol
.externally_visible
)
941 fprintf (dump_file
, " %s", cgraph_node_name (node
));
942 fprintf (dump_file
, "\n\n");
943 fprintf (dump_file
, "\nMarking externally visible variables:");
944 FOR_EACH_DEFINED_VARIABLE (vnode
)
945 if (vnode
->symbol
.externally_visible
)
946 fprintf (dump_file
, " %s", varpool_node_name (vnode
));
947 fprintf (dump_file
, "\n\n");
949 cgraph_function_flags_ready
= true;
953 /* Local function pass handling visibilities. This happens before LTO streaming
954 so in particular -fwhole-program should be ignored at this level. */
957 local_function_and_variable_visibility (void)
959 return function_and_variable_visibility (flag_whole_program
&& !flag_lto
);
962 struct simple_ipa_opt_pass pass_ipa_function_and_variable_visibility
=
966 "visibility", /* name */
967 OPTGROUP_NONE
, /* optinfo_flags */
969 local_function_and_variable_visibility
,/* execute */
972 0, /* static_pass_number */
973 TV_CGRAPHOPT
, /* tv_id */
974 0, /* properties_required */
975 0, /* properties_provided */
976 0, /* properties_destroyed */
977 0, /* todo_flags_start */
978 TODO_remove_functions
| TODO_dump_symtab
/* todo_flags_finish */
982 /* Free inline summary. */
985 free_inline_summary (void)
987 inline_free_summary ();
991 struct simple_ipa_opt_pass pass_ipa_free_inline_summary
=
995 "*free_inline_summary", /* name */
996 OPTGROUP_NONE
, /* optinfo_flags */
998 free_inline_summary
, /* execute */
1001 0, /* static_pass_number */
1002 TV_IPA_FREE_INLINE_SUMMARY
, /* tv_id */
1003 0, /* properties_required */
1004 0, /* properties_provided */
1005 0, /* properties_destroyed */
1006 0, /* todo_flags_start */
1007 0 /* todo_flags_finish */
1011 /* Do not re-run on ltrans stage. */
1014 gate_whole_program_function_and_variable_visibility (void)
1016 return !flag_ltrans
;
1019 /* Bring functionss local at LTO time with -fwhole-program. */
1022 whole_program_function_and_variable_visibility (void)
1024 function_and_variable_visibility (flag_whole_program
);
1026 ipa_discover_readonly_nonaddressable_vars ();
1030 struct ipa_opt_pass_d pass_ipa_whole_program_visibility
=
1034 "whole-program", /* name */
1035 OPTGROUP_NONE
, /* optinfo_flags */
1036 gate_whole_program_function_and_variable_visibility
,/* gate */
1037 whole_program_function_and_variable_visibility
,/* execute */
1040 0, /* static_pass_number */
1041 TV_CGRAPHOPT
, /* tv_id */
1042 0, /* properties_required */
1043 0, /* properties_provided */
1044 0, /* properties_destroyed */
1045 0, /* todo_flags_start */
1046 TODO_remove_functions
| TODO_dump_symtab
/* todo_flags_finish */
1048 NULL
, /* generate_summary */
1049 NULL
, /* write_summary */
1050 NULL
, /* read_summary */
1051 NULL
, /* write_optimization_summary */
1052 NULL
, /* read_optimization_summary */
1053 NULL
, /* stmt_fixup */
1055 NULL
, /* function_transform */
1056 NULL
, /* variable_transform */
1059 /* Entry in the histogram. */
1061 struct histogram_entry
1068 /* Histogram of profile values.
1069 The histogram is represented as an ordered vector of entries allocated via
1070 histogram_pool. During construction a separate hashtable is kept to lookup
1071 duplicate entries. */
1073 vec
<histogram_entry
*> histogram
;
1074 static alloc_pool histogram_pool
;
1076 /* Hashtable support for storing SSA names hashed by their SSA_NAME_VAR. */
1078 struct histogram_hash
: typed_noop_remove
<histogram_entry
>
1080 typedef histogram_entry value_type
;
1081 typedef histogram_entry compare_type
;
1082 static inline hashval_t
hash (const value_type
*);
1083 static inline int equal (const value_type
*, const compare_type
*);
1087 histogram_hash::hash (const histogram_entry
*val
)
1093 histogram_hash::equal (const histogram_entry
*val
, const histogram_entry
*val2
)
1095 return val
->count
== val2
->count
;
1098 /* Account TIME and SIZE executed COUNT times into HISTOGRAM.
1099 HASHTABLE is the on-side hash kept to avoid duplicates. */
1102 account_time_size (hash_table
<histogram_hash
> hashtable
,
1103 vec
<histogram_entry
*> &histogram
,
1104 gcov_type count
, int time
, int size
)
1106 histogram_entry key
= {count
, 0, 0};
1107 histogram_entry
**val
= hashtable
.find_slot (&key
, INSERT
);
1111 *val
= (histogram_entry
*) pool_alloc (histogram_pool
);
1113 histogram
.safe_push (*val
);
1115 (*val
)->time
+= time
;
1116 (*val
)->size
+= size
;
1120 cmp_counts (const void *v1
, const void *v2
)
1122 const histogram_entry
*h1
= *(const histogram_entry
* const *)v1
;
1123 const histogram_entry
*h2
= *(const histogram_entry
* const *)v2
;
1124 if (h1
->count
< h2
->count
)
1126 if (h1
->count
> h2
->count
)
1131 /* Dump HISTOGRAM to FILE. */
1134 dump_histogram (FILE *file
, vec
<histogram_entry
*> histogram
)
1137 gcov_type overall_time
= 0, cumulated_time
= 0, cumulated_size
= 0, overall_size
= 0;
1139 fprintf (dump_file
, "Histogram:\n");
1140 for (i
= 0; i
< histogram
.length (); i
++)
1142 overall_time
+= histogram
[i
]->count
* histogram
[i
]->time
;
1143 overall_size
+= histogram
[i
]->size
;
1149 for (i
= 0; i
< histogram
.length (); i
++)
1151 cumulated_time
+= histogram
[i
]->count
* histogram
[i
]->time
;
1152 cumulated_size
+= histogram
[i
]->size
;
1153 fprintf (file
, " "HOST_WIDEST_INT_PRINT_DEC
": time:%i (%2.2f) size:%i (%2.2f)\n",
1154 (HOST_WIDEST_INT
) histogram
[i
]->count
,
1156 cumulated_time
* 100.0 / overall_time
,
1158 cumulated_size
* 100.0 / overall_size
);
1162 /* Collect histogram from CFG profiles. */
1165 ipa_profile_generate_summary (void)
1167 struct cgraph_node
*node
;
1168 gimple_stmt_iterator gsi
;
1169 hash_table
<histogram_hash
> hashtable
;
1172 hashtable
.create (10);
1173 histogram_pool
= create_alloc_pool ("IPA histogram", sizeof (struct histogram_entry
),
1176 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node
)
1177 FOR_EACH_BB_FN (bb
, DECL_STRUCT_FUNCTION (node
->symbol
.decl
))
1181 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
1183 time
+= estimate_num_insns (gsi_stmt (gsi
), &eni_time_weights
);
1184 size
+= estimate_num_insns (gsi_stmt (gsi
), &eni_size_weights
);
1186 account_time_size (hashtable
, histogram
, bb
->count
, time
, size
);
1188 hashtable
.dispose ();
1189 histogram
.qsort (cmp_counts
);
1192 /* Serialize the ipa info for lto. */
1195 ipa_profile_write_summary (void)
1197 struct lto_simple_output_block
*ob
1198 = lto_create_simple_output_block (LTO_section_ipa_profile
);
1201 streamer_write_uhwi_stream (ob
->main_stream
, histogram
.length());
1202 for (i
= 0; i
< histogram
.length (); i
++)
1204 streamer_write_gcov_count_stream (ob
->main_stream
, histogram
[i
]->count
);
1205 streamer_write_uhwi_stream (ob
->main_stream
, histogram
[i
]->time
);
1206 streamer_write_uhwi_stream (ob
->main_stream
, histogram
[i
]->size
);
1208 lto_destroy_simple_output_block (ob
);
1211 /* Deserialize the ipa info for lto. */
1214 ipa_profile_read_summary (void)
1216 struct lto_file_decl_data
** file_data_vec
1217 = lto_get_file_decl_data ();
1218 struct lto_file_decl_data
* file_data
;
1219 hash_table
<histogram_hash
> hashtable
;
1222 hashtable
.create (10);
1223 histogram_pool
= create_alloc_pool ("IPA histogram", sizeof (struct histogram_entry
),
1226 while ((file_data
= file_data_vec
[j
++]))
1230 struct lto_input_block
*ib
1231 = lto_create_simple_input_block (file_data
,
1232 LTO_section_ipa_profile
,
1236 unsigned int num
= streamer_read_uhwi (ib
);
1238 for (n
= 0; n
< num
; n
++)
1240 gcov_type count
= streamer_read_gcov_count (ib
);
1241 int time
= streamer_read_uhwi (ib
);
1242 int size
= streamer_read_uhwi (ib
);
1243 account_time_size (hashtable
, histogram
,
1246 lto_destroy_simple_input_block (file_data
,
1247 LTO_section_ipa_profile
,
1251 hashtable
.dispose ();
1252 histogram
.qsort (cmp_counts
);
1255 /* Simple ipa profile pass propagating frequencies across the callgraph. */
1260 struct cgraph_node
**order
= XCNEWVEC (struct cgraph_node
*, cgraph_n_nodes
);
1261 struct cgraph_edge
*e
;
1263 bool something_changed
= false;
1265 gcov_type overall_time
= 0, cutoff
= 0, cumulated
= 0, overall_size
= 0;
1268 dump_histogram (dump_file
, histogram
);
1269 for (i
= 0; i
< (int)histogram
.length (); i
++)
1271 overall_time
+= histogram
[i
]->count
* histogram
[i
]->time
;
1272 overall_size
+= histogram
[i
]->size
;
1276 gcov_type threshold
;
1278 gcc_assert (overall_size
);
1281 gcov_type min
, cumulated_time
= 0, cumulated_size
= 0;
1283 fprintf (dump_file
, "Overall time: "HOST_WIDEST_INT_PRINT_DEC
"\n",
1284 (HOST_WIDEST_INT
)overall_time
);
1285 min
= get_hot_bb_threshold ();
1286 for (i
= 0; i
< (int)histogram
.length () && histogram
[i
]->count
>= min
;
1289 cumulated_time
+= histogram
[i
]->count
* histogram
[i
]->time
;
1290 cumulated_size
+= histogram
[i
]->size
;
1292 fprintf (dump_file
, "GCOV min count: "HOST_WIDEST_INT_PRINT_DEC
1293 " Time:%3.2f%% Size:%3.2f%%\n",
1294 (HOST_WIDEST_INT
)min
,
1295 cumulated_time
* 100.0 / overall_time
,
1296 cumulated_size
* 100.0 / overall_size
);
1298 cutoff
= (overall_time
* PARAM_VALUE (HOT_BB_COUNT_WS_PERMILLE
) + 500) / 1000;
1300 for (i
= 0; cumulated
< cutoff
; i
++)
1302 cumulated
+= histogram
[i
]->count
* histogram
[i
]->time
;
1303 threshold
= histogram
[i
]->count
;
1309 gcov_type cumulated_time
= 0, cumulated_size
= 0;
1312 i
< (int)histogram
.length () && histogram
[i
]->count
>= threshold
;
1315 cumulated_time
+= histogram
[i
]->count
* histogram
[i
]->time
;
1316 cumulated_size
+= histogram
[i
]->size
;
1318 fprintf (dump_file
, "Determined min count: "HOST_WIDEST_INT_PRINT_DEC
1319 " Time:%3.2f%% Size:%3.2f%%\n",
1320 (HOST_WIDEST_INT
)threshold
,
1321 cumulated_time
* 100.0 / overall_time
,
1322 cumulated_size
* 100.0 / overall_size
);
1324 if (threshold
> get_hot_bb_threshold ()
1328 fprintf (dump_file
, "Threshold updated.\n");
1329 set_hot_bb_threshold (threshold
);
1332 histogram
.release();
1333 free_alloc_pool (histogram_pool
);
1335 order_pos
= ipa_reverse_postorder (order
);
1336 for (i
= order_pos
- 1; i
>= 0; i
--)
1338 if (order
[i
]->local
.local
&& cgraph_propagate_frequency (order
[i
]))
1340 for (e
= order
[i
]->callees
; e
; e
= e
->next_callee
)
1341 if (e
->callee
->local
.local
&& !e
->callee
->symbol
.aux
)
1343 something_changed
= true;
1344 e
->callee
->symbol
.aux
= (void *)1;
1347 order
[i
]->symbol
.aux
= NULL
;
1350 while (something_changed
)
1352 something_changed
= false;
1353 for (i
= order_pos
- 1; i
>= 0; i
--)
1355 if (order
[i
]->symbol
.aux
&& cgraph_propagate_frequency (order
[i
]))
1357 for (e
= order
[i
]->callees
; e
; e
= e
->next_callee
)
1358 if (e
->callee
->local
.local
&& !e
->callee
->symbol
.aux
)
1360 something_changed
= true;
1361 e
->callee
->symbol
.aux
= (void *)1;
1364 order
[i
]->symbol
.aux
= NULL
;
1372 gate_ipa_profile (void)
1374 return flag_ipa_profile
;
1377 struct ipa_opt_pass_d pass_ipa_profile
=
1381 "profile_estimate", /* name */
1382 OPTGROUP_NONE
, /* optinfo_flags */
1383 gate_ipa_profile
, /* gate */
1384 ipa_profile
, /* execute */
1387 0, /* static_pass_number */
1388 TV_IPA_PROFILE
, /* tv_id */
1389 0, /* properties_required */
1390 0, /* properties_provided */
1391 0, /* properties_destroyed */
1392 0, /* todo_flags_start */
1393 0 /* todo_flags_finish */
1395 ipa_profile_generate_summary
, /* generate_summary */
1396 ipa_profile_write_summary
, /* write_summary */
1397 ipa_profile_read_summary
, /* read_summary */
1398 NULL
, /* write_optimization_summary */
1399 NULL
, /* read_optimization_summary */
1400 NULL
, /* stmt_fixup */
1402 NULL
, /* function_transform */
1403 NULL
/* variable_transform */
1406 /* Generate and emit a static constructor or destructor. WHICH must
1407 be one of 'I' (for a constructor) or 'D' (for a destructor). BODY
1408 is a STATEMENT_LIST containing GENERIC statements. PRIORITY is the
1409 initialization priority for this constructor or destructor.
1411 FINAL specify whether the externally visible name for collect2 should
1415 cgraph_build_static_cdtor_1 (char which
, tree body
, int priority
, bool final
)
1417 static int counter
= 0;
1419 tree decl
, name
, resdecl
;
1421 /* The priority is encoded in the constructor or destructor name.
1422 collect2 will sort the names and arrange that they are called at
1425 sprintf (which_buf
, "%c_%.5d_%d", which
, priority
, counter
++);
1427 /* Proudce sane name but one not recognizable by collect2, just for the
1428 case we fail to inline the function. */
1429 sprintf (which_buf
, "sub_%c_%.5d_%d", which
, priority
, counter
++);
1430 name
= get_file_function_name (which_buf
);
1432 decl
= build_decl (input_location
, FUNCTION_DECL
, name
,
1433 build_function_type_list (void_type_node
, NULL_TREE
));
1434 current_function_decl
= decl
;
1436 resdecl
= build_decl (input_location
,
1437 RESULT_DECL
, NULL_TREE
, void_type_node
);
1438 DECL_ARTIFICIAL (resdecl
) = 1;
1439 DECL_RESULT (decl
) = resdecl
;
1440 DECL_CONTEXT (resdecl
) = decl
;
1442 allocate_struct_function (decl
, false);
1444 TREE_STATIC (decl
) = 1;
1445 TREE_USED (decl
) = 1;
1446 DECL_ARTIFICIAL (decl
) = 1;
1447 DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl
) = 1;
1448 DECL_SAVED_TREE (decl
) = body
;
1449 if (!targetm
.have_ctors_dtors
&& final
)
1451 TREE_PUBLIC (decl
) = 1;
1452 DECL_PRESERVE_P (decl
) = 1;
1454 DECL_UNINLINABLE (decl
) = 1;
1456 DECL_INITIAL (decl
) = make_node (BLOCK
);
1457 TREE_USED (DECL_INITIAL (decl
)) = 1;
1459 DECL_SOURCE_LOCATION (decl
) = input_location
;
1460 cfun
->function_end_locus
= input_location
;
1465 DECL_STATIC_CONSTRUCTOR (decl
) = 1;
1466 decl_init_priority_insert (decl
, priority
);
1469 DECL_STATIC_DESTRUCTOR (decl
) = 1;
1470 decl_fini_priority_insert (decl
, priority
);
1476 gimplify_function_tree (decl
);
1478 cgraph_add_new_function (decl
, false);
1481 current_function_decl
= NULL
;
1484 /* Generate and emit a static constructor or destructor. WHICH must
1485 be one of 'I' (for a constructor) or 'D' (for a destructor). BODY
1486 is a STATEMENT_LIST containing GENERIC statements. PRIORITY is the
1487 initialization priority for this constructor or destructor. */
1490 cgraph_build_static_cdtor (char which
, tree body
, int priority
)
1492 cgraph_build_static_cdtor_1 (which
, body
, priority
, false);
1495 /* A vector of FUNCTION_DECLs declared as static constructors. */
1496 static vec
<tree
> static_ctors
;
1497 /* A vector of FUNCTION_DECLs declared as static destructors. */
1498 static vec
<tree
> static_dtors
;
1500 /* When target does not have ctors and dtors, we call all constructor
1501 and destructor by special initialization/destruction function
1502 recognized by collect2.
1504 When we are going to build this function, collect all constructors and
1505 destructors and turn them into normal functions. */
1508 record_cdtor_fn (struct cgraph_node
*node
)
1510 if (DECL_STATIC_CONSTRUCTOR (node
->symbol
.decl
))
1511 static_ctors
.safe_push (node
->symbol
.decl
);
1512 if (DECL_STATIC_DESTRUCTOR (node
->symbol
.decl
))
1513 static_dtors
.safe_push (node
->symbol
.decl
);
1514 node
= cgraph_get_node (node
->symbol
.decl
);
1515 DECL_DISREGARD_INLINE_LIMITS (node
->symbol
.decl
) = 1;
1518 /* Define global constructors/destructor functions for the CDTORS, of
1519 which they are LEN. The CDTORS are sorted by initialization
1520 priority. If CTOR_P is true, these are constructors; otherwise,
1521 they are destructors. */
1524 build_cdtor (bool ctor_p
, vec
<tree
> cdtors
)
1527 size_t len
= cdtors
.length ();
1534 priority_type priority
;
1543 p
= ctor_p
? DECL_INIT_PRIORITY (fn
) : DECL_FINI_PRIORITY (fn
);
1546 else if (p
!= priority
)
1552 /* When there is only one cdtor and target supports them, do nothing. */
1554 && targetm
.have_ctors_dtors
)
1559 /* Find the next batch of constructors/destructors with the same
1560 initialization priority. */
1565 call
= build_call_expr (fn
, 0);
1567 DECL_STATIC_CONSTRUCTOR (fn
) = 0;
1569 DECL_STATIC_DESTRUCTOR (fn
) = 0;
1570 /* We do not want to optimize away pure/const calls here.
1571 When optimizing, these should be already removed, when not
1572 optimizing, we want user to be able to breakpoint in them. */
1573 TREE_SIDE_EFFECTS (call
) = 1;
1574 append_to_statement_list (call
, &body
);
1576 gcc_assert (body
!= NULL_TREE
);
1577 /* Generate a function to call all the function of like
1579 cgraph_build_static_cdtor_1 (ctor_p
? 'I' : 'D', body
, priority
, true);
1583 /* Comparison function for qsort. P1 and P2 are actually of type
1584 "tree *" and point to static constructors. DECL_INIT_PRIORITY is
1585 used to determine the sort order. */
1588 compare_ctor (const void *p1
, const void *p2
)
1595 f1
= *(const tree
*)p1
;
1596 f2
= *(const tree
*)p2
;
1597 priority1
= DECL_INIT_PRIORITY (f1
);
1598 priority2
= DECL_INIT_PRIORITY (f2
);
1600 if (priority1
< priority2
)
1602 else if (priority1
> priority2
)
1605 /* Ensure a stable sort. Constructors are executed in backwarding
1606 order to make LTO initialize braries first. */
1607 return DECL_UID (f2
) - DECL_UID (f1
);
1610 /* Comparison function for qsort. P1 and P2 are actually of type
1611 "tree *" and point to static destructors. DECL_FINI_PRIORITY is
1612 used to determine the sort order. */
1615 compare_dtor (const void *p1
, const void *p2
)
1622 f1
= *(const tree
*)p1
;
1623 f2
= *(const tree
*)p2
;
1624 priority1
= DECL_FINI_PRIORITY (f1
);
1625 priority2
= DECL_FINI_PRIORITY (f2
);
1627 if (priority1
< priority2
)
1629 else if (priority1
> priority2
)
1632 /* Ensure a stable sort. */
1633 return DECL_UID (f1
) - DECL_UID (f2
);
1636 /* Generate functions to call static constructors and destructors
1637 for targets that do not support .ctors/.dtors sections. These
1638 functions have magic names which are detected by collect2. */
1641 build_cdtor_fns (void)
1643 if (!static_ctors
.is_empty ())
1645 gcc_assert (!targetm
.have_ctors_dtors
|| in_lto_p
);
1646 static_ctors
.qsort (compare_ctor
);
1647 build_cdtor (/*ctor_p=*/true, static_ctors
);
1650 if (!static_dtors
.is_empty ())
1652 gcc_assert (!targetm
.have_ctors_dtors
|| in_lto_p
);
1653 static_dtors
.qsort (compare_dtor
);
1654 build_cdtor (/*ctor_p=*/false, static_dtors
);
1658 /* Look for constructors and destructors and produce function calling them.
1659 This is needed for targets not supporting ctors or dtors, but we perform the
1660 transformation also at linktime to merge possibly numerous
1661 constructors/destructors into single function to improve code locality and
1665 ipa_cdtor_merge (void)
1667 struct cgraph_node
*node
;
1668 FOR_EACH_DEFINED_FUNCTION (node
)
1669 if (DECL_STATIC_CONSTRUCTOR (node
->symbol
.decl
)
1670 || DECL_STATIC_DESTRUCTOR (node
->symbol
.decl
))
1671 record_cdtor_fn (node
);
1673 static_ctors
.release ();
1674 static_dtors
.release ();
1678 /* Perform the pass when we have no ctors/dtors support
1679 or at LTO time to merge multiple constructors into single
1683 gate_ipa_cdtor_merge (void)
1685 return !targetm
.have_ctors_dtors
|| (optimize
&& in_lto_p
);
1688 struct ipa_opt_pass_d pass_ipa_cdtor_merge
=
1693 OPTGROUP_NONE
, /* optinfo_flags */
1694 gate_ipa_cdtor_merge
, /* gate */
1695 ipa_cdtor_merge
, /* execute */
1698 0, /* static_pass_number */
1699 TV_CGRAPHOPT
, /* tv_id */
1700 0, /* properties_required */
1701 0, /* properties_provided */
1702 0, /* properties_destroyed */
1703 0, /* todo_flags_start */
1704 0 /* todo_flags_finish */
1706 NULL
, /* generate_summary */
1707 NULL
, /* write_summary */
1708 NULL
, /* read_summary */
1709 NULL
, /* write_optimization_summary */
1710 NULL
, /* read_optimization_summary */
1711 NULL
, /* stmt_fixup */
1713 NULL
, /* function_transform */
1714 NULL
/* variable_transform */