]>
Commit | Line | Data |
---|---|---|
2aae7680 | 1 | /* Symbol table. |
d1e082c2 | 2 | Copyright (C) 2012-2013 Free Software Foundation, Inc. |
2aae7680 JH |
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 "tm.h" | |
25 | #include "tree.h" | |
8e9055ae | 26 | #include "gimple.h" |
2aae7680 | 27 | #include "tree-inline.h" |
8f940ee6 | 28 | #include "langhooks.h" |
2aae7680 | 29 | #include "hashtab.h" |
1ab24192 | 30 | #include "ggc.h" |
2aae7680 | 31 | #include "cgraph.h" |
1ab24192 | 32 | #include "diagnostic.h" |
474ffc72 | 33 | #include "timevar.h" |
65d630d4 JH |
34 | #include "lto-streamer.h" |
35 | #include "rtl.h" | |
36 | ||
37 | const char * const ld_plugin_symbol_resolution_names[]= | |
38 | { | |
39 | "", | |
40 | "undef", | |
41 | "prevailing_def", | |
42 | "prevailing_def_ironly", | |
43 | "preempted_reg", | |
44 | "preempted_ir", | |
45 | "resolved_ir", | |
46 | "resolved_exec", | |
47 | "resolved_dyn", | |
48 | "prevailing_def_ironly_exp" | |
49 | }; | |
1ab24192 JH |
50 | |
51 | /* Hash table used to convert declarations into nodes. */ | |
a3bfa8b8 | 52 | static GTY((param_is (symtab_node_base))) htab_t symtab_hash; |
1ab24192 | 53 | /* Hash table used to convert assembler names into nodes. */ |
a3bfa8b8 | 54 | static GTY((param_is (symtab_node_base))) htab_t assembler_name_hash; |
2aae7680 JH |
55 | |
56 | /* Linked list of symbol table nodes. */ | |
57 | symtab_node symtab_nodes; | |
58 | ||
59 | /* The order index of the next symtab node to be created. This is | |
60 | used so that we can sort the cgraph nodes in order by when we saw | |
61 | them, to support -fno-toplevel-reorder. */ | |
62 | int symtab_order; | |
63 | ||
1ab24192 JH |
64 | /* Returns a hash code for P. */ |
65 | ||
66 | static hashval_t | |
67 | hash_node (const void *p) | |
68 | { | |
69 | const_symtab_node n = (const_symtab_node ) p; | |
67348ccc | 70 | return (hashval_t) DECL_UID (n->decl); |
1ab24192 JH |
71 | } |
72 | ||
73 | ||
74 | /* Returns nonzero if P1 and P2 are equal. */ | |
75 | ||
76 | static int | |
77 | eq_node (const void *p1, const void *p2) | |
78 | { | |
79 | const_symtab_node n1 = (const_symtab_node) p1; | |
80 | const_symtab_node n2 = (const_symtab_node) p2; | |
67348ccc | 81 | return DECL_UID (n1->decl) == DECL_UID (n2->decl); |
1ab24192 JH |
82 | } |
83 | ||
84 | /* Returns a hash code for P. */ | |
85 | ||
86 | static hashval_t | |
87 | hash_node_by_assembler_name (const void *p) | |
88 | { | |
89 | const_symtab_node n = (const_symtab_node) p; | |
67348ccc | 90 | return (hashval_t) decl_assembler_name_hash (DECL_ASSEMBLER_NAME (n->decl)); |
1ab24192 JH |
91 | } |
92 | ||
93 | /* Returns nonzero if P1 and P2 are equal. */ | |
94 | ||
95 | static int | |
96 | eq_assembler_name (const void *p1, const void *p2) | |
97 | { | |
98 | const_symtab_node n1 = (const_symtab_node) p1; | |
99 | const_tree name = (const_tree)p2; | |
67348ccc | 100 | return (decl_assembler_name_equal (n1->decl, name)); |
1ab24192 JH |
101 | } |
102 | ||
103 | /* Insert NODE to assembler name hash. */ | |
104 | ||
105 | static void | |
c3167b00 | 106 | insert_to_assembler_name_hash (symtab_node node, bool with_clones) |
1ab24192 | 107 | { |
67348ccc | 108 | if (is_a <varpool_node> (node) && DECL_HARD_REGISTER (node->decl)) |
b5493fb2 | 109 | return; |
67348ccc DM |
110 | gcc_checking_assert (!node->previous_sharing_asm_name |
111 | && !node->next_sharing_asm_name); | |
1ab24192 JH |
112 | if (assembler_name_hash) |
113 | { | |
114 | void **aslot; | |
c3167b00 | 115 | struct cgraph_node *cnode; |
67348ccc | 116 | tree decl = node->decl; |
c3167b00 | 117 | |
67348ccc | 118 | tree name = DECL_ASSEMBLER_NAME (node->decl); |
1ab24192 JH |
119 | |
120 | aslot = htab_find_slot_with_hash (assembler_name_hash, name, | |
121 | decl_assembler_name_hash (name), | |
122 | INSERT); | |
123 | gcc_assert (*aslot != node); | |
67348ccc | 124 | node->next_sharing_asm_name = (symtab_node)*aslot; |
1ab24192 | 125 | if (*aslot != NULL) |
67348ccc | 126 | ((symtab_node)*aslot)->previous_sharing_asm_name = node; |
1ab24192 | 127 | *aslot = node; |
c3167b00 JH |
128 | |
129 | /* Update also possible inline clones sharing a decl. */ | |
130 | cnode = dyn_cast <cgraph_node> (node); | |
131 | if (cnode && cnode->clones && with_clones) | |
132 | for (cnode = cnode->clones; cnode; cnode = cnode->next_sibling_clone) | |
67348ccc DM |
133 | if (cnode->decl == decl) |
134 | insert_to_assembler_name_hash (cnode, true); | |
1ab24192 JH |
135 | } |
136 | ||
137 | } | |
138 | ||
139 | /* Remove NODE from assembler name hash. */ | |
140 | ||
141 | static void | |
c3167b00 | 142 | unlink_from_assembler_name_hash (symtab_node node, bool with_clones) |
1ab24192 JH |
143 | { |
144 | if (assembler_name_hash) | |
145 | { | |
c3167b00 | 146 | struct cgraph_node *cnode; |
67348ccc | 147 | tree decl = node->decl; |
c3167b00 | 148 | |
67348ccc DM |
149 | if (node->next_sharing_asm_name) |
150 | node->next_sharing_asm_name->previous_sharing_asm_name | |
151 | = node->previous_sharing_asm_name; | |
152 | if (node->previous_sharing_asm_name) | |
1ab24192 | 153 | { |
67348ccc DM |
154 | node->previous_sharing_asm_name->next_sharing_asm_name |
155 | = node->next_sharing_asm_name; | |
1ab24192 JH |
156 | } |
157 | else | |
158 | { | |
67348ccc | 159 | tree name = DECL_ASSEMBLER_NAME (node->decl); |
1ab24192 JH |
160 | void **slot; |
161 | slot = htab_find_slot_with_hash (assembler_name_hash, name, | |
162 | decl_assembler_name_hash (name), | |
163 | NO_INSERT); | |
164 | gcc_assert (*slot == node); | |
67348ccc | 165 | if (!node->next_sharing_asm_name) |
1ab24192 JH |
166 | htab_clear_slot (assembler_name_hash, slot); |
167 | else | |
67348ccc | 168 | *slot = node->next_sharing_asm_name; |
1ab24192 | 169 | } |
67348ccc DM |
170 | node->next_sharing_asm_name = NULL; |
171 | node->previous_sharing_asm_name = NULL; | |
c3167b00 JH |
172 | |
173 | /* Update also possible inline clones sharing a decl. */ | |
174 | cnode = dyn_cast <cgraph_node> (node); | |
175 | if (cnode && cnode->clones && with_clones) | |
176 | for (cnode = cnode->clones; cnode; cnode = cnode->next_sibling_clone) | |
67348ccc DM |
177 | if (cnode->decl == decl) |
178 | unlink_from_assembler_name_hash (cnode, true); | |
1ab24192 JH |
179 | } |
180 | } | |
181 | ||
b5493fb2 JH |
182 | /* Arrange node to be first in its entry of assembler_name_hash. */ |
183 | ||
184 | void | |
185 | symtab_prevail_in_asm_name_hash (symtab_node node) | |
186 | { | |
c3167b00 JH |
187 | unlink_from_assembler_name_hash (node, false); |
188 | insert_to_assembler_name_hash (node, false); | |
b5493fb2 JH |
189 | } |
190 | ||
1ab24192 | 191 | |
2aae7680 JH |
192 | /* Add node into symbol table. This function is not used directly, but via |
193 | cgraph/varpool node creation routines. */ | |
194 | ||
195 | void | |
196 | symtab_register_node (symtab_node node) | |
197 | { | |
1ab24192 JH |
198 | struct symtab_node_base key; |
199 | symtab_node *slot; | |
200 | ||
67348ccc DM |
201 | node->next = symtab_nodes; |
202 | node->previous = NULL; | |
2aae7680 | 203 | if (symtab_nodes) |
67348ccc | 204 | symtab_nodes->previous = node; |
2aae7680 JH |
205 | symtab_nodes = node; |
206 | ||
1ab24192 JH |
207 | if (!symtab_hash) |
208 | symtab_hash = htab_create_ggc (10, hash_node, eq_node, NULL); | |
67348ccc | 209 | key.decl = node->decl; |
1ab24192 JH |
210 | slot = (symtab_node *) htab_find_slot (symtab_hash, &key, INSERT); |
211 | if (*slot == NULL) | |
212 | *slot = node; | |
213 | ||
67348ccc | 214 | ipa_empty_ref_list (&node->ref_list); |
1ab24192 | 215 | |
67348ccc | 216 | node->order = symtab_order++; |
2aae7680 | 217 | |
66379195 JH |
218 | /* Be sure to do this last; C++ FE might create new nodes via |
219 | DECL_ASSEMBLER_NAME langhook! */ | |
c3167b00 | 220 | insert_to_assembler_name_hash (node, false); |
2aae7680 JH |
221 | } |
222 | ||
1ab24192 JH |
223 | /* Make NODE to be the one symtab hash is pointing to. Used when reshaping tree |
224 | of inline clones. */ | |
225 | ||
226 | void | |
227 | symtab_insert_node_to_hashtable (symtab_node node) | |
228 | { | |
229 | struct symtab_node_base key; | |
230 | symtab_node *slot; | |
231 | ||
232 | if (!symtab_hash) | |
233 | symtab_hash = htab_create_ggc (10, hash_node, eq_node, NULL); | |
67348ccc | 234 | key.decl = node->decl; |
1ab24192 JH |
235 | slot = (symtab_node *) htab_find_slot (symtab_hash, &key, INSERT); |
236 | *slot = node; | |
237 | } | |
238 | ||
2aae7680 JH |
239 | /* Remove node from symbol table. This function is not used directly, but via |
240 | cgraph/varpool node removal routines. */ | |
241 | ||
242 | void | |
243 | symtab_unregister_node (symtab_node node) | |
244 | { | |
1ab24192 | 245 | void **slot; |
67348ccc DM |
246 | ipa_remove_all_references (&node->ref_list); |
247 | ipa_remove_all_referring (&node->ref_list); | |
2aae7680 | 248 | |
67348ccc | 249 | if (node->same_comdat_group) |
2aae7680 JH |
250 | { |
251 | symtab_node prev; | |
67348ccc DM |
252 | for (prev = node->same_comdat_group; |
253 | prev->same_comdat_group != node; | |
254 | prev = prev->same_comdat_group) | |
2aae7680 | 255 | ; |
67348ccc DM |
256 | if (node->same_comdat_group == prev) |
257 | prev->same_comdat_group = NULL; | |
2aae7680 | 258 | else |
67348ccc DM |
259 | prev->same_comdat_group = node->same_comdat_group; |
260 | node->same_comdat_group = NULL; | |
2aae7680 JH |
261 | } |
262 | ||
67348ccc DM |
263 | if (node->previous) |
264 | node->previous->next = node->next; | |
2aae7680 | 265 | else |
67348ccc DM |
266 | symtab_nodes = node->next; |
267 | if (node->next) | |
268 | node->next->previous = node->previous; | |
269 | node->next = NULL; | |
270 | node->previous = NULL; | |
1ab24192 JH |
271 | |
272 | slot = htab_find_slot (symtab_hash, node, NO_INSERT); | |
bbf9ad07 JH |
273 | |
274 | /* During LTO symtab merging we temporarily corrupt decl to symtab node | |
275 | hash. */ | |
276 | gcc_assert ((slot && *slot) || in_lto_p); | |
277 | if (slot && *slot && *slot == node) | |
1ab24192 JH |
278 | { |
279 | symtab_node replacement_node = NULL; | |
5d59b5e1 | 280 | if (cgraph_node *cnode = dyn_cast <cgraph_node> (node)) |
67348ccc | 281 | replacement_node = cgraph_find_replacement_node (cnode); |
1ab24192 JH |
282 | if (!replacement_node) |
283 | htab_clear_slot (symtab_hash, slot); | |
284 | else | |
285 | *slot = replacement_node; | |
286 | } | |
67348ccc | 287 | if (!is_a <varpool_node> (node) || !DECL_HARD_REGISTER (node->decl)) |
8e4c9a10 | 288 | unlink_from_assembler_name_hash (node, false); |
1ab24192 JH |
289 | } |
290 | ||
291 | /* Return symbol table node associated with DECL, if any, | |
292 | and NULL otherwise. */ | |
293 | ||
294 | symtab_node | |
295 | symtab_get_node (const_tree decl) | |
296 | { | |
297 | symtab_node *slot; | |
298 | struct symtab_node_base key; | |
299 | ||
bbf9ad07 JH |
300 | #ifdef ENABLE_CHECKING |
301 | /* Check that we are called for sane type of object - functions | |
302 | and static or external variables. */ | |
1ab24192 JH |
303 | gcc_checking_assert (TREE_CODE (decl) == FUNCTION_DECL |
304 | || (TREE_CODE (decl) == VAR_DECL | |
305 | && (TREE_STATIC (decl) || DECL_EXTERNAL (decl) | |
306 | || in_lto_p))); | |
bbf9ad07 | 307 | #endif |
1ab24192 JH |
308 | |
309 | if (!symtab_hash) | |
310 | return NULL; | |
311 | ||
312 | key.decl = CONST_CAST2 (tree, const_tree, decl); | |
313 | ||
314 | slot = (symtab_node *) htab_find_slot (symtab_hash, &key, | |
315 | NO_INSERT); | |
316 | ||
317 | if (slot) | |
318 | return *slot; | |
319 | return NULL; | |
2aae7680 JH |
320 | } |
321 | ||
322 | /* Remove symtab NODE from the symbol table. */ | |
323 | ||
324 | void | |
325 | symtab_remove_node (symtab_node node) | |
326 | { | |
5d59b5e1 LC |
327 | if (cgraph_node *cnode = dyn_cast <cgraph_node> (node)) |
328 | cgraph_remove_node (cnode); | |
329 | else if (varpool_node *vnode = dyn_cast <varpool_node> (node)) | |
330 | varpool_remove_node (vnode); | |
2aae7680 | 331 | } |
1ab24192 | 332 | |
b5493fb2 | 333 | /* Initalize asm name hash unless. */ |
1ab24192 | 334 | |
b5493fb2 JH |
335 | void |
336 | symtab_initialize_asm_name_hash (void) | |
1ab24192 JH |
337 | { |
338 | symtab_node node; | |
1ab24192 JH |
339 | if (!assembler_name_hash) |
340 | { | |
341 | assembler_name_hash = | |
342 | htab_create_ggc (10, hash_node_by_assembler_name, eq_assembler_name, | |
343 | NULL); | |
344 | FOR_EACH_SYMBOL (node) | |
c3167b00 | 345 | insert_to_assembler_name_hash (node, false); |
1ab24192 | 346 | } |
b5493fb2 | 347 | } |
1ab24192 | 348 | |
b5493fb2 JH |
349 | /* Return the cgraph node that has ASMNAME for its DECL_ASSEMBLER_NAME. |
350 | Return NULL if there's no such node. */ | |
351 | ||
352 | symtab_node | |
353 | symtab_node_for_asm (const_tree asmname) | |
354 | { | |
355 | symtab_node node; | |
356 | void **slot; | |
357 | ||
358 | symtab_initialize_asm_name_hash (); | |
1ab24192 JH |
359 | slot = htab_find_slot_with_hash (assembler_name_hash, asmname, |
360 | decl_assembler_name_hash (asmname), | |
361 | NO_INSERT); | |
362 | ||
363 | if (slot) | |
364 | { | |
365 | node = (symtab_node) *slot; | |
366 | return node; | |
367 | } | |
368 | return NULL; | |
369 | } | |
370 | ||
371 | /* Set the DECL_ASSEMBLER_NAME and update symtab hashtables. */ | |
372 | ||
373 | void | |
374 | change_decl_assembler_name (tree decl, tree name) | |
375 | { | |
376 | symtab_node node = NULL; | |
377 | ||
378 | /* We can have user ASM names on things, like global register variables, that | |
379 | are not in the symbol table. */ | |
380 | if ((TREE_CODE (decl) == VAR_DECL | |
381 | && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))) | |
382 | || TREE_CODE (decl) == FUNCTION_DECL) | |
383 | node = symtab_get_node (decl); | |
384 | if (!DECL_ASSEMBLER_NAME_SET_P (decl)) | |
385 | { | |
386 | SET_DECL_ASSEMBLER_NAME (decl, name); | |
387 | if (node) | |
c3167b00 | 388 | insert_to_assembler_name_hash (node, true); |
1ab24192 JH |
389 | } |
390 | else | |
391 | { | |
392 | if (name == DECL_ASSEMBLER_NAME (decl)) | |
393 | return; | |
394 | ||
8a41354f JH |
395 | tree alias = (IDENTIFIER_TRANSPARENT_ALIAS (DECL_ASSEMBLER_NAME (decl)) |
396 | ? TREE_CHAIN (DECL_ASSEMBLER_NAME (decl)) | |
397 | : NULL); | |
1ab24192 | 398 | if (node) |
c3167b00 | 399 | unlink_from_assembler_name_hash (node, true); |
1ab24192 JH |
400 | if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) |
401 | && DECL_RTL_SET_P (decl)) | |
402 | warning (0, "%D renamed after being referenced in assembly", decl); | |
403 | ||
404 | SET_DECL_ASSEMBLER_NAME (decl, name); | |
8a41354f JH |
405 | if (alias) |
406 | { | |
407 | IDENTIFIER_TRANSPARENT_ALIAS (name) = 1; | |
408 | TREE_CHAIN (DECL_ASSEMBLER_NAME (name)) = alias; | |
409 | } | |
1ab24192 | 410 | if (node) |
c3167b00 | 411 | insert_to_assembler_name_hash (node, true); |
1ab24192 JH |
412 | } |
413 | } | |
414 | ||
65d630d4 JH |
415 | /* Add NEW_ to the same comdat group that OLD is in. */ |
416 | ||
417 | void | |
418 | symtab_add_to_same_comdat_group (symtab_node new_node, | |
419 | symtab_node old_node) | |
420 | { | |
67348ccc DM |
421 | gcc_assert (DECL_ONE_ONLY (old_node->decl)); |
422 | gcc_assert (!new_node->same_comdat_group); | |
65d630d4 JH |
423 | gcc_assert (new_node != old_node); |
424 | ||
67348ccc DM |
425 | DECL_COMDAT_GROUP (new_node->decl) = DECL_COMDAT_GROUP (old_node->decl); |
426 | new_node->same_comdat_group = old_node; | |
427 | if (!old_node->same_comdat_group) | |
428 | old_node->same_comdat_group = new_node; | |
65d630d4 JH |
429 | else |
430 | { | |
431 | symtab_node n; | |
67348ccc DM |
432 | for (n = old_node->same_comdat_group; |
433 | n->same_comdat_group != old_node; | |
434 | n = n->same_comdat_group) | |
65d630d4 | 435 | ; |
67348ccc | 436 | n->same_comdat_group = new_node; |
65d630d4 JH |
437 | } |
438 | } | |
439 | ||
440 | /* Dissolve the same_comdat_group list in which NODE resides. */ | |
441 | ||
442 | void | |
443 | symtab_dissolve_same_comdat_group_list (symtab_node node) | |
444 | { | |
445 | symtab_node n = node, next; | |
446 | ||
67348ccc | 447 | if (!node->same_comdat_group) |
65d630d4 JH |
448 | return; |
449 | do | |
450 | { | |
67348ccc DM |
451 | next = n->same_comdat_group; |
452 | n->same_comdat_group = NULL; | |
65d630d4 JH |
453 | n = next; |
454 | } | |
455 | while (n != node); | |
456 | } | |
457 | ||
8f940ee6 JH |
458 | /* Return printable assembler name of NODE. |
459 | This function is used only for debugging. When assembler name | |
460 | is unknown go with identifier name. */ | |
461 | ||
462 | const char * | |
463 | symtab_node_asm_name (symtab_node node) | |
464 | { | |
67348ccc DM |
465 | if (!DECL_ASSEMBLER_NAME_SET_P (node->decl)) |
466 | return lang_hooks.decl_printable_name (node->decl, 2); | |
467 | return IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->decl)); | |
8f940ee6 JH |
468 | } |
469 | ||
470 | /* Return printable identifier name. */ | |
471 | ||
472 | const char * | |
473 | symtab_node_name (symtab_node node) | |
474 | { | |
67348ccc | 475 | return lang_hooks.decl_printable_name (node->decl, 2); |
8f940ee6 JH |
476 | } |
477 | ||
478 | static const char * const symtab_type_names[] = {"symbol", "function", "variable"}; | |
479 | ||
480 | /* Dump base fields of symtab nodes. Not to be used directly. */ | |
481 | ||
482 | void | |
483 | dump_symtab_base (FILE *f, symtab_node node) | |
484 | { | |
485 | static const char * const visibility_types[] = { | |
486 | "default", "protected", "hidden", "internal" | |
487 | }; | |
488 | ||
489 | fprintf (f, "%s/%i (%s)", | |
490 | symtab_node_asm_name (node), | |
67348ccc | 491 | node->order, |
8f940ee6 JH |
492 | symtab_node_name (node)); |
493 | dump_addr (f, " @", (void *)node); | |
67348ccc | 494 | fprintf (f, "\n Type: %s", symtab_type_names[node->type]); |
e70670cf | 495 | |
67348ccc | 496 | if (node->definition) |
e70670cf | 497 | fprintf (f, " definition"); |
67348ccc | 498 | if (node->analyzed) |
e70670cf | 499 | fprintf (f, " analyzed"); |
67348ccc | 500 | if (node->alias) |
e70670cf | 501 | fprintf (f, " alias"); |
67348ccc | 502 | if (node->weakref) |
08346abd | 503 | fprintf (f, " weakref"); |
67348ccc | 504 | if (node->cpp_implicit_alias) |
40a7fe1e | 505 | fprintf (f, " cpp_implicit_alias"); |
67348ccc | 506 | if (node->alias_target) |
40a7fe1e | 507 | fprintf (f, " target:%s", |
67348ccc | 508 | DECL_P (node->alias_target) |
40a7fe1e | 509 | ? IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME |
67348ccc DM |
510 | (node->alias_target)) |
511 | : IDENTIFIER_POINTER (node->alias_target)); | |
e70670cf | 512 | fprintf (f, "\n Visibility:"); |
67348ccc | 513 | if (node->in_other_partition) |
8f940ee6 | 514 | fprintf (f, " in_other_partition"); |
67348ccc | 515 | if (node->used_from_other_partition) |
8f940ee6 | 516 | fprintf (f, " used_from_other_partition"); |
67348ccc | 517 | if (node->force_output) |
ead84f73 | 518 | fprintf (f, " force_output"); |
67348ccc | 519 | if (node->forced_by_abi) |
edb983b2 | 520 | fprintf (f, " forced_by_abi"); |
67348ccc | 521 | if (node->externally_visible) |
e5b962d0 | 522 | fprintf (f, " externally_visible"); |
67348ccc | 523 | if (node->resolution != LDPR_UNKNOWN) |
8f940ee6 | 524 | fprintf (f, " %s", |
67348ccc DM |
525 | ld_plugin_symbol_resolution_names[(int)node->resolution]); |
526 | if (TREE_ASM_WRITTEN (node->decl)) | |
8f940ee6 | 527 | fprintf (f, " asm_written"); |
67348ccc | 528 | if (DECL_EXTERNAL (node->decl)) |
8f940ee6 | 529 | fprintf (f, " external"); |
67348ccc | 530 | if (TREE_PUBLIC (node->decl)) |
8f940ee6 | 531 | fprintf (f, " public"); |
67348ccc | 532 | if (DECL_COMMON (node->decl)) |
8f940ee6 | 533 | fprintf (f, " common"); |
67348ccc | 534 | if (DECL_WEAK (node->decl)) |
8f940ee6 | 535 | fprintf (f, " weak"); |
67348ccc | 536 | if (DECL_DLLIMPORT_P (node->decl)) |
8f940ee6 | 537 | fprintf (f, " dll_import"); |
67348ccc | 538 | if (DECL_COMDAT (node->decl)) |
8f940ee6 | 539 | fprintf (f, " comdat"); |
67348ccc | 540 | if (DECL_COMDAT_GROUP (node->decl)) |
8f940ee6 | 541 | fprintf (f, " comdat_group:%s", |
67348ccc DM |
542 | IDENTIFIER_POINTER (DECL_COMDAT_GROUP (node->decl))); |
543 | if (DECL_ONE_ONLY (node->decl)) | |
8f940ee6 | 544 | fprintf (f, " one_only"); |
67348ccc | 545 | if (DECL_SECTION_NAME (node->decl)) |
8f940ee6 | 546 | fprintf (f, " section_name:%s", |
67348ccc DM |
547 | TREE_STRING_POINTER (DECL_SECTION_NAME (node->decl))); |
548 | if (DECL_VISIBILITY_SPECIFIED (node->decl)) | |
8f940ee6 | 549 | fprintf (f, " visibility_specified"); |
67348ccc | 550 | if (DECL_VISIBILITY (node->decl)) |
8f940ee6 | 551 | fprintf (f, " visibility:%s", |
67348ccc DM |
552 | visibility_types [DECL_VISIBILITY (node->decl)]); |
553 | if (DECL_VIRTUAL_P (node->decl)) | |
8f940ee6 | 554 | fprintf (f, " virtual"); |
67348ccc | 555 | if (DECL_ARTIFICIAL (node->decl)) |
8f940ee6 | 556 | fprintf (f, " artificial"); |
67348ccc | 557 | if (TREE_CODE (node->decl) == FUNCTION_DECL) |
838ff415 | 558 | { |
67348ccc | 559 | if (DECL_STATIC_CONSTRUCTOR (node->decl)) |
838ff415 | 560 | fprintf (f, " constructor"); |
67348ccc | 561 | if (DECL_STATIC_DESTRUCTOR (node->decl)) |
838ff415 JH |
562 | fprintf (f, " destructor"); |
563 | } | |
8f940ee6 JH |
564 | fprintf (f, "\n"); |
565 | ||
67348ccc | 566 | if (node->same_comdat_group) |
8f940ee6 | 567 | fprintf (f, " Same comdat group as: %s/%i\n", |
67348ccc DM |
568 | symtab_node_asm_name (node->same_comdat_group), |
569 | node->same_comdat_group->order); | |
570 | if (node->next_sharing_asm_name) | |
8f940ee6 | 571 | fprintf (f, " next sharing asm name: %i\n", |
67348ccc DM |
572 | node->next_sharing_asm_name->order); |
573 | if (node->previous_sharing_asm_name) | |
8f940ee6 | 574 | fprintf (f, " previous sharing asm name: %i\n", |
67348ccc | 575 | node->previous_sharing_asm_name->order); |
8f940ee6 | 576 | |
67348ccc | 577 | if (node->address_taken) |
fe0bd630 | 578 | fprintf (f, " Address is taken.\n"); |
67348ccc | 579 | if (node->aux) |
66058468 JH |
580 | { |
581 | fprintf (f, " Aux:"); | |
67348ccc | 582 | dump_addr (f, " @", (void *)node->aux); |
66058468 | 583 | } |
8f940ee6 JH |
584 | |
585 | fprintf (f, " References: "); | |
67348ccc | 586 | ipa_dump_references (f, &node->ref_list); |
5932a4d4 | 587 | fprintf (f, " Referring: "); |
67348ccc DM |
588 | ipa_dump_referring (f, &node->ref_list); |
589 | if (node->lto_file_data) | |
b5493fb2 | 590 | fprintf (f, " Read from file: %s\n", |
67348ccc | 591 | node->lto_file_data->file_name); |
8f940ee6 JH |
592 | } |
593 | ||
594 | /* Dump symtab node. */ | |
595 | ||
596 | void | |
597 | dump_symtab_node (FILE *f, symtab_node node) | |
598 | { | |
5d59b5e1 LC |
599 | if (cgraph_node *cnode = dyn_cast <cgraph_node> (node)) |
600 | dump_cgraph_node (f, cnode); | |
601 | else if (varpool_node *vnode = dyn_cast <varpool_node> (node)) | |
602 | dump_varpool_node (f, vnode); | |
8f940ee6 JH |
603 | } |
604 | ||
605 | /* Dump symbol table. */ | |
606 | ||
607 | void | |
608 | dump_symtab (FILE *f) | |
609 | { | |
610 | symtab_node node; | |
611 | fprintf (f, "Symbol table:\n\n"); | |
612 | FOR_EACH_SYMBOL (node) | |
613 | dump_symtab_node (f, node); | |
614 | } | |
615 | ||
616 | /* Dump symtab node NODE to stderr. */ | |
617 | ||
618 | DEBUG_FUNCTION void | |
619 | debug_symtab_node (symtab_node node) | |
620 | { | |
621 | dump_symtab_node (stderr, node); | |
622 | } | |
623 | ||
624 | /* Dump symbol table to stderr. */ | |
625 | ||
626 | DEBUG_FUNCTION void | |
627 | debug_symtab (void) | |
628 | { | |
629 | dump_symtab (stderr); | |
630 | } | |
631 | ||
474ffc72 JH |
632 | /* Verify common part of symtab nodes. */ |
633 | ||
634 | DEBUG_FUNCTION bool | |
635 | verify_symtab_base (symtab_node node) | |
636 | { | |
637 | bool error_found = false; | |
638 | symtab_node hashed_node; | |
639 | ||
5d59b5e1 | 640 | if (is_a <cgraph_node> (node)) |
474ffc72 | 641 | { |
67348ccc | 642 | if (TREE_CODE (node->decl) != FUNCTION_DECL) |
474ffc72 JH |
643 | { |
644 | error ("function symbol is not function"); | |
645 | error_found = true; | |
646 | } | |
647 | } | |
5d59b5e1 | 648 | else if (is_a <varpool_node> (node)) |
474ffc72 | 649 | { |
67348ccc | 650 | if (TREE_CODE (node->decl) != VAR_DECL) |
474ffc72 JH |
651 | { |
652 | error ("variable symbol is not variable"); | |
653 | error_found = true; | |
654 | } | |
655 | } | |
656 | else | |
657 | { | |
658 | error ("node has unknown type"); | |
659 | error_found = true; | |
660 | } | |
661 | ||
ca0f62a8 | 662 | if (cgraph_state != CGRAPH_LTO_STREAMING) |
474ffc72 | 663 | { |
67348ccc | 664 | hashed_node = symtab_get_node (node->decl); |
ca0f62a8 JH |
665 | if (!hashed_node) |
666 | { | |
667 | error ("node not found in symtab decl hashtable"); | |
668 | error_found = true; | |
669 | } | |
e5b962d0 JH |
670 | if (hashed_node != node |
671 | && (!is_a <cgraph_node> (node) | |
672 | || !dyn_cast <cgraph_node> (node)->clone_of | |
67348ccc DM |
673 | || dyn_cast <cgraph_node> (node)->clone_of->decl |
674 | != node->decl)) | |
e5b962d0 JH |
675 | { |
676 | error ("node differs from symtab decl hashtable"); | |
677 | error_found = true; | |
678 | } | |
474ffc72 JH |
679 | } |
680 | if (assembler_name_hash) | |
681 | { | |
67348ccc DM |
682 | hashed_node = symtab_node_for_asm (DECL_ASSEMBLER_NAME (node->decl)); |
683 | if (hashed_node && hashed_node->previous_sharing_asm_name) | |
474ffc72 JH |
684 | { |
685 | error ("assembler name hash list corrupted"); | |
686 | error_found = true; | |
687 | } | |
688 | while (hashed_node) | |
689 | { | |
690 | if (hashed_node == node) | |
691 | break; | |
67348ccc | 692 | hashed_node = hashed_node->next_sharing_asm_name; |
474ffc72 | 693 | } |
b5493fb2 | 694 | if (!hashed_node |
5d59b5e1 | 695 | && !(is_a <varpool_node> (node) |
67348ccc | 696 | || DECL_HARD_REGISTER (node->decl))) |
474ffc72 JH |
697 | { |
698 | error ("node not found in symtab assembler name hash"); | |
699 | error_found = true; | |
700 | } | |
701 | } | |
67348ccc DM |
702 | if (node->previous_sharing_asm_name |
703 | && node->previous_sharing_asm_name->next_sharing_asm_name != node) | |
474ffc72 JH |
704 | { |
705 | error ("double linked list of assembler names corrupted"); | |
e70670cf JH |
706 | error_found = true; |
707 | } | |
67348ccc | 708 | if (node->analyzed && !node->definition) |
e70670cf JH |
709 | { |
710 | error ("node is analyzed byt it is not a definition"); | |
711 | error_found = true; | |
474ffc72 | 712 | } |
67348ccc | 713 | if (node->cpp_implicit_alias && !node->alias) |
40a7fe1e JH |
714 | { |
715 | error ("node is alias but not implicit alias"); | |
716 | error_found = true; | |
717 | } | |
67348ccc DM |
718 | if (node->alias && !node->definition |
719 | && !node->weakref) | |
40a7fe1e JH |
720 | { |
721 | error ("node is alias but not definition"); | |
722 | error_found = true; | |
723 | } | |
67348ccc | 724 | if (node->weakref && !node->alias) |
08346abd JH |
725 | { |
726 | error ("node is weakref but not an alias"); | |
727 | error_found = true; | |
728 | } | |
67348ccc | 729 | if (node->same_comdat_group) |
474ffc72 | 730 | { |
67348ccc | 731 | symtab_node n = node->same_comdat_group; |
474ffc72 | 732 | |
67348ccc | 733 | if (!DECL_ONE_ONLY (n->decl)) |
474ffc72 JH |
734 | { |
735 | error ("non-DECL_ONE_ONLY node in a same_comdat_group list"); | |
736 | error_found = true; | |
737 | } | |
67348ccc | 738 | if (n->type != node->type) |
474ffc72 JH |
739 | { |
740 | error ("mixing different types of symbol in same comdat groups is not supported"); | |
741 | error_found = true; | |
742 | } | |
743 | if (n == node) | |
744 | { | |
745 | error ("node is alone in a comdat group"); | |
746 | error_found = true; | |
747 | } | |
748 | do | |
749 | { | |
67348ccc | 750 | if (!n->same_comdat_group) |
474ffc72 JH |
751 | { |
752 | error ("same_comdat_group is not a circular list"); | |
753 | error_found = true; | |
754 | break; | |
755 | } | |
67348ccc | 756 | n = n->same_comdat_group; |
474ffc72 JH |
757 | } |
758 | while (n != node); | |
759 | } | |
760 | return error_found; | |
761 | } | |
762 | ||
763 | /* Verify consistency of NODE. */ | |
764 | ||
765 | DEBUG_FUNCTION void | |
766 | verify_symtab_node (symtab_node node) | |
767 | { | |
768 | if (seen_error ()) | |
769 | return; | |
770 | ||
771 | timevar_push (TV_CGRAPH_VERIFY); | |
5d59b5e1 LC |
772 | if (cgraph_node *cnode = dyn_cast <cgraph_node> (node)) |
773 | verify_cgraph_node (cnode); | |
474ffc72 JH |
774 | else |
775 | if (verify_symtab_base (node)) | |
776 | { | |
777 | dump_symtab_node (stderr, node); | |
778 | internal_error ("verify_symtab_node failed"); | |
779 | } | |
780 | timevar_pop (TV_CGRAPH_VERIFY); | |
781 | } | |
782 | ||
783 | /* Verify symbol table for internal consistency. */ | |
784 | ||
785 | DEBUG_FUNCTION void | |
786 | verify_symtab (void) | |
787 | { | |
788 | symtab_node node; | |
789 | FOR_EACH_SYMBOL (node) | |
790 | verify_symtab_node (node); | |
791 | } | |
792 | ||
65d630d4 JH |
793 | /* Return true when RESOLUTION indicate that linker will use |
794 | the symbol from non-LTO object files. */ | |
795 | ||
796 | bool | |
797 | resolution_used_from_other_file_p (enum ld_plugin_symbol_resolution resolution) | |
798 | { | |
799 | return (resolution == LDPR_PREVAILING_DEF | |
800 | || resolution == LDPR_PREEMPTED_REG | |
801 | || resolution == LDPR_RESOLVED_EXEC | |
802 | || resolution == LDPR_RESOLVED_DYN); | |
803 | } | |
804 | ||
805 | /* Return true when NODE is known to be used from other (non-LTO) object file. | |
806 | Known only when doing LTO via linker plugin. */ | |
807 | ||
808 | bool | |
809 | symtab_used_from_object_file_p (symtab_node node) | |
810 | { | |
67348ccc | 811 | if (!TREE_PUBLIC (node->decl) || DECL_EXTERNAL (node->decl)) |
65d630d4 | 812 | return false; |
67348ccc | 813 | if (resolution_used_from_other_file_p (node->resolution)) |
65d630d4 JH |
814 | return true; |
815 | return false; | |
816 | } | |
817 | ||
818 | /* Make DECL local. FIXME: We shouldn't need to mess with rtl this early, | |
819 | but other code such as notice_global_symbol generates rtl. */ | |
40a7fe1e | 820 | |
65d630d4 JH |
821 | void |
822 | symtab_make_decl_local (tree decl) | |
823 | { | |
824 | rtx rtl, symbol; | |
825 | ||
826 | if (TREE_CODE (decl) == VAR_DECL) | |
827 | DECL_COMMON (decl) = 0; | |
828 | else gcc_assert (TREE_CODE (decl) == FUNCTION_DECL); | |
829 | ||
830 | if (DECL_ONE_ONLY (decl) || DECL_COMDAT (decl)) | |
831 | { | |
65d630d4 JH |
832 | DECL_SECTION_NAME (decl) = 0; |
833 | DECL_COMDAT (decl) = 0; | |
834 | } | |
835 | DECL_COMDAT_GROUP (decl) = 0; | |
836 | DECL_WEAK (decl) = 0; | |
837 | DECL_EXTERNAL (decl) = 0; | |
b5493fb2 JH |
838 | DECL_VISIBILITY_SPECIFIED (decl) = 0; |
839 | DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT; | |
65d630d4 JH |
840 | TREE_PUBLIC (decl) = 0; |
841 | if (!DECL_RTL_SET_P (decl)) | |
842 | return; | |
843 | ||
844 | /* Update rtl flags. */ | |
845 | make_decl_rtl (decl); | |
846 | ||
847 | rtl = DECL_RTL (decl); | |
848 | if (!MEM_P (rtl)) | |
849 | return; | |
850 | ||
851 | symbol = XEXP (rtl, 0); | |
852 | if (GET_CODE (symbol) != SYMBOL_REF) | |
853 | return; | |
854 | ||
855 | SYMBOL_REF_WEAK (symbol) = DECL_WEAK (decl); | |
856 | } | |
e70670cf | 857 | |
40a7fe1e JH |
858 | /* Return availability of NODE. */ |
859 | ||
860 | enum availability | |
861 | symtab_node_availability (symtab_node node) | |
862 | { | |
863 | if (is_a <cgraph_node> (node)) | |
864 | return cgraph_function_body_availability (cgraph (node)); | |
865 | else | |
866 | return cgraph_variable_initializer_availability (varpool (node)); | |
867 | } | |
868 | ||
e70670cf JH |
869 | /* Given NODE, walk the alias chain to return the symbol NODE is alias of. |
870 | If NODE is not an alias, return NODE. | |
871 | When AVAILABILITY is non-NULL, get minimal availability in the chain. */ | |
872 | ||
873 | symtab_node | |
874 | symtab_alias_ultimate_target (symtab_node node, enum availability *availability) | |
875 | { | |
aaae719d JH |
876 | bool weakref_p = false; |
877 | ||
67348ccc | 878 | if (!node->alias) |
aaae719d JH |
879 | { |
880 | if (availability) | |
881 | *availability = symtab_node_availability (node); | |
882 | return node; | |
883 | } | |
884 | ||
885 | /* To determine visibility of the target, we follow ELF semantic of aliases. | |
886 | Here alias is an alternative assembler name of a given definition. Its | |
1aa95df7 | 887 | availability prevails the availability of its target (i.e. static alias of |
aaae719d JH |
888 | weak definition is available. |
889 | ||
890 | Weakref is a different animal (and not part of ELF per se). It is just | |
891 | alternative name of a given symbol used within one complation unit | |
892 | and is translated prior hitting the object file. It inherits the | |
893 | visibility of its target (i.e. weakref of non-overwritable definition | |
894 | is non-overwritable, while weakref of weak definition is weak). | |
895 | ||
896 | If we ever get into supporting targets with different semantics, a target | |
897 | hook will be needed here. */ | |
898 | ||
e70670cf | 899 | if (availability) |
aaae719d | 900 | { |
67348ccc | 901 | weakref_p = node->weakref; |
aaae719d JH |
902 | if (!weakref_p) |
903 | *availability = symtab_node_availability (node); | |
904 | else | |
905 | *availability = AVAIL_LOCAL; | |
906 | } | |
e70670cf JH |
907 | while (node) |
908 | { | |
67348ccc | 909 | if (node->alias && node->analyzed) |
e70670cf JH |
910 | node = symtab_alias_target (node); |
911 | else | |
aaae719d JH |
912 | { |
913 | if (!availability) | |
914 | ; | |
67348ccc | 915 | else if (node->analyzed) |
aaae719d JH |
916 | { |
917 | if (weakref_p) | |
918 | { | |
919 | enum availability a = symtab_node_availability (node); | |
920 | if (a < *availability) | |
921 | *availability = a; | |
922 | } | |
923 | } | |
924 | else | |
925 | *availability = AVAIL_NOT_AVAILABLE; | |
926 | return node; | |
927 | } | |
928 | if (node && availability && weakref_p) | |
e70670cf | 929 | { |
40a7fe1e | 930 | enum availability a = symtab_node_availability (node); |
e70670cf JH |
931 | if (a < *availability) |
932 | *availability = a; | |
67348ccc | 933 | weakref_p = node->weakref; |
e70670cf JH |
934 | } |
935 | } | |
936 | if (availability) | |
937 | *availability = AVAIL_NOT_AVAILABLE; | |
938 | return NULL; | |
939 | } | |
40a7fe1e JH |
940 | |
941 | /* C++ FE sometimes change linkage flags after producing same body aliases. | |
942 | ||
943 | FIXME: C++ produce implicit aliases for virtual functions and vtables that | |
944 | are obviously equivalent. The way it is doing so is however somewhat | |
945 | kludgy and interferes with the visibility code. As a result we need to | |
946 | copy the visibility from the target to get things right. */ | |
947 | ||
948 | void | |
949 | fixup_same_cpp_alias_visibility (symtab_node node, symtab_node target) | |
950 | { | |
951 | if (is_a <cgraph_node> (node)) | |
952 | { | |
67348ccc DM |
953 | DECL_DECLARED_INLINE_P (node->decl) |
954 | = DECL_DECLARED_INLINE_P (target->decl); | |
955 | DECL_DISREGARD_INLINE_LIMITS (node->decl) | |
956 | = DECL_DISREGARD_INLINE_LIMITS (target->decl); | |
40a7fe1e JH |
957 | } |
958 | /* FIXME: It is not really clear why those flags should not be copied for | |
959 | functions, too. */ | |
960 | else | |
961 | { | |
67348ccc DM |
962 | DECL_WEAK (node->decl) = DECL_WEAK (target->decl); |
963 | DECL_EXTERNAL (node->decl) = DECL_EXTERNAL (target->decl); | |
964 | DECL_VISIBILITY (node->decl) = DECL_VISIBILITY (target->decl); | |
40a7fe1e | 965 | } |
67348ccc DM |
966 | DECL_VIRTUAL_P (node->decl) = DECL_VIRTUAL_P (target->decl); |
967 | if (TREE_PUBLIC (node->decl)) | |
40a7fe1e | 968 | { |
67348ccc DM |
969 | DECL_EXTERNAL (node->decl) = DECL_EXTERNAL (target->decl); |
970 | DECL_COMDAT (node->decl) = DECL_COMDAT (target->decl); | |
971 | DECL_COMDAT_GROUP (node->decl) | |
972 | = DECL_COMDAT_GROUP (target->decl); | |
973 | if (DECL_ONE_ONLY (target->decl) | |
974 | && !node->same_comdat_group) | |
975 | symtab_add_to_same_comdat_group (node, target); | |
40a7fe1e | 976 | } |
67348ccc | 977 | node->externally_visible = target->externally_visible; |
40a7fe1e JH |
978 | } |
979 | ||
980 | /* Add reference recording that NODE is alias of TARGET. | |
981 | The function can fail in the case of aliasing cycles; in this case | |
982 | it returns false. */ | |
983 | ||
984 | bool | |
985 | symtab_resolve_alias (symtab_node node, symtab_node target) | |
986 | { | |
987 | symtab_node n; | |
988 | ||
67348ccc DM |
989 | gcc_assert (!node->analyzed |
990 | && !vec_safe_length (node->ref_list.references)); | |
40a7fe1e JH |
991 | |
992 | /* Never let cycles to creep into the symbol table alias references; | |
993 | those will make alias walkers to be infinite. */ | |
67348ccc DM |
994 | for (n = target; n && n->alias; |
995 | n = n->analyzed ? symtab_alias_target (n) : NULL) | |
40a7fe1e JH |
996 | if (n == node) |
997 | { | |
998 | if (is_a <cgraph_node> (node)) | |
67348ccc | 999 | error ("function %q+D part of alias cycle", node->decl); |
40a7fe1e | 1000 | else if (is_a <varpool_node> (node)) |
67348ccc | 1001 | error ("variable %q+D part of alias cycle", node->decl); |
40a7fe1e JH |
1002 | else |
1003 | gcc_unreachable (); | |
67348ccc | 1004 | node->alias = false; |
40a7fe1e JH |
1005 | return false; |
1006 | } | |
1007 | ||
1008 | /* "analyze" the node - i.e. mark the reference. */ | |
67348ccc DM |
1009 | node->definition = true; |
1010 | node->alias = true; | |
1011 | node->analyzed = true; | |
40a7fe1e JH |
1012 | ipa_record_reference (node, target, IPA_REF_ALIAS, NULL); |
1013 | ||
1014 | /* Alias targets become reudndant after alias is resolved into an reference. | |
1015 | We do not want to keep it around or we would have to mind updating them | |
1016 | when renaming symbols. */ | |
67348ccc | 1017 | node->alias_target = NULL; |
40a7fe1e | 1018 | |
67348ccc | 1019 | if (node->cpp_implicit_alias && cgraph_state >= CGRAPH_STATE_CONSTRUCTION) |
40a7fe1e JH |
1020 | fixup_same_cpp_alias_visibility (node, target); |
1021 | ||
1022 | /* If alias has address taken, so does the target. */ | |
67348ccc DM |
1023 | if (node->address_taken) |
1024 | symtab_alias_ultimate_target (target, NULL)->address_taken = true; | |
40a7fe1e JH |
1025 | return true; |
1026 | } | |
af15184a JH |
1027 | |
1028 | /* Call calback on NODE and aliases associated to NODE. | |
1029 | When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are | |
1030 | skipped. */ | |
1031 | ||
1032 | bool | |
1033 | symtab_for_node_and_aliases (symtab_node node, | |
1034 | bool (*callback) (symtab_node, void *), | |
1035 | void *data, | |
1036 | bool include_overwritable) | |
1037 | { | |
1038 | int i; | |
1039 | struct ipa_ref *ref; | |
1040 | ||
1041 | if (callback (node, data)) | |
1042 | return true; | |
67348ccc | 1043 | for (i = 0; ipa_ref_list_referring_iterate (&node->ref_list, i, ref); i++) |
af15184a JH |
1044 | if (ref->use == IPA_REF_ALIAS) |
1045 | { | |
1046 | symtab_node alias = ref->referring; | |
1047 | if (include_overwritable | |
1048 | || symtab_node_availability (alias) > AVAIL_OVERWRITABLE) | |
1049 | if (symtab_for_node_and_aliases (alias, callback, data, | |
1050 | include_overwritable)) | |
1051 | return true; | |
1052 | } | |
1053 | return false; | |
1054 | } | |
1055 | ||
1056 | /* Worker searching nonoverwritable alias. */ | |
1057 | ||
1058 | static bool | |
1059 | symtab_nonoverwritable_alias_1 (symtab_node node, void *data) | |
1060 | { | |
67348ccc | 1061 | if (decl_binds_to_current_def_p (node->decl)) |
af15184a JH |
1062 | { |
1063 | *(symtab_node *)data = node; | |
1064 | return true; | |
1065 | } | |
1066 | return false; | |
1067 | } | |
1068 | ||
1069 | /* If NODE can not be overwriten by static or dynamic linker to point to different | |
1070 | definition, return NODE. Otherwise look for alias with such property and if | |
1071 | none exists, introduce new one. */ | |
1072 | ||
1073 | symtab_node | |
1074 | symtab_nonoverwritable_alias (symtab_node node) | |
1075 | { | |
1076 | tree new_decl; | |
1077 | symtab_node new_node = NULL; | |
8a41354f JH |
1078 | |
1079 | /* First try to look up existing alias or base object | |
1080 | (if that is already non-overwritable). */ | |
1081 | node = symtab_alias_ultimate_target (node, NULL); | |
67348ccc | 1082 | gcc_assert (!node->alias && !node->weakref); |
af15184a JH |
1083 | symtab_for_node_and_aliases (node, symtab_nonoverwritable_alias_1, |
1084 | (void *)&new_node, true); | |
1085 | if (new_node) | |
1086 | return new_node; | |
cdb87c08 JH |
1087 | #ifndef ASM_OUTPUT_DEF |
1088 | /* If aliases aren't supported by the assembler, fail. */ | |
1089 | return NULL; | |
1090 | #endif | |
af15184a | 1091 | |
8a41354f | 1092 | /* Otherwise create a new one. */ |
67348ccc DM |
1093 | new_decl = copy_node (node->decl); |
1094 | DECL_NAME (new_decl) = clone_function_name (node->decl, "localalias"); | |
af15184a JH |
1095 | if (TREE_CODE (new_decl) == FUNCTION_DECL) |
1096 | DECL_STRUCT_FUNCTION (new_decl) = NULL; | |
1097 | DECL_INITIAL (new_decl) = NULL; | |
1098 | SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl)); | |
1099 | SET_DECL_RTL (new_decl, NULL); | |
1100 | ||
1101 | /* Update the properties. */ | |
1102 | DECL_EXTERNAL (new_decl) = 0; | |
67348ccc | 1103 | if (DECL_ONE_ONLY (node->decl)) |
af15184a JH |
1104 | DECL_SECTION_NAME (new_decl) = NULL; |
1105 | DECL_COMDAT_GROUP (new_decl) = 0; | |
1106 | TREE_PUBLIC (new_decl) = 0; | |
1107 | DECL_COMDAT (new_decl) = 0; | |
1108 | DECL_WEAK (new_decl) = 0; | |
1109 | DECL_VIRTUAL_P (new_decl) = 0; | |
1110 | if (TREE_CODE (new_decl) == FUNCTION_DECL) | |
1111 | { | |
1112 | DECL_STATIC_CONSTRUCTOR (new_decl) = 0; | |
1113 | DECL_STATIC_DESTRUCTOR (new_decl) = 0; | |
67348ccc DM |
1114 | new_node = cgraph_create_function_alias |
1115 | (new_decl, node->decl); | |
af15184a JH |
1116 | } |
1117 | else | |
67348ccc DM |
1118 | new_node = varpool_create_variable_alias (new_decl, |
1119 | node->decl); | |
af15184a | 1120 | symtab_resolve_alias (new_node, node); |
fc11f321 | 1121 | gcc_assert (decl_binds_to_current_def_p (new_decl)); |
af15184a JH |
1122 | return new_node; |
1123 | } | |
fc11f321 JH |
1124 | |
1125 | /* Return true if A and B represents semantically equivalent symbols. */ | |
1126 | ||
1127 | bool | |
1128 | symtab_semantically_equivalent_p (symtab_node a, | |
1129 | symtab_node b) | |
1130 | { | |
1131 | enum availability avail; | |
1132 | symtab_node ba, bb; | |
1133 | ||
1134 | /* Equivalent functions are equivalent. */ | |
67348ccc | 1135 | if (a->decl == b->decl) |
fc11f321 JH |
1136 | return true; |
1137 | ||
1138 | /* If symbol is not overwritable by different implementation, | |
1139 | walk to the base object it defines. */ | |
1140 | ba = symtab_alias_ultimate_target (a, &avail); | |
1141 | if (avail >= AVAIL_AVAILABLE) | |
1142 | { | |
1143 | if (ba == b) | |
1144 | return true; | |
1145 | } | |
1146 | else | |
1147 | ba = a; | |
1148 | bb = symtab_alias_ultimate_target (b, &avail); | |
1149 | if (avail >= AVAIL_AVAILABLE) | |
1150 | { | |
1151 | if (a == bb) | |
1152 | return true; | |
1153 | } | |
1154 | else | |
1155 | bb = b; | |
1156 | return bb == ba; | |
1157 | } | |
1ab24192 | 1158 | #include "gt-symtab.h" |