Line data Source code
1 : /* Callgraph handling code.
2 : Copyright (C) 2003-2026 Free Software Foundation, Inc.
3 : Contributed by Jan Hubicka
4 :
5 : This file is part of GCC.
6 :
7 : GCC is free software; you can redistribute it and/or modify it under
8 : the terms of the GNU General Public License as published by the Free
9 : Software Foundation; either version 3, or (at your option) any later
10 : version.
11 :
12 : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 : WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 : for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with GCC; see the file COPYING3. If not see
19 : <http://www.gnu.org/licenses/>. */
20 :
21 : #include "config.h"
22 : #include "system.h"
23 : #include "coretypes.h"
24 : #include "backend.h"
25 : #include "target.h"
26 : #include "tree.h"
27 : #include "gimple.h"
28 : #include "timevar.h"
29 : #include "cgraph.h"
30 : #include "lto-streamer.h"
31 : #include "varasm.h"
32 : #include "debug.h"
33 : #include "output.h"
34 : #include "omp-offload.h"
35 : #include "context.h"
36 : #include "stringpool.h"
37 : #include "attribs.h"
38 : #include "tree-pass.h"
39 :
40 : const char * const tls_model_names[]={"none", "emulated",
41 : "global-dynamic", "local-dynamic",
42 : "initial-exec", "local-exec"};
43 :
44 : /* List of hooks triggered on varpool_node events. */
45 : struct varpool_node_hook_list {
46 : varpool_node_hook hook;
47 : void *data;
48 : struct varpool_node_hook_list *next;
49 : };
50 :
51 : /* Register HOOK to be called with DATA on each removed node. */
52 : varpool_node_hook_list *
53 300690 : symbol_table::add_varpool_removal_hook (varpool_node_hook hook, void *data)
54 : {
55 300690 : varpool_node_hook_list *entry;
56 601380 : varpool_node_hook_list **ptr = &m_first_varpool_removal_hook;
57 :
58 300690 : entry = (varpool_node_hook_list *) xmalloc (sizeof (*entry));
59 300690 : entry->hook = hook;
60 300690 : entry->data = data;
61 300690 : entry->next = NULL;
62 308482 : while (*ptr)
63 7792 : ptr = &(*ptr)->next;
64 300690 : *ptr = entry;
65 300690 : return entry;
66 : }
67 :
68 : /* Remove ENTRY from the list of hooks called on removing nodes. */
69 : void
70 287368 : symbol_table::remove_varpool_removal_hook (varpool_node_hook_list *entry)
71 : {
72 287368 : varpool_node_hook_list **ptr = &m_first_varpool_removal_hook;
73 :
74 294949 : while (*ptr != entry)
75 7581 : ptr = &(*ptr)->next;
76 287368 : *ptr = entry->next;
77 287368 : free (entry);
78 287368 : }
79 :
80 : /* Call all node removal hooks. */
81 : void
82 36766325 : symbol_table::call_varpool_removal_hooks (varpool_node *node)
83 : {
84 36766325 : varpool_node_hook_list *entry = m_first_varpool_removal_hook;
85 44956231 : while (entry)
86 : {
87 8189906 : entry->hook (node, entry->data);
88 8189906 : entry = entry->next;
89 : }
90 36766325 : }
91 :
92 : /* Register HOOK to be called with DATA on each inserted node. */
93 : varpool_node_hook_list *
94 0 : symbol_table::add_varpool_insertion_hook (varpool_node_hook hook, void *data)
95 : {
96 0 : varpool_node_hook_list *entry;
97 0 : varpool_node_hook_list **ptr = &m_first_varpool_insertion_hook;
98 :
99 0 : entry = (varpool_node_hook_list *) xmalloc (sizeof (*entry));
100 0 : entry->hook = hook;
101 0 : entry->data = data;
102 0 : entry->next = NULL;
103 0 : while (*ptr)
104 0 : ptr = &(*ptr)->next;
105 0 : *ptr = entry;
106 0 : return entry;
107 : }
108 :
109 : /* Remove ENTRY from the list of hooks called on inserted nodes. */
110 : void
111 0 : symbol_table::remove_varpool_insertion_hook (varpool_node_hook_list *entry)
112 : {
113 0 : varpool_node_hook_list **ptr = &m_first_varpool_insertion_hook;
114 :
115 0 : while (*ptr != entry)
116 0 : ptr = &(*ptr)->next;
117 0 : *ptr = entry->next;
118 0 : free (entry);
119 0 : }
120 :
121 : /* Call all node insertion hooks. */
122 : void
123 2371 : symbol_table::call_varpool_insertion_hooks (varpool_node *node)
124 : {
125 2371 : varpool_node_hook_list *entry = m_first_varpool_insertion_hook;
126 2371 : while (entry)
127 : {
128 0 : entry->hook (node, entry->data);
129 0 : entry = entry->next;
130 : }
131 2371 : }
132 :
133 : /* Allocate new callgraph node and insert it into basic data structures. */
134 :
135 : varpool_node *
136 40127287 : varpool_node::create_empty (void)
137 : {
138 40127287 : return new (ggc_alloc<varpool_node> ()) varpool_node ();
139 : }
140 :
141 : /* Return varpool node assigned to DECL. Create new one when needed. */
142 : varpool_node *
143 291331427 : varpool_node::get_create (tree decl)
144 : {
145 291331427 : varpool_node *node = varpool_node::get (decl);
146 291331427 : gcc_checking_assert (VAR_P (decl));
147 291331427 : if (node)
148 : return node;
149 :
150 40057001 : node = varpool_node::create_empty ();
151 40057001 : node->decl = decl;
152 :
153 40018628 : if ((flag_openacc || flag_openmp)
154 40215587 : && lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl)))
155 : {
156 5065 : node->offloadable = 1;
157 5065 : if (ENABLE_OFFLOADING && !DECL_EXTERNAL (decl))
158 : {
159 : g->have_offload = true;
160 : if (!in_lto_p)
161 : vec_safe_push (offload_vars, decl);
162 : }
163 : }
164 :
165 40057001 : node->register_symbol ();
166 40057001 : return node;
167 : }
168 :
169 : /* Remove variable from symbol table. */
170 :
171 : void
172 36766325 : varpool_node::remove (void)
173 : {
174 36766325 : symtab->call_varpool_removal_hooks (this);
175 36766325 : lto_free_function_in_decl_state_for_node (this);
176 :
177 : /* When streaming we can have multiple nodes associated with decl. */
178 36766325 : if (symtab->state == LTO_STREAMING)
179 : ;
180 : /* Keep constructor when it may be used for folding. We remove
181 : references to external variables before final compilation. */
182 71236068 : else if (DECL_INITIAL (decl) && DECL_INITIAL (decl) != error_mark_node
183 71234503 : && !ctor_useable_for_folding_p ())
184 3668 : remove_initializer ();
185 :
186 36766325 : unregister (NULL);
187 36766325 : ggc_free (this);
188 36766325 : }
189 :
190 : /* Remove node initializer when it is no longer needed. */
191 : void
192 1990951 : varpool_node::remove_initializer (void)
193 : {
194 1990951 : if (DECL_INITIAL (decl)
195 4205 : && !DECL_IN_CONSTANT_POOL (decl)
196 : /* Keep vtables for BINFO folding. */
197 4205 : && !DECL_VIRTUAL_P (decl)
198 : /* FIXME: http://gcc.gnu.org/PR55395 */
199 3984 : && debug_info_level == DINFO_LEVEL_NONE
200 : /* When doing declaration merging we have duplicate
201 : entries for given decl. Do not attempt to remove
202 : the bodies, or we will end up removing
203 : wrong one. */
204 1994190 : && symtab->state != LTO_STREAMING)
205 3239 : DECL_INITIAL (decl) = error_mark_node;
206 1990951 : }
207 :
208 : /* Dump given varpool node to F. */
209 : void
210 2468 : varpool_node::dump (FILE *f)
211 : {
212 2468 : dump_base (f);
213 2468 : fprintf (f, " Availability: %s\n",
214 2468 : symtab->function_flags_ready
215 2342 : ? cgraph_availability_names[get_availability ()]
216 : : "not-ready");
217 2468 : fprintf (f, " Varpool flags:");
218 2468 : if (DECL_INITIAL (decl))
219 1516 : fprintf (f, " initialized");
220 2468 : if (output)
221 0 : fprintf (f, " output");
222 2468 : if (used_by_single_function)
223 43 : fprintf (f, " used-by-single-function");
224 2468 : if (TREE_READONLY (decl))
225 1442 : fprintf (f, " read-only");
226 2468 : if (ctor_useable_for_folding_p ())
227 1153 : fprintf (f, " const-value-known");
228 2468 : if (writeonly)
229 0 : fprintf (f, " write-only");
230 2468 : if (tls_model)
231 59 : fprintf (f, " tls-%s", tls_model_names [tls_model]);
232 2468 : fprintf (f, "\n");
233 2468 : }
234 :
235 :
236 : /* Dump given varpool node to stderr. */
237 0 : void varpool_node::debug (void)
238 : {
239 0 : varpool_node::dump (stderr);
240 0 : }
241 :
242 : /* Dump the variable pool to F. */
243 : void
244 0 : varpool_node::dump_varpool (FILE *f)
245 : {
246 0 : varpool_node *node;
247 :
248 0 : fprintf (f, "variable pool:\n\n");
249 0 : FOR_EACH_VARIABLE (node)
250 0 : node->dump (f);
251 0 : }
252 :
253 : /* Dump the variable pool to stderr. */
254 :
255 : DEBUG_FUNCTION void
256 0 : varpool_node::debug_varpool (void)
257 : {
258 0 : dump_varpool (stderr);
259 0 : }
260 :
261 : /* Given an assembler name, lookup node. */
262 : varpool_node *
263 0 : varpool_node::get_for_asmname (tree asmname)
264 : {
265 0 : if (symtab_node *node = symtab_node::get_for_asmname (asmname))
266 0 : return dyn_cast <varpool_node *> (node);
267 : else
268 : return NULL;
269 : }
270 :
271 : /* When doing LTO, read variable's constructor from disk if
272 : it is not already present. */
273 :
274 : tree
275 7317410 : varpool_node::get_constructor (void)
276 : {
277 7317410 : lto_file_decl_data *file_data;
278 7317410 : const char *data, *name;
279 7317410 : size_t len;
280 :
281 7317410 : if (DECL_INITIAL (decl) != error_mark_node
282 7643 : || !in_lto_p
283 7325049 : || !lto_file_data)
284 7309771 : return DECL_INITIAL (decl);
285 :
286 7639 : timevar_push (TV_IPA_LTO_CTORS_IN);
287 :
288 7639 : file_data = lto_file_data;
289 7639 : name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
290 :
291 : /* We may have renamed the declaration, e.g., a static function. */
292 7639 : name = lto_get_decl_name_mapping (file_data, name);
293 7639 : struct lto_in_decl_state *decl_state
294 7639 : = lto_get_function_in_decl_state (file_data, decl);
295 :
296 15278 : data = lto_get_section_data (file_data, LTO_section_function_body,
297 7639 : name, order - file_data->order_base,
298 7639 : &len, decl_state->compressed);
299 7639 : if (!data)
300 0 : fatal_error (input_location, "%s: section %s.%d is missing",
301 : file_data->file_name,
302 0 : name, order - file_data->order_base);
303 :
304 7639 : if (!quiet_flag)
305 0 : fprintf (stderr, " in:%s", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
306 7639 : lto_input_variable_constructor (file_data, this, data);
307 7639 : gcc_assert (DECL_INITIAL (decl) != error_mark_node);
308 7639 : lto_stats.num_function_bodies++;
309 7639 : lto_free_section_data (file_data, LTO_section_function_body, name,
310 7639 : data, len, decl_state->compressed);
311 7639 : lto_free_function_in_decl_state_for_node (this);
312 7639 : timevar_pop (TV_IPA_LTO_CTORS_IN);
313 7639 : return DECL_INITIAL (decl);
314 : }
315 :
316 : /* Return true if variable has constructor that can be used for folding. */
317 :
318 : bool
319 73325516 : varpool_node::ctor_useable_for_folding_p (void)
320 : {
321 73325516 : varpool_node *real_node = this;
322 :
323 73325516 : if (real_node->alias && real_node->definition)
324 247749 : real_node = ultimate_alias_target ();
325 :
326 73325516 : if (TREE_CODE (decl) == CONST_DECL
327 73325516 : || DECL_IN_CONSTANT_POOL (decl))
328 : return true;
329 73324984 : if (TREE_THIS_VOLATILE (decl))
330 : return false;
331 :
332 : /* Avoid attempts to load constructors that was not streamed. */
333 857580 : if (in_lto_p && DECL_INITIAL (real_node->decl) == error_mark_node
334 73359630 : && real_node->body_removed)
335 : return false;
336 :
337 : /* If we do not have a constructor, we can't use it. */
338 73287384 : if (DECL_INITIAL (real_node->decl) == error_mark_node
339 73287384 : && !real_node->lto_file_data)
340 : return false;
341 :
342 : /* Folding may cross TU boundaries. */
343 73287233 : if (must_remain_in_tu_body)
344 : return false;
345 :
346 : /* Vtables are defined by their types and must match no matter of interposition
347 : rules. */
348 73287233 : if (DECL_VIRTUAL_P (decl))
349 : {
350 : /* The C++ front end creates VAR_DECLs for vtables of typeinfo
351 : classes not defined in the current TU so that it can refer
352 : to them from typeinfo objects. Avoid returning NULL_TREE. */
353 1344094 : return DECL_INITIAL (real_node->decl) != NULL;
354 : }
355 :
356 : /* An alias of a read-only variable is also read-only, since the variable
357 : is stored in read-only memory. We also accept read-only aliases of
358 : non-read-only locations assuming that the user knows what he is asking
359 : for. */
360 71943139 : if (!TREE_READONLY (decl) && !TREE_READONLY (real_node->decl))
361 : return false;
362 :
363 : /* Variables declared 'const' without an initializer
364 : have zero as the initializer if they may not be
365 : overridden at link or run time.
366 :
367 : It is actually requirement for C++ compiler to optimize const variables
368 : consistently. As a GNU extension, do not enforce this rule for user defined
369 : weak variables, so we support interposition on:
370 : static const int dummy = 0;
371 : extern const int foo __attribute__((__weak__, __alias__("dummy")));
372 : */
373 35713460 : if ((!DECL_INITIAL (real_node->decl)
374 34675419 : || (DECL_WEAK (decl) && !DECL_COMDAT (decl)))
375 35714066 : && ((DECL_EXTERNAL (decl) && !in_other_partition)
376 7104 : || decl_replaceable_p (decl, semantic_interposition)))
377 1032263 : return false;
378 :
379 : /* Variables declared `const' with an initializer are considered
380 : to not be overwritable with different initializer by default.
381 :
382 : ??? Previously we behaved so for scalar variables but not for array
383 : accesses. */
384 : return true;
385 : }
386 :
387 : /* If DECLARATION is constant variable and its initial value is known
388 : (so we can do constant folding), return its constructor (DECL_INITIAL).
389 : This may be an expression or NULL when DECL is initialized to 0.
390 : Return ERROR_MARK_NODE otherwise.
391 :
392 : In LTO this may actually trigger reading the constructor from disk.
393 : For this reason varpool_ctor_useable_for_folding_p should be used when
394 : the actual constructor value is not needed. */
395 :
396 : tree
397 145438813 : ctor_for_folding (tree decl)
398 : {
399 145438813 : varpool_node *node, *real_node;
400 145438813 : tree real_decl;
401 :
402 145438813 : if (!VAR_P (decl) && TREE_CODE (decl) != CONST_DECL)
403 4438303 : return error_mark_node;
404 :
405 141000510 : if (TREE_CODE (decl) == CONST_DECL
406 141000510 : || DECL_IN_CONSTANT_POOL (decl))
407 85931 : return DECL_INITIAL (decl);
408 :
409 140914579 : if (TREE_THIS_VOLATILE (decl))
410 2157310 : return error_mark_node;
411 :
412 : /* Do not care about automatic variables. Those are never initialized
413 : anyway, because gimplifier expands the code. */
414 138757269 : if (!TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
415 : {
416 99058517 : gcc_assert (!TREE_PUBLIC (decl));
417 : /* Unless this is called during FE folding. */
418 99058517 : if (cfun
419 99053853 : && (cfun->curr_properties & (PROP_gimple | PROP_rtl)) == 0
420 5809977 : && TREE_READONLY (decl)
421 16595 : && !TREE_SIDE_EFFECTS (decl)
422 99075112 : && DECL_INITIAL (decl))
423 423 : return DECL_INITIAL (decl);
424 99058094 : return error_mark_node;
425 : }
426 :
427 39698752 : gcc_assert (VAR_P (decl));
428 :
429 39698752 : real_node = node = varpool_node::get (decl);
430 39698752 : if (node)
431 : {
432 39137699 : real_node = node->ultimate_alias_target ();
433 39137699 : real_decl = real_node->decl;
434 : }
435 : else
436 : real_decl = decl;
437 :
438 : /* See if we are dealing with alias.
439 : In most cases alias is just alternative symbol pointing to a given
440 : constructor. This allows us to use interposition rules of DECL
441 : constructor of REAL_NODE. However weakrefs are special by being just
442 : alternative name of their target (if defined). */
443 39698752 : if (decl != real_decl)
444 : {
445 247445 : gcc_assert (!DECL_INITIAL (decl)
446 : || (node->alias && node->get_alias_target () == real_node)
447 : || DECL_INITIAL (decl) == error_mark_node);
448 247445 : while (node->transparent_alias && node->analyzed)
449 : {
450 0 : node = node->get_alias_target ();
451 0 : decl = node->decl;
452 : }
453 : }
454 :
455 39698752 : if ((!DECL_VIRTUAL_P (real_decl)
456 687929 : || DECL_INITIAL (real_decl) == error_mark_node
457 687403 : || !DECL_INITIAL (real_decl))
458 39770924 : && (!node || !node->ctor_useable_for_folding_p ()))
459 37606957 : return error_mark_node;
460 :
461 : /* OK, we can return constructor. See if we need to fetch it from disk
462 : in LTO mode. */
463 2091795 : if (DECL_INITIAL (real_decl) != error_mark_node
464 2091795 : || !in_lto_p)
465 2090436 : return DECL_INITIAL (real_decl);
466 1359 : return real_node->get_constructor ();
467 : }
468 :
469 : /* Add the variable DECL to the varpool.
470 : Unlike finalize_decl function is intended to be used
471 : by middle end and allows insertion of new variable at arbitrary point
472 : of compilation. */
473 : void
474 2371 : varpool_node::add (tree decl)
475 : {
476 2371 : varpool_node *node;
477 2371 : varpool_node::finalize_decl (decl);
478 2371 : node = varpool_node::get_create (decl);
479 2371 : symtab->call_varpool_insertion_hooks (node);
480 2371 : if (node->externally_visible_p ())
481 2358 : node->externally_visible = true;
482 2371 : if (lookup_attribute ("no_reorder", DECL_ATTRIBUTES (decl)))
483 0 : node->no_reorder = 1;
484 2371 : }
485 :
486 : /* Return variable availability. See cgraph.h for description of individual
487 : return values. */
488 : enum availability
489 170189865 : varpool_node::get_availability (symtab_node *ref)
490 : {
491 170189865 : if (!definition && !in_other_partition)
492 : return AVAIL_NOT_AVAILABLE;
493 146980613 : if (!TREE_PUBLIC (decl))
494 : return AVAIL_AVAILABLE;
495 51310369 : if (DECL_IN_CONSTANT_POOL (decl)
496 51310369 : || DECL_VIRTUAL_P (decl))
497 : return AVAIL_AVAILABLE;
498 51251729 : if (transparent_alias && definition)
499 : {
500 0 : enum availability avail;
501 :
502 0 : ultimate_alias_target (&avail, ref);
503 0 : return avail;
504 : }
505 : /* If this is a reference from symbol itself and there are no aliases, we
506 : may be sure that the symbol was not interposed by something else because
507 : the symbol itself would be unreachable otherwise. */
508 0 : if ((this == ref && !has_aliases_p ())
509 51251729 : || (ref && get_comdat_group ()
510 0 : && get_comdat_group () == ref->get_comdat_group ()))
511 : return AVAIL_AVAILABLE;
512 : /* If the variable can be overwritten, return OVERWRITABLE. Takes
513 : care of at least one notable extension - the COMDAT variables
514 : used to share template instantiations in C++. */
515 51251729 : if (decl_replaceable_p (decl, semantic_interposition)
516 51251729 : || (DECL_EXTERNAL (decl) && !in_other_partition))
517 : return AVAIL_INTERPOSABLE;
518 : return AVAIL_AVAILABLE;
519 : }
520 :
521 : void
522 3060772 : varpool_node::analyze (void)
523 : {
524 : /* When reading back varpool at LTO time, we re-construct the queue in order
525 : to have "needed" list right by inserting all needed nodes into varpool.
526 : We however don't want to re-analyze already analyzed nodes. */
527 3060772 : if (!analyzed)
528 : {
529 3060772 : gcc_assert (!in_lto_p || symtab->function_flags_ready);
530 : /* Compute the alignment early so function body expanders are
531 : already informed about increased alignment. */
532 3060772 : align_variable (decl, 0);
533 : }
534 3060772 : if (alias)
535 135 : resolve_alias (varpool_node::get (alias_target));
536 3060637 : else if (DECL_INITIAL (decl))
537 2004298 : record_references_in_initializer (decl, analyzed);
538 3060772 : analyzed = true;
539 3060772 : }
540 :
541 : /* Assemble thunks and aliases associated to varpool node. */
542 :
543 : void
544 2830271 : varpool_node::assemble_aliases (void)
545 : {
546 2830271 : ipa_ref *ref;
547 :
548 2835241 : FOR_EACH_ALIAS (this, ref)
549 : {
550 4970 : varpool_node *alias = dyn_cast <varpool_node *> (ref->referring);
551 4970 : if (alias->symver)
552 0 : do_assemble_symver (alias->decl,
553 : DECL_ASSEMBLER_NAME (decl));
554 4970 : else if (!alias->transparent_alias)
555 4970 : do_assemble_alias (alias->decl,
556 : DECL_ASSEMBLER_NAME (decl));
557 4970 : alias->assemble_aliases ();
558 : }
559 2830271 : }
560 :
561 : /* Output one variable, if necessary. Return whether we output it. */
562 :
563 : bool
564 2832394 : varpool_node::assemble_decl (void)
565 : {
566 : /* Aliases are output when their target is produced or by
567 : output_weakrefs. */
568 2832394 : if (alias)
569 : return false;
570 :
571 : /* Constant pool is output from RTL land when the reference
572 : survive till this level. */
573 2827421 : if (DECL_IN_CONSTANT_POOL (decl) && TREE_ASM_WRITTEN (decl))
574 : return false;
575 :
576 : /* Decls with VALUE_EXPR should not be in the varpool at all. They
577 : are not real variables, but just info for debugging and codegen.
578 : Unfortunately at the moment emutls is not updating varpool correctly
579 : after turning real vars into value_expr vars. */
580 2825481 : if (DECL_HAS_VALUE_EXPR_P (decl)
581 2825481 : && !targetm.have_tls)
582 : return false;
583 :
584 : /* Hard register vars do not need to be output. */
585 2825481 : if (DECL_HARD_REGISTER (decl))
586 : return false;
587 :
588 2825481 : gcc_checking_assert (!TREE_ASM_WRITTEN (decl)
589 : && VAR_P (decl)
590 : && !DECL_HAS_VALUE_EXPR_P (decl));
591 :
592 2825481 : if (!in_other_partition
593 2825481 : && !DECL_EXTERNAL (decl))
594 : {
595 2825301 : get_constructor ();
596 2825301 : assemble_variable (decl, 0, 1, 0);
597 2825301 : gcc_assert (TREE_ASM_WRITTEN (decl));
598 2825301 : gcc_assert (definition);
599 2825301 : assemble_aliases ();
600 : /* After the parser has generated debugging information, augment
601 : this information with any new location/etc information that may
602 : have become available after the compilation proper. */
603 2825301 : debug_hooks->late_global_decl (decl);
604 2825301 : return true;
605 : }
606 :
607 : return false;
608 : }
609 :
610 : /* Add NODE to queue starting at FIRST.
611 : The queue is linked via AUX pointers and terminated by pointer to 1. */
612 :
613 : static void
614 4721214 : enqueue_node (varpool_node *node, varpool_node **first)
615 : {
616 4721214 : if (node->aux)
617 : return;
618 2827655 : gcc_checking_assert (*first);
619 2827655 : node->aux = *first;
620 2827655 : *first = node;
621 : }
622 :
623 : /* Optimization of function bodies might've rendered some variables as
624 : unnecessary so we want to avoid these from being compiled. Re-do
625 : reachability starting from variables that are either externally visible
626 : or was referred from the asm output routines. */
627 :
628 : void
629 230133 : symbol_table::remove_unreferenced_decls (void)
630 : {
631 230133 : varpool_node *next, *node;
632 230133 : varpool_node *first = (varpool_node *)(void *)1;
633 230133 : int i;
634 230133 : ipa_ref *ref = NULL;
635 230133 : hash_set<varpool_node *> referenced;
636 :
637 230133 : if (seen_error ())
638 0 : return;
639 :
640 230133 : if (dump_file)
641 72 : fprintf (dump_file, "Trivially needed variables:");
642 3113596 : FOR_EACH_DEFINED_VARIABLE (node)
643 : {
644 2883463 : if (node->analyzed
645 2883463 : && (!node->can_remove_if_no_refs_p ()
646 : /* We just expanded all function bodies. See if any of
647 : them needed the variable. */
648 1390434 : || DECL_RTL_SET_P (node->decl)))
649 : {
650 2215278 : enqueue_node (node, &first);
651 2215278 : if (dump_file)
652 59 : fprintf (dump_file, " %s", node->dump_asm_name ());
653 : }
654 : }
655 3057788 : while (first != (varpool_node *)(void *)1)
656 : {
657 2827655 : node = first;
658 2827655 : first = (varpool_node *)first->aux;
659 :
660 2827655 : if (node->same_comdat_group)
661 : {
662 : symtab_node *next;
663 209786 : for (next = node->same_comdat_group;
664 219357 : next != node;
665 209786 : next = next->same_comdat_group)
666 : {
667 419572 : varpool_node *vnext = dyn_cast <varpool_node *> (next);
668 419572 : if (vnext && vnext->analyzed && !next->comdat_local_p ())
669 209780 : enqueue_node (vnext, &first);
670 : }
671 : }
672 9355744 : for (i = 0; node->iterate_reference (i, ref); i++)
673 : {
674 3470301 : varpool_node *vnode = dyn_cast <varpool_node *> (ref->referred);
675 3470301 : if (vnode
676 2541623 : && !vnode->in_other_partition
677 2541616 : && (!DECL_EXTERNAL (ref->referred->decl)
678 245453 : || vnode->alias)
679 5766464 : && vnode->analyzed)
680 2296156 : enqueue_node (vnode, &first);
681 : else
682 : {
683 1174145 : if (vnode)
684 245467 : referenced.add (vnode);
685 1174145 : while (vnode && vnode->alias && vnode->definition)
686 : {
687 0 : vnode = vnode->get_alias_target ();
688 0 : gcc_checking_assert (vnode);
689 0 : referenced.add (vnode);
690 : }
691 : }
692 : }
693 : }
694 230133 : if (dump_file)
695 72 : fprintf (dump_file, "\nRemoving variables:");
696 3113596 : for (node = first_defined_variable (); node; node = next)
697 : {
698 2883463 : next = next_defined_variable (node);
699 2883463 : if (!node->aux && !node->no_reorder)
700 : {
701 55807 : if (dump_file)
702 0 : fprintf (dump_file, " %s", node->dump_asm_name ());
703 55807 : if (referenced.contains(node))
704 0 : node->remove_initializer ();
705 : else
706 55807 : node->remove ();
707 : }
708 : }
709 :
710 230133 : if (dump_file)
711 72 : fprintf (dump_file, "\n");
712 230133 : }
713 :
714 : /* For variables in named sections make sure get_variable_section
715 : is called before we switch to those sections. Then section
716 : conflicts between read-only and read-only requiring relocations
717 : sections can be resolved. */
718 : void
719 2820162 : varpool_node::finalize_named_section_flags (void)
720 : {
721 2820162 : if (!TREE_ASM_WRITTEN (decl)
722 2818489 : && !alias
723 2813549 : && !in_other_partition
724 2813549 : && !DECL_EXTERNAL (decl)
725 2813513 : && VAR_P (decl)
726 2813513 : && !DECL_HAS_VALUE_EXPR_P (decl)
727 5633675 : && get_section ())
728 1432445 : get_variable_section (decl, false);
729 2820162 : }
730 :
731 : /* Output all variables enqueued to be assembled. */
732 : bool
733 230419 : symbol_table::output_variables (void)
734 : {
735 230419 : bool changed = false;
736 230419 : varpool_node *node;
737 :
738 230419 : if (seen_error ())
739 : return false;
740 :
741 230133 : remove_unreferenced_decls ();
742 :
743 230133 : timevar_push (TV_VAROUT);
744 :
745 3057789 : FOR_EACH_DEFINED_VARIABLE (node)
746 : {
747 : /* Handled in output_in_order. */
748 2827656 : if (node->no_reorder)
749 997651 : continue;
750 :
751 1830005 : node->finalize_named_section_flags ();
752 : }
753 :
754 : /* There is a similar loop in output_in_order. Please keep them in sync. */
755 3351635 : FOR_EACH_VARIABLE (node)
756 : {
757 : /* Handled in output_in_order. */
758 3121502 : if (node->no_reorder)
759 998291 : continue;
760 2123211 : if (DECL_HARD_REGISTER (node->decl)
761 2123211 : || DECL_HAS_VALUE_EXPR_P (node->decl))
762 62 : continue;
763 2123149 : if (node->definition)
764 1829943 : changed |= node->assemble_decl ();
765 : else
766 293206 : assemble_undefined_decl (node->decl);
767 : }
768 230133 : timevar_pop (TV_VAROUT);
769 230133 : return changed;
770 : }
771 :
772 : /* Attempt to mark ALIAS as an alias to DECL. Return TRUE if successful.
773 : Extra name aliases are output whenever DECL is output. */
774 :
775 : varpool_node *
776 12464 : varpool_node::create_alias (tree alias, tree decl)
777 : {
778 12464 : varpool_node *alias_node;
779 :
780 12464 : gcc_assert (VAR_P (decl));
781 12464 : gcc_assert (VAR_P (alias));
782 12464 : alias_node = varpool_node::get_create (alias);
783 12464 : alias_node->alias = true;
784 12464 : alias_node->definition = true;
785 12464 : alias_node->semantic_interposition = flag_semantic_interposition;
786 12464 : alias_node->alias_target = decl;
787 12464 : if (lookup_attribute ("weakref", DECL_ATTRIBUTES (alias)) != NULL)
788 11 : alias_node->weakref = alias_node->transparent_alias = true;
789 12464 : return alias_node;
790 : }
791 :
792 : /* Attempt to mark ALIAS as an alias to DECL. Return TRUE if successful.
793 : Extra name aliases are output whenever DECL is output. */
794 :
795 : varpool_node *
796 54 : varpool_node::create_extra_name_alias (tree alias, tree decl)
797 : {
798 54 : varpool_node *alias_node;
799 :
800 : /* If aliases aren't supported by the assembler, fail. */
801 54 : if (!TARGET_SUPPORTS_ALIASES)
802 : return NULL;
803 :
804 54 : alias_node = varpool_node::create_alias (alias, decl);
805 54 : alias_node->cpp_implicit_alias = true;
806 :
807 : /* Extra name alias mechanism creates aliases really late
808 : via DECL_ASSEMBLER_NAME mechanism.
809 : This is unfortunate because they are not going through the
810 : standard channels. Ensure they get output. */
811 54 : if (symtab->cpp_implicit_aliases_done)
812 54 : alias_node->resolve_alias (varpool_node::get_create (decl));
813 54 : return alias_node;
814 : }
815 :
816 : /* Worker for call_for_symbol_and_aliases. */
817 :
818 : bool
819 6815 : varpool_node::call_for_symbol_and_aliases_1 (bool (*callback) (varpool_node *,
820 : void *),
821 : void *data,
822 : bool include_overwritable)
823 : {
824 6815 : ipa_ref *ref;
825 :
826 29549 : FOR_EACH_ALIAS (this, ref)
827 : {
828 22734 : varpool_node *alias = dyn_cast <varpool_node *> (ref->referring);
829 22734 : if (include_overwritable
830 22734 : || alias->get_availability () > AVAIL_INTERPOSABLE)
831 22734 : if (alias->call_for_symbol_and_aliases (callback, data,
832 : include_overwritable))
833 : return true;
834 : }
835 : return false;
836 : }
|