comparison gcc/varpool.c @ 63:b7f97abdc517 gcc-4.6-20100522

update gcc from gcc-4.5.0 to gcc-4.6
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Mon, 24 May 2010 12:47:05 +0900
parents 77e2b8dfacca
children f6334be47118
comparison
equal deleted inserted replaced
56:3c8a44c06a95 63:b7f97abdc517
1 /* Callgraph handling code. 1 /* Callgraph handling code.
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2010
3 Free Software Foundation, Inc. 3 Free Software Foundation, Inc.
4 Contributed by Jan Hubicka 4 Contributed by Jan Hubicka
5 5
6 This file is part of GCC. 6 This file is part of GCC.
7 7
103 const struct varpool_node *n2 = 103 const struct varpool_node *n2 =
104 (const struct varpool_node *) p2; 104 (const struct varpool_node *) p2;
105 return DECL_UID (n1->decl) == DECL_UID (n2->decl); 105 return DECL_UID (n1->decl) == DECL_UID (n2->decl);
106 } 106 }
107 107
108 /* Return varpool node assigned to DECL without creating new one. */
109 struct varpool_node *
110 varpool_get_node (tree decl)
111 {
112 struct varpool_node key, **slot;
113
114 gcc_assert (DECL_P (decl) && TREE_CODE (decl) != FUNCTION_DECL);
115
116 if (!varpool_hash)
117 return NULL;
118 key.decl = decl;
119 slot = (struct varpool_node **)
120 htab_find_slot (varpool_hash, &key, INSERT);
121 return *slot;
122 }
123
108 /* Return varpool node assigned to DECL. Create new one when needed. */ 124 /* Return varpool node assigned to DECL. Create new one when needed. */
109 struct varpool_node * 125 struct varpool_node *
110 varpool_node (tree decl) 126 varpool_node (tree decl)
111 { 127 {
112 struct varpool_node key, *node, **slot; 128 struct varpool_node key, *node, **slot;
123 return *slot; 139 return *slot;
124 node = GGC_CNEW (struct varpool_node); 140 node = GGC_CNEW (struct varpool_node);
125 node->decl = decl; 141 node->decl = decl;
126 node->order = cgraph_order++; 142 node->order = cgraph_order++;
127 node->next = varpool_nodes; 143 node->next = varpool_nodes;
144 ipa_empty_ref_list (&node->ref_list);
145 if (varpool_nodes)
146 varpool_nodes->prev = node;
128 varpool_nodes = node; 147 varpool_nodes = node;
129 *slot = node; 148 *slot = node;
130 return node; 149 return node;
150 }
151
152 /* Remove node from the varpool. */
153 void
154 varpool_remove_node (struct varpool_node *node)
155 {
156 void **slot;
157 slot = htab_find_slot (varpool_hash, node, NO_INSERT);
158 gcc_assert (*slot == node);
159 htab_clear_slot (varpool_hash, slot);
160 gcc_assert (!varpool_assembled_nodes_queue);
161 if (!node->alias)
162 while (node->extra_name)
163 varpool_remove_node (node->extra_name);
164 if (node->next)
165 node->next->prev = node->prev;
166 if (node->prev)
167 node->prev->next = node->next;
168 else
169 {
170 if (node->alias && node->extra_name)
171 {
172 gcc_assert (node->extra_name->extra_name == node);
173 node->extra_name->extra_name = node->next;
174 }
175 else
176 {
177 gcc_assert (varpool_nodes == node);
178 varpool_nodes = node->next;
179 }
180 }
181 if (varpool_first_unanalyzed_node == node)
182 varpool_first_unanalyzed_node = node->next_needed;
183 if (node->next_needed)
184 node->next_needed->prev_needed = node->prev_needed;
185 else if (node->prev_needed)
186 {
187 gcc_assert (varpool_last_needed_node);
188 varpool_last_needed_node = node->prev_needed;
189 }
190 if (node->prev_needed)
191 node->prev_needed->next_needed = node->next_needed;
192 else if (node->next_needed)
193 {
194 gcc_assert (varpool_nodes_queue == node);
195 varpool_nodes_queue = node->next_needed;
196 }
197 if (node->same_comdat_group)
198 {
199 struct varpool_node *prev;
200 for (prev = node->same_comdat_group;
201 prev->same_comdat_group != node;
202 prev = prev->same_comdat_group)
203 ;
204 if (node->same_comdat_group == prev)
205 prev->same_comdat_group = NULL;
206 else
207 prev->same_comdat_group = node->same_comdat_group;
208 node->same_comdat_group = NULL;
209 }
210 ipa_remove_all_references (&node->ref_list);
211 ipa_remove_all_refering (&node->ref_list);
212 ggc_free (node);
131 } 213 }
132 214
133 /* Dump given cgraph node. */ 215 /* Dump given cgraph node. */
134 void 216 void
135 dump_varpool_node (FILE *f, struct varpool_node *node) 217 dump_varpool_node (FILE *f, struct varpool_node *node)
137 fprintf (f, "%s:", varpool_node_name (node)); 219 fprintf (f, "%s:", varpool_node_name (node));
138 fprintf (f, " availability:%s", 220 fprintf (f, " availability:%s",
139 cgraph_function_flags_ready 221 cgraph_function_flags_ready
140 ? cgraph_availability_names[cgraph_variable_initializer_availability (node)] 222 ? cgraph_availability_names[cgraph_variable_initializer_availability (node)]
141 : "not-ready"); 223 : "not-ready");
224 if (DECL_ASSEMBLER_NAME_SET_P (node->decl))
225 fprintf (f, " (asm: %s)", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->decl)));
142 if (DECL_INITIAL (node->decl)) 226 if (DECL_INITIAL (node->decl))
143 fprintf (f, " initialized"); 227 fprintf (f, " initialized");
228 if (TREE_ASM_WRITTEN (node->decl))
229 fprintf (f, " (asm written)");
144 if (node->needed) 230 if (node->needed)
145 fprintf (f, " needed"); 231 fprintf (f, " needed");
146 if (node->analyzed) 232 if (node->analyzed)
147 fprintf (f, " analyzed"); 233 fprintf (f, " analyzed");
148 if (node->finalized) 234 if (node->finalized)
149 fprintf (f, " finalized"); 235 fprintf (f, " finalized");
150 if (node->output) 236 if (node->output)
151 fprintf (f, " output"); 237 fprintf (f, " output");
152 if (node->externally_visible) 238 if (node->externally_visible)
153 fprintf (f, " externally_visible"); 239 fprintf (f, " externally_visible");
240 if (node->in_other_partition)
241 fprintf (f, " in_other_partition");
242 else if (node->used_from_other_partition)
243 fprintf (f, " used_from_other_partition");
154 fprintf (f, "\n"); 244 fprintf (f, "\n");
245 fprintf (f, " References: ");
246 ipa_dump_references (f, &node->ref_list);
247 fprintf (f, " Refering this var: ");
248 ipa_dump_refering (f, &node->ref_list);
155 } 249 }
156 250
157 /* Dump the variable pool. */ 251 /* Dump the variable pool. */
158 void 252 void
159 dump_varpool (FILE *f) 253 dump_varpool (FILE *f)
190 be analyzed and compiled. */ 284 be analyzed and compiled. */
191 static void 285 static void
192 varpool_enqueue_needed_node (struct varpool_node *node) 286 varpool_enqueue_needed_node (struct varpool_node *node)
193 { 287 {
194 if (varpool_last_needed_node) 288 if (varpool_last_needed_node)
195 varpool_last_needed_node->next_needed = node; 289 {
290 varpool_last_needed_node->next_needed = node;
291 node->prev_needed = varpool_last_needed_node;
292 }
196 varpool_last_needed_node = node; 293 varpool_last_needed_node = node;
197 node->next_needed = NULL; 294 node->next_needed = NULL;
198 if (!varpool_nodes_queue) 295 if (!varpool_nodes_queue)
199 varpool_nodes_queue = node; 296 varpool_nodes_queue = node;
200 if (!varpool_first_unanalyzed_node) 297 if (!varpool_first_unanalyzed_node)
205 /* Notify finalize_compilation_unit that given node is reachable 302 /* Notify finalize_compilation_unit that given node is reachable
206 or needed. */ 303 or needed. */
207 void 304 void
208 varpool_mark_needed_node (struct varpool_node *node) 305 varpool_mark_needed_node (struct varpool_node *node)
209 { 306 {
307 if (node->alias && node->extra_name)
308 node = node->extra_name;
210 if (!node->needed && node->finalized 309 if (!node->needed && node->finalized
211 && !TREE_ASM_WRITTEN (node->decl)) 310 && !TREE_ASM_WRITTEN (node->decl))
212 varpool_enqueue_needed_node (node); 311 varpool_enqueue_needed_node (node);
213 node->needed = 1; 312 node->needed = 1;
214 } 313 }
215 314
216 /* Reset the queue of needed nodes. */ 315 /* Reset the queue of needed nodes. */
217 static void 316 void
218 varpool_reset_queue (void) 317 varpool_reset_queue (void)
219 { 318 {
220 varpool_last_needed_node = NULL; 319 varpool_last_needed_node = NULL;
221 varpool_nodes_queue = NULL; 320 varpool_nodes_queue = NULL;
222 varpool_first_unanalyzed_node = NULL; 321 varpool_first_unanalyzed_node = NULL;
226 either outside this translation unit, something magic in the system 325 either outside this translation unit, something magic in the system
227 configury */ 326 configury */
228 bool 327 bool
229 decide_is_variable_needed (struct varpool_node *node, tree decl) 328 decide_is_variable_needed (struct varpool_node *node, tree decl)
230 { 329 {
330 if (node->used_from_other_partition)
331 return true;
231 /* If the user told us it is used, then it must be so. */ 332 /* If the user told us it is used, then it must be so. */
232 if ((node->externally_visible && !DECL_COMDAT (decl)) 333 if ((node->externally_visible && !DECL_COMDAT (decl))
233 || node->force_output) 334 || node->force_output)
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; 335 return true;
242 336
243 /* Externally visible variables must be output. The exception is 337 /* Externally visible variables must be output. The exception is
244 COMDAT variables that must be output only when they are needed. */ 338 COMDAT variables that must be output only when they are needed. */
245 if (TREE_PUBLIC (decl) 339 if (TREE_PUBLIC (decl)
278 void 372 void
279 varpool_finalize_decl (tree decl) 373 varpool_finalize_decl (tree decl)
280 { 374 {
281 struct varpool_node *node = varpool_node (decl); 375 struct varpool_node *node = varpool_node (decl);
282 376
283 /* FIXME: We don't really stream varpool datastructure and instead rebuild it
284 by varpool_finalize_decl. This is not quite correct since this way we can't
285 attach any info to varpool. Eventually we will want to stream varpool nodes
286 and the flags.
287
288 For the moment just prevent analysis of varpool nodes to happen again, so
289 we will re-try to compute "address_taken" flag of varpool that breaks
290 in presence of clones. */
291 if (in_lto_p)
292 node->analyzed = true;
293
294 /* The first declaration of a variable that comes through this function 377 /* The first declaration of a variable that comes through this function
295 decides whether it is global (in C, has external linkage) 378 decides whether it is global (in C, has external linkage)
296 or local (in C, has internal linkage). So do nothing more 379 or local (in C, has internal linkage). So do nothing more
297 if this function has already run. */ 380 if this function has already run. */
298 if (node->finalized) 381 if (node->finalized)
302 return; 385 return;
303 } 386 }
304 if (node->needed) 387 if (node->needed)
305 varpool_enqueue_needed_node (node); 388 varpool_enqueue_needed_node (node);
306 node->finalized = true; 389 node->finalized = true;
390 if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl))
391 node->force_output = true;
307 392
308 if (decide_is_variable_needed (node, decl)) 393 if (decide_is_variable_needed (node, decl))
309 varpool_mark_needed_node (node); 394 varpool_mark_needed_node (node);
310 /* Since we reclaim unreachable nodes at the end of every language 395 /* Since we reclaim unreachable nodes at the end of every language
311 level unit, we need to be conservative about possible entry points 396 level unit, we need to be conservative about possible entry points
338 variables or functions and add them into the worklists. */ 423 variables or functions and add them into the worklists. */
339 bool 424 bool
340 varpool_analyze_pending_decls (void) 425 varpool_analyze_pending_decls (void)
341 { 426 {
342 bool changed = false; 427 bool changed = false;
343 timevar_push (TV_CGRAPH); 428
344 429 timevar_push (TV_VARPOOL);
345 while (varpool_first_unanalyzed_node) 430 while (varpool_first_unanalyzed_node)
346 { 431 {
347 tree decl = varpool_first_unanalyzed_node->decl; 432 struct varpool_node *node = varpool_first_unanalyzed_node, *next;
348 bool analyzed = varpool_first_unanalyzed_node->analyzed; 433 tree decl = node->decl;
434 bool analyzed = node->analyzed;
349 435
350 varpool_first_unanalyzed_node->analyzed = true; 436 varpool_first_unanalyzed_node->analyzed = true;
351 437
352 varpool_first_unanalyzed_node = varpool_first_unanalyzed_node->next_needed; 438 varpool_first_unanalyzed_node = varpool_first_unanalyzed_node->next_needed;
353 439
354 /* When reading back varpool at LTO time, we re-construct the queue in order 440 /* When reading back varpool at LTO time, we re-construct the queue in order
355 to have "needed" list right by inserting all needed nodes into varpool. 441 to have "needed" list right by inserting all needed nodes into varpool.
356 We however don't want to re-analyze already analyzed nodes. */ 442 We however don't want to re-analyze already analyzed nodes. */
357 if (!analyzed) 443 if (!analyzed)
358 { 444 {
359 gcc_assert (!in_lto_p); 445 gcc_assert (!in_lto_p || cgraph_function_flags_ready);
360 /* Compute the alignment early so function body expanders are 446 /* Compute the alignment early so function body expanders are
361 already informed about increased alignment. */ 447 already informed about increased alignment. */
362 align_variable (decl, 0); 448 align_variable (decl, 0);
363 } 449 }
364 if (DECL_INITIAL (decl)) 450 if (DECL_INITIAL (decl))
365 record_references_in_initializer (decl, analyzed); 451 record_references_in_initializer (decl, analyzed);
452 if (node->same_comdat_group)
453 {
454 for (next = node->same_comdat_group;
455 next != node;
456 next = next->same_comdat_group)
457 varpool_mark_needed_node (next);
458 }
366 changed = true; 459 changed = true;
367 } 460 }
368 timevar_pop (TV_CGRAPH); 461 timevar_pop (TV_VARPOOL);
369 return changed; 462 return changed;
370 } 463 }
371 464
372 /* Output one variable, if necessary. Return whether we output it. */ 465 /* Output one variable, if necessary. Return whether we output it. */
373 bool 466 bool
375 { 468 {
376 tree decl = node->decl; 469 tree decl = node->decl;
377 470
378 if (!TREE_ASM_WRITTEN (decl) 471 if (!TREE_ASM_WRITTEN (decl)
379 && !node->alias 472 && !node->alias
473 && !node->in_other_partition
380 && !DECL_EXTERNAL (decl) 474 && !DECL_EXTERNAL (decl)
381 && (TREE_CODE (decl) != VAR_DECL || !DECL_HAS_VALUE_EXPR_P (decl))) 475 && (TREE_CODE (decl) != VAR_DECL || !DECL_HAS_VALUE_EXPR_P (decl)))
382 { 476 {
383 assemble_variable (decl, 0, 1, 0); 477 assemble_variable (decl, 0, 1, 0);
384 if (TREE_ASM_WRITTEN (decl)) 478 if (TREE_ASM_WRITTEN (decl))
385 { 479 {
480 struct varpool_node *alias;
481
386 node->next_needed = varpool_assembled_nodes_queue; 482 node->next_needed = varpool_assembled_nodes_queue;
483 node->prev_needed = NULL;
484 if (varpool_assembled_nodes_queue)
485 varpool_assembled_nodes_queue->prev_needed = node;
387 varpool_assembled_nodes_queue = node; 486 varpool_assembled_nodes_queue = node;
388 node->finalized = 1; 487 node->finalized = 1;
488
489 /* Also emit any extra name aliases. */
490 for (alias = node->extra_name; alias; alias = alias->next)
491 {
492 /* Update linkage fields in case they've changed. */
493 DECL_WEAK (alias->decl) = DECL_WEAK (decl);
494 TREE_PUBLIC (alias->decl) = TREE_PUBLIC (decl);
495 DECL_VISIBILITY (alias->decl) = DECL_VISIBILITY (decl);
496 assemble_alias (alias->decl, DECL_ASSEMBLER_NAME (decl));
497 }
498
389 return true; 499 return true;
390 } 500 }
391 } 501 }
392 502
393 return false; 503 return false;
440 bool changed = false; 550 bool changed = false;
441 551
442 if (errorcount || sorrycount) 552 if (errorcount || sorrycount)
443 return false; 553 return false;
444 554
555 timevar_push (TV_VAROUT);
445 /* EH might mark decls as needed during expansion. This should be safe since 556 /* 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 557 we don't create references to new function, but it should not be used
447 elsewhere. */ 558 elsewhere. */
448 varpool_analyze_pending_decls (); 559 varpool_analyze_pending_decls ();
449 560
453 564
454 varpool_nodes_queue = varpool_nodes_queue->next_needed; 565 varpool_nodes_queue = varpool_nodes_queue->next_needed;
455 if (varpool_assemble_decl (node)) 566 if (varpool_assemble_decl (node))
456 changed = true; 567 changed = true;
457 else 568 else
458 node->next_needed = NULL; 569 {
570 node->prev_needed = NULL;
571 node->next_needed = NULL;
572 }
459 } 573 }
460 /* varpool_nodes_queue is now empty, clear the pointer to the last element 574 /* varpool_nodes_queue is now empty, clear the pointer to the last element
461 in the queue. */ 575 in the queue. */
462 varpool_last_needed_node = NULL; 576 varpool_last_needed_node = NULL;
577 timevar_pop (TV_VAROUT);
463 return changed; 578 return changed;
464 } 579 }
465 580
466 /* Remove all elements from the queue so we can re-use it for debug output. */ 581 /* Remove all elements from the queue so we can re-use it for debug output. */
467 void 582 void
475 while (varpool_nodes_queue) 590 while (varpool_nodes_queue)
476 { 591 {
477 struct varpool_node *node = varpool_nodes_queue; 592 struct varpool_node *node = varpool_nodes_queue;
478 varpool_nodes_queue = varpool_nodes_queue->next_needed; 593 varpool_nodes_queue = varpool_nodes_queue->next_needed;
479 node->next_needed = NULL; 594 node->next_needed = NULL;
595 node->prev_needed = NULL;
480 } 596 }
481 /* varpool_nodes_queue is now empty, clear the pointer to the last element 597 /* varpool_nodes_queue is now empty, clear the pointer to the last element
482 in the queue. */ 598 in the queue. */
483 varpool_last_needed_node = NULL; 599 varpool_last_needed_node = NULL;
484 } 600 }
505 varpool_finalize_decl (new_decl); 621 varpool_finalize_decl (new_decl);
506 622
507 return new_node->decl; 623 return new_node->decl;
508 } 624 }
509 625
626 /* Attempt to mark ALIAS as an alias to DECL. Return TRUE if successful.
627 Extra name aliases are output whenever DECL is output. */
628
629 bool
630 varpool_extra_name_alias (tree alias, tree decl)
631 {
632 struct varpool_node key, *alias_node, *decl_node, **slot;
633
634 #ifndef ASM_OUTPUT_DEF
635 /* If aliases aren't supported by the assembler, fail. */
636 return false;
637 #endif
638
639 gcc_assert (TREE_CODE (decl) == VAR_DECL);
640 gcc_assert (TREE_CODE (alias) == VAR_DECL);
641 /* Make sure the hash table has been created. */
642 decl_node = varpool_node (decl);
643
644 key.decl = alias;
645
646 slot = (struct varpool_node **) htab_find_slot (varpool_hash, &key, INSERT);
647
648 /* If the varpool_node has been already created, fail. */
649 if (*slot)
650 return false;
651
652 alias_node = GGC_CNEW (struct varpool_node);
653 alias_node->decl = alias;
654 alias_node->alias = 1;
655 alias_node->extra_name = decl_node;
656 alias_node->next = decl_node->extra_name;
657 ipa_empty_ref_list (&alias_node->ref_list);
658 if (decl_node->extra_name)
659 decl_node->extra_name->prev = alias_node;
660 decl_node->extra_name = alias_node;
661 *slot = alias_node;
662 return true;
663 }
664
510 #include "gt-varpool.h" 665 #include "gt-varpool.h"