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