2013-05-30 Ed Smith-Rowland <3dw4rd@verizon.net>
[official-gcc.git] / gcc / ipa.c
blob5382b7a8f315f6566ed4861c0f3920dccc9fe067
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)
392 if (file)
393 fprintf (file, " %s", varpool_node_name (vnode));
394 varpool_remove_node (vnode);
395 changed = true;
397 else if (!pointer_set_contains (reachable, vnode))
399 if (vnode->symbol.definition)
401 if (file)
402 fprintf (file, " %s", varpool_node_name (vnode));
403 changed = true;
405 vnode->symbol.definition = false;
406 vnode->symbol.analyzed = false;
407 vnode->symbol.aux = NULL;
409 /* Keep body if it may be useful for constant folding. */
410 if (!const_value_known_p (vnode->symbol.decl))
411 varpool_remove_initializer (vnode);
412 ipa_remove_all_references (&vnode->symbol.ref_list);
414 else
415 vnode->symbol.aux = NULL;
418 pointer_set_destroy (reachable);
419 pointer_set_destroy (body_needed_for_clonning);
421 /* Now update address_taken flags and try to promote functions to be local. */
422 if (file)
423 fprintf (file, "\nClearing address taken flags:");
424 FOR_EACH_DEFINED_FUNCTION (node)
425 if (node->symbol.address_taken
426 && !node->symbol.used_from_other_partition)
428 if (!cgraph_for_node_and_aliases (node, has_addr_references_p, NULL, true))
430 if (file)
431 fprintf (file, " %s", cgraph_node_name (node));
432 node->symbol.address_taken = false;
433 changed = true;
434 if (cgraph_local_node_p (node))
436 node->local.local = true;
437 if (file)
438 fprintf (file, " (local)");
442 if (file)
443 fprintf (file, "\n");
445 #ifdef ENABLE_CHECKING
446 verify_symtab ();
447 #endif
449 /* If we removed something, perhaps profile could be improved. */
450 if (changed && optimize && inline_edge_summary_vec.exists ())
451 FOR_EACH_DEFINED_FUNCTION (node)
452 cgraph_propagate_frequency (node);
454 return changed;
457 /* Discover variables that have no longer address taken or that are read only
458 and update their flags.
460 FIXME: This can not be done in between gimplify and omp_expand since
461 readonly flag plays role on what is shared and what is not. Currently we do
462 this transformation as part of whole program visibility and re-do at
463 ipa-reference pass (to take into account clonning), but it would
464 make sense to do it before early optimizations. */
466 void
467 ipa_discover_readonly_nonaddressable_vars (void)
469 struct varpool_node *vnode;
470 if (dump_file)
471 fprintf (dump_file, "Clearing variable flags:");
472 FOR_EACH_VARIABLE (vnode)
473 if (vnode->symbol.definition && varpool_all_refs_explicit_p (vnode)
474 && (TREE_ADDRESSABLE (vnode->symbol.decl)
475 || !TREE_READONLY (vnode->symbol.decl)))
477 bool written = false;
478 bool address_taken = false;
479 int i;
480 struct ipa_ref *ref;
481 for (i = 0; ipa_ref_list_referring_iterate (&vnode->symbol.ref_list,
482 i, ref)
483 && (!written || !address_taken); i++)
484 switch (ref->use)
486 case IPA_REF_ADDR:
487 address_taken = true;
488 break;
489 case IPA_REF_LOAD:
490 break;
491 case IPA_REF_STORE:
492 written = true;
493 break;
495 if (TREE_ADDRESSABLE (vnode->symbol.decl) && !address_taken)
497 if (dump_file)
498 fprintf (dump_file, " %s (addressable)", varpool_node_name (vnode));
499 TREE_ADDRESSABLE (vnode->symbol.decl) = 0;
501 if (!TREE_READONLY (vnode->symbol.decl) && !address_taken && !written
502 /* Making variable in explicit section readonly can cause section
503 type conflict.
504 See e.g. gcc.c-torture/compile/pr23237.c */
505 && DECL_SECTION_NAME (vnode->symbol.decl) == NULL)
507 if (dump_file)
508 fprintf (dump_file, " %s (read-only)", varpool_node_name (vnode));
509 TREE_READONLY (vnode->symbol.decl) = 1;
512 if (dump_file)
513 fprintf (dump_file, "\n");
516 /* Return true when there is a reference to node and it is not vtable. */
517 static bool
518 cgraph_address_taken_from_non_vtable_p (struct cgraph_node *node)
520 int i;
521 struct ipa_ref *ref;
522 for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list,
523 i, ref); i++)
524 if (ref->use == IPA_REF_ADDR)
526 struct varpool_node *node;
527 if (is_a <cgraph_node> (ref->referring))
528 return true;
529 node = ipa_ref_referring_varpool_node (ref);
530 if (!DECL_VIRTUAL_P (node->symbol.decl))
531 return true;
533 return false;
536 /* COMDAT functions must be shared only if they have address taken,
537 otherwise we can produce our own private implementation with
538 -fwhole-program.
539 Return true when turning COMDAT functoin static can not lead to wrong
540 code when the resulting object links with a library defining same COMDAT.
542 Virtual functions do have their addresses taken from the vtables,
543 but in C++ there is no way to compare their addresses for equality. */
545 static bool
546 cgraph_comdat_can_be_unshared_p (struct cgraph_node *node)
548 if ((cgraph_address_taken_from_non_vtable_p (node)
549 && !DECL_VIRTUAL_P (node->symbol.decl))
550 || !node->symbol.definition)
551 return false;
552 if (node->symbol.same_comdat_group)
554 struct cgraph_node *next;
556 /* If more than one function is in the same COMDAT group, it must
557 be shared even if just one function in the comdat group has
558 address taken. */
559 for (next = cgraph (node->symbol.same_comdat_group);
560 next != node; next = cgraph (next->symbol.same_comdat_group))
561 if (cgraph_address_taken_from_non_vtable_p (next)
562 && !DECL_VIRTUAL_P (next->symbol.decl))
563 return false;
565 return true;
568 /* Return true when function NODE should be considered externally visible. */
570 static bool
571 cgraph_externally_visible_p (struct cgraph_node *node,
572 bool whole_program)
574 if (!node->symbol.definition)
575 return false;
576 if (!DECL_COMDAT (node->symbol.decl)
577 && (!TREE_PUBLIC (node->symbol.decl)
578 || DECL_EXTERNAL (node->symbol.decl)))
579 return false;
581 /* Do not try to localize built-in functions yet. One of problems is that we
582 end up mangling their asm for WHOPR that makes it impossible to call them
583 using the implicit built-in declarations anymore. Similarly this enables
584 us to remove them as unreachable before actual calls may appear during
585 expansion or folding. */
586 if (DECL_BUILT_IN (node->symbol.decl))
587 return true;
589 /* If linker counts on us, we must preserve the function. */
590 if (symtab_used_from_object_file_p ((symtab_node) node))
591 return true;
592 if (DECL_PRESERVE_P (node->symbol.decl))
593 return true;
594 if (lookup_attribute ("externally_visible",
595 DECL_ATTRIBUTES (node->symbol.decl)))
596 return true;
597 if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
598 && lookup_attribute ("dllexport",
599 DECL_ATTRIBUTES (node->symbol.decl)))
600 return true;
601 if (node->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY)
602 return false;
603 /* When doing LTO or whole program, we can bring COMDAT functoins static.
604 This improves code quality and we know we will duplicate them at most twice
605 (in the case that we are not using plugin and link with object file
606 implementing same COMDAT) */
607 if ((in_lto_p || whole_program)
608 && DECL_COMDAT (node->symbol.decl)
609 && cgraph_comdat_can_be_unshared_p (node))
610 return false;
612 /* When doing link time optimizations, hidden symbols become local. */
613 if (in_lto_p
614 && (DECL_VISIBILITY (node->symbol.decl) == VISIBILITY_HIDDEN
615 || DECL_VISIBILITY (node->symbol.decl) == VISIBILITY_INTERNAL)
616 /* Be sure that node is defined in IR file, not in other object
617 file. In that case we don't set used_from_other_object_file. */
618 && node->symbol.definition)
620 else if (!whole_program)
621 return true;
623 if (MAIN_NAME_P (DECL_NAME (node->symbol.decl)))
624 return true;
626 return false;
629 /* Return true when variable VNODE should be considered externally visible. */
631 bool
632 varpool_externally_visible_p (struct varpool_node *vnode)
634 /* Do not touch weakrefs; while they are not externally visible,
635 dropping their DECL_EXTERNAL flags confuse most
636 of code handling them. */
637 if (vnode->symbol.alias && DECL_EXTERNAL (vnode->symbol.decl))
638 return true;
640 if (DECL_EXTERNAL (vnode->symbol.decl))
641 return true;
643 if (!DECL_COMDAT (vnode->symbol.decl) && !TREE_PUBLIC (vnode->symbol.decl))
644 return false;
646 /* If linker counts on us, we must preserve the function. */
647 if (symtab_used_from_object_file_p ((symtab_node) vnode))
648 return true;
650 if (DECL_HARD_REGISTER (vnode->symbol.decl))
651 return true;
652 if (DECL_PRESERVE_P (vnode->symbol.decl))
653 return true;
654 if (lookup_attribute ("externally_visible",
655 DECL_ATTRIBUTES (vnode->symbol.decl)))
656 return true;
657 if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
658 && lookup_attribute ("dllexport",
659 DECL_ATTRIBUTES (vnode->symbol.decl)))
660 return true;
662 /* See if we have linker information about symbol not being used or
663 if we need to make guess based on the declaration.
665 Even if the linker clams the symbol is unused, never bring internal
666 symbols that are declared by user as used or externally visible.
667 This is needed for i.e. references from asm statements. */
668 if (symtab_used_from_object_file_p ((symtab_node) vnode))
669 return true;
670 if (vnode->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY)
671 return false;
673 /* As a special case, the COMDAT virtual tables can be unshared.
674 In LTO mode turn vtables into static variables. The variable is readonly,
675 so this does not enable more optimization, but referring static var
676 is faster for dynamic linking. Also this match logic hidding vtables
677 from LTO symbol tables. */
678 if ((in_lto_p || flag_whole_program)
679 && !vnode->symbol.force_output
680 && DECL_COMDAT (vnode->symbol.decl) && DECL_VIRTUAL_P (vnode->symbol.decl))
681 return false;
683 /* When doing link time optimizations, hidden symbols become local. */
684 if (in_lto_p
685 && (DECL_VISIBILITY (vnode->symbol.decl) == VISIBILITY_HIDDEN
686 || DECL_VISIBILITY (vnode->symbol.decl) == VISIBILITY_INTERNAL)
687 /* Be sure that node is defined in IR file, not in other object
688 file. In that case we don't set used_from_other_object_file. */
689 && vnode->symbol.definition)
691 else if (!flag_whole_program)
692 return true;
694 /* Do not attempt to privatize COMDATS by default.
695 This would break linking with C++ libraries sharing
696 inline definitions.
698 FIXME: We can do so for readonly vars with no address taken and
699 possibly also for vtables since no direct pointer comparsion is done.
700 It might be interesting to do so to reduce linking overhead. */
701 if (DECL_COMDAT (vnode->symbol.decl) || DECL_WEAK (vnode->symbol.decl))
702 return true;
703 return false;
706 /* Mark visibility of all functions.
708 A local function is one whose calls can occur only in the current
709 compilation unit and all its calls are explicit, so we can change
710 its calling convention. We simply mark all static functions whose
711 address is not taken as local.
713 We also change the TREE_PUBLIC flag of all declarations that are public
714 in language point of view but we want to overwrite this default
715 via visibilities for the backend point of view. */
717 static unsigned int
718 function_and_variable_visibility (bool whole_program)
720 struct cgraph_node *node;
721 struct varpool_node *vnode;
723 /* All aliases should be procssed at this point. */
724 gcc_checking_assert (!alias_pairs || !alias_pairs->length());
726 FOR_EACH_FUNCTION (node)
728 int flags = flags_from_decl_or_type (node->symbol.decl);
730 /* Optimize away PURE and CONST constructors and destructors. */
731 if (optimize
732 && (flags & (ECF_CONST | ECF_PURE))
733 && !(flags & ECF_LOOPING_CONST_OR_PURE))
735 DECL_STATIC_CONSTRUCTOR (node->symbol.decl) = 0;
736 DECL_STATIC_DESTRUCTOR (node->symbol.decl) = 0;
739 /* Frontends and alias code marks nodes as needed before parsing is finished.
740 We may end up marking as node external nodes where this flag is meaningless
741 strip it. */
742 if (node->symbol.force_output
743 && (DECL_EXTERNAL (node->symbol.decl) || !node->symbol.definition))
744 node->symbol.force_output = 0;
746 /* C++ FE on lack of COMDAT support create local COMDAT functions
747 (that ought to be shared but can not due to object format
748 limitations). It is necessary to keep the flag to make rest of C++ FE
749 happy. Clear the flag here to avoid confusion in middle-end. */
750 if (DECL_COMDAT (node->symbol.decl) && !TREE_PUBLIC (node->symbol.decl))
751 DECL_COMDAT (node->symbol.decl) = 0;
752 /* For external decls stop tracking same_comdat_group, it doesn't matter
753 what comdat group they are in when they won't be emitted in this TU,
754 and simplifies later passes. */
755 if (node->symbol.same_comdat_group && DECL_EXTERNAL (node->symbol.decl))
757 #ifdef ENABLE_CHECKING
758 symtab_node n;
760 for (n = node->symbol.same_comdat_group;
761 n != (symtab_node)node;
762 n = n->symbol.same_comdat_group)
763 /* If at least one of same comdat group functions is external,
764 all of them have to be, otherwise it is a front-end bug. */
765 gcc_assert (DECL_EXTERNAL (n->symbol.decl));
766 #endif
767 symtab_dissolve_same_comdat_group_list ((symtab_node) node);
769 gcc_assert ((!DECL_WEAK (node->symbol.decl)
770 && !DECL_COMDAT (node->symbol.decl))
771 || TREE_PUBLIC (node->symbol.decl)
772 || DECL_EXTERNAL (node->symbol.decl));
773 if (cgraph_externally_visible_p (node, whole_program))
775 gcc_assert (!node->global.inlined_to);
776 node->symbol.externally_visible = true;
778 else
779 node->symbol.externally_visible = false;
780 if (!node->symbol.externally_visible && node->symbol.definition
781 && !DECL_EXTERNAL (node->symbol.decl))
783 gcc_assert (whole_program || in_lto_p
784 || !TREE_PUBLIC (node->symbol.decl));
785 node->symbol.unique_name = ((node->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY
786 || node->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
787 && TREE_PUBLIC (node->symbol.decl));
788 symtab_make_decl_local (node->symbol.decl);
789 node->symbol.resolution = LDPR_PREVAILING_DEF_IRONLY;
790 if (node->symbol.same_comdat_group)
791 /* cgraph_externally_visible_p has already checked all other nodes
792 in the group and they will all be made local. We need to
793 dissolve the group at once so that the predicate does not
794 segfault though. */
795 symtab_dissolve_same_comdat_group_list ((symtab_node) node);
798 if (node->thunk.thunk_p
799 && TREE_PUBLIC (node->symbol.decl))
801 struct cgraph_node *decl_node = node;
803 decl_node = cgraph_function_node (decl_node->callees->callee, NULL);
805 /* Thunks have the same visibility as function they are attached to.
806 Make sure the C++ front end set this up properly. */
807 if (DECL_ONE_ONLY (decl_node->symbol.decl))
809 gcc_checking_assert (DECL_COMDAT (node->symbol.decl)
810 == DECL_COMDAT (decl_node->symbol.decl));
811 gcc_checking_assert (DECL_COMDAT_GROUP (node->symbol.decl)
812 == DECL_COMDAT_GROUP (decl_node->symbol.decl));
813 gcc_checking_assert (node->symbol.same_comdat_group);
815 if (DECL_EXTERNAL (decl_node->symbol.decl))
816 DECL_EXTERNAL (node->symbol.decl) = 1;
819 FOR_EACH_DEFINED_FUNCTION (node)
820 node->local.local = cgraph_local_node_p (node);
821 FOR_EACH_VARIABLE (vnode)
823 /* weak flag makes no sense on local variables. */
824 gcc_assert (!DECL_WEAK (vnode->symbol.decl)
825 || TREE_PUBLIC (vnode->symbol.decl)
826 || DECL_EXTERNAL (vnode->symbol.decl));
827 /* In several cases declarations can not be common:
829 - when declaration has initializer
830 - when it is in weak
831 - when it has specific section
832 - when it resides in non-generic address space.
833 - if declaration is local, it will get into .local common section
834 so common flag is not needed. Frontends still produce these in
835 certain cases, such as for:
837 static int a __attribute__ ((common))
839 Canonicalize things here and clear the redundant flag. */
840 if (DECL_COMMON (vnode->symbol.decl)
841 && (!(TREE_PUBLIC (vnode->symbol.decl)
842 || DECL_EXTERNAL (vnode->symbol.decl))
843 || (DECL_INITIAL (vnode->symbol.decl)
844 && DECL_INITIAL (vnode->symbol.decl) != error_mark_node)
845 || DECL_WEAK (vnode->symbol.decl)
846 || DECL_SECTION_NAME (vnode->symbol.decl) != NULL
847 || ! (ADDR_SPACE_GENERIC_P
848 (TYPE_ADDR_SPACE (TREE_TYPE (vnode->symbol.decl))))))
849 DECL_COMMON (vnode->symbol.decl) = 0;
851 FOR_EACH_DEFINED_VARIABLE (vnode)
853 if (!vnode->symbol.definition)
854 continue;
855 if (varpool_externally_visible_p (vnode))
856 vnode->symbol.externally_visible = true;
857 else
858 vnode->symbol.externally_visible = false;
859 if (!vnode->symbol.externally_visible)
861 gcc_assert (in_lto_p || whole_program || !TREE_PUBLIC (vnode->symbol.decl));
862 symtab_make_decl_local (vnode->symbol.decl);
863 vnode->symbol.unique_name = ((vnode->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY
864 || vnode->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
865 && TREE_PUBLIC (vnode->symbol.decl));
866 if (vnode->symbol.same_comdat_group)
867 symtab_dissolve_same_comdat_group_list ((symtab_node) vnode);
868 vnode->symbol.resolution = LDPR_PREVAILING_DEF_IRONLY;
872 if (dump_file)
874 fprintf (dump_file, "\nMarking local functions:");
875 FOR_EACH_DEFINED_FUNCTION (node)
876 if (node->local.local)
877 fprintf (dump_file, " %s", cgraph_node_name (node));
878 fprintf (dump_file, "\n\n");
879 fprintf (dump_file, "\nMarking externally visible functions:");
880 FOR_EACH_DEFINED_FUNCTION (node)
881 if (node->symbol.externally_visible)
882 fprintf (dump_file, " %s", cgraph_node_name (node));
883 fprintf (dump_file, "\n\n");
884 fprintf (dump_file, "\nMarking externally visible variables:");
885 FOR_EACH_DEFINED_VARIABLE (vnode)
886 if (vnode->symbol.externally_visible)
887 fprintf (dump_file, " %s", varpool_node_name (vnode));
888 fprintf (dump_file, "\n\n");
890 cgraph_function_flags_ready = true;
891 return 0;
894 /* Local function pass handling visibilities. This happens before LTO streaming
895 so in particular -fwhole-program should be ignored at this level. */
897 static unsigned int
898 local_function_and_variable_visibility (void)
900 return function_and_variable_visibility (flag_whole_program && !flag_lto);
903 struct simple_ipa_opt_pass pass_ipa_function_and_variable_visibility =
906 SIMPLE_IPA_PASS,
907 "visibility", /* name */
908 OPTGROUP_NONE, /* optinfo_flags */
909 NULL, /* gate */
910 local_function_and_variable_visibility,/* execute */
911 NULL, /* sub */
912 NULL, /* next */
913 0, /* static_pass_number */
914 TV_CGRAPHOPT, /* tv_id */
915 0, /* properties_required */
916 0, /* properties_provided */
917 0, /* properties_destroyed */
918 0, /* todo_flags_start */
919 TODO_remove_functions | TODO_dump_symtab /* todo_flags_finish */
923 /* Free inline summary. */
925 static unsigned
926 free_inline_summary (void)
928 inline_free_summary ();
929 return 0;
932 struct simple_ipa_opt_pass pass_ipa_free_inline_summary =
935 SIMPLE_IPA_PASS,
936 "*free_inline_summary", /* name */
937 OPTGROUP_NONE, /* optinfo_flags */
938 NULL, /* gate */
939 free_inline_summary, /* execute */
940 NULL, /* sub */
941 NULL, /* next */
942 0, /* static_pass_number */
943 TV_IPA_FREE_INLINE_SUMMARY, /* tv_id */
944 0, /* properties_required */
945 0, /* properties_provided */
946 0, /* properties_destroyed */
947 0, /* todo_flags_start */
948 0 /* todo_flags_finish */
952 /* Do not re-run on ltrans stage. */
954 static bool
955 gate_whole_program_function_and_variable_visibility (void)
957 return !flag_ltrans;
960 /* Bring functionss local at LTO time with -fwhole-program. */
962 static unsigned int
963 whole_program_function_and_variable_visibility (void)
965 function_and_variable_visibility (flag_whole_program);
966 if (optimize)
967 ipa_discover_readonly_nonaddressable_vars ();
968 return 0;
971 struct ipa_opt_pass_d pass_ipa_whole_program_visibility =
974 IPA_PASS,
975 "whole-program", /* name */
976 OPTGROUP_NONE, /* optinfo_flags */
977 gate_whole_program_function_and_variable_visibility,/* gate */
978 whole_program_function_and_variable_visibility,/* execute */
979 NULL, /* sub */
980 NULL, /* next */
981 0, /* static_pass_number */
982 TV_CGRAPHOPT, /* tv_id */
983 0, /* properties_required */
984 0, /* properties_provided */
985 0, /* properties_destroyed */
986 0, /* todo_flags_start */
987 TODO_remove_functions | TODO_dump_symtab /* todo_flags_finish */
989 NULL, /* generate_summary */
990 NULL, /* write_summary */
991 NULL, /* read_summary */
992 NULL, /* write_optimization_summary */
993 NULL, /* read_optimization_summary */
994 NULL, /* stmt_fixup */
995 0, /* TODOs */
996 NULL, /* function_transform */
997 NULL, /* variable_transform */
1000 /* Entry in the histogram. */
1002 struct histogram_entry
1004 gcov_type count;
1005 int time;
1006 int size;
1009 /* Histogram of profile values.
1010 The histogram is represented as an ordered vector of entries allocated via
1011 histogram_pool. During construction a separate hashtable is kept to lookup
1012 duplicate entries. */
1014 vec<histogram_entry *> histogram;
1015 static alloc_pool histogram_pool;
1017 /* Hashtable support for storing SSA names hashed by their SSA_NAME_VAR. */
1019 struct histogram_hash : typed_noop_remove <histogram_entry>
1021 typedef histogram_entry value_type;
1022 typedef histogram_entry compare_type;
1023 static inline hashval_t hash (const value_type *);
1024 static inline int equal (const value_type *, const compare_type *);
1027 inline hashval_t
1028 histogram_hash::hash (const histogram_entry *val)
1030 return val->count;
1033 inline int
1034 histogram_hash::equal (const histogram_entry *val, const histogram_entry *val2)
1036 return val->count == val2->count;
1039 /* Account TIME and SIZE executed COUNT times into HISTOGRAM.
1040 HASHTABLE is the on-side hash kept to avoid duplicates. */
1042 static void
1043 account_time_size (hash_table <histogram_hash> hashtable,
1044 vec<histogram_entry *> &histogram,
1045 gcov_type count, int time, int size)
1047 histogram_entry key = {count, 0, 0};
1048 histogram_entry **val = hashtable.find_slot (&key, INSERT);
1050 if (!*val)
1052 *val = (histogram_entry *) pool_alloc (histogram_pool);
1053 **val = key;
1054 histogram.safe_push (*val);
1056 (*val)->time += time;
1057 (*val)->size += size;
1061 cmp_counts (const void *v1, const void *v2)
1063 const histogram_entry *h1 = *(const histogram_entry * const *)v1;
1064 const histogram_entry *h2 = *(const histogram_entry * const *)v2;
1065 if (h1->count < h2->count)
1066 return 1;
1067 if (h1->count > h2->count)
1068 return -1;
1069 return 0;
1072 /* Dump HISTOGRAM to FILE. */
1074 static void
1075 dump_histogram (FILE *file, vec<histogram_entry *> histogram)
1077 unsigned int i;
1078 gcov_type overall_time = 0, cumulated_time = 0, cumulated_size = 0, overall_size = 0;
1080 fprintf (dump_file, "Histogram:\n");
1081 for (i = 0; i < histogram.length (); i++)
1083 overall_time += histogram[i]->count * histogram[i]->time;
1084 overall_size += histogram[i]->size;
1086 if (!overall_time)
1087 overall_time = 1;
1088 if (!overall_size)
1089 overall_size = 1;
1090 for (i = 0; i < histogram.length (); i++)
1092 cumulated_time += histogram[i]->count * histogram[i]->time;
1093 cumulated_size += histogram[i]->size;
1094 fprintf (file, " "HOST_WIDEST_INT_PRINT_DEC": time:%i (%2.2f) size:%i (%2.2f)\n",
1095 (HOST_WIDEST_INT) histogram[i]->count,
1096 histogram[i]->time,
1097 cumulated_time * 100.0 / overall_time,
1098 histogram[i]->size,
1099 cumulated_size * 100.0 / overall_size);
1103 /* Collect histogram from CFG profiles. */
1105 static void
1106 ipa_profile_generate_summary (void)
1108 struct cgraph_node *node;
1109 gimple_stmt_iterator gsi;
1110 hash_table <histogram_hash> hashtable;
1111 basic_block bb;
1113 hashtable.create (10);
1114 histogram_pool = create_alloc_pool ("IPA histogram", sizeof (struct histogram_entry),
1115 10);
1117 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
1118 FOR_EACH_BB_FN (bb, DECL_STRUCT_FUNCTION (node->symbol.decl))
1120 int time = 0;
1121 int size = 0;
1122 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1124 time += estimate_num_insns (gsi_stmt (gsi), &eni_time_weights);
1125 size += estimate_num_insns (gsi_stmt (gsi), &eni_size_weights);
1127 account_time_size (hashtable, histogram, bb->count, time, size);
1129 hashtable.dispose ();
1130 histogram.qsort (cmp_counts);
1133 /* Serialize the ipa info for lto. */
1135 static void
1136 ipa_profile_write_summary (void)
1138 struct lto_simple_output_block *ob
1139 = lto_create_simple_output_block (LTO_section_ipa_profile);
1140 unsigned int i;
1142 streamer_write_uhwi_stream (ob->main_stream, histogram.length());
1143 for (i = 0; i < histogram.length (); i++)
1145 streamer_write_gcov_count_stream (ob->main_stream, histogram[i]->count);
1146 streamer_write_uhwi_stream (ob->main_stream, histogram[i]->time);
1147 streamer_write_uhwi_stream (ob->main_stream, histogram[i]->size);
1149 lto_destroy_simple_output_block (ob);
1152 /* Deserialize the ipa info for lto. */
1154 static void
1155 ipa_profile_read_summary (void)
1157 struct lto_file_decl_data ** file_data_vec
1158 = lto_get_file_decl_data ();
1159 struct lto_file_decl_data * file_data;
1160 hash_table <histogram_hash> hashtable;
1161 int j = 0;
1163 hashtable.create (10);
1164 histogram_pool = create_alloc_pool ("IPA histogram", sizeof (struct histogram_entry),
1165 10);
1167 while ((file_data = file_data_vec[j++]))
1169 const char *data;
1170 size_t len;
1171 struct lto_input_block *ib
1172 = lto_create_simple_input_block (file_data,
1173 LTO_section_ipa_profile,
1174 &data, &len);
1175 if (ib)
1177 unsigned int num = streamer_read_uhwi (ib);
1178 unsigned int n;
1179 for (n = 0; n < num; n++)
1181 gcov_type count = streamer_read_gcov_count (ib);
1182 int time = streamer_read_uhwi (ib);
1183 int size = streamer_read_uhwi (ib);
1184 account_time_size (hashtable, histogram,
1185 count, time, size);
1187 lto_destroy_simple_input_block (file_data,
1188 LTO_section_ipa_profile,
1189 ib, data, len);
1192 hashtable.dispose ();
1193 histogram.qsort (cmp_counts);
1196 /* Simple ipa profile pass propagating frequencies across the callgraph. */
1198 static unsigned int
1199 ipa_profile (void)
1201 struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
1202 struct cgraph_edge *e;
1203 int order_pos;
1204 bool something_changed = false;
1205 int i;
1206 gcov_type overall_time = 0, cutoff = 0, cumulated = 0, overall_size = 0;
1208 if (dump_file)
1209 dump_histogram (dump_file, histogram);
1210 for (i = 0; i < (int)histogram.length (); i++)
1212 overall_time += histogram[i]->count * histogram[i]->time;
1213 overall_size += histogram[i]->size;
1215 if (overall_time)
1217 gcov_type threshold;
1219 gcc_assert (overall_size);
1220 if (dump_file)
1222 gcov_type min, cumulated_time = 0, cumulated_size = 0;
1224 fprintf (dump_file, "Overall time: "HOST_WIDEST_INT_PRINT_DEC"\n",
1225 (HOST_WIDEST_INT)overall_time);
1226 min = get_hot_bb_threshold ();
1227 for (i = 0; i < (int)histogram.length () && histogram[i]->count >= min;
1228 i++)
1230 cumulated_time += histogram[i]->count * histogram[i]->time;
1231 cumulated_size += histogram[i]->size;
1233 fprintf (dump_file, "GCOV min count: "HOST_WIDEST_INT_PRINT_DEC
1234 " Time:%3.2f%% Size:%3.2f%%\n",
1235 (HOST_WIDEST_INT)min,
1236 cumulated_time * 100.0 / overall_time,
1237 cumulated_size * 100.0 / overall_size);
1239 cutoff = (overall_time * PARAM_VALUE (HOT_BB_COUNT_WS_PERMILLE) + 500) / 1000;
1240 threshold = 0;
1241 for (i = 0; cumulated < cutoff; i++)
1243 cumulated += histogram[i]->count * histogram[i]->time;
1244 threshold = histogram[i]->count;
1246 if (!threshold)
1247 threshold = 1;
1248 if (dump_file)
1250 gcov_type cumulated_time = 0, cumulated_size = 0;
1252 for (i = 0;
1253 i < (int)histogram.length () && histogram[i]->count >= threshold;
1254 i++)
1256 cumulated_time += histogram[i]->count * histogram[i]->time;
1257 cumulated_size += histogram[i]->size;
1259 fprintf (dump_file, "Determined min count: "HOST_WIDEST_INT_PRINT_DEC
1260 " Time:%3.2f%% Size:%3.2f%%\n",
1261 (HOST_WIDEST_INT)threshold,
1262 cumulated_time * 100.0 / overall_time,
1263 cumulated_size * 100.0 / overall_size);
1265 if (threshold > get_hot_bb_threshold ()
1266 || in_lto_p)
1268 if (dump_file)
1269 fprintf (dump_file, "Threshold updated.\n");
1270 set_hot_bb_threshold (threshold);
1273 histogram.release();
1274 free_alloc_pool (histogram_pool);
1276 order_pos = ipa_reverse_postorder (order);
1277 for (i = order_pos - 1; i >= 0; i--)
1279 if (order[i]->local.local && cgraph_propagate_frequency (order[i]))
1281 for (e = order[i]->callees; e; e = e->next_callee)
1282 if (e->callee->local.local && !e->callee->symbol.aux)
1284 something_changed = true;
1285 e->callee->symbol.aux = (void *)1;
1288 order[i]->symbol.aux = NULL;
1291 while (something_changed)
1293 something_changed = false;
1294 for (i = order_pos - 1; i >= 0; i--)
1296 if (order[i]->symbol.aux && cgraph_propagate_frequency (order[i]))
1298 for (e = order[i]->callees; e; e = e->next_callee)
1299 if (e->callee->local.local && !e->callee->symbol.aux)
1301 something_changed = true;
1302 e->callee->symbol.aux = (void *)1;
1305 order[i]->symbol.aux = NULL;
1308 free (order);
1309 return 0;
1312 static bool
1313 gate_ipa_profile (void)
1315 return flag_ipa_profile;
1318 struct ipa_opt_pass_d pass_ipa_profile =
1321 IPA_PASS,
1322 "profile_estimate", /* name */
1323 OPTGROUP_NONE, /* optinfo_flags */
1324 gate_ipa_profile, /* gate */
1325 ipa_profile, /* execute */
1326 NULL, /* sub */
1327 NULL, /* next */
1328 0, /* static_pass_number */
1329 TV_IPA_PROFILE, /* tv_id */
1330 0, /* properties_required */
1331 0, /* properties_provided */
1332 0, /* properties_destroyed */
1333 0, /* todo_flags_start */
1334 0 /* todo_flags_finish */
1336 ipa_profile_generate_summary, /* generate_summary */
1337 ipa_profile_write_summary, /* write_summary */
1338 ipa_profile_read_summary, /* read_summary */
1339 NULL, /* write_optimization_summary */
1340 NULL, /* read_optimization_summary */
1341 NULL, /* stmt_fixup */
1342 0, /* TODOs */
1343 NULL, /* function_transform */
1344 NULL /* variable_transform */
1347 /* Generate and emit a static constructor or destructor. WHICH must
1348 be one of 'I' (for a constructor) or 'D' (for a destructor). BODY
1349 is a STATEMENT_LIST containing GENERIC statements. PRIORITY is the
1350 initialization priority for this constructor or destructor.
1352 FINAL specify whether the externally visible name for collect2 should
1353 be produced. */
1355 static void
1356 cgraph_build_static_cdtor_1 (char which, tree body, int priority, bool final)
1358 static int counter = 0;
1359 char which_buf[16];
1360 tree decl, name, resdecl;
1362 /* The priority is encoded in the constructor or destructor name.
1363 collect2 will sort the names and arrange that they are called at
1364 program startup. */
1365 if (final)
1366 sprintf (which_buf, "%c_%.5d_%d", which, priority, counter++);
1367 else
1368 /* Proudce sane name but one not recognizable by collect2, just for the
1369 case we fail to inline the function. */
1370 sprintf (which_buf, "sub_%c_%.5d_%d", which, priority, counter++);
1371 name = get_file_function_name (which_buf);
1373 decl = build_decl (input_location, FUNCTION_DECL, name,
1374 build_function_type_list (void_type_node, NULL_TREE));
1375 current_function_decl = decl;
1377 resdecl = build_decl (input_location,
1378 RESULT_DECL, NULL_TREE, void_type_node);
1379 DECL_ARTIFICIAL (resdecl) = 1;
1380 DECL_RESULT (decl) = resdecl;
1381 DECL_CONTEXT (resdecl) = decl;
1383 allocate_struct_function (decl, false);
1385 TREE_STATIC (decl) = 1;
1386 TREE_USED (decl) = 1;
1387 DECL_ARTIFICIAL (decl) = 1;
1388 DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;
1389 DECL_SAVED_TREE (decl) = body;
1390 if (!targetm.have_ctors_dtors && final)
1392 TREE_PUBLIC (decl) = 1;
1393 DECL_PRESERVE_P (decl) = 1;
1395 DECL_UNINLINABLE (decl) = 1;
1397 DECL_INITIAL (decl) = make_node (BLOCK);
1398 TREE_USED (DECL_INITIAL (decl)) = 1;
1400 DECL_SOURCE_LOCATION (decl) = input_location;
1401 cfun->function_end_locus = input_location;
1403 switch (which)
1405 case 'I':
1406 DECL_STATIC_CONSTRUCTOR (decl) = 1;
1407 decl_init_priority_insert (decl, priority);
1408 break;
1409 case 'D':
1410 DECL_STATIC_DESTRUCTOR (decl) = 1;
1411 decl_fini_priority_insert (decl, priority);
1412 break;
1413 default:
1414 gcc_unreachable ();
1417 gimplify_function_tree (decl);
1419 cgraph_add_new_function (decl, false);
1421 set_cfun (NULL);
1422 current_function_decl = NULL;
1425 /* Generate and emit a static constructor or destructor. WHICH must
1426 be one of 'I' (for a constructor) or 'D' (for a destructor). BODY
1427 is a STATEMENT_LIST containing GENERIC statements. PRIORITY is the
1428 initialization priority for this constructor or destructor. */
1430 void
1431 cgraph_build_static_cdtor (char which, tree body, int priority)
1433 cgraph_build_static_cdtor_1 (which, body, priority, false);
1436 /* A vector of FUNCTION_DECLs declared as static constructors. */
1437 static vec<tree> static_ctors;
1438 /* A vector of FUNCTION_DECLs declared as static destructors. */
1439 static vec<tree> static_dtors;
1441 /* When target does not have ctors and dtors, we call all constructor
1442 and destructor by special initialization/destruction function
1443 recognized by collect2.
1445 When we are going to build this function, collect all constructors and
1446 destructors and turn them into normal functions. */
1448 static void
1449 record_cdtor_fn (struct cgraph_node *node)
1451 if (DECL_STATIC_CONSTRUCTOR (node->symbol.decl))
1452 static_ctors.safe_push (node->symbol.decl);
1453 if (DECL_STATIC_DESTRUCTOR (node->symbol.decl))
1454 static_dtors.safe_push (node->symbol.decl);
1455 node = cgraph_get_node (node->symbol.decl);
1456 DECL_DISREGARD_INLINE_LIMITS (node->symbol.decl) = 1;
1459 /* Define global constructors/destructor functions for the CDTORS, of
1460 which they are LEN. The CDTORS are sorted by initialization
1461 priority. If CTOR_P is true, these are constructors; otherwise,
1462 they are destructors. */
1464 static void
1465 build_cdtor (bool ctor_p, vec<tree> cdtors)
1467 size_t i,j;
1468 size_t len = cdtors.length ();
1470 i = 0;
1471 while (i < len)
1473 tree body;
1474 tree fn;
1475 priority_type priority;
1477 priority = 0;
1478 body = NULL_TREE;
1479 j = i;
1482 priority_type p;
1483 fn = cdtors[j];
1484 p = ctor_p ? DECL_INIT_PRIORITY (fn) : DECL_FINI_PRIORITY (fn);
1485 if (j == i)
1486 priority = p;
1487 else if (p != priority)
1488 break;
1489 j++;
1491 while (j < len);
1493 /* When there is only one cdtor and target supports them, do nothing. */
1494 if (j == i + 1
1495 && targetm.have_ctors_dtors)
1497 i++;
1498 continue;
1500 /* Find the next batch of constructors/destructors with the same
1501 initialization priority. */
1502 for (;i < j; i++)
1504 tree call;
1505 fn = cdtors[i];
1506 call = build_call_expr (fn, 0);
1507 if (ctor_p)
1508 DECL_STATIC_CONSTRUCTOR (fn) = 0;
1509 else
1510 DECL_STATIC_DESTRUCTOR (fn) = 0;
1511 /* We do not want to optimize away pure/const calls here.
1512 When optimizing, these should be already removed, when not
1513 optimizing, we want user to be able to breakpoint in them. */
1514 TREE_SIDE_EFFECTS (call) = 1;
1515 append_to_statement_list (call, &body);
1517 gcc_assert (body != NULL_TREE);
1518 /* Generate a function to call all the function of like
1519 priority. */
1520 cgraph_build_static_cdtor_1 (ctor_p ? 'I' : 'D', body, priority, true);
1524 /* Comparison function for qsort. P1 and P2 are actually of type
1525 "tree *" and point to static constructors. DECL_INIT_PRIORITY is
1526 used to determine the sort order. */
1528 static int
1529 compare_ctor (const void *p1, const void *p2)
1531 tree f1;
1532 tree f2;
1533 int priority1;
1534 int priority2;
1536 f1 = *(const tree *)p1;
1537 f2 = *(const tree *)p2;
1538 priority1 = DECL_INIT_PRIORITY (f1);
1539 priority2 = DECL_INIT_PRIORITY (f2);
1541 if (priority1 < priority2)
1542 return -1;
1543 else if (priority1 > priority2)
1544 return 1;
1545 else
1546 /* Ensure a stable sort. Constructors are executed in backwarding
1547 order to make LTO initialize braries first. */
1548 return DECL_UID (f2) - DECL_UID (f1);
1551 /* Comparison function for qsort. P1 and P2 are actually of type
1552 "tree *" and point to static destructors. DECL_FINI_PRIORITY is
1553 used to determine the sort order. */
1555 static int
1556 compare_dtor (const void *p1, const void *p2)
1558 tree f1;
1559 tree f2;
1560 int priority1;
1561 int priority2;
1563 f1 = *(const tree *)p1;
1564 f2 = *(const tree *)p2;
1565 priority1 = DECL_FINI_PRIORITY (f1);
1566 priority2 = DECL_FINI_PRIORITY (f2);
1568 if (priority1 < priority2)
1569 return -1;
1570 else if (priority1 > priority2)
1571 return 1;
1572 else
1573 /* Ensure a stable sort. */
1574 return DECL_UID (f1) - DECL_UID (f2);
1577 /* Generate functions to call static constructors and destructors
1578 for targets that do not support .ctors/.dtors sections. These
1579 functions have magic names which are detected by collect2. */
1581 static void
1582 build_cdtor_fns (void)
1584 if (!static_ctors.is_empty ())
1586 gcc_assert (!targetm.have_ctors_dtors || in_lto_p);
1587 static_ctors.qsort (compare_ctor);
1588 build_cdtor (/*ctor_p=*/true, static_ctors);
1591 if (!static_dtors.is_empty ())
1593 gcc_assert (!targetm.have_ctors_dtors || in_lto_p);
1594 static_dtors.qsort (compare_dtor);
1595 build_cdtor (/*ctor_p=*/false, static_dtors);
1599 /* Look for constructors and destructors and produce function calling them.
1600 This is needed for targets not supporting ctors or dtors, but we perform the
1601 transformation also at linktime to merge possibly numerous
1602 constructors/destructors into single function to improve code locality and
1603 reduce size. */
1605 static unsigned int
1606 ipa_cdtor_merge (void)
1608 struct cgraph_node *node;
1609 FOR_EACH_DEFINED_FUNCTION (node)
1610 if (DECL_STATIC_CONSTRUCTOR (node->symbol.decl)
1611 || DECL_STATIC_DESTRUCTOR (node->symbol.decl))
1612 record_cdtor_fn (node);
1613 build_cdtor_fns ();
1614 static_ctors.release ();
1615 static_dtors.release ();
1616 return 0;
1619 /* Perform the pass when we have no ctors/dtors support
1620 or at LTO time to merge multiple constructors into single
1621 function. */
1623 static bool
1624 gate_ipa_cdtor_merge (void)
1626 return !targetm.have_ctors_dtors || (optimize && in_lto_p);
1629 struct ipa_opt_pass_d pass_ipa_cdtor_merge =
1632 IPA_PASS,
1633 "cdtor", /* name */
1634 OPTGROUP_NONE, /* optinfo_flags */
1635 gate_ipa_cdtor_merge, /* gate */
1636 ipa_cdtor_merge, /* execute */
1637 NULL, /* sub */
1638 NULL, /* next */
1639 0, /* static_pass_number */
1640 TV_CGRAPHOPT, /* tv_id */
1641 0, /* properties_required */
1642 0, /* properties_provided */
1643 0, /* properties_destroyed */
1644 0, /* todo_flags_start */
1645 0 /* todo_flags_finish */
1647 NULL, /* generate_summary */
1648 NULL, /* write_summary */
1649 NULL, /* read_summary */
1650 NULL, /* write_optimization_summary */
1651 NULL, /* read_optimization_summary */
1652 NULL, /* stmt_fixup */
1653 0, /* TODOs */
1654 NULL, /* function_transform */
1655 NULL /* variable_transform */