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