Compile gcc.target/i386/fuse-caller-save.c with -fomit-frame-pointer (PR target/61533)
[official-gcc.git] / gcc / ipa.c
blob5128b4dbd2e5049b26559ace2fb6c03c175c6f68
1 /* Basic IPA optimizations and utilities.
2 Copyright (C) 2003-2014 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 "tree.h"
25 #include "calls.h"
26 #include "stringpool.h"
27 #include "cgraph.h"
28 #include "tree-pass.h"
29 #include "pointer-set.h"
30 #include "gimple-expr.h"
31 #include "gimplify.h"
32 #include "flags.h"
33 #include "target.h"
34 #include "tree-iterator.h"
35 #include "ipa-utils.h"
36 #include "ipa-inline.h"
37 #include "tree-inline.h"
38 #include "profile.h"
39 #include "params.h"
40 #include "internal-fn.h"
41 #include "tree-ssa-alias.h"
42 #include "gimple.h"
43 #include "dbgcnt.h"
46 /* Return true when NODE has ADDR reference. */
48 static bool
49 has_addr_references_p (struct cgraph_node *node,
50 void *data ATTRIBUTE_UNUSED)
52 int i;
53 struct ipa_ref *ref;
55 for (i = 0; ipa_ref_list_referring_iterate (&node->ref_list,
56 i, ref); i++)
57 if (ref->use == IPA_REF_ADDR)
58 return true;
59 return false;
62 /* Look for all functions inlined to NODE and update their inlined_to pointers
63 to INLINED_TO. */
65 static void
66 update_inlined_to_pointer (struct cgraph_node *node, struct cgraph_node *inlined_to)
68 struct cgraph_edge *e;
69 for (e = node->callees; e; e = e->next_callee)
70 if (e->callee->global.inlined_to)
72 e->callee->global.inlined_to = inlined_to;
73 update_inlined_to_pointer (e->callee, inlined_to);
77 /* Add symtab NODE to queue starting at FIRST.
79 The queue is linked via AUX pointers and terminated by pointer to 1.
80 We enqueue nodes at two occasions: when we find them reachable or when we find
81 their bodies needed for further clonning. In the second case we mark them
82 by pointer to 2 after processing so they are re-queue when they become
83 reachable. */
85 static void
86 enqueue_node (symtab_node *node, symtab_node **first,
87 struct pointer_set_t *reachable)
89 /* Node is still in queue; do nothing. */
90 if (node->aux && node->aux != (void *) 2)
91 return;
92 /* Node was already processed as unreachable, re-enqueue
93 only if it became reachable now. */
94 if (node->aux == (void *)2 && !pointer_set_contains (reachable, node))
95 return;
96 node->aux = *first;
97 *first = node;
100 /* Process references. */
102 static void
103 process_references (struct ipa_ref_list *list,
104 symtab_node **first,
105 bool before_inlining_p,
106 struct pointer_set_t *reachable)
108 int i;
109 struct ipa_ref *ref;
110 for (i = 0; ipa_ref_list_reference_iterate (list, i, ref); i++)
112 symtab_node *node = ref->referred;
114 if (node->definition && !node->in_other_partition
115 && ((!DECL_EXTERNAL (node->decl) || node->alias)
116 || (((before_inlining_p
117 && (cgraph_state < CGRAPH_STATE_IPA_SSA
118 || !lookup_attribute ("always_inline",
119 DECL_ATTRIBUTES (node->decl)))))
120 /* We use variable constructors during late complation for
121 constant folding. Keep references alive so partitioning
122 knows about potential references. */
123 || (TREE_CODE (node->decl) == VAR_DECL
124 && flag_wpa
125 && ctor_for_folding (node->decl)
126 != error_mark_node))))
127 pointer_set_insert (reachable, node);
128 enqueue_node (node, first, reachable);
132 /* EDGE is an polymorphic call. If BEFORE_INLINING_P is set, mark
133 all its potential targets as reachable to permit later inlining if
134 devirtualization happens. After inlining still keep their declarations
135 around, so we can devirtualize to a direct call.
137 Also try to make trivial devirutalization when no or only one target is
138 possible. */
140 static void
141 walk_polymorphic_call_targets (pointer_set_t *reachable_call_targets,
142 struct cgraph_edge *edge,
143 symtab_node **first,
144 pointer_set_t *reachable, bool before_inlining_p)
146 unsigned int i;
147 void *cache_token;
148 bool final;
149 vec <cgraph_node *>targets
150 = possible_polymorphic_call_targets
151 (edge, &final, &cache_token);
153 if (!pointer_set_insert (reachable_call_targets,
154 cache_token))
156 for (i = 0; i < targets.length (); i++)
158 struct cgraph_node *n = targets[i];
160 /* Do not bother to mark virtual methods in anonymous namespace;
161 either we will find use of virtual table defining it, or it is
162 unused. */
163 if (TREE_CODE (TREE_TYPE (n->decl)) == METHOD_TYPE
164 && type_in_anonymous_namespace_p
165 (method_class_type (TREE_TYPE (n->decl))))
166 continue;
168 /* Prior inlining, keep alive bodies of possible targets for
169 devirtualization. */
170 if (n->definition
171 && (before_inlining_p
172 && (cgraph_state < CGRAPH_STATE_IPA_SSA
173 || !lookup_attribute ("always_inline",
174 DECL_ATTRIBUTES (n->decl)))))
175 pointer_set_insert (reachable, n);
177 /* Even after inlining we want to keep the possible targets in the
178 boundary, so late passes can still produce direct call even if
179 the chance for inlining is lost. */
180 enqueue_node (n, first, reachable);
184 /* Very trivial devirtualization; when the type is
185 final or anonymous (so we know all its derivation)
186 and there is only one possible virtual call target,
187 make the edge direct. */
188 if (final)
190 if (targets.length () <= 1 && dbg_cnt (devirt))
192 cgraph_node *target, *node = edge->caller;
193 if (targets.length () == 1)
194 target = targets[0];
195 else
196 target = cgraph_get_create_node
197 (builtin_decl_implicit (BUILT_IN_UNREACHABLE));
199 if (dump_enabled_p ())
201 location_t locus = gimple_location (edge->call_stmt);
202 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, locus,
203 "devirtualizing call in %s/%i to %s/%i\n",
204 edge->caller->name (), edge->caller->order,
205 target->name (),
206 target->order);
208 edge = cgraph_make_edge_direct (edge, target);
209 if (inline_summary_vec)
210 inline_update_overall_summary (node);
211 else if (edge->call_stmt)
212 cgraph_redirect_edge_call_stmt_to_callee (edge);
217 /* Perform reachability analysis and reclaim all unreachable nodes.
219 The algorithm is basically mark&sweep but with some extra refinements:
221 - reachable extern inline functions needs special handling; the bodies needs
222 to stay in memory until inlining in hope that they will be inlined.
223 After inlining we release their bodies and turn them into unanalyzed
224 nodes even when they are reachable.
226 BEFORE_INLINING_P specify whether we are before or after inlining.
228 - virtual functions are kept in callgraph even if they seem unreachable in
229 hope calls to them will be devirtualized.
231 Again we remove them after inlining. In late optimization some
232 devirtualization may happen, but it is not important since we won't inline
233 the call. In theory early opts and IPA should work out all important cases.
235 - virtual clones needs bodies of their origins for later materialization;
236 this means that we want to keep the body even if the origin is unreachable
237 otherwise. To avoid origin from sitting in the callgraph and being
238 walked by IPA passes, we turn them into unanalyzed nodes with body
239 defined.
241 We maintain set of function declaration where body needs to stay in
242 body_needed_for_clonning
244 Inline clones represent special case: their declaration match the
245 declaration of origin and cgraph_remove_node already knows how to
246 reshape callgraph and preserve body when offline copy of function or
247 inline clone is being removed.
249 - C++ virtual tables keyed to other unit are represented as DECL_EXTERNAL
250 variables with DECL_INITIAL set. We finalize these and keep reachable
251 ones around for constant folding purposes. After inlining we however
252 stop walking their references to let everything static referneced by them
253 to be removed when it is otherwise unreachable.
255 We maintain queue of both reachable symbols (i.e. defined symbols that needs
256 to stay) and symbols that are in boundary (i.e. external symbols referenced
257 by reachable symbols or origins of clones). The queue is represented
258 as linked list by AUX pointer terminated by 1.
260 At the end we keep all reachable symbols. For symbols in boundary we always
261 turn definition into a declaration, but we may keep function body around
262 based on body_needed_for_clonning
264 All symbols that enter the queue have AUX pointer non-zero and are in the
265 boundary. Pointer set REACHABLE is used to track reachable symbols.
267 Every symbol can be visited twice - once as part of boundary and once
268 as real reachable symbol. enqueue_node needs to decide whether the
269 node needs to be re-queued for second processing. For this purpose
270 we set AUX pointer of processed symbols in the boundary to constant 2. */
272 bool
273 symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
275 symtab_node *first = (symtab_node *) (void *) 1;
276 struct cgraph_node *node, *next;
277 varpool_node *vnode, *vnext;
278 bool changed = false;
279 struct pointer_set_t *reachable = pointer_set_create ();
280 struct pointer_set_t *body_needed_for_clonning = pointer_set_create ();
281 struct pointer_set_t *reachable_call_targets = pointer_set_create ();
283 timevar_push (TV_IPA_UNREACHABLE);
284 if (optimize && flag_devirtualize)
285 build_type_inheritance_graph ();
286 if (file)
287 fprintf (file, "\nReclaiming functions:");
288 #ifdef ENABLE_CHECKING
289 FOR_EACH_FUNCTION (node)
290 gcc_assert (!node->aux);
291 FOR_EACH_VARIABLE (vnode)
292 gcc_assert (!vnode->aux);
293 #endif
294 /* Mark functions whose bodies are obviously needed.
295 This is mostly when they can be referenced externally. Inline clones
296 are special since their declarations are shared with master clone and thus
297 cgraph_can_remove_if_no_direct_calls_and_refs_p should not be called on them. */
298 FOR_EACH_FUNCTION (node)
300 node->used_as_abstract_origin = false;
301 if (node->definition
302 && !node->global.inlined_to
303 && !node->in_other_partition
304 && !cgraph_can_remove_if_no_direct_calls_and_refs_p (node))
306 gcc_assert (!node->global.inlined_to);
307 pointer_set_insert (reachable, node);
308 enqueue_node (node, &first, reachable);
310 else
311 gcc_assert (!node->aux);
314 /* Mark variables that are obviously needed. */
315 FOR_EACH_DEFINED_VARIABLE (vnode)
316 if (!varpool_can_remove_if_no_refs (vnode)
317 && !vnode->in_other_partition)
319 pointer_set_insert (reachable, vnode);
320 enqueue_node (vnode, &first, reachable);
323 /* Perform reachability analysis. */
324 while (first != (symtab_node *) (void *) 1)
326 bool in_boundary_p = !pointer_set_contains (reachable, first);
327 symtab_node *node = first;
329 first = (symtab_node *)first->aux;
331 /* If we are processing symbol in boundary, mark its AUX pointer for
332 possible later re-processing in enqueue_node. */
333 if (in_boundary_p)
334 node->aux = (void *)2;
335 else
337 if (TREE_CODE (node->decl) == FUNCTION_DECL
338 && DECL_ABSTRACT_ORIGIN (node->decl))
340 struct cgraph_node *origin_node
341 = cgraph_get_create_node (DECL_ABSTRACT_ORIGIN (node->decl));
342 origin_node->used_as_abstract_origin = true;
343 enqueue_node (origin_node, &first, reachable);
345 /* If any symbol in a comdat group is reachable, force
346 all externally visible symbols in the same comdat
347 group to be reachable as well. Comdat-local symbols
348 can be discarded if all uses were inlined. */
349 if (node->same_comdat_group)
351 symtab_node *next;
352 for (next = node->same_comdat_group;
353 next != node;
354 next = next->same_comdat_group)
355 if (!symtab_comdat_local_p (next)
356 && !pointer_set_insert (reachable, next))
357 enqueue_node (next, &first, reachable);
359 /* Mark references as reachable. */
360 process_references (&node->ref_list, &first,
361 before_inlining_p, reachable);
364 if (cgraph_node *cnode = dyn_cast <cgraph_node *> (node))
366 /* Mark the callees reachable unless they are direct calls to extern
367 inline functions we decided to not inline. */
368 if (!in_boundary_p)
370 struct cgraph_edge *e;
371 /* Keep alive possible targets for devirtualization. */
372 if (optimize && flag_devirtualize)
374 struct cgraph_edge *next;
375 for (e = cnode->indirect_calls; e; e = next)
377 next = e->next_callee;
378 if (e->indirect_info->polymorphic)
379 walk_polymorphic_call_targets (reachable_call_targets,
380 e, &first, reachable,
381 before_inlining_p);
384 for (e = cnode->callees; e; e = e->next_callee)
386 if (e->callee->definition
387 && !e->callee->in_other_partition
388 && (!e->inline_failed
389 || !DECL_EXTERNAL (e->callee->decl)
390 || e->callee->alias
391 || before_inlining_p))
393 /* Be sure that we will not optimize out alias target
394 body. */
395 if (DECL_EXTERNAL (e->callee->decl)
396 && e->callee->alias
397 && before_inlining_p)
399 pointer_set_insert (reachable,
400 cgraph_function_node (e->callee));
402 pointer_set_insert (reachable, e->callee);
404 enqueue_node (e->callee, &first, reachable);
407 /* When inline clone exists, mark body to be preserved so when removing
408 offline copy of the function we don't kill it. */
409 if (cnode->global.inlined_to)
410 pointer_set_insert (body_needed_for_clonning, cnode->decl);
412 /* For non-inline clones, force their origins to the boundary and ensure
413 that body is not removed. */
414 while (cnode->clone_of)
416 bool noninline = cnode->clone_of->decl != cnode->decl;
417 cnode = cnode->clone_of;
418 if (noninline)
420 pointer_set_insert (body_needed_for_clonning, cnode->decl);
421 enqueue_node (cnode, &first, reachable);
426 /* If any reachable function has simd clones, mark them as
427 reachable as well. */
428 if (cnode->simd_clones)
430 cgraph_node *next;
431 for (next = cnode->simd_clones;
432 next;
433 next = next->simdclone->next_clone)
434 if (in_boundary_p
435 || !pointer_set_insert (reachable, next))
436 enqueue_node (next, &first, reachable);
439 /* When we see constructor of external variable, keep referred nodes in the
440 boundary. This will also hold initializers of the external vars NODE
441 refers to. */
442 varpool_node *vnode = dyn_cast <varpool_node *> (node);
443 if (vnode
444 && DECL_EXTERNAL (node->decl)
445 && !vnode->alias
446 && in_boundary_p)
448 struct ipa_ref *ref;
449 for (int i = 0; ipa_ref_list_reference_iterate (&node->ref_list, i, ref); i++)
450 enqueue_node (ref->referred, &first, reachable);
454 /* Remove unreachable functions. */
455 for (node = cgraph_first_function (); node; node = next)
457 next = cgraph_next_function (node);
459 /* If node is not needed at all, remove it. */
460 if (!node->aux)
462 if (file)
463 fprintf (file, " %s/%i", node->name (), node->order);
464 cgraph_remove_node (node);
465 changed = true;
467 /* If node is unreachable, remove its body. */
468 else if (!pointer_set_contains (reachable, node))
470 if (!pointer_set_contains (body_needed_for_clonning, node->decl))
471 cgraph_release_function_body (node);
472 else if (!node->clone_of)
473 gcc_assert (in_lto_p || DECL_RESULT (node->decl));
474 if (node->definition)
476 if (file)
477 fprintf (file, " %s/%i", node->name (), node->order);
478 node->body_removed = true;
479 node->analyzed = false;
480 node->definition = false;
481 node->cpp_implicit_alias = false;
482 node->alias = false;
483 node->thunk.thunk_p = false;
484 node->weakref = false;
485 /* After early inlining we drop always_inline attributes on
486 bodies of functions that are still referenced (have their
487 address taken). */
488 DECL_ATTRIBUTES (node->decl)
489 = remove_attribute ("always_inline",
490 DECL_ATTRIBUTES (node->decl));
491 if (!node->in_other_partition)
492 node->local.local = false;
493 cgraph_node_remove_callees (node);
494 symtab_remove_from_same_comdat_group (node);
495 ipa_remove_all_references (&node->ref_list);
496 changed = true;
499 else
500 gcc_assert (node->clone_of || !cgraph_function_with_gimple_body_p (node)
501 || in_lto_p || DECL_RESULT (node->decl));
504 /* Inline clones might be kept around so their materializing allows further
505 cloning. If the function the clone is inlined into is removed, we need
506 to turn it into normal cone. */
507 FOR_EACH_FUNCTION (node)
509 if (node->global.inlined_to
510 && !node->callers)
512 gcc_assert (node->clones);
513 node->global.inlined_to = NULL;
514 update_inlined_to_pointer (node, node);
516 node->aux = NULL;
519 /* Remove unreachable variables. */
520 if (file)
521 fprintf (file, "\nReclaiming variables:");
522 for (vnode = varpool_first_variable (); vnode; vnode = vnext)
524 vnext = varpool_next_variable (vnode);
525 if (!vnode->aux
526 /* For can_refer_decl_in_current_unit_p we want to track for
527 all external variables if they are defined in other partition
528 or not. */
529 && (!flag_ltrans || !DECL_EXTERNAL (vnode->decl)))
531 if (file)
532 fprintf (file, " %s/%i", vnode->name (), vnode->order);
533 varpool_remove_node (vnode);
534 changed = true;
536 else if (!pointer_set_contains (reachable, vnode))
538 tree init;
539 if (vnode->definition)
541 if (file)
542 fprintf (file, " %s", vnode->name ());
543 changed = true;
545 vnode->body_removed = true;
546 vnode->definition = false;
547 vnode->analyzed = false;
548 vnode->aux = NULL;
550 symtab_remove_from_same_comdat_group (vnode);
552 /* Keep body if it may be useful for constant folding. */
553 if ((init = ctor_for_folding (vnode->decl)) == error_mark_node)
554 varpool_remove_initializer (vnode);
555 else
556 DECL_INITIAL (vnode->decl) = init;
557 ipa_remove_all_references (&vnode->ref_list);
559 else
560 vnode->aux = NULL;
563 pointer_set_destroy (reachable);
564 pointer_set_destroy (body_needed_for_clonning);
565 pointer_set_destroy (reachable_call_targets);
567 /* Now update address_taken flags and try to promote functions to be local. */
568 if (file)
569 fprintf (file, "\nClearing address taken flags:");
570 FOR_EACH_DEFINED_FUNCTION (node)
571 if (node->address_taken
572 && !node->used_from_other_partition)
574 if (!cgraph_for_node_and_aliases (node, has_addr_references_p, NULL, true))
576 if (file)
577 fprintf (file, " %s", node->name ());
578 node->address_taken = false;
579 changed = true;
580 if (cgraph_local_node_p (node))
582 node->local.local = true;
583 if (file)
584 fprintf (file, " (local)");
588 if (file)
589 fprintf (file, "\n");
591 #ifdef ENABLE_CHECKING
592 verify_symtab ();
593 #endif
595 /* If we removed something, perhaps profile could be improved. */
596 if (changed && optimize && inline_edge_summary_vec.exists ())
597 FOR_EACH_DEFINED_FUNCTION (node)
598 ipa_propagate_frequency (node);
600 timevar_pop (TV_IPA_UNREACHABLE);
601 return changed;
604 /* Process references to VNODE and set flags WRITTEN, ADDRESS_TAKEN, READ
605 as needed, also clear EXPLICIT_REFS if the references to given variable
606 do not need to be explicit. */
608 void
609 process_references (varpool_node *vnode,
610 bool *written, bool *address_taken,
611 bool *read, bool *explicit_refs)
613 int i;
614 struct ipa_ref *ref;
616 if (!varpool_all_refs_explicit_p (vnode)
617 || TREE_THIS_VOLATILE (vnode->decl))
618 *explicit_refs = false;
620 for (i = 0; ipa_ref_list_referring_iterate (&vnode->ref_list,
621 i, ref)
622 && *explicit_refs && (!*written || !*address_taken || !*read); i++)
623 switch (ref->use)
625 case IPA_REF_ADDR:
626 *address_taken = true;
627 break;
628 case IPA_REF_LOAD:
629 *read = true;
630 break;
631 case IPA_REF_STORE:
632 *written = true;
633 break;
634 case IPA_REF_ALIAS:
635 process_references (varpool (ref->referring), written, address_taken,
636 read, explicit_refs);
637 break;
641 /* Set TREE_READONLY bit. */
643 bool
644 set_readonly_bit (varpool_node *vnode, void *data ATTRIBUTE_UNUSED)
646 TREE_READONLY (vnode->decl) = true;
647 return false;
650 /* Set writeonly bit and clear the initalizer, since it will not be needed. */
652 bool
653 set_writeonly_bit (varpool_node *vnode, void *data ATTRIBUTE_UNUSED)
655 vnode->writeonly = true;
656 if (optimize)
658 DECL_INITIAL (vnode->decl) = NULL;
659 if (!vnode->alias)
660 ipa_remove_all_references (&vnode->ref_list);
662 return false;
665 /* Clear addressale bit of VNODE. */
667 bool
668 clear_addressable_bit (varpool_node *vnode, void *data ATTRIBUTE_UNUSED)
670 vnode->address_taken = false;
671 TREE_ADDRESSABLE (vnode->decl) = 0;
672 return false;
675 /* Discover variables that have no longer address taken or that are read only
676 and update their flags.
678 FIXME: This can not be done in between gimplify and omp_expand since
679 readonly flag plays role on what is shared and what is not. Currently we do
680 this transformation as part of whole program visibility and re-do at
681 ipa-reference pass (to take into account clonning), but it would
682 make sense to do it before early optimizations. */
684 void
685 ipa_discover_readonly_nonaddressable_vars (void)
687 varpool_node *vnode;
688 if (dump_file)
689 fprintf (dump_file, "Clearing variable flags:");
690 FOR_EACH_VARIABLE (vnode)
691 if (!vnode->alias
692 && (TREE_ADDRESSABLE (vnode->decl)
693 || !vnode->writeonly
694 || !TREE_READONLY (vnode->decl)))
696 bool written = false;
697 bool address_taken = false;
698 bool read = false;
699 bool explicit_refs = true;
701 process_references (vnode, &written, &address_taken, &read, &explicit_refs);
702 if (!explicit_refs)
703 continue;
704 if (!address_taken)
706 if (TREE_ADDRESSABLE (vnode->decl) && dump_file)
707 fprintf (dump_file, " %s (non-addressable)", vnode->name ());
708 varpool_for_node_and_aliases (vnode, clear_addressable_bit, NULL, true);
710 if (!address_taken && !written
711 /* Making variable in explicit section readonly can cause section
712 type conflict.
713 See e.g. gcc.c-torture/compile/pr23237.c */
714 && vnode->get_section () == NULL)
716 if (!TREE_READONLY (vnode->decl) && dump_file)
717 fprintf (dump_file, " %s (read-only)", vnode->name ());
718 varpool_for_node_and_aliases (vnode, set_readonly_bit, NULL, true);
720 if (!vnode->writeonly && !read && !address_taken && written)
722 if (dump_file)
723 fprintf (dump_file, " %s (write-only)", vnode->name ());
724 varpool_for_node_and_aliases (vnode, set_writeonly_bit, NULL, true);
727 if (dump_file)
728 fprintf (dump_file, "\n");
731 /* Free inline summary. */
733 namespace {
735 const pass_data pass_data_ipa_free_inline_summary =
737 SIMPLE_IPA_PASS, /* type */
738 "*free_inline_summary", /* name */
739 OPTGROUP_NONE, /* optinfo_flags */
740 true, /* has_execute */
741 TV_IPA_FREE_INLINE_SUMMARY, /* tv_id */
742 0, /* properties_required */
743 0, /* properties_provided */
744 0, /* properties_destroyed */
745 0, /* todo_flags_start */
746 0, /* todo_flags_finish */
749 class pass_ipa_free_inline_summary : public simple_ipa_opt_pass
751 public:
752 pass_ipa_free_inline_summary (gcc::context *ctxt)
753 : simple_ipa_opt_pass (pass_data_ipa_free_inline_summary, ctxt)
756 /* opt_pass methods: */
757 virtual unsigned int execute (function *)
759 inline_free_summary ();
760 return 0;
763 }; // class pass_ipa_free_inline_summary
765 } // anon namespace
767 simple_ipa_opt_pass *
768 make_pass_ipa_free_inline_summary (gcc::context *ctxt)
770 return new pass_ipa_free_inline_summary (ctxt);
773 /* Generate and emit a static constructor or destructor. WHICH must
774 be one of 'I' (for a constructor) or 'D' (for a destructor). BODY
775 is a STATEMENT_LIST containing GENERIC statements. PRIORITY is the
776 initialization priority for this constructor or destructor.
778 FINAL specify whether the externally visible name for collect2 should
779 be produced. */
781 static void
782 cgraph_build_static_cdtor_1 (char which, tree body, int priority, bool final)
784 static int counter = 0;
785 char which_buf[16];
786 tree decl, name, resdecl;
788 /* The priority is encoded in the constructor or destructor name.
789 collect2 will sort the names and arrange that they are called at
790 program startup. */
791 if (final)
792 sprintf (which_buf, "%c_%.5d_%d", which, priority, counter++);
793 else
794 /* Proudce sane name but one not recognizable by collect2, just for the
795 case we fail to inline the function. */
796 sprintf (which_buf, "sub_%c_%.5d_%d", which, priority, counter++);
797 name = get_file_function_name (which_buf);
799 decl = build_decl (input_location, FUNCTION_DECL, name,
800 build_function_type_list (void_type_node, NULL_TREE));
801 current_function_decl = decl;
803 resdecl = build_decl (input_location,
804 RESULT_DECL, NULL_TREE, void_type_node);
805 DECL_ARTIFICIAL (resdecl) = 1;
806 DECL_RESULT (decl) = resdecl;
807 DECL_CONTEXT (resdecl) = decl;
809 allocate_struct_function (decl, false);
811 TREE_STATIC (decl) = 1;
812 TREE_USED (decl) = 1;
813 DECL_ARTIFICIAL (decl) = 1;
814 DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;
815 DECL_SAVED_TREE (decl) = body;
816 if (!targetm.have_ctors_dtors && final)
818 TREE_PUBLIC (decl) = 1;
819 DECL_PRESERVE_P (decl) = 1;
821 DECL_UNINLINABLE (decl) = 1;
823 DECL_INITIAL (decl) = make_node (BLOCK);
824 TREE_USED (DECL_INITIAL (decl)) = 1;
826 DECL_SOURCE_LOCATION (decl) = input_location;
827 cfun->function_end_locus = input_location;
829 switch (which)
831 case 'I':
832 DECL_STATIC_CONSTRUCTOR (decl) = 1;
833 decl_init_priority_insert (decl, priority);
834 break;
835 case 'D':
836 DECL_STATIC_DESTRUCTOR (decl) = 1;
837 decl_fini_priority_insert (decl, priority);
838 break;
839 default:
840 gcc_unreachable ();
843 gimplify_function_tree (decl);
845 cgraph_add_new_function (decl, false);
847 set_cfun (NULL);
848 current_function_decl = NULL;
851 /* Generate and emit a static constructor or destructor. WHICH must
852 be one of 'I' (for a constructor) or 'D' (for a destructor). BODY
853 is a STATEMENT_LIST containing GENERIC statements. PRIORITY is the
854 initialization priority for this constructor or destructor. */
856 void
857 cgraph_build_static_cdtor (char which, tree body, int priority)
859 cgraph_build_static_cdtor_1 (which, body, priority, false);
862 /* A vector of FUNCTION_DECLs declared as static constructors. */
863 static vec<tree> static_ctors;
864 /* A vector of FUNCTION_DECLs declared as static destructors. */
865 static vec<tree> static_dtors;
867 /* When target does not have ctors and dtors, we call all constructor
868 and destructor by special initialization/destruction function
869 recognized by collect2.
871 When we are going to build this function, collect all constructors and
872 destructors and turn them into normal functions. */
874 static void
875 record_cdtor_fn (struct cgraph_node *node)
877 if (DECL_STATIC_CONSTRUCTOR (node->decl))
878 static_ctors.safe_push (node->decl);
879 if (DECL_STATIC_DESTRUCTOR (node->decl))
880 static_dtors.safe_push (node->decl);
881 node = cgraph_get_node (node->decl);
882 DECL_DISREGARD_INLINE_LIMITS (node->decl) = 1;
885 /* Define global constructors/destructor functions for the CDTORS, of
886 which they are LEN. The CDTORS are sorted by initialization
887 priority. If CTOR_P is true, these are constructors; otherwise,
888 they are destructors. */
890 static void
891 build_cdtor (bool ctor_p, vec<tree> cdtors)
893 size_t i,j;
894 size_t len = cdtors.length ();
896 i = 0;
897 while (i < len)
899 tree body;
900 tree fn;
901 priority_type priority;
903 priority = 0;
904 body = NULL_TREE;
905 j = i;
908 priority_type p;
909 fn = cdtors[j];
910 p = ctor_p ? DECL_INIT_PRIORITY (fn) : DECL_FINI_PRIORITY (fn);
911 if (j == i)
912 priority = p;
913 else if (p != priority)
914 break;
915 j++;
917 while (j < len);
919 /* When there is only one cdtor and target supports them, do nothing. */
920 if (j == i + 1
921 && targetm.have_ctors_dtors)
923 i++;
924 continue;
926 /* Find the next batch of constructors/destructors with the same
927 initialization priority. */
928 for (;i < j; i++)
930 tree call;
931 fn = cdtors[i];
932 call = build_call_expr (fn, 0);
933 if (ctor_p)
934 DECL_STATIC_CONSTRUCTOR (fn) = 0;
935 else
936 DECL_STATIC_DESTRUCTOR (fn) = 0;
937 /* We do not want to optimize away pure/const calls here.
938 When optimizing, these should be already removed, when not
939 optimizing, we want user to be able to breakpoint in them. */
940 TREE_SIDE_EFFECTS (call) = 1;
941 append_to_statement_list (call, &body);
943 gcc_assert (body != NULL_TREE);
944 /* Generate a function to call all the function of like
945 priority. */
946 cgraph_build_static_cdtor_1 (ctor_p ? 'I' : 'D', body, priority, true);
950 /* Comparison function for qsort. P1 and P2 are actually of type
951 "tree *" and point to static constructors. DECL_INIT_PRIORITY is
952 used to determine the sort order. */
954 static int
955 compare_ctor (const void *p1, const void *p2)
957 tree f1;
958 tree f2;
959 int priority1;
960 int priority2;
962 f1 = *(const tree *)p1;
963 f2 = *(const tree *)p2;
964 priority1 = DECL_INIT_PRIORITY (f1);
965 priority2 = DECL_INIT_PRIORITY (f2);
967 if (priority1 < priority2)
968 return -1;
969 else if (priority1 > priority2)
970 return 1;
971 else
972 /* Ensure a stable sort. Constructors are executed in backwarding
973 order to make LTO initialize braries first. */
974 return DECL_UID (f2) - DECL_UID (f1);
977 /* Comparison function for qsort. P1 and P2 are actually of type
978 "tree *" and point to static destructors. DECL_FINI_PRIORITY is
979 used to determine the sort order. */
981 static int
982 compare_dtor (const void *p1, const void *p2)
984 tree f1;
985 tree f2;
986 int priority1;
987 int priority2;
989 f1 = *(const tree *)p1;
990 f2 = *(const tree *)p2;
991 priority1 = DECL_FINI_PRIORITY (f1);
992 priority2 = DECL_FINI_PRIORITY (f2);
994 if (priority1 < priority2)
995 return -1;
996 else if (priority1 > priority2)
997 return 1;
998 else
999 /* Ensure a stable sort. */
1000 return DECL_UID (f1) - DECL_UID (f2);
1003 /* Generate functions to call static constructors and destructors
1004 for targets that do not support .ctors/.dtors sections. These
1005 functions have magic names which are detected by collect2. */
1007 static void
1008 build_cdtor_fns (void)
1010 if (!static_ctors.is_empty ())
1012 gcc_assert (!targetm.have_ctors_dtors || in_lto_p);
1013 static_ctors.qsort (compare_ctor);
1014 build_cdtor (/*ctor_p=*/true, static_ctors);
1017 if (!static_dtors.is_empty ())
1019 gcc_assert (!targetm.have_ctors_dtors || in_lto_p);
1020 static_dtors.qsort (compare_dtor);
1021 build_cdtor (/*ctor_p=*/false, static_dtors);
1025 /* Look for constructors and destructors and produce function calling them.
1026 This is needed for targets not supporting ctors or dtors, but we perform the
1027 transformation also at linktime to merge possibly numerous
1028 constructors/destructors into single function to improve code locality and
1029 reduce size. */
1031 static unsigned int
1032 ipa_cdtor_merge (void)
1034 struct cgraph_node *node;
1035 FOR_EACH_DEFINED_FUNCTION (node)
1036 if (DECL_STATIC_CONSTRUCTOR (node->decl)
1037 || DECL_STATIC_DESTRUCTOR (node->decl))
1038 record_cdtor_fn (node);
1039 build_cdtor_fns ();
1040 static_ctors.release ();
1041 static_dtors.release ();
1042 return 0;
1045 namespace {
1047 const pass_data pass_data_ipa_cdtor_merge =
1049 IPA_PASS, /* type */
1050 "cdtor", /* name */
1051 OPTGROUP_NONE, /* optinfo_flags */
1052 true, /* has_execute */
1053 TV_CGRAPHOPT, /* tv_id */
1054 0, /* properties_required */
1055 0, /* properties_provided */
1056 0, /* properties_destroyed */
1057 0, /* todo_flags_start */
1058 0, /* todo_flags_finish */
1061 class pass_ipa_cdtor_merge : public ipa_opt_pass_d
1063 public:
1064 pass_ipa_cdtor_merge (gcc::context *ctxt)
1065 : ipa_opt_pass_d (pass_data_ipa_cdtor_merge, ctxt,
1066 NULL, /* generate_summary */
1067 NULL, /* write_summary */
1068 NULL, /* read_summary */
1069 NULL, /* write_optimization_summary */
1070 NULL, /* read_optimization_summary */
1071 NULL, /* stmt_fixup */
1072 0, /* function_transform_todo_flags_start */
1073 NULL, /* function_transform */
1074 NULL) /* variable_transform */
1077 /* opt_pass methods: */
1078 virtual bool gate (function *);
1079 virtual unsigned int execute (function *) { return ipa_cdtor_merge (); }
1081 }; // class pass_ipa_cdtor_merge
1083 bool
1084 pass_ipa_cdtor_merge::gate (function *)
1086 /* Perform the pass when we have no ctors/dtors support
1087 or at LTO time to merge multiple constructors into single
1088 function. */
1089 return !targetm.have_ctors_dtors || (optimize && in_lto_p);
1092 } // anon namespace
1094 ipa_opt_pass_d *
1095 make_pass_ipa_cdtor_merge (gcc::context *ctxt)
1097 return new pass_ipa_cdtor_merge (ctxt);