111
|
1 /* Symbol table.
|
131
|
2 Copyright (C) 2012-2018 Free Software Foundation, Inc.
|
111
|
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 "rtl.h"
|
|
27 #include "tree.h"
|
|
28 #include "gimple.h"
|
|
29 #include "timevar.h"
|
|
30 #include "cgraph.h"
|
|
31 #include "lto-streamer.h"
|
|
32 #include "print-tree.h"
|
|
33 #include "varasm.h"
|
|
34 #include "langhooks.h"
|
|
35 #include "output.h"
|
|
36 #include "ipa-utils.h"
|
|
37 #include "calls.h"
|
|
38 #include "stringpool.h"
|
|
39 #include "attribs.h"
|
131
|
40 #include "builtins.h"
|
111
|
41
|
131
|
42 static const char *ipa_ref_use_name[] = {"read","write","addr","alias"};
|
111
|
43
|
|
44 const char * const ld_plugin_symbol_resolution_names[]=
|
|
45 {
|
|
46 "",
|
|
47 "undef",
|
|
48 "prevailing_def",
|
|
49 "prevailing_def_ironly",
|
|
50 "preempted_reg",
|
|
51 "preempted_ir",
|
|
52 "resolved_ir",
|
|
53 "resolved_exec",
|
|
54 "resolved_dyn",
|
|
55 "prevailing_def_ironly_exp"
|
|
56 };
|
|
57
|
|
58 /* Follow the IDENTIFIER_TRANSPARENT_ALIAS chain starting at ALIAS
|
|
59 until we find an identifier that is not itself a transparent alias. */
|
|
60
|
|
61 static inline tree
|
|
62 ultimate_transparent_alias_target (tree alias)
|
|
63 {
|
|
64 tree target = alias;
|
|
65
|
|
66 while (IDENTIFIER_TRANSPARENT_ALIAS (target))
|
|
67 {
|
|
68 gcc_checking_assert (TREE_CHAIN (target));
|
|
69 target = TREE_CHAIN (target);
|
|
70 }
|
|
71 gcc_checking_assert (! IDENTIFIER_TRANSPARENT_ALIAS (target)
|
|
72 && ! TREE_CHAIN (target));
|
|
73
|
|
74 return target;
|
|
75 }
|
|
76
|
|
77
|
|
78 /* Hash asmnames ignoring the user specified marks. */
|
|
79
|
|
80 hashval_t
|
|
81 symbol_table::decl_assembler_name_hash (const_tree asmname)
|
|
82 {
|
|
83 if (IDENTIFIER_POINTER (asmname)[0] == '*')
|
|
84 {
|
|
85 const char *decl_str = IDENTIFIER_POINTER (asmname) + 1;
|
|
86 size_t ulp_len = strlen (user_label_prefix);
|
|
87
|
|
88 if (ulp_len == 0)
|
|
89 ;
|
|
90 else if (strncmp (decl_str, user_label_prefix, ulp_len) == 0)
|
|
91 decl_str += ulp_len;
|
|
92
|
|
93 return htab_hash_string (decl_str);
|
|
94 }
|
|
95
|
|
96 return htab_hash_string (IDENTIFIER_POINTER (asmname));
|
|
97 }
|
|
98
|
|
99 /* Return true if assembler names NAME1 and NAME2 leads to the same symbol
|
|
100 name. */
|
|
101
|
|
102 bool
|
|
103 symbol_table::assembler_names_equal_p (const char *name1, const char *name2)
|
|
104 {
|
|
105 if (name1 != name2)
|
|
106 {
|
|
107 if (name1[0] == '*')
|
|
108 {
|
|
109 size_t ulp_len = strlen (user_label_prefix);
|
|
110
|
|
111 name1 ++;
|
|
112
|
|
113 if (ulp_len == 0)
|
|
114 ;
|
|
115 else if (strncmp (name1, user_label_prefix, ulp_len) == 0)
|
|
116 name1 += ulp_len;
|
|
117 else
|
|
118 return false;
|
|
119 }
|
|
120 if (name2[0] == '*')
|
|
121 {
|
|
122 size_t ulp_len = strlen (user_label_prefix);
|
|
123
|
|
124 name2 ++;
|
|
125
|
|
126 if (ulp_len == 0)
|
|
127 ;
|
|
128 else if (strncmp (name2, user_label_prefix, ulp_len) == 0)
|
|
129 name2 += ulp_len;
|
|
130 else
|
|
131 return false;
|
|
132 }
|
|
133 return !strcmp (name1, name2);
|
|
134 }
|
|
135 return true;
|
|
136 }
|
|
137
|
|
138 /* Compare ASMNAME with the DECL_ASSEMBLER_NAME of DECL. */
|
|
139
|
|
140 bool
|
|
141 symbol_table::decl_assembler_name_equal (tree decl, const_tree asmname)
|
|
142 {
|
|
143 tree decl_asmname = DECL_ASSEMBLER_NAME (decl);
|
|
144 const char *decl_str;
|
|
145 const char *asmname_str;
|
|
146
|
|
147 if (decl_asmname == asmname)
|
|
148 return true;
|
|
149
|
|
150 decl_str = IDENTIFIER_POINTER (decl_asmname);
|
|
151 asmname_str = IDENTIFIER_POINTER (asmname);
|
|
152 return assembler_names_equal_p (decl_str, asmname_str);
|
|
153 }
|
|
154
|
|
155
|
|
156 /* Returns nonzero if P1 and P2 are equal. */
|
|
157
|
|
158 /* Insert NODE to assembler name hash. */
|
|
159
|
|
160 void
|
|
161 symbol_table::insert_to_assembler_name_hash (symtab_node *node,
|
|
162 bool with_clones)
|
|
163 {
|
|
164 if (is_a <varpool_node *> (node) && DECL_HARD_REGISTER (node->decl))
|
|
165 return;
|
|
166 gcc_checking_assert (!node->previous_sharing_asm_name
|
|
167 && !node->next_sharing_asm_name);
|
|
168 if (assembler_name_hash)
|
|
169 {
|
|
170 symtab_node **aslot;
|
|
171 cgraph_node *cnode;
|
|
172 tree decl = node->decl;
|
|
173
|
|
174 tree name = DECL_ASSEMBLER_NAME (node->decl);
|
|
175
|
|
176 /* C++ FE can produce decls without associated assembler name and insert
|
|
177 them to symtab to hold section or TLS information. */
|
|
178 if (!name)
|
|
179 return;
|
|
180
|
|
181 hashval_t hash = decl_assembler_name_hash (name);
|
|
182 aslot = assembler_name_hash->find_slot_with_hash (name, hash, INSERT);
|
|
183 gcc_assert (*aslot != node);
|
|
184 node->next_sharing_asm_name = (symtab_node *)*aslot;
|
|
185 if (*aslot != NULL)
|
|
186 (*aslot)->previous_sharing_asm_name = node;
|
|
187 *aslot = node;
|
|
188
|
|
189 /* Update also possible inline clones sharing a decl. */
|
|
190 cnode = dyn_cast <cgraph_node *> (node);
|
|
191 if (cnode && cnode->clones && with_clones)
|
|
192 for (cnode = cnode->clones; cnode; cnode = cnode->next_sibling_clone)
|
|
193 if (cnode->decl == decl)
|
|
194 insert_to_assembler_name_hash (cnode, true);
|
|
195 }
|
|
196
|
|
197 }
|
|
198
|
|
199 /* Remove NODE from assembler name hash. */
|
|
200
|
|
201 void
|
|
202 symbol_table::unlink_from_assembler_name_hash (symtab_node *node,
|
|
203 bool with_clones)
|
|
204 {
|
|
205 if (assembler_name_hash)
|
|
206 {
|
|
207 cgraph_node *cnode;
|
|
208 tree decl = node->decl;
|
|
209
|
|
210 if (node->next_sharing_asm_name)
|
|
211 node->next_sharing_asm_name->previous_sharing_asm_name
|
|
212 = node->previous_sharing_asm_name;
|
|
213 if (node->previous_sharing_asm_name)
|
|
214 {
|
|
215 node->previous_sharing_asm_name->next_sharing_asm_name
|
|
216 = node->next_sharing_asm_name;
|
|
217 }
|
|
218 else
|
|
219 {
|
|
220 tree name = DECL_ASSEMBLER_NAME (node->decl);
|
|
221 symtab_node **slot;
|
|
222
|
|
223 if (!name)
|
|
224 return;
|
|
225
|
|
226 hashval_t hash = decl_assembler_name_hash (name);
|
|
227 slot = assembler_name_hash->find_slot_with_hash (name, hash,
|
|
228 NO_INSERT);
|
|
229 gcc_assert (*slot == node);
|
|
230 if (!node->next_sharing_asm_name)
|
|
231 assembler_name_hash->clear_slot (slot);
|
|
232 else
|
|
233 *slot = node->next_sharing_asm_name;
|
|
234 }
|
|
235 node->next_sharing_asm_name = NULL;
|
|
236 node->previous_sharing_asm_name = NULL;
|
|
237
|
|
238 /* Update also possible inline clones sharing a decl. */
|
|
239 cnode = dyn_cast <cgraph_node *> (node);
|
|
240 if (cnode && cnode->clones && with_clones)
|
|
241 for (cnode = cnode->clones; cnode; cnode = cnode->next_sibling_clone)
|
|
242 if (cnode->decl == decl)
|
|
243 unlink_from_assembler_name_hash (cnode, true);
|
|
244 }
|
|
245 }
|
|
246
|
|
247 /* Arrange node to be first in its entry of assembler_name_hash. */
|
|
248
|
|
249 void
|
|
250 symbol_table::symtab_prevail_in_asm_name_hash (symtab_node *node)
|
|
251 {
|
|
252 unlink_from_assembler_name_hash (node, false);
|
|
253 insert_to_assembler_name_hash (node, false);
|
|
254 }
|
|
255
|
|
256 /* Initalize asm name hash unless. */
|
|
257
|
|
258 void
|
|
259 symbol_table::symtab_initialize_asm_name_hash (void)
|
|
260 {
|
|
261 symtab_node *node;
|
|
262 if (!assembler_name_hash)
|
|
263 {
|
|
264 assembler_name_hash = hash_table<asmname_hasher>::create_ggc (10);
|
|
265 FOR_EACH_SYMBOL (node)
|
|
266 insert_to_assembler_name_hash (node, false);
|
|
267 }
|
|
268 }
|
|
269
|
|
270 /* Set the DECL_ASSEMBLER_NAME and update symtab hashtables. */
|
|
271
|
|
272 void
|
|
273 symbol_table::change_decl_assembler_name (tree decl, tree name)
|
|
274 {
|
|
275 symtab_node *node = NULL;
|
|
276
|
|
277 /* We can have user ASM names on things, like global register variables, that
|
|
278 are not in the symbol table. */
|
|
279 if ((VAR_P (decl) && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
|
|
280 || TREE_CODE (decl) == FUNCTION_DECL)
|
|
281 node = symtab_node::get (decl);
|
|
282 if (!DECL_ASSEMBLER_NAME_SET_P (decl))
|
|
283 {
|
|
284 SET_DECL_ASSEMBLER_NAME (decl, name);
|
|
285 if (node)
|
|
286 insert_to_assembler_name_hash (node, true);
|
|
287 }
|
|
288 else
|
|
289 {
|
|
290 if (name == DECL_ASSEMBLER_NAME (decl))
|
|
291 return;
|
|
292
|
|
293 tree alias = (IDENTIFIER_TRANSPARENT_ALIAS (DECL_ASSEMBLER_NAME (decl))
|
|
294 ? TREE_CHAIN (DECL_ASSEMBLER_NAME (decl))
|
|
295 : NULL);
|
|
296 if (node)
|
|
297 unlink_from_assembler_name_hash (node, true);
|
|
298
|
|
299 const char *old_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
|
|
300 if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
|
|
301 && DECL_RTL_SET_P (decl))
|
|
302 warning (0, "%qD renamed after being referenced in assembly", decl);
|
|
303
|
|
304 SET_DECL_ASSEMBLER_NAME (decl, name);
|
|
305 if (alias)
|
|
306 {
|
|
307 IDENTIFIER_TRANSPARENT_ALIAS (name) = 1;
|
|
308 TREE_CHAIN (name) = alias;
|
|
309 }
|
|
310 /* If we change assembler name, also all transparent aliases must
|
|
311 be updated. There are three kinds - those having same assembler name,
|
|
312 those being renamed in varasm.c and weakref being renamed by the
|
|
313 assembler. */
|
|
314 if (node)
|
|
315 {
|
|
316 insert_to_assembler_name_hash (node, true);
|
|
317 ipa_ref *ref;
|
|
318 for (unsigned i = 0; node->iterate_direct_aliases (i, ref); i++)
|
|
319 {
|
|
320 struct symtab_node *alias = ref->referring;
|
|
321 if (alias->transparent_alias && !alias->weakref
|
|
322 && symbol_table::assembler_names_equal_p
|
|
323 (old_name, IDENTIFIER_POINTER (
|
|
324 DECL_ASSEMBLER_NAME (alias->decl))))
|
|
325 change_decl_assembler_name (alias->decl, name);
|
|
326 else if (alias->transparent_alias
|
|
327 && IDENTIFIER_TRANSPARENT_ALIAS (alias->decl))
|
|
328 {
|
|
329 gcc_assert (TREE_CHAIN (DECL_ASSEMBLER_NAME (alias->decl))
|
|
330 && IDENTIFIER_TRANSPARENT_ALIAS
|
|
331 (DECL_ASSEMBLER_NAME (alias->decl)));
|
|
332
|
|
333 TREE_CHAIN (DECL_ASSEMBLER_NAME (alias->decl)) =
|
|
334 ultimate_transparent_alias_target
|
|
335 (DECL_ASSEMBLER_NAME (node->decl));
|
|
336 }
|
|
337 #ifdef ASM_OUTPUT_WEAKREF
|
|
338 else gcc_assert (!alias->transparent_alias || alias->weakref);
|
|
339 #else
|
|
340 else gcc_assert (!alias->transparent_alias);
|
|
341 #endif
|
|
342 }
|
|
343 gcc_assert (!node->transparent_alias || !node->definition
|
|
344 || node->weakref
|
|
345 || TREE_CHAIN (DECL_ASSEMBLER_NAME (decl))
|
|
346 || symbol_table::assembler_names_equal_p
|
|
347 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)),
|
|
348 IDENTIFIER_POINTER
|
|
349 (DECL_ASSEMBLER_NAME
|
|
350 (node->get_alias_target ()->decl))));
|
|
351 }
|
|
352 }
|
|
353 }
|
|
354
|
|
355 /* Hash sections by their names. */
|
|
356
|
|
357 hashval_t
|
|
358 section_name_hasher::hash (section_hash_entry *n)
|
|
359 {
|
|
360 return htab_hash_string (n->name);
|
|
361 }
|
|
362
|
|
363 /* Return true if section P1 name equals to P2. */
|
|
364
|
|
365 bool
|
|
366 section_name_hasher::equal (section_hash_entry *n1, const char *name)
|
|
367 {
|
|
368 return n1->name == name || !strcmp (n1->name, name);
|
|
369 }
|
|
370
|
|
371 /* Add node into symbol table. This function is not used directly, but via
|
|
372 cgraph/varpool node creation routines. */
|
|
373
|
|
374 void
|
|
375 symtab_node::register_symbol (void)
|
|
376 {
|
|
377 symtab->register_symbol (this);
|
|
378
|
|
379 if (!decl->decl_with_vis.symtab_node)
|
|
380 decl->decl_with_vis.symtab_node = this;
|
|
381
|
|
382 ref_list.clear ();
|
|
383
|
|
384 /* Be sure to do this last; C++ FE might create new nodes via
|
|
385 DECL_ASSEMBLER_NAME langhook! */
|
|
386 symtab->insert_to_assembler_name_hash (this, false);
|
|
387 }
|
|
388
|
|
389 /* Remove NODE from same comdat group. */
|
|
390
|
|
391 void
|
|
392 symtab_node::remove_from_same_comdat_group (void)
|
|
393 {
|
|
394 if (same_comdat_group)
|
|
395 {
|
|
396 symtab_node *prev;
|
|
397 for (prev = same_comdat_group;
|
|
398 prev->same_comdat_group != this;
|
|
399 prev = prev->same_comdat_group)
|
|
400 ;
|
|
401 if (same_comdat_group == prev)
|
|
402 prev->same_comdat_group = NULL;
|
|
403 else
|
|
404 prev->same_comdat_group = same_comdat_group;
|
|
405 same_comdat_group = NULL;
|
|
406 set_comdat_group (NULL);
|
|
407 }
|
|
408 }
|
|
409
|
|
410 /* Remove node from symbol table. This function is not used directly, but via
|
|
411 cgraph/varpool node removal routines. */
|
|
412
|
|
413 void
|
|
414 symtab_node::unregister (void)
|
|
415 {
|
|
416 remove_all_references ();
|
|
417 remove_all_referring ();
|
|
418
|
|
419 /* Remove reference to section. */
|
|
420 set_section_for_node (NULL);
|
|
421
|
|
422 remove_from_same_comdat_group ();
|
|
423
|
|
424 symtab->unregister (this);
|
|
425
|
|
426 /* During LTO symtab merging we temporarily corrupt decl to symtab node
|
|
427 hash. */
|
|
428 gcc_assert (decl->decl_with_vis.symtab_node || in_lto_p);
|
|
429 if (decl->decl_with_vis.symtab_node == this)
|
|
430 {
|
|
431 symtab_node *replacement_node = NULL;
|
|
432 if (cgraph_node *cnode = dyn_cast <cgraph_node *> (this))
|
|
433 replacement_node = cnode->find_replacement ();
|
|
434 decl->decl_with_vis.symtab_node = replacement_node;
|
|
435 }
|
|
436 if (!is_a <varpool_node *> (this) || !DECL_HARD_REGISTER (decl))
|
|
437 symtab->unlink_from_assembler_name_hash (this, false);
|
|
438 if (in_init_priority_hash)
|
|
439 symtab->init_priority_hash->remove (this);
|
|
440 }
|
|
441
|
|
442
|
|
443 /* Remove symbol from symbol table. */
|
|
444
|
|
445 void
|
|
446 symtab_node::remove (void)
|
|
447 {
|
|
448 if (cgraph_node *cnode = dyn_cast <cgraph_node *> (this))
|
|
449 cnode->remove ();
|
|
450 else if (varpool_node *vnode = dyn_cast <varpool_node *> (this))
|
|
451 vnode->remove ();
|
|
452 }
|
|
453
|
|
454 /* Add NEW_ to the same comdat group that OLD is in. */
|
|
455
|
|
456 void
|
|
457 symtab_node::add_to_same_comdat_group (symtab_node *old_node)
|
|
458 {
|
|
459 gcc_assert (old_node->get_comdat_group ());
|
|
460 gcc_assert (!same_comdat_group);
|
|
461 gcc_assert (this != old_node);
|
|
462
|
|
463 set_comdat_group (old_node->get_comdat_group ());
|
|
464 same_comdat_group = old_node;
|
|
465 if (!old_node->same_comdat_group)
|
|
466 old_node->same_comdat_group = this;
|
|
467 else
|
|
468 {
|
|
469 symtab_node *n;
|
|
470 for (n = old_node->same_comdat_group;
|
|
471 n->same_comdat_group != old_node;
|
|
472 n = n->same_comdat_group)
|
|
473 ;
|
|
474 n->same_comdat_group = this;
|
|
475 }
|
|
476 }
|
|
477
|
|
478 /* Dissolve the same_comdat_group list in which NODE resides. */
|
|
479
|
|
480 void
|
|
481 symtab_node::dissolve_same_comdat_group_list (void)
|
|
482 {
|
|
483 symtab_node *n = this;
|
|
484 symtab_node *next;
|
|
485
|
|
486 if (!same_comdat_group)
|
|
487 return;
|
|
488 do
|
|
489 {
|
|
490 next = n->same_comdat_group;
|
|
491 n->same_comdat_group = NULL;
|
|
492 /* Clear comdat_group for comdat locals, since
|
|
493 make_decl_local doesn't. */
|
|
494 if (!TREE_PUBLIC (n->decl))
|
|
495 n->set_comdat_group (NULL);
|
|
496 n = next;
|
|
497 }
|
|
498 while (n != this);
|
|
499 }
|
|
500
|
|
501 /* Return printable assembler name of NODE.
|
|
502 This function is used only for debugging. When assembler name
|
|
503 is unknown go with identifier name. */
|
|
504
|
|
505 const char *
|
|
506 symtab_node::asm_name () const
|
|
507 {
|
|
508 if (!DECL_ASSEMBLER_NAME_SET_P (decl))
|
|
509 return name ();
|
|
510 return IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
|
|
511 }
|
|
512
|
|
513 /* Return printable identifier name. */
|
|
514
|
|
515 const char *
|
|
516 symtab_node::name () const
|
|
517 {
|
|
518 if (!DECL_NAME (decl))
|
|
519 {
|
|
520 if (DECL_ASSEMBLER_NAME_SET_P (decl))
|
|
521 return asm_name ();
|
|
522 else
|
|
523 return "<unnamed>";
|
|
524 }
|
|
525 return lang_hooks.decl_printable_name (decl, 2);
|
|
526 }
|
|
527
|
|
528 const char *
|
|
529 symtab_node::get_dump_name (bool asm_name_p) const
|
|
530 {
|
|
531 #define EXTRA 16
|
|
532 const char *fname = asm_name_p ? asm_name () : name ();
|
|
533 unsigned l = strlen (fname);
|
|
534
|
|
535 char *s = (char *)ggc_internal_cleared_alloc (l + EXTRA);
|
|
536 snprintf (s, l + EXTRA, "%s/%d", fname, order);
|
|
537
|
|
538 return s;
|
|
539 }
|
|
540
|
|
541 const char *
|
|
542 symtab_node::dump_name () const
|
|
543 {
|
|
544 return get_dump_name (false);
|
|
545 }
|
|
546
|
|
547 const char *
|
|
548 symtab_node::dump_asm_name () const
|
|
549 {
|
|
550 return get_dump_name (true);
|
|
551 }
|
|
552
|
|
553 /* Return ipa reference from this symtab_node to
|
|
554 REFERED_NODE or REFERED_VARPOOL_NODE. USE_TYPE specify type
|
|
555 of the use. */
|
|
556
|
|
557 ipa_ref *
|
|
558 symtab_node::create_reference (symtab_node *referred_node,
|
|
559 enum ipa_ref_use use_type)
|
|
560 {
|
|
561 return create_reference (referred_node, use_type, NULL);
|
|
562 }
|
|
563
|
|
564
|
|
565 /* Return ipa reference from this symtab_node to
|
|
566 REFERED_NODE or REFERED_VARPOOL_NODE. USE_TYPE specify type
|
|
567 of the use and STMT the statement (if it exists). */
|
|
568
|
|
569 ipa_ref *
|
|
570 symtab_node::create_reference (symtab_node *referred_node,
|
|
571 enum ipa_ref_use use_type, gimple *stmt)
|
|
572 {
|
|
573 ipa_ref *ref = NULL, *ref2 = NULL;
|
|
574 ipa_ref_list *list, *list2;
|
|
575 ipa_ref_t *old_references;
|
|
576
|
|
577 gcc_checking_assert (!stmt || is_a <cgraph_node *> (this));
|
|
578 gcc_checking_assert (use_type != IPA_REF_ALIAS || !stmt);
|
|
579
|
|
580 list = &ref_list;
|
|
581 old_references = vec_safe_address (list->references);
|
|
582 vec_safe_grow (list->references, vec_safe_length (list->references) + 1);
|
|
583 ref = &list->references->last ();
|
|
584
|
|
585 list2 = &referred_node->ref_list;
|
|
586
|
|
587 /* IPA_REF_ALIAS is always inserted at the beginning of the list. */
|
|
588 if(use_type == IPA_REF_ALIAS)
|
|
589 {
|
|
590 list2->referring.safe_insert (0, ref);
|
|
591 ref->referred_index = 0;
|
|
592
|
|
593 for (unsigned int i = 1; i < list2->referring.length (); i++)
|
|
594 list2->referring[i]->referred_index = i;
|
|
595 }
|
|
596 else
|
|
597 {
|
|
598 list2->referring.safe_push (ref);
|
|
599 ref->referred_index = list2->referring.length () - 1;
|
|
600 }
|
|
601
|
|
602 ref->referring = this;
|
|
603 ref->referred = referred_node;
|
|
604 ref->stmt = stmt;
|
|
605 ref->lto_stmt_uid = 0;
|
|
606 ref->use = use_type;
|
|
607 ref->speculative = 0;
|
|
608
|
|
609 /* If vector was moved in memory, update pointers. */
|
|
610 if (old_references != list->references->address ())
|
|
611 {
|
|
612 int i;
|
|
613 for (i = 0; iterate_reference(i, ref2); i++)
|
|
614 ref2->referred_ref_list ()->referring[ref2->referred_index] = ref2;
|
|
615 }
|
|
616 return ref;
|
|
617 }
|
|
618
|
|
619 ipa_ref *
|
|
620 symtab_node::maybe_create_reference (tree val, gimple *stmt)
|
|
621 {
|
|
622 STRIP_NOPS (val);
|
|
623 ipa_ref_use use_type;
|
|
624
|
|
625 switch (TREE_CODE (val))
|
|
626 {
|
|
627 case VAR_DECL:
|
|
628 use_type = IPA_REF_LOAD;
|
|
629 break;
|
|
630 case ADDR_EXPR:
|
|
631 use_type = IPA_REF_ADDR;
|
|
632 break;
|
|
633 default:
|
|
634 gcc_assert (!handled_component_p (val));
|
|
635 return NULL;
|
|
636 }
|
|
637
|
|
638 val = get_base_var (val);
|
|
639 if (val && VAR_OR_FUNCTION_DECL_P (val))
|
|
640 {
|
|
641 symtab_node *referred = symtab_node::get (val);
|
|
642 gcc_checking_assert (referred);
|
|
643 return create_reference (referred, use_type, stmt);
|
|
644 }
|
|
645 return NULL;
|
|
646 }
|
|
647
|
|
648 /* Clone all references from symtab NODE to this symtab_node. */
|
|
649
|
|
650 void
|
|
651 symtab_node::clone_references (symtab_node *node)
|
|
652 {
|
|
653 ipa_ref *ref = NULL, *ref2 = NULL;
|
|
654 int i;
|
|
655 for (i = 0; node->iterate_reference (i, ref); i++)
|
|
656 {
|
|
657 bool speculative = ref->speculative;
|
|
658 unsigned int stmt_uid = ref->lto_stmt_uid;
|
|
659
|
|
660 ref2 = create_reference (ref->referred, ref->use, ref->stmt);
|
|
661 ref2->speculative = speculative;
|
|
662 ref2->lto_stmt_uid = stmt_uid;
|
|
663 }
|
|
664 }
|
|
665
|
|
666 /* Clone all referring from symtab NODE to this symtab_node. */
|
|
667
|
|
668 void
|
|
669 symtab_node::clone_referring (symtab_node *node)
|
|
670 {
|
|
671 ipa_ref *ref = NULL, *ref2 = NULL;
|
|
672 int i;
|
|
673 for (i = 0; node->iterate_referring(i, ref); i++)
|
|
674 {
|
|
675 bool speculative = ref->speculative;
|
|
676 unsigned int stmt_uid = ref->lto_stmt_uid;
|
|
677
|
|
678 ref2 = ref->referring->create_reference (this, ref->use, ref->stmt);
|
|
679 ref2->speculative = speculative;
|
|
680 ref2->lto_stmt_uid = stmt_uid;
|
|
681 }
|
|
682 }
|
|
683
|
|
684 /* Clone reference REF to this symtab_node and set its stmt to STMT. */
|
|
685
|
|
686 ipa_ref *
|
|
687 symtab_node::clone_reference (ipa_ref *ref, gimple *stmt)
|
|
688 {
|
|
689 bool speculative = ref->speculative;
|
|
690 unsigned int stmt_uid = ref->lto_stmt_uid;
|
|
691 ipa_ref *ref2;
|
|
692
|
|
693 ref2 = create_reference (ref->referred, ref->use, stmt);
|
|
694 ref2->speculative = speculative;
|
|
695 ref2->lto_stmt_uid = stmt_uid;
|
|
696 return ref2;
|
|
697 }
|
|
698
|
|
699 /* Find the structure describing a reference to REFERRED_NODE
|
|
700 and associated with statement STMT. */
|
|
701
|
|
702 ipa_ref *
|
|
703 symtab_node::find_reference (symtab_node *referred_node,
|
|
704 gimple *stmt, unsigned int lto_stmt_uid)
|
|
705 {
|
|
706 ipa_ref *r = NULL;
|
|
707 int i;
|
|
708
|
|
709 for (i = 0; iterate_reference (i, r); i++)
|
|
710 if (r->referred == referred_node
|
|
711 && !r->speculative
|
|
712 && ((stmt && r->stmt == stmt)
|
|
713 || (lto_stmt_uid && r->lto_stmt_uid == lto_stmt_uid)
|
|
714 || (!stmt && !lto_stmt_uid && !r->stmt && !r->lto_stmt_uid)))
|
|
715 return r;
|
|
716 return NULL;
|
|
717 }
|
|
718
|
|
719 /* Remove all references that are associated with statement STMT. */
|
|
720
|
|
721 void
|
|
722 symtab_node::remove_stmt_references (gimple *stmt)
|
|
723 {
|
|
724 ipa_ref *r = NULL;
|
|
725 int i = 0;
|
|
726
|
|
727 while (iterate_reference (i, r))
|
|
728 if (r->stmt == stmt)
|
|
729 r->remove_reference ();
|
|
730 else
|
|
731 i++;
|
|
732 }
|
|
733
|
|
734 /* Remove all stmt references in non-speculative references.
|
|
735 Those are not maintained during inlining & clonning.
|
|
736 The exception are speculative references that are updated along
|
|
737 with callgraph edges associated with them. */
|
|
738
|
|
739 void
|
|
740 symtab_node::clear_stmts_in_references (void)
|
|
741 {
|
|
742 ipa_ref *r = NULL;
|
|
743 int i;
|
|
744
|
|
745 for (i = 0; iterate_reference (i, r); i++)
|
|
746 if (!r->speculative)
|
|
747 {
|
|
748 r->stmt = NULL;
|
|
749 r->lto_stmt_uid = 0;
|
|
750 }
|
|
751 }
|
|
752
|
|
753 /* Remove all references in ref list. */
|
|
754
|
|
755 void
|
|
756 symtab_node::remove_all_references (void)
|
|
757 {
|
|
758 while (vec_safe_length (ref_list.references))
|
|
759 ref_list.references->last ().remove_reference ();
|
|
760 vec_free (ref_list.references);
|
|
761 }
|
|
762
|
|
763 /* Remove all referring items in ref list. */
|
|
764
|
|
765 void
|
|
766 symtab_node::remove_all_referring (void)
|
|
767 {
|
|
768 while (ref_list.referring.length ())
|
|
769 ref_list.referring.last ()->remove_reference ();
|
|
770 ref_list.referring.release ();
|
|
771 }
|
|
772
|
|
773 /* Dump references in ref list to FILE. */
|
|
774
|
|
775 void
|
|
776 symtab_node::dump_references (FILE *file)
|
|
777 {
|
|
778 ipa_ref *ref = NULL;
|
|
779 int i;
|
|
780 for (i = 0; iterate_reference (i, ref); i++)
|
|
781 {
|
|
782 fprintf (file, "%s (%s)",
|
|
783 ref->referred->dump_asm_name (),
|
|
784 ipa_ref_use_name [ref->use]);
|
|
785 if (ref->speculative)
|
|
786 fprintf (file, " (speculative)");
|
|
787 }
|
|
788 fprintf (file, "\n");
|
|
789 }
|
|
790
|
|
791 /* Dump referring in list to FILE. */
|
|
792
|
|
793 void
|
|
794 symtab_node::dump_referring (FILE *file)
|
|
795 {
|
|
796 ipa_ref *ref = NULL;
|
|
797 int i;
|
|
798 for (i = 0; iterate_referring(i, ref); i++)
|
|
799 {
|
|
800 fprintf (file, "%s (%s)",
|
|
801 ref->referring->dump_asm_name (),
|
|
802 ipa_ref_use_name [ref->use]);
|
|
803 if (ref->speculative)
|
|
804 fprintf (file, " (speculative)");
|
|
805 }
|
|
806 fprintf (file, "\n");
|
|
807 }
|
|
808
|
|
809 static const char * const symtab_type_names[] = {"symbol", "function", "variable"};
|
|
810
|
|
811 /* Dump base fields of symtab nodes to F. Not to be used directly. */
|
|
812
|
|
813 void
|
|
814 symtab_node::dump_base (FILE *f)
|
|
815 {
|
|
816 static const char * const visibility_types[] = {
|
|
817 "default", "protected", "hidden", "internal"
|
|
818 };
|
|
819
|
|
820 fprintf (f, "%s (%s)", dump_asm_name (), name ());
|
|
821 dump_addr (f, " @", (void *)this);
|
|
822 fprintf (f, "\n Type: %s", symtab_type_names[type]);
|
|
823
|
|
824 if (definition)
|
|
825 fprintf (f, " definition");
|
|
826 if (analyzed)
|
|
827 fprintf (f, " analyzed");
|
|
828 if (alias)
|
|
829 fprintf (f, " alias");
|
|
830 if (transparent_alias)
|
|
831 fprintf (f, " transparent_alias");
|
|
832 if (weakref)
|
|
833 fprintf (f, " weakref");
|
|
834 if (cpp_implicit_alias)
|
|
835 fprintf (f, " cpp_implicit_alias");
|
|
836 if (alias_target)
|
|
837 fprintf (f, " target:%s",
|
|
838 DECL_P (alias_target)
|
|
839 ? IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME
|
|
840 (alias_target))
|
|
841 : IDENTIFIER_POINTER (alias_target));
|
|
842 if (body_removed)
|
|
843 fprintf (f, "\n Body removed by symtab_remove_unreachable_nodes");
|
|
844 fprintf (f, "\n Visibility:");
|
|
845 if (in_other_partition)
|
|
846 fprintf (f, " in_other_partition");
|
|
847 if (used_from_other_partition)
|
|
848 fprintf (f, " used_from_other_partition");
|
|
849 if (force_output)
|
|
850 fprintf (f, " force_output");
|
|
851 if (forced_by_abi)
|
|
852 fprintf (f, " forced_by_abi");
|
|
853 if (externally_visible)
|
|
854 fprintf (f, " externally_visible");
|
|
855 if (no_reorder)
|
|
856 fprintf (f, " no_reorder");
|
|
857 if (resolution != LDPR_UNKNOWN)
|
|
858 fprintf (f, " %s",
|
|
859 ld_plugin_symbol_resolution_names[(int)resolution]);
|
|
860 if (TREE_ASM_WRITTEN (decl))
|
|
861 fprintf (f, " asm_written");
|
|
862 if (DECL_EXTERNAL (decl))
|
|
863 fprintf (f, " external");
|
|
864 if (TREE_PUBLIC (decl))
|
|
865 fprintf (f, " public");
|
|
866 if (DECL_COMMON (decl))
|
|
867 fprintf (f, " common");
|
|
868 if (DECL_WEAK (decl))
|
|
869 fprintf (f, " weak");
|
|
870 if (DECL_DLLIMPORT_P (decl))
|
|
871 fprintf (f, " dll_import");
|
|
872 if (DECL_COMDAT (decl))
|
|
873 fprintf (f, " comdat");
|
|
874 if (get_comdat_group ())
|
|
875 fprintf (f, " comdat_group:%s",
|
|
876 IDENTIFIER_POINTER (get_comdat_group_id ()));
|
|
877 if (DECL_ONE_ONLY (decl))
|
|
878 fprintf (f, " one_only");
|
|
879 if (get_section ())
|
|
880 fprintf (f, " section:%s",
|
|
881 get_section ());
|
|
882 if (implicit_section)
|
|
883 fprintf (f," (implicit_section)");
|
|
884 if (DECL_VISIBILITY_SPECIFIED (decl))
|
|
885 fprintf (f, " visibility_specified");
|
|
886 if (DECL_VISIBILITY (decl))
|
|
887 fprintf (f, " visibility:%s",
|
|
888 visibility_types [DECL_VISIBILITY (decl)]);
|
|
889 if (DECL_VIRTUAL_P (decl))
|
|
890 fprintf (f, " virtual");
|
|
891 if (DECL_ARTIFICIAL (decl))
|
|
892 fprintf (f, " artificial");
|
|
893 if (TREE_CODE (decl) == FUNCTION_DECL)
|
|
894 {
|
|
895 if (DECL_STATIC_CONSTRUCTOR (decl))
|
|
896 fprintf (f, " constructor");
|
|
897 if (DECL_STATIC_DESTRUCTOR (decl))
|
|
898 fprintf (f, " destructor");
|
|
899 }
|
|
900 fprintf (f, "\n");
|
|
901
|
|
902 if (same_comdat_group)
|
|
903 fprintf (f, " Same comdat group as: %s\n",
|
|
904 same_comdat_group->dump_asm_name ());
|
|
905 if (next_sharing_asm_name)
|
|
906 fprintf (f, " next sharing asm name: %i\n",
|
|
907 next_sharing_asm_name->order);
|
|
908 if (previous_sharing_asm_name)
|
|
909 fprintf (f, " previous sharing asm name: %i\n",
|
|
910 previous_sharing_asm_name->order);
|
|
911
|
|
912 if (address_taken)
|
|
913 fprintf (f, " Address is taken.\n");
|
|
914 if (aux)
|
|
915 {
|
|
916 fprintf (f, " Aux:");
|
|
917 dump_addr (f, " @", (void *)aux);
|
|
918 fprintf (f, "\n");
|
|
919 }
|
|
920
|
|
921 fprintf (f, " References: ");
|
|
922 dump_references (f);
|
|
923 fprintf (f, " Referring: ");
|
|
924 dump_referring (f);
|
|
925 if (lto_file_data)
|
|
926 fprintf (f, " Read from file: %s\n",
|
|
927 lto_file_data->file_name);
|
|
928 }
|
|
929
|
|
930 /* Dump symtab node to F. */
|
|
931
|
|
932 void
|
|
933 symtab_node::dump (FILE *f)
|
|
934 {
|
|
935 if (cgraph_node *cnode = dyn_cast <cgraph_node *> (this))
|
|
936 cnode->dump (f);
|
|
937 else if (varpool_node *vnode = dyn_cast <varpool_node *> (this))
|
|
938 vnode->dump (f);
|
|
939 }
|
|
940
|
|
941 void
|
|
942 symbol_table::dump (FILE *f)
|
|
943 {
|
|
944 symtab_node *node;
|
|
945 fprintf (f, "Symbol table:\n\n");
|
|
946 FOR_EACH_SYMBOL (node)
|
|
947 node->dump (f);
|
|
948 }
|
|
949
|
131
|
950 DEBUG_FUNCTION void
|
|
951 symbol_table::debug (void)
|
|
952 {
|
|
953 dump (stderr);
|
|
954 }
|
|
955
|
111
|
956 /* Return the cgraph node that has ASMNAME for its DECL_ASSEMBLER_NAME.
|
|
957 Return NULL if there's no such node. */
|
|
958
|
|
959 symtab_node *
|
|
960 symtab_node::get_for_asmname (const_tree asmname)
|
|
961 {
|
|
962 symtab_node *node;
|
|
963
|
|
964 symtab->symtab_initialize_asm_name_hash ();
|
|
965 hashval_t hash = symtab->decl_assembler_name_hash (asmname);
|
|
966 symtab_node **slot
|
|
967 = symtab->assembler_name_hash->find_slot_with_hash (asmname, hash,
|
|
968 NO_INSERT);
|
|
969
|
|
970 if (slot)
|
|
971 {
|
|
972 node = *slot;
|
|
973 return node;
|
|
974 }
|
|
975 return NULL;
|
|
976 }
|
|
977
|
|
978 /* Dump symtab node NODE to stderr. */
|
|
979
|
|
980 DEBUG_FUNCTION void
|
|
981 symtab_node::debug (void)
|
|
982 {
|
|
983 dump (stderr);
|
|
984 }
|
|
985
|
|
986 /* Verify common part of symtab nodes. */
|
|
987
|
|
988 DEBUG_FUNCTION bool
|
|
989 symtab_node::verify_base (void)
|
|
990 {
|
|
991 bool error_found = false;
|
|
992 symtab_node *hashed_node;
|
|
993
|
|
994 if (is_a <cgraph_node *> (this))
|
|
995 {
|
|
996 if (TREE_CODE (decl) != FUNCTION_DECL)
|
|
997 {
|
|
998 error ("function symbol is not function");
|
|
999 error_found = true;
|
|
1000 }
|
131
|
1001 else if ((lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl))
|
|
1002 != NULL)
|
|
1003 != dyn_cast <cgraph_node *> (this)->ifunc_resolver)
|
|
1004 {
|
|
1005 error ("inconsistent `ifunc' attribute");
|
|
1006 error_found = true;
|
|
1007 }
|
111
|
1008 }
|
|
1009 else if (is_a <varpool_node *> (this))
|
|
1010 {
|
|
1011 if (!VAR_P (decl))
|
|
1012 {
|
|
1013 error ("variable symbol is not variable");
|
|
1014 error_found = true;
|
|
1015 }
|
|
1016 }
|
|
1017 else
|
|
1018 {
|
|
1019 error ("node has unknown type");
|
|
1020 error_found = true;
|
|
1021 }
|
|
1022
|
|
1023 if (symtab->state != LTO_STREAMING)
|
|
1024 {
|
|
1025 hashed_node = symtab_node::get (decl);
|
|
1026 if (!hashed_node)
|
|
1027 {
|
|
1028 error ("node not found node->decl->decl_with_vis.symtab_node");
|
|
1029 error_found = true;
|
|
1030 }
|
|
1031 if (hashed_node != this
|
|
1032 && (!is_a <cgraph_node *> (this)
|
|
1033 || !dyn_cast <cgraph_node *> (this)->clone_of
|
|
1034 || dyn_cast <cgraph_node *> (this)->clone_of->decl != decl))
|
|
1035 {
|
|
1036 error ("node differs from node->decl->decl_with_vis.symtab_node");
|
|
1037 error_found = true;
|
|
1038 }
|
|
1039 }
|
|
1040 if (symtab->assembler_name_hash)
|
|
1041 {
|
|
1042 hashed_node = symtab_node::get_for_asmname (DECL_ASSEMBLER_NAME (decl));
|
|
1043 if (hashed_node && hashed_node->previous_sharing_asm_name)
|
|
1044 {
|
|
1045 error ("assembler name hash list corrupted");
|
|
1046 error_found = true;
|
|
1047 }
|
|
1048 while (hashed_node)
|
|
1049 {
|
|
1050 if (hashed_node == this)
|
|
1051 break;
|
|
1052 hashed_node = hashed_node->next_sharing_asm_name;
|
|
1053 }
|
|
1054 if (!hashed_node
|
|
1055 && !(is_a <varpool_node *> (this)
|
|
1056 && DECL_HARD_REGISTER (decl)))
|
|
1057 {
|
|
1058 error ("node not found in symtab assembler name hash");
|
|
1059 error_found = true;
|
|
1060 }
|
|
1061 }
|
|
1062 if (previous_sharing_asm_name
|
|
1063 && previous_sharing_asm_name->next_sharing_asm_name != this)
|
|
1064 {
|
|
1065 error ("double linked list of assembler names corrupted");
|
|
1066 error_found = true;
|
|
1067 }
|
|
1068 if (body_removed && definition)
|
|
1069 {
|
|
1070 error ("node has body_removed but is definition");
|
|
1071 error_found = true;
|
|
1072 }
|
|
1073 if (analyzed && !definition)
|
|
1074 {
|
|
1075 error ("node is analyzed but it is not a definition");
|
|
1076 error_found = true;
|
|
1077 }
|
|
1078 if (cpp_implicit_alias && !alias)
|
|
1079 {
|
|
1080 error ("node is alias but not implicit alias");
|
|
1081 error_found = true;
|
|
1082 }
|
|
1083 if (alias && !definition && !weakref)
|
|
1084 {
|
|
1085 error ("node is alias but not definition");
|
|
1086 error_found = true;
|
|
1087 }
|
|
1088 if (weakref && !transparent_alias)
|
|
1089 {
|
|
1090 error ("node is weakref but not an transparent_alias");
|
|
1091 error_found = true;
|
|
1092 }
|
|
1093 if (transparent_alias && !alias)
|
|
1094 {
|
|
1095 error ("node is transparent_alias but not an alias");
|
|
1096 error_found = true;
|
|
1097 }
|
|
1098 if (same_comdat_group)
|
|
1099 {
|
|
1100 symtab_node *n = same_comdat_group;
|
|
1101
|
|
1102 if (!n->get_comdat_group ())
|
|
1103 {
|
|
1104 error ("node is in same_comdat_group list but has no comdat_group");
|
|
1105 error_found = true;
|
|
1106 }
|
|
1107 if (n->get_comdat_group () != get_comdat_group ())
|
|
1108 {
|
|
1109 error ("same_comdat_group list across different groups");
|
|
1110 error_found = true;
|
|
1111 }
|
|
1112 if (n->type != type)
|
|
1113 {
|
|
1114 error ("mixing different types of symbol in same comdat groups is not supported");
|
|
1115 error_found = true;
|
|
1116 }
|
|
1117 if (n == this)
|
|
1118 {
|
|
1119 error ("node is alone in a comdat group");
|
|
1120 error_found = true;
|
|
1121 }
|
|
1122 do
|
|
1123 {
|
|
1124 if (!n->same_comdat_group)
|
|
1125 {
|
|
1126 error ("same_comdat_group is not a circular list");
|
|
1127 error_found = true;
|
|
1128 break;
|
|
1129 }
|
|
1130 n = n->same_comdat_group;
|
|
1131 }
|
|
1132 while (n != this);
|
|
1133 if (comdat_local_p ())
|
|
1134 {
|
|
1135 ipa_ref *ref = NULL;
|
|
1136
|
|
1137 for (int i = 0; iterate_referring (i, ref); ++i)
|
|
1138 {
|
|
1139 if (!in_same_comdat_group_p (ref->referring))
|
|
1140 {
|
|
1141 error ("comdat-local symbol referred to by %s outside its "
|
|
1142 "comdat",
|
|
1143 identifier_to_locale (ref->referring->name()));
|
|
1144 error_found = true;
|
|
1145 }
|
|
1146 }
|
|
1147 }
|
|
1148 }
|
|
1149 if (implicit_section && !get_section ())
|
|
1150 {
|
|
1151 error ("implicit_section flag is set but section isn't");
|
|
1152 error_found = true;
|
|
1153 }
|
|
1154 if (get_section () && get_comdat_group ()
|
|
1155 && !implicit_section
|
|
1156 && !lookup_attribute ("section", DECL_ATTRIBUTES (decl)))
|
|
1157 {
|
|
1158 error ("Both section and comdat group is set");
|
|
1159 error_found = true;
|
|
1160 }
|
|
1161 /* TODO: Add string table for sections, so we do not keep holding duplicated
|
|
1162 strings. */
|
|
1163 if (alias && definition
|
|
1164 && get_section () != get_alias_target ()->get_section ()
|
|
1165 && (!get_section()
|
|
1166 || !get_alias_target ()->get_section ()
|
|
1167 || strcmp (get_section(),
|
|
1168 get_alias_target ()->get_section ())))
|
|
1169 {
|
|
1170 error ("Alias and target's section differs");
|
|
1171 get_alias_target ()->dump (stderr);
|
|
1172 error_found = true;
|
|
1173 }
|
|
1174 if (alias && definition
|
|
1175 && get_comdat_group () != get_alias_target ()->get_comdat_group ())
|
|
1176 {
|
|
1177 error ("Alias and target's comdat groups differs");
|
|
1178 get_alias_target ()->dump (stderr);
|
|
1179 error_found = true;
|
|
1180 }
|
|
1181 if (transparent_alias && definition && !weakref)
|
|
1182 {
|
|
1183 symtab_node *to = get_alias_target ();
|
|
1184 const char *name1
|
|
1185 = IDENTIFIER_POINTER (
|
|
1186 ultimate_transparent_alias_target (DECL_ASSEMBLER_NAME (decl)));
|
|
1187 const char *name2
|
|
1188 = IDENTIFIER_POINTER (
|
|
1189 ultimate_transparent_alias_target (DECL_ASSEMBLER_NAME (to->decl)));
|
|
1190 if (!symbol_table::assembler_names_equal_p (name1, name2))
|
|
1191 {
|
|
1192 error ("Transparent alias and target's assembler names differs");
|
|
1193 get_alias_target ()->dump (stderr);
|
|
1194 error_found = true;
|
|
1195 }
|
|
1196 }
|
|
1197 if (transparent_alias && definition
|
|
1198 && get_alias_target()->transparent_alias && get_alias_target()->analyzed)
|
|
1199 {
|
|
1200 error ("Chained transparent aliases");
|
|
1201 get_alias_target ()->dump (stderr);
|
|
1202 error_found = true;
|
|
1203 }
|
|
1204
|
|
1205 return error_found;
|
|
1206 }
|
|
1207
|
|
1208 /* Verify consistency of NODE. */
|
|
1209
|
|
1210 DEBUG_FUNCTION void
|
|
1211 symtab_node::verify (void)
|
|
1212 {
|
|
1213 if (seen_error ())
|
|
1214 return;
|
|
1215
|
|
1216 timevar_push (TV_CGRAPH_VERIFY);
|
|
1217 if (cgraph_node *node = dyn_cast <cgraph_node *> (this))
|
|
1218 node->verify_node ();
|
|
1219 else
|
|
1220 if (verify_base ())
|
|
1221 {
|
|
1222 debug ();
|
|
1223 internal_error ("symtab_node::verify failed");
|
|
1224 }
|
|
1225 timevar_pop (TV_CGRAPH_VERIFY);
|
|
1226 }
|
|
1227
|
|
1228 /* Verify symbol table for internal consistency. */
|
|
1229
|
|
1230 DEBUG_FUNCTION void
|
|
1231 symtab_node::verify_symtab_nodes (void)
|
|
1232 {
|
|
1233 symtab_node *node;
|
|
1234 hash_map<tree, symtab_node *> comdat_head_map (251);
|
|
1235
|
|
1236 FOR_EACH_SYMBOL (node)
|
|
1237 {
|
|
1238 node->verify ();
|
|
1239 if (node->get_comdat_group ())
|
|
1240 {
|
|
1241 symtab_node **entry, *s;
|
|
1242 bool existed;
|
|
1243
|
|
1244 entry = &comdat_head_map.get_or_insert (node->get_comdat_group (),
|
|
1245 &existed);
|
|
1246 if (!existed)
|
|
1247 *entry = node;
|
|
1248 else if (!DECL_EXTERNAL (node->decl))
|
|
1249 {
|
|
1250 for (s = (*entry)->same_comdat_group;
|
|
1251 s != NULL && s != node && s != *entry;
|
|
1252 s = s->same_comdat_group)
|
|
1253 ;
|
|
1254 if (!s || s == *entry)
|
|
1255 {
|
|
1256 error ("Two symbols with same comdat_group are not linked by "
|
|
1257 "the same_comdat_group list.");
|
|
1258 (*entry)->debug ();
|
|
1259 node->debug ();
|
|
1260 internal_error ("symtab_node::verify failed");
|
|
1261 }
|
|
1262 }
|
|
1263 }
|
|
1264 }
|
|
1265 }
|
|
1266
|
|
1267 /* Make DECL local. FIXME: We shouldn't need to mess with rtl this early,
|
|
1268 but other code such as notice_global_symbol generates rtl. */
|
|
1269
|
|
1270 void
|
|
1271 symtab_node::make_decl_local (void)
|
|
1272 {
|
|
1273 rtx rtl, symbol;
|
|
1274
|
|
1275 if (weakref)
|
|
1276 {
|
|
1277 weakref = false;
|
|
1278 IDENTIFIER_TRANSPARENT_ALIAS (DECL_ASSEMBLER_NAME (decl)) = 0;
|
|
1279 TREE_CHAIN (DECL_ASSEMBLER_NAME (decl)) = NULL_TREE;
|
|
1280 symtab->change_decl_assembler_name
|
|
1281 (decl, DECL_ASSEMBLER_NAME (get_alias_target ()->decl));
|
|
1282 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
|
|
1283 DECL_ATTRIBUTES (decl));
|
|
1284 }
|
|
1285 /* Avoid clearing comdat_groups on comdat-local decls. */
|
|
1286 else if (TREE_PUBLIC (decl) == 0)
|
|
1287 return;
|
|
1288
|
|
1289 /* Localizing a symbol also make all its transparent aliases local. */
|
|
1290 ipa_ref *ref;
|
|
1291 for (unsigned i = 0; iterate_direct_aliases (i, ref); i++)
|
|
1292 {
|
|
1293 struct symtab_node *alias = ref->referring;
|
|
1294 if (alias->transparent_alias)
|
|
1295 alias->make_decl_local ();
|
|
1296 }
|
|
1297
|
|
1298 if (VAR_P (decl))
|
|
1299 {
|
|
1300 DECL_COMMON (decl) = 0;
|
|
1301 /* ADDRESSABLE flag is not defined for public symbols. */
|
|
1302 TREE_ADDRESSABLE (decl) = 1;
|
|
1303 TREE_STATIC (decl) = 1;
|
|
1304 }
|
|
1305 else
|
|
1306 gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
|
|
1307
|
|
1308 DECL_COMDAT (decl) = 0;
|
|
1309 DECL_WEAK (decl) = 0;
|
|
1310 DECL_EXTERNAL (decl) = 0;
|
|
1311 DECL_VISIBILITY_SPECIFIED (decl) = 0;
|
|
1312 DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
|
|
1313 TREE_PUBLIC (decl) = 0;
|
|
1314 DECL_DLLIMPORT_P (decl) = 0;
|
|
1315 if (!DECL_RTL_SET_P (decl))
|
|
1316 return;
|
|
1317
|
|
1318 /* Update rtl flags. */
|
|
1319 make_decl_rtl (decl);
|
|
1320
|
|
1321 rtl = DECL_RTL (decl);
|
|
1322 if (!MEM_P (rtl))
|
|
1323 return;
|
|
1324
|
|
1325 symbol = XEXP (rtl, 0);
|
|
1326 if (GET_CODE (symbol) != SYMBOL_REF)
|
|
1327 return;
|
|
1328
|
|
1329 SYMBOL_REF_WEAK (symbol) = DECL_WEAK (decl);
|
|
1330 }
|
|
1331
|
|
1332 /* Copy visibility from N.
|
|
1333 This is useful when THIS becomes a transparent alias of N. */
|
|
1334
|
|
1335 void
|
|
1336 symtab_node::copy_visibility_from (symtab_node *n)
|
|
1337 {
|
|
1338 gcc_checking_assert (n->weakref == weakref);
|
|
1339
|
|
1340 ipa_ref *ref;
|
|
1341 for (unsigned i = 0; iterate_direct_aliases (i, ref); i++)
|
|
1342 {
|
|
1343 struct symtab_node *alias = ref->referring;
|
|
1344 if (alias->transparent_alias)
|
|
1345 alias->copy_visibility_from (n);
|
|
1346 }
|
|
1347
|
|
1348 if (VAR_P (decl))
|
|
1349 {
|
|
1350 DECL_COMMON (decl) = DECL_COMMON (n->decl);
|
|
1351 /* ADDRESSABLE flag is not defined for public symbols. */
|
|
1352 if (TREE_PUBLIC (decl) && !TREE_PUBLIC (n->decl))
|
|
1353 TREE_ADDRESSABLE (decl) = 1;
|
|
1354 TREE_STATIC (decl) = TREE_STATIC (n->decl);
|
|
1355 }
|
|
1356 else gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
|
|
1357
|
|
1358 DECL_COMDAT (decl) = DECL_COMDAT (n->decl);
|
|
1359 DECL_WEAK (decl) = DECL_WEAK (n->decl);
|
|
1360 DECL_EXTERNAL (decl) = DECL_EXTERNAL (n->decl);
|
|
1361 DECL_VISIBILITY_SPECIFIED (decl) = DECL_VISIBILITY_SPECIFIED (n->decl);
|
|
1362 DECL_VISIBILITY (decl) = DECL_VISIBILITY (n->decl);
|
|
1363 TREE_PUBLIC (decl) = TREE_PUBLIC (n->decl);
|
|
1364 DECL_DLLIMPORT_P (decl) = DECL_DLLIMPORT_P (n->decl);
|
|
1365 resolution = n->resolution;
|
|
1366 set_comdat_group (n->get_comdat_group ());
|
|
1367 call_for_symbol_and_aliases (symtab_node::set_section,
|
|
1368 const_cast<char *>(n->get_section ()), true);
|
|
1369 externally_visible = n->externally_visible;
|
|
1370 if (!DECL_RTL_SET_P (decl))
|
|
1371 return;
|
|
1372
|
|
1373 /* Update rtl flags. */
|
|
1374 make_decl_rtl (decl);
|
|
1375
|
|
1376 rtx rtl = DECL_RTL (decl);
|
|
1377 if (!MEM_P (rtl))
|
|
1378 return;
|
|
1379
|
|
1380 rtx symbol = XEXP (rtl, 0);
|
|
1381 if (GET_CODE (symbol) != SYMBOL_REF)
|
|
1382 return;
|
|
1383
|
|
1384 SYMBOL_REF_WEAK (symbol) = DECL_WEAK (decl);
|
|
1385 }
|
|
1386
|
|
1387 /* Walk the alias chain to return the symbol NODE is alias of.
|
|
1388 If NODE is not an alias, return NODE.
|
|
1389 Assumes NODE is known to be alias. */
|
|
1390
|
|
1391 symtab_node *
|
|
1392 symtab_node::ultimate_alias_target_1 (enum availability *availability,
|
|
1393 symtab_node *ref)
|
|
1394 {
|
|
1395 bool transparent_p = false;
|
|
1396
|
|
1397 /* To determine visibility of the target, we follow ELF semantic of aliases.
|
|
1398 Here alias is an alternative assembler name of a given definition. Its
|
|
1399 availability prevails the availability of its target (i.e. static alias of
|
|
1400 weak definition is available.
|
|
1401
|
|
1402 Transaparent alias is just alternative anme of a given symbol used within
|
|
1403 one compilation unit and is translated prior hitting the object file. It
|
|
1404 inherits the visibility of its target.
|
|
1405 Weakref is a different animal (and noweak definition is weak).
|
|
1406
|
|
1407 If we ever get into supporting targets with different semantics, a target
|
|
1408 hook will be needed here. */
|
|
1409
|
|
1410 if (availability)
|
|
1411 {
|
|
1412 transparent_p = transparent_alias;
|
|
1413 if (!transparent_p)
|
|
1414 *availability = get_availability (ref);
|
|
1415 else
|
|
1416 *availability = AVAIL_NOT_AVAILABLE;
|
|
1417 }
|
|
1418
|
|
1419 symtab_node *node = this;
|
|
1420 while (node)
|
|
1421 {
|
|
1422 if (node->alias && node->analyzed)
|
|
1423 node = node->get_alias_target ();
|
|
1424 else
|
|
1425 {
|
|
1426 if (!availability || (!transparent_p && node->analyzed))
|
|
1427 ;
|
|
1428 else if (node->analyzed && !node->transparent_alias)
|
|
1429 *availability = node->get_availability (ref);
|
|
1430 else
|
|
1431 *availability = AVAIL_NOT_AVAILABLE;
|
|
1432 return node;
|
|
1433 }
|
|
1434 if (node && availability && transparent_p
|
|
1435 && node->transparent_alias)
|
|
1436 {
|
|
1437 *availability = node->get_availability (ref);
|
|
1438 transparent_p = false;
|
|
1439 }
|
|
1440 }
|
|
1441 if (availability)
|
|
1442 *availability = AVAIL_NOT_AVAILABLE;
|
|
1443 return NULL;
|
|
1444 }
|
|
1445
|
|
1446 /* C++ FE sometimes change linkage flags after producing same body aliases.
|
|
1447
|
|
1448 FIXME: C++ produce implicit aliases for virtual functions and vtables that
|
|
1449 are obviously equivalent. The way it is doing so is however somewhat
|
|
1450 kludgy and interferes with the visibility code. As a result we need to
|
|
1451 copy the visibility from the target to get things right. */
|
|
1452
|
|
1453 void
|
|
1454 symtab_node::fixup_same_cpp_alias_visibility (symtab_node *target)
|
|
1455 {
|
|
1456 if (is_a <cgraph_node *> (this))
|
|
1457 {
|
|
1458 DECL_DECLARED_INLINE_P (decl)
|
|
1459 = DECL_DECLARED_INLINE_P (target->decl);
|
|
1460 DECL_DISREGARD_INLINE_LIMITS (decl)
|
|
1461 = DECL_DISREGARD_INLINE_LIMITS (target->decl);
|
|
1462 }
|
|
1463 /* FIXME: It is not really clear why those flags should not be copied for
|
|
1464 functions, too. */
|
|
1465 else
|
|
1466 {
|
|
1467 DECL_WEAK (decl) = DECL_WEAK (target->decl);
|
|
1468 DECL_EXTERNAL (decl) = DECL_EXTERNAL (target->decl);
|
|
1469 DECL_VISIBILITY (decl) = DECL_VISIBILITY (target->decl);
|
|
1470 }
|
|
1471 if (TREE_PUBLIC (decl))
|
|
1472 {
|
|
1473 tree group;
|
|
1474
|
|
1475 DECL_EXTERNAL (decl) = DECL_EXTERNAL (target->decl);
|
|
1476 DECL_COMDAT (decl) = DECL_COMDAT (target->decl);
|
|
1477 group = target->get_comdat_group ();
|
|
1478 set_comdat_group (group);
|
|
1479 if (group && !same_comdat_group)
|
|
1480 add_to_same_comdat_group (target);
|
|
1481 }
|
|
1482 externally_visible = target->externally_visible;
|
|
1483 }
|
|
1484
|
|
1485 /* Set section, do not recurse into aliases.
|
|
1486 When one wants to change section of a symbol and its aliases,
|
|
1487 use set_section. */
|
|
1488
|
|
1489 void
|
|
1490 symtab_node::set_section_for_node (const char *section)
|
|
1491 {
|
|
1492 const char *current = get_section ();
|
|
1493 section_hash_entry **slot;
|
|
1494
|
|
1495 if (current == section
|
|
1496 || (current && section
|
|
1497 && !strcmp (current, section)))
|
|
1498 return;
|
|
1499
|
|
1500 if (current)
|
|
1501 {
|
|
1502 x_section->ref_count--;
|
|
1503 if (!x_section->ref_count)
|
|
1504 {
|
|
1505 hashval_t hash = htab_hash_string (x_section->name);
|
|
1506 slot = symtab->section_hash->find_slot_with_hash (x_section->name,
|
|
1507 hash, INSERT);
|
|
1508 ggc_free (x_section);
|
|
1509 symtab->section_hash->clear_slot (slot);
|
|
1510 }
|
|
1511 x_section = NULL;
|
|
1512 }
|
|
1513 if (!section)
|
|
1514 {
|
|
1515 implicit_section = false;
|
|
1516 return;
|
|
1517 }
|
|
1518 if (!symtab->section_hash)
|
|
1519 symtab->section_hash = hash_table<section_name_hasher>::create_ggc (10);
|
|
1520 slot = symtab->section_hash->find_slot_with_hash (section,
|
|
1521 htab_hash_string (section),
|
|
1522 INSERT);
|
|
1523 if (*slot)
|
|
1524 x_section = (section_hash_entry *)*slot;
|
|
1525 else
|
|
1526 {
|
|
1527 int len = strlen (section);
|
|
1528 *slot = x_section = ggc_cleared_alloc<section_hash_entry> ();
|
|
1529 x_section->name = ggc_vec_alloc<char> (len + 1);
|
|
1530 memcpy (x_section->name, section, len + 1);
|
|
1531 }
|
|
1532 x_section->ref_count++;
|
|
1533 }
|
|
1534
|
|
1535 /* Worker for set_section. */
|
|
1536
|
|
1537 bool
|
|
1538 symtab_node::set_section (symtab_node *n, void *s)
|
|
1539 {
|
|
1540 n->set_section_for_node ((char *)s);
|
|
1541 return false;
|
|
1542 }
|
|
1543
|
|
1544 /* Set section of symbol and its aliases. */
|
|
1545
|
|
1546 void
|
|
1547 symtab_node::set_section (const char *section)
|
|
1548 {
|
|
1549 gcc_assert (!this->alias);
|
|
1550 call_for_symbol_and_aliases
|
|
1551 (symtab_node::set_section, const_cast<char *>(section), true);
|
|
1552 }
|
|
1553
|
|
1554 /* Return the initialization priority. */
|
|
1555
|
|
1556 priority_type
|
|
1557 symtab_node::get_init_priority ()
|
|
1558 {
|
|
1559 if (!this->in_init_priority_hash)
|
|
1560 return DEFAULT_INIT_PRIORITY;
|
|
1561
|
|
1562 symbol_priority_map *h = symtab->init_priority_hash->get (this);
|
|
1563 return h ? h->init : DEFAULT_INIT_PRIORITY;
|
|
1564 }
|
|
1565
|
|
1566 /* Return the finalization priority. */
|
|
1567
|
|
1568 priority_type
|
|
1569 cgraph_node::get_fini_priority ()
|
|
1570 {
|
|
1571 if (!this->in_init_priority_hash)
|
|
1572 return DEFAULT_INIT_PRIORITY;
|
|
1573 symbol_priority_map *h = symtab->init_priority_hash->get (this);
|
|
1574 return h ? h->fini : DEFAULT_INIT_PRIORITY;
|
|
1575 }
|
|
1576
|
|
1577 /* Return the initialization and finalization priority information for
|
|
1578 DECL. If there is no previous priority information, a freshly
|
|
1579 allocated structure is returned. */
|
|
1580
|
|
1581 symbol_priority_map *
|
|
1582 symtab_node::priority_info (void)
|
|
1583 {
|
|
1584 if (!symtab->init_priority_hash)
|
|
1585 symtab->init_priority_hash = hash_map<symtab_node *, symbol_priority_map>::create_ggc (13);
|
|
1586
|
|
1587 bool existed;
|
|
1588 symbol_priority_map *h
|
|
1589 = &symtab->init_priority_hash->get_or_insert (this, &existed);
|
|
1590 if (!existed)
|
|
1591 {
|
|
1592 h->init = DEFAULT_INIT_PRIORITY;
|
|
1593 h->fini = DEFAULT_INIT_PRIORITY;
|
|
1594 in_init_priority_hash = true;
|
|
1595 }
|
|
1596
|
|
1597 return h;
|
|
1598 }
|
|
1599
|
|
1600 /* Set initialization priority to PRIORITY. */
|
|
1601
|
|
1602 void
|
|
1603 symtab_node::set_init_priority (priority_type priority)
|
|
1604 {
|
|
1605 symbol_priority_map *h;
|
|
1606
|
|
1607 if (is_a <cgraph_node *> (this))
|
|
1608 gcc_assert (DECL_STATIC_CONSTRUCTOR (this->decl));
|
|
1609
|
|
1610 if (priority == DEFAULT_INIT_PRIORITY)
|
|
1611 {
|
|
1612 gcc_assert (get_init_priority() == priority);
|
|
1613 return;
|
|
1614 }
|
|
1615 h = priority_info ();
|
|
1616 h->init = priority;
|
|
1617 }
|
|
1618
|
|
1619 /* Set fialization priority to PRIORITY. */
|
|
1620
|
|
1621 void
|
|
1622 cgraph_node::set_fini_priority (priority_type priority)
|
|
1623 {
|
|
1624 symbol_priority_map *h;
|
|
1625
|
|
1626 gcc_assert (DECL_STATIC_DESTRUCTOR (this->decl));
|
|
1627
|
|
1628 if (priority == DEFAULT_INIT_PRIORITY)
|
|
1629 {
|
|
1630 gcc_assert (get_fini_priority() == priority);
|
|
1631 return;
|
|
1632 }
|
|
1633 h = priority_info ();
|
|
1634 h->fini = priority;
|
|
1635 }
|
|
1636
|
|
1637 /* Worker for symtab_resolve_alias. */
|
|
1638
|
|
1639 bool
|
|
1640 symtab_node::set_implicit_section (symtab_node *n,
|
|
1641 void *data ATTRIBUTE_UNUSED)
|
|
1642 {
|
|
1643 n->implicit_section = true;
|
|
1644 return false;
|
|
1645 }
|
|
1646
|
|
1647 /* Add reference recording that symtab node is alias of TARGET.
|
|
1648 The function can fail in the case of aliasing cycles; in this case
|
|
1649 it returns false. */
|
|
1650
|
|
1651 bool
|
|
1652 symtab_node::resolve_alias (symtab_node *target, bool transparent)
|
|
1653 {
|
|
1654 symtab_node *n;
|
|
1655
|
|
1656 gcc_assert (!analyzed && !vec_safe_length (ref_list.references));
|
|
1657
|
|
1658 /* Never let cycles to creep into the symbol table alias references;
|
|
1659 those will make alias walkers to be infinite. */
|
|
1660 for (n = target; n && n->alias;
|
|
1661 n = n->analyzed ? n->get_alias_target () : NULL)
|
|
1662 if (n == this)
|
|
1663 {
|
|
1664 if (is_a <cgraph_node *> (this))
|
|
1665 error ("function %q+D part of alias cycle", decl);
|
|
1666 else if (is_a <varpool_node *> (this))
|
|
1667 error ("variable %q+D part of alias cycle", decl);
|
|
1668 else
|
|
1669 gcc_unreachable ();
|
|
1670 alias = false;
|
|
1671 return false;
|
|
1672 }
|
|
1673
|
|
1674 /* "analyze" the node - i.e. mark the reference. */
|
|
1675 definition = true;
|
|
1676 alias = true;
|
|
1677 analyzed = true;
|
|
1678 transparent |= transparent_alias;
|
|
1679 transparent_alias = transparent;
|
|
1680 if (transparent)
|
|
1681 while (target->transparent_alias && target->analyzed)
|
|
1682 target = target->get_alias_target ();
|
|
1683 create_reference (target, IPA_REF_ALIAS, NULL);
|
|
1684
|
|
1685 /* Add alias into the comdat group of its target unless it is already there. */
|
|
1686 if (same_comdat_group)
|
|
1687 remove_from_same_comdat_group ();
|
|
1688 set_comdat_group (NULL);
|
|
1689 if (target->get_comdat_group ())
|
|
1690 add_to_same_comdat_group (target);
|
|
1691
|
|
1692 if ((get_section () != target->get_section ()
|
|
1693 || target->get_comdat_group ()) && get_section () && !implicit_section)
|
|
1694 {
|
|
1695 error ("section of alias %q+D must match section of its target", decl);
|
|
1696 }
|
|
1697 call_for_symbol_and_aliases (symtab_node::set_section,
|
|
1698 const_cast<char *>(target->get_section ()), true);
|
|
1699 if (target->implicit_section)
|
|
1700 call_for_symbol_and_aliases (set_implicit_section, NULL, true);
|
|
1701
|
|
1702 /* Alias targets become redundant after alias is resolved into an reference.
|
|
1703 We do not want to keep it around or we would have to mind updating them
|
|
1704 when renaming symbols. */
|
|
1705 alias_target = NULL;
|
|
1706
|
|
1707 if (!transparent && cpp_implicit_alias && symtab->state >= CONSTRUCTION)
|
|
1708 fixup_same_cpp_alias_visibility (target);
|
|
1709
|
|
1710 /* If alias has address taken, so does the target. */
|
|
1711 if (address_taken)
|
|
1712 target->ultimate_alias_target ()->address_taken = true;
|
|
1713
|
|
1714 /* All non-transparent aliases of THIS are now in fact aliases of TARGET.
|
|
1715 If alias is transparent, also all transparent aliases of THIS are now
|
|
1716 aliases of TARGET.
|
|
1717 Also merge same comdat group lists. */
|
|
1718 ipa_ref *ref;
|
|
1719 for (unsigned i = 0; iterate_direct_aliases (i, ref);)
|
|
1720 {
|
|
1721 struct symtab_node *alias_alias = ref->referring;
|
|
1722 if (alias_alias->get_comdat_group ())
|
|
1723 {
|
|
1724 alias_alias->remove_from_same_comdat_group ();
|
|
1725 alias_alias->set_comdat_group (NULL);
|
|
1726 if (target->get_comdat_group ())
|
|
1727 alias_alias->add_to_same_comdat_group (target);
|
|
1728 }
|
|
1729 if (!alias_alias->transparent_alias || transparent)
|
|
1730 {
|
|
1731 alias_alias->remove_all_references ();
|
|
1732 alias_alias->create_reference (target, IPA_REF_ALIAS, NULL);
|
|
1733 }
|
|
1734 else i++;
|
|
1735 }
|
|
1736 return true;
|
|
1737 }
|
|
1738
|
|
1739 /* Worker searching noninterposable alias. */
|
|
1740
|
|
1741 bool
|
|
1742 symtab_node::noninterposable_alias (symtab_node *node, void *data)
|
|
1743 {
|
|
1744 if (!node->transparent_alias && decl_binds_to_current_def_p (node->decl))
|
|
1745 {
|
|
1746 symtab_node *fn = node->ultimate_alias_target ();
|
|
1747
|
|
1748 /* Ensure that the alias is well formed this may not be the case
|
|
1749 of user defined aliases and currently it is not always the case
|
|
1750 of C++ same body aliases (that is a bug). */
|
|
1751 if (TREE_TYPE (node->decl) != TREE_TYPE (fn->decl)
|
|
1752 || DECL_CONTEXT (node->decl) != DECL_CONTEXT (fn->decl)
|
|
1753 || (TREE_CODE (node->decl) == FUNCTION_DECL
|
|
1754 && flags_from_decl_or_type (node->decl)
|
|
1755 != flags_from_decl_or_type (fn->decl))
|
|
1756 || DECL_ATTRIBUTES (node->decl) != DECL_ATTRIBUTES (fn->decl))
|
|
1757 return false;
|
|
1758 *(symtab_node **)data = node;
|
|
1759 return true;
|
|
1760 }
|
|
1761 return false;
|
|
1762 }
|
|
1763
|
|
1764 /* If node can not be overwriten by static or dynamic linker to point to
|
|
1765 different definition, return NODE. Otherwise look for alias with such
|
|
1766 property and if none exists, introduce new one. */
|
|
1767
|
|
1768 symtab_node *
|
|
1769 symtab_node::noninterposable_alias (void)
|
|
1770 {
|
|
1771 tree new_decl;
|
|
1772 symtab_node *new_node = NULL;
|
|
1773
|
|
1774 /* First try to look up existing alias or base object
|
|
1775 (if that is already non-overwritable). */
|
|
1776 symtab_node *node = ultimate_alias_target ();
|
|
1777 gcc_assert (!node->alias && !node->weakref);
|
|
1778 node->call_for_symbol_and_aliases (symtab_node::noninterposable_alias,
|
|
1779 (void *)&new_node, true);
|
|
1780 if (new_node)
|
|
1781 return new_node;
|
|
1782
|
|
1783 /* If aliases aren't supported by the assembler, fail. */
|
|
1784 if (!TARGET_SUPPORTS_ALIASES)
|
|
1785 return NULL;
|
|
1786
|
|
1787 /* Otherwise create a new one. */
|
|
1788 new_decl = copy_node (node->decl);
|
|
1789 DECL_DLLIMPORT_P (new_decl) = 0;
|
|
1790 DECL_NAME (new_decl) = clone_function_name (node->decl, "localalias");
|
|
1791 if (TREE_CODE (new_decl) == FUNCTION_DECL)
|
|
1792 DECL_STRUCT_FUNCTION (new_decl) = NULL;
|
|
1793 DECL_INITIAL (new_decl) = NULL;
|
|
1794 SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
|
|
1795 SET_DECL_RTL (new_decl, NULL);
|
|
1796
|
|
1797 /* Update the properties. */
|
|
1798 DECL_EXTERNAL (new_decl) = 0;
|
|
1799 TREE_PUBLIC (new_decl) = 0;
|
|
1800 DECL_COMDAT (new_decl) = 0;
|
|
1801 DECL_WEAK (new_decl) = 0;
|
|
1802
|
|
1803 /* Since the aliases can be added to vtables, keep DECL_VIRTUAL flag. */
|
|
1804 DECL_VIRTUAL_P (new_decl) = DECL_VIRTUAL_P (node->decl);
|
|
1805 if (TREE_CODE (new_decl) == FUNCTION_DECL)
|
|
1806 {
|
|
1807 DECL_STATIC_CONSTRUCTOR (new_decl) = 0;
|
|
1808 DECL_STATIC_DESTRUCTOR (new_decl) = 0;
|
|
1809 new_node = cgraph_node::create_alias (new_decl, node->decl);
|
|
1810 }
|
|
1811 else
|
|
1812 {
|
|
1813 TREE_READONLY (new_decl) = TREE_READONLY (node->decl);
|
|
1814 DECL_INITIAL (new_decl) = error_mark_node;
|
|
1815 new_node = varpool_node::create_alias (new_decl, node->decl);
|
|
1816 }
|
|
1817 new_node->resolve_alias (node);
|
|
1818 gcc_assert (decl_binds_to_current_def_p (new_decl)
|
|
1819 && targetm.binds_local_p (new_decl));
|
|
1820 return new_node;
|
|
1821 }
|
|
1822
|
|
1823 /* Return true if symtab node and TARGET represents
|
|
1824 semantically equivalent symbols. */
|
|
1825
|
|
1826 bool
|
|
1827 symtab_node::semantically_equivalent_p (symtab_node *target)
|
|
1828 {
|
|
1829 enum availability avail;
|
|
1830 symtab_node *ba;
|
|
1831 symtab_node *bb;
|
|
1832
|
|
1833 /* Equivalent functions are equivalent. */
|
|
1834 if (decl == target->decl)
|
|
1835 return true;
|
|
1836
|
|
1837 /* If symbol is not overwritable by different implementation,
|
|
1838 walk to the base object it defines. */
|
|
1839 ba = ultimate_alias_target (&avail);
|
|
1840 if (avail >= AVAIL_AVAILABLE)
|
|
1841 {
|
|
1842 if (target == ba)
|
|
1843 return true;
|
|
1844 }
|
|
1845 else
|
|
1846 ba = this;
|
|
1847 bb = target->ultimate_alias_target (&avail);
|
|
1848 if (avail >= AVAIL_AVAILABLE)
|
|
1849 {
|
|
1850 if (this == bb)
|
|
1851 return true;
|
|
1852 }
|
|
1853 else
|
|
1854 bb = target;
|
|
1855 return bb == ba;
|
|
1856 }
|
|
1857
|
|
1858 /* Classify symbol symtab node for partitioning. */
|
|
1859
|
|
1860 enum symbol_partitioning_class
|
|
1861 symtab_node::get_partitioning_class (void)
|
|
1862 {
|
|
1863 /* Inline clones are always duplicated.
|
|
1864 This include external delcarations. */
|
|
1865 cgraph_node *cnode = dyn_cast <cgraph_node *> (this);
|
|
1866
|
|
1867 if (DECL_ABSTRACT_P (decl))
|
|
1868 return SYMBOL_EXTERNAL;
|
|
1869
|
|
1870 if (cnode && cnode->global.inlined_to)
|
|
1871 return SYMBOL_DUPLICATE;
|
|
1872
|
|
1873 /* Transparent aliases are always duplicated. */
|
|
1874 if (transparent_alias)
|
|
1875 return definition ? SYMBOL_DUPLICATE : SYMBOL_EXTERNAL;
|
|
1876
|
|
1877 /* External declarations are external. */
|
|
1878 if (DECL_EXTERNAL (decl))
|
|
1879 return SYMBOL_EXTERNAL;
|
|
1880
|
|
1881 if (varpool_node *vnode = dyn_cast <varpool_node *> (this))
|
|
1882 {
|
|
1883 if (alias && definition && !ultimate_alias_target ()->definition)
|
|
1884 return SYMBOL_EXTERNAL;
|
|
1885 /* Constant pool references use local symbol names that can not
|
|
1886 be promoted global. We should never put into a constant pool
|
|
1887 objects that can not be duplicated across partitions. */
|
|
1888 if (DECL_IN_CONSTANT_POOL (decl))
|
|
1889 return SYMBOL_DUPLICATE;
|
|
1890 if (DECL_HARD_REGISTER (decl))
|
|
1891 return SYMBOL_DUPLICATE;
|
|
1892 gcc_checking_assert (vnode->definition);
|
|
1893 }
|
|
1894 /* Functions that are cloned may stay in callgraph even if they are unused.
|
|
1895 Handle them as external; compute_ltrans_boundary take care to make
|
|
1896 proper things to happen (i.e. to make them appear in the boundary but
|
|
1897 with body streamed, so clone can me materialized). */
|
|
1898 else if (!dyn_cast <cgraph_node *> (this)->function_symbol ()->definition)
|
|
1899 return SYMBOL_EXTERNAL;
|
|
1900
|
|
1901 /* Linker discardable symbols are duplicated to every use unless they are
|
|
1902 keyed. */
|
|
1903 if (DECL_ONE_ONLY (decl)
|
|
1904 && !force_output
|
|
1905 && !forced_by_abi
|
|
1906 && !used_from_object_file_p ())
|
|
1907 return SYMBOL_DUPLICATE;
|
|
1908
|
|
1909 return SYMBOL_PARTITION;
|
|
1910 }
|
|
1911
|
|
1912 /* Return true when symbol is known to be non-zero. */
|
|
1913
|
|
1914 bool
|
|
1915 symtab_node::nonzero_address ()
|
|
1916 {
|
|
1917 /* Weakrefs may be NULL when their target is not defined. */
|
|
1918 if (alias && weakref)
|
|
1919 {
|
|
1920 if (analyzed)
|
|
1921 {
|
|
1922 symtab_node *target = ultimate_alias_target ();
|
|
1923
|
|
1924 if (target->alias && target->weakref)
|
|
1925 return false;
|
|
1926 /* We can not recurse to target::nonzero. It is possible that the
|
|
1927 target is used only via the alias.
|
|
1928 We may walk references and look for strong use, but we do not know
|
|
1929 if this strong use will survive to final binary, so be
|
|
1930 conservative here.
|
|
1931 ??? Maybe we could do the lookup during late optimization that
|
|
1932 could be useful to eliminate the NULL pointer checks in LTO
|
|
1933 programs. */
|
|
1934 if (target->definition && !DECL_EXTERNAL (target->decl))
|
|
1935 return true;
|
|
1936 if (target->resolution != LDPR_UNKNOWN
|
|
1937 && target->resolution != LDPR_UNDEF
|
|
1938 && !target->can_be_discarded_p ()
|
|
1939 && flag_delete_null_pointer_checks)
|
|
1940 return true;
|
|
1941 return false;
|
|
1942 }
|
|
1943 else
|
|
1944 return false;
|
|
1945 }
|
|
1946
|
|
1947 /* With !flag_delete_null_pointer_checks we assume that symbols may
|
|
1948 bind to NULL. This is on by default on embedded targets only.
|
|
1949
|
|
1950 Otherwise all non-WEAK symbols must be defined and thus non-NULL or
|
|
1951 linking fails. Important case of WEAK we want to do well are comdats.
|
|
1952 Those are handled by later check for definition.
|
|
1953
|
|
1954 When parsing, beware the cases when WEAK attribute is added later. */
|
|
1955 if (!DECL_WEAK (decl)
|
|
1956 && flag_delete_null_pointer_checks)
|
|
1957 {
|
|
1958 refuse_visibility_changes = true;
|
|
1959 return true;
|
|
1960 }
|
|
1961
|
131
|
1962 /* If target is defined and either comdat or not extern, we know it will be
|
|
1963 output and thus it will bind to non-NULL.
|
|
1964 Play safe for flag_delete_null_pointer_checks where weak definition may
|
111
|
1965 be re-defined by NULL. */
|
131
|
1966 if (definition && (!DECL_EXTERNAL (decl) || DECL_COMDAT (decl))
|
111
|
1967 && (flag_delete_null_pointer_checks || !DECL_WEAK (decl)))
|
|
1968 {
|
|
1969 if (!DECL_WEAK (decl))
|
|
1970 refuse_visibility_changes = true;
|
|
1971 return true;
|
|
1972 }
|
|
1973
|
|
1974 /* As the last resort, check the resolution info. */
|
|
1975 if (resolution != LDPR_UNKNOWN
|
|
1976 && resolution != LDPR_UNDEF
|
|
1977 && !can_be_discarded_p ()
|
|
1978 && flag_delete_null_pointer_checks)
|
|
1979 return true;
|
|
1980 return false;
|
|
1981 }
|
|
1982
|
|
1983 /* Return 0 if symbol is known to have different address than S2,
|
|
1984 Return 1 if symbol is known to have same address as S2,
|
|
1985 return -1 otherwise.
|
|
1986
|
|
1987 If MEMORY_ACCESSED is true, assume that both memory pointer to THIS
|
|
1988 and S2 is going to be accessed. This eliminates the situations when
|
|
1989 either THIS or S2 is NULL and is seful for comparing bases when deciding
|
|
1990 about memory aliasing. */
|
|
1991 int
|
|
1992 symtab_node::equal_address_to (symtab_node *s2, bool memory_accessed)
|
|
1993 {
|
|
1994 enum availability avail1, avail2;
|
|
1995
|
|
1996 /* A Shortcut: equivalent symbols are always equivalent. */
|
|
1997 if (this == s2)
|
|
1998 return 1;
|
|
1999
|
|
2000 /* Unwind transparent aliases first; those are always equal to their
|
|
2001 target. */
|
|
2002 if (this->transparent_alias && this->analyzed)
|
|
2003 return this->get_alias_target ()->equal_address_to (s2);
|
|
2004 while (s2->transparent_alias && s2->analyzed)
|
|
2005 s2 = s2->get_alias_target();
|
|
2006
|
|
2007 if (this == s2)
|
|
2008 return 1;
|
|
2009
|
|
2010 /* For non-interposable aliases, lookup and compare their actual definitions.
|
|
2011 Also check if the symbol needs to bind to given definition. */
|
|
2012 symtab_node *rs1 = ultimate_alias_target (&avail1);
|
|
2013 symtab_node *rs2 = s2->ultimate_alias_target (&avail2);
|
|
2014 bool binds_local1 = rs1->analyzed && decl_binds_to_current_def_p (this->decl);
|
|
2015 bool binds_local2 = rs2->analyzed && decl_binds_to_current_def_p (s2->decl);
|
|
2016 bool really_binds_local1 = binds_local1;
|
|
2017 bool really_binds_local2 = binds_local2;
|
|
2018
|
|
2019 /* Addresses of vtables and virtual functions can not be used by user
|
|
2020 code and are used only within speculation. In this case we may make
|
|
2021 symbol equivalent to its alias even if interposition may break this
|
|
2022 rule. Doing so will allow us to turn speculative inlining into
|
|
2023 non-speculative more agressively. */
|
|
2024 if (DECL_VIRTUAL_P (this->decl) && avail1 >= AVAIL_AVAILABLE)
|
|
2025 binds_local1 = true;
|
|
2026 if (DECL_VIRTUAL_P (s2->decl) && avail2 >= AVAIL_AVAILABLE)
|
|
2027 binds_local2 = true;
|
|
2028
|
|
2029 /* If both definitions are available we know that even if they are bound
|
|
2030 to other unit they must be defined same way and therefore we can use
|
|
2031 equivalence test. */
|
|
2032 if (rs1 != rs2 && avail1 >= AVAIL_AVAILABLE && avail2 >= AVAIL_AVAILABLE)
|
|
2033 binds_local1 = binds_local2 = true;
|
|
2034
|
|
2035 if (binds_local1 && binds_local2 && rs1 == rs2)
|
|
2036 {
|
|
2037 /* We made use of the fact that alias is not weak. */
|
|
2038 if (rs1 != this)
|
|
2039 refuse_visibility_changes = true;
|
|
2040 if (rs2 != s2)
|
|
2041 s2->refuse_visibility_changes = true;
|
|
2042 return 1;
|
|
2043 }
|
|
2044
|
|
2045 /* If both symbols may resolve to NULL, we can not really prove them
|
|
2046 different. */
|
|
2047 if (!memory_accessed && !nonzero_address () && !s2->nonzero_address ())
|
|
2048 return -1;
|
|
2049
|
|
2050 /* Except for NULL, functions and variables never overlap. */
|
|
2051 if (TREE_CODE (decl) != TREE_CODE (s2->decl))
|
|
2052 return 0;
|
|
2053
|
|
2054 /* If one of the symbols is unresolved alias, punt. */
|
|
2055 if (rs1->alias || rs2->alias)
|
|
2056 return -1;
|
|
2057
|
|
2058 /* If we have a non-interposale definition of at least one of the symbols
|
|
2059 and the other symbol is different, we know other unit can not interpose
|
|
2060 it to the first symbol; all aliases of the definition needs to be
|
|
2061 present in the current unit. */
|
|
2062 if (((really_binds_local1 || really_binds_local2)
|
|
2063 /* If we have both definitions and they are different, we know they
|
|
2064 will be different even in units they binds to. */
|
|
2065 || (binds_local1 && binds_local2))
|
|
2066 && rs1 != rs2)
|
|
2067 {
|
|
2068 /* We make use of the fact that one symbol is not alias of the other
|
|
2069 and that the definition is non-interposable. */
|
|
2070 refuse_visibility_changes = true;
|
|
2071 s2->refuse_visibility_changes = true;
|
|
2072 rs1->refuse_visibility_changes = true;
|
|
2073 rs2->refuse_visibility_changes = true;
|
|
2074 return 0;
|
|
2075 }
|
|
2076
|
|
2077 /* TODO: Alias oracle basically assume that addresses of global variables
|
|
2078 are different unless they are declared as alias of one to another while
|
|
2079 the code folding comparsions doesn't.
|
|
2080 We probably should be consistent and use this fact here, too, but for
|
|
2081 the moment return false only when we are called from the alias oracle. */
|
|
2082
|
|
2083 return memory_accessed && rs1 != rs2 ? 0 : -1;
|
|
2084 }
|
|
2085
|
|
2086 /* Worker for call_for_symbol_and_aliases. */
|
|
2087
|
|
2088 bool
|
|
2089 symtab_node::call_for_symbol_and_aliases_1 (bool (*callback) (symtab_node *,
|
|
2090 void *),
|
|
2091 void *data,
|
|
2092 bool include_overwritable)
|
|
2093 {
|
|
2094 ipa_ref *ref;
|
|
2095 FOR_EACH_ALIAS (this, ref)
|
|
2096 {
|
|
2097 symtab_node *alias = ref->referring;
|
|
2098 if (include_overwritable
|
|
2099 || alias->get_availability () > AVAIL_INTERPOSABLE)
|
|
2100 if (alias->call_for_symbol_and_aliases (callback, data,
|
|
2101 include_overwritable))
|
|
2102 return true;
|
|
2103 }
|
|
2104 return false;
|
|
2105 }
|
|
2106
|
|
2107 /* Return true if address of N is possibly compared. */
|
|
2108
|
|
2109 static bool
|
|
2110 address_matters_1 (symtab_node *n, void *)
|
|
2111 {
|
|
2112 struct ipa_ref *ref;
|
|
2113
|
|
2114 if (!n->address_can_be_compared_p ())
|
|
2115 return false;
|
|
2116 if (n->externally_visible || n->force_output)
|
|
2117 return true;
|
|
2118
|
|
2119 for (unsigned int i = 0; n->iterate_referring (i, ref); i++)
|
|
2120 if (ref->address_matters_p ())
|
|
2121 return true;
|
|
2122 return false;
|
|
2123 }
|
|
2124
|
|
2125 /* Return true if symbol's address may possibly be compared to other
|
|
2126 symbol's address. */
|
|
2127
|
|
2128 bool
|
|
2129 symtab_node::address_matters_p ()
|
|
2130 {
|
|
2131 gcc_assert (!alias);
|
|
2132 return call_for_symbol_and_aliases (address_matters_1, NULL, true);
|
|
2133 }
|
|
2134
|
|
2135 /* Return true if symbol's alignment may be increased. */
|
|
2136
|
|
2137 bool
|
|
2138 symtab_node::can_increase_alignment_p (void)
|
|
2139 {
|
|
2140 symtab_node *target = ultimate_alias_target ();
|
|
2141
|
|
2142 /* For now support only variables. */
|
|
2143 if (!VAR_P (decl))
|
|
2144 return false;
|
|
2145
|
|
2146 /* With -fno-toplevel-reorder we may have already output the constant. */
|
|
2147 if (TREE_ASM_WRITTEN (target->decl))
|
|
2148 return false;
|
|
2149
|
|
2150 /* If target is already placed in an anchor, we can not touch its
|
|
2151 alignment. */
|
|
2152 if (DECL_RTL_SET_P (target->decl)
|
|
2153 && MEM_P (DECL_RTL (target->decl))
|
|
2154 && SYMBOL_REF_HAS_BLOCK_INFO_P (XEXP (DECL_RTL (target->decl), 0)))
|
|
2155 return false;
|
|
2156
|
|
2157 /* Constant pool entries may be shared. */
|
|
2158 if (DECL_IN_CONSTANT_POOL (target->decl))
|
|
2159 return false;
|
|
2160
|
|
2161 /* We cannot change alignment of symbols that may bind to symbols
|
|
2162 in other translation unit that may contain a definition with lower
|
|
2163 alignment. */
|
|
2164 if (!decl_binds_to_current_def_p (decl))
|
|
2165 return false;
|
|
2166
|
|
2167 /* When compiling partition, be sure the symbol is not output by other
|
|
2168 partition. */
|
|
2169 if (flag_ltrans
|
|
2170 && (target->in_other_partition
|
|
2171 || target->get_partitioning_class () == SYMBOL_DUPLICATE))
|
|
2172 return false;
|
|
2173
|
|
2174 /* Do not override the alignment as specified by the ABI when the used
|
|
2175 attribute is set. */
|
|
2176 if (DECL_PRESERVE_P (decl) || DECL_PRESERVE_P (target->decl))
|
|
2177 return false;
|
|
2178
|
|
2179 /* Do not override explicit alignment set by the user when an explicit
|
|
2180 section name is also used. This is a common idiom used by many
|
|
2181 software projects. */
|
|
2182 if (DECL_SECTION_NAME (target->decl) != NULL && !target->implicit_section)
|
|
2183 return false;
|
|
2184
|
|
2185 return true;
|
|
2186 }
|
|
2187
|
|
2188 /* Worker for symtab_node::increase_alignment. */
|
|
2189
|
|
2190 static bool
|
|
2191 increase_alignment_1 (symtab_node *n, void *v)
|
|
2192 {
|
|
2193 unsigned int align = (size_t)v;
|
|
2194 if (DECL_ALIGN (n->decl) < align
|
|
2195 && n->can_increase_alignment_p ())
|
|
2196 {
|
|
2197 SET_DECL_ALIGN (n->decl, align);
|
|
2198 DECL_USER_ALIGN (n->decl) = 1;
|
|
2199 }
|
|
2200 return false;
|
|
2201 }
|
|
2202
|
|
2203 /* Increase alignment of THIS to ALIGN. */
|
|
2204
|
|
2205 void
|
|
2206 symtab_node::increase_alignment (unsigned int align)
|
|
2207 {
|
131
|
2208 gcc_assert (can_increase_alignment_p () && align <= MAX_OFILE_ALIGNMENT);
|
111
|
2209 ultimate_alias_target()->call_for_symbol_and_aliases (increase_alignment_1,
|
|
2210 (void *)(size_t) align,
|
|
2211 true);
|
|
2212 gcc_assert (DECL_ALIGN (decl) >= align);
|
|
2213 }
|
|
2214
|
|
2215 /* Helper for symtab_node::definition_alignment. */
|
|
2216
|
|
2217 static bool
|
|
2218 get_alignment_1 (symtab_node *n, void *v)
|
|
2219 {
|
|
2220 *((unsigned int *)v) = MAX (*((unsigned int *)v), DECL_ALIGN (n->decl));
|
|
2221 return false;
|
|
2222 }
|
|
2223
|
|
2224 /* Return desired alignment of the definition. This is NOT alignment useful
|
|
2225 to access THIS, because THIS may be interposable and DECL_ALIGN should
|
|
2226 be used instead. It however must be guaranteed when output definition
|
|
2227 of THIS. */
|
|
2228
|
|
2229 unsigned int
|
|
2230 symtab_node::definition_alignment ()
|
|
2231 {
|
|
2232 unsigned int align = 0;
|
|
2233 gcc_assert (!alias);
|
|
2234 call_for_symbol_and_aliases (get_alignment_1, &align, true);
|
|
2235 return align;
|
|
2236 }
|
|
2237
|
|
2238 /* Return symbol used to separate symbol name from suffix. */
|
|
2239
|
|
2240 char
|
|
2241 symbol_table::symbol_suffix_separator ()
|
|
2242 {
|
|
2243 #ifndef NO_DOT_IN_LABEL
|
|
2244 return '.';
|
|
2245 #elif !defined NO_DOLLAR_IN_LABEL
|
|
2246 return '$';
|
|
2247 #else
|
|
2248 return '_';
|
|
2249 #endif
|
|
2250 }
|
|
2251
|
|
2252 /* Return true when references to this symbol from REF must bind to current
|
|
2253 definition in final executable. */
|
|
2254
|
|
2255 bool
|
|
2256 symtab_node::binds_to_current_def_p (symtab_node *ref)
|
|
2257 {
|
|
2258 if (!definition)
|
|
2259 return false;
|
|
2260 if (transparent_alias)
|
|
2261 return definition
|
|
2262 && get_alias_target()->binds_to_current_def_p (ref);
|
131
|
2263 cgraph_node *cnode = dyn_cast <cgraph_node *> (this);
|
|
2264 if (cnode && cnode->ifunc_resolver)
|
111
|
2265 return false;
|
|
2266 if (decl_binds_to_current_def_p (decl))
|
|
2267 return true;
|
|
2268
|
|
2269 /* Inline clones always binds locally. */
|
|
2270 if (cnode && cnode->global.inlined_to)
|
|
2271 return true;
|
|
2272
|
|
2273 if (DECL_EXTERNAL (decl))
|
|
2274 return false;
|
|
2275
|
|
2276 gcc_assert (externally_visible);
|
|
2277
|
|
2278 if (ref)
|
|
2279 {
|
|
2280 cgraph_node *cref = dyn_cast <cgraph_node *> (ref);
|
|
2281 if (cref)
|
|
2282 ref = cref->global.inlined_to;
|
|
2283 }
|
|
2284
|
|
2285 /* If this is a reference from symbol itself and there are no aliases, we
|
|
2286 may be sure that the symbol was not interposed by something else because
|
|
2287 the symbol itself would be unreachable otherwise. This is important
|
|
2288 to optimize recursive functions well.
|
|
2289
|
|
2290 This assumption may be broken by inlining: if symbol is interposable
|
|
2291 but the body is available (i.e. declared inline), inliner may make
|
|
2292 the body reachable even with interposition. */
|
|
2293 if (this == ref && !has_aliases_p ()
|
|
2294 && (!cnode
|
|
2295 || symtab->state >= IPA_SSA_AFTER_INLINING
|
|
2296 || get_availability () >= AVAIL_INTERPOSABLE))
|
|
2297 return true;
|
|
2298
|
|
2299
|
|
2300 /* References within one comdat group are always bound in a group. */
|
|
2301 if (ref
|
|
2302 && symtab->state >= IPA_SSA_AFTER_INLINING
|
|
2303 && get_comdat_group ()
|
|
2304 && get_comdat_group () == ref->get_comdat_group ())
|
|
2305 return true;
|
|
2306
|
|
2307 return false;
|
|
2308 }
|
131
|
2309
|
|
2310 /* Return true if symbol should be output to the symbol table. */
|
|
2311
|
|
2312 bool
|
|
2313 symtab_node::output_to_lto_symbol_table_p (void)
|
|
2314 {
|
|
2315 /* Only externally visible symbols matter. */
|
|
2316 if (!TREE_PUBLIC (decl))
|
|
2317 return false;
|
|
2318 if (!real_symbol_p ())
|
|
2319 return false;
|
|
2320 /* FIXME: variables probably should not be considered as real symbols at
|
|
2321 first place. */
|
|
2322 if (VAR_P (decl) && DECL_HARD_REGISTER (decl))
|
|
2323 return false;
|
|
2324 /* FIXME: Builtins corresponding to real functions probably should have
|
|
2325 symbol table entries. */
|
|
2326 if (TREE_CODE (decl) == FUNCTION_DECL && fndecl_built_in_p (decl))
|
|
2327 return false;
|
|
2328
|
|
2329 /* We have real symbol that should be in symbol table. However try to trim
|
|
2330 down the refernces to libraries bit more because linker will otherwise
|
|
2331 bring unnecesary object files into the final link.
|
|
2332 FIXME: The following checks can easily be confused i.e. by self recursive
|
|
2333 function or self-referring variable. */
|
|
2334
|
|
2335 /* We keep external functions in symtab for sake of inlining
|
|
2336 and devirtualization. We do not want to see them in symbol table as
|
|
2337 references unless they are really used. */
|
|
2338 cgraph_node *cnode = dyn_cast <cgraph_node *> (this);
|
|
2339 if (cnode && (!definition || DECL_EXTERNAL (decl))
|
|
2340 && cnode->callers)
|
|
2341 return true;
|
|
2342
|
|
2343 /* Ignore all references from external vars initializers - they are not really
|
|
2344 part of the compilation unit until they are used by folding. Some symbols,
|
|
2345 like references to external construction vtables can not be referred to at
|
|
2346 all. We decide this at can_refer_decl_in_current_unit_p. */
|
|
2347 if (!definition || DECL_EXTERNAL (decl))
|
|
2348 {
|
|
2349 int i;
|
|
2350 struct ipa_ref *ref;
|
|
2351 for (i = 0; iterate_referring (i, ref); i++)
|
|
2352 {
|
|
2353 if (ref->use == IPA_REF_ALIAS)
|
|
2354 continue;
|
|
2355 if (is_a <cgraph_node *> (ref->referring))
|
|
2356 return true;
|
|
2357 if (!DECL_EXTERNAL (ref->referring->decl))
|
|
2358 return true;
|
|
2359 }
|
|
2360 return false;
|
|
2361 }
|
|
2362 return true;
|
|
2363 }
|