arm.md (split for eq(reg, 0)): Add variants for ARMv5 and Thumb2.
[official-gcc.git] / gcc / ipa.c
blob0f2a5c8b424d0f9594d8b520c33b5b25c6b347de
1 /* Basic IPA optimizations and utilities.
2 Copyright (C) 2003-2013 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "tm.h"
24 #include "cgraph.h"
25 #include "tree-pass.h"
26 #include "gimple.h"
27 #include "ggc.h"
28 #include "flags.h"
29 #include "pointer-set.h"
30 #include "target.h"
31 #include "tree-iterator.h"
32 #include "ipa-utils.h"
33 #include "pointer-set.h"
34 #include "ipa-inline.h"
35 #include "hash-table.h"
36 #include "tree-inline.h"
37 #include "profile.h"
38 #include "params.h"
39 #include "lto-streamer.h"
40 #include "data-streamer.h"
42 /* Return true when NODE can not be local. Worker for cgraph_local_node_p. */
44 static bool
45 cgraph_non_local_node_p_1 (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
47 /* FIXME: Aliases can be local, but i386 gets thunks wrong then. */
48 return !(cgraph_only_called_directly_or_aliased_p (node)
49 && !ipa_ref_has_aliases_p (&node->symbol.ref_list)
50 && node->symbol.definition
51 && !DECL_EXTERNAL (node->symbol.decl)
52 && !node->symbol.externally_visible
53 && !node->symbol.used_from_other_partition
54 && !node->symbol.in_other_partition);
57 /* Return true when function can be marked local. */
59 static bool
60 cgraph_local_node_p (struct cgraph_node *node)
62 struct cgraph_node *n = cgraph_function_or_thunk_node (node, NULL);
64 /* FIXME: thunks can be considered local, but we need prevent i386
65 from attempting to change calling convention of them. */
66 if (n->thunk.thunk_p)
67 return false;
68 return !cgraph_for_node_and_aliases (n,
69 cgraph_non_local_node_p_1, NULL, true);
73 /* Return true when NODE has ADDR reference. */
75 static bool
76 has_addr_references_p (struct cgraph_node *node,
77 void *data ATTRIBUTE_UNUSED)
79 int i;
80 struct ipa_ref *ref;
82 for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list,
83 i, ref); i++)
84 if (ref->use == IPA_REF_ADDR)
85 return true;
86 return false;
89 /* Look for all functions inlined to NODE and update their inlined_to pointers
90 to INLINED_TO. */
92 static void
93 update_inlined_to_pointer (struct cgraph_node *node, struct cgraph_node *inlined_to)
95 struct cgraph_edge *e;
96 for (e = node->callees; e; e = e->next_callee)
97 if (e->callee->global.inlined_to)
99 e->callee->global.inlined_to = inlined_to;
100 update_inlined_to_pointer (e->callee, inlined_to);
104 /* Add symtab NODE to queue starting at FIRST.
106 The queue is linked via AUX pointers and terminated by pointer to 1.
107 We enqueue nodes at two occasions: when we find them reachable or when we find
108 their bodies needed for further clonning. In the second case we mark them
109 by pointer to 2 after processing so they are re-queue when they become
110 reachable. */
112 static void
113 enqueue_node (symtab_node node, symtab_node *first,
114 struct pointer_set_t *reachable)
116 /* Node is still in queue; do nothing. */
117 if (node->symbol.aux && node->symbol.aux != (void *) 2)
118 return;
119 /* Node was already processed as unreachable, re-enqueue
120 only if it became reachable now. */
121 if (node->symbol.aux == (void *)2 && !pointer_set_contains (reachable, node))
122 return;
123 node->symbol.aux = *first;
124 *first = node;
127 /* Process references. */
129 static void
130 process_references (struct ipa_ref_list *list,
131 symtab_node *first,
132 bool before_inlining_p,
133 struct pointer_set_t *reachable)
135 int i;
136 struct ipa_ref *ref;
137 for (i = 0; ipa_ref_list_reference_iterate (list, i, ref); i++)
139 symtab_node node = ref->referred;
141 if (node->symbol.definition
142 && ((!DECL_EXTERNAL (node->symbol.decl) || node->symbol.alias)
143 || (before_inlining_p
144 /* We use variable constructors during late complation for
145 constant folding. Keep references alive so partitioning
146 knows about potential references. */
147 || (TREE_CODE (node->symbol.decl) == VAR_DECL
148 && flag_wpa && const_value_known_p (node->symbol.decl)))))
149 pointer_set_insert (reachable, node);
150 enqueue_node ((symtab_node) node, first, reachable);
155 /* Perform reachability analysis and reclaim all unreachable nodes.
157 The algorithm is basically mark&sweep but with some extra refinements:
159 - reachable extern inline functions needs special handling; the bodies needs
160 to stay in memory until inlining in hope that they will be inlined.
161 After inlining we release their bodies and turn them into unanalyzed
162 nodes even when they are reachable.
164 BEFORE_INLINING_P specify whether we are before or after inlining.
166 - virtual functions are kept in callgraph even if they seem unreachable in
167 hope calls to them will be devirtualized.
169 Again we remove them after inlining. In late optimization some
170 devirtualization may happen, but it is not importnat since we won't inline
171 the call. In theory early opts and IPA should work out all important cases.
173 - virtual clones needs bodies of their origins for later materialization;
174 this means that we want to keep the body even if the origin is unreachable
175 otherwise. To avoid origin from sitting in the callgraph and being
176 walked by IPA passes, we turn them into unanalyzed nodes with body
177 defined.
179 We maintain set of function declaration where body needs to stay in
180 body_needed_for_clonning
182 Inline clones represent special case: their declaration match the
183 declaration of origin and cgraph_remove_node already knows how to
184 reshape callgraph and preserve body when offline copy of function or
185 inline clone is being removed.
187 - C++ virtual tables keyed to other unit are represented as DECL_EXTERNAL
188 variables with DECL_INITIAL set. We finalize these and keep reachable
189 ones around for constant folding purposes. After inlining we however
190 stop walking their references to let everything static referneced by them
191 to be removed when it is otherwise unreachable.
193 We maintain queue of both reachable symbols (i.e. defined symbols that needs
194 to stay) and symbols that are in boundary (i.e. external symbols referenced
195 by reachable symbols or origins of clones). The queue is represented
196 as linked list by AUX pointer terminated by 1.
198 A the end we keep all reachable symbols. For symbols in boundary we always
199 turn definition into a declaration, but we may keep function body around
200 based on body_needed_for_clonning
202 All symbols that enter the queue have AUX pointer non-zero and are in the
203 boundary. Pointer set REACHABLE is used to track reachable symbols.
205 Every symbol can be visited twice - once as part of boundary and once
206 as real reachable symbol. enqueue_node needs to decide whether the
207 node needs to be re-queued for second processing. For this purpose
208 we set AUX pointer of processed symbols in the boundary to constant 2. */
210 bool
211 symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
213 symtab_node first = (symtab_node) (void *) 1;
214 struct cgraph_node *node, *next;
215 struct varpool_node *vnode, *vnext;
216 bool changed = false;
217 struct pointer_set_t *reachable = pointer_set_create ();
218 struct pointer_set_t *body_needed_for_clonning = pointer_set_create ();
220 #ifdef ENABLE_CHECKING
221 verify_symtab ();
222 #endif
223 if (file)
224 fprintf (file, "\nReclaiming functions:");
225 #ifdef ENABLE_CHECKING
226 FOR_EACH_FUNCTION (node)
227 gcc_assert (!node->symbol.aux);
228 FOR_EACH_VARIABLE (vnode)
229 gcc_assert (!vnode->symbol.aux);
230 #endif
231 /* Mark functions whose bodies are obviously needed.
232 This is mostly when they can be referenced externally. Inline clones
233 are special since their declarations are shared with master clone and thus
234 cgraph_can_remove_if_no_direct_calls_and_refs_p should not be called on them. */
235 FOR_EACH_DEFINED_FUNCTION (node)
236 if (!node->global.inlined_to
237 && (!cgraph_can_remove_if_no_direct_calls_and_refs_p (node)
238 /* Keep around virtual functions for possible devirtualization. */
239 || (before_inlining_p
240 && DECL_VIRTUAL_P (node->symbol.decl))))
242 gcc_assert (!node->global.inlined_to);
243 pointer_set_insert (reachable, node);
244 enqueue_node ((symtab_node)node, &first, reachable);
246 else
247 gcc_assert (!node->symbol.aux);
249 /* Mark variables that are obviously needed. */
250 FOR_EACH_DEFINED_VARIABLE (vnode)
251 if (!varpool_can_remove_if_no_refs (vnode))
253 pointer_set_insert (reachable, vnode);
254 enqueue_node ((symtab_node)vnode, &first, reachable);
257 /* Perform reachability analysis. */
258 while (first != (symtab_node) (void *) 1)
260 bool in_boundary_p = !pointer_set_contains (reachable, first);
261 symtab_node node = first;
263 first = (symtab_node)first->symbol.aux;
265 /* If we are processing symbol in boundary, mark its AUX pointer for
266 possible later re-processing in enqueue_node. */
267 if (in_boundary_p)
268 node->symbol.aux = (void *)2;
269 else
271 /* If any symbol in a comdat group is reachable, force
272 all other in the same comdat group to be also reachable. */
273 if (node->symbol.same_comdat_group)
275 symtab_node next;
276 for (next = node->symbol.same_comdat_group;
277 next != node;
278 next = next->symbol.same_comdat_group)
279 if (!pointer_set_insert (reachable, next))
280 enqueue_node ((symtab_node) next, &first, reachable);
282 /* Mark references as reachable. */
283 process_references (&node->symbol.ref_list, &first,
284 before_inlining_p, reachable);
287 if (cgraph_node *cnode = dyn_cast <cgraph_node> (node))
289 /* Mark the callees reachable unless they are direct calls to extern
290 inline functions we decided to not inline. */
291 if (!in_boundary_p)
293 struct cgraph_edge *e;
294 for (e = cnode->callees; e; e = e->next_callee)
296 if (e->callee->symbol.definition
297 && (!e->inline_failed
298 || !DECL_EXTERNAL (e->callee->symbol.decl)
299 || e->callee->symbol.alias
300 || before_inlining_p))
301 pointer_set_insert (reachable, e->callee);
302 enqueue_node ((symtab_node) e->callee, &first, reachable);
305 /* When inline clone exists, mark body to be preserved so when removing
306 offline copy of the function we don't kill it. */
307 if (!cnode->symbol.alias && cnode->global.inlined_to)
308 pointer_set_insert (body_needed_for_clonning, cnode->symbol.decl);
311 /* For non-inline clones, force their origins to the boundary and ensure
312 that body is not removed. */
313 while (cnode->clone_of
314 && !gimple_has_body_p (cnode->symbol.decl))
316 bool noninline = cnode->clone_of->symbol.decl != cnode->symbol.decl;
317 cnode = cnode->clone_of;
318 if (noninline)
320 pointer_set_insert (body_needed_for_clonning, cnode->symbol.decl);
321 enqueue_node ((symtab_node)cnode, &first, reachable);
322 break;
326 /* When we see constructor of external variable, keep referred nodes in the
327 boundary. This will also hold initializers of the external vars NODE
328 refers to. */
329 varpool_node *vnode = dyn_cast <varpool_node> (node);
330 if (vnode
331 && DECL_EXTERNAL (node->symbol.decl)
332 && !vnode->symbol.alias
333 && in_boundary_p)
335 struct ipa_ref *ref;
336 for (int i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list, i, ref); i++)
337 enqueue_node (ref->referred, &first, reachable);
341 /* Remove unreachable functions. */
342 for (node = cgraph_first_function (); node; node = next)
344 next = cgraph_next_function (node);
346 /* If node is not needed at all, remove it. */
347 if (!node->symbol.aux)
349 if (file)
350 fprintf (file, " %s", cgraph_node_name (node));
351 cgraph_remove_node (node);
352 changed = true;
354 /* If node is unreachable, remove its body. */
355 else if (!pointer_set_contains (reachable, node))
357 if (!pointer_set_contains (body_needed_for_clonning, node->symbol.decl))
358 cgraph_release_function_body (node);
359 if (node->symbol.definition)
361 if (file)
362 fprintf (file, " %s", cgraph_node_name (node));
363 cgraph_reset_node (node);
364 changed = true;
369 /* Inline clones might be kept around so their materializing allows further
370 cloning. If the function the clone is inlined into is removed, we need
371 to turn it into normal cone. */
372 FOR_EACH_FUNCTION (node)
374 if (node->global.inlined_to
375 && !node->callers)
377 gcc_assert (node->clones);
378 node->global.inlined_to = NULL;
379 update_inlined_to_pointer (node, node);
381 node->symbol.aux = NULL;
384 /* Remove unreachable variables. */
385 if (file)
386 fprintf (file, "\nReclaiming variables:");
387 for (vnode = varpool_first_variable (); vnode; vnode = vnext)
389 vnext = varpool_next_variable (vnode);
390 if (!vnode->symbol.aux
391 /* For can_refer_decl_in_current_unit_p we want to track for
392 all external variables if they are defined in other partition
393 or not. */
394 && (!flag_ltrans || !DECL_EXTERNAL (vnode->symbol.decl)))
396 if (file)
397 fprintf (file, " %s", varpool_node_name (vnode));
398 varpool_remove_node (vnode);
399 changed = true;
401 else if (!pointer_set_contains (reachable, vnode))
403 if (vnode->symbol.definition)
405 if (file)
406 fprintf (file, " %s", varpool_node_name (vnode));
407 changed = true;
409 vnode->symbol.definition = false;
410 vnode->symbol.analyzed = false;
411 vnode->symbol.aux = NULL;
413 /* Keep body if it may be useful for constant folding. */
414 if (!const_value_known_p (vnode->symbol.decl))
415 varpool_remove_initializer (vnode);
416 ipa_remove_all_references (&vnode->symbol.ref_list);
418 else
419 vnode->symbol.aux = NULL;
422 pointer_set_destroy (reachable);
423 pointer_set_destroy (body_needed_for_clonning);
425 /* Now update address_taken flags and try to promote functions to be local. */
426 if (file)
427 fprintf (file, "\nClearing address taken flags:");
428 FOR_EACH_DEFINED_FUNCTION (node)
429 if (node->symbol.address_taken
430 && !node->symbol.used_from_other_partition)
432 if (!cgraph_for_node_and_aliases (node, has_addr_references_p, NULL, true))
434 if (file)
435 fprintf (file, " %s", cgraph_node_name (node));
436 node->symbol.address_taken = false;
437 changed = true;
438 if (cgraph_local_node_p (node))
440 node->local.local = true;
441 if (file)
442 fprintf (file, " (local)");
446 if (file)
447 fprintf (file, "\n");
449 #ifdef ENABLE_CHECKING
450 verify_symtab ();
451 #endif
453 /* If we removed something, perhaps profile could be improved. */
454 if (changed && optimize && inline_edge_summary_vec.exists ())
455 FOR_EACH_DEFINED_FUNCTION (node)
456 cgraph_propagate_frequency (node);
458 return changed;
461 /* Discover variables that have no longer address taken or that are read only
462 and update their flags.
464 FIXME: This can not be done in between gimplify and omp_expand since
465 readonly flag plays role on what is shared and what is not. Currently we do
466 this transformation as part of whole program visibility and re-do at
467 ipa-reference pass (to take into account clonning), but it would
468 make sense to do it before early optimizations. */
470 void
471 ipa_discover_readonly_nonaddressable_vars (void)
473 struct varpool_node *vnode;
474 if (dump_file)
475 fprintf (dump_file, "Clearing variable flags:");
476 FOR_EACH_VARIABLE (vnode)
477 if (vnode->symbol.definition && varpool_all_refs_explicit_p (vnode)
478 && (TREE_ADDRESSABLE (vnode->symbol.decl)
479 || !TREE_READONLY (vnode->symbol.decl)))
481 bool written = false;
482 bool address_taken = false;
483 int i;
484 struct ipa_ref *ref;
485 for (i = 0; ipa_ref_list_referring_iterate (&vnode->symbol.ref_list,
486 i, ref)
487 && (!written || !address_taken); i++)
488 switch (ref->use)
490 case IPA_REF_ADDR:
491 address_taken = true;
492 break;
493 case IPA_REF_LOAD:
494 break;
495 case IPA_REF_STORE:
496 written = true;
497 break;
499 if (TREE_ADDRESSABLE (vnode->symbol.decl) && !address_taken)
501 if (dump_file)
502 fprintf (dump_file, " %s (addressable)", varpool_node_name (vnode));
503 TREE_ADDRESSABLE (vnode->symbol.decl) = 0;
505 if (!TREE_READONLY (vnode->symbol.decl) && !address_taken && !written
506 /* Making variable in explicit section readonly can cause section
507 type conflict.
508 See e.g. gcc.c-torture/compile/pr23237.c */
509 && DECL_SECTION_NAME (vnode->symbol.decl) == NULL)
511 if (dump_file)
512 fprintf (dump_file, " %s (read-only)", varpool_node_name (vnode));
513 TREE_READONLY (vnode->symbol.decl) = 1;
516 if (dump_file)
517 fprintf (dump_file, "\n");
520 /* Return true when there is a reference to node and it is not vtable. */
521 static bool
522 address_taken_from_non_vtable_p (symtab_node node)
524 int i;
525 struct ipa_ref *ref;
526 for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list,
527 i, ref); i++)
528 if (ref->use == IPA_REF_ADDR)
530 struct varpool_node *node;
531 if (is_a <cgraph_node> (ref->referring))
532 return true;
533 node = ipa_ref_referring_varpool_node (ref);
534 if (!DECL_VIRTUAL_P (node->symbol.decl))
535 return true;
537 return false;
540 /* A helper for comdat_can_be_unshared_p. */
542 static bool
543 comdat_can_be_unshared_p_1 (symtab_node node)
545 /* When address is taken, we don't know if equality comparison won't
546 break eventaully. Exception are virutal functions and vtables, where
547 this is not possible by language standard. */
548 if (!DECL_VIRTUAL_P (node->symbol.decl)
549 && address_taken_from_non_vtable_p (node))
550 return false;
552 /* If the symbol is used in some weird way, better to not touch it. */
553 if (node->symbol.force_output)
554 return false;
556 /* Explicit instantiations needs to be output when possibly
557 used externally. */
558 if (node->symbol.forced_by_abi
559 && TREE_PUBLIC (node->symbol.decl)
560 && (node->symbol.resolution != LDPR_PREVAILING_DEF_IRONLY
561 && !flag_whole_program))
562 return false;
564 /* Non-readonly and volatile variables can not be duplicated. */
565 if (is_a <varpool_node> (node)
566 && (!TREE_READONLY (node->symbol.decl)
567 || TREE_THIS_VOLATILE (node->symbol.decl)))
568 return false;
569 return true;
572 /* COMDAT functions must be shared only if they have address taken,
573 otherwise we can produce our own private implementation with
574 -fwhole-program.
575 Return true when turning COMDAT functoin static can not lead to wrong
576 code when the resulting object links with a library defining same COMDAT.
578 Virtual functions do have their addresses taken from the vtables,
579 but in C++ there is no way to compare their addresses for equality. */
581 static bool
582 comdat_can_be_unshared_p (symtab_node node)
584 if (!comdat_can_be_unshared_p_1 (node))
585 return false;
586 if (node->symbol.same_comdat_group)
588 symtab_node next;
590 /* If more than one function is in the same COMDAT group, it must
591 be shared even if just one function in the comdat group has
592 address taken. */
593 for (next = node->symbol.same_comdat_group;
594 next != node; next = next->symbol.same_comdat_group)
595 if (!comdat_can_be_unshared_p_1 (next))
596 return false;
598 return true;
601 /* Return true when function NODE should be considered externally visible. */
603 static bool
604 cgraph_externally_visible_p (struct cgraph_node *node,
605 bool whole_program)
607 if (!node->symbol.definition)
608 return false;
609 if (!TREE_PUBLIC (node->symbol.decl)
610 || DECL_EXTERNAL (node->symbol.decl))
611 return false;
613 /* Do not try to localize built-in functions yet. One of problems is that we
614 end up mangling their asm for WHOPR that makes it impossible to call them
615 using the implicit built-in declarations anymore. Similarly this enables
616 us to remove them as unreachable before actual calls may appear during
617 expansion or folding. */
618 if (DECL_BUILT_IN (node->symbol.decl))
619 return true;
621 /* If linker counts on us, we must preserve the function. */
622 if (symtab_used_from_object_file_p ((symtab_node) node))
623 return true;
624 if (DECL_PRESERVE_P (node->symbol.decl))
625 return true;
626 if (lookup_attribute ("externally_visible",
627 DECL_ATTRIBUTES (node->symbol.decl)))
628 return true;
629 if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
630 && lookup_attribute ("dllexport",
631 DECL_ATTRIBUTES (node->symbol.decl)))
632 return true;
633 if (node->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY)
634 return false;
635 /* When doing LTO or whole program, we can bring COMDAT functoins static.
636 This improves code quality and we know we will duplicate them at most twice
637 (in the case that we are not using plugin and link with object file
638 implementing same COMDAT) */
639 if ((in_lto_p || whole_program)
640 && DECL_COMDAT (node->symbol.decl)
641 && comdat_can_be_unshared_p ((symtab_node) node))
642 return false;
644 /* When doing link time optimizations, hidden symbols become local. */
645 if (in_lto_p
646 && (DECL_VISIBILITY (node->symbol.decl) == VISIBILITY_HIDDEN
647 || DECL_VISIBILITY (node->symbol.decl) == VISIBILITY_INTERNAL)
648 /* Be sure that node is defined in IR file, not in other object
649 file. In that case we don't set used_from_other_object_file. */
650 && node->symbol.definition)
652 else if (!whole_program)
653 return true;
655 if (MAIN_NAME_P (DECL_NAME (node->symbol.decl)))
656 return true;
658 return false;
661 /* Return true when variable VNODE should be considered externally visible. */
663 bool
664 varpool_externally_visible_p (struct varpool_node *vnode)
666 if (DECL_EXTERNAL (vnode->symbol.decl))
667 return true;
669 if (!TREE_PUBLIC (vnode->symbol.decl))
670 return false;
672 /* If linker counts on us, we must preserve the function. */
673 if (symtab_used_from_object_file_p ((symtab_node) vnode))
674 return true;
676 if (DECL_HARD_REGISTER (vnode->symbol.decl))
677 return true;
678 if (DECL_PRESERVE_P (vnode->symbol.decl))
679 return true;
680 if (lookup_attribute ("externally_visible",
681 DECL_ATTRIBUTES (vnode->symbol.decl)))
682 return true;
683 if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
684 && lookup_attribute ("dllexport",
685 DECL_ATTRIBUTES (vnode->symbol.decl)))
686 return true;
688 /* See if we have linker information about symbol not being used or
689 if we need to make guess based on the declaration.
691 Even if the linker clams the symbol is unused, never bring internal
692 symbols that are declared by user as used or externally visible.
693 This is needed for i.e. references from asm statements. */
694 if (symtab_used_from_object_file_p ((symtab_node) vnode))
695 return true;
696 if (vnode->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY)
697 return false;
699 /* As a special case, the COMDAT virtual tables can be unshared.
700 In LTO mode turn vtables into static variables. The variable is readonly,
701 so this does not enable more optimization, but referring static var
702 is faster for dynamic linking. Also this match logic hidding vtables
703 from LTO symbol tables. */
704 if ((in_lto_p || flag_whole_program)
705 && DECL_COMDAT (vnode->symbol.decl)
706 && comdat_can_be_unshared_p ((symtab_node) vnode))
707 return false;
709 /* When doing link time optimizations, hidden symbols become local. */
710 if (in_lto_p
711 && (DECL_VISIBILITY (vnode->symbol.decl) == VISIBILITY_HIDDEN
712 || DECL_VISIBILITY (vnode->symbol.decl) == VISIBILITY_INTERNAL)
713 /* Be sure that node is defined in IR file, not in other object
714 file. In that case we don't set used_from_other_object_file. */
715 && vnode->symbol.definition)
717 else if (!flag_whole_program)
718 return true;
720 /* Do not attempt to privatize COMDATS by default.
721 This would break linking with C++ libraries sharing
722 inline definitions.
724 FIXME: We can do so for readonly vars with no address taken and
725 possibly also for vtables since no direct pointer comparsion is done.
726 It might be interesting to do so to reduce linking overhead. */
727 if (DECL_COMDAT (vnode->symbol.decl) || DECL_WEAK (vnode->symbol.decl))
728 return true;
729 return false;
732 /* Mark visibility of all functions.
734 A local function is one whose calls can occur only in the current
735 compilation unit and all its calls are explicit, so we can change
736 its calling convention. We simply mark all static functions whose
737 address is not taken as local.
739 We also change the TREE_PUBLIC flag of all declarations that are public
740 in language point of view but we want to overwrite this default
741 via visibilities for the backend point of view. */
743 static unsigned int
744 function_and_variable_visibility (bool whole_program)
746 struct cgraph_node *node;
747 struct varpool_node *vnode;
749 /* All aliases should be procssed at this point. */
750 gcc_checking_assert (!alias_pairs || !alias_pairs->length());
752 FOR_EACH_FUNCTION (node)
754 int flags = flags_from_decl_or_type (node->symbol.decl);
756 /* Optimize away PURE and CONST constructors and destructors. */
757 if (optimize
758 && (flags & (ECF_CONST | ECF_PURE))
759 && !(flags & ECF_LOOPING_CONST_OR_PURE))
761 DECL_STATIC_CONSTRUCTOR (node->symbol.decl) = 0;
762 DECL_STATIC_DESTRUCTOR (node->symbol.decl) = 0;
765 /* Frontends and alias code marks nodes as needed before parsing is finished.
766 We may end up marking as node external nodes where this flag is meaningless
767 strip it. */
768 if (DECL_EXTERNAL (node->symbol.decl) || !node->symbol.definition)
770 node->symbol.force_output = 0;
771 node->symbol.forced_by_abi = 0;
774 /* C++ FE on lack of COMDAT support create local COMDAT functions
775 (that ought to be shared but can not due to object format
776 limitations). It is necessary to keep the flag to make rest of C++ FE
777 happy. Clear the flag here to avoid confusion in middle-end. */
778 if (DECL_COMDAT (node->symbol.decl) && !TREE_PUBLIC (node->symbol.decl))
779 DECL_COMDAT (node->symbol.decl) = 0;
781 /* For external decls stop tracking same_comdat_group. It doesn't matter
782 what comdat group they are in when they won't be emitted in this TU. */
783 if (node->symbol.same_comdat_group && DECL_EXTERNAL (node->symbol.decl))
785 #ifdef ENABLE_CHECKING
786 symtab_node n;
788 for (n = node->symbol.same_comdat_group;
789 n != (symtab_node)node;
790 n = n->symbol.same_comdat_group)
791 /* If at least one of same comdat group functions is external,
792 all of them have to be, otherwise it is a front-end bug. */
793 gcc_assert (DECL_EXTERNAL (n->symbol.decl));
794 #endif
795 symtab_dissolve_same_comdat_group_list ((symtab_node) node);
797 gcc_assert ((!DECL_WEAK (node->symbol.decl)
798 && !DECL_COMDAT (node->symbol.decl))
799 || TREE_PUBLIC (node->symbol.decl)
800 || node->symbol.weakref
801 || DECL_EXTERNAL (node->symbol.decl));
802 if (cgraph_externally_visible_p (node, whole_program))
804 gcc_assert (!node->global.inlined_to);
805 node->symbol.externally_visible = true;
807 else
809 node->symbol.externally_visible = false;
810 node->symbol.forced_by_abi = false;
812 if (!node->symbol.externally_visible
813 && node->symbol.definition && !node->symbol.weakref
814 && !DECL_EXTERNAL (node->symbol.decl))
816 gcc_assert (whole_program || in_lto_p
817 || !TREE_PUBLIC (node->symbol.decl));
818 node->symbol.unique_name = ((node->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY
819 || node->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
820 && TREE_PUBLIC (node->symbol.decl));
821 symtab_make_decl_local (node->symbol.decl);
822 node->symbol.resolution = LDPR_PREVAILING_DEF_IRONLY;
823 if (node->symbol.same_comdat_group)
824 /* cgraph_externally_visible_p has already checked all other nodes
825 in the group and they will all be made local. We need to
826 dissolve the group at once so that the predicate does not
827 segfault though. */
828 symtab_dissolve_same_comdat_group_list ((symtab_node) node);
831 if (node->thunk.thunk_p
832 && TREE_PUBLIC (node->symbol.decl))
834 struct cgraph_node *decl_node = node;
836 decl_node = cgraph_function_node (decl_node->callees->callee, NULL);
838 /* Thunks have the same visibility as function they are attached to.
839 Make sure the C++ front end set this up properly. */
840 if (DECL_ONE_ONLY (decl_node->symbol.decl))
842 gcc_checking_assert (DECL_COMDAT (node->symbol.decl)
843 == DECL_COMDAT (decl_node->symbol.decl));
844 gcc_checking_assert (DECL_COMDAT_GROUP (node->symbol.decl)
845 == DECL_COMDAT_GROUP (decl_node->symbol.decl));
846 gcc_checking_assert (node->symbol.same_comdat_group);
848 if (DECL_EXTERNAL (decl_node->symbol.decl))
849 DECL_EXTERNAL (node->symbol.decl) = 1;
852 FOR_EACH_DEFINED_FUNCTION (node)
853 node->local.local = cgraph_local_node_p (node);
854 FOR_EACH_VARIABLE (vnode)
856 /* weak flag makes no sense on local variables. */
857 gcc_assert (!DECL_WEAK (vnode->symbol.decl)
858 || vnode->symbol.weakref
859 || TREE_PUBLIC (vnode->symbol.decl)
860 || DECL_EXTERNAL (vnode->symbol.decl));
861 /* In several cases declarations can not be common:
863 - when declaration has initializer
864 - when it is in weak
865 - when it has specific section
866 - when it resides in non-generic address space.
867 - if declaration is local, it will get into .local common section
868 so common flag is not needed. Frontends still produce these in
869 certain cases, such as for:
871 static int a __attribute__ ((common))
873 Canonicalize things here and clear the redundant flag. */
874 if (DECL_COMMON (vnode->symbol.decl)
875 && (!(TREE_PUBLIC (vnode->symbol.decl)
876 || DECL_EXTERNAL (vnode->symbol.decl))
877 || (DECL_INITIAL (vnode->symbol.decl)
878 && DECL_INITIAL (vnode->symbol.decl) != error_mark_node)
879 || DECL_WEAK (vnode->symbol.decl)
880 || DECL_SECTION_NAME (vnode->symbol.decl) != NULL
881 || ! (ADDR_SPACE_GENERIC_P
882 (TYPE_ADDR_SPACE (TREE_TYPE (vnode->symbol.decl))))))
883 DECL_COMMON (vnode->symbol.decl) = 0;
885 FOR_EACH_DEFINED_VARIABLE (vnode)
887 if (!vnode->symbol.definition)
888 continue;
889 if (varpool_externally_visible_p (vnode))
890 vnode->symbol.externally_visible = true;
891 else
893 vnode->symbol.externally_visible = false;
894 vnode->symbol.forced_by_abi = false;
896 if (!vnode->symbol.externally_visible
897 && !vnode->symbol.weakref)
899 gcc_assert (in_lto_p || whole_program || !TREE_PUBLIC (vnode->symbol.decl));
900 symtab_make_decl_local (vnode->symbol.decl);
901 vnode->symbol.unique_name = ((vnode->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY
902 || vnode->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
903 && TREE_PUBLIC (vnode->symbol.decl));
904 if (vnode->symbol.same_comdat_group)
905 symtab_dissolve_same_comdat_group_list ((symtab_node) vnode);
906 vnode->symbol.resolution = LDPR_PREVAILING_DEF_IRONLY;
910 if (dump_file)
912 fprintf (dump_file, "\nMarking local functions:");
913 FOR_EACH_DEFINED_FUNCTION (node)
914 if (node->local.local)
915 fprintf (dump_file, " %s", cgraph_node_name (node));
916 fprintf (dump_file, "\n\n");
917 fprintf (dump_file, "\nMarking externally visible functions:");
918 FOR_EACH_DEFINED_FUNCTION (node)
919 if (node->symbol.externally_visible)
920 fprintf (dump_file, " %s", cgraph_node_name (node));
921 fprintf (dump_file, "\n\n");
922 fprintf (dump_file, "\nMarking externally visible variables:");
923 FOR_EACH_DEFINED_VARIABLE (vnode)
924 if (vnode->symbol.externally_visible)
925 fprintf (dump_file, " %s", varpool_node_name (vnode));
926 fprintf (dump_file, "\n\n");
928 cgraph_function_flags_ready = true;
929 return 0;
932 /* Local function pass handling visibilities. This happens before LTO streaming
933 so in particular -fwhole-program should be ignored at this level. */
935 static unsigned int
936 local_function_and_variable_visibility (void)
938 return function_and_variable_visibility (flag_whole_program && !flag_lto);
941 struct simple_ipa_opt_pass pass_ipa_function_and_variable_visibility =
944 SIMPLE_IPA_PASS,
945 "visibility", /* name */
946 OPTGROUP_NONE, /* optinfo_flags */
947 NULL, /* gate */
948 local_function_and_variable_visibility,/* execute */
949 NULL, /* sub */
950 NULL, /* next */
951 0, /* static_pass_number */
952 TV_CGRAPHOPT, /* tv_id */
953 0, /* properties_required */
954 0, /* properties_provided */
955 0, /* properties_destroyed */
956 0, /* todo_flags_start */
957 TODO_remove_functions | TODO_dump_symtab /* todo_flags_finish */
961 /* Free inline summary. */
963 static unsigned
964 free_inline_summary (void)
966 inline_free_summary ();
967 return 0;
970 struct simple_ipa_opt_pass pass_ipa_free_inline_summary =
973 SIMPLE_IPA_PASS,
974 "*free_inline_summary", /* name */
975 OPTGROUP_NONE, /* optinfo_flags */
976 NULL, /* gate */
977 free_inline_summary, /* execute */
978 NULL, /* sub */
979 NULL, /* next */
980 0, /* static_pass_number */
981 TV_IPA_FREE_INLINE_SUMMARY, /* tv_id */
982 0, /* properties_required */
983 0, /* properties_provided */
984 0, /* properties_destroyed */
985 0, /* todo_flags_start */
986 0 /* todo_flags_finish */
990 /* Do not re-run on ltrans stage. */
992 static bool
993 gate_whole_program_function_and_variable_visibility (void)
995 return !flag_ltrans;
998 /* Bring functionss local at LTO time with -fwhole-program. */
1000 static unsigned int
1001 whole_program_function_and_variable_visibility (void)
1003 function_and_variable_visibility (flag_whole_program);
1004 if (optimize)
1005 ipa_discover_readonly_nonaddressable_vars ();
1006 return 0;
1009 struct ipa_opt_pass_d pass_ipa_whole_program_visibility =
1012 IPA_PASS,
1013 "whole-program", /* name */
1014 OPTGROUP_NONE, /* optinfo_flags */
1015 gate_whole_program_function_and_variable_visibility,/* gate */
1016 whole_program_function_and_variable_visibility,/* execute */
1017 NULL, /* sub */
1018 NULL, /* next */
1019 0, /* static_pass_number */
1020 TV_CGRAPHOPT, /* tv_id */
1021 0, /* properties_required */
1022 0, /* properties_provided */
1023 0, /* properties_destroyed */
1024 0, /* todo_flags_start */
1025 TODO_remove_functions | TODO_dump_symtab /* todo_flags_finish */
1027 NULL, /* generate_summary */
1028 NULL, /* write_summary */
1029 NULL, /* read_summary */
1030 NULL, /* write_optimization_summary */
1031 NULL, /* read_optimization_summary */
1032 NULL, /* stmt_fixup */
1033 0, /* TODOs */
1034 NULL, /* function_transform */
1035 NULL, /* variable_transform */
1038 /* Entry in the histogram. */
1040 struct histogram_entry
1042 gcov_type count;
1043 int time;
1044 int size;
1047 /* Histogram of profile values.
1048 The histogram is represented as an ordered vector of entries allocated via
1049 histogram_pool. During construction a separate hashtable is kept to lookup
1050 duplicate entries. */
1052 vec<histogram_entry *> histogram;
1053 static alloc_pool histogram_pool;
1055 /* Hashtable support for storing SSA names hashed by their SSA_NAME_VAR. */
1057 struct histogram_hash : typed_noop_remove <histogram_entry>
1059 typedef histogram_entry value_type;
1060 typedef histogram_entry compare_type;
1061 static inline hashval_t hash (const value_type *);
1062 static inline int equal (const value_type *, const compare_type *);
1065 inline hashval_t
1066 histogram_hash::hash (const histogram_entry *val)
1068 return val->count;
1071 inline int
1072 histogram_hash::equal (const histogram_entry *val, const histogram_entry *val2)
1074 return val->count == val2->count;
1077 /* Account TIME and SIZE executed COUNT times into HISTOGRAM.
1078 HASHTABLE is the on-side hash kept to avoid duplicates. */
1080 static void
1081 account_time_size (hash_table <histogram_hash> hashtable,
1082 vec<histogram_entry *> &histogram,
1083 gcov_type count, int time, int size)
1085 histogram_entry key = {count, 0, 0};
1086 histogram_entry **val = hashtable.find_slot (&key, INSERT);
1088 if (!*val)
1090 *val = (histogram_entry *) pool_alloc (histogram_pool);
1091 **val = key;
1092 histogram.safe_push (*val);
1094 (*val)->time += time;
1095 (*val)->size += size;
1099 cmp_counts (const void *v1, const void *v2)
1101 const histogram_entry *h1 = *(const histogram_entry * const *)v1;
1102 const histogram_entry *h2 = *(const histogram_entry * const *)v2;
1103 if (h1->count < h2->count)
1104 return 1;
1105 if (h1->count > h2->count)
1106 return -1;
1107 return 0;
1110 /* Dump HISTOGRAM to FILE. */
1112 static void
1113 dump_histogram (FILE *file, vec<histogram_entry *> histogram)
1115 unsigned int i;
1116 gcov_type overall_time = 0, cumulated_time = 0, cumulated_size = 0, overall_size = 0;
1118 fprintf (dump_file, "Histogram:\n");
1119 for (i = 0; i < histogram.length (); i++)
1121 overall_time += histogram[i]->count * histogram[i]->time;
1122 overall_size += histogram[i]->size;
1124 if (!overall_time)
1125 overall_time = 1;
1126 if (!overall_size)
1127 overall_size = 1;
1128 for (i = 0; i < histogram.length (); i++)
1130 cumulated_time += histogram[i]->count * histogram[i]->time;
1131 cumulated_size += histogram[i]->size;
1132 fprintf (file, " "HOST_WIDEST_INT_PRINT_DEC": time:%i (%2.2f) size:%i (%2.2f)\n",
1133 (HOST_WIDEST_INT) histogram[i]->count,
1134 histogram[i]->time,
1135 cumulated_time * 100.0 / overall_time,
1136 histogram[i]->size,
1137 cumulated_size * 100.0 / overall_size);
1141 /* Collect histogram from CFG profiles. */
1143 static void
1144 ipa_profile_generate_summary (void)
1146 struct cgraph_node *node;
1147 gimple_stmt_iterator gsi;
1148 hash_table <histogram_hash> hashtable;
1149 basic_block bb;
1151 hashtable.create (10);
1152 histogram_pool = create_alloc_pool ("IPA histogram", sizeof (struct histogram_entry),
1153 10);
1155 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
1156 FOR_EACH_BB_FN (bb, DECL_STRUCT_FUNCTION (node->symbol.decl))
1158 int time = 0;
1159 int size = 0;
1160 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1162 time += estimate_num_insns (gsi_stmt (gsi), &eni_time_weights);
1163 size += estimate_num_insns (gsi_stmt (gsi), &eni_size_weights);
1165 account_time_size (hashtable, histogram, bb->count, time, size);
1167 hashtable.dispose ();
1168 histogram.qsort (cmp_counts);
1171 /* Serialize the ipa info for lto. */
1173 static void
1174 ipa_profile_write_summary (void)
1176 struct lto_simple_output_block *ob
1177 = lto_create_simple_output_block (LTO_section_ipa_profile);
1178 unsigned int i;
1180 streamer_write_uhwi_stream (ob->main_stream, histogram.length());
1181 for (i = 0; i < histogram.length (); i++)
1183 streamer_write_gcov_count_stream (ob->main_stream, histogram[i]->count);
1184 streamer_write_uhwi_stream (ob->main_stream, histogram[i]->time);
1185 streamer_write_uhwi_stream (ob->main_stream, histogram[i]->size);
1187 lto_destroy_simple_output_block (ob);
1190 /* Deserialize the ipa info for lto. */
1192 static void
1193 ipa_profile_read_summary (void)
1195 struct lto_file_decl_data ** file_data_vec
1196 = lto_get_file_decl_data ();
1197 struct lto_file_decl_data * file_data;
1198 hash_table <histogram_hash> hashtable;
1199 int j = 0;
1201 hashtable.create (10);
1202 histogram_pool = create_alloc_pool ("IPA histogram", sizeof (struct histogram_entry),
1203 10);
1205 while ((file_data = file_data_vec[j++]))
1207 const char *data;
1208 size_t len;
1209 struct lto_input_block *ib
1210 = lto_create_simple_input_block (file_data,
1211 LTO_section_ipa_profile,
1212 &data, &len);
1213 if (ib)
1215 unsigned int num = streamer_read_uhwi (ib);
1216 unsigned int n;
1217 for (n = 0; n < num; n++)
1219 gcov_type count = streamer_read_gcov_count (ib);
1220 int time = streamer_read_uhwi (ib);
1221 int size = streamer_read_uhwi (ib);
1222 account_time_size (hashtable, histogram,
1223 count, time, size);
1225 lto_destroy_simple_input_block (file_data,
1226 LTO_section_ipa_profile,
1227 ib, data, len);
1230 hashtable.dispose ();
1231 histogram.qsort (cmp_counts);
1234 /* Simple ipa profile pass propagating frequencies across the callgraph. */
1236 static unsigned int
1237 ipa_profile (void)
1239 struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
1240 struct cgraph_edge *e;
1241 int order_pos;
1242 bool something_changed = false;
1243 int i;
1244 gcov_type overall_time = 0, cutoff = 0, cumulated = 0, overall_size = 0;
1246 if (dump_file)
1247 dump_histogram (dump_file, histogram);
1248 for (i = 0; i < (int)histogram.length (); i++)
1250 overall_time += histogram[i]->count * histogram[i]->time;
1251 overall_size += histogram[i]->size;
1253 if (overall_time)
1255 gcov_type threshold;
1257 gcc_assert (overall_size);
1258 if (dump_file)
1260 gcov_type min, cumulated_time = 0, cumulated_size = 0;
1262 fprintf (dump_file, "Overall time: "HOST_WIDEST_INT_PRINT_DEC"\n",
1263 (HOST_WIDEST_INT)overall_time);
1264 min = get_hot_bb_threshold ();
1265 for (i = 0; i < (int)histogram.length () && histogram[i]->count >= min;
1266 i++)
1268 cumulated_time += histogram[i]->count * histogram[i]->time;
1269 cumulated_size += histogram[i]->size;
1271 fprintf (dump_file, "GCOV min count: "HOST_WIDEST_INT_PRINT_DEC
1272 " Time:%3.2f%% Size:%3.2f%%\n",
1273 (HOST_WIDEST_INT)min,
1274 cumulated_time * 100.0 / overall_time,
1275 cumulated_size * 100.0 / overall_size);
1277 cutoff = (overall_time * PARAM_VALUE (HOT_BB_COUNT_WS_PERMILLE) + 500) / 1000;
1278 threshold = 0;
1279 for (i = 0; cumulated < cutoff; i++)
1281 cumulated += histogram[i]->count * histogram[i]->time;
1282 threshold = histogram[i]->count;
1284 if (!threshold)
1285 threshold = 1;
1286 if (dump_file)
1288 gcov_type cumulated_time = 0, cumulated_size = 0;
1290 for (i = 0;
1291 i < (int)histogram.length () && histogram[i]->count >= threshold;
1292 i++)
1294 cumulated_time += histogram[i]->count * histogram[i]->time;
1295 cumulated_size += histogram[i]->size;
1297 fprintf (dump_file, "Determined min count: "HOST_WIDEST_INT_PRINT_DEC
1298 " Time:%3.2f%% Size:%3.2f%%\n",
1299 (HOST_WIDEST_INT)threshold,
1300 cumulated_time * 100.0 / overall_time,
1301 cumulated_size * 100.0 / overall_size);
1303 if (threshold > get_hot_bb_threshold ()
1304 || in_lto_p)
1306 if (dump_file)
1307 fprintf (dump_file, "Threshold updated.\n");
1308 set_hot_bb_threshold (threshold);
1311 histogram.release();
1312 free_alloc_pool (histogram_pool);
1314 order_pos = ipa_reverse_postorder (order);
1315 for (i = order_pos - 1; i >= 0; i--)
1317 if (order[i]->local.local && cgraph_propagate_frequency (order[i]))
1319 for (e = order[i]->callees; e; e = e->next_callee)
1320 if (e->callee->local.local && !e->callee->symbol.aux)
1322 something_changed = true;
1323 e->callee->symbol.aux = (void *)1;
1326 order[i]->symbol.aux = NULL;
1329 while (something_changed)
1331 something_changed = false;
1332 for (i = order_pos - 1; i >= 0; i--)
1334 if (order[i]->symbol.aux && cgraph_propagate_frequency (order[i]))
1336 for (e = order[i]->callees; e; e = e->next_callee)
1337 if (e->callee->local.local && !e->callee->symbol.aux)
1339 something_changed = true;
1340 e->callee->symbol.aux = (void *)1;
1343 order[i]->symbol.aux = NULL;
1346 free (order);
1347 return 0;
1350 static bool
1351 gate_ipa_profile (void)
1353 return flag_ipa_profile;
1356 struct ipa_opt_pass_d pass_ipa_profile =
1359 IPA_PASS,
1360 "profile_estimate", /* name */
1361 OPTGROUP_NONE, /* optinfo_flags */
1362 gate_ipa_profile, /* gate */
1363 ipa_profile, /* execute */
1364 NULL, /* sub */
1365 NULL, /* next */
1366 0, /* static_pass_number */
1367 TV_IPA_PROFILE, /* tv_id */
1368 0, /* properties_required */
1369 0, /* properties_provided */
1370 0, /* properties_destroyed */
1371 0, /* todo_flags_start */
1372 0 /* todo_flags_finish */
1374 ipa_profile_generate_summary, /* generate_summary */
1375 ipa_profile_write_summary, /* write_summary */
1376 ipa_profile_read_summary, /* read_summary */
1377 NULL, /* write_optimization_summary */
1378 NULL, /* read_optimization_summary */
1379 NULL, /* stmt_fixup */
1380 0, /* TODOs */
1381 NULL, /* function_transform */
1382 NULL /* variable_transform */
1385 /* Generate and emit a static constructor or destructor. WHICH must
1386 be one of 'I' (for a constructor) or 'D' (for a destructor). BODY
1387 is a STATEMENT_LIST containing GENERIC statements. PRIORITY is the
1388 initialization priority for this constructor or destructor.
1390 FINAL specify whether the externally visible name for collect2 should
1391 be produced. */
1393 static void
1394 cgraph_build_static_cdtor_1 (char which, tree body, int priority, bool final)
1396 static int counter = 0;
1397 char which_buf[16];
1398 tree decl, name, resdecl;
1400 /* The priority is encoded in the constructor or destructor name.
1401 collect2 will sort the names and arrange that they are called at
1402 program startup. */
1403 if (final)
1404 sprintf (which_buf, "%c_%.5d_%d", which, priority, counter++);
1405 else
1406 /* Proudce sane name but one not recognizable by collect2, just for the
1407 case we fail to inline the function. */
1408 sprintf (which_buf, "sub_%c_%.5d_%d", which, priority, counter++);
1409 name = get_file_function_name (which_buf);
1411 decl = build_decl (input_location, FUNCTION_DECL, name,
1412 build_function_type_list (void_type_node, NULL_TREE));
1413 current_function_decl = decl;
1415 resdecl = build_decl (input_location,
1416 RESULT_DECL, NULL_TREE, void_type_node);
1417 DECL_ARTIFICIAL (resdecl) = 1;
1418 DECL_RESULT (decl) = resdecl;
1419 DECL_CONTEXT (resdecl) = decl;
1421 allocate_struct_function (decl, false);
1423 TREE_STATIC (decl) = 1;
1424 TREE_USED (decl) = 1;
1425 DECL_ARTIFICIAL (decl) = 1;
1426 DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;
1427 DECL_SAVED_TREE (decl) = body;
1428 if (!targetm.have_ctors_dtors && final)
1430 TREE_PUBLIC (decl) = 1;
1431 DECL_PRESERVE_P (decl) = 1;
1433 DECL_UNINLINABLE (decl) = 1;
1435 DECL_INITIAL (decl) = make_node (BLOCK);
1436 TREE_USED (DECL_INITIAL (decl)) = 1;
1438 DECL_SOURCE_LOCATION (decl) = input_location;
1439 cfun->function_end_locus = input_location;
1441 switch (which)
1443 case 'I':
1444 DECL_STATIC_CONSTRUCTOR (decl) = 1;
1445 decl_init_priority_insert (decl, priority);
1446 break;
1447 case 'D':
1448 DECL_STATIC_DESTRUCTOR (decl) = 1;
1449 decl_fini_priority_insert (decl, priority);
1450 break;
1451 default:
1452 gcc_unreachable ();
1455 gimplify_function_tree (decl);
1457 cgraph_add_new_function (decl, false);
1459 set_cfun (NULL);
1460 current_function_decl = NULL;
1463 /* Generate and emit a static constructor or destructor. WHICH must
1464 be one of 'I' (for a constructor) or 'D' (for a destructor). BODY
1465 is a STATEMENT_LIST containing GENERIC statements. PRIORITY is the
1466 initialization priority for this constructor or destructor. */
1468 void
1469 cgraph_build_static_cdtor (char which, tree body, int priority)
1471 cgraph_build_static_cdtor_1 (which, body, priority, false);
1474 /* A vector of FUNCTION_DECLs declared as static constructors. */
1475 static vec<tree> static_ctors;
1476 /* A vector of FUNCTION_DECLs declared as static destructors. */
1477 static vec<tree> static_dtors;
1479 /* When target does not have ctors and dtors, we call all constructor
1480 and destructor by special initialization/destruction function
1481 recognized by collect2.
1483 When we are going to build this function, collect all constructors and
1484 destructors and turn them into normal functions. */
1486 static void
1487 record_cdtor_fn (struct cgraph_node *node)
1489 if (DECL_STATIC_CONSTRUCTOR (node->symbol.decl))
1490 static_ctors.safe_push (node->symbol.decl);
1491 if (DECL_STATIC_DESTRUCTOR (node->symbol.decl))
1492 static_dtors.safe_push (node->symbol.decl);
1493 node = cgraph_get_node (node->symbol.decl);
1494 DECL_DISREGARD_INLINE_LIMITS (node->symbol.decl) = 1;
1497 /* Define global constructors/destructor functions for the CDTORS, of
1498 which they are LEN. The CDTORS are sorted by initialization
1499 priority. If CTOR_P is true, these are constructors; otherwise,
1500 they are destructors. */
1502 static void
1503 build_cdtor (bool ctor_p, vec<tree> cdtors)
1505 size_t i,j;
1506 size_t len = cdtors.length ();
1508 i = 0;
1509 while (i < len)
1511 tree body;
1512 tree fn;
1513 priority_type priority;
1515 priority = 0;
1516 body = NULL_TREE;
1517 j = i;
1520 priority_type p;
1521 fn = cdtors[j];
1522 p = ctor_p ? DECL_INIT_PRIORITY (fn) : DECL_FINI_PRIORITY (fn);
1523 if (j == i)
1524 priority = p;
1525 else if (p != priority)
1526 break;
1527 j++;
1529 while (j < len);
1531 /* When there is only one cdtor and target supports them, do nothing. */
1532 if (j == i + 1
1533 && targetm.have_ctors_dtors)
1535 i++;
1536 continue;
1538 /* Find the next batch of constructors/destructors with the same
1539 initialization priority. */
1540 for (;i < j; i++)
1542 tree call;
1543 fn = cdtors[i];
1544 call = build_call_expr (fn, 0);
1545 if (ctor_p)
1546 DECL_STATIC_CONSTRUCTOR (fn) = 0;
1547 else
1548 DECL_STATIC_DESTRUCTOR (fn) = 0;
1549 /* We do not want to optimize away pure/const calls here.
1550 When optimizing, these should be already removed, when not
1551 optimizing, we want user to be able to breakpoint in them. */
1552 TREE_SIDE_EFFECTS (call) = 1;
1553 append_to_statement_list (call, &body);
1555 gcc_assert (body != NULL_TREE);
1556 /* Generate a function to call all the function of like
1557 priority. */
1558 cgraph_build_static_cdtor_1 (ctor_p ? 'I' : 'D', body, priority, true);
1562 /* Comparison function for qsort. P1 and P2 are actually of type
1563 "tree *" and point to static constructors. DECL_INIT_PRIORITY is
1564 used to determine the sort order. */
1566 static int
1567 compare_ctor (const void *p1, const void *p2)
1569 tree f1;
1570 tree f2;
1571 int priority1;
1572 int priority2;
1574 f1 = *(const tree *)p1;
1575 f2 = *(const tree *)p2;
1576 priority1 = DECL_INIT_PRIORITY (f1);
1577 priority2 = DECL_INIT_PRIORITY (f2);
1579 if (priority1 < priority2)
1580 return -1;
1581 else if (priority1 > priority2)
1582 return 1;
1583 else
1584 /* Ensure a stable sort. Constructors are executed in backwarding
1585 order to make LTO initialize braries first. */
1586 return DECL_UID (f2) - DECL_UID (f1);
1589 /* Comparison function for qsort. P1 and P2 are actually of type
1590 "tree *" and point to static destructors. DECL_FINI_PRIORITY is
1591 used to determine the sort order. */
1593 static int
1594 compare_dtor (const void *p1, const void *p2)
1596 tree f1;
1597 tree f2;
1598 int priority1;
1599 int priority2;
1601 f1 = *(const tree *)p1;
1602 f2 = *(const tree *)p2;
1603 priority1 = DECL_FINI_PRIORITY (f1);
1604 priority2 = DECL_FINI_PRIORITY (f2);
1606 if (priority1 < priority2)
1607 return -1;
1608 else if (priority1 > priority2)
1609 return 1;
1610 else
1611 /* Ensure a stable sort. */
1612 return DECL_UID (f1) - DECL_UID (f2);
1615 /* Generate functions to call static constructors and destructors
1616 for targets that do not support .ctors/.dtors sections. These
1617 functions have magic names which are detected by collect2. */
1619 static void
1620 build_cdtor_fns (void)
1622 if (!static_ctors.is_empty ())
1624 gcc_assert (!targetm.have_ctors_dtors || in_lto_p);
1625 static_ctors.qsort (compare_ctor);
1626 build_cdtor (/*ctor_p=*/true, static_ctors);
1629 if (!static_dtors.is_empty ())
1631 gcc_assert (!targetm.have_ctors_dtors || in_lto_p);
1632 static_dtors.qsort (compare_dtor);
1633 build_cdtor (/*ctor_p=*/false, static_dtors);
1637 /* Look for constructors and destructors and produce function calling them.
1638 This is needed for targets not supporting ctors or dtors, but we perform the
1639 transformation also at linktime to merge possibly numerous
1640 constructors/destructors into single function to improve code locality and
1641 reduce size. */
1643 static unsigned int
1644 ipa_cdtor_merge (void)
1646 struct cgraph_node *node;
1647 FOR_EACH_DEFINED_FUNCTION (node)
1648 if (DECL_STATIC_CONSTRUCTOR (node->symbol.decl)
1649 || DECL_STATIC_DESTRUCTOR (node->symbol.decl))
1650 record_cdtor_fn (node);
1651 build_cdtor_fns ();
1652 static_ctors.release ();
1653 static_dtors.release ();
1654 return 0;
1657 /* Perform the pass when we have no ctors/dtors support
1658 or at LTO time to merge multiple constructors into single
1659 function. */
1661 static bool
1662 gate_ipa_cdtor_merge (void)
1664 return !targetm.have_ctors_dtors || (optimize && in_lto_p);
1667 struct ipa_opt_pass_d pass_ipa_cdtor_merge =
1670 IPA_PASS,
1671 "cdtor", /* name */
1672 OPTGROUP_NONE, /* optinfo_flags */
1673 gate_ipa_cdtor_merge, /* gate */
1674 ipa_cdtor_merge, /* execute */
1675 NULL, /* sub */
1676 NULL, /* next */
1677 0, /* static_pass_number */
1678 TV_CGRAPHOPT, /* tv_id */
1679 0, /* properties_required */
1680 0, /* properties_provided */
1681 0, /* properties_destroyed */
1682 0, /* todo_flags_start */
1683 0 /* todo_flags_finish */
1685 NULL, /* generate_summary */
1686 NULL, /* write_summary */
1687 NULL, /* read_summary */
1688 NULL, /* write_optimization_summary */
1689 NULL, /* read_optimization_summary */
1690 NULL, /* stmt_fixup */
1691 0, /* TODOs */
1692 NULL, /* function_transform */
1693 NULL /* variable_transform */