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