Mercurial > hg > CbC > CbC_gcc
annotate gcc/varpool.c @ 55:77e2b8dfacca gcc-4.4.5
update it from 4.4.3 to 4.5.0
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:39:51 +0900 |
parents | a06113de4d67 |
children | b7f97abdc517 |
rev | line source |
---|---|
0 | 1 /* Callgraph handling code. |
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 | |
3 Free Software Foundation, Inc. | |
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 | |
10 Software Foundation; either version 3, or (at your option) any later | |
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 | |
19 along with GCC; see the file COPYING3. If not see | |
20 <http://www.gnu.org/licenses/>. */ | |
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" | |
29 #include "diagnostic.h" | |
30 #include "hashtab.h" | |
31 #include "ggc.h" | |
32 #include "timevar.h" | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
33 #include "debug.h" |
0 | 34 #include "target.h" |
35 #include "output.h" | |
36 #include "gimple.h" | |
37 #include "tree-flow.h" | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
38 #include "flags.h" |
0 | 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 | |
46 The varpool nodes are allocated lazily for declarations | |
47 either by frontend or at callgraph construction time. | |
48 All variables supposed to be output into final file needs to be | |
49 explicitly marked by frontend via VARPOOL_FINALIZE_DECL function. */ | |
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 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
60 pointer. |
0 | 61 |
62 LAST_NEEDED_NODE points to the end of queue, so it can be | |
63 maintained in forward order. GTY is needed to make it friendly to | |
64 PCH. | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
65 |
0 | 66 During compilation we construct the queue of needed variables |
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. | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
70 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
71 Each variable is thus first analyzed and then later possibly output. |
0 | 72 FIRST_UNANALYZED_NODE points to first node in queue that was not analyzed |
73 yet and is moved via VARPOOL_ANALYZE_PENDING_DECLS. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
74 |
0 | 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. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
83 const char * |
0 | 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 | |
108 /* Return varpool node assigned to DECL. Create new one when needed. */ | |
109 struct varpool_node * | |
110 varpool_node (tree decl) | |
111 { | |
112 struct varpool_node key, *node, **slot; | |
113 | |
114 gcc_assert (DECL_P (decl) && TREE_CODE (decl) != FUNCTION_DECL); | |
115 | |
116 if (!varpool_hash) | |
117 varpool_hash = htab_create_ggc (10, hash_varpool_node, | |
118 eq_varpool_node, NULL); | |
119 key.decl = decl; | |
120 slot = (struct varpool_node **) | |
121 htab_find_slot (varpool_hash, &key, INSERT); | |
122 if (*slot) | |
123 return *slot; | |
124 node = GGC_CNEW (struct varpool_node); | |
125 node->decl = decl; | |
126 node->order = cgraph_order++; | |
127 node->next = varpool_nodes; | |
128 varpool_nodes = node; | |
129 *slot = node; | |
130 return node; | |
131 } | |
132 | |
133 /* Dump given cgraph node. */ | |
134 void | |
135 dump_varpool_node (FILE *f, struct varpool_node *node) | |
136 { | |
137 fprintf (f, "%s:", varpool_node_name (node)); | |
138 fprintf (f, " availability:%s", | |
139 cgraph_function_flags_ready | |
140 ? cgraph_availability_names[cgraph_variable_initializer_availability (node)] | |
141 : "not-ready"); | |
142 if (DECL_INITIAL (node->decl)) | |
143 fprintf (f, " initialized"); | |
144 if (node->needed) | |
145 fprintf (f, " needed"); | |
146 if (node->analyzed) | |
147 fprintf (f, " analyzed"); | |
148 if (node->finalized) | |
149 fprintf (f, " finalized"); | |
150 if (node->output) | |
151 fprintf (f, " output"); | |
152 if (node->externally_visible) | |
153 fprintf (f, " externally_visible"); | |
154 fprintf (f, "\n"); | |
155 } | |
156 | |
157 /* Dump the variable pool. */ | |
158 void | |
159 dump_varpool (FILE *f) | |
160 { | |
161 struct varpool_node *node; | |
162 | |
163 fprintf (f, "variable pool:\n\n"); | |
164 for (node = varpool_nodes; node; node = node->next) | |
165 dump_varpool_node (f, node); | |
166 } | |
167 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
168 /* Dump the variable pool to stderr. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
169 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
170 void |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
171 debug_varpool (void) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
172 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
173 dump_varpool (stderr); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
174 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
175 |
0 | 176 /* Given an assembler name, lookup node. */ |
177 struct varpool_node * | |
178 varpool_node_for_asm (tree asmname) | |
179 { | |
180 struct varpool_node *node; | |
181 | |
182 for (node = varpool_nodes; node ; node = node->next) | |
183 if (decl_assembler_name_equal (node->decl, asmname)) | |
184 return node; | |
185 | |
186 return NULL; | |
187 } | |
188 | |
189 /* Helper function for finalization code - add node into lists so it will | |
190 be analyzed and compiled. */ | |
191 static void | |
192 varpool_enqueue_needed_node (struct varpool_node *node) | |
193 { | |
194 if (varpool_last_needed_node) | |
195 varpool_last_needed_node->next_needed = node; | |
196 varpool_last_needed_node = node; | |
197 node->next_needed = NULL; | |
198 if (!varpool_nodes_queue) | |
199 varpool_nodes_queue = node; | |
200 if (!varpool_first_unanalyzed_node) | |
201 varpool_first_unanalyzed_node = node; | |
202 notice_global_symbol (node->decl); | |
203 } | |
204 | |
205 /* Notify finalize_compilation_unit that given node is reachable | |
206 or needed. */ | |
207 void | |
208 varpool_mark_needed_node (struct varpool_node *node) | |
209 { | |
210 if (!node->needed && node->finalized | |
211 && !TREE_ASM_WRITTEN (node->decl)) | |
212 varpool_enqueue_needed_node (node); | |
213 node->needed = 1; | |
214 } | |
215 | |
216 /* Reset the queue of needed nodes. */ | |
217 static void | |
218 varpool_reset_queue (void) | |
219 { | |
220 varpool_last_needed_node = NULL; | |
221 varpool_nodes_queue = NULL; | |
222 varpool_first_unanalyzed_node = NULL; | |
223 } | |
224 | |
225 /* Determine if variable DECL is needed. That is, visible to something | |
226 either outside this translation unit, something magic in the system | |
227 configury */ | |
228 bool | |
229 decide_is_variable_needed (struct varpool_node *node, tree decl) | |
230 { | |
231 /* If the user told us it is used, then it must be so. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
232 if ((node->externally_visible && !DECL_COMDAT (decl)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
233 || node->force_output) |
0 | 234 return true; |
235 | |
236 /* ??? If the assembler name is set by hand, it is possible to assemble | |
237 the name later after finalizing the function and the fact is noticed | |
238 in assemble_name then. This is arguably a bug. */ | |
239 if (DECL_ASSEMBLER_NAME_SET_P (decl) | |
240 && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) | |
241 return true; | |
242 | |
243 /* Externally visible variables must be output. The exception is | |
244 COMDAT variables that must be output only when they are needed. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
245 if (TREE_PUBLIC (decl) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
246 && !flag_whole_program |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
247 && !flag_lto |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
248 && !flag_whopr |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
249 && !DECL_COMDAT (decl) |
0 | 250 && !DECL_EXTERNAL (decl)) |
251 return true; | |
252 | |
253 /* When emulating tls, we actually see references to the control | |
254 variable, rather than the user-level variable. */ | |
255 if (!targetm.have_tls | |
256 && TREE_CODE (decl) == VAR_DECL | |
257 && DECL_THREAD_LOCAL_P (decl)) | |
258 { | |
259 tree control = emutls_decl (decl); | |
260 if (decide_is_variable_needed (varpool_node (control), control)) | |
261 return true; | |
262 } | |
263 | |
264 /* When not reordering top level variables, we have to assume that | |
265 we are going to keep everything. */ | |
266 if (flag_toplevel_reorder) | |
267 return false; | |
268 | |
269 /* We want to emit COMDAT variables only when absolutely necessary. */ | |
270 if (DECL_COMDAT (decl)) | |
271 return false; | |
272 return true; | |
273 } | |
274 | |
275 /* Mark DECL as finalized. By finalizing the declaration, frontend instruct the | |
276 middle end to output the variable to asm file, if needed or externally | |
277 visible. */ | |
278 void | |
279 varpool_finalize_decl (tree decl) | |
280 { | |
281 struct varpool_node *node = varpool_node (decl); | |
282 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
283 /* FIXME: We don't really stream varpool datastructure and instead rebuild it |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
284 by varpool_finalize_decl. This is not quite correct since this way we can't |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
285 attach any info to varpool. Eventually we will want to stream varpool nodes |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
286 and the flags. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
287 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
288 For the moment just prevent analysis of varpool nodes to happen again, so |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
289 we will re-try to compute "address_taken" flag of varpool that breaks |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
290 in presence of clones. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
291 if (in_lto_p) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
292 node->analyzed = true; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
293 |
0 | 294 /* The first declaration of a variable that comes through this function |
295 decides whether it is global (in C, has external linkage) | |
296 or local (in C, has internal linkage). So do nothing more | |
297 if this function has already run. */ | |
298 if (node->finalized) | |
299 { | |
300 if (cgraph_global_info_ready) | |
301 varpool_assemble_pending_decls (); | |
302 return; | |
303 } | |
304 if (node->needed) | |
305 varpool_enqueue_needed_node (node); | |
306 node->finalized = true; | |
307 | |
308 if (decide_is_variable_needed (node, decl)) | |
309 varpool_mark_needed_node (node); | |
310 /* Since we reclaim unreachable nodes at the end of every language | |
311 level unit, we need to be conservative about possible entry points | |
312 there. */ | |
313 else if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl)) | |
314 varpool_mark_needed_node (node); | |
315 if (cgraph_global_info_ready) | |
316 varpool_assemble_pending_decls (); | |
317 } | |
318 | |
319 /* Return variable availability. See cgraph.h for description of individual | |
320 return values. */ | |
321 enum availability | |
322 cgraph_variable_initializer_availability (struct varpool_node *node) | |
323 { | |
324 gcc_assert (cgraph_function_flags_ready); | |
325 if (!node->finalized) | |
326 return AVAIL_NOT_AVAILABLE; | |
327 if (!TREE_PUBLIC (node->decl)) | |
328 return AVAIL_AVAILABLE; | |
329 /* If the variable can be overwritten, return OVERWRITABLE. Takes | |
330 care of at least two notable extensions - the COMDAT variables | |
331 used to share template instantiations in C++. */ | |
332 if (!(*targetm.binds_local_p) (node->decl) && !DECL_COMDAT (node->decl)) | |
333 return AVAIL_OVERWRITABLE; | |
334 return AVAIL_AVAILABLE; | |
335 } | |
336 | |
337 /* Walk the decls we marked as necessary and see if they reference new | |
338 variables or functions and add them into the worklists. */ | |
339 bool | |
340 varpool_analyze_pending_decls (void) | |
341 { | |
342 bool changed = false; | |
343 timevar_push (TV_CGRAPH); | |
344 | |
345 while (varpool_first_unanalyzed_node) | |
346 { | |
347 tree decl = varpool_first_unanalyzed_node->decl; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
348 bool analyzed = varpool_first_unanalyzed_node->analyzed; |
0 | 349 |
350 varpool_first_unanalyzed_node->analyzed = true; | |
351 | |
352 varpool_first_unanalyzed_node = varpool_first_unanalyzed_node->next_needed; | |
353 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
354 /* When reading back varpool at LTO time, we re-construct the queue in order |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
355 to have "needed" list right by inserting all needed nodes into varpool. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
356 We however don't want to re-analyze already analyzed nodes. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
357 if (!analyzed) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
358 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
359 gcc_assert (!in_lto_p); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
360 /* Compute the alignment early so function body expanders are |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
361 already informed about increased alignment. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
362 align_variable (decl, 0); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
363 } |
0 | 364 if (DECL_INITIAL (decl)) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
365 record_references_in_initializer (decl, analyzed); |
0 | 366 changed = true; |
367 } | |
368 timevar_pop (TV_CGRAPH); | |
369 return changed; | |
370 } | |
371 | |
372 /* Output one variable, if necessary. Return whether we output it. */ | |
373 bool | |
374 varpool_assemble_decl (struct varpool_node *node) | |
375 { | |
376 tree decl = node->decl; | |
377 | |
378 if (!TREE_ASM_WRITTEN (decl) | |
379 && !node->alias | |
380 && !DECL_EXTERNAL (decl) | |
381 && (TREE_CODE (decl) != VAR_DECL || !DECL_HAS_VALUE_EXPR_P (decl))) | |
382 { | |
383 assemble_variable (decl, 0, 1, 0); | |
384 if (TREE_ASM_WRITTEN (decl)) | |
385 { | |
386 node->next_needed = varpool_assembled_nodes_queue; | |
387 varpool_assembled_nodes_queue = node; | |
388 node->finalized = 1; | |
389 return true; | |
390 } | |
391 } | |
392 | |
393 return false; | |
394 } | |
395 | |
396 /* Optimization of function bodies might've rendered some variables as | |
397 unnecessary so we want to avoid these from being compiled. | |
398 | |
399 This is done by pruning the queue and keeping only the variables that | |
400 really appear needed (ie they are either externally visible or referenced | |
401 by compiled function). Re-doing the reachability analysis on variables | |
402 brings back the remaining variables referenced by these. */ | |
403 void | |
404 varpool_remove_unreferenced_decls (void) | |
405 { | |
406 struct varpool_node *next, *node = varpool_nodes_queue; | |
407 | |
408 varpool_reset_queue (); | |
409 | |
410 if (errorcount || sorrycount) | |
411 return; | |
412 | |
413 while (node) | |
414 { | |
415 tree decl = node->decl; | |
416 next = node->next_needed; | |
417 node->needed = 0; | |
418 | |
419 if (node->finalized | |
420 && (decide_is_variable_needed (node, decl) | |
421 /* ??? Cgraph does not yet rule the world with an iron hand, | |
422 and does not control the emission of debug information. | |
423 After a variable has its DECL_RTL set, we must assume that | |
424 it may be referenced by the debug information, and we can | |
425 no longer elide it. */ | |
426 || DECL_RTL_SET_P (decl))) | |
427 varpool_mark_needed_node (node); | |
428 | |
429 node = next; | |
430 } | |
431 /* Make sure we mark alias targets as used targets. */ | |
432 finish_aliases_1 (); | |
433 varpool_analyze_pending_decls (); | |
434 } | |
435 | |
436 /* Output all variables enqueued to be assembled. */ | |
437 bool | |
438 varpool_assemble_pending_decls (void) | |
439 { | |
440 bool changed = false; | |
441 | |
442 if (errorcount || sorrycount) | |
443 return false; | |
444 | |
445 /* EH might mark decls as needed during expansion. This should be safe since | |
446 we don't create references to new function, but it should not be used | |
447 elsewhere. */ | |
448 varpool_analyze_pending_decls (); | |
449 | |
450 while (varpool_nodes_queue) | |
451 { | |
452 struct varpool_node *node = varpool_nodes_queue; | |
453 | |
454 varpool_nodes_queue = varpool_nodes_queue->next_needed; | |
455 if (varpool_assemble_decl (node)) | |
456 changed = true; | |
457 else | |
458 node->next_needed = NULL; | |
459 } | |
460 /* varpool_nodes_queue is now empty, clear the pointer to the last element | |
461 in the queue. */ | |
462 varpool_last_needed_node = NULL; | |
463 return changed; | |
464 } | |
465 | |
466 /* Remove all elements from the queue so we can re-use it for debug output. */ | |
467 void | |
468 varpool_empty_needed_queue (void) | |
469 { | |
470 /* EH might mark decls as needed during expansion. This should be safe since | |
471 we don't create references to new function, but it should not be used | |
472 elsewhere. */ | |
473 varpool_analyze_pending_decls (); | |
474 | |
475 while (varpool_nodes_queue) | |
476 { | |
477 struct varpool_node *node = varpool_nodes_queue; | |
478 varpool_nodes_queue = varpool_nodes_queue->next_needed; | |
479 node->next_needed = NULL; | |
480 } | |
481 /* varpool_nodes_queue is now empty, clear the pointer to the last element | |
482 in the queue. */ | |
483 varpool_last_needed_node = NULL; | |
484 } | |
485 | |
486 /* Create a new global variable of type TYPE. */ | |
487 tree | |
488 add_new_static_var (tree type) | |
489 { | |
490 tree new_decl; | |
491 struct varpool_node *new_node; | |
492 | |
493 new_decl = create_tmp_var (type, NULL); | |
494 DECL_NAME (new_decl) = create_tmp_var_name (NULL); | |
495 TREE_READONLY (new_decl) = 0; | |
496 TREE_STATIC (new_decl) = 1; | |
497 TREE_USED (new_decl) = 1; | |
498 DECL_CONTEXT (new_decl) = NULL_TREE; | |
499 DECL_ABSTRACT (new_decl) = 0; | |
500 lang_hooks.dup_lang_specific_decl (new_decl); | |
501 create_var_ann (new_decl); | |
502 new_node = varpool_node (new_decl); | |
503 varpool_mark_needed_node (new_node); | |
504 add_referenced_var (new_decl); | |
505 varpool_finalize_decl (new_decl); | |
506 | |
507 return new_node->decl; | |
508 } | |
509 | |
510 #include "gt-varpool.h" |