PR rtl-optimization/43520
[official-gcc.git] / gcc / ipa.c
blobd559ab2f285f6fd6421b243238439ba3e3552181
1 /* Basic IPA optimizations and utilities.
2 Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2010
3 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "cgraph.h"
26 #include "tree-pass.h"
27 #include "timevar.h"
28 #include "gimple.h"
29 #include "ggc.h"
31 /* Fill array order with all nodes with output flag set in the reverse
32 topological order. */
34 int
35 cgraph_postorder (struct cgraph_node **order)
37 struct cgraph_node *node, *node2;
38 int stack_size = 0;
39 int order_pos = 0;
40 struct cgraph_edge *edge, last;
41 int pass;
43 struct cgraph_node **stack =
44 XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
46 /* We have to deal with cycles nicely, so use a depth first traversal
47 output algorithm. Ignore the fact that some functions won't need
48 to be output and put them into order as well, so we get dependencies
49 right through inline functions. */
50 for (node = cgraph_nodes; node; node = node->next)
51 node->aux = NULL;
52 for (pass = 0; pass < 2; pass++)
53 for (node = cgraph_nodes; node; node = node->next)
54 if (!node->aux
55 && (pass
56 || (!cgraph_only_called_directly_p (node)
57 && !node->address_taken)))
59 node2 = node;
60 if (!node->callers)
61 node->aux = &last;
62 else
63 node->aux = node->callers;
64 while (node2)
66 while (node2->aux != &last)
68 edge = (struct cgraph_edge *) node2->aux;
69 if (edge->next_caller)
70 node2->aux = edge->next_caller;
71 else
72 node2->aux = &last;
73 /* Break possible cycles involving always-inline
74 functions by ignoring edges from always-inline
75 functions to non-always-inline functions. */
76 if (edge->caller->local.disregard_inline_limits
77 && !edge->callee->local.disregard_inline_limits)
78 continue;
79 if (!edge->caller->aux)
81 if (!edge->caller->callers)
82 edge->caller->aux = &last;
83 else
84 edge->caller->aux = edge->caller->callers;
85 stack[stack_size++] = node2;
86 node2 = edge->caller;
87 break;
90 if (node2->aux == &last)
92 order[order_pos++] = node2;
93 if (stack_size)
94 node2 = stack[--stack_size];
95 else
96 node2 = NULL;
100 free (stack);
101 for (node = cgraph_nodes; node; node = node->next)
102 node->aux = NULL;
103 return order_pos;
106 /* Look for all functions inlined to NODE and update their inlined_to pointers
107 to INLINED_TO. */
109 static void
110 update_inlined_to_pointer (struct cgraph_node *node, struct cgraph_node *inlined_to)
112 struct cgraph_edge *e;
113 for (e = node->callees; e; e = e->next_callee)
114 if (e->callee->global.inlined_to)
116 e->callee->global.inlined_to = inlined_to;
117 update_inlined_to_pointer (e->callee, inlined_to);
121 /* Perform reachability analysis and reclaim all unreachable nodes.
122 If BEFORE_INLINING_P is true this function is called before inlining
123 decisions has been made. If BEFORE_INLINING_P is false this function also
124 removes unneeded bodies of extern inline functions. */
126 bool
127 cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
129 struct cgraph_node *first = (struct cgraph_node *) (void *) 1;
130 struct cgraph_node *processed = (struct cgraph_node *) (void *) 2;
131 struct cgraph_node *node, *next;
132 bool changed = false;
134 #ifdef ENABLE_CHECKING
135 verify_cgraph ();
136 #endif
137 if (file)
138 fprintf (file, "\nReclaiming functions:");
139 #ifdef ENABLE_CHECKING
140 for (node = cgraph_nodes; node; node = node->next)
141 gcc_assert (!node->aux);
142 #endif
143 for (node = cgraph_nodes; node; node = node->next)
144 if (!cgraph_can_remove_if_no_direct_calls_p (node)
145 && ((!DECL_EXTERNAL (node->decl))
146 || !node->analyzed
147 || before_inlining_p))
149 gcc_assert (!node->global.inlined_to);
150 node->aux = first;
151 first = node;
152 node->reachable = true;
154 else
156 gcc_assert (!node->aux);
157 node->reachable = false;
160 /* Perform reachability analysis. As a special case do not consider
161 extern inline functions not inlined as live because we won't output
162 them at all. */
163 while (first != (void *) 1)
165 struct cgraph_edge *e;
166 node = first;
167 first = (struct cgraph_node *) first->aux;
168 node->aux = processed;
170 if (node->reachable)
171 for (e = node->callees; e; e = e->next_callee)
172 if (!e->callee->reachable
173 && node->analyzed
174 && (!e->inline_failed || !e->callee->analyzed
175 || (!DECL_EXTERNAL (e->callee->decl))
176 || before_inlining_p))
178 bool prev_reachable = e->callee->reachable;
179 e->callee->reachable |= node->reachable;
180 if (!e->callee->aux
181 || (e->callee->aux == processed
182 && prev_reachable != e->callee->reachable))
184 e->callee->aux = first;
185 first = e->callee;
189 /* If any function in a comdat group is reachable, force
190 all other functions in the same comdat group to be
191 also reachable. */
192 if (node->same_comdat_group
193 && node->reachable
194 && !node->global.inlined_to)
196 for (next = node->same_comdat_group;
197 next != node;
198 next = next->same_comdat_group)
199 if (!next->reachable)
201 next->aux = first;
202 first = next;
203 next->reachable = true;
207 /* We can freely remove inline clones even if they are cloned, however if
208 function is clone of real clone, we must keep it around in order to
209 make materialize_clones produce function body with the changes
210 applied. */
211 while (node->clone_of && !node->clone_of->aux && !gimple_has_body_p (node->decl))
213 bool noninline = node->clone_of->decl != node->decl;
214 node = node->clone_of;
215 if (noninline)
217 node->aux = first;
218 first = node;
219 break;
224 /* Remove unreachable nodes. Extern inline functions need special care;
225 Unreachable extern inline functions shall be removed.
226 Reachable extern inline functions we never inlined shall get their bodies
227 eliminated.
228 Reachable extern inline functions we sometimes inlined will be turned into
229 unanalyzed nodes so they look like for true extern functions to the rest
230 of code. Body of such functions is released via remove_node once the
231 inline clones are eliminated. */
232 for (node = cgraph_nodes; node; node = next)
234 next = node->next;
235 if (node->aux && !node->reachable)
237 cgraph_node_remove_callees (node);
238 node->analyzed = false;
239 node->local.inlinable = false;
241 if (!node->aux)
243 node->global.inlined_to = NULL;
244 if (file)
245 fprintf (file, " %s", cgraph_node_name (node));
246 if (!node->analyzed || !DECL_EXTERNAL (node->decl) || before_inlining_p)
247 cgraph_remove_node (node);
248 else
250 struct cgraph_edge *e;
252 /* See if there is reachable caller. */
253 for (e = node->callers; e; e = e->next_caller)
254 if (e->caller->aux)
255 break;
257 /* If so, we need to keep node in the callgraph. */
258 if (e || node->needed)
260 struct cgraph_node *clone;
262 /* If there are still clones, we must keep body around.
263 Otherwise we can just remove the body but keep the clone. */
264 for (clone = node->clones; clone;
265 clone = clone->next_sibling_clone)
266 if (clone->aux)
267 break;
268 if (!clone)
270 cgraph_release_function_body (node);
271 node->analyzed = false;
272 node->local.inlinable = false;
274 cgraph_node_remove_callees (node);
275 if (node->prev_sibling_clone)
276 node->prev_sibling_clone->next_sibling_clone = node->next_sibling_clone;
277 else if (node->clone_of)
278 node->clone_of->clones = node->next_sibling_clone;
279 if (node->next_sibling_clone)
280 node->next_sibling_clone->prev_sibling_clone = node->prev_sibling_clone;
281 node->clone_of = NULL;
282 node->next_sibling_clone = NULL;
283 node->prev_sibling_clone = NULL;
285 else
286 cgraph_remove_node (node);
288 changed = true;
291 for (node = cgraph_nodes; node; node = node->next)
293 /* Inline clones might be kept around so their materializing allows further
294 cloning. If the function the clone is inlined into is removed, we need
295 to turn it into normal cone. */
296 if (node->global.inlined_to
297 && !node->callers)
299 gcc_assert (node->clones);
300 node->global.inlined_to = NULL;
301 update_inlined_to_pointer (node, node);
303 node->aux = NULL;
305 #ifdef ENABLE_CHECKING
306 verify_cgraph ();
307 #endif
309 /* Reclaim alias pairs for functions that have disappeared from the
310 call graph. */
311 remove_unreachable_alias_pairs ();
313 return changed;
316 static bool
317 cgraph_externally_visible_p (struct cgraph_node *node, bool whole_program)
319 if (!node->local.finalized)
320 return false;
321 if (!DECL_COMDAT (node->decl)
322 && (!TREE_PUBLIC (node->decl) || DECL_EXTERNAL (node->decl)))
323 return false;
324 if (!whole_program)
325 return true;
326 if (DECL_PRESERVE_P (node->decl))
327 return true;
328 /* COMDAT functions must be shared only if they have address taken,
329 otherwise we can produce our own private implementation with
330 -fwhole-program. */
331 if (DECL_COMDAT (node->decl))
333 if (node->address_taken || !node->analyzed)
334 return true;
335 if (node->same_comdat_group)
337 struct cgraph_node *next;
339 /* If more than one function is in the same COMDAT group, it must
340 be shared even if just one function in the comdat group has
341 address taken. */
342 for (next = node->same_comdat_group;
343 next != node;
344 next = next->same_comdat_group)
345 if (next->address_taken || !next->analyzed)
346 return true;
349 if (MAIN_NAME_P (DECL_NAME (node->decl)))
350 return true;
351 if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (node->decl)))
352 return true;
353 return false;
356 /* Mark visibility of all functions.
358 A local function is one whose calls can occur only in the current
359 compilation unit and all its calls are explicit, so we can change
360 its calling convention. We simply mark all static functions whose
361 address is not taken as local.
363 We also change the TREE_PUBLIC flag of all declarations that are public
364 in language point of view but we want to overwrite this default
365 via visibilities for the backend point of view. */
367 static unsigned int
368 function_and_variable_visibility (bool whole_program)
370 struct cgraph_node *node;
371 struct varpool_node *vnode;
373 for (node = cgraph_nodes; node; node = node->next)
375 /* C++ FE on lack of COMDAT support create local COMDAT functions
376 (that ought to be shared but can not due to object format
377 limitations). It is neccesary to keep the flag to make rest of C++ FE
378 happy. Clear the flag here to avoid confusion in middle-end. */
379 if (DECL_COMDAT (node->decl) && !TREE_PUBLIC (node->decl))
380 DECL_COMDAT (node->decl) = 0;
381 /* For external decls stop tracking same_comdat_group, it doesn't matter
382 what comdat group they are in when they won't be emitted in this TU,
383 and simplifies later passes. */
384 if (node->same_comdat_group && DECL_EXTERNAL (node->decl))
386 struct cgraph_node *n = node, *next;
389 /* If at least one of same comdat group functions is external,
390 all of them have to be, otherwise it is a front-end bug. */
391 gcc_assert (DECL_EXTERNAL (n->decl));
392 next = n->same_comdat_group;
393 n->same_comdat_group = NULL;
394 n = next;
396 while (n != node);
398 gcc_assert ((!DECL_WEAK (node->decl) && !DECL_COMDAT (node->decl))
399 || TREE_PUBLIC (node->decl) || DECL_EXTERNAL (node->decl));
400 if (cgraph_externally_visible_p (node, whole_program))
402 gcc_assert (!node->global.inlined_to);
403 node->local.externally_visible = true;
405 else
406 node->local.externally_visible = false;
407 if (!node->local.externally_visible && node->analyzed
408 && !DECL_EXTERNAL (node->decl))
410 gcc_assert (whole_program || !TREE_PUBLIC (node->decl));
411 cgraph_make_decl_local (node->decl);
413 node->local.local = (cgraph_only_called_directly_p (node)
414 && node->analyzed
415 && !DECL_EXTERNAL (node->decl)
416 && !node->local.externally_visible);
418 for (vnode = varpool_nodes; vnode; vnode = vnode->next)
420 /* weak flag makes no sense on local variables. */
421 gcc_assert (!DECL_WEAK (vnode->decl)
422 || TREE_PUBLIC (vnode->decl) || DECL_EXTERNAL (vnode->decl));
423 /* In several cases declarations can not be common:
425 - when declaration has initializer
426 - when it is in weak
427 - when it has specific section
428 - when it resides in non-generic address space.
429 - if declaration is local, it will get into .local common section
430 so common flag is not needed. Frontends still produce these in
431 certain cases, such as for:
433 static int a __attribute__ ((common))
435 Canonicalize things here and clear the redundant flag. */
436 if (DECL_COMMON (vnode->decl)
437 && (!(TREE_PUBLIC (vnode->decl) || DECL_EXTERNAL (vnode->decl))
438 || (DECL_INITIAL (vnode->decl)
439 && DECL_INITIAL (vnode->decl) != error_mark_node)
440 || DECL_WEAK (vnode->decl)
441 || DECL_SECTION_NAME (vnode->decl) != NULL
442 || ! (ADDR_SPACE_GENERIC_P
443 (TYPE_ADDR_SPACE (TREE_TYPE (vnode->decl))))))
444 DECL_COMMON (vnode->decl) = 0;
446 for (vnode = varpool_nodes_queue; vnode; vnode = vnode->next_needed)
448 if (!vnode->finalized)
449 continue;
450 if (vnode->needed
451 && (DECL_COMDAT (vnode->decl) || TREE_PUBLIC (vnode->decl))
452 && (!whole_program
453 /* We can privatize comdat readonly variables whose address is not taken,
454 but doing so is not going to bring us optimization oppurtunities until
455 we start reordering datastructures. */
456 || DECL_COMDAT (vnode->decl)
457 || DECL_WEAK (vnode->decl)
458 || lookup_attribute ("externally_visible",
459 DECL_ATTRIBUTES (vnode->decl))))
460 vnode->externally_visible = true;
461 else
462 vnode->externally_visible = false;
463 if (!vnode->externally_visible)
465 gcc_assert (whole_program || !TREE_PUBLIC (vnode->decl));
466 cgraph_make_decl_local (vnode->decl);
468 gcc_assert (TREE_STATIC (vnode->decl));
471 if (dump_file)
473 fprintf (dump_file, "\nMarking local functions:");
474 for (node = cgraph_nodes; node; node = node->next)
475 if (node->local.local)
476 fprintf (dump_file, " %s", cgraph_node_name (node));
477 fprintf (dump_file, "\n\n");
478 fprintf (dump_file, "\nMarking externally visible functions:");
479 for (node = cgraph_nodes; node; node = node->next)
480 if (node->local.externally_visible)
481 fprintf (dump_file, " %s", cgraph_node_name (node));
482 fprintf (dump_file, "\n\n");
483 fprintf (dump_file, "\nMarking externally visible variables:");
484 for (vnode = varpool_nodes_queue; vnode; vnode = vnode->next_needed)
485 if (vnode->externally_visible)
486 fprintf (dump_file, " %s", varpool_node_name (vnode));
487 fprintf (dump_file, "\n\n");
489 cgraph_function_flags_ready = true;
490 return 0;
493 /* Local function pass handling visibilities. This happens before LTO streaming
494 so in particular -fwhole-program should be ignored at this level. */
496 static unsigned int
497 local_function_and_variable_visibility (void)
499 return function_and_variable_visibility (flag_whole_program && !flag_lto && !flag_whopr);
502 struct simple_ipa_opt_pass pass_ipa_function_and_variable_visibility =
505 SIMPLE_IPA_PASS,
506 "visibility", /* name */
507 NULL, /* gate */
508 local_function_and_variable_visibility,/* execute */
509 NULL, /* sub */
510 NULL, /* next */
511 0, /* static_pass_number */
512 TV_CGRAPHOPT, /* tv_id */
513 0, /* properties_required */
514 0, /* properties_provided */
515 0, /* properties_destroyed */
516 0, /* todo_flags_start */
517 TODO_remove_functions | TODO_dump_cgraph/* todo_flags_finish */
521 /* Do not re-run on ltrans stage. */
523 static bool
524 gate_whole_program_function_and_variable_visibility (void)
526 return !flag_ltrans;
529 /* Bring functionss local at LTO time whith -fwhole-program. */
531 static unsigned int
532 whole_program_function_and_variable_visibility (void)
534 struct cgraph_node *node;
535 struct varpool_node *vnode;
537 function_and_variable_visibility (flag_whole_program);
539 for (node = cgraph_nodes; node; node = node->next)
540 if ((node->local.externally_visible && !DECL_COMDAT (node->decl))
541 && node->local.finalized)
542 cgraph_mark_needed_node (node);
543 for (vnode = varpool_nodes_queue; vnode; vnode = vnode->next_needed)
544 if (vnode->externally_visible && !DECL_COMDAT (vnode->decl))
545 varpool_mark_needed_node (vnode);
546 if (dump_file)
548 fprintf (dump_file, "\nNeeded variables:");
549 for (vnode = varpool_nodes_queue; vnode; vnode = vnode->next_needed)
550 if (vnode->needed)
551 fprintf (dump_file, " %s", varpool_node_name (vnode));
552 fprintf (dump_file, "\n\n");
554 return 0;
557 struct ipa_opt_pass_d pass_ipa_whole_program_visibility =
560 IPA_PASS,
561 "whole-program", /* name */
562 gate_whole_program_function_and_variable_visibility,/* gate */
563 whole_program_function_and_variable_visibility,/* execute */
564 NULL, /* sub */
565 NULL, /* next */
566 0, /* static_pass_number */
567 TV_CGRAPHOPT, /* tv_id */
568 0, /* properties_required */
569 0, /* properties_provided */
570 0, /* properties_destroyed */
571 0, /* todo_flags_start */
572 TODO_dump_cgraph | TODO_remove_functions/* todo_flags_finish */
574 NULL, /* generate_summary */
575 NULL, /* write_summary */
576 NULL, /* read_summary */
577 NULL, /* function_read_summary */
578 NULL, /* stmt_fixup */
579 0, /* TODOs */
580 NULL, /* function_transform */
581 NULL, /* variable_transform */
584 /* Hash a cgraph node set element. */
586 static hashval_t
587 hash_cgraph_node_set_element (const void *p)
589 const_cgraph_node_set_element element = (const_cgraph_node_set_element) p;
590 return htab_hash_pointer (element->node);
593 /* Compare two cgraph node set elements. */
595 static int
596 eq_cgraph_node_set_element (const void *p1, const void *p2)
598 const_cgraph_node_set_element e1 = (const_cgraph_node_set_element) p1;
599 const_cgraph_node_set_element e2 = (const_cgraph_node_set_element) p2;
601 return e1->node == e2->node;
604 /* Create a new cgraph node set. */
606 cgraph_node_set
607 cgraph_node_set_new (void)
609 cgraph_node_set new_node_set;
611 new_node_set = GGC_NEW (struct cgraph_node_set_def);
612 new_node_set->hashtab = htab_create_ggc (10,
613 hash_cgraph_node_set_element,
614 eq_cgraph_node_set_element,
615 NULL);
616 new_node_set->nodes = NULL;
617 return new_node_set;
620 /* Add cgraph_node NODE to cgraph_node_set SET. */
622 void
623 cgraph_node_set_add (cgraph_node_set set, struct cgraph_node *node)
625 void **slot;
626 cgraph_node_set_element element;
627 struct cgraph_node_set_element_def dummy;
629 dummy.node = node;
630 slot = htab_find_slot (set->hashtab, &dummy, INSERT);
632 if (*slot != HTAB_EMPTY_ENTRY)
634 element = (cgraph_node_set_element) *slot;
635 gcc_assert (node == element->node
636 && (VEC_index (cgraph_node_ptr, set->nodes, element->index)
637 == node));
638 return;
641 /* Insert node into hash table. */
642 element =
643 (cgraph_node_set_element) GGC_NEW (struct cgraph_node_set_element_def);
644 element->node = node;
645 element->index = VEC_length (cgraph_node_ptr, set->nodes);
646 *slot = element;
648 /* Insert into node vector. */
649 VEC_safe_push (cgraph_node_ptr, gc, set->nodes, node);
652 /* Remove cgraph_node NODE from cgraph_node_set SET. */
654 void
655 cgraph_node_set_remove (cgraph_node_set set, struct cgraph_node *node)
657 void **slot, **last_slot;
658 cgraph_node_set_element element, last_element;
659 struct cgraph_node *last_node;
660 struct cgraph_node_set_element_def dummy;
662 dummy.node = node;
663 slot = htab_find_slot (set->hashtab, &dummy, NO_INSERT);
664 if (slot == NULL)
665 return;
667 element = (cgraph_node_set_element) *slot;
668 gcc_assert (VEC_index (cgraph_node_ptr, set->nodes, element->index)
669 == node);
671 /* Remove from vector. We do this by swapping node with the last element
672 of the vector. */
673 last_node = VEC_pop (cgraph_node_ptr, set->nodes);
674 if (last_node != node)
676 dummy.node = last_node;
677 last_slot = htab_find_slot (set->hashtab, &dummy, NO_INSERT);
678 last_element = (cgraph_node_set_element) *last_slot;
679 gcc_assert (last_element);
681 /* Move the last element to the original spot of NODE. */
682 last_element->index = element->index;
683 VEC_replace (cgraph_node_ptr, set->nodes, last_element->index,
684 last_node);
687 /* Remove element from hash table. */
688 htab_clear_slot (set->hashtab, slot);
689 ggc_free (element);
692 /* Find NODE in SET and return an iterator to it if found. A null iterator
693 is returned if NODE is not in SET. */
695 cgraph_node_set_iterator
696 cgraph_node_set_find (cgraph_node_set set, struct cgraph_node *node)
698 void **slot;
699 struct cgraph_node_set_element_def dummy;
700 cgraph_node_set_element element;
701 cgraph_node_set_iterator csi;
703 dummy.node = node;
704 slot = htab_find_slot (set->hashtab, &dummy, NO_INSERT);
705 if (slot == NULL)
706 csi.index = (unsigned) ~0;
707 else
709 element = (cgraph_node_set_element) *slot;
710 gcc_assert (VEC_index (cgraph_node_ptr, set->nodes, element->index)
711 == node);
712 csi.index = element->index;
714 csi.set = set;
716 return csi;
719 /* Dump content of SET to file F. */
721 void
722 dump_cgraph_node_set (FILE *f, cgraph_node_set set)
724 cgraph_node_set_iterator iter;
726 for (iter = csi_start (set); !csi_end_p (iter); csi_next (&iter))
728 struct cgraph_node *node = csi_node (iter);
729 dump_cgraph_node (f, node);
733 /* Dump content of SET to stderr. */
735 void
736 debug_cgraph_node_set (cgraph_node_set set)
738 dump_cgraph_node_set (stderr, set);