2 Copyright (C) 2012 Free Software Foundation, Inc.
3 Contributed by Jan Hubicka
5 This file is part of GCC.
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
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
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/>. */
23 #include "coretypes.h"
26 #include "tree-inline.h"
30 #include "diagnostic.h"
32 /* Hash table used to convert declarations into nodes. */
33 static GTY((param_is (union symtab_node_def
))) htab_t symtab_hash
;
34 /* Hash table used to convert assembler names into nodes. */
35 static GTY((param_is (union symtab_node_def
))) htab_t assembler_name_hash
;
37 /* Linked list of symbol table nodes. */
38 symtab_node symtab_nodes
;
40 /* The order index of the next symtab node to be created. This is
41 used so that we can sort the cgraph nodes in order by when we saw
42 them, to support -fno-toplevel-reorder. */
45 /* Returns a hash code for P. */
48 hash_node (const void *p
)
50 const_symtab_node n
= (const_symtab_node
) p
;
51 return (hashval_t
) DECL_UID (n
->symbol
.decl
);
55 /* Returns nonzero if P1 and P2 are equal. */
58 eq_node (const void *p1
, const void *p2
)
60 const_symtab_node n1
= (const_symtab_node
) p1
;
61 const_symtab_node n2
= (const_symtab_node
) p2
;
62 return DECL_UID (n1
->symbol
.decl
) == DECL_UID (n2
->symbol
.decl
);
65 /* Returns a hash code for P. */
68 hash_node_by_assembler_name (const void *p
)
70 const_symtab_node n
= (const_symtab_node
) p
;
71 return (hashval_t
) decl_assembler_name_hash (DECL_ASSEMBLER_NAME (n
->symbol
.decl
));
74 /* Returns nonzero if P1 and P2 are equal. */
77 eq_assembler_name (const void *p1
, const void *p2
)
79 const_symtab_node n1
= (const_symtab_node
) p1
;
80 const_tree name
= (const_tree
)p2
;
81 return (decl_assembler_name_equal (n1
->symbol
.decl
, name
));
84 /* Insert NODE to assembler name hash. */
87 insert_to_assembler_name_hash (symtab_node node
)
89 gcc_checking_assert (!node
->symbol
.previous_sharing_asm_name
90 && !node
->symbol
.next_sharing_asm_name
);
91 if (assembler_name_hash
)
94 tree name
= DECL_ASSEMBLER_NAME (node
->symbol
.decl
);
96 aslot
= htab_find_slot_with_hash (assembler_name_hash
, name
,
97 decl_assembler_name_hash (name
),
99 gcc_assert (*aslot
!= node
);
100 node
->symbol
.next_sharing_asm_name
= (symtab_node
)*aslot
;
102 ((symtab_node
)*aslot
)->symbol
.previous_sharing_asm_name
= node
;
108 /* Remove NODE from assembler name hash. */
111 unlink_from_assembler_name_hash (symtab_node node
)
113 if (assembler_name_hash
)
115 if (node
->symbol
.next_sharing_asm_name
)
116 node
->symbol
.next_sharing_asm_name
->symbol
.previous_sharing_asm_name
117 = node
->symbol
.previous_sharing_asm_name
;
118 if (node
->symbol
.previous_sharing_asm_name
)
120 node
->symbol
.previous_sharing_asm_name
->symbol
.next_sharing_asm_name
121 = node
->symbol
.next_sharing_asm_name
;
125 tree name
= DECL_ASSEMBLER_NAME (node
->symbol
.decl
);
127 slot
= htab_find_slot_with_hash (assembler_name_hash
, name
,
128 decl_assembler_name_hash (name
),
130 gcc_assert (*slot
== node
);
131 if (!node
->symbol
.next_sharing_asm_name
)
132 htab_clear_slot (assembler_name_hash
, slot
);
134 *slot
= node
->symbol
.next_sharing_asm_name
;
140 /* Add node into symbol table. This function is not used directly, but via
141 cgraph/varpool node creation routines. */
144 symtab_register_node (symtab_node node
)
146 struct symtab_node_base key
;
149 node
->symbol
.next
= symtab_nodes
;
150 node
->symbol
.previous
= NULL
;
152 symtab_nodes
->symbol
.previous
= node
;
156 symtab_hash
= htab_create_ggc (10, hash_node
, eq_node
, NULL
);
157 key
.decl
= node
->symbol
.decl
;
158 slot
= (symtab_node
*) htab_find_slot (symtab_hash
, &key
, INSERT
);
162 insert_to_assembler_name_hash (node
);
164 node
->symbol
.order
= symtab_order
++;
166 ipa_empty_ref_list (&node
->symbol
.ref_list
);
169 /* Make NODE to be the one symtab hash is pointing to. Used when reshaping tree
173 symtab_insert_node_to_hashtable (symtab_node node
)
175 struct symtab_node_base key
;
179 symtab_hash
= htab_create_ggc (10, hash_node
, eq_node
, NULL
);
180 key
.decl
= node
->symbol
.decl
;
181 slot
= (symtab_node
*) htab_find_slot (symtab_hash
, &key
, INSERT
);
185 /* Remove node from symbol table. This function is not used directly, but via
186 cgraph/varpool node removal routines. */
189 symtab_unregister_node (symtab_node node
)
192 ipa_remove_all_references (&node
->symbol
.ref_list
);
193 ipa_remove_all_refering (&node
->symbol
.ref_list
);
195 if (node
->symbol
.same_comdat_group
)
198 for (prev
= node
->symbol
.same_comdat_group
;
199 prev
->symbol
.same_comdat_group
!= node
;
200 prev
= prev
->symbol
.same_comdat_group
)
202 if (node
->symbol
.same_comdat_group
== prev
)
203 prev
->symbol
.same_comdat_group
= NULL
;
205 prev
->symbol
.same_comdat_group
= node
->symbol
.same_comdat_group
;
206 node
->symbol
.same_comdat_group
= NULL
;
209 if (node
->symbol
.previous
)
210 node
->symbol
.previous
->symbol
.next
= node
->symbol
.next
;
212 symtab_nodes
= node
->symbol
.next
;
213 if (node
->symbol
.next
)
214 node
->symbol
.next
->symbol
.previous
= node
->symbol
.previous
;
215 node
->symbol
.next
= NULL
;
216 node
->symbol
.previous
= NULL
;
218 slot
= htab_find_slot (symtab_hash
, node
, NO_INSERT
);
221 symtab_node replacement_node
= NULL
;
222 if (symtab_function_p (node
))
223 replacement_node
= (symtab_node
)cgraph_find_replacement_node (cgraph (node
));
224 if (!replacement_node
)
225 htab_clear_slot (symtab_hash
, slot
);
227 *slot
= replacement_node
;
229 unlink_from_assembler_name_hash (node
);
232 /* Return symbol table node associated with DECL, if any,
233 and NULL otherwise. */
236 symtab_get_node (const_tree decl
)
239 struct symtab_node_base key
;
241 gcc_checking_assert (TREE_CODE (decl
) == FUNCTION_DECL
242 || (TREE_CODE (decl
) == VAR_DECL
243 && (TREE_STATIC (decl
) || DECL_EXTERNAL (decl
)
249 key
.decl
= CONST_CAST2 (tree
, const_tree
, decl
);
251 slot
= (symtab_node
*) htab_find_slot (symtab_hash
, &key
,
259 /* Remove symtab NODE from the symbol table. */
262 symtab_remove_node (symtab_node node
)
264 if (symtab_function_p (node
))
265 cgraph_remove_node (cgraph (node
));
266 else if (symtab_variable_p (node
))
267 varpool_remove_node (varpool (node
));
270 /* Return the cgraph node that has ASMNAME for its DECL_ASSEMBLER_NAME.
271 Return NULL if there's no such node. */
274 symtab_node_for_asm (const_tree asmname
)
279 if (!assembler_name_hash
)
281 assembler_name_hash
=
282 htab_create_ggc (10, hash_node_by_assembler_name
, eq_assembler_name
,
284 FOR_EACH_SYMBOL (node
)
285 insert_to_assembler_name_hash (node
);
288 slot
= htab_find_slot_with_hash (assembler_name_hash
, asmname
,
289 decl_assembler_name_hash (asmname
),
294 node
= (symtab_node
) *slot
;
300 /* Set the DECL_ASSEMBLER_NAME and update symtab hashtables. */
303 change_decl_assembler_name (tree decl
, tree name
)
305 symtab_node node
= NULL
;
307 /* We can have user ASM names on things, like global register variables, that
308 are not in the symbol table. */
309 if ((TREE_CODE (decl
) == VAR_DECL
310 && (TREE_STATIC (decl
) || DECL_EXTERNAL (decl
)))
311 || TREE_CODE (decl
) == FUNCTION_DECL
)
312 node
= symtab_get_node (decl
);
313 if (!DECL_ASSEMBLER_NAME_SET_P (decl
))
315 SET_DECL_ASSEMBLER_NAME (decl
, name
);
317 insert_to_assembler_name_hash (node
);
321 if (name
== DECL_ASSEMBLER_NAME (decl
))
325 unlink_from_assembler_name_hash (node
);
326 if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl
))
327 && DECL_RTL_SET_P (decl
))
328 warning (0, "%D renamed after being referenced in assembly", decl
);
330 SET_DECL_ASSEMBLER_NAME (decl
, name
);
332 insert_to_assembler_name_hash (node
);
336 #include "gt-symtab.h"