]>
Commit | Line | Data |
---|---|---|
e72fcfe8 JH |
1 | /* Callgraph handling code. |
2 | Copyright (C) 2003 Free Software Foundation, Inc. | |
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 2, 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 COPYING. If not, write to the Free | |
19 | Software Foundation, 59 Temple Place - Suite 330, Boston, MA | |
20 | 02111-1307, USA. */ | |
21 | ||
22 | #include "config.h" | |
23 | #include "system.h" | |
24 | #include "coretypes.h" | |
25 | #include "tm.h" | |
26 | #include "tree.h" | |
e72fcfe8 JH |
27 | #include "langhooks.h" |
28 | #include "hashtab.h" | |
29 | #include "toplev.h" | |
30 | #include "flags.h" | |
31 | #include "ggc.h" | |
32 | #include "debug.h" | |
33 | #include "target.h" | |
1c4a429a | 34 | #include "cgraph.h" |
988d1653 | 35 | #include "varray.h" |
e69529cd | 36 | #include "output.h" |
988d1653 | 37 | |
e72fcfe8 JH |
38 | |
39 | /* Hash table used to convert declarations into nodes. */ | |
ed2df68b | 40 | static GTY((param_is (struct cgraph_node))) htab_t cgraph_hash; |
e72fcfe8 JH |
41 | |
42 | /* The linked list of cgraph nodes. */ | |
1c4a429a | 43 | struct cgraph_node *cgraph_nodes; |
e72fcfe8 | 44 | |
1668aabc JH |
45 | /* Queue of cgraph nodes scheduled to be lowered. */ |
46 | struct cgraph_node *cgraph_nodes_queue; | |
47 | ||
e72fcfe8 | 48 | /* Number of nodes in existence. */ |
1c4a429a | 49 | int cgraph_n_nodes; |
e72fcfe8 | 50 | |
b58b1157 JH |
51 | /* Maximal uid used in cgraph nodes. */ |
52 | int cgraph_max_uid; | |
53 | ||
dafc5b82 JH |
54 | /* Set when whole unit has been analyzed so we can access global info. */ |
55 | bool cgraph_global_info_ready = false; | |
56 | ||
e69529cd | 57 | /* Hash table used to convert declarations into nodes. */ |
ed2df68b | 58 | static GTY((param_is (struct cgraph_varpool_node))) htab_t cgraph_varpool_hash; |
e69529cd JH |
59 | |
60 | /* Queue of cgraph nodes scheduled to be lowered and output. */ | |
61 | struct cgraph_varpool_node *cgraph_varpool_nodes_queue; | |
62 | ||
63 | /* Number of nodes in existence. */ | |
64 | int cgraph_varpool_n_nodes; | |
65 | ||
ed2df68b JH |
66 | /* The linked list of cgraph varpool nodes. */ |
67 | static GTY(()) struct cgraph_varpool_node *cgraph_varpool_nodes; | |
68 | ||
439f7bc3 AJ |
69 | static struct cgraph_edge *create_edge (struct cgraph_node *, |
70 | struct cgraph_node *); | |
439f7bc3 AJ |
71 | static hashval_t hash_node (const void *); |
72 | static int eq_node (const void *, const void *); | |
e72fcfe8 JH |
73 | |
74 | /* Returns a hash code for P. */ | |
75 | ||
76 | static hashval_t | |
439f7bc3 | 77 | hash_node (const void *p) |
e72fcfe8 | 78 | { |
ed2df68b JH |
79 | return ((hashval_t) |
80 | IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME | |
81 | (((struct cgraph_node *) p)->decl))); | |
e72fcfe8 JH |
82 | } |
83 | ||
6356f892 | 84 | /* Returns nonzero if P1 and P2 are equal. */ |
e72fcfe8 JH |
85 | |
86 | static int | |
439f7bc3 | 87 | eq_node (const void *p1, const void *p2) |
e72fcfe8 JH |
88 | { |
89 | return ((DECL_ASSEMBLER_NAME (((struct cgraph_node *) p1)->decl)) == | |
1668aabc | 90 | (tree) p2); |
e72fcfe8 JH |
91 | } |
92 | ||
93 | /* Return cgraph node assigned to DECL. Create new one when needed. */ | |
1c4a429a | 94 | struct cgraph_node * |
439f7bc3 | 95 | cgraph_node (tree decl) |
e72fcfe8 JH |
96 | { |
97 | struct cgraph_node *node; | |
98 | struct cgraph_node **slot; | |
99 | ||
988d1653 JH |
100 | if (TREE_CODE (decl) != FUNCTION_DECL) |
101 | abort (); | |
102 | ||
e72fcfe8 | 103 | if (!cgraph_hash) |
ed2df68b | 104 | cgraph_hash = htab_create_ggc (10, hash_node, eq_node, NULL); |
e72fcfe8 | 105 | |
ed2df68b JH |
106 | slot = (struct cgraph_node **) |
107 | htab_find_slot_with_hash (cgraph_hash, DECL_ASSEMBLER_NAME (decl), | |
108 | IDENTIFIER_HASH_VALUE | |
109 | (DECL_ASSEMBLER_NAME (decl)), 1); | |
e72fcfe8 JH |
110 | if (*slot) |
111 | return *slot; | |
ed2df68b | 112 | node = ggc_alloc_cleared (sizeof (*node)); |
e72fcfe8 JH |
113 | node->decl = decl; |
114 | node->next = cgraph_nodes; | |
b58b1157 | 115 | node->uid = cgraph_max_uid++; |
18d13f34 JH |
116 | if (cgraph_nodes) |
117 | cgraph_nodes->previous = node; | |
118 | node->previous = NULL; | |
e72fcfe8 JH |
119 | cgraph_nodes = node; |
120 | cgraph_n_nodes++; | |
121 | *slot = node; | |
5c2e00ee | 122 | if (DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL) |
e72fcfe8 JH |
123 | { |
124 | node->origin = cgraph_node (DECL_CONTEXT (decl)); | |
125 | node->next_nested = node->origin->nested; | |
126 | node->origin->nested = node; | |
127 | } | |
128 | return node; | |
129 | } | |
130 | ||
1668aabc JH |
131 | /* Try to find existing function for identifier ID. */ |
132 | struct cgraph_node * | |
439f7bc3 | 133 | cgraph_node_for_identifier (tree id) |
1668aabc JH |
134 | { |
135 | struct cgraph_node **slot; | |
136 | ||
137 | if (TREE_CODE (id) != IDENTIFIER_NODE) | |
138 | abort (); | |
139 | ||
140 | if (!cgraph_hash) | |
e69529cd | 141 | return NULL; |
1668aabc | 142 | |
ed2df68b JH |
143 | slot = (struct cgraph_node **) |
144 | htab_find_slot_with_hash (cgraph_hash, id, | |
439f7bc3 | 145 | IDENTIFIER_HASH_VALUE (id), 0); |
1668aabc JH |
146 | if (!slot) |
147 | return NULL; | |
148 | return *slot; | |
149 | } | |
150 | ||
e72fcfe8 JH |
151 | /* Create edge from CALLER to CALLEE in the cgraph. */ |
152 | ||
153 | static struct cgraph_edge * | |
439f7bc3 | 154 | create_edge (struct cgraph_node *caller, struct cgraph_node *callee) |
e72fcfe8 | 155 | { |
ed2df68b | 156 | struct cgraph_edge *edge = ggc_alloc (sizeof (struct cgraph_edge)); |
b58b1157 JH |
157 | struct cgraph_edge *edge2; |
158 | ||
159 | edge->inline_call = false; | |
160 | /* At the moment we don't associate calls with specific CALL_EXPRs | |
161 | as we probably ought to, so we must preserve inline_call flags to | |
162 | be the same in all copies of the same edge. */ | |
163 | if (cgraph_global_info_ready) | |
fdacb904 | 164 | for (edge2 = caller->callees; edge2; edge2 = edge2->next_callee) |
b58b1157 JH |
165 | if (edge2->callee == callee) |
166 | { | |
167 | edge->inline_call = edge2->inline_call; | |
168 | break; | |
169 | } | |
e72fcfe8 JH |
170 | |
171 | edge->caller = caller; | |
172 | edge->callee = callee; | |
173 | edge->next_caller = callee->callers; | |
174 | edge->next_callee = caller->callees; | |
175 | caller->callees = edge; | |
176 | callee->callers = edge; | |
177 | return edge; | |
178 | } | |
179 | ||
180 | /* Remove the edge from CALLER to CALLEE in the cgraph. */ | |
181 | ||
cb967da5 | 182 | void |
439f7bc3 | 183 | cgraph_remove_edge (struct cgraph_node *caller, struct cgraph_node *callee) |
e72fcfe8 JH |
184 | { |
185 | struct cgraph_edge **edge, **edge2; | |
186 | ||
187 | for (edge = &callee->callers; *edge && (*edge)->caller != caller; | |
188 | edge = &((*edge)->next_caller)) | |
189 | continue; | |
190 | if (!*edge) | |
191 | abort (); | |
192 | *edge = (*edge)->next_caller; | |
193 | for (edge2 = &caller->callees; *edge2 && (*edge2)->callee != callee; | |
194 | edge2 = &(*edge2)->next_callee) | |
195 | continue; | |
196 | if (!*edge2) | |
197 | abort (); | |
198 | *edge2 = (*edge2)->next_callee; | |
199 | } | |
200 | ||
18d13f34 JH |
201 | /* Remove the node from cgraph. */ |
202 | ||
203 | void | |
439f7bc3 | 204 | cgraph_remove_node (struct cgraph_node *node) |
18d13f34 | 205 | { |
2ee1067b | 206 | void **slot; |
18d13f34 JH |
207 | while (node->callers) |
208 | cgraph_remove_edge (node->callers->caller, node); | |
209 | while (node->callees) | |
210 | cgraph_remove_edge (node, node->callees->callee); | |
211 | while (node->nested) | |
212 | cgraph_remove_node (node->nested); | |
213 | if (node->origin) | |
214 | { | |
215 | struct cgraph_node **node2 = &node->origin->nested; | |
216 | ||
217 | while (*node2 != node) | |
218 | node2 = &(*node2)->next_nested; | |
219 | *node2 = node->next_nested; | |
220 | } | |
221 | if (node->previous) | |
222 | node->previous->next = node->next; | |
223 | else | |
224 | cgraph_nodes = node; | |
225 | if (node->next) | |
226 | node->next->previous = node->previous; | |
227 | DECL_SAVED_TREE (node->decl) = NULL; | |
2ee1067b JH |
228 | slot = |
229 | htab_find_slot_with_hash (cgraph_hash, DECL_ASSEMBLER_NAME (node->decl), | |
230 | IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME | |
231 | (node->decl)), 1); | |
232 | htab_clear_slot (cgraph_hash, slot); | |
18d13f34 JH |
233 | /* Do not free the structure itself so the walk over chain can continue. */ |
234 | } | |
235 | ||
8dafba3c RH |
236 | /* Notify finalize_compilation_unit that given node is reachable. */ |
237 | ||
1668aabc | 238 | void |
8dafba3c | 239 | cgraph_mark_reachable_node (struct cgraph_node *node) |
1668aabc | 240 | { |
ba245151 | 241 | if (!node->reachable && node->local.finalized) |
1668aabc | 242 | { |
ba245151 | 243 | notice_global_symbol (node->decl); |
1668aabc | 244 | node->reachable = 1; |
e767b5be JH |
245 | |
246 | node->next_needed = cgraph_nodes_queue; | |
247 | cgraph_nodes_queue = node; | |
248 | ||
249 | /* At the moment frontend automatically emits all nested functions. */ | |
250 | if (node->nested) | |
1668aabc | 251 | { |
e767b5be JH |
252 | struct cgraph_node *node2; |
253 | ||
254 | for (node2 = node->nested; node2; node2 = node2->next_nested) | |
255 | if (!node2->reachable) | |
8dafba3c | 256 | cgraph_mark_reachable_node (node2); |
e767b5be | 257 | } |
1668aabc JH |
258 | } |
259 | } | |
260 | ||
8dafba3c RH |
261 | /* Likewise indicate that a node is needed, i.e. reachable via some |
262 | external means. */ | |
263 | ||
264 | void | |
265 | cgraph_mark_needed_node (struct cgraph_node *node) | |
266 | { | |
267 | node->needed = 1; | |
268 | cgraph_mark_reachable_node (node); | |
269 | } | |
18d13f34 | 270 | |
e72fcfe8 JH |
271 | /* Record call from CALLER to CALLEE */ |
272 | ||
1c4a429a | 273 | struct cgraph_edge * |
439f7bc3 | 274 | cgraph_record_call (tree caller, tree callee) |
e72fcfe8 JH |
275 | { |
276 | return create_edge (cgraph_node (caller), cgraph_node (callee)); | |
277 | } | |
278 | ||
279 | void | |
439f7bc3 | 280 | cgraph_remove_call (tree caller, tree callee) |
e72fcfe8 | 281 | { |
18d13f34 | 282 | cgraph_remove_edge (cgraph_node (caller), cgraph_node (callee)); |
e72fcfe8 JH |
283 | } |
284 | ||
285 | /* Return true when CALLER_DECL calls CALLEE_DECL. */ | |
286 | ||
287 | bool | |
439f7bc3 | 288 | cgraph_calls_p (tree caller_decl, tree callee_decl) |
e72fcfe8 JH |
289 | { |
290 | struct cgraph_node *caller = cgraph_node (caller_decl); | |
291 | struct cgraph_node *callee = cgraph_node (callee_decl); | |
292 | struct cgraph_edge *edge; | |
293 | ||
294 | for (edge = callee->callers; edge && (edge)->caller != caller; | |
295 | edge = (edge->next_caller)) | |
296 | continue; | |
297 | return edge != NULL; | |
298 | } | |
299 | ||
dafc5b82 JH |
300 | /* Return local info for the compiled function. */ |
301 | ||
302 | struct cgraph_local_info * | |
439f7bc3 | 303 | cgraph_local_info (tree decl) |
dafc5b82 JH |
304 | { |
305 | struct cgraph_node *node; | |
306 | if (TREE_CODE (decl) != FUNCTION_DECL) | |
307 | abort (); | |
308 | node = cgraph_node (decl); | |
309 | return &node->local; | |
310 | } | |
311 | ||
312 | /* Return local info for the compiled function. */ | |
313 | ||
314 | struct cgraph_global_info * | |
439f7bc3 | 315 | cgraph_global_info (tree decl) |
dafc5b82 JH |
316 | { |
317 | struct cgraph_node *node; | |
318 | if (TREE_CODE (decl) != FUNCTION_DECL || !cgraph_global_info_ready) | |
319 | abort (); | |
320 | node = cgraph_node (decl); | |
321 | return &node->global; | |
322 | } | |
323 | ||
b255a036 JH |
324 | /* Return local info for the compiled function. */ |
325 | ||
326 | struct cgraph_rtl_info * | |
439f7bc3 | 327 | cgraph_rtl_info (tree decl) |
b255a036 JH |
328 | { |
329 | struct cgraph_node *node; | |
330 | if (TREE_CODE (decl) != FUNCTION_DECL) | |
331 | abort (); | |
332 | node = cgraph_node (decl); | |
333 | if (decl != current_function_decl | |
334 | && !TREE_ASM_WRITTEN (node->decl)) | |
335 | return NULL; | |
336 | return &node->rtl; | |
337 | } | |
338 | ||
a194aa56 JH |
339 | /* Return name of the node used in debug output. */ |
340 | const char * | |
439f7bc3 | 341 | cgraph_node_name (struct cgraph_node *node) |
a194aa56 JH |
342 | { |
343 | return (*lang_hooks.decl_printable_name) (node->decl, 2); | |
344 | } | |
dafc5b82 | 345 | |
e72fcfe8 JH |
346 | /* Dump the callgraph. */ |
347 | ||
348 | void | |
439f7bc3 | 349 | dump_cgraph (FILE *f) |
e72fcfe8 JH |
350 | { |
351 | struct cgraph_node *node; | |
352 | ||
353 | fprintf (f, "\nCallgraph:\n\n"); | |
354 | for (node = cgraph_nodes; node; node = node->next) | |
355 | { | |
356 | struct cgraph_edge *edge; | |
a194aa56 | 357 | fprintf (f, "%s", cgraph_node_name (node)); |
b58b1157 JH |
358 | if (node->local.self_insns) |
359 | fprintf (f, " %i insns", node->local.self_insns); | |
e72fcfe8 | 360 | if (node->origin) |
a194aa56 | 361 | fprintf (f, " nested in: %s", cgraph_node_name (node->origin)); |
e72fcfe8 JH |
362 | if (node->needed) |
363 | fprintf (f, " needed"); | |
364 | else if (node->reachable) | |
365 | fprintf (f, " reachable"); | |
366 | if (DECL_SAVED_TREE (node->decl)) | |
367 | fprintf (f, " tree"); | |
368 | ||
b3c3af2f | 369 | if (node->local.disregard_inline_limits) |
b58b1157 JH |
370 | fprintf (f, " always_inline"); |
371 | else if (node->local.inlinable) | |
372 | fprintf (f, " inlinable"); | |
373 | if (node->global.insns && node->global.insns != node->local.self_insns) | |
374 | fprintf (f, " %i insns after inlining", node->global.insns); | |
375 | if (node->global.cloned_times > 1) | |
376 | fprintf (f, " cloned %ix", node->global.cloned_times); | |
b58b1157 | 377 | |
7dd87381 | 378 | fprintf (f, "\n called by: "); |
e72fcfe8 | 379 | for (edge = node->callers; edge; edge = edge->next_caller) |
b58b1157 JH |
380 | { |
381 | fprintf (f, "%s ", cgraph_node_name (edge->caller)); | |
382 | if (edge->inline_call) | |
383 | fprintf(f, "(inlined) "); | |
384 | } | |
e72fcfe8 JH |
385 | |
386 | fprintf (f, "\n calls: "); | |
387 | for (edge = node->callees; edge; edge = edge->next_callee) | |
b58b1157 JH |
388 | { |
389 | fprintf (f, "%s ", cgraph_node_name (edge->callee)); | |
390 | if (edge->inline_call) | |
391 | fprintf(f, "(inlined) "); | |
392 | } | |
e72fcfe8 JH |
393 | fprintf (f, "\n"); |
394 | } | |
395 | } | |
988d1653 | 396 | |
e69529cd JH |
397 | /* Returns a hash code for P. */ |
398 | ||
399 | static hashval_t | |
439f7bc3 | 400 | cgraph_varpool_hash_node (const void *p) |
e69529cd | 401 | { |
ed2df68b JH |
402 | return ((hashval_t) |
403 | IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME | |
404 | (((struct cgraph_varpool_node *) p)->decl))); | |
e69529cd JH |
405 | } |
406 | ||
f1ba665b | 407 | /* Returns nonzero if P1 and P2 are equal. */ |
e69529cd JH |
408 | |
409 | static int | |
439f7bc3 | 410 | eq_cgraph_varpool_node (const void *p1, const void *p2) |
e69529cd JH |
411 | { |
412 | return ((DECL_ASSEMBLER_NAME (((struct cgraph_varpool_node *) p1)->decl)) == | |
413 | (tree) p2); | |
414 | } | |
415 | ||
416 | /* Return cgraph_varpool node assigned to DECL. Create new one when needed. */ | |
417 | struct cgraph_varpool_node * | |
418 | cgraph_varpool_node (tree decl) | |
419 | { | |
420 | struct cgraph_varpool_node *node; | |
421 | struct cgraph_varpool_node **slot; | |
422 | ||
423 | if (!DECL_P (decl) || TREE_CODE (decl) == FUNCTION_DECL) | |
424 | abort (); | |
425 | ||
426 | if (!cgraph_varpool_hash) | |
ed2df68b JH |
427 | cgraph_varpool_hash = htab_create_ggc (10, cgraph_varpool_hash_node, |
428 | eq_cgraph_varpool_node, NULL); | |
429 | ||
e69529cd | 430 | |
ed2df68b JH |
431 | slot = (struct cgraph_varpool_node **) |
432 | htab_find_slot_with_hash (cgraph_varpool_hash, DECL_ASSEMBLER_NAME (decl), | |
433 | IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME (decl)), | |
434 | 1); | |
e69529cd JH |
435 | if (*slot) |
436 | return *slot; | |
ed2df68b | 437 | node = ggc_alloc_cleared (sizeof (*node)); |
e69529cd JH |
438 | node->decl = decl; |
439 | cgraph_varpool_n_nodes++; | |
ed2df68b | 440 | cgraph_varpool_nodes = node; |
e69529cd | 441 | *slot = node; |
e69529cd JH |
442 | return node; |
443 | } | |
444 | ||
445 | /* Try to find existing function for identifier ID. */ | |
446 | struct cgraph_varpool_node * | |
447 | cgraph_varpool_node_for_identifier (tree id) | |
448 | { | |
449 | struct cgraph_varpool_node **slot; | |
450 | ||
451 | if (TREE_CODE (id) != IDENTIFIER_NODE) | |
452 | abort (); | |
453 | ||
454 | if (!cgraph_varpool_hash) | |
455 | return NULL; | |
456 | ||
ed2df68b JH |
457 | slot = (struct cgraph_varpool_node **) |
458 | htab_find_slot_with_hash (cgraph_varpool_hash, id, | |
459 | IDENTIFIER_HASH_VALUE (id), 0); | |
e69529cd JH |
460 | if (!slot) |
461 | return NULL; | |
462 | return *slot; | |
463 | } | |
464 | ||
465 | /* Notify finalize_compilation_unit that given node is reachable | |
466 | or needed. */ | |
467 | void | |
468 | cgraph_varpool_mark_needed_node (struct cgraph_varpool_node *node) | |
469 | { | |
470 | if (!node->needed && node->finalized) | |
471 | { | |
8bd87c4e | 472 | node->next_needed = cgraph_varpool_nodes_queue; |
e69529cd | 473 | cgraph_varpool_nodes_queue = node; |
810db579 | 474 | notice_global_symbol (node->decl); |
e69529cd JH |
475 | } |
476 | node->needed = 1; | |
477 | } | |
478 | ||
479 | void | |
480 | cgraph_varpool_finalize_decl (tree decl) | |
481 | { | |
482 | struct cgraph_varpool_node *node = cgraph_varpool_node (decl); | |
d853a20e JH |
483 | |
484 | /* The first declaration of a variable that comes through this function | |
485 | decides whether it is global (in C, has external linkage) | |
486 | or local (in C, has internal linkage). So do nothing more | |
487 | if this function has already run. */ | |
488 | if (node->finalized) | |
489 | return; | |
490 | if (node->needed) | |
e69529cd | 491 | { |
8bd87c4e | 492 | node->next_needed = cgraph_varpool_nodes_queue; |
e69529cd | 493 | cgraph_varpool_nodes_queue = node; |
ba245151 | 494 | notice_global_symbol (decl); |
e69529cd JH |
495 | } |
496 | node->finalized = true; | |
497 | ||
498 | if (/* Externally visible variables must be output. The exception are | |
499 | COMDAT functions that must be output only when they are needed. */ | |
500 | (TREE_PUBLIC (decl) && !DECL_COMDAT (decl)) | |
501 | /* Function whose name is output to the assembler file must be produced. | |
502 | It is possible to assemble the name later after finalizing the function | |
503 | and the fact is noticed in assemble_name then. */ | |
504 | || (DECL_ASSEMBLER_NAME_SET_P (decl) | |
505 | && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))) | |
506 | { | |
507 | cgraph_varpool_mark_needed_node (node); | |
508 | } | |
509 | } | |
510 | ||
511 | bool | |
439f7bc3 | 512 | cgraph_varpool_assemble_pending_decls (void) |
e69529cd JH |
513 | { |
514 | bool changed = false; | |
515 | ||
516 | while (cgraph_varpool_nodes_queue) | |
517 | { | |
518 | tree decl = cgraph_varpool_nodes_queue->decl; | |
519 | struct cgraph_varpool_node *node = cgraph_varpool_nodes_queue; | |
520 | ||
8bd87c4e | 521 | cgraph_varpool_nodes_queue = cgraph_varpool_nodes_queue->next_needed; |
e69529cd JH |
522 | if (!TREE_ASM_WRITTEN (decl)) |
523 | { | |
524 | assemble_variable (decl, 0, 1, 0); | |
525 | changed = true; | |
526 | } | |
8bd87c4e | 527 | node->next_needed = NULL; |
e69529cd JH |
528 | } |
529 | return changed; | |
530 | } | |
531 | ||
532 | ||
988d1653 | 533 | #include "gt-cgraph.h" |