]>
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" | |
26 | #include "tree-inline.h" | |
8f940ee6 | 27 | #include "langhooks.h" |
2aae7680 | 28 | #include "hashtab.h" |
1ab24192 | 29 | #include "ggc.h" |
2aae7680 | 30 | #include "cgraph.h" |
1ab24192 | 31 | #include "diagnostic.h" |
474ffc72 | 32 | #include "timevar.h" |
65d630d4 JH |
33 | #include "lto-streamer.h" |
34 | #include "rtl.h" | |
35 | ||
36 | const char * const ld_plugin_symbol_resolution_names[]= | |
37 | { | |
38 | "", | |
39 | "undef", | |
40 | "prevailing_def", | |
41 | "prevailing_def_ironly", | |
42 | "preempted_reg", | |
43 | "preempted_ir", | |
44 | "resolved_ir", | |
45 | "resolved_exec", | |
46 | "resolved_dyn", | |
47 | "prevailing_def_ironly_exp" | |
48 | }; | |
1ab24192 JH |
49 | |
50 | /* Hash table used to convert declarations into nodes. */ | |
51 | static GTY((param_is (union symtab_node_def))) htab_t symtab_hash; | |
52 | /* Hash table used to convert assembler names into nodes. */ | |
53 | static GTY((param_is (union symtab_node_def))) htab_t assembler_name_hash; | |
2aae7680 JH |
54 | |
55 | /* Linked list of symbol table nodes. */ | |
56 | symtab_node symtab_nodes; | |
57 | ||
58 | /* The order index of the next symtab node to be created. This is | |
59 | used so that we can sort the cgraph nodes in order by when we saw | |
60 | them, to support -fno-toplevel-reorder. */ | |
61 | int symtab_order; | |
62 | ||
1ab24192 JH |
63 | /* Returns a hash code for P. */ |
64 | ||
65 | static hashval_t | |
66 | hash_node (const void *p) | |
67 | { | |
68 | const_symtab_node n = (const_symtab_node ) p; | |
69 | return (hashval_t) DECL_UID (n->symbol.decl); | |
70 | } | |
71 | ||
72 | ||
73 | /* Returns nonzero if P1 and P2 are equal. */ | |
74 | ||
75 | static int | |
76 | eq_node (const void *p1, const void *p2) | |
77 | { | |
78 | const_symtab_node n1 = (const_symtab_node) p1; | |
79 | const_symtab_node n2 = (const_symtab_node) p2; | |
80 | return DECL_UID (n1->symbol.decl) == DECL_UID (n2->symbol.decl); | |
81 | } | |
82 | ||
83 | /* Returns a hash code for P. */ | |
84 | ||
85 | static hashval_t | |
86 | hash_node_by_assembler_name (const void *p) | |
87 | { | |
88 | const_symtab_node n = (const_symtab_node) p; | |
89 | return (hashval_t) decl_assembler_name_hash (DECL_ASSEMBLER_NAME (n->symbol.decl)); | |
90 | } | |
91 | ||
92 | /* Returns nonzero if P1 and P2 are equal. */ | |
93 | ||
94 | static int | |
95 | eq_assembler_name (const void *p1, const void *p2) | |
96 | { | |
97 | const_symtab_node n1 = (const_symtab_node) p1; | |
98 | const_tree name = (const_tree)p2; | |
99 | return (decl_assembler_name_equal (n1->symbol.decl, name)); | |
100 | } | |
101 | ||
102 | /* Insert NODE to assembler name hash. */ | |
103 | ||
104 | static void | |
105 | insert_to_assembler_name_hash (symtab_node node) | |
106 | { | |
5d59b5e1 | 107 | if (is_a <varpool_node> (node) && DECL_HARD_REGISTER (node->symbol.decl)) |
b5493fb2 | 108 | return; |
1ab24192 JH |
109 | gcc_checking_assert (!node->symbol.previous_sharing_asm_name |
110 | && !node->symbol.next_sharing_asm_name); | |
111 | if (assembler_name_hash) | |
112 | { | |
113 | void **aslot; | |
114 | tree name = DECL_ASSEMBLER_NAME (node->symbol.decl); | |
115 | ||
116 | aslot = htab_find_slot_with_hash (assembler_name_hash, name, | |
117 | decl_assembler_name_hash (name), | |
118 | INSERT); | |
119 | gcc_assert (*aslot != node); | |
120 | node->symbol.next_sharing_asm_name = (symtab_node)*aslot; | |
121 | if (*aslot != NULL) | |
122 | ((symtab_node)*aslot)->symbol.previous_sharing_asm_name = node; | |
123 | *aslot = node; | |
124 | } | |
125 | ||
126 | } | |
127 | ||
128 | /* Remove NODE from assembler name hash. */ | |
129 | ||
130 | static void | |
131 | unlink_from_assembler_name_hash (symtab_node node) | |
132 | { | |
133 | if (assembler_name_hash) | |
134 | { | |
135 | if (node->symbol.next_sharing_asm_name) | |
136 | node->symbol.next_sharing_asm_name->symbol.previous_sharing_asm_name | |
137 | = node->symbol.previous_sharing_asm_name; | |
138 | if (node->symbol.previous_sharing_asm_name) | |
139 | { | |
140 | node->symbol.previous_sharing_asm_name->symbol.next_sharing_asm_name | |
141 | = node->symbol.next_sharing_asm_name; | |
142 | } | |
143 | else | |
144 | { | |
145 | tree name = DECL_ASSEMBLER_NAME (node->symbol.decl); | |
146 | void **slot; | |
147 | slot = htab_find_slot_with_hash (assembler_name_hash, name, | |
148 | decl_assembler_name_hash (name), | |
149 | NO_INSERT); | |
150 | gcc_assert (*slot == node); | |
151 | if (!node->symbol.next_sharing_asm_name) | |
152 | htab_clear_slot (assembler_name_hash, slot); | |
153 | else | |
154 | *slot = node->symbol.next_sharing_asm_name; | |
155 | } | |
b5493fb2 JH |
156 | node->symbol.next_sharing_asm_name = NULL; |
157 | node->symbol.previous_sharing_asm_name = NULL; | |
1ab24192 JH |
158 | } |
159 | } | |
160 | ||
b5493fb2 JH |
161 | /* Arrange node to be first in its entry of assembler_name_hash. */ |
162 | ||
163 | void | |
164 | symtab_prevail_in_asm_name_hash (symtab_node node) | |
165 | { | |
166 | unlink_from_assembler_name_hash (node); | |
167 | insert_to_assembler_name_hash (node); | |
168 | } | |
169 | ||
1ab24192 | 170 | |
2aae7680 JH |
171 | /* Add node into symbol table. This function is not used directly, but via |
172 | cgraph/varpool node creation routines. */ | |
173 | ||
174 | void | |
175 | symtab_register_node (symtab_node node) | |
176 | { | |
1ab24192 JH |
177 | struct symtab_node_base key; |
178 | symtab_node *slot; | |
179 | ||
2aae7680 JH |
180 | node->symbol.next = symtab_nodes; |
181 | node->symbol.previous = NULL; | |
182 | if (symtab_nodes) | |
183 | symtab_nodes->symbol.previous = node; | |
184 | symtab_nodes = node; | |
185 | ||
1ab24192 JH |
186 | if (!symtab_hash) |
187 | symtab_hash = htab_create_ggc (10, hash_node, eq_node, NULL); | |
188 | key.decl = node->symbol.decl; | |
189 | slot = (symtab_node *) htab_find_slot (symtab_hash, &key, INSERT); | |
190 | if (*slot == NULL) | |
191 | *slot = node; | |
192 | ||
66379195 | 193 | ipa_empty_ref_list (&node->symbol.ref_list); |
1ab24192 | 194 | |
2aae7680 JH |
195 | node->symbol.order = symtab_order++; |
196 | ||
66379195 JH |
197 | /* Be sure to do this last; C++ FE might create new nodes via |
198 | DECL_ASSEMBLER_NAME langhook! */ | |
199 | insert_to_assembler_name_hash (node); | |
2aae7680 JH |
200 | } |
201 | ||
1ab24192 JH |
202 | /* Make NODE to be the one symtab hash is pointing to. Used when reshaping tree |
203 | of inline clones. */ | |
204 | ||
205 | void | |
206 | symtab_insert_node_to_hashtable (symtab_node node) | |
207 | { | |
208 | struct symtab_node_base key; | |
209 | symtab_node *slot; | |
210 | ||
211 | if (!symtab_hash) | |
212 | symtab_hash = htab_create_ggc (10, hash_node, eq_node, NULL); | |
213 | key.decl = node->symbol.decl; | |
214 | slot = (symtab_node *) htab_find_slot (symtab_hash, &key, INSERT); | |
215 | *slot = node; | |
216 | } | |
217 | ||
2aae7680 JH |
218 | /* Remove node from symbol table. This function is not used directly, but via |
219 | cgraph/varpool node removal routines. */ | |
220 | ||
221 | void | |
222 | symtab_unregister_node (symtab_node node) | |
223 | { | |
1ab24192 | 224 | void **slot; |
2aae7680 | 225 | ipa_remove_all_references (&node->symbol.ref_list); |
5932a4d4 | 226 | ipa_remove_all_referring (&node->symbol.ref_list); |
2aae7680 JH |
227 | |
228 | if (node->symbol.same_comdat_group) | |
229 | { | |
230 | symtab_node prev; | |
231 | for (prev = node->symbol.same_comdat_group; | |
232 | prev->symbol.same_comdat_group != node; | |
233 | prev = prev->symbol.same_comdat_group) | |
234 | ; | |
235 | if (node->symbol.same_comdat_group == prev) | |
236 | prev->symbol.same_comdat_group = NULL; | |
237 | else | |
238 | prev->symbol.same_comdat_group = node->symbol.same_comdat_group; | |
239 | node->symbol.same_comdat_group = NULL; | |
240 | } | |
241 | ||
242 | if (node->symbol.previous) | |
243 | node->symbol.previous->symbol.next = node->symbol.next; | |
244 | else | |
245 | symtab_nodes = node->symbol.next; | |
246 | if (node->symbol.next) | |
247 | node->symbol.next->symbol.previous = node->symbol.previous; | |
248 | node->symbol.next = NULL; | |
249 | node->symbol.previous = NULL; | |
1ab24192 JH |
250 | |
251 | slot = htab_find_slot (symtab_hash, node, NO_INSERT); | |
252 | if (*slot == node) | |
253 | { | |
254 | symtab_node replacement_node = NULL; | |
5d59b5e1 LC |
255 | if (cgraph_node *cnode = dyn_cast <cgraph_node> (node)) |
256 | replacement_node = (symtab_node)cgraph_find_replacement_node (cnode); | |
1ab24192 JH |
257 | if (!replacement_node) |
258 | htab_clear_slot (symtab_hash, slot); | |
259 | else | |
260 | *slot = replacement_node; | |
261 | } | |
262 | unlink_from_assembler_name_hash (node); | |
263 | } | |
264 | ||
265 | /* Return symbol table node associated with DECL, if any, | |
266 | and NULL otherwise. */ | |
267 | ||
268 | symtab_node | |
269 | symtab_get_node (const_tree decl) | |
270 | { | |
271 | symtab_node *slot; | |
272 | struct symtab_node_base key; | |
273 | ||
274 | gcc_checking_assert (TREE_CODE (decl) == FUNCTION_DECL | |
275 | || (TREE_CODE (decl) == VAR_DECL | |
276 | && (TREE_STATIC (decl) || DECL_EXTERNAL (decl) | |
277 | || in_lto_p))); | |
278 | ||
279 | if (!symtab_hash) | |
280 | return NULL; | |
281 | ||
282 | key.decl = CONST_CAST2 (tree, const_tree, decl); | |
283 | ||
284 | slot = (symtab_node *) htab_find_slot (symtab_hash, &key, | |
285 | NO_INSERT); | |
286 | ||
287 | if (slot) | |
288 | return *slot; | |
289 | return NULL; | |
2aae7680 JH |
290 | } |
291 | ||
292 | /* Remove symtab NODE from the symbol table. */ | |
293 | ||
294 | void | |
295 | symtab_remove_node (symtab_node node) | |
296 | { | |
5d59b5e1 LC |
297 | if (cgraph_node *cnode = dyn_cast <cgraph_node> (node)) |
298 | cgraph_remove_node (cnode); | |
299 | else if (varpool_node *vnode = dyn_cast <varpool_node> (node)) | |
300 | varpool_remove_node (vnode); | |
2aae7680 | 301 | } |
1ab24192 | 302 | |
b5493fb2 | 303 | /* Initalize asm name hash unless. */ |
1ab24192 | 304 | |
b5493fb2 JH |
305 | void |
306 | symtab_initialize_asm_name_hash (void) | |
1ab24192 JH |
307 | { |
308 | symtab_node node; | |
1ab24192 JH |
309 | if (!assembler_name_hash) |
310 | { | |
311 | assembler_name_hash = | |
312 | htab_create_ggc (10, hash_node_by_assembler_name, eq_assembler_name, | |
313 | NULL); | |
314 | FOR_EACH_SYMBOL (node) | |
315 | insert_to_assembler_name_hash (node); | |
316 | } | |
b5493fb2 | 317 | } |
1ab24192 | 318 | |
b5493fb2 JH |
319 | /* Return the cgraph node that has ASMNAME for its DECL_ASSEMBLER_NAME. |
320 | Return NULL if there's no such node. */ | |
321 | ||
322 | symtab_node | |
323 | symtab_node_for_asm (const_tree asmname) | |
324 | { | |
325 | symtab_node node; | |
326 | void **slot; | |
327 | ||
328 | symtab_initialize_asm_name_hash (); | |
1ab24192 JH |
329 | slot = htab_find_slot_with_hash (assembler_name_hash, asmname, |
330 | decl_assembler_name_hash (asmname), | |
331 | NO_INSERT); | |
332 | ||
333 | if (slot) | |
334 | { | |
335 | node = (symtab_node) *slot; | |
336 | return node; | |
337 | } | |
338 | return NULL; | |
339 | } | |
340 | ||
341 | /* Set the DECL_ASSEMBLER_NAME and update symtab hashtables. */ | |
342 | ||
343 | void | |
344 | change_decl_assembler_name (tree decl, tree name) | |
345 | { | |
346 | symtab_node node = NULL; | |
347 | ||
348 | /* We can have user ASM names on things, like global register variables, that | |
349 | are not in the symbol table. */ | |
350 | if ((TREE_CODE (decl) == VAR_DECL | |
351 | && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))) | |
352 | || TREE_CODE (decl) == FUNCTION_DECL) | |
353 | node = symtab_get_node (decl); | |
354 | if (!DECL_ASSEMBLER_NAME_SET_P (decl)) | |
355 | { | |
356 | SET_DECL_ASSEMBLER_NAME (decl, name); | |
357 | if (node) | |
358 | insert_to_assembler_name_hash (node); | |
359 | } | |
360 | else | |
361 | { | |
362 | if (name == DECL_ASSEMBLER_NAME (decl)) | |
363 | return; | |
364 | ||
365 | if (node) | |
366 | unlink_from_assembler_name_hash (node); | |
367 | if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) | |
368 | && DECL_RTL_SET_P (decl)) | |
369 | warning (0, "%D renamed after being referenced in assembly", decl); | |
370 | ||
371 | SET_DECL_ASSEMBLER_NAME (decl, name); | |
372 | if (node) | |
373 | insert_to_assembler_name_hash (node); | |
374 | } | |
375 | } | |
376 | ||
65d630d4 JH |
377 | /* Add NEW_ to the same comdat group that OLD is in. */ |
378 | ||
379 | void | |
380 | symtab_add_to_same_comdat_group (symtab_node new_node, | |
381 | symtab_node old_node) | |
382 | { | |
383 | gcc_assert (DECL_ONE_ONLY (old_node->symbol.decl)); | |
384 | gcc_assert (!new_node->symbol.same_comdat_group); | |
385 | gcc_assert (new_node != old_node); | |
386 | ||
387 | DECL_COMDAT_GROUP (new_node->symbol.decl) = DECL_COMDAT_GROUP (old_node->symbol.decl); | |
388 | new_node->symbol.same_comdat_group = old_node; | |
389 | if (!old_node->symbol.same_comdat_group) | |
390 | old_node->symbol.same_comdat_group = new_node; | |
391 | else | |
392 | { | |
393 | symtab_node n; | |
394 | for (n = old_node->symbol.same_comdat_group; | |
395 | n->symbol.same_comdat_group != old_node; | |
396 | n = n->symbol.same_comdat_group) | |
397 | ; | |
398 | n->symbol.same_comdat_group = new_node; | |
399 | } | |
400 | } | |
401 | ||
402 | /* Dissolve the same_comdat_group list in which NODE resides. */ | |
403 | ||
404 | void | |
405 | symtab_dissolve_same_comdat_group_list (symtab_node node) | |
406 | { | |
407 | symtab_node n = node, next; | |
408 | ||
409 | if (!node->symbol.same_comdat_group) | |
410 | return; | |
411 | do | |
412 | { | |
413 | next = n->symbol.same_comdat_group; | |
414 | n->symbol.same_comdat_group = NULL; | |
415 | n = next; | |
416 | } | |
417 | while (n != node); | |
418 | } | |
419 | ||
8f940ee6 JH |
420 | /* Return printable assembler name of NODE. |
421 | This function is used only for debugging. When assembler name | |
422 | is unknown go with identifier name. */ | |
423 | ||
424 | const char * | |
425 | symtab_node_asm_name (symtab_node node) | |
426 | { | |
427 | if (!DECL_ASSEMBLER_NAME_SET_P (node->symbol.decl)) | |
428 | return lang_hooks.decl_printable_name (node->symbol.decl, 2); | |
429 | return IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->symbol.decl)); | |
430 | } | |
431 | ||
432 | /* Return printable identifier name. */ | |
433 | ||
434 | const char * | |
435 | symtab_node_name (symtab_node node) | |
436 | { | |
437 | return lang_hooks.decl_printable_name (node->symbol.decl, 2); | |
438 | } | |
439 | ||
440 | static const char * const symtab_type_names[] = {"symbol", "function", "variable"}; | |
441 | ||
442 | /* Dump base fields of symtab nodes. Not to be used directly. */ | |
443 | ||
444 | void | |
445 | dump_symtab_base (FILE *f, symtab_node node) | |
446 | { | |
447 | static const char * const visibility_types[] = { | |
448 | "default", "protected", "hidden", "internal" | |
449 | }; | |
450 | ||
451 | fprintf (f, "%s/%i (%s)", | |
452 | symtab_node_asm_name (node), | |
453 | node->symbol.order, | |
454 | symtab_node_name (node)); | |
455 | dump_addr (f, " @", (void *)node); | |
456 | fprintf (f, "\n Type: %s\n", symtab_type_names[node->symbol.type]); | |
457 | fprintf (f, " Visibility:"); | |
458 | ||
459 | if (node->symbol.in_other_partition) | |
460 | fprintf (f, " in_other_partition"); | |
461 | if (node->symbol.used_from_other_partition) | |
462 | fprintf (f, " used_from_other_partition"); | |
ead84f73 JH |
463 | if (node->symbol.force_output) |
464 | fprintf (f, " force_output"); | |
8f940ee6 JH |
465 | if (node->symbol.resolution != LDPR_UNKNOWN) |
466 | fprintf (f, " %s", | |
467 | ld_plugin_symbol_resolution_names[(int)node->symbol.resolution]); | |
468 | if (TREE_ASM_WRITTEN (node->symbol.decl)) | |
469 | fprintf (f, " asm_written"); | |
470 | if (DECL_EXTERNAL (node->symbol.decl)) | |
471 | fprintf (f, " external"); | |
472 | if (TREE_PUBLIC (node->symbol.decl)) | |
473 | fprintf (f, " public"); | |
474 | if (DECL_COMMON (node->symbol.decl)) | |
475 | fprintf (f, " common"); | |
476 | if (DECL_WEAK (node->symbol.decl)) | |
477 | fprintf (f, " weak"); | |
478 | if (DECL_DLLIMPORT_P (node->symbol.decl)) | |
479 | fprintf (f, " dll_import"); | |
480 | if (DECL_COMDAT (node->symbol.decl)) | |
481 | fprintf (f, " comdat"); | |
482 | if (DECL_COMDAT_GROUP (node->symbol.decl)) | |
483 | fprintf (f, " comdat_group:%s", | |
484 | IDENTIFIER_POINTER (DECL_COMDAT_GROUP (node->symbol.decl))); | |
485 | if (DECL_ONE_ONLY (node->symbol.decl)) | |
486 | fprintf (f, " one_only"); | |
487 | if (DECL_SECTION_NAME (node->symbol.decl)) | |
488 | fprintf (f, " section_name:%s", | |
f68c0487 | 489 | TREE_STRING_POINTER (DECL_SECTION_NAME (node->symbol.decl))); |
8f940ee6 JH |
490 | if (DECL_VISIBILITY_SPECIFIED (node->symbol.decl)) |
491 | fprintf (f, " visibility_specified"); | |
492 | if (DECL_VISIBILITY (node->symbol.decl)) | |
493 | fprintf (f, " visibility:%s", | |
494 | visibility_types [DECL_VISIBILITY (node->symbol.decl)]); | |
495 | if (DECL_VIRTUAL_P (node->symbol.decl)) | |
496 | fprintf (f, " virtual"); | |
497 | if (DECL_ARTIFICIAL (node->symbol.decl)) | |
498 | fprintf (f, " artificial"); | |
838ff415 JH |
499 | if (TREE_CODE (node->symbol.decl) == FUNCTION_DECL) |
500 | { | |
501 | if (DECL_STATIC_CONSTRUCTOR (node->symbol.decl)) | |
502 | fprintf (f, " constructor"); | |
503 | if (DECL_STATIC_DESTRUCTOR (node->symbol.decl)) | |
504 | fprintf (f, " destructor"); | |
505 | } | |
8f940ee6 JH |
506 | fprintf (f, "\n"); |
507 | ||
508 | if (node->symbol.same_comdat_group) | |
509 | fprintf (f, " Same comdat group as: %s/%i\n", | |
510 | symtab_node_asm_name (node->symbol.same_comdat_group), | |
511 | node->symbol.same_comdat_group->symbol.order); | |
512 | if (node->symbol.next_sharing_asm_name) | |
513 | fprintf (f, " next sharing asm name: %i\n", | |
fe0bd630 | 514 | node->symbol.next_sharing_asm_name->symbol.order); |
8f940ee6 JH |
515 | if (node->symbol.previous_sharing_asm_name) |
516 | fprintf (f, " previous sharing asm name: %i\n", | |
fe0bd630 | 517 | node->symbol.previous_sharing_asm_name->symbol.order); |
8f940ee6 JH |
518 | |
519 | if (node->symbol.address_taken) | |
fe0bd630 | 520 | fprintf (f, " Address is taken.\n"); |
66058468 JH |
521 | if (node->symbol.aux) |
522 | { | |
523 | fprintf (f, " Aux:"); | |
524 | dump_addr (f, " @", (void *)node->symbol.aux); | |
525 | } | |
8f940ee6 JH |
526 | |
527 | fprintf (f, " References: "); | |
528 | ipa_dump_references (f, &node->symbol.ref_list); | |
5932a4d4 JH |
529 | fprintf (f, " Referring: "); |
530 | ipa_dump_referring (f, &node->symbol.ref_list); | |
b5493fb2 JH |
531 | if (node->symbol.lto_file_data) |
532 | fprintf (f, " Read from file: %s\n", | |
533 | node->symbol.lto_file_data->file_name); | |
8f940ee6 JH |
534 | } |
535 | ||
536 | /* Dump symtab node. */ | |
537 | ||
538 | void | |
539 | dump_symtab_node (FILE *f, symtab_node node) | |
540 | { | |
5d59b5e1 LC |
541 | if (cgraph_node *cnode = dyn_cast <cgraph_node> (node)) |
542 | dump_cgraph_node (f, cnode); | |
543 | else if (varpool_node *vnode = dyn_cast <varpool_node> (node)) | |
544 | dump_varpool_node (f, vnode); | |
8f940ee6 JH |
545 | } |
546 | ||
547 | /* Dump symbol table. */ | |
548 | ||
549 | void | |
550 | dump_symtab (FILE *f) | |
551 | { | |
552 | symtab_node node; | |
553 | fprintf (f, "Symbol table:\n\n"); | |
554 | FOR_EACH_SYMBOL (node) | |
555 | dump_symtab_node (f, node); | |
556 | } | |
557 | ||
558 | /* Dump symtab node NODE to stderr. */ | |
559 | ||
560 | DEBUG_FUNCTION void | |
561 | debug_symtab_node (symtab_node node) | |
562 | { | |
563 | dump_symtab_node (stderr, node); | |
564 | } | |
565 | ||
566 | /* Dump symbol table to stderr. */ | |
567 | ||
568 | DEBUG_FUNCTION void | |
569 | debug_symtab (void) | |
570 | { | |
571 | dump_symtab (stderr); | |
572 | } | |
573 | ||
474ffc72 JH |
574 | /* Verify common part of symtab nodes. */ |
575 | ||
576 | DEBUG_FUNCTION bool | |
577 | verify_symtab_base (symtab_node node) | |
578 | { | |
579 | bool error_found = false; | |
580 | symtab_node hashed_node; | |
581 | ||
5d59b5e1 | 582 | if (is_a <cgraph_node> (node)) |
474ffc72 JH |
583 | { |
584 | if (TREE_CODE (node->symbol.decl) != FUNCTION_DECL) | |
585 | { | |
586 | error ("function symbol is not function"); | |
587 | error_found = true; | |
588 | } | |
589 | } | |
5d59b5e1 | 590 | else if (is_a <varpool_node> (node)) |
474ffc72 JH |
591 | { |
592 | if (TREE_CODE (node->symbol.decl) != VAR_DECL) | |
593 | { | |
594 | error ("variable symbol is not variable"); | |
595 | error_found = true; | |
596 | } | |
597 | } | |
598 | else | |
599 | { | |
600 | error ("node has unknown type"); | |
601 | error_found = true; | |
602 | } | |
603 | ||
604 | hashed_node = symtab_get_node (node->symbol.decl); | |
605 | if (!hashed_node) | |
606 | { | |
607 | error ("node not found in symtab decl hashtable"); | |
608 | error_found = true; | |
609 | } | |
610 | if (assembler_name_hash) | |
611 | { | |
612 | hashed_node = symtab_node_for_asm (DECL_ASSEMBLER_NAME (node->symbol.decl)); | |
613 | if (hashed_node && hashed_node->symbol.previous_sharing_asm_name) | |
614 | { | |
615 | error ("assembler name hash list corrupted"); | |
616 | error_found = true; | |
617 | } | |
618 | while (hashed_node) | |
619 | { | |
620 | if (hashed_node == node) | |
621 | break; | |
622 | hashed_node = hashed_node->symbol.next_sharing_asm_name; | |
623 | } | |
b5493fb2 | 624 | if (!hashed_node |
5d59b5e1 LC |
625 | && !(is_a <varpool_node> (node) |
626 | || DECL_HARD_REGISTER (node->symbol.decl))) | |
474ffc72 JH |
627 | { |
628 | error ("node not found in symtab assembler name hash"); | |
629 | error_found = true; | |
630 | } | |
631 | } | |
632 | if (node->symbol.previous_sharing_asm_name | |
633 | && node->symbol.previous_sharing_asm_name->symbol.next_sharing_asm_name != node) | |
634 | { | |
635 | error ("double linked list of assembler names corrupted"); | |
636 | } | |
637 | if (node->symbol.same_comdat_group) | |
638 | { | |
639 | symtab_node n = node->symbol.same_comdat_group; | |
640 | ||
641 | if (!DECL_ONE_ONLY (n->symbol.decl)) | |
642 | { | |
643 | error ("non-DECL_ONE_ONLY node in a same_comdat_group list"); | |
644 | error_found = true; | |
645 | } | |
646 | if (n->symbol.type != node->symbol.type) | |
647 | { | |
648 | error ("mixing different types of symbol in same comdat groups is not supported"); | |
649 | error_found = true; | |
650 | } | |
651 | if (n == node) | |
652 | { | |
653 | error ("node is alone in a comdat group"); | |
654 | error_found = true; | |
655 | } | |
656 | do | |
657 | { | |
658 | if (!n->symbol.same_comdat_group) | |
659 | { | |
660 | error ("same_comdat_group is not a circular list"); | |
661 | error_found = true; | |
662 | break; | |
663 | } | |
664 | n = n->symbol.same_comdat_group; | |
665 | } | |
666 | while (n != node); | |
667 | } | |
668 | return error_found; | |
669 | } | |
670 | ||
671 | /* Verify consistency of NODE. */ | |
672 | ||
673 | DEBUG_FUNCTION void | |
674 | verify_symtab_node (symtab_node node) | |
675 | { | |
676 | if (seen_error ()) | |
677 | return; | |
678 | ||
679 | timevar_push (TV_CGRAPH_VERIFY); | |
5d59b5e1 LC |
680 | if (cgraph_node *cnode = dyn_cast <cgraph_node> (node)) |
681 | verify_cgraph_node (cnode); | |
474ffc72 JH |
682 | else |
683 | if (verify_symtab_base (node)) | |
684 | { | |
685 | dump_symtab_node (stderr, node); | |
686 | internal_error ("verify_symtab_node failed"); | |
687 | } | |
688 | timevar_pop (TV_CGRAPH_VERIFY); | |
689 | } | |
690 | ||
691 | /* Verify symbol table for internal consistency. */ | |
692 | ||
693 | DEBUG_FUNCTION void | |
694 | verify_symtab (void) | |
695 | { | |
696 | symtab_node node; | |
697 | FOR_EACH_SYMBOL (node) | |
698 | verify_symtab_node (node); | |
699 | } | |
700 | ||
65d630d4 JH |
701 | /* Return true when RESOLUTION indicate that linker will use |
702 | the symbol from non-LTO object files. */ | |
703 | ||
704 | bool | |
705 | resolution_used_from_other_file_p (enum ld_plugin_symbol_resolution resolution) | |
706 | { | |
707 | return (resolution == LDPR_PREVAILING_DEF | |
708 | || resolution == LDPR_PREEMPTED_REG | |
709 | || resolution == LDPR_RESOLVED_EXEC | |
710 | || resolution == LDPR_RESOLVED_DYN); | |
711 | } | |
712 | ||
713 | /* Return true when NODE is known to be used from other (non-LTO) object file. | |
714 | Known only when doing LTO via linker plugin. */ | |
715 | ||
716 | bool | |
717 | symtab_used_from_object_file_p (symtab_node node) | |
718 | { | |
719 | if (!TREE_PUBLIC (node->symbol.decl) || DECL_EXTERNAL (node->symbol.decl)) | |
720 | return false; | |
721 | if (resolution_used_from_other_file_p (node->symbol.resolution)) | |
722 | return true; | |
723 | return false; | |
724 | } | |
725 | ||
726 | /* Make DECL local. FIXME: We shouldn't need to mess with rtl this early, | |
727 | but other code such as notice_global_symbol generates rtl. */ | |
728 | void | |
729 | symtab_make_decl_local (tree decl) | |
730 | { | |
731 | rtx rtl, symbol; | |
732 | ||
733 | if (TREE_CODE (decl) == VAR_DECL) | |
734 | DECL_COMMON (decl) = 0; | |
735 | else gcc_assert (TREE_CODE (decl) == FUNCTION_DECL); | |
736 | ||
737 | if (DECL_ONE_ONLY (decl) || DECL_COMDAT (decl)) | |
738 | { | |
739 | /* It is possible that we are linking against library defining same COMDAT | |
740 | function. To avoid conflict we need to rename our local name of the | |
741 | function just in the case WHOPR partitioning decide to make it hidden | |
742 | to avoid cross partition references. */ | |
743 | if (flag_wpa) | |
744 | { | |
745 | const char *old_name; | |
746 | symtab_node node = symtab_get_node (decl); | |
747 | old_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); | |
748 | change_decl_assembler_name (decl, | |
749 | clone_function_name (decl, "local")); | |
750 | if (node->symbol.lto_file_data) | |
751 | lto_record_renamed_decl (node->symbol.lto_file_data, | |
752 | old_name, | |
753 | IDENTIFIER_POINTER | |
754 | (DECL_ASSEMBLER_NAME (decl))); | |
755 | } | |
756 | DECL_SECTION_NAME (decl) = 0; | |
757 | DECL_COMDAT (decl) = 0; | |
758 | } | |
759 | DECL_COMDAT_GROUP (decl) = 0; | |
760 | DECL_WEAK (decl) = 0; | |
761 | DECL_EXTERNAL (decl) = 0; | |
b5493fb2 JH |
762 | DECL_VISIBILITY_SPECIFIED (decl) = 0; |
763 | DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT; | |
65d630d4 | 764 | TREE_PUBLIC (decl) = 0; |
1cdbb3f9 JH |
765 | DECL_VISIBILITY_SPECIFIED (decl) = 0; |
766 | DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT; | |
65d630d4 JH |
767 | if (!DECL_RTL_SET_P (decl)) |
768 | return; | |
769 | ||
770 | /* Update rtl flags. */ | |
771 | make_decl_rtl (decl); | |
772 | ||
773 | rtl = DECL_RTL (decl); | |
774 | if (!MEM_P (rtl)) | |
775 | return; | |
776 | ||
777 | symbol = XEXP (rtl, 0); | |
778 | if (GET_CODE (symbol) != SYMBOL_REF) | |
779 | return; | |
780 | ||
781 | SYMBOL_REF_WEAK (symbol) = DECL_WEAK (decl); | |
782 | } | |
1ab24192 | 783 | #include "gt-symtab.h" |