add hash_map class
[official-gcc.git] / gcc / ipa.c
blob04f2c79ae331182a638e5cc5b3bc8915d5ea7689
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 "hash-map.h"
30 #include "pointer-set.h"
31 #include "gimple-expr.h"
32 #include "gimplify.h"
33 #include "flags.h"
34 #include "target.h"
35 #include "tree-iterator.h"
36 #include "ipa-utils.h"
37 #include "ipa-inline.h"
38 #include "tree-inline.h"
39 #include "profile.h"
40 #include "params.h"
41 #include "internal-fn.h"
42 #include "tree-ssa-alias.h"
43 #include "gimple.h"
44 #include "dbgcnt.h"
47 /* Return true when NODE has ADDR reference. */
49 static bool
50 has_addr_references_p (struct cgraph_node *node,
51 void *data ATTRIBUTE_UNUSED)
53 int i;
54 struct ipa_ref *ref;
56 for (i = 0; ipa_ref_list_referring_iterate (&node->ref_list,
57 i, ref); i++)
58 if (ref->use == IPA_REF_ADDR)
59 return true;
60 return false;
63 /* Look for all functions inlined to NODE and update their inlined_to pointers
64 to INLINED_TO. */
66 static void
67 update_inlined_to_pointer (struct cgraph_node *node, struct cgraph_node *inlined_to)
69 struct cgraph_edge *e;
70 for (e = node->callees; e; e = e->next_callee)
71 if (e->callee->global.inlined_to)
73 e->callee->global.inlined_to = inlined_to;
74 update_inlined_to_pointer (e->callee, inlined_to);
78 /* Add symtab NODE to queue starting at FIRST.
80 The queue is linked via AUX pointers and terminated by pointer to 1.
81 We enqueue nodes at two occasions: when we find them reachable or when we find
82 their bodies needed for further clonning. In the second case we mark them
83 by pointer to 2 after processing so they are re-queue when they become
84 reachable. */
86 static void
87 enqueue_node (symtab_node *node, symtab_node **first,
88 struct pointer_set_t *reachable)
90 /* Node is still in queue; do nothing. */
91 if (node->aux && node->aux != (void *) 2)
92 return;
93 /* Node was already processed as unreachable, re-enqueue
94 only if it became reachable now. */
95 if (node->aux == (void *)2 && !pointer_set_contains (reachable, node))
96 return;
97 node->aux = *first;
98 *first = node;
101 /* Process references. */
103 static void
104 process_references (struct ipa_ref_list *list,
105 symtab_node **first,
106 bool before_inlining_p,
107 struct pointer_set_t *reachable)
109 int i;
110 struct ipa_ref *ref;
111 for (i = 0; ipa_ref_list_reference_iterate (list, i, ref); i++)
113 symtab_node *node = ref->referred;
115 if (node->definition && !node->in_other_partition
116 && ((!DECL_EXTERNAL (node->decl) || node->alias)
117 || (((before_inlining_p
118 && (cgraph_state < CGRAPH_STATE_IPA_SSA
119 || !lookup_attribute ("always_inline",
120 DECL_ATTRIBUTES (node->decl)))))
121 /* We use variable constructors during late complation for
122 constant folding. Keep references alive so partitioning
123 knows about potential references. */
124 || (TREE_CODE (node->decl) == VAR_DECL
125 && flag_wpa
126 && ctor_for_folding (node->decl)
127 != error_mark_node))))
128 pointer_set_insert (reachable, node);
129 enqueue_node (node, first, reachable);
133 /* EDGE is an polymorphic call. If BEFORE_INLINING_P is set, mark
134 all its potential targets as reachable to permit later inlining if
135 devirtualization happens. After inlining still keep their declarations
136 around, so we can devirtualize to a direct call.
138 Also try to make trivial devirutalization when no or only one target is
139 possible. */
141 static void
142 walk_polymorphic_call_targets (pointer_set_t *reachable_call_targets,
143 struct cgraph_edge *edge,
144 symtab_node **first,
145 pointer_set_t *reachable, bool before_inlining_p)
147 unsigned int i;
148 void *cache_token;
149 bool final;
150 vec <cgraph_node *>targets
151 = possible_polymorphic_call_targets
152 (edge, &final, &cache_token);
154 if (!pointer_set_insert (reachable_call_targets,
155 cache_token))
157 for (i = 0; i < targets.length (); i++)
159 struct cgraph_node *n = targets[i];
161 /* Do not bother to mark virtual methods in anonymous namespace;
162 either we will find use of virtual table defining it, or it is
163 unused. */
164 if (TREE_CODE (TREE_TYPE (n->decl)) == METHOD_TYPE
165 && type_in_anonymous_namespace_p
166 (method_class_type (TREE_TYPE (n->decl))))
167 continue;
169 /* Prior inlining, keep alive bodies of possible targets for
170 devirtualization. */
171 if (n->definition
172 && (before_inlining_p
173 && (cgraph_state < CGRAPH_STATE_IPA_SSA
174 || !lookup_attribute ("always_inline",
175 DECL_ATTRIBUTES (n->decl)))))
176 pointer_set_insert (reachable, n);
178 /* Even after inlining we want to keep the possible targets in the
179 boundary, so late passes can still produce direct call even if
180 the chance for inlining is lost. */
181 enqueue_node (n, first, reachable);
185 /* Very trivial devirtualization; when the type is
186 final or anonymous (so we know all its derivation)
187 and there is only one possible virtual call target,
188 make the edge direct. */
189 if (final)
191 if (targets.length () <= 1 && dbg_cnt (devirt))
193 cgraph_node *target, *node = edge->caller;
194 if (targets.length () == 1)
195 target = targets[0];
196 else
197 target = cgraph_get_create_node
198 (builtin_decl_implicit (BUILT_IN_UNREACHABLE));
200 if (dump_enabled_p ())
202 location_t locus = gimple_location (edge->call_stmt);
203 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, locus,
204 "devirtualizing call in %s/%i to %s/%i\n",
205 edge->caller->name (), edge->caller->order,
206 target->name (),
207 target->order);
209 edge = cgraph_make_edge_direct (edge, target);
210 if (inline_summary_vec)
211 inline_update_overall_summary (node);
212 else if (edge->call_stmt)
213 cgraph_redirect_edge_call_stmt_to_callee (edge);
218 /* Perform reachability analysis and reclaim all unreachable nodes.
220 The algorithm is basically mark&sweep but with some extra refinements:
222 - reachable extern inline functions needs special handling; the bodies needs
223 to stay in memory until inlining in hope that they will be inlined.
224 After inlining we release their bodies and turn them into unanalyzed
225 nodes even when they are reachable.
227 BEFORE_INLINING_P specify whether we are before or after inlining.
229 - virtual functions are kept in callgraph even if they seem unreachable in
230 hope calls to them will be devirtualized.
232 Again we remove them after inlining. In late optimization some
233 devirtualization may happen, but it is not important since we won't inline
234 the call. In theory early opts and IPA should work out all important cases.
236 - virtual clones needs bodies of their origins for later materialization;
237 this means that we want to keep the body even if the origin is unreachable
238 otherwise. To avoid origin from sitting in the callgraph and being
239 walked by IPA passes, we turn them into unanalyzed nodes with body
240 defined.
242 We maintain set of function declaration where body needs to stay in
243 body_needed_for_clonning
245 Inline clones represent special case: their declaration match the
246 declaration of origin and cgraph_remove_node already knows how to
247 reshape callgraph and preserve body when offline copy of function or
248 inline clone is being removed.
250 - C++ virtual tables keyed to other unit are represented as DECL_EXTERNAL
251 variables with DECL_INITIAL set. We finalize these and keep reachable
252 ones around for constant folding purposes. After inlining we however
253 stop walking their references to let everything static referneced by them
254 to be removed when it is otherwise unreachable.
256 We maintain queue of both reachable symbols (i.e. defined symbols that needs
257 to stay) and symbols that are in boundary (i.e. external symbols referenced
258 by reachable symbols or origins of clones). The queue is represented
259 as linked list by AUX pointer terminated by 1.
261 At the end we keep all reachable symbols. For symbols in boundary we always
262 turn definition into a declaration, but we may keep function body around
263 based on body_needed_for_clonning
265 All symbols that enter the queue have AUX pointer non-zero and are in the
266 boundary. Pointer set REACHABLE is used to track reachable symbols.
268 Every symbol can be visited twice - once as part of boundary and once
269 as real reachable symbol. enqueue_node needs to decide whether the
270 node needs to be re-queued for second processing. For this purpose
271 we set AUX pointer of processed symbols in the boundary to constant 2. */
273 bool
274 symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
276 symtab_node *first = (symtab_node *) (void *) 1;
277 struct cgraph_node *node, *next;
278 varpool_node *vnode, *vnext;
279 bool changed = false;
280 struct pointer_set_t *reachable = pointer_set_create ();
281 struct pointer_set_t *body_needed_for_clonning = pointer_set_create ();
282 struct pointer_set_t *reachable_call_targets = pointer_set_create ();
284 timevar_push (TV_IPA_UNREACHABLE);
285 if (optimize && flag_devirtualize)
286 build_type_inheritance_graph ();
287 if (file)
288 fprintf (file, "\nReclaiming functions:");
289 #ifdef ENABLE_CHECKING
290 FOR_EACH_FUNCTION (node)
291 gcc_assert (!node->aux);
292 FOR_EACH_VARIABLE (vnode)
293 gcc_assert (!vnode->aux);
294 #endif
295 /* Mark functions whose bodies are obviously needed.
296 This is mostly when they can be referenced externally. Inline clones
297 are special since their declarations are shared with master clone and thus
298 cgraph_can_remove_if_no_direct_calls_and_refs_p should not be called on them. */
299 FOR_EACH_FUNCTION (node)
301 node->used_as_abstract_origin = false;
302 if (node->definition
303 && !node->global.inlined_to
304 && !node->in_other_partition
305 && !cgraph_can_remove_if_no_direct_calls_and_refs_p (node))
307 gcc_assert (!node->global.inlined_to);
308 pointer_set_insert (reachable, node);
309 enqueue_node (node, &first, reachable);
311 else
312 gcc_assert (!node->aux);
315 /* Mark variables that are obviously needed. */
316 FOR_EACH_DEFINED_VARIABLE (vnode)
317 if (!varpool_can_remove_if_no_refs (vnode)
318 && !vnode->in_other_partition)
320 pointer_set_insert (reachable, vnode);
321 enqueue_node (vnode, &first, reachable);
324 /* Perform reachability analysis. */
325 while (first != (symtab_node *) (void *) 1)
327 bool in_boundary_p = !pointer_set_contains (reachable, first);
328 symtab_node *node = first;
330 first = (symtab_node *)first->aux;
332 /* If we are processing symbol in boundary, mark its AUX pointer for
333 possible later re-processing in enqueue_node. */
334 if (in_boundary_p)
335 node->aux = (void *)2;
336 else
338 if (TREE_CODE (node->decl) == FUNCTION_DECL
339 && DECL_ABSTRACT_ORIGIN (node->decl))
341 struct cgraph_node *origin_node
342 = cgraph_get_create_node (DECL_ABSTRACT_ORIGIN (node->decl));
343 origin_node->used_as_abstract_origin = true;
344 enqueue_node (origin_node, &first, reachable);
346 /* If any symbol in a comdat group is reachable, force
347 all externally visible symbols in the same comdat
348 group to be reachable as well. Comdat-local symbols
349 can be discarded if all uses were inlined. */
350 if (node->same_comdat_group)
352 symtab_node *next;
353 for (next = node->same_comdat_group;
354 next != node;
355 next = next->same_comdat_group)
356 if (!symtab_comdat_local_p (next)
357 && !pointer_set_insert (reachable, next))
358 enqueue_node (next, &first, reachable);
360 /* Mark references as reachable. */
361 process_references (&node->ref_list, &first,
362 before_inlining_p, reachable);
365 if (cgraph_node *cnode = dyn_cast <cgraph_node *> (node))
367 /* Mark the callees reachable unless they are direct calls to extern
368 inline functions we decided to not inline. */
369 if (!in_boundary_p)
371 struct cgraph_edge *e;
372 /* Keep alive possible targets for devirtualization. */
373 if (optimize && flag_devirtualize)
375 struct cgraph_edge *next;
376 for (e = cnode->indirect_calls; e; e = next)
378 next = e->next_callee;
379 if (e->indirect_info->polymorphic)
380 walk_polymorphic_call_targets (reachable_call_targets,
381 e, &first, reachable,
382 before_inlining_p);
385 for (e = cnode->callees; e; e = e->next_callee)
387 if (e->callee->definition
388 && !e->callee->in_other_partition
389 && (!e->inline_failed
390 || !DECL_EXTERNAL (e->callee->decl)
391 || e->callee->alias
392 || before_inlining_p))
394 /* Be sure that we will not optimize out alias target
395 body. */
396 if (DECL_EXTERNAL (e->callee->decl)
397 && e->callee->alias
398 && before_inlining_p)
400 pointer_set_insert (reachable,
401 cgraph_function_node (e->callee));
403 pointer_set_insert (reachable, e->callee);
405 enqueue_node (e->callee, &first, reachable);
408 /* When inline clone exists, mark body to be preserved so when removing
409 offline copy of the function we don't kill it. */
410 if (cnode->global.inlined_to)
411 pointer_set_insert (body_needed_for_clonning, cnode->decl);
413 /* For non-inline clones, force their origins to the boundary and ensure
414 that body is not removed. */
415 while (cnode->clone_of)
417 bool noninline = cnode->clone_of->decl != cnode->decl;
418 cnode = cnode->clone_of;
419 if (noninline)
421 pointer_set_insert (body_needed_for_clonning, cnode->decl);
422 enqueue_node (cnode, &first, reachable);
427 /* If any reachable function has simd clones, mark them as
428 reachable as well. */
429 if (cnode->simd_clones)
431 cgraph_node *next;
432 for (next = cnode->simd_clones;
433 next;
434 next = next->simdclone->next_clone)
435 if (in_boundary_p
436 || !pointer_set_insert (reachable, next))
437 enqueue_node (next, &first, reachable);
440 /* When we see constructor of external variable, keep referred nodes in the
441 boundary. This will also hold initializers of the external vars NODE
442 refers to. */
443 varpool_node *vnode = dyn_cast <varpool_node *> (node);
444 if (vnode
445 && DECL_EXTERNAL (node->decl)
446 && !vnode->alias
447 && in_boundary_p)
449 struct ipa_ref *ref;
450 for (int i = 0; ipa_ref_list_reference_iterate (&node->ref_list, i, ref); i++)
451 enqueue_node (ref->referred, &first, reachable);
455 /* Remove unreachable functions. */
456 for (node = cgraph_first_function (); node; node = next)
458 next = cgraph_next_function (node);
460 /* If node is not needed at all, remove it. */
461 if (!node->aux)
463 if (file)
464 fprintf (file, " %s/%i", node->name (), node->order);
465 cgraph_remove_node (node);
466 changed = true;
468 /* If node is unreachable, remove its body. */
469 else if (!pointer_set_contains (reachable, node))
471 if (!pointer_set_contains (body_needed_for_clonning, node->decl))
472 cgraph_release_function_body (node);
473 else if (!node->clone_of)
474 gcc_assert (in_lto_p || DECL_RESULT (node->decl));
475 if (node->definition)
477 if (file)
478 fprintf (file, " %s/%i", node->name (), node->order);
479 node->body_removed = true;
480 node->analyzed = false;
481 node->definition = false;
482 node->cpp_implicit_alias = false;
483 node->alias = false;
484 node->thunk.thunk_p = false;
485 node->weakref = false;
486 /* After early inlining we drop always_inline attributes on
487 bodies of functions that are still referenced (have their
488 address taken). */
489 DECL_ATTRIBUTES (node->decl)
490 = remove_attribute ("always_inline",
491 DECL_ATTRIBUTES (node->decl));
492 if (!node->in_other_partition)
493 node->local.local = false;
494 cgraph_node_remove_callees (node);
495 symtab_remove_from_same_comdat_group (node);
496 ipa_remove_all_references (&node->ref_list);
497 changed = true;
500 else
501 gcc_assert (node->clone_of || !cgraph_function_with_gimple_body_p (node)
502 || in_lto_p || DECL_RESULT (node->decl));
505 /* Inline clones might be kept around so their materializing allows further
506 cloning. If the function the clone is inlined into is removed, we need
507 to turn it into normal cone. */
508 FOR_EACH_FUNCTION (node)
510 if (node->global.inlined_to
511 && !node->callers)
513 gcc_assert (node->clones);
514 node->global.inlined_to = NULL;
515 update_inlined_to_pointer (node, node);
517 node->aux = NULL;
520 /* Remove unreachable variables. */
521 if (file)
522 fprintf (file, "\nReclaiming variables:");
523 for (vnode = varpool_first_variable (); vnode; vnode = vnext)
525 vnext = varpool_next_variable (vnode);
526 if (!vnode->aux
527 /* For can_refer_decl_in_current_unit_p we want to track for
528 all external variables if they are defined in other partition
529 or not. */
530 && (!flag_ltrans || !DECL_EXTERNAL (vnode->decl)))
532 if (file)
533 fprintf (file, " %s/%i", vnode->name (), vnode->order);
534 varpool_remove_node (vnode);
535 changed = true;
537 else if (!pointer_set_contains (reachable, vnode))
539 tree init;
540 if (vnode->definition)
542 if (file)
543 fprintf (file, " %s", vnode->name ());
544 changed = true;
546 vnode->body_removed = true;
547 vnode->definition = false;
548 vnode->analyzed = false;
549 vnode->aux = NULL;
551 symtab_remove_from_same_comdat_group (vnode);
553 /* Keep body if it may be useful for constant folding. */
554 if ((init = ctor_for_folding (vnode->decl)) == error_mark_node)
555 varpool_remove_initializer (vnode);
556 else
557 DECL_INITIAL (vnode->decl) = init;
558 ipa_remove_all_references (&vnode->ref_list);
560 else
561 vnode->aux = NULL;
564 pointer_set_destroy (reachable);
565 pointer_set_destroy (body_needed_for_clonning);
566 pointer_set_destroy (reachable_call_targets);
568 /* Now update address_taken flags and try to promote functions to be local. */
569 if (file)
570 fprintf (file, "\nClearing address taken flags:");
571 FOR_EACH_DEFINED_FUNCTION (node)
572 if (node->address_taken
573 && !node->used_from_other_partition)
575 if (!cgraph_for_node_and_aliases (node, has_addr_references_p, NULL, true))
577 if (file)
578 fprintf (file, " %s", node->name ());
579 node->address_taken = false;
580 changed = true;
581 if (cgraph_local_node_p (node))
583 node->local.local = true;
584 if (file)
585 fprintf (file, " (local)");
589 if (file)
590 fprintf (file, "\n");
592 #ifdef ENABLE_CHECKING
593 verify_symtab ();
594 #endif
596 /* If we removed something, perhaps profile could be improved. */
597 if (changed && optimize && inline_edge_summary_vec.exists ())
598 FOR_EACH_DEFINED_FUNCTION (node)
599 ipa_propagate_frequency (node);
601 timevar_pop (TV_IPA_UNREACHABLE);
602 return changed;
605 /* Process references to VNODE and set flags WRITTEN, ADDRESS_TAKEN, READ
606 as needed, also clear EXPLICIT_REFS if the references to given variable
607 do not need to be explicit. */
609 void
610 process_references (varpool_node *vnode,
611 bool *written, bool *address_taken,
612 bool *read, bool *explicit_refs)
614 int i;
615 struct ipa_ref *ref;
617 if (!varpool_all_refs_explicit_p (vnode)
618 || TREE_THIS_VOLATILE (vnode->decl))
619 *explicit_refs = false;
621 for (i = 0; ipa_ref_list_referring_iterate (&vnode->ref_list,
622 i, ref)
623 && *explicit_refs && (!*written || !*address_taken || !*read); i++)
624 switch (ref->use)
626 case IPA_REF_ADDR:
627 *address_taken = true;
628 break;
629 case IPA_REF_LOAD:
630 *read = true;
631 break;
632 case IPA_REF_STORE:
633 *written = true;
634 break;
635 case IPA_REF_ALIAS:
636 process_references (varpool (ref->referring), written, address_taken,
637 read, explicit_refs);
638 break;
642 /* Set TREE_READONLY bit. */
644 bool
645 set_readonly_bit (varpool_node *vnode, void *data ATTRIBUTE_UNUSED)
647 TREE_READONLY (vnode->decl) = true;
648 return false;
651 /* Set writeonly bit and clear the initalizer, since it will not be needed. */
653 bool
654 set_writeonly_bit (varpool_node *vnode, void *data ATTRIBUTE_UNUSED)
656 vnode->writeonly = true;
657 if (optimize)
659 DECL_INITIAL (vnode->decl) = NULL;
660 if (!vnode->alias)
661 ipa_remove_all_references (&vnode->ref_list);
663 return false;
666 /* Clear addressale bit of VNODE. */
668 bool
669 clear_addressable_bit (varpool_node *vnode, void *data ATTRIBUTE_UNUSED)
671 vnode->address_taken = false;
672 TREE_ADDRESSABLE (vnode->decl) = 0;
673 return false;
676 /* Discover variables that have no longer address taken or that are read only
677 and update their flags.
679 FIXME: This can not be done in between gimplify and omp_expand since
680 readonly flag plays role on what is shared and what is not. Currently we do
681 this transformation as part of whole program visibility and re-do at
682 ipa-reference pass (to take into account clonning), but it would
683 make sense to do it before early optimizations. */
685 void
686 ipa_discover_readonly_nonaddressable_vars (void)
688 varpool_node *vnode;
689 if (dump_file)
690 fprintf (dump_file, "Clearing variable flags:");
691 FOR_EACH_VARIABLE (vnode)
692 if (!vnode->alias
693 && (TREE_ADDRESSABLE (vnode->decl)
694 || !vnode->writeonly
695 || !TREE_READONLY (vnode->decl)))
697 bool written = false;
698 bool address_taken = false;
699 bool read = false;
700 bool explicit_refs = true;
702 process_references (vnode, &written, &address_taken, &read, &explicit_refs);
703 if (!explicit_refs)
704 continue;
705 if (!address_taken)
707 if (TREE_ADDRESSABLE (vnode->decl) && dump_file)
708 fprintf (dump_file, " %s (non-addressable)", vnode->name ());
709 varpool_for_node_and_aliases (vnode, clear_addressable_bit, NULL, true);
711 if (!address_taken && !written
712 /* Making variable in explicit section readonly can cause section
713 type conflict.
714 See e.g. gcc.c-torture/compile/pr23237.c */
715 && vnode->get_section () == NULL)
717 if (!TREE_READONLY (vnode->decl) && dump_file)
718 fprintf (dump_file, " %s (read-only)", vnode->name ());
719 varpool_for_node_and_aliases (vnode, set_readonly_bit, NULL, true);
721 if (!vnode->writeonly && !read && !address_taken && written)
723 if (dump_file)
724 fprintf (dump_file, " %s (write-only)", vnode->name ());
725 varpool_for_node_and_aliases (vnode, set_writeonly_bit, NULL, true);
728 if (dump_file)
729 fprintf (dump_file, "\n");
732 /* Free inline summary. */
734 namespace {
736 const pass_data pass_data_ipa_free_inline_summary =
738 SIMPLE_IPA_PASS, /* type */
739 "*free_inline_summary", /* name */
740 OPTGROUP_NONE, /* optinfo_flags */
741 true, /* has_execute */
742 TV_IPA_FREE_INLINE_SUMMARY, /* tv_id */
743 0, /* properties_required */
744 0, /* properties_provided */
745 0, /* properties_destroyed */
746 0, /* todo_flags_start */
747 0, /* todo_flags_finish */
750 class pass_ipa_free_inline_summary : public simple_ipa_opt_pass
752 public:
753 pass_ipa_free_inline_summary (gcc::context *ctxt)
754 : simple_ipa_opt_pass (pass_data_ipa_free_inline_summary, ctxt)
757 /* opt_pass methods: */
758 virtual unsigned int execute (function *)
760 inline_free_summary ();
761 return 0;
764 }; // class pass_ipa_free_inline_summary
766 } // anon namespace
768 simple_ipa_opt_pass *
769 make_pass_ipa_free_inline_summary (gcc::context *ctxt)
771 return new pass_ipa_free_inline_summary (ctxt);
774 /* Generate and emit a static constructor or destructor. WHICH must
775 be one of 'I' (for a constructor) or 'D' (for a destructor). BODY
776 is a STATEMENT_LIST containing GENERIC statements. PRIORITY is the
777 initialization priority for this constructor or destructor.
779 FINAL specify whether the externally visible name for collect2 should
780 be produced. */
782 static void
783 cgraph_build_static_cdtor_1 (char which, tree body, int priority, bool final)
785 static int counter = 0;
786 char which_buf[16];
787 tree decl, name, resdecl;
789 /* The priority is encoded in the constructor or destructor name.
790 collect2 will sort the names and arrange that they are called at
791 program startup. */
792 if (final)
793 sprintf (which_buf, "%c_%.5d_%d", which, priority, counter++);
794 else
795 /* Proudce sane name but one not recognizable by collect2, just for the
796 case we fail to inline the function. */
797 sprintf (which_buf, "sub_%c_%.5d_%d", which, priority, counter++);
798 name = get_file_function_name (which_buf);
800 decl = build_decl (input_location, FUNCTION_DECL, name,
801 build_function_type_list (void_type_node, NULL_TREE));
802 current_function_decl = decl;
804 resdecl = build_decl (input_location,
805 RESULT_DECL, NULL_TREE, void_type_node);
806 DECL_ARTIFICIAL (resdecl) = 1;
807 DECL_RESULT (decl) = resdecl;
808 DECL_CONTEXT (resdecl) = decl;
810 allocate_struct_function (decl, false);
812 TREE_STATIC (decl) = 1;
813 TREE_USED (decl) = 1;
814 DECL_ARTIFICIAL (decl) = 1;
815 DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;
816 DECL_SAVED_TREE (decl) = body;
817 if (!targetm.have_ctors_dtors && final)
819 TREE_PUBLIC (decl) = 1;
820 DECL_PRESERVE_P (decl) = 1;
822 DECL_UNINLINABLE (decl) = 1;
824 DECL_INITIAL (decl) = make_node (BLOCK);
825 TREE_USED (DECL_INITIAL (decl)) = 1;
827 DECL_SOURCE_LOCATION (decl) = input_location;
828 cfun->function_end_locus = input_location;
830 switch (which)
832 case 'I':
833 DECL_STATIC_CONSTRUCTOR (decl) = 1;
834 decl_init_priority_insert (decl, priority);
835 break;
836 case 'D':
837 DECL_STATIC_DESTRUCTOR (decl) = 1;
838 decl_fini_priority_insert (decl, priority);
839 break;
840 default:
841 gcc_unreachable ();
844 gimplify_function_tree (decl);
846 cgraph_add_new_function (decl, false);
848 set_cfun (NULL);
849 current_function_decl = NULL;
852 /* Generate and emit a static constructor or destructor. WHICH must
853 be one of 'I' (for a constructor) or 'D' (for a destructor). BODY
854 is a STATEMENT_LIST containing GENERIC statements. PRIORITY is the
855 initialization priority for this constructor or destructor. */
857 void
858 cgraph_build_static_cdtor (char which, tree body, int priority)
860 cgraph_build_static_cdtor_1 (which, body, priority, false);
863 /* A vector of FUNCTION_DECLs declared as static constructors. */
864 static vec<tree> static_ctors;
865 /* A vector of FUNCTION_DECLs declared as static destructors. */
866 static vec<tree> static_dtors;
868 /* When target does not have ctors and dtors, we call all constructor
869 and destructor by special initialization/destruction function
870 recognized by collect2.
872 When we are going to build this function, collect all constructors and
873 destructors and turn them into normal functions. */
875 static void
876 record_cdtor_fn (struct cgraph_node *node)
878 if (DECL_STATIC_CONSTRUCTOR (node->decl))
879 static_ctors.safe_push (node->decl);
880 if (DECL_STATIC_DESTRUCTOR (node->decl))
881 static_dtors.safe_push (node->decl);
882 node = cgraph_get_node (node->decl);
883 DECL_DISREGARD_INLINE_LIMITS (node->decl) = 1;
886 /* Define global constructors/destructor functions for the CDTORS, of
887 which they are LEN. The CDTORS are sorted by initialization
888 priority. If CTOR_P is true, these are constructors; otherwise,
889 they are destructors. */
891 static void
892 build_cdtor (bool ctor_p, vec<tree> cdtors)
894 size_t i,j;
895 size_t len = cdtors.length ();
897 i = 0;
898 while (i < len)
900 tree body;
901 tree fn;
902 priority_type priority;
904 priority = 0;
905 body = NULL_TREE;
906 j = i;
909 priority_type p;
910 fn = cdtors[j];
911 p = ctor_p ? DECL_INIT_PRIORITY (fn) : DECL_FINI_PRIORITY (fn);
912 if (j == i)
913 priority = p;
914 else if (p != priority)
915 break;
916 j++;
918 while (j < len);
920 /* When there is only one cdtor and target supports them, do nothing. */
921 if (j == i + 1
922 && targetm.have_ctors_dtors)
924 i++;
925 continue;
927 /* Find the next batch of constructors/destructors with the same
928 initialization priority. */
929 for (;i < j; i++)
931 tree call;
932 fn = cdtors[i];
933 call = build_call_expr (fn, 0);
934 if (ctor_p)
935 DECL_STATIC_CONSTRUCTOR (fn) = 0;
936 else
937 DECL_STATIC_DESTRUCTOR (fn) = 0;
938 /* We do not want to optimize away pure/const calls here.
939 When optimizing, these should be already removed, when not
940 optimizing, we want user to be able to breakpoint in them. */
941 TREE_SIDE_EFFECTS (call) = 1;
942 append_to_statement_list (call, &body);
944 gcc_assert (body != NULL_TREE);
945 /* Generate a function to call all the function of like
946 priority. */
947 cgraph_build_static_cdtor_1 (ctor_p ? 'I' : 'D', body, priority, true);
951 /* Comparison function for qsort. P1 and P2 are actually of type
952 "tree *" and point to static constructors. DECL_INIT_PRIORITY is
953 used to determine the sort order. */
955 static int
956 compare_ctor (const void *p1, const void *p2)
958 tree f1;
959 tree f2;
960 int priority1;
961 int priority2;
963 f1 = *(const tree *)p1;
964 f2 = *(const tree *)p2;
965 priority1 = DECL_INIT_PRIORITY (f1);
966 priority2 = DECL_INIT_PRIORITY (f2);
968 if (priority1 < priority2)
969 return -1;
970 else if (priority1 > priority2)
971 return 1;
972 else
973 /* Ensure a stable sort. Constructors are executed in backwarding
974 order to make LTO initialize braries first. */
975 return DECL_UID (f2) - DECL_UID (f1);
978 /* Comparison function for qsort. P1 and P2 are actually of type
979 "tree *" and point to static destructors. DECL_FINI_PRIORITY is
980 used to determine the sort order. */
982 static int
983 compare_dtor (const void *p1, const void *p2)
985 tree f1;
986 tree f2;
987 int priority1;
988 int priority2;
990 f1 = *(const tree *)p1;
991 f2 = *(const tree *)p2;
992 priority1 = DECL_FINI_PRIORITY (f1);
993 priority2 = DECL_FINI_PRIORITY (f2);
995 if (priority1 < priority2)
996 return -1;
997 else if (priority1 > priority2)
998 return 1;
999 else
1000 /* Ensure a stable sort. */
1001 return DECL_UID (f1) - DECL_UID (f2);
1004 /* Generate functions to call static constructors and destructors
1005 for targets that do not support .ctors/.dtors sections. These
1006 functions have magic names which are detected by collect2. */
1008 static void
1009 build_cdtor_fns (void)
1011 if (!static_ctors.is_empty ())
1013 gcc_assert (!targetm.have_ctors_dtors || in_lto_p);
1014 static_ctors.qsort (compare_ctor);
1015 build_cdtor (/*ctor_p=*/true, static_ctors);
1018 if (!static_dtors.is_empty ())
1020 gcc_assert (!targetm.have_ctors_dtors || in_lto_p);
1021 static_dtors.qsort (compare_dtor);
1022 build_cdtor (/*ctor_p=*/false, static_dtors);
1026 /* Look for constructors and destructors and produce function calling them.
1027 This is needed for targets not supporting ctors or dtors, but we perform the
1028 transformation also at linktime to merge possibly numerous
1029 constructors/destructors into single function to improve code locality and
1030 reduce size. */
1032 static unsigned int
1033 ipa_cdtor_merge (void)
1035 struct cgraph_node *node;
1036 FOR_EACH_DEFINED_FUNCTION (node)
1037 if (DECL_STATIC_CONSTRUCTOR (node->decl)
1038 || DECL_STATIC_DESTRUCTOR (node->decl))
1039 record_cdtor_fn (node);
1040 build_cdtor_fns ();
1041 static_ctors.release ();
1042 static_dtors.release ();
1043 return 0;
1046 namespace {
1048 const pass_data pass_data_ipa_cdtor_merge =
1050 IPA_PASS, /* type */
1051 "cdtor", /* name */
1052 OPTGROUP_NONE, /* optinfo_flags */
1053 true, /* has_execute */
1054 TV_CGRAPHOPT, /* tv_id */
1055 0, /* properties_required */
1056 0, /* properties_provided */
1057 0, /* properties_destroyed */
1058 0, /* todo_flags_start */
1059 0, /* todo_flags_finish */
1062 class pass_ipa_cdtor_merge : public ipa_opt_pass_d
1064 public:
1065 pass_ipa_cdtor_merge (gcc::context *ctxt)
1066 : ipa_opt_pass_d (pass_data_ipa_cdtor_merge, ctxt,
1067 NULL, /* generate_summary */
1068 NULL, /* write_summary */
1069 NULL, /* read_summary */
1070 NULL, /* write_optimization_summary */
1071 NULL, /* read_optimization_summary */
1072 NULL, /* stmt_fixup */
1073 0, /* function_transform_todo_flags_start */
1074 NULL, /* function_transform */
1075 NULL) /* variable_transform */
1078 /* opt_pass methods: */
1079 virtual bool gate (function *);
1080 virtual unsigned int execute (function *) { return ipa_cdtor_merge (); }
1082 }; // class pass_ipa_cdtor_merge
1084 bool
1085 pass_ipa_cdtor_merge::gate (function *)
1087 /* Perform the pass when we have no ctors/dtors support
1088 or at LTO time to merge multiple constructors into single
1089 function. */
1090 return !targetm.have_ctors_dtors || (optimize && in_lto_p);
1093 } // anon namespace
1095 ipa_opt_pass_d *
1096 make_pass_ipa_cdtor_merge (gcc::context *ctxt)
1098 return new pass_ipa_cdtor_merge (ctxt);
1101 /* Invalid pointer representing BOTTOM for single user dataflow. */
1102 #define BOTTOM ((cgraph_node *)(size_t) 2)
1104 /* Meet operation for single user dataflow.
1105 Here we want to associate variables with sigle function that may access it.
1107 FUNCTION is current single user of a variable, VAR is variable that uses it.
1108 Latttice is stored in SINGLE_USER_MAP.
1110 We represent:
1111 - TOP by no entry in SIGNLE_USER_MAP
1112 - BOTTOM by BOTTOM in AUX pointer (to save lookups)
1113 - known single user by cgraph pointer in SINGLE_USER_MAP. */
1115 cgraph_node *
1116 meet (cgraph_node *function, varpool_node *var,
1117 hash_map<varpool_node *, cgraph_node *> &single_user_map)
1119 struct cgraph_node *user, **f;
1121 if (var->aux == BOTTOM)
1122 return BOTTOM;
1124 f = single_user_map.get (var);
1125 if (!f)
1126 return function;
1127 user = *f;
1128 if (!function)
1129 return user;
1130 else if (function != user)
1131 return BOTTOM;
1132 else
1133 return function;
1136 /* Propagation step of single-use dataflow.
1138 Check all uses of VNODE and see if they are used by single function FUNCTION.
1139 SINGLE_USER_MAP represents the dataflow lattice. */
1141 cgraph_node *
1142 propagate_single_user (varpool_node *vnode, cgraph_node *function,
1143 hash_map<varpool_node *, cgraph_node *> &single_user_map)
1145 int i;
1146 struct ipa_ref *ref;
1148 gcc_assert (!vnode->externally_visible);
1150 /* If node is an alias, first meet with its target. */
1151 if (vnode->alias)
1152 function = meet (function, varpool_alias_target (vnode), single_user_map);
1154 /* Check all users and see if they correspond to a single function. */
1155 for (i = 0;
1156 ipa_ref_list_referring_iterate (&vnode->ref_list, i, ref)
1157 && function != BOTTOM; i++)
1159 struct cgraph_node *cnode = dyn_cast <cgraph_node *> (ref->referring);
1160 if (cnode)
1162 if (cnode->global.inlined_to)
1163 cnode = cnode->global.inlined_to;
1164 if (!function)
1165 function = cnode;
1166 else if (function != cnode)
1167 function = BOTTOM;
1169 else
1170 function = meet (function, dyn_cast <varpool_node *> (ref->referring), single_user_map);
1172 return function;
1175 /* Pass setting used_by_single_function flag.
1176 This flag is set on variable when there is only one function that may possibly
1177 referr to it. */
1179 static unsigned int
1180 ipa_single_use (void)
1182 varpool_node *first = (varpool_node *) (void *) 1;
1183 varpool_node *var;
1184 hash_map<varpool_node *, cgraph_node *> single_user_map;
1186 FOR_EACH_DEFINED_VARIABLE (var)
1187 if (!varpool_all_refs_explicit_p (var))
1188 var->aux = BOTTOM;
1189 else
1191 /* Enqueue symbol for dataflow. */
1192 var->aux = first;
1193 first = var;
1196 /* The actual dataflow. */
1198 while (first != (void *) 1)
1200 cgraph_node *user, *orig_user, **f;
1202 var = first;
1203 first = (varpool_node *)first->aux;
1205 f = single_user_map.get (var);
1206 if (f)
1207 orig_user = *f;
1208 else
1209 orig_user = NULL;
1210 user = propagate_single_user (var, orig_user, single_user_map);
1212 gcc_checking_assert (var->aux != BOTTOM);
1214 /* If user differs, enqueue all references. */
1215 if (user != orig_user)
1217 unsigned int i;
1218 ipa_ref *ref;
1220 single_user_map.put (var, user);
1222 /* Enqueue all aliases for re-processing. */
1223 for (i = 0;
1224 ipa_ref_list_referring_iterate (&var->ref_list, i, ref); i++)
1225 if (ref->use == IPA_REF_ALIAS
1226 && !ref->referring->aux)
1228 ref->referring->aux = first;
1229 first = dyn_cast <varpool_node *> (ref->referring);
1231 /* Enqueue all users for re-processing. */
1232 for (i = 0;
1233 ipa_ref_list_reference_iterate (&var->ref_list, i, ref); i++)
1234 if (!ref->referred->aux
1235 && ref->referred->definition
1236 && is_a <varpool_node *> (ref->referred))
1238 ref->referred->aux = first;
1239 first = dyn_cast <varpool_node *> (ref->referred);
1242 /* If user is BOTTOM, just punt on this var. */
1243 if (user == BOTTOM)
1244 var->aux = BOTTOM;
1245 else
1246 var->aux = NULL;
1248 else
1249 var->aux = NULL;
1252 FOR_EACH_DEFINED_VARIABLE (var)
1254 if (var->aux != BOTTOM)
1256 #ifdef ENABLE_CHECKING
1257 if (!single_user_map.get (var))
1258 gcc_assert (single_user_map.get (var));
1259 #endif
1260 if (dump_file)
1262 fprintf (dump_file, "Variable %s/%i is used by single function\n",
1263 var->name (), var->order);
1265 var->used_by_single_function = true;
1267 var->aux = NULL;
1269 return 0;
1272 namespace {
1274 const pass_data pass_data_ipa_single_use =
1276 IPA_PASS, /* type */
1277 "single-use", /* name */
1278 OPTGROUP_NONE, /* optinfo_flags */
1279 true, /* has_execute */
1280 TV_CGRAPHOPT, /* tv_id */
1281 0, /* properties_required */
1282 0, /* properties_provided */
1283 0, /* properties_destroyed */
1284 0, /* todo_flags_start */
1285 0, /* todo_flags_finish */
1288 class pass_ipa_single_use : public ipa_opt_pass_d
1290 public:
1291 pass_ipa_single_use (gcc::context *ctxt)
1292 : ipa_opt_pass_d (pass_data_ipa_single_use, ctxt,
1293 NULL, /* generate_summary */
1294 NULL, /* write_summary */
1295 NULL, /* read_summary */
1296 NULL, /* write_optimization_summary */
1297 NULL, /* read_optimization_summary */
1298 NULL, /* stmt_fixup */
1299 0, /* function_transform_todo_flags_start */
1300 NULL, /* function_transform */
1301 NULL) /* variable_transform */
1304 /* opt_pass methods: */
1305 virtual bool gate (function *);
1306 virtual unsigned int execute (function *) { return ipa_single_use (); }
1308 }; // class pass_ipa_single_use
1310 bool
1311 pass_ipa_single_use::gate (function *)
1313 return optimize;
1316 } // anon namespace
1318 ipa_opt_pass_d *
1319 make_pass_ipa_single_use (gcc::context *ctxt)
1321 return new pass_ipa_single_use (ctxt);