]>
Commit | Line | Data |
---|---|---|
8a4a83ed | 1 | /* Callgraph handling code. |
c75c517d | 2 | Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2010 |
66647d44 | 3 | Free Software Foundation, Inc. |
8a4a83ed JH |
4 | Contributed by Jan Hubicka |
5 | ||
6 | This file is part of GCC. | |
7 | ||
8 | GCC is free software; you can redistribute it and/or modify it under | |
9 | the terms of the GNU General Public License as published by the Free | |
9dcd6f09 | 10 | Software Foundation; either version 3, or (at your option) any later |
8a4a83ed JH |
11 | version. |
12 | ||
13 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
14 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 | for more details. | |
17 | ||
18 | You should have received a copy of the GNU General Public License | |
9dcd6f09 NC |
19 | along with GCC; see the file COPYING3. If not see |
20 | <http://www.gnu.org/licenses/>. */ | |
8a4a83ed JH |
21 | |
22 | #include "config.h" | |
23 | #include "system.h" | |
24 | #include "coretypes.h" | |
25 | #include "tm.h" | |
26 | #include "tree.h" | |
27 | #include "cgraph.h" | |
28 | #include "langhooks.h" | |
1da2ed5f | 29 | #include "diagnostic-core.h" |
8a4a83ed JH |
30 | #include "hashtab.h" |
31 | #include "ggc.h" | |
32 | #include "timevar.h" | |
b8698a0f | 33 | #include "debug.h" |
8a4a83ed JH |
34 | #include "target.h" |
35 | #include "output.h" | |
726a989a | 36 | #include "gimple.h" |
43d861a5 | 37 | #include "tree-flow.h" |
b20996ff | 38 | #include "flags.h" |
8a4a83ed JH |
39 | |
40 | /* This file contains basic routines manipulating variable pool. | |
41 | ||
42 | Varpool acts as interface in between the front-end and middle-end | |
43 | and drives the decision process on what variables and when are | |
44 | going to be compiled. | |
45 | ||
2e226e66 | 46 | The varpool nodes are allocated lazily for declarations |
8a4a83ed JH |
47 | either by frontend or at callgraph construction time. |
48 | All variables supposed to be output into final file needs to be | |
dbb23ff7 | 49 | explicitly marked by frontend via VARPOOL_FINALIZE_DECL function. */ |
8a4a83ed JH |
50 | |
51 | /* Hash table used to convert declarations into nodes. */ | |
52 | static GTY((param_is (struct varpool_node))) htab_t varpool_hash; | |
53 | ||
54 | /* The linked list of cgraph varpool nodes. | |
55 | Linked via node->next pointer. */ | |
56 | struct varpool_node *varpool_nodes; | |
57 | ||
58 | /* Queue of cgraph nodes scheduled to be lowered and output. | |
59 | The queue is maintained via mark_needed_node, linked via node->next_needed | |
b8698a0f | 60 | pointer. |
8a4a83ed | 61 | |
f9837879 | 62 | LAST_NEEDED_NODE points to the end of queue, so it can be |
f3a032e9 | 63 | maintained in forward order. GTY is needed to make it friendly to |
f9837879 | 64 | PCH. |
b8698a0f | 65 | |
7e8b322a | 66 | During compilation we construct the queue of needed variables |
8a4a83ed JH |
67 | twice: first time it is during cgraph construction, second time it is at the |
68 | end of compilation in VARPOOL_REMOVE_UNREFERENCED_DECLS so we can avoid | |
69 | optimized out variables being output. | |
b8698a0f L |
70 | |
71 | Each variable is thus first analyzed and then later possibly output. | |
8a4a83ed JH |
72 | FIRST_UNANALYZED_NODE points to first node in queue that was not analyzed |
73 | yet and is moved via VARPOOL_ANALYZE_PENDING_DECLS. */ | |
b8698a0f | 74 | |
8a4a83ed JH |
75 | struct varpool_node *varpool_nodes_queue; |
76 | static GTY(()) struct varpool_node *varpool_last_needed_node; | |
77 | static GTY(()) struct varpool_node *varpool_first_unanalyzed_node; | |
78 | ||
79 | /* Lists all assembled variables to be sent to debugger output later on. */ | |
80 | static GTY(()) struct varpool_node *varpool_assembled_nodes_queue; | |
81 | ||
82 | /* Return name of the node used in debug output. */ | |
a8289259 | 83 | const char * |
8a4a83ed JH |
84 | varpool_node_name (struct varpool_node *node) |
85 | { | |
86 | return lang_hooks.decl_printable_name (node->decl, 2); | |
87 | } | |
88 | ||
89 | /* Returns a hash code for P. */ | |
90 | static hashval_t | |
91 | hash_varpool_node (const void *p) | |
92 | { | |
93 | const struct varpool_node *n = (const struct varpool_node *) p; | |
94 | return (hashval_t) DECL_UID (n->decl); | |
95 | } | |
96 | ||
97 | /* Returns nonzero if P1 and P2 are equal. */ | |
98 | static int | |
99 | eq_varpool_node (const void *p1, const void *p2) | |
100 | { | |
101 | const struct varpool_node *n1 = | |
102 | (const struct varpool_node *) p1; | |
103 | const struct varpool_node *n2 = | |
104 | (const struct varpool_node *) p2; | |
105 | return DECL_UID (n1->decl) == DECL_UID (n2->decl); | |
106 | } | |
107 | ||
2942c502 JH |
108 | /* Return varpool node assigned to DECL without creating new one. */ |
109 | struct varpool_node * | |
051f8cc6 | 110 | varpool_get_node (const_tree decl) |
2942c502 JH |
111 | { |
112 | struct varpool_node key, **slot; | |
113 | ||
a482b1f5 JH |
114 | gcc_assert (TREE_CODE (decl) == VAR_DECL |
115 | && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))); | |
2942c502 JH |
116 | |
117 | if (!varpool_hash) | |
118 | return NULL; | |
051f8cc6 | 119 | key.decl = CONST_CAST2 (tree, const_tree, decl); |
2942c502 | 120 | slot = (struct varpool_node **) |
4cceafb8 JH |
121 | htab_find_slot (varpool_hash, &key, NO_INSERT); |
122 | if (!slot) | |
123 | return NULL; | |
2942c502 JH |
124 | return *slot; |
125 | } | |
126 | ||
8a4a83ed JH |
127 | /* Return varpool node assigned to DECL. Create new one when needed. */ |
128 | struct varpool_node * | |
129 | varpool_node (tree decl) | |
130 | { | |
131 | struct varpool_node key, *node, **slot; | |
132 | ||
a482b1f5 JH |
133 | gcc_assert (TREE_CODE (decl) == VAR_DECL |
134 | && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))); | |
8a4a83ed JH |
135 | |
136 | if (!varpool_hash) | |
137 | varpool_hash = htab_create_ggc (10, hash_varpool_node, | |
138 | eq_varpool_node, NULL); | |
139 | key.decl = decl; | |
140 | slot = (struct varpool_node **) | |
141 | htab_find_slot (varpool_hash, &key, INSERT); | |
142 | if (*slot) | |
143 | return *slot; | |
a9429e29 | 144 | node = ggc_alloc_cleared_varpool_node (); |
8a4a83ed JH |
145 | node->decl = decl; |
146 | node->order = cgraph_order++; | |
147 | node->next = varpool_nodes; | |
369451ec | 148 | ipa_empty_ref_list (&node->ref_list); |
2942c502 JH |
149 | if (varpool_nodes) |
150 | varpool_nodes->prev = node; | |
8a4a83ed JH |
151 | varpool_nodes = node; |
152 | *slot = node; | |
153 | return node; | |
154 | } | |
155 | ||
2942c502 JH |
156 | /* Remove node from the varpool. */ |
157 | void | |
158 | varpool_remove_node (struct varpool_node *node) | |
159 | { | |
160 | void **slot; | |
161 | slot = htab_find_slot (varpool_hash, node, NO_INSERT); | |
162 | gcc_assert (*slot == node); | |
163 | htab_clear_slot (varpool_hash, slot); | |
164 | gcc_assert (!varpool_assembled_nodes_queue); | |
688a10c2 JH |
165 | if (!node->alias) |
166 | while (node->extra_name) | |
167 | varpool_remove_node (node->extra_name); | |
2942c502 JH |
168 | if (node->next) |
169 | node->next->prev = node->prev; | |
170 | if (node->prev) | |
171 | node->prev->next = node->next; | |
688a10c2 | 172 | else |
2942c502 | 173 | { |
a14f1878 | 174 | if (node->alias && node->extra_name) |
688a10c2 JH |
175 | { |
176 | gcc_assert (node->extra_name->extra_name == node); | |
177 | node->extra_name->extra_name = node->next; | |
178 | } | |
179 | else | |
180 | { | |
181 | gcc_assert (varpool_nodes == node); | |
182 | varpool_nodes = node->next; | |
183 | } | |
2942c502 JH |
184 | } |
185 | if (varpool_first_unanalyzed_node == node) | |
186 | varpool_first_unanalyzed_node = node->next_needed; | |
187 | if (node->next_needed) | |
188 | node->next_needed->prev_needed = node->prev_needed; | |
189 | else if (node->prev_needed) | |
190 | { | |
191 | gcc_assert (varpool_last_needed_node); | |
192 | varpool_last_needed_node = node->prev_needed; | |
193 | } | |
194 | if (node->prev_needed) | |
195 | node->prev_needed->next_needed = node->next_needed; | |
196 | else if (node->next_needed) | |
197 | { | |
198 | gcc_assert (varpool_nodes_queue == node); | |
199 | varpool_nodes_queue = node->next_needed; | |
200 | } | |
9f90e80a JH |
201 | if (node->same_comdat_group) |
202 | { | |
203 | struct varpool_node *prev; | |
204 | for (prev = node->same_comdat_group; | |
205 | prev->same_comdat_group != node; | |
206 | prev = prev->same_comdat_group) | |
207 | ; | |
208 | if (node->same_comdat_group == prev) | |
209 | prev->same_comdat_group = NULL; | |
210 | else | |
211 | prev->same_comdat_group = node->same_comdat_group; | |
212 | node->same_comdat_group = NULL; | |
213 | } | |
369451ec JH |
214 | ipa_remove_all_references (&node->ref_list); |
215 | ipa_remove_all_refering (&node->ref_list); | |
688a10c2 | 216 | ggc_free (node); |
2942c502 JH |
217 | } |
218 | ||
8a4a83ed JH |
219 | /* Dump given cgraph node. */ |
220 | void | |
221 | dump_varpool_node (FILE *f, struct varpool_node *node) | |
222 | { | |
223 | fprintf (f, "%s:", varpool_node_name (node)); | |
224 | fprintf (f, " availability:%s", | |
225 | cgraph_function_flags_ready | |
226 | ? cgraph_availability_names[cgraph_variable_initializer_availability (node)] | |
227 | : "not-ready"); | |
2942c502 JH |
228 | if (DECL_ASSEMBLER_NAME_SET_P (node->decl)) |
229 | fprintf (f, " (asm: %s)", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->decl))); | |
8a4a83ed JH |
230 | if (DECL_INITIAL (node->decl)) |
231 | fprintf (f, " initialized"); | |
2942c502 JH |
232 | if (TREE_ASM_WRITTEN (node->decl)) |
233 | fprintf (f, " (asm written)"); | |
8a4a83ed JH |
234 | if (node->needed) |
235 | fprintf (f, " needed"); | |
236 | if (node->analyzed) | |
237 | fprintf (f, " analyzed"); | |
238 | if (node->finalized) | |
239 | fprintf (f, " finalized"); | |
240 | if (node->output) | |
241 | fprintf (f, " output"); | |
242 | if (node->externally_visible) | |
243 | fprintf (f, " externally_visible"); | |
2942c502 JH |
244 | if (node->in_other_partition) |
245 | fprintf (f, " in_other_partition"); | |
246 | else if (node->used_from_other_partition) | |
247 | fprintf (f, " used_from_other_partition"); | |
8a4a83ed | 248 | fprintf (f, "\n"); |
369451ec JH |
249 | fprintf (f, " References: "); |
250 | ipa_dump_references (f, &node->ref_list); | |
251 | fprintf (f, " Refering this var: "); | |
252 | ipa_dump_refering (f, &node->ref_list); | |
8a4a83ed JH |
253 | } |
254 | ||
255 | /* Dump the variable pool. */ | |
256 | void | |
257 | dump_varpool (FILE *f) | |
258 | { | |
259 | struct varpool_node *node; | |
260 | ||
261 | fprintf (f, "variable pool:\n\n"); | |
f3a032e9 | 262 | for (node = varpool_nodes; node; node = node->next) |
8a4a83ed JH |
263 | dump_varpool_node (f, node); |
264 | } | |
265 | ||
d85478c2 RAE |
266 | /* Dump the variable pool to stderr. */ |
267 | ||
24e47c76 | 268 | DEBUG_FUNCTION void |
d85478c2 RAE |
269 | debug_varpool (void) |
270 | { | |
271 | dump_varpool (stderr); | |
272 | } | |
273 | ||
8a4a83ed JH |
274 | /* Given an assembler name, lookup node. */ |
275 | struct varpool_node * | |
276 | varpool_node_for_asm (tree asmname) | |
277 | { | |
278 | struct varpool_node *node; | |
279 | ||
280 | for (node = varpool_nodes; node ; node = node->next) | |
281 | if (decl_assembler_name_equal (node->decl, asmname)) | |
282 | return node; | |
283 | ||
284 | return NULL; | |
285 | } | |
286 | ||
287 | /* Helper function for finalization code - add node into lists so it will | |
288 | be analyzed and compiled. */ | |
289 | static void | |
290 | varpool_enqueue_needed_node (struct varpool_node *node) | |
291 | { | |
292 | if (varpool_last_needed_node) | |
2942c502 JH |
293 | { |
294 | varpool_last_needed_node->next_needed = node; | |
295 | node->prev_needed = varpool_last_needed_node; | |
296 | } | |
8a4a83ed JH |
297 | varpool_last_needed_node = node; |
298 | node->next_needed = NULL; | |
299 | if (!varpool_nodes_queue) | |
300 | varpool_nodes_queue = node; | |
301 | if (!varpool_first_unanalyzed_node) | |
302 | varpool_first_unanalyzed_node = node; | |
303 | notice_global_symbol (node->decl); | |
304 | } | |
305 | ||
306 | /* Notify finalize_compilation_unit that given node is reachable | |
307 | or needed. */ | |
308 | void | |
309 | varpool_mark_needed_node (struct varpool_node *node) | |
310 | { | |
2c71ac78 JM |
311 | if (node->alias && node->extra_name) |
312 | node = node->extra_name; | |
8a4a83ed JH |
313 | if (!node->needed && node->finalized |
314 | && !TREE_ASM_WRITTEN (node->decl)) | |
315 | varpool_enqueue_needed_node (node); | |
316 | node->needed = 1; | |
317 | } | |
318 | ||
319 | /* Reset the queue of needed nodes. */ | |
b34fd25c | 320 | void |
8a4a83ed JH |
321 | varpool_reset_queue (void) |
322 | { | |
323 | varpool_last_needed_node = NULL; | |
324 | varpool_nodes_queue = NULL; | |
325 | varpool_first_unanalyzed_node = NULL; | |
326 | } | |
327 | ||
328 | /* Determine if variable DECL is needed. That is, visible to something | |
329 | either outside this translation unit, something magic in the system | |
7e8b322a | 330 | configury */ |
8a4a83ed JH |
331 | bool |
332 | decide_is_variable_needed (struct varpool_node *node, tree decl) | |
333 | { | |
2942c502 | 334 | if (node->used_from_other_partition) |
c9945504 | 335 | return true; |
8a4a83ed | 336 | /* If the user told us it is used, then it must be so. */ |
a8289259 JH |
337 | if ((node->externally_visible && !DECL_COMDAT (decl)) |
338 | || node->force_output) | |
8a4a83ed | 339 | return true; |
8a4a83ed | 340 | |
8a4a83ed JH |
341 | /* Externally visible variables must be output. The exception is |
342 | COMDAT variables that must be output only when they are needed. */ | |
b20996ff JH |
343 | if (TREE_PUBLIC (decl) |
344 | && !flag_whole_program | |
345 | && !flag_lto | |
346 | && !flag_whopr | |
347 | && !DECL_COMDAT (decl) | |
8a4a83ed JH |
348 | && !DECL_EXTERNAL (decl)) |
349 | return true; | |
350 | ||
351 | /* When not reordering top level variables, we have to assume that | |
352 | we are going to keep everything. */ | |
7e8b322a | 353 | if (flag_toplevel_reorder) |
8a4a83ed JH |
354 | return false; |
355 | ||
356 | /* We want to emit COMDAT variables only when absolutely necessary. */ | |
357 | if (DECL_COMDAT (decl)) | |
358 | return false; | |
359 | return true; | |
360 | } | |
361 | ||
64e0f5ff JH |
362 | /* Return if DECL is constant and its initial value is known (so we can do |
363 | constant folding using DECL_INITIAL (decl)). */ | |
155c92a7 JH |
364 | |
365 | bool | |
64e0f5ff | 366 | const_value_known_p (tree decl) |
155c92a7 | 367 | { |
1d0804d4 JH |
368 | if (TREE_CODE (decl) != VAR_DECL |
369 | &&TREE_CODE (decl) != CONST_DECL) | |
64e0f5ff JH |
370 | return false; |
371 | ||
372 | if (TREE_CODE (decl) == CONST_DECL | |
373 | || DECL_IN_CONSTANT_POOL (decl)) | |
374 | return true; | |
155c92a7 | 375 | |
155c92a7 | 376 | gcc_assert (TREE_CODE (decl) == VAR_DECL); |
64e0f5ff | 377 | |
155c92a7 JH |
378 | if (!TREE_READONLY (decl)) |
379 | return false; | |
64e0f5ff JH |
380 | |
381 | /* Gimplifier takes away constructors of local vars */ | |
382 | if (!TREE_STATIC (decl) && !DECL_EXTERNAL (decl)) | |
383 | return DECL_INITIAL (decl) != NULL; | |
384 | ||
385 | gcc_assert (TREE_STATIC (decl) || DECL_EXTERNAL (decl)); | |
386 | ||
155c92a7 JH |
387 | /* Variables declared 'const' without an initializer |
388 | have zero as the initializer if they may not be | |
389 | overridden at link or run time. */ | |
390 | if (!DECL_INITIAL (decl) | |
391 | && (DECL_EXTERNAL (decl) | |
051f8cc6 | 392 | || decl_replaceable_p (decl))) |
155c92a7 JH |
393 | return false; |
394 | ||
395 | /* Variables declared `const' with an initializer are considered | |
396 | to not be overwritable with different initializer by default. | |
397 | ||
398 | ??? Previously we behaved so for scalar variables but not for array | |
399 | accesses. */ | |
400 | return true; | |
401 | } | |
402 | ||
8a4a83ed JH |
403 | /* Mark DECL as finalized. By finalizing the declaration, frontend instruct the |
404 | middle end to output the variable to asm file, if needed or externally | |
405 | visible. */ | |
406 | void | |
407 | varpool_finalize_decl (tree decl) | |
408 | { | |
409 | struct varpool_node *node = varpool_node (decl); | |
410 | ||
a482b1f5 JH |
411 | gcc_assert (TREE_STATIC (decl)); |
412 | ||
8a4a83ed JH |
413 | /* The first declaration of a variable that comes through this function |
414 | decides whether it is global (in C, has external linkage) | |
415 | or local (in C, has internal linkage). So do nothing more | |
416 | if this function has already run. */ | |
417 | if (node->finalized) | |
418 | { | |
7e8b322a | 419 | if (cgraph_global_info_ready) |
8a4a83ed JH |
420 | varpool_assemble_pending_decls (); |
421 | return; | |
422 | } | |
423 | if (node->needed) | |
424 | varpool_enqueue_needed_node (node); | |
425 | node->finalized = true; | |
4a444e58 | 426 | if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)) |
b34fd25c | 427 | node->force_output = true; |
8a4a83ed JH |
428 | |
429 | if (decide_is_variable_needed (node, decl)) | |
430 | varpool_mark_needed_node (node); | |
431 | /* Since we reclaim unreachable nodes at the end of every language | |
432 | level unit, we need to be conservative about possible entry points | |
433 | there. */ | |
434 | else if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl)) | |
435 | varpool_mark_needed_node (node); | |
7e8b322a | 436 | if (cgraph_global_info_ready) |
8a4a83ed JH |
437 | varpool_assemble_pending_decls (); |
438 | } | |
439 | ||
440 | /* Return variable availability. See cgraph.h for description of individual | |
441 | return values. */ | |
442 | enum availability | |
443 | cgraph_variable_initializer_availability (struct varpool_node *node) | |
444 | { | |
445 | gcc_assert (cgraph_function_flags_ready); | |
446 | if (!node->finalized) | |
447 | return AVAIL_NOT_AVAILABLE; | |
448 | if (!TREE_PUBLIC (node->decl)) | |
449 | return AVAIL_AVAILABLE; | |
450 | /* If the variable can be overwritten, return OVERWRITABLE. Takes | |
451 | care of at least two notable extensions - the COMDAT variables | |
452 | used to share template instantiations in C++. */ | |
051f8cc6 | 453 | if (!decl_replaceable_p (node->decl)) |
8a4a83ed JH |
454 | return AVAIL_OVERWRITABLE; |
455 | return AVAIL_AVAILABLE; | |
456 | } | |
457 | ||
458 | /* Walk the decls we marked as necessary and see if they reference new | |
459 | variables or functions and add them into the worklists. */ | |
460 | bool | |
461 | varpool_analyze_pending_decls (void) | |
462 | { | |
463 | bool changed = false; | |
8a4a83ed | 464 | |
49ba8180 | 465 | timevar_push (TV_VARPOOL); |
8a4a83ed JH |
466 | while (varpool_first_unanalyzed_node) |
467 | { | |
9f90e80a JH |
468 | struct varpool_node *node = varpool_first_unanalyzed_node, *next; |
469 | tree decl = node->decl; | |
470 | bool analyzed = node->analyzed; | |
8a4a83ed JH |
471 | |
472 | varpool_first_unanalyzed_node->analyzed = true; | |
473 | ||
474 | varpool_first_unanalyzed_node = varpool_first_unanalyzed_node->next_needed; | |
475 | ||
b20996ff JH |
476 | /* When reading back varpool at LTO time, we re-construct the queue in order |
477 | to have "needed" list right by inserting all needed nodes into varpool. | |
478 | We however don't want to re-analyze already analyzed nodes. */ | |
479 | if (!analyzed) | |
480 | { | |
2942c502 | 481 | gcc_assert (!in_lto_p || cgraph_function_flags_ready); |
b20996ff JH |
482 | /* Compute the alignment early so function body expanders are |
483 | already informed about increased alignment. */ | |
484 | align_variable (decl, 0); | |
b20996ff | 485 | } |
625f802c JH |
486 | if (DECL_INITIAL (decl)) |
487 | record_references_in_initializer (decl, analyzed); | |
9f90e80a JH |
488 | if (node->same_comdat_group) |
489 | { | |
490 | for (next = node->same_comdat_group; | |
491 | next != node; | |
492 | next = next->same_comdat_group) | |
493 | varpool_mark_needed_node (next); | |
494 | } | |
8a4a83ed JH |
495 | changed = true; |
496 | } | |
49ba8180 | 497 | timevar_pop (TV_VARPOOL); |
8a4a83ed JH |
498 | return changed; |
499 | } | |
500 | ||
501 | /* Output one variable, if necessary. Return whether we output it. */ | |
502 | bool | |
503 | varpool_assemble_decl (struct varpool_node *node) | |
504 | { | |
505 | tree decl = node->decl; | |
506 | ||
507 | if (!TREE_ASM_WRITTEN (decl) | |
508 | && !node->alias | |
2942c502 | 509 | && !node->in_other_partition |
8a4a83ed JH |
510 | && !DECL_EXTERNAL (decl) |
511 | && (TREE_CODE (decl) != VAR_DECL || !DECL_HAS_VALUE_EXPR_P (decl))) | |
512 | { | |
513 | assemble_variable (decl, 0, 1, 0); | |
7386e3ee JH |
514 | if (TREE_ASM_WRITTEN (decl)) |
515 | { | |
2c71ac78 JM |
516 | struct varpool_node *alias; |
517 | ||
7386e3ee | 518 | node->next_needed = varpool_assembled_nodes_queue; |
2942c502 JH |
519 | node->prev_needed = NULL; |
520 | if (varpool_assembled_nodes_queue) | |
521 | varpool_assembled_nodes_queue->prev_needed = node; | |
7386e3ee JH |
522 | varpool_assembled_nodes_queue = node; |
523 | node->finalized = 1; | |
2c71ac78 JM |
524 | |
525 | /* Also emit any extra name aliases. */ | |
526 | for (alias = node->extra_name; alias; alias = alias->next) | |
527 | { | |
528 | /* Update linkage fields in case they've changed. */ | |
529 | DECL_WEAK (alias->decl) = DECL_WEAK (decl); | |
530 | TREE_PUBLIC (alias->decl) = TREE_PUBLIC (decl); | |
531 | DECL_VISIBILITY (alias->decl) = DECL_VISIBILITY (decl); | |
532 | assemble_alias (alias->decl, DECL_ASSEMBLER_NAME (decl)); | |
533 | } | |
534 | ||
7386e3ee JH |
535 | return true; |
536 | } | |
8a4a83ed JH |
537 | } |
538 | ||
539 | return false; | |
540 | } | |
541 | ||
542 | /* Optimization of function bodies might've rendered some variables as | |
543 | unnecessary so we want to avoid these from being compiled. | |
544 | ||
545 | This is done by pruning the queue and keeping only the variables that | |
546 | really appear needed (ie they are either externally visible or referenced | |
547 | by compiled function). Re-doing the reachability analysis on variables | |
548 | brings back the remaining variables referenced by these. */ | |
549 | void | |
550 | varpool_remove_unreferenced_decls (void) | |
551 | { | |
552 | struct varpool_node *next, *node = varpool_nodes_queue; | |
553 | ||
554 | varpool_reset_queue (); | |
555 | ||
1da2ed5f | 556 | if (seen_error ()) |
8a4a83ed JH |
557 | return; |
558 | ||
559 | while (node) | |
560 | { | |
561 | tree decl = node->decl; | |
562 | next = node->next_needed; | |
563 | node->needed = 0; | |
564 | ||
565 | if (node->finalized | |
8893239d | 566 | && (decide_is_variable_needed (node, decl) |
8a4a83ed JH |
567 | /* ??? Cgraph does not yet rule the world with an iron hand, |
568 | and does not control the emission of debug information. | |
569 | After a variable has its DECL_RTL set, we must assume that | |
570 | it may be referenced by the debug information, and we can | |
571 | no longer elide it. */ | |
572 | || DECL_RTL_SET_P (decl))) | |
573 | varpool_mark_needed_node (node); | |
574 | ||
575 | node = next; | |
576 | } | |
577 | /* Make sure we mark alias targets as used targets. */ | |
578 | finish_aliases_1 (); | |
579 | varpool_analyze_pending_decls (); | |
580 | } | |
581 | ||
582 | /* Output all variables enqueued to be assembled. */ | |
583 | bool | |
584 | varpool_assemble_pending_decls (void) | |
585 | { | |
586 | bool changed = false; | |
587 | ||
1da2ed5f | 588 | if (seen_error ()) |
8a4a83ed JH |
589 | return false; |
590 | ||
49ba8180 | 591 | timevar_push (TV_VAROUT); |
8a4a83ed JH |
592 | /* EH might mark decls as needed during expansion. This should be safe since |
593 | we don't create references to new function, but it should not be used | |
594 | elsewhere. */ | |
595 | varpool_analyze_pending_decls (); | |
596 | ||
597 | while (varpool_nodes_queue) | |
598 | { | |
599 | struct varpool_node *node = varpool_nodes_queue; | |
600 | ||
601 | varpool_nodes_queue = varpool_nodes_queue->next_needed; | |
602 | if (varpool_assemble_decl (node)) | |
7386e3ee | 603 | changed = true; |
8a4a83ed | 604 | else |
2942c502 JH |
605 | { |
606 | node->prev_needed = NULL; | |
607 | node->next_needed = NULL; | |
608 | } | |
8a4a83ed | 609 | } |
a615f803 SE |
610 | /* varpool_nodes_queue is now empty, clear the pointer to the last element |
611 | in the queue. */ | |
612 | varpool_last_needed_node = NULL; | |
49ba8180 | 613 | timevar_pop (TV_VAROUT); |
8a4a83ed JH |
614 | return changed; |
615 | } | |
616 | ||
7386e3ee JH |
617 | /* Remove all elements from the queue so we can re-use it for debug output. */ |
618 | void | |
619 | varpool_empty_needed_queue (void) | |
620 | { | |
621 | /* EH might mark decls as needed during expansion. This should be safe since | |
622 | we don't create references to new function, but it should not be used | |
623 | elsewhere. */ | |
624 | varpool_analyze_pending_decls (); | |
625 | ||
626 | while (varpool_nodes_queue) | |
627 | { | |
628 | struct varpool_node *node = varpool_nodes_queue; | |
629 | varpool_nodes_queue = varpool_nodes_queue->next_needed; | |
630 | node->next_needed = NULL; | |
2942c502 | 631 | node->prev_needed = NULL; |
7386e3ee JH |
632 | } |
633 | /* varpool_nodes_queue is now empty, clear the pointer to the last element | |
634 | in the queue. */ | |
635 | varpool_last_needed_node = NULL; | |
636 | } | |
637 | ||
43d861a5 RL |
638 | /* Create a new global variable of type TYPE. */ |
639 | tree | |
640 | add_new_static_var (tree type) | |
641 | { | |
642 | tree new_decl; | |
643 | struct varpool_node *new_node; | |
644 | ||
645 | new_decl = create_tmp_var (type, NULL); | |
646 | DECL_NAME (new_decl) = create_tmp_var_name (NULL); | |
647 | TREE_READONLY (new_decl) = 0; | |
648 | TREE_STATIC (new_decl) = 1; | |
649 | TREE_USED (new_decl) = 1; | |
650 | DECL_CONTEXT (new_decl) = NULL_TREE; | |
651 | DECL_ABSTRACT (new_decl) = 0; | |
652 | lang_hooks.dup_lang_specific_decl (new_decl); | |
653 | create_var_ann (new_decl); | |
654 | new_node = varpool_node (new_decl); | |
655 | varpool_mark_needed_node (new_node); | |
656 | add_referenced_var (new_decl); | |
657 | varpool_finalize_decl (new_decl); | |
658 | ||
659 | return new_node->decl; | |
660 | } | |
661 | ||
2c71ac78 JM |
662 | /* Attempt to mark ALIAS as an alias to DECL. Return TRUE if successful. |
663 | Extra name aliases are output whenever DECL is output. */ | |
664 | ||
051f8cc6 | 665 | struct varpool_node * |
2c71ac78 JM |
666 | varpool_extra_name_alias (tree alias, tree decl) |
667 | { | |
668 | struct varpool_node key, *alias_node, *decl_node, **slot; | |
669 | ||
670 | #ifndef ASM_OUTPUT_DEF | |
671 | /* If aliases aren't supported by the assembler, fail. */ | |
672 | return false; | |
673 | #endif | |
674 | ||
675 | gcc_assert (TREE_CODE (decl) == VAR_DECL); | |
676 | gcc_assert (TREE_CODE (alias) == VAR_DECL); | |
677 | /* Make sure the hash table has been created. */ | |
678 | decl_node = varpool_node (decl); | |
679 | ||
680 | key.decl = alias; | |
681 | ||
682 | slot = (struct varpool_node **) htab_find_slot (varpool_hash, &key, INSERT); | |
683 | ||
684 | /* If the varpool_node has been already created, fail. */ | |
685 | if (*slot) | |
051f8cc6 | 686 | return NULL; |
2c71ac78 | 687 | |
a9429e29 | 688 | alias_node = ggc_alloc_cleared_varpool_node (); |
2c71ac78 JM |
689 | alias_node->decl = alias; |
690 | alias_node->alias = 1; | |
691 | alias_node->extra_name = decl_node; | |
692 | alias_node->next = decl_node->extra_name; | |
369451ec | 693 | ipa_empty_ref_list (&alias_node->ref_list); |
2942c502 JH |
694 | if (decl_node->extra_name) |
695 | decl_node->extra_name->prev = alias_node; | |
2c71ac78 JM |
696 | decl_node->extra_name = alias_node; |
697 | *slot = alias_node; | |
051f8cc6 JH |
698 | return alias_node; |
699 | } | |
700 | ||
701 | /* Return true when NODE is known to be used from other (non-LTO) object file. | |
702 | Known only when doing LTO via linker plugin. */ | |
703 | ||
704 | bool | |
705 | varpool_used_from_object_file_p (struct varpool_node *node) | |
706 | { | |
707 | struct varpool_node *alias; | |
708 | ||
709 | if (!TREE_PUBLIC (node->decl)) | |
710 | return false; | |
711 | if (resolution_used_from_other_file_p (node->resolution)) | |
712 | return true; | |
713 | for (alias = node->extra_name; alias; alias = alias->next) | |
714 | if (TREE_PUBLIC (alias->decl) | |
715 | && resolution_used_from_other_file_p (alias->resolution)) | |
716 | return true; | |
717 | return false; | |
2c71ac78 JM |
718 | } |
719 | ||
8a4a83ed | 720 | #include "gt-varpool.h" |