]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/ipa.c
tree.c (prototype_p, [...]): Constify.
[thirdparty/gcc.git] / gcc / ipa.c
CommitLineData
ca31b95f 1/* Basic IPA optimizations and utilities.
5624e564 2 Copyright (C) 2003-2015 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"
40e23961
MC
24#include "hash-set.h"
25#include "machmode.h"
26#include "vec.h"
27#include "double-int.h"
28#include "input.h"
29#include "alias.h"
30#include "symtab.h"
31#include "options.h"
32#include "wide-int.h"
33#include "inchash.h"
4d648807 34#include "tree.h"
40e23961 35#include "fold-const.h"
d8a2d370
DN
36#include "calls.h"
37#include "stringpool.h"
60393bbc
AM
38#include "predict.h"
39#include "basic-block.h"
1eb68d2d 40#include "hash-map.h"
c582198b
AM
41#include "is-a.h"
42#include "plugin-api.h"
c582198b
AM
43#include "hard-reg-set.h"
44#include "input.h"
45#include "function.h"
46#include "ipa-ref.h"
47#include "cgraph.h"
48#include "tree-pass.h"
2fb9a547 49#include "gimple-expr.h"
45b0be94 50#include "gimplify.h"
4a444e58 51#include "flags.h"
9e97ff61
JH
52#include "target.h"
53#include "tree-iterator.h"
af8bca3c 54#include "ipa-utils.h"
c582198b 55#include "alloc-pool.h"
dd912cb8 56#include "symbol-summary.h"
c582198b 57#include "ipa-prop.h"
04142cc3 58#include "ipa-inline.h"
0208f7da
JH
59#include "tree-inline.h"
60#include "profile.h"
61#include "params.h"
2b5f0895
XDL
62#include "internal-fn.h"
63#include "tree-ssa-alias.h"
64#include "gimple.h"
65#include "dbgcnt.h"
ca31b95f 66
e70670cf
JH
67
68/* Return true when NODE has ADDR reference. */
69
70static bool
71has_addr_references_p (struct cgraph_node *node,
72 void *data ATTRIBUTE_UNUSED)
73{
74 int i;
d122681a 75 struct ipa_ref *ref = NULL;
e70670cf 76
d122681a 77 for (i = 0; node->iterate_referring (i, ref); i++)
e70670cf
JH
78 if (ref->use == IPA_REF_ADDR)
79 return true;
80 return false;
81}
82
d563610d
JH
83/* Look for all functions inlined to NODE and update their inlined_to pointers
84 to INLINED_TO. */
85
86static void
87update_inlined_to_pointer (struct cgraph_node *node, struct cgraph_node *inlined_to)
88{
89 struct cgraph_edge *e;
90 for (e = node->callees; e; e = e->next_callee)
91 if (e->callee->global.inlined_to)
92 {
93 e->callee->global.inlined_to = inlined_to;
94 update_inlined_to_pointer (e->callee, inlined_to);
95 }
96}
97
04142cc3 98/* Add symtab NODE to queue starting at FIRST.
19fb0b86
JH
99
100 The queue is linked via AUX pointers and terminated by pointer to 1.
101 We enqueue nodes at two occasions: when we find them reachable or when we find
102 their bodies needed for further clonning. In the second case we mark them
103 by pointer to 2 after processing so they are re-queue when they become
104 reachable. */
b34fd25c
JH
105
106static void
5e20cdc9 107enqueue_node (symtab_node *node, symtab_node **first,
6e2830c3 108 hash_set<symtab_node *> *reachable)
b34fd25c 109{
19fb0b86 110 /* Node is still in queue; do nothing. */
67348ccc 111 if (node->aux && node->aux != (void *) 2)
19fb0b86
JH
112 return;
113 /* Node was already processed as unreachable, re-enqueue
114 only if it became reachable now. */
6e2830c3 115 if (node->aux == (void *)2 && !reachable->contains (node))
19fb0b86 116 return;
67348ccc 117 node->aux = *first;
b34fd25c
JH
118 *first = node;
119}
120
b34fd25c
JH
121/* Process references. */
122
123static void
d122681a 124process_references (symtab_node *snode,
5e20cdc9 125 symtab_node **first,
93a18a70 126 bool before_inlining_p,
6e2830c3 127 hash_set<symtab_node *> *reachable)
b34fd25c
JH
128{
129 int i;
d122681a
ML
130 struct ipa_ref *ref = NULL;
131 for (i = 0; snode->iterate_reference (i, ref); i++)
b34fd25c 132 {
5e20cdc9 133 symtab_node *node = ref->referred;
17e0fc92 134 symtab_node *body = node->ultimate_alias_target ();
e70670cf 135
67348ccc
DM
136 if (node->definition && !node->in_other_partition
137 && ((!DECL_EXTERNAL (node->decl) || node->alias)
8fe91ca8 138 || (((before_inlining_p
f1ced6f5
JH
139 && ((TREE_CODE (node->decl) != FUNCTION_DECL
140 && optimize)
141 || (TREE_CODE (node->decl) == FUNCTION_DECL
142 && opt_for_fn (body->decl, optimize))
17e0fc92
JH
143 || (symtab->state < IPA_SSA
144 && lookup_attribute
145 ("always_inline",
146 DECL_ATTRIBUTES (body->decl))))))
147 /* We use variable constructors during late compilation for
e70670cf
JH
148 constant folding. Keep references alive so partitioning
149 knows about potential references. */
67348ccc 150 || (TREE_CODE (node->decl) == VAR_DECL
6a6dac52 151 && flag_wpa
67348ccc 152 && ctor_for_folding (node->decl)
6a6dac52 153 != error_mark_node))))
17e0fc92
JH
154 {
155 /* Be sure that we will not optimize out alias target
156 body. */
157 if (DECL_EXTERNAL (node->decl)
158 && node->alias
159 && before_inlining_p)
160 reachable->add (body);
161 reachable->add (node);
162 }
67348ccc 163 enqueue_node (node, first, reachable);
b34fd25c
JH
164 }
165}
166
3462aa02
JH
167/* EDGE is an polymorphic call. If BEFORE_INLINING_P is set, mark
168 all its potential targets as reachable to permit later inlining if
169 devirtualization happens. After inlining still keep their declarations
170 around, so we can devirtualize to a direct call.
171
172 Also try to make trivial devirutalization when no or only one target is
173 possible. */
174
175static void
6e2830c3 176walk_polymorphic_call_targets (hash_set<void *> *reachable_call_targets,
3462aa02 177 struct cgraph_edge *edge,
5e20cdc9 178 symtab_node **first,
6e2830c3
TS
179 hash_set<symtab_node *> *reachable,
180 bool before_inlining_p)
3462aa02
JH
181{
182 unsigned int i;
183 void *cache_token;
184 bool final;
185 vec <cgraph_node *>targets
186 = possible_polymorphic_call_targets
187 (edge, &final, &cache_token);
188
6e2830c3 189 if (!reachable_call_targets->add (cache_token))
3462aa02 190 {
c3284718 191 for (i = 0; i < targets.length (); i++)
3462aa02
JH
192 {
193 struct cgraph_node *n = targets[i];
194
195 /* Do not bother to mark virtual methods in anonymous namespace;
196 either we will find use of virtual table defining it, or it is
197 unused. */
67348ccc 198 if (TREE_CODE (TREE_TYPE (n->decl)) == METHOD_TYPE
3462aa02 199 && type_in_anonymous_namespace_p
67348ccc 200 (method_class_type (TREE_TYPE (n->decl))))
3462aa02
JH
201 continue;
202
17e0fc92
JH
203 symtab_node *body = n->function_symbol ();
204
3462aa02
JH
205 /* Prior inlining, keep alive bodies of possible targets for
206 devirtualization. */
67348ccc 207 if (n->definition
8fe91ca8 208 && (before_inlining_p
17e0fc92
JH
209 && opt_for_fn (body->decl, optimize)
210 && opt_for_fn (body->decl, flag_devirtualize)))
211 {
212 /* Be sure that we will not optimize out alias target
213 body. */
214 if (DECL_EXTERNAL (n->decl)
215 && n->alias
216 && before_inlining_p)
217 reachable->add (body);
218 reachable->add (n);
219 }
3462aa02
JH
220 /* Even after inlining we want to keep the possible targets in the
221 boundary, so late passes can still produce direct call even if
222 the chance for inlining is lost. */
67348ccc 223 enqueue_node (n, first, reachable);
3462aa02
JH
224 }
225 }
226
227 /* Very trivial devirtualization; when the type is
228 final or anonymous (so we know all its derivation)
229 and there is only one possible virtual call target,
230 make the edge direct. */
231 if (final)
232 {
2b5f0895 233 if (targets.length () <= 1 && dbg_cnt (devirt))
3462aa02 234 {
7b395ddd 235 cgraph_node *target, *node = edge->caller;
3462aa02
JH
236 if (targets.length () == 1)
237 target = targets[0];
238 else
d52f5295 239 target = cgraph_node::get_create
3462aa02
JH
240 (builtin_decl_implicit (BUILT_IN_UNREACHABLE));
241
2b5f0895
XDL
242 if (dump_enabled_p ())
243 {
9189aff7
JH
244 location_t locus;
245 if (edge->call_stmt)
246 locus = gimple_location (edge->call_stmt);
247 else
248 locus = UNKNOWN_LOCATION;
d52f5295 249 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, locus,
2b5f0895
XDL
250 "devirtualizing call in %s/%i to %s/%i\n",
251 edge->caller->name (), edge->caller->order,
252 target->name (),
253 target->order);
254 }
3dafb85c 255 edge = edge->make_direct (target);
9a1e784a 256 if (inline_summaries)
7b395ddd 257 inline_update_overall_summary (node);
477145c8 258 else if (edge->call_stmt)
d5e254e1
IE
259 {
260 edge->redirect_call_stmt_to_callee ();
261
262 /* Call to __builtin_unreachable shouldn't be instrumented. */
263 if (!targets.length ())
264 gimple_call_set_with_bounds (edge->call_stmt, false);
265 }
3462aa02
JH
266 }
267 }
268}
41817394 269
ca31b95f 270/* Perform reachability analysis and reclaim all unreachable nodes.
04142cc3
JH
271
272 The algorithm is basically mark&sweep but with some extra refinements:
273
274 - reachable extern inline functions needs special handling; the bodies needs
275 to stay in memory until inlining in hope that they will be inlined.
276 After inlining we release their bodies and turn them into unanalyzed
277 nodes even when they are reachable.
278
04142cc3
JH
279 - virtual functions are kept in callgraph even if they seem unreachable in
280 hope calls to them will be devirtualized.
281
282 Again we remove them after inlining. In late optimization some
31519c38 283 devirtualization may happen, but it is not important since we won't inline
04142cc3
JH
284 the call. In theory early opts and IPA should work out all important cases.
285
286 - virtual clones needs bodies of their origins for later materialization;
287 this means that we want to keep the body even if the origin is unreachable
288 otherwise. To avoid origin from sitting in the callgraph and being
289 walked by IPA passes, we turn them into unanalyzed nodes with body
290 defined.
291
292 We maintain set of function declaration where body needs to stay in
293 body_needed_for_clonning
294
295 Inline clones represent special case: their declaration match the
296 declaration of origin and cgraph_remove_node already knows how to
297 reshape callgraph and preserve body when offline copy of function or
298 inline clone is being removed.
299
6649df51
JH
300 - C++ virtual tables keyed to other unit are represented as DECL_EXTERNAL
301 variables with DECL_INITIAL set. We finalize these and keep reachable
302 ones around for constant folding purposes. After inlining we however
303 stop walking their references to let everything static referneced by them
304 to be removed when it is otherwise unreachable.
305
04142cc3
JH
306 We maintain queue of both reachable symbols (i.e. defined symbols that needs
307 to stay) and symbols that are in boundary (i.e. external symbols referenced
308 by reachable symbols or origins of clones). The queue is represented
309 as linked list by AUX pointer terminated by 1.
310
31519c38 311 At the end we keep all reachable symbols. For symbols in boundary we always
04142cc3
JH
312 turn definition into a declaration, but we may keep function body around
313 based on body_needed_for_clonning
314
315 All symbols that enter the queue have AUX pointer non-zero and are in the
316 boundary. Pointer set REACHABLE is used to track reachable symbols.
317
318 Every symbol can be visited twice - once as part of boundary and once
319 as real reachable symbol. enqueue_node needs to decide whether the
320 node needs to be re-queued for second processing. For this purpose
321 we set AUX pointer of processed symbols in the boundary to constant 2. */
ca31b95f
JH
322
323bool
17e0fc92 324symbol_table::remove_unreachable_nodes (FILE *file)
ca31b95f 325{
5e20cdc9 326 symtab_node *first = (symtab_node *) (void *) 1;
96fc428c 327 struct cgraph_node *node, *next;
2c8326a5 328 varpool_node *vnode, *vnext;
ca31b95f 329 bool changed = false;
6e2830c3
TS
330 hash_set<symtab_node *> reachable;
331 hash_set<tree> body_needed_for_clonning;
332 hash_set<void *> reachable_call_targets;
17e0fc92
JH
333 bool before_inlining_p = symtab->state < (!optimize ? IPA_SSA
334 : IPA_SSA_AFTER_INLINING);
ca31b95f 335
3462aa02 336 timevar_push (TV_IPA_UNREACHABLE);
2bf86c84 337 build_type_inheritance_graph ();
10d22567
ZD
338 if (file)
339 fprintf (file, "\nReclaiming functions:");
ca31b95f 340#ifdef ENABLE_CHECKING
65c70e6b 341 FOR_EACH_FUNCTION (node)
67348ccc 342 gcc_assert (!node->aux);
65c70e6b 343 FOR_EACH_VARIABLE (vnode)
67348ccc 344 gcc_assert (!vnode->aux);
ca31b95f 345#endif
530f3a1b
JH
346 /* Mark functions whose bodies are obviously needed.
347 This is mostly when they can be referenced externally. Inline clones
348 are special since their declarations are shared with master clone and thus
349 cgraph_can_remove_if_no_direct_calls_and_refs_p should not be called on them. */
c0c123ef
JH
350 FOR_EACH_FUNCTION (node)
351 {
352 node->used_as_abstract_origin = false;
67348ccc 353 if (node->definition
c0c123ef 354 && !node->global.inlined_to
67348ccc 355 && !node->in_other_partition
d52f5295 356 && !node->can_remove_if_no_direct_calls_and_refs_p ())
c0c123ef
JH
357 {
358 gcc_assert (!node->global.inlined_to);
6e2830c3
TS
359 reachable.add (node);
360 enqueue_node (node, &first, &reachable);
c0c123ef
JH
361 }
362 else
67348ccc 363 gcc_assert (!node->aux);
c0c123ef 364 }
530f3a1b
JH
365
366 /* Mark variables that are obviously needed. */
04142cc3 367 FOR_EACH_DEFINED_VARIABLE (vnode)
9041d2e6 368 if (!vnode->can_remove_if_no_refs_p()
67348ccc 369 && !vnode->in_other_partition)
04142cc3 370 {
6e2830c3
TS
371 reachable.add (vnode);
372 enqueue_node (vnode, &first, &reachable);
04142cc3
JH
373 }
374
375 /* Perform reachability analysis. */
5e20cdc9 376 while (first != (symtab_node *) (void *) 1)
b34fd25c 377 {
6e2830c3 378 bool in_boundary_p = !reachable.contains (first);
5e20cdc9 379 symtab_node *node = first;
ca31b95f 380
5e20cdc9 381 first = (symtab_node *)first->aux;
19fb0b86 382
04142cc3
JH
383 /* If we are processing symbol in boundary, mark its AUX pointer for
384 possible later re-processing in enqueue_node. */
385 if (in_boundary_p)
4bd019b8
JH
386 {
387 node->aux = (void *)2;
388 if (node->alias && node->analyzed)
389 enqueue_node (node->get_alias_target (), &first, &reachable);
390 }
04142cc3
JH
391 else
392 {
31dad809
JJ
393 if (TREE_CODE (node->decl) == FUNCTION_DECL
394 && DECL_ABSTRACT_ORIGIN (node->decl))
c0c123ef
JH
395 {
396 struct cgraph_node *origin_node
4ad08ee8
JH
397 = cgraph_node::get (DECL_ABSTRACT_ORIGIN (node->decl));
398 if (origin_node && !origin_node->used_as_abstract_origin)
399 {
400 origin_node->used_as_abstract_origin = true;
401 gcc_assert (!origin_node->prev_sibling_clone);
402 gcc_assert (!origin_node->next_sibling_clone);
403 for (cgraph_node *n = origin_node->clones; n;
404 n = n->next_sibling_clone)
405 if (n->decl == DECL_ABSTRACT_ORIGIN (node->decl))
406 n->used_as_abstract_origin = true;
4ad08ee8 407 }
c0c123ef 408 }
04142cc3 409 /* If any symbol in a comdat group is reachable, force
1f26ac87
JM
410 all externally visible symbols in the same comdat
411 group to be reachable as well. Comdat-local symbols
412 can be discarded if all uses were inlined. */
67348ccc 413 if (node->same_comdat_group)
04142cc3 414 {
5e20cdc9 415 symtab_node *next;
67348ccc 416 for (next = node->same_comdat_group;
04142cc3 417 next != node;
67348ccc 418 next = next->same_comdat_group)
d52f5295 419 if (!next->comdat_local_p ()
6e2830c3
TS
420 && !reachable.add (next))
421 enqueue_node (next, &first, &reachable);
04142cc3
JH
422 }
423 /* Mark references as reachable. */
6e2830c3 424 process_references (node, &first, before_inlining_p, &reachable);
04142cc3 425 }
19fb0b86 426
7de90a6c 427 if (cgraph_node *cnode = dyn_cast <cgraph_node *> (node))
b34fd25c 428 {
04142cc3
JH
429 /* Mark the callees reachable unless they are direct calls to extern
430 inline functions we decided to not inline. */
431 if (!in_boundary_p)
8a6295ba 432 {
04142cc3 433 struct cgraph_edge *e;
3462aa02 434 /* Keep alive possible targets for devirtualization. */
2bf86c84
JH
435 if (opt_for_fn (cnode->decl, optimize)
436 && opt_for_fn (cnode->decl, flag_devirtualize))
3462aa02
JH
437 {
438 struct cgraph_edge *next;
439 for (e = cnode->indirect_calls; e; e = next)
440 {
441 next = e->next_callee;
442 if (e->indirect_info->polymorphic)
6e2830c3
TS
443 walk_polymorphic_call_targets (&reachable_call_targets,
444 e, &first, &reachable,
3462aa02
JH
445 before_inlining_p);
446 }
447 }
04142cc3 448 for (e = cnode->callees; e; e = e->next_callee)
ed62e0d9 449 {
17e0fc92 450 symtab_node *body = e->callee->function_symbol ();
67348ccc
DM
451 if (e->callee->definition
452 && !e->callee->in_other_partition
ed62e0d9 453 && (!e->inline_failed
67348ccc
DM
454 || !DECL_EXTERNAL (e->callee->decl)
455 || e->callee->alias
17e0fc92
JH
456 || (before_inlining_p
457 && (opt_for_fn (body->decl, optimize)
458 || (symtab->state < IPA_SSA
459 && lookup_attribute
460 ("always_inline",
461 DECL_ATTRIBUTES (body->decl)))))))
789c2741
JH
462 {
463 /* Be sure that we will not optimize out alias target
464 body. */
465 if (DECL_EXTERNAL (e->callee->decl)
466 && e->callee->alias
467 && before_inlining_p)
17e0fc92 468 reachable.add (body);
6e2830c3 469 reachable.add (e->callee);
789c2741 470 }
6e2830c3 471 enqueue_node (e->callee, &first, &reachable);
93a18a70 472 }
04142cc3
JH
473
474 /* When inline clone exists, mark body to be preserved so when removing
475 offline copy of the function we don't kill it. */
4f63dfc6 476 if (cnode->global.inlined_to)
6e2830c3 477 body_needed_for_clonning.add (cnode->decl);
b66887e4 478
4f63dfc6
JH
479 /* For non-inline clones, force their origins to the boundary and ensure
480 that body is not removed. */
481 while (cnode->clone_of)
482 {
67348ccc 483 bool noninline = cnode->clone_of->decl != cnode->decl;
4f63dfc6
JH
484 cnode = cnode->clone_of;
485 if (noninline)
486 {
6e2830c3
TS
487 body_needed_for_clonning.add (cnode->decl);
488 enqueue_node (cnode, &first, &reachable);
4f63dfc6 489 }
b34fd25c 490 }
0136f8f0
AH
491
492 }
4bd019b8
JH
493 else if (cnode->thunk.thunk_p)
494 enqueue_node (cnode->callees->callee, &first, &reachable);
495
0136f8f0
AH
496 /* If any reachable function has simd clones, mark them as
497 reachable as well. */
498 if (cnode->simd_clones)
499 {
500 cgraph_node *next;
501 for (next = cnode->simd_clones;
502 next;
503 next = next->simdclone->next_clone)
504 if (in_boundary_p
6e2830c3
TS
505 || !reachable.add (next))
506 enqueue_node (next, &first, &reachable);
47cb0d7d 507 }
b34fd25c 508 }
6649df51 509 /* When we see constructor of external variable, keep referred nodes in the
5d59b5e1
LC
510 boundary. This will also hold initializers of the external vars NODE
511 refers to. */
7de90a6c 512 varpool_node *vnode = dyn_cast <varpool_node *> (node);
5d59b5e1 513 if (vnode
67348ccc
DM
514 && DECL_EXTERNAL (node->decl)
515 && !vnode->alias
6649df51 516 && in_boundary_p)
5d59b5e1 517 {
d122681a
ML
518 struct ipa_ref *ref = NULL;
519 for (int i = 0; node->iterate_reference (i, ref); i++)
6e2830c3 520 enqueue_node (ref->referred, &first, &reachable);
5d59b5e1 521 }
ca31b95f
JH
522 }
523
04142cc3 524 /* Remove unreachable functions. */
3dafb85c 525 for (node = first_function (); node; node = next)
ca31b95f 526 {
3dafb85c 527 next = next_function (node);
e70670cf
JH
528
529 /* If node is not needed at all, remove it. */
67348ccc 530 if (!node->aux)
ca31b95f 531 {
10d22567 532 if (file)
5bed50e8 533 fprintf (file, " %s/%i", node->name (), node->order);
d52f5295 534 node->remove ();
04142cc3
JH
535 changed = true;
536 }
e70670cf 537 /* If node is unreachable, remove its body. */
6e2830c3 538 else if (!reachable.contains (node))
04142cc3 539 {
d3f2e41e
JH
540 /* We keep definitions of thunks and aliases in the boundary so
541 we can walk to the ultimate alias targets and function symbols
542 reliably. */
543 if (node->alias || node->thunk.thunk_p)
544 ;
545 else if (!body_needed_for_clonning.contains (node->decl)
546 && !node->alias && !node->thunk.thunk_p)
d52f5295 547 node->release_body ();
4f63dfc6 548 else if (!node->clone_of)
67348ccc 549 gcc_assert (in_lto_p || DECL_RESULT (node->decl));
4bd019b8 550 if (node->definition && !node->alias && !node->thunk.thunk_p)
bb853349 551 {
04142cc3 552 if (file)
5bed50e8 553 fprintf (file, " %s/%i", node->name (), node->order);
3d8d0043 554 node->body_removed = true;
67348ccc
DM
555 node->analyzed = false;
556 node->definition = false;
557 node->cpp_implicit_alias = false;
558 node->alias = false;
d833415c 559 node->thunk.thunk_p = false;
67348ccc 560 node->weakref = false;
8fe91ca8
JH
561 /* After early inlining we drop always_inline attributes on
562 bodies of functions that are still referenced (have their
563 address taken). */
564 DECL_ATTRIBUTES (node->decl)
565 = remove_attribute ("always_inline",
566 DECL_ATTRIBUTES (node->decl));
67348ccc 567 if (!node->in_other_partition)
51a5c0c2 568 node->local.local = false;
d52f5295 569 node->remove_callees ();
d122681a 570 node->remove_all_references ();
bb853349 571 changed = true;
d5e254e1
IE
572 if (node->thunk.thunk_p
573 && node->thunk.add_pointer_bounds_args)
574 {
575 node->thunk.thunk_p = false;
576 node->thunk.add_pointer_bounds_args = false;
577 }
bb853349 578 }
ca31b95f 579 }
4f63dfc6 580 else
d52f5295 581 gcc_assert (node->clone_of || !node->has_gimple_body_p ()
67348ccc 582 || in_lto_p || DECL_RESULT (node->decl));
ca31b95f 583 }
04142cc3
JH
584
585 /* Inline clones might be kept around so their materializing allows further
586 cloning. If the function the clone is inlined into is removed, we need
587 to turn it into normal cone. */
65c70e6b 588 FOR_EACH_FUNCTION (node)
9187e02d 589 {
9187e02d
JH
590 if (node->global.inlined_to
591 && !node->callers)
592 {
593 gcc_assert (node->clones);
d563610d
JH
594 node->global.inlined_to = NULL;
595 update_inlined_to_pointer (node, node);
9187e02d 596 }
67348ccc 597 node->aux = NULL;
9187e02d 598 }
4a444e58 599
04142cc3 600 /* Remove unreachable variables. */
4a444e58 601 if (file)
04142cc3 602 fprintf (file, "\nReclaiming variables:");
3dafb85c 603 for (vnode = first_variable (); vnode; vnode = vnext)
b34fd25c 604 {
3dafb85c 605 vnext = next_variable (vnode);
67348ccc 606 if (!vnode->aux
b9bd2075
JH
607 /* For can_refer_decl_in_current_unit_p we want to track for
608 all external variables if they are defined in other partition
609 or not. */
67348ccc 610 && (!flag_ltrans || !DECL_EXTERNAL (vnode->decl)))
04142cc3 611 {
d2b35c04
JH
612 struct ipa_ref *ref = NULL;
613
614 /* First remove the aliases, so varpool::remove can possibly lookup
615 the constructor and save it for future use. */
616 while (vnode->iterate_direct_aliases (0, ref))
617 {
618 if (file)
619 fprintf (file, " %s/%i", ref->referred->name (),
620 ref->referred->order);
621 ref->referring->remove ();
622 }
4a444e58 623 if (file)
5bed50e8 624 fprintf (file, " %s/%i", vnode->name (), vnode->order);
d2b35c04 625 vnext = next_variable (vnode);
d52f5295 626 vnode->remove ();
4a444e58 627 changed = true;
b34fd25c 628 }
4bd019b8 629 else if (!reachable.contains (vnode) && !vnode->alias)
04142cc3 630 {
6a6dac52 631 tree init;
67348ccc 632 if (vnode->definition)
04142cc3
JH
633 {
634 if (file)
fec39fa6 635 fprintf (file, " %s", vnode->name ());
04142cc3
JH
636 changed = true;
637 }
1acc5591 638 /* Keep body if it may be useful for constant folding. */
d5e254e1
IE
639 if ((init = ctor_for_folding (vnode->decl)) == error_mark_node
640 && !POINTER_BOUNDS_P (vnode->decl))
1acc5591
JH
641 vnode->remove_initializer ();
642 else
643 DECL_INITIAL (vnode->decl) = init;
3d8d0043 644 vnode->body_removed = true;
67348ccc
DM
645 vnode->definition = false;
646 vnode->analyzed = false;
647 vnode->aux = NULL;
e70670cf 648
d52f5295 649 vnode->remove_from_same_comdat_group ();
7b3376a0 650
d122681a 651 vnode->remove_all_references ();
04142cc3
JH
652 }
653 else
67348ccc 654 vnode->aux = NULL;
b34fd25c 655 }
4a444e58 656
04142cc3 657 /* Now update address_taken flags and try to promote functions to be local. */
bd3cdcc0
JH
658 if (file)
659 fprintf (file, "\nClearing address taken flags:");
65c70e6b 660 FOR_EACH_DEFINED_FUNCTION (node)
67348ccc
DM
661 if (node->address_taken
662 && !node->used_from_other_partition)
bd3cdcc0 663 {
1ede94c5 664 if (!node->call_for_symbol_and_aliases
d5e254e1
IE
665 (has_addr_references_p, NULL, true)
666 && (!node->instrumentation_clone
667 || !node->instrumented_version
668 || !node->instrumented_version->address_taken))
bd3cdcc0
JH
669 {
670 if (file)
fec39fa6 671 fprintf (file, " %s", node->name ());
67348ccc 672 node->address_taken = false;
4a444e58 673 changed = true;
d52f5295 674 if (node->local_p ())
4a444e58
JH
675 {
676 node->local.local = true;
677 if (file)
678 fprintf (file, " (local)");
679 }
bd3cdcc0
JH
680 }
681 }
10a5dd5d
JH
682 if (file)
683 fprintf (file, "\n");
b34fd25c 684
873aa8f5 685#ifdef ENABLE_CHECKING
d52f5295 686 symtab_node::verify_symtab_nodes ();
873aa8f5 687#endif
4537ec0c 688
a8da72b8 689 /* If we removed something, perhaps profile could be improved. */
9771b263 690 if (changed && optimize && inline_edge_summary_vec.exists ())
a8da72b8 691 FOR_EACH_DEFINED_FUNCTION (node)
08f835dc 692 ipa_propagate_frequency (node);
a8da72b8 693
3462aa02 694 timevar_pop (TV_IPA_UNREACHABLE);
ca31b95f
JH
695 return changed;
696}
f4b3ca72 697
6de88c6a
JH
698/* Process references to VNODE and set flags WRITTEN, ADDRESS_TAKEN, READ
699 as needed, also clear EXPLICIT_REFS if the references to given variable
700 do not need to be explicit. */
701
702void
703process_references (varpool_node *vnode,
704 bool *written, bool *address_taken,
705 bool *read, bool *explicit_refs)
706{
707 int i;
708 struct ipa_ref *ref;
709
9041d2e6 710 if (!vnode->all_refs_explicit_p ()
6de88c6a
JH
711 || TREE_THIS_VOLATILE (vnode->decl))
712 *explicit_refs = false;
713
d122681a 714 for (i = 0; vnode->iterate_referring (i, ref)
6de88c6a
JH
715 && *explicit_refs && (!*written || !*address_taken || !*read); i++)
716 switch (ref->use)
717 {
718 case IPA_REF_ADDR:
719 *address_taken = true;
720 break;
721 case IPA_REF_LOAD:
722 *read = true;
723 break;
724 case IPA_REF_STORE:
725 *written = true;
726 break;
727 case IPA_REF_ALIAS:
d52f5295
ML
728 process_references (dyn_cast<varpool_node *> (ref->referring), written,
729 address_taken, read, explicit_refs);
6de88c6a 730 break;
d5e254e1
IE
731 case IPA_REF_CHKP:
732 gcc_unreachable ();
6de88c6a
JH
733 }
734}
735
736/* Set TREE_READONLY bit. */
737
738bool
739set_readonly_bit (varpool_node *vnode, void *data ATTRIBUTE_UNUSED)
740{
741 TREE_READONLY (vnode->decl) = true;
742 return false;
743}
744
745/* Set writeonly bit and clear the initalizer, since it will not be needed. */
746
747bool
dea91a66 748set_writeonly_bit (varpool_node *vnode, void *data)
6de88c6a
JH
749{
750 vnode->writeonly = true;
751 if (optimize)
752 {
753 DECL_INITIAL (vnode->decl) = NULL;
754 if (!vnode->alias)
dea91a66
JH
755 {
756 if (vnode->num_references ())
757 *(bool *)data = true;
758 vnode->remove_all_references ();
759 }
6de88c6a
JH
760 }
761 return false;
762}
763
764/* Clear addressale bit of VNODE. */
765
766bool
767clear_addressable_bit (varpool_node *vnode, void *data ATTRIBUTE_UNUSED)
768{
769 vnode->address_taken = false;
770 TREE_ADDRESSABLE (vnode->decl) = 0;
771 return false;
772}
773
4a444e58
JH
774/* Discover variables that have no longer address taken or that are read only
775 and update their flags.
776
dea91a66
JH
777 Return true when unreachable symbol removan should be done.
778
4a444e58
JH
779 FIXME: This can not be done in between gimplify and omp_expand since
780 readonly flag plays role on what is shared and what is not. Currently we do
f10ea640
JH
781 this transformation as part of whole program visibility and re-do at
782 ipa-reference pass (to take into account clonning), but it would
783 make sense to do it before early optimizations. */
4a444e58 784
dea91a66 785bool
4a444e58
JH
786ipa_discover_readonly_nonaddressable_vars (void)
787{
dea91a66 788 bool remove_p = false;
2c8326a5 789 varpool_node *vnode;
4a444e58
JH
790 if (dump_file)
791 fprintf (dump_file, "Clearing variable flags:");
65c70e6b 792 FOR_EACH_VARIABLE (vnode)
6de88c6a 793 if (!vnode->alias
67348ccc 794 && (TREE_ADDRESSABLE (vnode->decl)
6de88c6a 795 || !vnode->writeonly
67348ccc 796 || !TREE_READONLY (vnode->decl)))
4a444e58
JH
797 {
798 bool written = false;
799 bool address_taken = false;
6de88c6a
JH
800 bool read = false;
801 bool explicit_refs = true;
802
dea91a66
JH
803 process_references (vnode, &written, &address_taken, &read,
804 &explicit_refs);
6de88c6a
JH
805 if (!explicit_refs)
806 continue;
807 if (!address_taken)
4a444e58 808 {
6de88c6a 809 if (TREE_ADDRESSABLE (vnode->decl) && dump_file)
d5ce4663 810 fprintf (dump_file, " %s (non-addressable)", vnode->name ());
31de7606
JH
811 vnode->call_for_symbol_and_aliases (clear_addressable_bit, NULL,
812 true);
4a444e58 813 }
6de88c6a 814 if (!address_taken && !written
4a444e58
JH
815 /* Making variable in explicit section readonly can cause section
816 type conflict.
817 See e.g. gcc.c-torture/compile/pr23237.c */
24d047a3 818 && vnode->get_section () == NULL)
4a444e58 819 {
6de88c6a 820 if (!TREE_READONLY (vnode->decl) && dump_file)
fec39fa6 821 fprintf (dump_file, " %s (read-only)", vnode->name ());
31de7606 822 vnode->call_for_symbol_and_aliases (set_readonly_bit, NULL, true);
6de88c6a 823 }
d5ce4663 824 if (!vnode->writeonly && !read && !address_taken && written)
6de88c6a
JH
825 {
826 if (dump_file)
827 fprintf (dump_file, " %s (write-only)", vnode->name ());
31de7606
JH
828 vnode->call_for_symbol_and_aliases (set_writeonly_bit, &remove_p,
829 true);
4a444e58
JH
830 }
831 }
832 if (dump_file)
833 fprintf (dump_file, "\n");
dea91a66 834 return remove_p;
4a444e58
JH
835}
836
a8da72b8
L
837/* Free inline summary. */
838
27a4cd48
DM
839namespace {
840
841const pass_data pass_data_ipa_free_inline_summary =
a8da72b8 842{
27a4cd48 843 SIMPLE_IPA_PASS, /* type */
8605403e 844 "free-inline-summary", /* name */
27a4cd48 845 OPTGROUP_NONE, /* optinfo_flags */
27a4cd48
DM
846 TV_IPA_FREE_INLINE_SUMMARY, /* tv_id */
847 0, /* properties_required */
848 0, /* properties_provided */
849 0, /* properties_destroyed */
850 0, /* todo_flags_start */
8605403e
JH
851 /* Early optimizations may make function unreachable. We can not
852 remove unreachable functions as part of the ealry opts pass because
853 TODOs are run before subpasses. Do it here. */
854 ( TODO_remove_functions | TODO_dump_symtab ), /* todo_flags_finish */
a8da72b8
L
855};
856
27a4cd48
DM
857class pass_ipa_free_inline_summary : public simple_ipa_opt_pass
858{
859public:
c3284718
RS
860 pass_ipa_free_inline_summary (gcc::context *ctxt)
861 : simple_ipa_opt_pass (pass_data_ipa_free_inline_summary, ctxt)
27a4cd48
DM
862 {}
863
864 /* opt_pass methods: */
be55bfe6
TS
865 virtual unsigned int execute (function *)
866 {
867 inline_free_summary ();
868 return 0;
869 }
27a4cd48
DM
870
871}; // class pass_ipa_free_inline_summary
872
873} // anon namespace
874
875simple_ipa_opt_pass *
876make_pass_ipa_free_inline_summary (gcc::context *ctxt)
877{
878 return new pass_ipa_free_inline_summary (ctxt);
879}
880
9e97ff61 881/* Generate and emit a static constructor or destructor. WHICH must
d5e254e1
IE
882 be one of 'I' (for a constructor), 'D' (for a destructor), 'P'
883 (for chp static vars constructor) or 'B' (for chkp static bounds
884 constructor). BODY is a STATEMENT_LIST containing GENERIC
885 statements. PRIORITY is the initialization priority for this
886 constructor or destructor.
9e97ff61 887
3a9ed12a
JH
888 FINAL specify whether the externally visible name for collect2 should
889 be produced. */
890
891static void
892cgraph_build_static_cdtor_1 (char which, tree body, int priority, bool final)
9e97ff61
JH
893{
894 static int counter = 0;
895 char which_buf[16];
896 tree decl, name, resdecl;
897
898 /* The priority is encoded in the constructor or destructor name.
899 collect2 will sort the names and arrange that they are called at
900 program startup. */
3a9ed12a
JH
901 if (final)
902 sprintf (which_buf, "%c_%.5d_%d", which, priority, counter++);
903 else
904 /* Proudce sane name but one not recognizable by collect2, just for the
905 case we fail to inline the function. */
906 sprintf (which_buf, "sub_%c_%.5d_%d", which, priority, counter++);
9e97ff61
JH
907 name = get_file_function_name (which_buf);
908
909 decl = build_decl (input_location, FUNCTION_DECL, name,
910 build_function_type_list (void_type_node, NULL_TREE));
911 current_function_decl = decl;
912
913 resdecl = build_decl (input_location,
914 RESULT_DECL, NULL_TREE, void_type_node);
915 DECL_ARTIFICIAL (resdecl) = 1;
916 DECL_RESULT (decl) = resdecl;
917 DECL_CONTEXT (resdecl) = decl;
918
919 allocate_struct_function (decl, false);
920
921 TREE_STATIC (decl) = 1;
922 TREE_USED (decl) = 1;
923 DECL_ARTIFICIAL (decl) = 1;
924 DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;
925 DECL_SAVED_TREE (decl) = body;
3a9ed12a 926 if (!targetm.have_ctors_dtors && final)
9e97ff61
JH
927 {
928 TREE_PUBLIC (decl) = 1;
929 DECL_PRESERVE_P (decl) = 1;
930 }
931 DECL_UNINLINABLE (decl) = 1;
932
933 DECL_INITIAL (decl) = make_node (BLOCK);
934 TREE_USED (DECL_INITIAL (decl)) = 1;
935
936 DECL_SOURCE_LOCATION (decl) = input_location;
937 cfun->function_end_locus = input_location;
938
939 switch (which)
940 {
941 case 'I':
942 DECL_STATIC_CONSTRUCTOR (decl) = 1;
943 decl_init_priority_insert (decl, priority);
944 break;
d5e254e1
IE
945 case 'P':
946 DECL_STATIC_CONSTRUCTOR (decl) = 1;
947 DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("chkp ctor"),
948 NULL,
949 NULL_TREE);
950 decl_init_priority_insert (decl, priority);
951 break;
952 case 'B':
953 DECL_STATIC_CONSTRUCTOR (decl) = 1;
954 DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("bnd_legacy"),
955 NULL,
956 NULL_TREE);
957 decl_init_priority_insert (decl, priority);
958 break;
9e97ff61
JH
959 case 'D':
960 DECL_STATIC_DESTRUCTOR (decl) = 1;
961 decl_fini_priority_insert (decl, priority);
962 break;
963 default:
964 gcc_unreachable ();
965 }
966
967 gimplify_function_tree (decl);
968
d52f5295 969 cgraph_node::add_new_function (decl, false);
9e97ff61
JH
970
971 set_cfun (NULL);
972 current_function_decl = NULL;
973}
974
3a9ed12a 975/* Generate and emit a static constructor or destructor. WHICH must
d5e254e1
IE
976 be one of 'I' (for a constructor), 'D' (for a destructor), 'P'
977 (for chkp static vars constructor) or 'B' (for chkp static bounds
978 constructor). BODY is a STATEMENT_LIST containing GENERIC
979 statements. PRIORITY is the initialization priority for this
980 constructor or destructor. */
3a9ed12a
JH
981
982void
983cgraph_build_static_cdtor (char which, tree body, int priority)
984{
985 cgraph_build_static_cdtor_1 (which, body, priority, false);
986}
9e97ff61
JH
987
988/* A vector of FUNCTION_DECLs declared as static constructors. */
9771b263 989static vec<tree> static_ctors;
9e97ff61 990/* A vector of FUNCTION_DECLs declared as static destructors. */
9771b263 991static vec<tree> static_dtors;
9e97ff61
JH
992
993/* When target does not have ctors and dtors, we call all constructor
994 and destructor by special initialization/destruction function
995 recognized by collect2.
996
997 When we are going to build this function, collect all constructors and
998 destructors and turn them into normal functions. */
999
1000static void
1001record_cdtor_fn (struct cgraph_node *node)
1002{
67348ccc
DM
1003 if (DECL_STATIC_CONSTRUCTOR (node->decl))
1004 static_ctors.safe_push (node->decl);
1005 if (DECL_STATIC_DESTRUCTOR (node->decl))
1006 static_dtors.safe_push (node->decl);
d52f5295 1007 node = cgraph_node::get (node->decl);
67348ccc 1008 DECL_DISREGARD_INLINE_LIMITS (node->decl) = 1;
9e97ff61
JH
1009}
1010
1011/* Define global constructors/destructor functions for the CDTORS, of
1012 which they are LEN. The CDTORS are sorted by initialization
1013 priority. If CTOR_P is true, these are constructors; otherwise,
1014 they are destructors. */
1015
1016static void
9771b263 1017build_cdtor (bool ctor_p, vec<tree> cdtors)
9e97ff61
JH
1018{
1019 size_t i,j;
9771b263 1020 size_t len = cdtors.length ();
9e97ff61
JH
1021
1022 i = 0;
1023 while (i < len)
1024 {
1025 tree body;
1026 tree fn;
1027 priority_type priority;
1028
1029 priority = 0;
1030 body = NULL_TREE;
1031 j = i;
1032 do
1033 {
1034 priority_type p;
9771b263 1035 fn = cdtors[j];
9e97ff61
JH
1036 p = ctor_p ? DECL_INIT_PRIORITY (fn) : DECL_FINI_PRIORITY (fn);
1037 if (j == i)
1038 priority = p;
1039 else if (p != priority)
1040 break;
1041 j++;
1042 }
1043 while (j < len);
1044
48c24aca 1045 /* When there is only one cdtor and target supports them, do nothing. */
9e97ff61
JH
1046 if (j == i + 1
1047 && targetm.have_ctors_dtors)
1048 {
1049 i++;
1050 continue;
1051 }
1052 /* Find the next batch of constructors/destructors with the same
1053 initialization priority. */
48c24aca 1054 for (;i < j; i++)
9e97ff61 1055 {
9e97ff61 1056 tree call;
9771b263 1057 fn = cdtors[i];
9e97ff61
JH
1058 call = build_call_expr (fn, 0);
1059 if (ctor_p)
1060 DECL_STATIC_CONSTRUCTOR (fn) = 0;
1061 else
1062 DECL_STATIC_DESTRUCTOR (fn) = 0;
1063 /* We do not want to optimize away pure/const calls here.
1064 When optimizing, these should be already removed, when not
1065 optimizing, we want user to be able to breakpoint in them. */
1066 TREE_SIDE_EFFECTS (call) = 1;
1067 append_to_statement_list (call, &body);
9e97ff61 1068 }
9e97ff61
JH
1069 gcc_assert (body != NULL_TREE);
1070 /* Generate a function to call all the function of like
1071 priority. */
3a9ed12a 1072 cgraph_build_static_cdtor_1 (ctor_p ? 'I' : 'D', body, priority, true);
9e97ff61
JH
1073 }
1074}
1075
1076/* Comparison function for qsort. P1 and P2 are actually of type
1077 "tree *" and point to static constructors. DECL_INIT_PRIORITY is
1078 used to determine the sort order. */
1079
1080static int
1081compare_ctor (const void *p1, const void *p2)
1082{
1083 tree f1;
1084 tree f2;
1085 int priority1;
1086 int priority2;
1087
1088 f1 = *(const tree *)p1;
1089 f2 = *(const tree *)p2;
1090 priority1 = DECL_INIT_PRIORITY (f1);
1091 priority2 = DECL_INIT_PRIORITY (f2);
1092
1093 if (priority1 < priority2)
1094 return -1;
1095 else if (priority1 > priority2)
1096 return 1;
1097 else
1098 /* Ensure a stable sort. Constructors are executed in backwarding
1099 order to make LTO initialize braries first. */
1100 return DECL_UID (f2) - DECL_UID (f1);
1101}
1102
1103/* Comparison function for qsort. P1 and P2 are actually of type
1104 "tree *" and point to static destructors. DECL_FINI_PRIORITY is
1105 used to determine the sort order. */
1106
1107static int
1108compare_dtor (const void *p1, const void *p2)
1109{
1110 tree f1;
1111 tree f2;
1112 int priority1;
1113 int priority2;
1114
1115 f1 = *(const tree *)p1;
1116 f2 = *(const tree *)p2;
1117 priority1 = DECL_FINI_PRIORITY (f1);
1118 priority2 = DECL_FINI_PRIORITY (f2);
1119
1120 if (priority1 < priority2)
1121 return -1;
1122 else if (priority1 > priority2)
1123 return 1;
1124 else
1125 /* Ensure a stable sort. */
1126 return DECL_UID (f1) - DECL_UID (f2);
1127}
1128
1129/* Generate functions to call static constructors and destructors
1130 for targets that do not support .ctors/.dtors sections. These
1131 functions have magic names which are detected by collect2. */
1132
1133static void
1134build_cdtor_fns (void)
1135{
9771b263 1136 if (!static_ctors.is_empty ())
9e97ff61
JH
1137 {
1138 gcc_assert (!targetm.have_ctors_dtors || in_lto_p);
9771b263 1139 static_ctors.qsort (compare_ctor);
48c24aca 1140 build_cdtor (/*ctor_p=*/true, static_ctors);
9e97ff61
JH
1141 }
1142
9771b263 1143 if (!static_dtors.is_empty ())
9e97ff61
JH
1144 {
1145 gcc_assert (!targetm.have_ctors_dtors || in_lto_p);
9771b263 1146 static_dtors.qsort (compare_dtor);
48c24aca 1147 build_cdtor (/*ctor_p=*/false, static_dtors);
9e97ff61
JH
1148 }
1149}
1150
1151/* Look for constructors and destructors and produce function calling them.
1152 This is needed for targets not supporting ctors or dtors, but we perform the
073a8998 1153 transformation also at linktime to merge possibly numerous
9e97ff61
JH
1154 constructors/destructors into single function to improve code locality and
1155 reduce size. */
1156
1157static unsigned int
1158ipa_cdtor_merge (void)
1159{
1160 struct cgraph_node *node;
65c70e6b 1161 FOR_EACH_DEFINED_FUNCTION (node)
67348ccc
DM
1162 if (DECL_STATIC_CONSTRUCTOR (node->decl)
1163 || DECL_STATIC_DESTRUCTOR (node->decl))
9e97ff61
JH
1164 record_cdtor_fn (node);
1165 build_cdtor_fns ();
9771b263
DN
1166 static_ctors.release ();
1167 static_dtors.release ();
9e97ff61
JH
1168 return 0;
1169}
1170
27a4cd48
DM
1171namespace {
1172
1173const pass_data pass_data_ipa_cdtor_merge =
9e97ff61 1174{
27a4cd48
DM
1175 IPA_PASS, /* type */
1176 "cdtor", /* name */
1177 OPTGROUP_NONE, /* optinfo_flags */
27a4cd48
DM
1178 TV_CGRAPHOPT, /* tv_id */
1179 0, /* properties_required */
1180 0, /* properties_provided */
1181 0, /* properties_destroyed */
1182 0, /* todo_flags_start */
1183 0, /* todo_flags_finish */
9e97ff61 1184};
27a4cd48
DM
1185
1186class pass_ipa_cdtor_merge : public ipa_opt_pass_d
1187{
1188public:
c3284718
RS
1189 pass_ipa_cdtor_merge (gcc::context *ctxt)
1190 : ipa_opt_pass_d (pass_data_ipa_cdtor_merge, ctxt,
1191 NULL, /* generate_summary */
1192 NULL, /* write_summary */
1193 NULL, /* read_summary */
1194 NULL, /* write_optimization_summary */
1195 NULL, /* read_optimization_summary */
1196 NULL, /* stmt_fixup */
1197 0, /* function_transform_todo_flags_start */
1198 NULL, /* function_transform */
1199 NULL) /* variable_transform */
27a4cd48
DM
1200 {}
1201
1202 /* opt_pass methods: */
1a3d085c 1203 virtual bool gate (function *);
be55bfe6 1204 virtual unsigned int execute (function *) { return ipa_cdtor_merge (); }
27a4cd48
DM
1205
1206}; // class pass_ipa_cdtor_merge
1207
1a3d085c
TS
1208bool
1209pass_ipa_cdtor_merge::gate (function *)
1210{
1211 /* Perform the pass when we have no ctors/dtors support
1212 or at LTO time to merge multiple constructors into single
1213 function. */
1214 return !targetm.have_ctors_dtors || (optimize && in_lto_p);
1215}
1216
27a4cd48
DM
1217} // anon namespace
1218
1219ipa_opt_pass_d *
1220make_pass_ipa_cdtor_merge (gcc::context *ctxt)
1221{
1222 return new pass_ipa_cdtor_merge (ctxt);
1223}
eb6a09a7
JH
1224
1225/* Invalid pointer representing BOTTOM for single user dataflow. */
1226#define BOTTOM ((cgraph_node *)(size_t) 2)
1227
1228/* Meet operation for single user dataflow.
1229 Here we want to associate variables with sigle function that may access it.
1230
1231 FUNCTION is current single user of a variable, VAR is variable that uses it.
1232 Latttice is stored in SINGLE_USER_MAP.
1233
1234 We represent:
1235 - TOP by no entry in SIGNLE_USER_MAP
1236 - BOTTOM by BOTTOM in AUX pointer (to save lookups)
1237 - known single user by cgraph pointer in SINGLE_USER_MAP. */
1238
1239cgraph_node *
1240meet (cgraph_node *function, varpool_node *var,
1eb68d2d 1241 hash_map<varpool_node *, cgraph_node *> &single_user_map)
eb6a09a7
JH
1242{
1243 struct cgraph_node *user, **f;
1244
1245 if (var->aux == BOTTOM)
1246 return BOTTOM;
1247
1eb68d2d 1248 f = single_user_map.get (var);
eb6a09a7
JH
1249 if (!f)
1250 return function;
1251 user = *f;
1252 if (!function)
1253 return user;
1254 else if (function != user)
1255 return BOTTOM;
1256 else
1257 return function;
1258}
1259
1260/* Propagation step of single-use dataflow.
1261
1262 Check all uses of VNODE and see if they are used by single function FUNCTION.
1263 SINGLE_USER_MAP represents the dataflow lattice. */
1264
1265cgraph_node *
1266propagate_single_user (varpool_node *vnode, cgraph_node *function,
1eb68d2d 1267 hash_map<varpool_node *, cgraph_node *> &single_user_map)
eb6a09a7
JH
1268{
1269 int i;
1270 struct ipa_ref *ref;
1271
1272 gcc_assert (!vnode->externally_visible);
1273
1274 /* If node is an alias, first meet with its target. */
1275 if (vnode->alias)
9041d2e6 1276 function = meet (function, vnode->get_alias_target (), single_user_map);
eb6a09a7
JH
1277
1278 /* Check all users and see if they correspond to a single function. */
d52f5295 1279 for (i = 0; vnode->iterate_referring (i, ref) && function != BOTTOM; i++)
eb6a09a7
JH
1280 {
1281 struct cgraph_node *cnode = dyn_cast <cgraph_node *> (ref->referring);
1282 if (cnode)
1283 {
1284 if (cnode->global.inlined_to)
1285 cnode = cnode->global.inlined_to;
1286 if (!function)
1287 function = cnode;
1288 else if (function != cnode)
1289 function = BOTTOM;
1290 }
1291 else
17e0fc92
JH
1292 function = meet (function, dyn_cast <varpool_node *> (ref->referring),
1293 single_user_map);
eb6a09a7
JH
1294 }
1295 return function;
1296}
1297
1298/* Pass setting used_by_single_function flag.
17e0fc92
JH
1299 This flag is set on variable when there is only one function that may
1300 possibly referr to it. */
eb6a09a7
JH
1301
1302static unsigned int
1303ipa_single_use (void)
1304{
1305 varpool_node *first = (varpool_node *) (void *) 1;
1306 varpool_node *var;
1eb68d2d 1307 hash_map<varpool_node *, cgraph_node *> single_user_map;
eb6a09a7
JH
1308
1309 FOR_EACH_DEFINED_VARIABLE (var)
9041d2e6 1310 if (!var->all_refs_explicit_p ())
eb6a09a7
JH
1311 var->aux = BOTTOM;
1312 else
1313 {
1314 /* Enqueue symbol for dataflow. */
1315 var->aux = first;
1316 first = var;
1317 }
1318
1319 /* The actual dataflow. */
1320
1321 while (first != (void *) 1)
1322 {
1323 cgraph_node *user, *orig_user, **f;
1324
1325 var = first;
1326 first = (varpool_node *)first->aux;
1327
1eb68d2d 1328 f = single_user_map.get (var);
eb6a09a7
JH
1329 if (f)
1330 orig_user = *f;
1331 else
1332 orig_user = NULL;
1333 user = propagate_single_user (var, orig_user, single_user_map);
1334
1335 gcc_checking_assert (var->aux != BOTTOM);
1336
1337 /* If user differs, enqueue all references. */
1338 if (user != orig_user)
1339 {
1340 unsigned int i;
1341 ipa_ref *ref;
1342
1eb68d2d 1343 single_user_map.put (var, user);
eb6a09a7
JH
1344
1345 /* Enqueue all aliases for re-processing. */
31de7606
JH
1346 for (i = 0; var->iterate_direct_aliases (i, ref); i++)
1347 if (!ref->referring->aux)
eb6a09a7
JH
1348 {
1349 ref->referring->aux = first;
1350 first = dyn_cast <varpool_node *> (ref->referring);
1351 }
1352 /* Enqueue all users for re-processing. */
d52f5295 1353 for (i = 0; var->iterate_reference (i, ref); i++)
eb6a09a7
JH
1354 if (!ref->referred->aux
1355 && ref->referred->definition
1356 && is_a <varpool_node *> (ref->referred))
1357 {
1358 ref->referred->aux = first;
1359 first = dyn_cast <varpool_node *> (ref->referred);
1360 }
1361
1362 /* If user is BOTTOM, just punt on this var. */
1363 if (user == BOTTOM)
1364 var->aux = BOTTOM;
1365 else
1366 var->aux = NULL;
1367 }
1368 else
1369 var->aux = NULL;
1370 }
1371
1372 FOR_EACH_DEFINED_VARIABLE (var)
1373 {
1374 if (var->aux != BOTTOM)
1375 {
1376#ifdef ENABLE_CHECKING
17e0fc92
JH
1377 /* Not having the single user known means that the VAR is
1378 unreachable. Either someone forgot to remove unreachable
1379 variables or the reachability here is wrong. */
1380
1eb68d2d 1381 gcc_assert (single_user_map.get (var));
eb6a09a7
JH
1382#endif
1383 if (dump_file)
1384 {
1385 fprintf (dump_file, "Variable %s/%i is used by single function\n",
1386 var->name (), var->order);
1387 }
1388 var->used_by_single_function = true;
1389 }
1390 var->aux = NULL;
1391 }
1392 return 0;
1393}
1394
1395namespace {
1396
1397const pass_data pass_data_ipa_single_use =
1398{
1399 IPA_PASS, /* type */
1400 "single-use", /* name */
1401 OPTGROUP_NONE, /* optinfo_flags */
eb6a09a7
JH
1402 TV_CGRAPHOPT, /* tv_id */
1403 0, /* properties_required */
1404 0, /* properties_provided */
1405 0, /* properties_destroyed */
1406 0, /* todo_flags_start */
1407 0, /* todo_flags_finish */
1408};
1409
1410class pass_ipa_single_use : public ipa_opt_pass_d
1411{
1412public:
1413 pass_ipa_single_use (gcc::context *ctxt)
1414 : ipa_opt_pass_d (pass_data_ipa_single_use, ctxt,
1415 NULL, /* generate_summary */
1416 NULL, /* write_summary */
1417 NULL, /* read_summary */
1418 NULL, /* write_optimization_summary */
1419 NULL, /* read_optimization_summary */
1420 NULL, /* stmt_fixup */
1421 0, /* function_transform_todo_flags_start */
1422 NULL, /* function_transform */
1423 NULL) /* variable_transform */
1424 {}
1425
1426 /* opt_pass methods: */
1427 virtual bool gate (function *);
1428 virtual unsigned int execute (function *) { return ipa_single_use (); }
1429
1430}; // class pass_ipa_single_use
1431
1432bool
1433pass_ipa_single_use::gate (function *)
1434{
1435 return optimize;
1436}
1437
1438} // anon namespace
1439
1440ipa_opt_pass_d *
1441make_pass_ipa_single_use (gcc::context *ctxt)
1442{
1443 return new pass_ipa_single_use (ctxt);
1444}