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 302295 : symbol_table::add_varpool_removal_hook (varpool_node_hook hook, void *data)
54 : {
55 302295 : varpool_node_hook_list *entry;
56 604590 : varpool_node_hook_list **ptr = &m_first_varpool_removal_hook;
57 :
58 302295 : entry = (varpool_node_hook_list *) xmalloc (sizeof (*entry));
59 302295 : entry->hook = hook;
60 302295 : entry->data = data;
61 302295 : entry->next = NULL;
62 310146 : while (*ptr)
63 7851 : ptr = &(*ptr)->next;
64 302295 : *ptr = entry;
65 302295 : return entry;
66 : }
67 :
68 : /* Remove ENTRY from the list of hooks called on removing nodes. */
69 : void
70 288888 : symbol_table::remove_varpool_removal_hook (varpool_node_hook_list *entry)
71 : {
72 288888 : varpool_node_hook_list **ptr = &m_first_varpool_removal_hook;
73 :
74 296509 : while (*ptr != entry)
75 7621 : ptr = &(*ptr)->next;
76 288888 : *ptr = entry->next;
77 288888 : free (entry);
78 288888 : }
79 :
80 : /* Call all node removal hooks. */
81 : void
82 32072240 : symbol_table::call_varpool_removal_hooks (varpool_node *node)
83 : {
84 32072240 : varpool_node_hook_list *entry = m_first_varpool_removal_hook;
85 39204728 : while (entry)
86 : {
87 7132488 : entry->hook (node, entry->data);
88 7132488 : entry = entry->next;
89 : }
90 32072240 : }
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 2378 : symbol_table::call_varpool_insertion_hooks (varpool_node *node)
124 : {
125 2378 : varpool_node_hook_list *entry = m_first_varpool_insertion_hook;
126 2378 : while (entry)
127 : {
128 0 : entry->hook (node, entry->data);
129 0 : entry = entry->next;
130 : }
131 2378 : }
132 :
133 : /* Allocate new callgraph node and insert it into basic data structures. */
134 :
135 : varpool_node *
136 35438544 : varpool_node::create_empty (void)
137 : {
138 35438544 : 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 254485026 : varpool_node::get_create (tree decl)
144 : {
145 254485026 : varpool_node *node = varpool_node::get (decl);
146 254485026 : gcc_checking_assert (VAR_P (decl));
147 254485026 : if (node)
148 : return node;
149 :
150 35368080 : node = varpool_node::create_empty ();
151 35368080 : node->decl = decl;
152 :
153 35329683 : if ((flag_openacc || flag_openmp)
154 35526804 : && lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl)))
155 : {
156 5070 : node->offloadable = 1;
157 5070 : 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 35368080 : node->register_symbol ();
166 35368080 : return node;
167 : }
168 :
169 : /* Remove variable from symbol table. */
170 :
171 : void
172 32072240 : varpool_node::remove (void)
173 : {
174 32072240 : symtab->call_varpool_removal_hooks (this);
175 32072240 : lto_free_function_in_decl_state_for_node (this);
176 :
177 : /* When streaming we can have multiple nodes associated with decl. */
178 32072240 : 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 61794352 : else if (DECL_INITIAL (decl) && DECL_INITIAL (decl) != error_mark_node
183 61792790 : && !ctor_useable_for_folding_p ())
184 3912 : remove_initializer ();
185 :
186 32072240 : unregister (NULL);
187 32072240 : ggc_free (this);
188 32072240 : }
189 :
190 : /* Remove node initializer when it is no longer needed. */
191 : void
192 1991811 : varpool_node::remove_initializer (void)
193 : {
194 1991811 : if (DECL_INITIAL (decl)
195 4449 : && !DECL_IN_CONSTANT_POOL (decl)
196 : /* Keep vtables for BINFO folding. */
197 4449 : && !DECL_VIRTUAL_P (decl)
198 : /* FIXME: http://gcc.gnu.org/PR55395 */
199 4228 : && 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 1994818 : && symtab->state != LTO_STREAMING)
205 3007 : DECL_INITIAL (decl) = error_mark_node;
206 1991811 : }
207 :
208 : /* Dump given varpool node to F. */
209 : void
210 2548 : varpool_node::dump (FILE *f)
211 : {
212 2548 : dump_base (f);
213 2548 : fprintf (f, " Availability: %s\n",
214 2548 : symtab->function_flags_ready
215 2422 : ? cgraph_availability_names[get_availability ()]
216 : : "not-ready");
217 2548 : fprintf (f, " Varpool flags:");
218 2548 : if (DECL_INITIAL (decl))
219 1516 : fprintf (f, " initialized");
220 2548 : if (output)
221 0 : fprintf (f, " output");
222 2548 : if (used_by_single_function)
223 43 : fprintf (f, " used-by-single-function");
224 2548 : if (TREE_READONLY (decl))
225 1442 : fprintf (f, " read-only");
226 2548 : if (ctor_useable_for_folding_p ())
227 1153 : fprintf (f, " const-value-known");
228 2548 : if (writeonly)
229 0 : fprintf (f, " write-only");
230 2548 : if (tls_model)
231 60 : fprintf (f, " tls-%s", tls_model_names [tls_model]);
232 2548 : fprintf (f, "\n");
233 2548 : }
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 7326597 : varpool_node::get_constructor (void)
276 : {
277 7326597 : lto_file_decl_data *file_data;
278 7326597 : const char *data, *name;
279 7326597 : size_t len;
280 :
281 7326597 : if (DECL_INITIAL (decl) != error_mark_node
282 7674 : || !in_lto_p
283 7334267 : || !lto_file_data)
284 7318927 : return DECL_INITIAL (decl);
285 :
286 7670 : timevar_push (TV_IPA_LTO_CTORS_IN);
287 :
288 7670 : file_data = lto_file_data;
289 7670 : name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
290 :
291 : /* We may have renamed the declaration, e.g., a static function. */
292 7670 : name = lto_get_decl_name_mapping (file_data, name);
293 7670 : struct lto_in_decl_state *decl_state
294 7670 : = lto_get_function_in_decl_state (file_data, decl);
295 :
296 15340 : data = lto_get_section_data (file_data, LTO_section_function_body,
297 7670 : name, order - file_data->order_base,
298 7670 : &len, decl_state->compressed);
299 7670 : 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 7670 : if (!quiet_flag)
305 0 : fprintf (stderr, " in:%s", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
306 7670 : lto_input_variable_constructor (file_data, this, data);
307 7670 : gcc_assert (DECL_INITIAL (decl) != error_mark_node);
308 7670 : lto_stats.num_function_bodies++;
309 7670 : lto_free_section_data (file_data, LTO_section_function_body, name,
310 7670 : data, len, decl_state->compressed);
311 7670 : lto_free_function_in_decl_state_for_node (this);
312 7670 : timevar_pop (TV_IPA_LTO_CTORS_IN);
313 7670 : return DECL_INITIAL (decl);
314 : }
315 :
316 : /* Return true if variable has constructor that can be used for folding. */
317 :
318 : bool
319 68798768 : varpool_node::ctor_useable_for_folding_p (void)
320 : {
321 68798768 : varpool_node *real_node = this;
322 :
323 68798768 : if (real_node->alias && real_node->definition)
324 248012 : real_node = ultimate_alias_target ();
325 :
326 68798768 : if (TREE_CODE (decl) == CONST_DECL
327 68798768 : || DECL_IN_CONSTANT_POOL (decl))
328 : return true;
329 68798236 : if (TREE_THIS_VOLATILE (decl))
330 : return false;
331 :
332 : /* Avoid attempts to load constructors that was not streamed. */
333 858687 : if (in_lto_p && DECL_INITIAL (real_node->decl) == error_mark_node
334 68832840 : && real_node->body_removed)
335 : return false;
336 :
337 : /* If we do not have a constructor, we can't use it. */
338 68760634 : if (DECL_INITIAL (real_node->decl) == error_mark_node
339 68760634 : && !real_node->lto_file_data)
340 : return false;
341 :
342 : /* Folding may cross TU boundaries. */
343 68760475 : 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 68760475 : 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 1248613 : 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 67511862 : 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 31057764 : if ((!DECL_INITIAL (real_node->decl)
374 30019469 : || (DECL_WEAK (decl) && !DECL_COMDAT (decl)))
375 31058370 : && ((DECL_EXTERNAL (decl) && !in_other_partition)
376 7120 : || decl_replaceable_p (decl, semantic_interposition)))
377 1032501 : 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 144624297 : ctor_for_folding (tree decl)
398 : {
399 144624297 : varpool_node *node, *real_node;
400 144624297 : tree real_decl;
401 :
402 144624297 : if (!VAR_P (decl) && TREE_CODE (decl) != CONST_DECL)
403 4406166 : return error_mark_node;
404 :
405 140218131 : if (TREE_CODE (decl) == CONST_DECL
406 140218131 : || DECL_IN_CONSTANT_POOL (decl))
407 85977 : return DECL_INITIAL (decl);
408 :
409 140132154 : if (TREE_THIS_VOLATILE (decl))
410 2160309 : return error_mark_node;
411 :
412 : /* Do not care about automatic variables. Those are never initialized
413 : anyway, because gimplifier expands the code. */
414 137971845 : if (!TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
415 : {
416 98095641 : gcc_assert (!TREE_PUBLIC (decl));
417 : /* Unless this is called during FE folding. */
418 98095641 : if (cfun
419 98090977 : && (cfun->curr_properties & (PROP_gimple | PROP_rtl)) == 0
420 5828415 : && TREE_READONLY (decl)
421 15284 : && !TREE_SIDE_EFFECTS (decl)
422 98110925 : && DECL_INITIAL (decl))
423 421 : return DECL_INITIAL (decl);
424 98095220 : return error_mark_node;
425 : }
426 :
427 39876204 : gcc_assert (VAR_P (decl));
428 :
429 39876204 : real_node = node = varpool_node::get (decl);
430 39876204 : if (node)
431 : {
432 39333964 : real_node = node->ultimate_alias_target ();
433 39333964 : 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 39876204 : if (decl != real_decl)
444 : {
445 247708 : gcc_assert (!DECL_INITIAL (decl)
446 : || (node->alias && node->get_alias_target () == real_node)
447 : || DECL_INITIAL (decl) == error_mark_node);
448 247708 : while (node->transparent_alias && node->analyzed)
449 : {
450 0 : node = node->get_alias_target ();
451 0 : decl = node->decl;
452 : }
453 : }
454 :
455 39876204 : if ((!DECL_VIRTUAL_P (real_decl)
456 641754 : || DECL_INITIAL (real_decl) == error_mark_node
457 641195 : || !DECL_INITIAL (real_decl))
458 39948498 : && (!node || !node->ctor_useable_for_folding_p ()))
459 37834422 : 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 2041782 : if (DECL_INITIAL (real_decl) != error_mark_node
464 2041782 : || !in_lto_p)
465 2040412 : return DECL_INITIAL (real_decl);
466 1370 : 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 2378 : varpool_node::add (tree decl)
475 : {
476 2378 : varpool_node *node;
477 2378 : varpool_node::finalize_decl (decl);
478 2378 : node = varpool_node::get_create (decl);
479 2378 : symtab->call_varpool_insertion_hooks (node);
480 2378 : if (node->externally_visible_p ())
481 2365 : node->externally_visible = true;
482 2378 : if (lookup_attribute ("no_reorder", DECL_ATTRIBUTES (decl)))
483 0 : node->no_reorder = 1;
484 2378 : }
485 :
486 : /* Return variable availability. See cgraph.h for description of individual
487 : return values. */
488 : enum availability
489 170724784 : varpool_node::get_availability (symtab_node *ref)
490 : {
491 170724784 : if (!definition && !in_other_partition)
492 : return AVAIL_NOT_AVAILABLE;
493 147504350 : if (!TREE_PUBLIC (decl))
494 : return AVAIL_AVAILABLE;
495 51874886 : if (DECL_IN_CONSTANT_POOL (decl)
496 51874886 : || DECL_VIRTUAL_P (decl))
497 : return AVAIL_AVAILABLE;
498 51816246 : 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 51816246 : || (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 51816246 : if (decl_replaceable_p (decl, semantic_interposition)
516 51816246 : || (DECL_EXTERNAL (decl) && !in_other_partition))
517 : return AVAIL_INTERPOSABLE;
518 : return AVAIL_AVAILABLE;
519 : }
520 :
521 : void
522 3066438 : 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 3066438 : if (!analyzed)
528 : {
529 3066438 : 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 3066438 : align_variable (decl, 0);
533 : }
534 3066438 : if (alias)
535 135 : resolve_alias (varpool_node::get (alias_target));
536 3066303 : else if (DECL_INITIAL (decl))
537 2008551 : record_references_in_initializer (decl, analyzed);
538 3066438 : analyzed = true;
539 3066438 : }
540 :
541 : /* Assemble thunks and aliases associated to varpool node. */
542 :
543 : void
544 2834819 : varpool_node::assemble_aliases (void)
545 : {
546 2834819 : ipa_ref *ref;
547 :
548 2839798 : FOR_EACH_ALIAS (this, ref)
549 : {
550 4979 : varpool_node *alias = dyn_cast <varpool_node *> (ref->referring);
551 4979 : if (alias->symver)
552 0 : do_assemble_symver (alias->decl,
553 : DECL_ASSEMBLER_NAME (decl));
554 4979 : else if (!alias->transparent_alias)
555 4979 : do_assemble_alias (alias->decl,
556 : DECL_ASSEMBLER_NAME (decl));
557 4979 : alias->assemble_aliases ();
558 : }
559 2834819 : }
560 :
561 : /* Output one variable, if necessary. Return whether we output it. */
562 :
563 : bool
564 2837329 : varpool_node::assemble_decl (void)
565 : {
566 : /* Aliases are output when their target is produced or by
567 : output_weakrefs. */
568 2837329 : if (alias)
569 : return false;
570 :
571 : /* Constant pool is output from RTL land when the reference
572 : survive till this level. */
573 2832347 : 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 2830020 : if (DECL_HAS_VALUE_EXPR_P (decl)
581 2830020 : && !targetm.have_tls)
582 : return false;
583 :
584 : /* Hard register vars do not need to be output. */
585 2830020 : if (DECL_HARD_REGISTER (decl))
586 : return false;
587 :
588 2830020 : gcc_checking_assert (!TREE_ASM_WRITTEN (decl)
589 : && VAR_P (decl)
590 : && !DECL_HAS_VALUE_EXPR_P (decl));
591 :
592 2830020 : if (!in_other_partition
593 2830020 : && !DECL_EXTERNAL (decl))
594 : {
595 2829840 : get_constructor ();
596 2829840 : assemble_variable (decl, 0, 1, 0);
597 2829840 : gcc_assert (TREE_ASM_WRITTEN (decl));
598 2829840 : gcc_assert (definition);
599 2829840 : 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 2829840 : debug_hooks->late_global_decl (decl);
604 2829840 : 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 4726494 : enqueue_node (varpool_node *node, varpool_node **first)
615 : {
616 4726494 : if (node->aux)
617 : return;
618 2832597 : gcc_checking_assert (*first);
619 2832597 : node->aux = *first;
620 2832597 : *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 232112 : symbol_table::remove_unreferenced_decls (void)
630 : {
631 232112 : varpool_node *next, *node;
632 232112 : varpool_node *first = (varpool_node *)(void *)1;
633 232112 : int i;
634 232112 : ipa_ref *ref = NULL;
635 232112 : hash_set<varpool_node *> referenced;
636 :
637 232112 : if (seen_error ())
638 0 : return;
639 :
640 232112 : if (dump_file)
641 72 : fprintf (dump_file, "Trivially needed variables:");
642 3121440 : FOR_EACH_DEFINED_VARIABLE (node)
643 : {
644 2889328 : if (node->analyzed
645 2889328 : && (!node->can_remove_if_no_refs_p ()
646 : /* We just expanded all function bodies. See if any of
647 : them needed the variable. */
648 1394321 : || DECL_RTL_SET_P (node->decl)))
649 : {
650 2220396 : enqueue_node (node, &first);
651 2220396 : if (dump_file)
652 59 : fprintf (dump_file, " %s", node->dump_asm_name ());
653 : }
654 : }
655 3064709 : while (first != (varpool_node *)(void *)1)
656 : {
657 2832597 : node = first;
658 2832597 : first = (varpool_node *)first->aux;
659 :
660 2832597 : 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 9367424 : for (i = 0; node->iterate_reference (i, ref); i++)
673 : {
674 3470118 : varpool_node *vnode = dyn_cast <varpool_node *> (ref->referred);
675 3470118 : if (vnode
676 2541645 : && !vnode->in_other_partition
677 2541638 : && (!DECL_EXTERNAL (ref->referred->decl)
678 245313 : || vnode->alias)
679 5766443 : && vnode->analyzed)
680 2296318 : enqueue_node (vnode, &first);
681 : else
682 : {
683 1173800 : if (vnode)
684 245327 : referenced.add (vnode);
685 1173800 : 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 232112 : if (dump_file)
695 72 : fprintf (dump_file, "\nRemoving variables:");
696 3121440 : for (node = first_defined_variable (); node; node = next)
697 : {
698 2889328 : next = next_defined_variable (node);
699 2889328 : if (!node->aux && !node->no_reorder)
700 : {
701 56730 : if (dump_file)
702 0 : fprintf (dump_file, " %s", node->dump_asm_name ());
703 56730 : if (referenced.contains(node))
704 0 : node->remove_initializer ();
705 : else
706 56730 : node->remove ();
707 : }
708 : }
709 :
710 232112 : if (dump_file)
711 72 : fprintf (dump_file, "\n");
712 232112 : }
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 2824867 : varpool_node::finalize_named_section_flags (void)
720 : {
721 2824867 : if (!TREE_ASM_WRITTEN (decl)
722 2822807 : && !alias
723 2817858 : && !in_other_partition
724 2817858 : && !DECL_EXTERNAL (decl)
725 2817822 : && VAR_P (decl)
726 2817822 : && !DECL_HAS_VALUE_EXPR_P (decl)
727 5642689 : && get_section ())
728 1432574 : get_variable_section (decl, false);
729 2824867 : }
730 :
731 : /* Output all variables enqueued to be assembled. */
732 : bool
733 232398 : symbol_table::output_variables (void)
734 : {
735 232398 : bool changed = false;
736 232398 : varpool_node *node;
737 :
738 232398 : if (seen_error ())
739 : return false;
740 :
741 232112 : remove_unreferenced_decls ();
742 :
743 232112 : timevar_push (TV_VAROUT);
744 :
745 3064710 : FOR_EACH_DEFINED_VARIABLE (node)
746 : {
747 : /* Handled in output_in_order. */
748 2832598 : if (node->no_reorder)
749 999354 : continue;
750 :
751 1833244 : node->finalize_named_section_flags ();
752 : }
753 :
754 : /* There is a similar loop in output_in_order. Please keep them in sync. */
755 3358833 : FOR_EACH_VARIABLE (node)
756 : {
757 : /* Handled in output_in_order. */
758 3126721 : if (node->no_reorder)
759 999996 : continue;
760 2126725 : if (DECL_HARD_REGISTER (node->decl)
761 2126725 : || DECL_HAS_VALUE_EXPR_P (node->decl))
762 62 : continue;
763 2126663 : if (node->definition)
764 1833182 : changed |= node->assemble_decl ();
765 : else
766 293481 : assemble_undefined_decl (node->decl);
767 : }
768 232112 : timevar_pop (TV_VAROUT);
769 232112 : 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 12497 : varpool_node::create_alias (tree alias, tree decl)
777 : {
778 12497 : varpool_node *alias_node;
779 :
780 12497 : gcc_assert (VAR_P (decl));
781 12497 : gcc_assert (VAR_P (alias));
782 12497 : alias_node = varpool_node::get_create (alias);
783 12497 : alias_node->alias = true;
784 12497 : alias_node->definition = true;
785 12497 : alias_node->semantic_interposition = flag_semantic_interposition;
786 12497 : alias_node->alias_target = decl;
787 12497 : if (lookup_attribute ("weakref", DECL_ATTRIBUTES (alias)) != NULL)
788 11 : alias_node->weakref = alias_node->transparent_alias = true;
789 12497 : 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 59 : varpool_node::create_extra_name_alias (tree alias, tree decl)
797 : {
798 59 : varpool_node *alias_node;
799 :
800 : /* If aliases aren't supported by the assembler, fail. */
801 59 : if (!TARGET_SUPPORTS_ALIASES)
802 : return NULL;
803 :
804 59 : alias_node = varpool_node::create_alias (alias, decl);
805 59 : 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 59 : if (symtab->cpp_implicit_aliases_done)
812 59 : alias_node->resolve_alias (varpool_node::get_create (decl));
813 59 : return alias_node;
814 : }
815 :
816 : /* Worker for call_for_symbol_and_aliases. */
817 :
818 : bool
819 6855 : varpool_node::call_for_symbol_and_aliases_1 (bool (*callback) (varpool_node *,
820 : void *),
821 : void *data,
822 : bool include_overwritable)
823 : {
824 6855 : ipa_ref *ref;
825 :
826 29645 : FOR_EACH_ALIAS (this, ref)
827 : {
828 22790 : varpool_node *alias = dyn_cast <varpool_node *> (ref->referring);
829 22790 : if (include_overwritable
830 22790 : || alias->get_availability () > AVAIL_INTERPOSABLE)
831 22790 : if (alias->call_for_symbol_and_aliases (callback, data,
832 : include_overwritable))
833 : return true;
834 : }
835 : return false;
836 : }
|