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"
26 #include "tree-pass.h"
31 #include "pointer-set.h"
33 #include "tree-iterator.h"
34 #include "ipa-utils.h"
35 #include "ipa-inline.h"
36 #include "tree-inline.h"
40 /* Return true when NODE can not be local. Worker for cgraph_local_node_p. */
43 cgraph_non_local_node_p_1 (struct cgraph_node
*node
, void *data ATTRIBUTE_UNUSED
)
45 /* FIXME: Aliases can be local, but i386 gets thunks wrong then. */
46 return !(cgraph_only_called_directly_or_aliased_p (node
)
47 && !ipa_ref_has_aliases_p (&node
->ref_list
)
49 && !DECL_EXTERNAL (node
->decl
)
50 && !node
->externally_visible
51 && !node
->used_from_other_partition
52 && !node
->in_other_partition
);
55 /* Return true when function can be marked local. */
58 cgraph_local_node_p (struct cgraph_node
*node
)
60 struct cgraph_node
*n
= cgraph_function_or_thunk_node (node
, NULL
);
62 /* FIXME: thunks can be considered local, but we need prevent i386
63 from attempting to change calling convention of them. */
66 return !cgraph_for_node_and_aliases (n
,
67 cgraph_non_local_node_p_1
, NULL
, true);
71 /* Return true when NODE has ADDR reference. */
74 has_addr_references_p (struct cgraph_node
*node
,
75 void *data ATTRIBUTE_UNUSED
)
80 for (i
= 0; ipa_ref_list_referring_iterate (&node
->ref_list
,
82 if (ref
->use
== IPA_REF_ADDR
)
87 /* Look for all functions inlined to NODE and update their inlined_to pointers
91 update_inlined_to_pointer (struct cgraph_node
*node
, struct cgraph_node
*inlined_to
)
93 struct cgraph_edge
*e
;
94 for (e
= node
->callees
; e
; e
= e
->next_callee
)
95 if (e
->callee
->global
.inlined_to
)
97 e
->callee
->global
.inlined_to
= inlined_to
;
98 update_inlined_to_pointer (e
->callee
, inlined_to
);
102 /* Add symtab NODE to queue starting at FIRST.
104 The queue is linked via AUX pointers and terminated by pointer to 1.
105 We enqueue nodes at two occasions: when we find them reachable or when we find
106 their bodies needed for further clonning. In the second case we mark them
107 by pointer to 2 after processing so they are re-queue when they become
111 enqueue_node (symtab_node
*node
, symtab_node
**first
,
112 struct pointer_set_t
*reachable
)
114 /* Node is still in queue; do nothing. */
115 if (node
->aux
&& node
->aux
!= (void *) 2)
117 /* Node was already processed as unreachable, re-enqueue
118 only if it became reachable now. */
119 if (node
->aux
== (void *)2 && !pointer_set_contains (reachable
, node
))
125 /* Process references. */
128 process_references (struct ipa_ref_list
*list
,
130 bool before_inlining_p
,
131 struct pointer_set_t
*reachable
)
135 for (i
= 0; ipa_ref_list_reference_iterate (list
, i
, ref
); i
++)
137 symtab_node
*node
= ref
->referred
;
139 if (node
->definition
&& !node
->in_other_partition
140 && ((!DECL_EXTERNAL (node
->decl
) || node
->alias
)
141 || (before_inlining_p
142 /* We use variable constructors during late complation for
143 constant folding. Keep references alive so partitioning
144 knows about potential references. */
145 || (TREE_CODE (node
->decl
) == VAR_DECL
147 && ctor_for_folding (node
->decl
)
148 != error_mark_node
))))
149 pointer_set_insert (reachable
, node
);
150 enqueue_node (node
, first
, reachable
);
154 /* EDGE is an polymorphic call. If BEFORE_INLINING_P is set, mark
155 all its potential targets as reachable to permit later inlining if
156 devirtualization happens. After inlining still keep their declarations
157 around, so we can devirtualize to a direct call.
159 Also try to make trivial devirutalization when no or only one target is
163 walk_polymorphic_call_targets (pointer_set_t
*reachable_call_targets
,
164 struct cgraph_edge
*edge
,
166 pointer_set_t
*reachable
, bool before_inlining_p
)
171 vec
<cgraph_node
*>targets
172 = possible_polymorphic_call_targets
173 (edge
, &final
, &cache_token
);
175 if (!pointer_set_insert (reachable_call_targets
,
178 for (i
= 0; i
< targets
.length (); i
++)
180 struct cgraph_node
*n
= targets
[i
];
182 /* Do not bother to mark virtual methods in anonymous namespace;
183 either we will find use of virtual table defining it, or it is
185 if (TREE_CODE (TREE_TYPE (n
->decl
)) == METHOD_TYPE
186 && type_in_anonymous_namespace_p
187 (method_class_type (TREE_TYPE (n
->decl
))))
190 /* Prior inlining, keep alive bodies of possible targets for
193 && before_inlining_p
)
194 pointer_set_insert (reachable
, n
);
196 /* Even after inlining we want to keep the possible targets in the
197 boundary, so late passes can still produce direct call even if
198 the chance for inlining is lost. */
199 enqueue_node (n
, first
, reachable
);
203 /* Very trivial devirtualization; when the type is
204 final or anonymous (so we know all its derivation)
205 and there is only one possible virtual call target,
206 make the edge direct. */
209 if (targets
.length () <= 1)
211 cgraph_node
*target
, *node
= edge
->caller
;
212 if (targets
.length () == 1)
215 target
= cgraph_get_create_node
216 (builtin_decl_implicit (BUILT_IN_UNREACHABLE
));
220 "Devirtualizing call in %s/%i to %s/%i\n",
221 edge
->caller
->name (),
223 target
->name (), target
->order
);
224 edge
= cgraph_make_edge_direct (edge
, target
);
225 if (!inline_summary_vec
&& edge
->call_stmt
)
226 cgraph_redirect_edge_call_stmt_to_callee (edge
);
228 inline_update_overall_summary (node
);
233 /* Perform reachability analysis and reclaim all unreachable nodes.
235 The algorithm is basically mark&sweep but with some extra refinements:
237 - reachable extern inline functions needs special handling; the bodies needs
238 to stay in memory until inlining in hope that they will be inlined.
239 After inlining we release their bodies and turn them into unanalyzed
240 nodes even when they are reachable.
242 BEFORE_INLINING_P specify whether we are before or after inlining.
244 - virtual functions are kept in callgraph even if they seem unreachable in
245 hope calls to them will be devirtualized.
247 Again we remove them after inlining. In late optimization some
248 devirtualization may happen, but it is not importnat since we won't inline
249 the call. In theory early opts and IPA should work out all important cases.
251 - virtual clones needs bodies of their origins for later materialization;
252 this means that we want to keep the body even if the origin is unreachable
253 otherwise. To avoid origin from sitting in the callgraph and being
254 walked by IPA passes, we turn them into unanalyzed nodes with body
257 We maintain set of function declaration where body needs to stay in
258 body_needed_for_clonning
260 Inline clones represent special case: their declaration match the
261 declaration of origin and cgraph_remove_node already knows how to
262 reshape callgraph and preserve body when offline copy of function or
263 inline clone is being removed.
265 - C++ virtual tables keyed to other unit are represented as DECL_EXTERNAL
266 variables with DECL_INITIAL set. We finalize these and keep reachable
267 ones around for constant folding purposes. After inlining we however
268 stop walking their references to let everything static referneced by them
269 to be removed when it is otherwise unreachable.
271 We maintain queue of both reachable symbols (i.e. defined symbols that needs
272 to stay) and symbols that are in boundary (i.e. external symbols referenced
273 by reachable symbols or origins of clones). The queue is represented
274 as linked list by AUX pointer terminated by 1.
276 A the end we keep all reachable symbols. For symbols in boundary we always
277 turn definition into a declaration, but we may keep function body around
278 based on body_needed_for_clonning
280 All symbols that enter the queue have AUX pointer non-zero and are in the
281 boundary. Pointer set REACHABLE is used to track reachable symbols.
283 Every symbol can be visited twice - once as part of boundary and once
284 as real reachable symbol. enqueue_node needs to decide whether the
285 node needs to be re-queued for second processing. For this purpose
286 we set AUX pointer of processed symbols in the boundary to constant 2. */
289 symtab_remove_unreachable_nodes (bool before_inlining_p
, FILE *file
)
291 symtab_node
*first
= (symtab_node
*) (void *) 1;
292 struct cgraph_node
*node
, *next
;
293 struct varpool_node
*vnode
, *vnext
;
294 bool changed
= false;
295 struct pointer_set_t
*reachable
= pointer_set_create ();
296 struct pointer_set_t
*body_needed_for_clonning
= pointer_set_create ();
297 struct pointer_set_t
*reachable_call_targets
= pointer_set_create ();
299 timevar_push (TV_IPA_UNREACHABLE
);
300 #ifdef ENABLE_CHECKING
303 if (optimize
&& flag_devirtualize
)
304 build_type_inheritance_graph ();
306 fprintf (file
, "\nReclaiming functions:");
307 #ifdef ENABLE_CHECKING
308 FOR_EACH_FUNCTION (node
)
309 gcc_assert (!node
->aux
);
310 FOR_EACH_VARIABLE (vnode
)
311 gcc_assert (!vnode
->aux
);
313 /* Mark functions whose bodies are obviously needed.
314 This is mostly when they can be referenced externally. Inline clones
315 are special since their declarations are shared with master clone and thus
316 cgraph_can_remove_if_no_direct_calls_and_refs_p should not be called on them. */
317 FOR_EACH_FUNCTION (node
)
319 node
->used_as_abstract_origin
= false;
321 && !node
->global
.inlined_to
322 && !node
->in_other_partition
323 && !cgraph_can_remove_if_no_direct_calls_and_refs_p (node
))
325 gcc_assert (!node
->global
.inlined_to
);
326 pointer_set_insert (reachable
, node
);
327 enqueue_node (node
, &first
, reachable
);
330 gcc_assert (!node
->aux
);
333 /* Mark variables that are obviously needed. */
334 FOR_EACH_DEFINED_VARIABLE (vnode
)
335 if (!varpool_can_remove_if_no_refs (vnode
)
336 && !vnode
->in_other_partition
)
338 pointer_set_insert (reachable
, vnode
);
339 enqueue_node (vnode
, &first
, reachable
);
342 /* Perform reachability analysis. */
343 while (first
!= (symtab_node
*) (void *) 1)
345 bool in_boundary_p
= !pointer_set_contains (reachable
, first
);
346 symtab_node
*node
= first
;
348 first
= (symtab_node
*)first
->aux
;
350 /* If we are processing symbol in boundary, mark its AUX pointer for
351 possible later re-processing in enqueue_node. */
353 node
->aux
= (void *)2;
356 if (DECL_ABSTRACT_ORIGIN (node
->decl
))
358 struct cgraph_node
*origin_node
359 = cgraph_get_create_node (DECL_ABSTRACT_ORIGIN (node
->decl
));
360 origin_node
->used_as_abstract_origin
= true;
361 enqueue_node (origin_node
, &first
, reachable
);
363 /* If any symbol in a comdat group is reachable, force
364 all other in the same comdat group to be also reachable. */
365 if (node
->same_comdat_group
)
368 for (next
= node
->same_comdat_group
;
370 next
= next
->same_comdat_group
)
371 if (!pointer_set_insert (reachable
, next
))
372 enqueue_node (next
, &first
, reachable
);
374 /* Mark references as reachable. */
375 process_references (&node
->ref_list
, &first
,
376 before_inlining_p
, reachable
);
379 if (cgraph_node
*cnode
= dyn_cast
<cgraph_node
> (node
))
381 /* Mark the callees reachable unless they are direct calls to extern
382 inline functions we decided to not inline. */
385 struct cgraph_edge
*e
;
386 /* Keep alive possible targets for devirtualization. */
387 if (optimize
&& flag_devirtualize
)
389 struct cgraph_edge
*next
;
390 for (e
= cnode
->indirect_calls
; e
; e
= next
)
392 next
= e
->next_callee
;
393 if (e
->indirect_info
->polymorphic
)
394 walk_polymorphic_call_targets (reachable_call_targets
,
395 e
, &first
, reachable
,
399 for (e
= cnode
->callees
; e
; e
= e
->next_callee
)
401 if (e
->callee
->definition
402 && !e
->callee
->in_other_partition
403 && (!e
->inline_failed
404 || !DECL_EXTERNAL (e
->callee
->decl
)
406 || before_inlining_p
))
407 pointer_set_insert (reachable
, e
->callee
);
408 enqueue_node (e
->callee
, &first
, reachable
);
411 /* When inline clone exists, mark body to be preserved so when removing
412 offline copy of the function we don't kill it. */
413 if (cnode
->global
.inlined_to
)
414 pointer_set_insert (body_needed_for_clonning
, cnode
->decl
);
416 /* For non-inline clones, force their origins to the boundary and ensure
417 that body is not removed. */
418 while (cnode
->clone_of
)
420 bool noninline
= cnode
->clone_of
->decl
!= cnode
->decl
;
421 cnode
= cnode
->clone_of
;
424 pointer_set_insert (body_needed_for_clonning
, cnode
->decl
);
425 enqueue_node (cnode
, &first
, reachable
);
430 /* When we see constructor of external variable, keep referred nodes in the
431 boundary. This will also hold initializers of the external vars NODE
433 varpool_node
*vnode
= dyn_cast
<varpool_node
> (node
);
435 && DECL_EXTERNAL (node
->decl
)
440 for (int i
= 0; ipa_ref_list_reference_iterate (&node
->ref_list
, i
, ref
); i
++)
441 enqueue_node (ref
->referred
, &first
, reachable
);
445 /* Remove unreachable functions. */
446 for (node
= cgraph_first_function (); node
; node
= next
)
448 next
= cgraph_next_function (node
);
450 /* If node is not needed at all, remove it. */
454 fprintf (file
, " %s", node
->name ());
455 cgraph_remove_node (node
);
458 /* If node is unreachable, remove its body. */
459 else if (!pointer_set_contains (reachable
, node
))
461 if (!pointer_set_contains (body_needed_for_clonning
, node
->decl
))
462 cgraph_release_function_body (node
);
463 else if (!node
->clone_of
)
464 gcc_assert (in_lto_p
|| DECL_RESULT (node
->decl
));
465 if (node
->definition
)
468 fprintf (file
, " %s", node
->name ());
469 node
->analyzed
= false;
470 node
->definition
= false;
471 node
->cpp_implicit_alias
= false;
473 node
->weakref
= false;
474 if (!node
->in_other_partition
)
475 node
->local
.local
= false;
476 cgraph_node_remove_callees (node
);
477 ipa_remove_all_references (&node
->ref_list
);
482 gcc_assert (node
->clone_of
|| !cgraph_function_with_gimple_body_p (node
)
483 || in_lto_p
|| DECL_RESULT (node
->decl
));
486 /* Inline clones might be kept around so their materializing allows further
487 cloning. If the function the clone is inlined into is removed, we need
488 to turn it into normal cone. */
489 FOR_EACH_FUNCTION (node
)
491 if (node
->global
.inlined_to
494 gcc_assert (node
->clones
);
495 node
->global
.inlined_to
= NULL
;
496 update_inlined_to_pointer (node
, node
);
501 /* Remove unreachable variables. */
503 fprintf (file
, "\nReclaiming variables:");
504 for (vnode
= varpool_first_variable (); vnode
; vnode
= vnext
)
506 vnext
= varpool_next_variable (vnode
);
508 /* For can_refer_decl_in_current_unit_p we want to track for
509 all external variables if they are defined in other partition
511 && (!flag_ltrans
|| !DECL_EXTERNAL (vnode
->decl
)))
514 fprintf (file
, " %s", vnode
->name ());
515 varpool_remove_node (vnode
);
518 else if (!pointer_set_contains (reachable
, vnode
))
521 if (vnode
->definition
)
524 fprintf (file
, " %s", vnode
->name ());
527 vnode
->definition
= false;
528 vnode
->analyzed
= false;
531 /* Keep body if it may be useful for constant folding. */
532 if ((init
= ctor_for_folding (vnode
->decl
)) == error_mark_node
)
533 varpool_remove_initializer (vnode
);
535 DECL_INITIAL (vnode
->decl
) = init
;
536 ipa_remove_all_references (&vnode
->ref_list
);
542 pointer_set_destroy (reachable
);
543 pointer_set_destroy (body_needed_for_clonning
);
544 pointer_set_destroy (reachable_call_targets
);
546 /* Now update address_taken flags and try to promote functions to be local. */
548 fprintf (file
, "\nClearing address taken flags:");
549 FOR_EACH_DEFINED_FUNCTION (node
)
550 if (node
->address_taken
551 && !node
->used_from_other_partition
)
553 if (!cgraph_for_node_and_aliases (node
, has_addr_references_p
, NULL
, true))
556 fprintf (file
, " %s", node
->name ());
557 node
->address_taken
= false;
559 if (cgraph_local_node_p (node
))
561 node
->local
.local
= true;
563 fprintf (file
, " (local)");
568 fprintf (file
, "\n");
570 #ifdef ENABLE_CHECKING
574 /* If we removed something, perhaps profile could be improved. */
575 if (changed
&& optimize
&& inline_edge_summary_vec
.exists ())
576 FOR_EACH_DEFINED_FUNCTION (node
)
577 ipa_propagate_frequency (node
);
579 timevar_pop (TV_IPA_UNREACHABLE
);
583 /* Discover variables that have no longer address taken or that are read only
584 and update their flags.
586 FIXME: This can not be done in between gimplify and omp_expand since
587 readonly flag plays role on what is shared and what is not. Currently we do
588 this transformation as part of whole program visibility and re-do at
589 ipa-reference pass (to take into account clonning), but it would
590 make sense to do it before early optimizations. */
593 ipa_discover_readonly_nonaddressable_vars (void)
595 struct varpool_node
*vnode
;
597 fprintf (dump_file
, "Clearing variable flags:");
598 FOR_EACH_VARIABLE (vnode
)
599 if (vnode
->definition
&& varpool_all_refs_explicit_p (vnode
)
600 && (TREE_ADDRESSABLE (vnode
->decl
)
601 || !TREE_READONLY (vnode
->decl
)))
603 bool written
= false;
604 bool address_taken
= false;
607 for (i
= 0; ipa_ref_list_referring_iterate (&vnode
->ref_list
,
609 && (!written
|| !address_taken
); i
++)
613 address_taken
= true;
621 if (TREE_ADDRESSABLE (vnode
->decl
) && !address_taken
)
624 fprintf (dump_file
, " %s (addressable)", vnode
->name ());
625 TREE_ADDRESSABLE (vnode
->decl
) = 0;
627 if (!TREE_READONLY (vnode
->decl
) && !address_taken
&& !written
628 /* Making variable in explicit section readonly can cause section
630 See e.g. gcc.c-torture/compile/pr23237.c */
631 && DECL_SECTION_NAME (vnode
->decl
) == NULL
)
634 fprintf (dump_file
, " %s (read-only)", vnode
->name ());
635 TREE_READONLY (vnode
->decl
) = 1;
639 fprintf (dump_file
, "\n");
642 /* Return true when there is a reference to node and it is not vtable. */
644 address_taken_from_non_vtable_p (symtab_node
*node
)
648 for (i
= 0; ipa_ref_list_referring_iterate (&node
->ref_list
,
650 if (ref
->use
== IPA_REF_ADDR
)
652 struct varpool_node
*node
;
653 if (is_a
<cgraph_node
> (ref
->referring
))
655 node
= ipa_ref_referring_varpool_node (ref
);
656 if (!DECL_VIRTUAL_P (node
->decl
))
662 /* A helper for comdat_can_be_unshared_p. */
665 comdat_can_be_unshared_p_1 (symtab_node
*node
)
667 /* When address is taken, we don't know if equality comparison won't
668 break eventually. Exception are virutal functions, C++
669 constructors/destructors and vtables, where this is not possible by
670 language standard. */
671 if (!DECL_VIRTUAL_P (node
->decl
)
672 && (TREE_CODE (node
->decl
) != FUNCTION_DECL
673 || (!DECL_CXX_CONSTRUCTOR_P (node
->decl
)
674 && !DECL_CXX_DESTRUCTOR_P (node
->decl
)))
675 && address_taken_from_non_vtable_p (node
))
678 /* If the symbol is used in some weird way, better to not touch it. */
679 if (node
->force_output
)
682 /* Explicit instantiations needs to be output when possibly
684 if (node
->forced_by_abi
685 && TREE_PUBLIC (node
->decl
)
686 && (node
->resolution
!= LDPR_PREVAILING_DEF_IRONLY
687 && !flag_whole_program
))
690 /* Non-readonly and volatile variables can not be duplicated. */
691 if (is_a
<varpool_node
> (node
)
692 && (!TREE_READONLY (node
->decl
)
693 || TREE_THIS_VOLATILE (node
->decl
)))
698 /* COMDAT functions must be shared only if they have address taken,
699 otherwise we can produce our own private implementation with
701 Return true when turning COMDAT functoin static can not lead to wrong
702 code when the resulting object links with a library defining same COMDAT.
704 Virtual functions do have their addresses taken from the vtables,
705 but in C++ there is no way to compare their addresses for equality. */
708 comdat_can_be_unshared_p (symtab_node
*node
)
710 if (!comdat_can_be_unshared_p_1 (node
))
712 if (node
->same_comdat_group
)
716 /* If more than one function is in the same COMDAT group, it must
717 be shared even if just one function in the comdat group has
719 for (next
= node
->same_comdat_group
;
720 next
!= node
; next
= next
->same_comdat_group
)
721 if (!comdat_can_be_unshared_p_1 (next
))
727 /* Return true when function NODE should be considered externally visible. */
730 cgraph_externally_visible_p (struct cgraph_node
*node
,
733 if (!node
->definition
)
735 if (!TREE_PUBLIC (node
->decl
)
736 || DECL_EXTERNAL (node
->decl
))
739 /* Do not try to localize built-in functions yet. One of problems is that we
740 end up mangling their asm for WHOPR that makes it impossible to call them
741 using the implicit built-in declarations anymore. Similarly this enables
742 us to remove them as unreachable before actual calls may appear during
743 expansion or folding. */
744 if (DECL_BUILT_IN (node
->decl
))
747 /* If linker counts on us, we must preserve the function. */
748 if (symtab_used_from_object_file_p (node
))
750 if (DECL_PRESERVE_P (node
->decl
))
752 if (lookup_attribute ("externally_visible",
753 DECL_ATTRIBUTES (node
->decl
)))
755 if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
756 && lookup_attribute ("dllexport",
757 DECL_ATTRIBUTES (node
->decl
)))
759 if (node
->resolution
== LDPR_PREVAILING_DEF_IRONLY
)
761 /* When doing LTO or whole program, we can bring COMDAT functoins static.
762 This improves code quality and we know we will duplicate them at most twice
763 (in the case that we are not using plugin and link with object file
764 implementing same COMDAT) */
765 if ((in_lto_p
|| whole_program
)
766 && DECL_COMDAT (node
->decl
)
767 && comdat_can_be_unshared_p (node
))
770 /* When doing link time optimizations, hidden symbols become local. */
772 && (DECL_VISIBILITY (node
->decl
) == VISIBILITY_HIDDEN
773 || DECL_VISIBILITY (node
->decl
) == VISIBILITY_INTERNAL
)
774 /* Be sure that node is defined in IR file, not in other object
775 file. In that case we don't set used_from_other_object_file. */
778 else if (!whole_program
)
781 if (MAIN_NAME_P (DECL_NAME (node
->decl
)))
787 /* Return true when variable VNODE should be considered externally visible. */
790 varpool_externally_visible_p (struct varpool_node
*vnode
)
792 if (DECL_EXTERNAL (vnode
->decl
))
795 if (!TREE_PUBLIC (vnode
->decl
))
798 /* If linker counts on us, we must preserve the function. */
799 if (symtab_used_from_object_file_p (vnode
))
802 if (DECL_HARD_REGISTER (vnode
->decl
))
804 if (DECL_PRESERVE_P (vnode
->decl
))
806 if (lookup_attribute ("externally_visible",
807 DECL_ATTRIBUTES (vnode
->decl
)))
809 if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
810 && lookup_attribute ("dllexport",
811 DECL_ATTRIBUTES (vnode
->decl
)))
814 /* See if we have linker information about symbol not being used or
815 if we need to make guess based on the declaration.
817 Even if the linker clams the symbol is unused, never bring internal
818 symbols that are declared by user as used or externally visible.
819 This is needed for i.e. references from asm statements. */
820 if (symtab_used_from_object_file_p (vnode
))
822 if (vnode
->resolution
== LDPR_PREVAILING_DEF_IRONLY
)
825 /* As a special case, the COMDAT virtual tables can be unshared.
826 In LTO mode turn vtables into static variables. The variable is readonly,
827 so this does not enable more optimization, but referring static var
828 is faster for dynamic linking. Also this match logic hidding vtables
829 from LTO symbol tables. */
830 if ((in_lto_p
|| flag_whole_program
)
831 && DECL_COMDAT (vnode
->decl
)
832 && comdat_can_be_unshared_p (vnode
))
835 /* When doing link time optimizations, hidden symbols become local. */
837 && (DECL_VISIBILITY (vnode
->decl
) == VISIBILITY_HIDDEN
838 || DECL_VISIBILITY (vnode
->decl
) == VISIBILITY_INTERNAL
)
839 /* Be sure that node is defined in IR file, not in other object
840 file. In that case we don't set used_from_other_object_file. */
841 && vnode
->definition
)
843 else if (!flag_whole_program
)
846 /* Do not attempt to privatize COMDATS by default.
847 This would break linking with C++ libraries sharing
850 FIXME: We can do so for readonly vars with no address taken and
851 possibly also for vtables since no direct pointer comparsion is done.
852 It might be interesting to do so to reduce linking overhead. */
853 if (DECL_COMDAT (vnode
->decl
) || DECL_WEAK (vnode
->decl
))
858 /* Return true if reference to NODE can be replaced by a local alias.
859 Local aliases save dynamic linking overhead and enable more optimizations.
863 can_replace_by_local_alias (symtab_node
*node
)
865 return (symtab_node_availability (node
) > AVAIL_OVERWRITABLE
866 && !symtab_can_be_discarded (node
));
869 /* Mark visibility of all functions.
871 A local function is one whose calls can occur only in the current
872 compilation unit and all its calls are explicit, so we can change
873 its calling convention. We simply mark all static functions whose
874 address is not taken as local.
876 We also change the TREE_PUBLIC flag of all declarations that are public
877 in language point of view but we want to overwrite this default
878 via visibilities for the backend point of view. */
881 function_and_variable_visibility (bool whole_program
)
883 struct cgraph_node
*node
;
884 struct varpool_node
*vnode
;
886 /* All aliases should be procssed at this point. */
887 gcc_checking_assert (!alias_pairs
|| !alias_pairs
->length ());
889 FOR_EACH_FUNCTION (node
)
891 int flags
= flags_from_decl_or_type (node
->decl
);
893 /* Optimize away PURE and CONST constructors and destructors. */
895 && (flags
& (ECF_CONST
| ECF_PURE
))
896 && !(flags
& ECF_LOOPING_CONST_OR_PURE
))
898 DECL_STATIC_CONSTRUCTOR (node
->decl
) = 0;
899 DECL_STATIC_DESTRUCTOR (node
->decl
) = 0;
902 /* Frontends and alias code marks nodes as needed before parsing is finished.
903 We may end up marking as node external nodes where this flag is meaningless
905 if (DECL_EXTERNAL (node
->decl
) || !node
->definition
)
907 node
->force_output
= 0;
908 node
->forced_by_abi
= 0;
911 /* C++ FE on lack of COMDAT support create local COMDAT functions
912 (that ought to be shared but can not due to object format
913 limitations). It is necessary to keep the flag to make rest of C++ FE
914 happy. Clear the flag here to avoid confusion in middle-end. */
915 if (DECL_COMDAT (node
->decl
) && !TREE_PUBLIC (node
->decl
))
916 DECL_COMDAT (node
->decl
) = 0;
918 /* For external decls stop tracking same_comdat_group. It doesn't matter
919 what comdat group they are in when they won't be emitted in this TU. */
920 if (node
->same_comdat_group
&& DECL_EXTERNAL (node
->decl
))
922 #ifdef ENABLE_CHECKING
925 for (n
= node
->same_comdat_group
;
927 n
= n
->same_comdat_group
)
928 /* If at least one of same comdat group functions is external,
929 all of them have to be, otherwise it is a front-end bug. */
930 gcc_assert (DECL_EXTERNAL (n
->decl
));
932 symtab_dissolve_same_comdat_group_list (node
);
934 gcc_assert ((!DECL_WEAK (node
->decl
)
935 && !DECL_COMDAT (node
->decl
))
936 || TREE_PUBLIC (node
->decl
)
938 || DECL_EXTERNAL (node
->decl
));
939 if (cgraph_externally_visible_p (node
, whole_program
))
941 gcc_assert (!node
->global
.inlined_to
);
942 node
->externally_visible
= true;
946 node
->externally_visible
= false;
947 node
->forced_by_abi
= false;
949 if (!node
->externally_visible
950 && node
->definition
&& !node
->weakref
951 && !DECL_EXTERNAL (node
->decl
))
953 gcc_assert (whole_program
|| in_lto_p
954 || !TREE_PUBLIC (node
->decl
));
955 node
->unique_name
= ((node
->resolution
== LDPR_PREVAILING_DEF_IRONLY
956 || node
->resolution
== LDPR_PREVAILING_DEF_IRONLY_EXP
)
957 && TREE_PUBLIC (node
->decl
));
958 symtab_make_decl_local (node
->decl
);
959 node
->resolution
= LDPR_PREVAILING_DEF_IRONLY
;
960 if (node
->same_comdat_group
)
961 /* cgraph_externally_visible_p has already checked all other nodes
962 in the group and they will all be made local. We need to
963 dissolve the group at once so that the predicate does not
965 symtab_dissolve_same_comdat_group_list (node
);
968 if (node
->thunk
.thunk_p
969 && TREE_PUBLIC (node
->decl
))
971 struct cgraph_node
*decl_node
= node
;
973 decl_node
= cgraph_function_node (decl_node
->callees
->callee
, NULL
);
975 /* Thunks have the same visibility as function they are attached to.
976 Make sure the C++ front end set this up properly. */
977 if (DECL_ONE_ONLY (decl_node
->decl
))
979 gcc_checking_assert (DECL_COMDAT (node
->decl
)
980 == DECL_COMDAT (decl_node
->decl
));
981 gcc_checking_assert (DECL_COMDAT_GROUP (node
->decl
)
982 == DECL_COMDAT_GROUP (decl_node
->decl
));
983 gcc_checking_assert (node
->same_comdat_group
);
985 if (DECL_EXTERNAL (decl_node
->decl
))
986 DECL_EXTERNAL (node
->decl
) = 1;
989 FOR_EACH_DEFINED_FUNCTION (node
)
991 node
->local
.local
|= cgraph_local_node_p (node
);
993 /* If we know that function can not be overwritten by a different semantics
994 and moreover its section can not be discarded, replace all direct calls
995 by calls to an nonoverwritable alias. This make dynamic linking
996 cheaper and enable more optimization.
998 TODO: We can also update virtual tables. */
999 if (node
->callers
&& can_replace_by_local_alias (node
))
1001 struct cgraph_node
*alias
= cgraph (symtab_nonoverwritable_alias (node
));
1003 if (alias
&& alias
!= node
)
1005 while (node
->callers
)
1007 struct cgraph_edge
*e
= node
->callers
;
1009 cgraph_redirect_edge_callee (e
, alias
);
1010 if (gimple_has_body_p (e
->caller
->decl
))
1012 push_cfun (DECL_STRUCT_FUNCTION (e
->caller
->decl
));
1013 cgraph_redirect_edge_call_stmt_to_callee (e
);
1020 FOR_EACH_VARIABLE (vnode
)
1022 /* weak flag makes no sense on local variables. */
1023 gcc_assert (!DECL_WEAK (vnode
->decl
)
1025 || TREE_PUBLIC (vnode
->decl
)
1026 || DECL_EXTERNAL (vnode
->decl
));
1027 /* In several cases declarations can not be common:
1029 - when declaration has initializer
1030 - when it is in weak
1031 - when it has specific section
1032 - when it resides in non-generic address space.
1033 - if declaration is local, it will get into .local common section
1034 so common flag is not needed. Frontends still produce these in
1035 certain cases, such as for:
1037 static int a __attribute__ ((common))
1039 Canonicalize things here and clear the redundant flag. */
1040 if (DECL_COMMON (vnode
->decl
)
1041 && (!(TREE_PUBLIC (vnode
->decl
)
1042 || DECL_EXTERNAL (vnode
->decl
))
1043 || (DECL_INITIAL (vnode
->decl
)
1044 && DECL_INITIAL (vnode
->decl
) != error_mark_node
)
1045 || DECL_WEAK (vnode
->decl
)
1046 || DECL_SECTION_NAME (vnode
->decl
) != NULL
1047 || ! (ADDR_SPACE_GENERIC_P
1048 (TYPE_ADDR_SPACE (TREE_TYPE (vnode
->decl
))))))
1049 DECL_COMMON (vnode
->decl
) = 0;
1051 FOR_EACH_DEFINED_VARIABLE (vnode
)
1053 if (!vnode
->definition
)
1055 if (varpool_externally_visible_p (vnode
))
1056 vnode
->externally_visible
= true;
1059 vnode
->externally_visible
= false;
1060 vnode
->forced_by_abi
= false;
1062 if (!vnode
->externally_visible
1065 gcc_assert (in_lto_p
|| whole_program
|| !TREE_PUBLIC (vnode
->decl
));
1066 vnode
->unique_name
= ((vnode
->resolution
== LDPR_PREVAILING_DEF_IRONLY
1067 || vnode
->resolution
== LDPR_PREVAILING_DEF_IRONLY_EXP
)
1068 && TREE_PUBLIC (vnode
->decl
));
1069 symtab_make_decl_local (vnode
->decl
);
1070 if (vnode
->same_comdat_group
)
1071 symtab_dissolve_same_comdat_group_list (vnode
);
1072 vnode
->resolution
= LDPR_PREVAILING_DEF_IRONLY
;
1078 fprintf (dump_file
, "\nMarking local functions:");
1079 FOR_EACH_DEFINED_FUNCTION (node
)
1080 if (node
->local
.local
)
1081 fprintf (dump_file
, " %s", node
->name ());
1082 fprintf (dump_file
, "\n\n");
1083 fprintf (dump_file
, "\nMarking externally visible functions:");
1084 FOR_EACH_DEFINED_FUNCTION (node
)
1085 if (node
->externally_visible
)
1086 fprintf (dump_file
, " %s", node
->name ());
1087 fprintf (dump_file
, "\n\n");
1088 fprintf (dump_file
, "\nMarking externally visible variables:");
1089 FOR_EACH_DEFINED_VARIABLE (vnode
)
1090 if (vnode
->externally_visible
)
1091 fprintf (dump_file
, " %s", vnode
->name ());
1092 fprintf (dump_file
, "\n\n");
1094 cgraph_function_flags_ready
= true;
1098 /* Local function pass handling visibilities. This happens before LTO streaming
1099 so in particular -fwhole-program should be ignored at this level. */
1102 local_function_and_variable_visibility (void)
1104 return function_and_variable_visibility (flag_whole_program
&& !flag_lto
);
1109 const pass_data pass_data_ipa_function_and_variable_visibility
=
1111 SIMPLE_IPA_PASS
, /* type */
1112 "visibility", /* name */
1113 OPTGROUP_NONE
, /* optinfo_flags */
1114 false, /* has_gate */
1115 true, /* has_execute */
1116 TV_CGRAPHOPT
, /* tv_id */
1117 0, /* properties_required */
1118 0, /* properties_provided */
1119 0, /* properties_destroyed */
1120 0, /* todo_flags_start */
1121 ( TODO_remove_functions
| TODO_dump_symtab
), /* todo_flags_finish */
1124 class pass_ipa_function_and_variable_visibility
: public simple_ipa_opt_pass
1127 pass_ipa_function_and_variable_visibility (gcc::context
*ctxt
)
1128 : simple_ipa_opt_pass (pass_data_ipa_function_and_variable_visibility
,
1132 /* opt_pass methods: */
1133 unsigned int execute () {
1134 return local_function_and_variable_visibility ();
1137 }; // class pass_ipa_function_and_variable_visibility
1141 simple_ipa_opt_pass
*
1142 make_pass_ipa_function_and_variable_visibility (gcc::context
*ctxt
)
1144 return new pass_ipa_function_and_variable_visibility (ctxt
);
1147 /* Free inline summary. */
1150 free_inline_summary (void)
1152 inline_free_summary ();
1158 const pass_data pass_data_ipa_free_inline_summary
=
1160 SIMPLE_IPA_PASS
, /* type */
1161 "*free_inline_summary", /* name */
1162 OPTGROUP_NONE
, /* optinfo_flags */
1163 false, /* has_gate */
1164 true, /* has_execute */
1165 TV_IPA_FREE_INLINE_SUMMARY
, /* tv_id */
1166 0, /* properties_required */
1167 0, /* properties_provided */
1168 0, /* properties_destroyed */
1169 0, /* todo_flags_start */
1170 0, /* todo_flags_finish */
1173 class pass_ipa_free_inline_summary
: public simple_ipa_opt_pass
1176 pass_ipa_free_inline_summary (gcc::context
*ctxt
)
1177 : simple_ipa_opt_pass (pass_data_ipa_free_inline_summary
, ctxt
)
1180 /* opt_pass methods: */
1181 unsigned int execute () { return free_inline_summary (); }
1183 }; // class pass_ipa_free_inline_summary
1187 simple_ipa_opt_pass
*
1188 make_pass_ipa_free_inline_summary (gcc::context
*ctxt
)
1190 return new pass_ipa_free_inline_summary (ctxt
);
1193 /* Do not re-run on ltrans stage. */
1196 gate_whole_program_function_and_variable_visibility (void)
1198 return !flag_ltrans
;
1201 /* Bring functionss local at LTO time with -fwhole-program. */
1204 whole_program_function_and_variable_visibility (void)
1206 function_and_variable_visibility (flag_whole_program
);
1208 ipa_discover_readonly_nonaddressable_vars ();
1214 const pass_data pass_data_ipa_whole_program_visibility
=
1216 IPA_PASS
, /* type */
1217 "whole-program", /* name */
1218 OPTGROUP_NONE
, /* optinfo_flags */
1219 true, /* has_gate */
1220 true, /* has_execute */
1221 TV_CGRAPHOPT
, /* tv_id */
1222 0, /* properties_required */
1223 0, /* properties_provided */
1224 0, /* properties_destroyed */
1225 0, /* todo_flags_start */
1226 ( TODO_remove_functions
| TODO_dump_symtab
), /* todo_flags_finish */
1229 class pass_ipa_whole_program_visibility
: public ipa_opt_pass_d
1232 pass_ipa_whole_program_visibility (gcc::context
*ctxt
)
1233 : ipa_opt_pass_d (pass_data_ipa_whole_program_visibility
, ctxt
,
1234 NULL
, /* generate_summary */
1235 NULL
, /* write_summary */
1236 NULL
, /* read_summary */
1237 NULL
, /* write_optimization_summary */
1238 NULL
, /* read_optimization_summary */
1239 NULL
, /* stmt_fixup */
1240 0, /* function_transform_todo_flags_start */
1241 NULL
, /* function_transform */
1242 NULL
) /* variable_transform */
1245 /* opt_pass methods: */
1247 return gate_whole_program_function_and_variable_visibility ();
1249 unsigned int execute () {
1250 return whole_program_function_and_variable_visibility ();
1253 }; // class pass_ipa_whole_program_visibility
1258 make_pass_ipa_whole_program_visibility (gcc::context
*ctxt
)
1260 return new pass_ipa_whole_program_visibility (ctxt
);
1263 /* Generate and emit a static constructor or destructor. WHICH must
1264 be one of 'I' (for a constructor), 'D' (for a destructor), 'P'
1265 (for chp static vars constructor) or 'B' (for chkp static bounds
1266 constructor). BODY is a STATEMENT_LIST containing GENERIC
1267 statements. PRIORITY is the initialization priority for this
1268 constructor or destructor.
1270 FINAL specify whether the externally visible name for collect2 should
1274 cgraph_build_static_cdtor_1 (char which
, tree body
, int priority
, bool final
)
1276 static int counter
= 0;
1278 tree decl
, name
, resdecl
;
1280 /* The priority is encoded in the constructor or destructor name.
1281 collect2 will sort the names and arrange that they are called at
1284 sprintf (which_buf
, "%c_%.5d_%d", which
, priority
, counter
++);
1286 /* Proudce sane name but one not recognizable by collect2, just for the
1287 case we fail to inline the function. */
1288 sprintf (which_buf
, "sub_%c_%.5d_%d", which
, priority
, counter
++);
1289 name
= get_file_function_name (which_buf
);
1291 decl
= build_decl (input_location
, FUNCTION_DECL
, name
,
1292 build_function_type_list (void_type_node
, NULL_TREE
));
1293 current_function_decl
= decl
;
1295 resdecl
= build_decl (input_location
,
1296 RESULT_DECL
, NULL_TREE
, void_type_node
);
1297 DECL_ARTIFICIAL (resdecl
) = 1;
1298 DECL_RESULT (decl
) = resdecl
;
1299 DECL_CONTEXT (resdecl
) = decl
;
1301 allocate_struct_function (decl
, false);
1303 TREE_STATIC (decl
) = 1;
1304 TREE_USED (decl
) = 1;
1305 DECL_ARTIFICIAL (decl
) = 1;
1306 DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl
) = 1;
1307 DECL_SAVED_TREE (decl
) = body
;
1308 if (!targetm
.have_ctors_dtors
&& final
)
1310 TREE_PUBLIC (decl
) = 1;
1311 DECL_PRESERVE_P (decl
) = 1;
1313 DECL_UNINLINABLE (decl
) = 1;
1315 DECL_INITIAL (decl
) = make_node (BLOCK
);
1316 TREE_USED (DECL_INITIAL (decl
)) = 1;
1318 DECL_SOURCE_LOCATION (decl
) = input_location
;
1319 cfun
->function_end_locus
= input_location
;
1324 DECL_STATIC_CONSTRUCTOR (decl
) = 1;
1325 decl_init_priority_insert (decl
, priority
);
1328 DECL_STATIC_CONSTRUCTOR (decl
) = 1;
1329 DECL_ATTRIBUTES (decl
) = tree_cons (get_identifier ("chkp ctor"),
1332 decl_init_priority_insert (decl
, priority
);
1335 DECL_STATIC_CONSTRUCTOR (decl
) = 1;
1336 DECL_ATTRIBUTES (decl
) = tree_cons (get_identifier ("bnd_legacy"),
1339 decl_init_priority_insert (decl
, priority
);
1342 DECL_STATIC_DESTRUCTOR (decl
) = 1;
1343 decl_fini_priority_insert (decl
, priority
);
1349 gimplify_function_tree (decl
);
1351 cgraph_add_new_function (decl
, false);
1354 current_function_decl
= NULL
;
1357 /* Generate and emit a static constructor or destructor. WHICH must
1358 be one of 'I' (for a constructor), 'D' (for a destructor), 'P'
1359 (for chkp static vars constructor) or 'B' (for chkp static bounds
1360 constructor). BODY is a STATEMENT_LIST containing GENERIC
1361 statements. PRIORITY is the initialization priority for this
1362 constructor or destructor. */
1365 cgraph_build_static_cdtor (char which
, tree body
, int priority
)
1367 cgraph_build_static_cdtor_1 (which
, body
, priority
, false);
1370 /* A vector of FUNCTION_DECLs declared as static constructors. */
1371 static vec
<tree
> static_ctors
;
1372 /* A vector of FUNCTION_DECLs declared as static destructors. */
1373 static vec
<tree
> static_dtors
;
1375 /* When target does not have ctors and dtors, we call all constructor
1376 and destructor by special initialization/destruction function
1377 recognized by collect2.
1379 When we are going to build this function, collect all constructors and
1380 destructors and turn them into normal functions. */
1383 record_cdtor_fn (struct cgraph_node
*node
)
1385 if (DECL_STATIC_CONSTRUCTOR (node
->decl
))
1386 static_ctors
.safe_push (node
->decl
);
1387 if (DECL_STATIC_DESTRUCTOR (node
->decl
))
1388 static_dtors
.safe_push (node
->decl
);
1389 node
= cgraph_get_node (node
->decl
);
1390 DECL_DISREGARD_INLINE_LIMITS (node
->decl
) = 1;
1393 /* Define global constructors/destructor functions for the CDTORS, of
1394 which they are LEN. The CDTORS are sorted by initialization
1395 priority. If CTOR_P is true, these are constructors; otherwise,
1396 they are destructors. */
1399 build_cdtor (bool ctor_p
, vec
<tree
> cdtors
)
1402 size_t len
= cdtors
.length ();
1409 priority_type priority
;
1418 p
= ctor_p
? DECL_INIT_PRIORITY (fn
) : DECL_FINI_PRIORITY (fn
);
1421 else if (p
!= priority
)
1427 /* When there is only one cdtor and target supports them, do nothing. */
1429 && targetm
.have_ctors_dtors
)
1434 /* Find the next batch of constructors/destructors with the same
1435 initialization priority. */
1440 call
= build_call_expr (fn
, 0);
1442 DECL_STATIC_CONSTRUCTOR (fn
) = 0;
1444 DECL_STATIC_DESTRUCTOR (fn
) = 0;
1445 /* We do not want to optimize away pure/const calls here.
1446 When optimizing, these should be already removed, when not
1447 optimizing, we want user to be able to breakpoint in them. */
1448 TREE_SIDE_EFFECTS (call
) = 1;
1449 append_to_statement_list (call
, &body
);
1451 gcc_assert (body
!= NULL_TREE
);
1452 /* Generate a function to call all the function of like
1454 cgraph_build_static_cdtor_1 (ctor_p
? 'I' : 'D', body
, priority
, true);
1458 /* Comparison function for qsort. P1 and P2 are actually of type
1459 "tree *" and point to static constructors. DECL_INIT_PRIORITY is
1460 used to determine the sort order. */
1463 compare_ctor (const void *p1
, const void *p2
)
1470 f1
= *(const tree
*)p1
;
1471 f2
= *(const tree
*)p2
;
1472 priority1
= DECL_INIT_PRIORITY (f1
);
1473 priority2
= DECL_INIT_PRIORITY (f2
);
1475 if (priority1
< priority2
)
1477 else if (priority1
> priority2
)
1480 /* Ensure a stable sort. Constructors are executed in backwarding
1481 order to make LTO initialize braries first. */
1482 return DECL_UID (f2
) - DECL_UID (f1
);
1485 /* Comparison function for qsort. P1 and P2 are actually of type
1486 "tree *" and point to static destructors. DECL_FINI_PRIORITY is
1487 used to determine the sort order. */
1490 compare_dtor (const void *p1
, const void *p2
)
1497 f1
= *(const tree
*)p1
;
1498 f2
= *(const tree
*)p2
;
1499 priority1
= DECL_FINI_PRIORITY (f1
);
1500 priority2
= DECL_FINI_PRIORITY (f2
);
1502 if (priority1
< priority2
)
1504 else if (priority1
> priority2
)
1507 /* Ensure a stable sort. */
1508 return DECL_UID (f1
) - DECL_UID (f2
);
1511 /* Generate functions to call static constructors and destructors
1512 for targets that do not support .ctors/.dtors sections. These
1513 functions have magic names which are detected by collect2. */
1516 build_cdtor_fns (void)
1518 if (!static_ctors
.is_empty ())
1520 gcc_assert (!targetm
.have_ctors_dtors
|| in_lto_p
);
1521 static_ctors
.qsort (compare_ctor
);
1522 build_cdtor (/*ctor_p=*/true, static_ctors
);
1525 if (!static_dtors
.is_empty ())
1527 gcc_assert (!targetm
.have_ctors_dtors
|| in_lto_p
);
1528 static_dtors
.qsort (compare_dtor
);
1529 build_cdtor (/*ctor_p=*/false, static_dtors
);
1533 /* Look for constructors and destructors and produce function calling them.
1534 This is needed for targets not supporting ctors or dtors, but we perform the
1535 transformation also at linktime to merge possibly numerous
1536 constructors/destructors into single function to improve code locality and
1540 ipa_cdtor_merge (void)
1542 struct cgraph_node
*node
;
1543 FOR_EACH_DEFINED_FUNCTION (node
)
1544 if (DECL_STATIC_CONSTRUCTOR (node
->decl
)
1545 || DECL_STATIC_DESTRUCTOR (node
->decl
))
1546 record_cdtor_fn (node
);
1548 static_ctors
.release ();
1549 static_dtors
.release ();
1553 /* Perform the pass when we have no ctors/dtors support
1554 or at LTO time to merge multiple constructors into single
1558 gate_ipa_cdtor_merge (void)
1560 return !targetm
.have_ctors_dtors
|| (optimize
&& in_lto_p
);
1565 const pass_data pass_data_ipa_cdtor_merge
=
1567 IPA_PASS
, /* type */
1569 OPTGROUP_NONE
, /* optinfo_flags */
1570 true, /* has_gate */
1571 true, /* has_execute */
1572 TV_CGRAPHOPT
, /* tv_id */
1573 0, /* properties_required */
1574 0, /* properties_provided */
1575 0, /* properties_destroyed */
1576 0, /* todo_flags_start */
1577 0, /* todo_flags_finish */
1580 class pass_ipa_cdtor_merge
: public ipa_opt_pass_d
1583 pass_ipa_cdtor_merge (gcc::context
*ctxt
)
1584 : ipa_opt_pass_d (pass_data_ipa_cdtor_merge
, ctxt
,
1585 NULL
, /* generate_summary */
1586 NULL
, /* write_summary */
1587 NULL
, /* read_summary */
1588 NULL
, /* write_optimization_summary */
1589 NULL
, /* read_optimization_summary */
1590 NULL
, /* stmt_fixup */
1591 0, /* function_transform_todo_flags_start */
1592 NULL
, /* function_transform */
1593 NULL
) /* variable_transform */
1596 /* opt_pass methods: */
1597 bool gate () { return gate_ipa_cdtor_merge (); }
1598 unsigned int execute () { return ipa_cdtor_merge (); }
1600 }; // class pass_ipa_cdtor_merge
1605 make_pass_ipa_cdtor_merge (gcc::context
*ctxt
)
1607 return new pass_ipa_cdtor_merge (ctxt
);