cgraph.c revision 132718
11195Srgrimes/* Callgraph handling code. 250472Speter Copyright (C) 2003, 2004 Free Software Foundation, Inc. 337Srgrimes Contributed by Jan Hubicka 4156813Sru 5156813SruThis file is part of GCC. 6156813Sru 738103SpeterGCC is free software; you can redistribute it and/or modify it under 873251Sgshapirothe terms of the GNU General Public License as published by the Free 938103SpeterSoftware Foundation; either version 2, or (at your option) any later 10236965Sdesversion. 11231849Seadler 12231849SeadlerGCC is distributed in the hope that it will be useful, but WITHOUT ANY 13231849SeadlerWARRANTY; without even the implied warranty of MERCHANTABILITY or 14231849SeadlerFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15231849Seadlerfor more details. 16231849Seadler 17231849SeadlerYou should have received a copy of the GNU General Public License 18231849Seadleralong with GCC; see the file COPYING. If not, write to the Free 19231849SeadlerSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA 20231849Seadler02111-1307, USA. */ 21231849Seadler 22231849Seadler#include "config.h" 23231849Seadler#include "system.h" 24231849Seadler#include "coretypes.h" 25231849Seadler#include "tm.h" 26231849Seadler#include "tree.h" 27231849Seadler#include "langhooks.h" 28231849Seadler#include "hashtab.h" 29231849Seadler#include "toplev.h" 30231849Seadler#include "flags.h" 31231849Seadler#include "ggc.h" 32231849Seadler#include "debug.h" 33231849Seadler#include "target.h" 34231849Seadler#include "cgraph.h" 35231849Seadler#include "varray.h" 36231849Seadler#include "output.h" 37231849Seadler#include "intl.h" 38231849Seadler 39231849Seadler 40231849Seadler/* Hash table used to convert declarations into nodes. */ 41231849Seadlerstatic GTY((param_is (struct cgraph_node))) htab_t cgraph_hash; 42231849Seadler 43231849Seadler/* The linked list of cgraph nodes. */ 44231849Seadlerstruct cgraph_node *cgraph_nodes; 45231849Seadler 46231849Seadler/* Queue of cgraph nodes scheduled to be lowered. */ 47231849Seadlerstruct cgraph_node *cgraph_nodes_queue; 48231849Seadler 49231849Seadler/* Number of nodes in existence. */ 50231849Seadlerint cgraph_n_nodes; 51155210Srwatson 52199249Sed/* Maximal uid used in cgraph nodes. */ 53199249Sedint cgraph_max_uid; 54209134Simp 55209134Simp/* Set when whole unit has been analyzed so we can access global info. */ 56209134Simpbool cgraph_global_info_ready = false; 57209134Simp 58199249Sed/* Hash table used to convert declarations into nodes. */ 59209134Simpstatic GTY((param_is (struct cgraph_varpool_node))) htab_t cgraph_varpool_hash; 60199249Sed 61199249Sed/* Queue of cgraph nodes scheduled to be lowered and output. */ 62155210Srwatsonstruct cgraph_varpool_node *cgraph_varpool_nodes_queue; 63155210Srwatson 64155210Srwatson/* Number of nodes in existence. */ 65155210Srwatsonint cgraph_varpool_n_nodes; 66155210Srwatson 67155210Srwatson/* The linked list of cgraph varpool nodes. */ 68155210Srwatsonstatic GTY(()) struct cgraph_varpool_node *cgraph_varpool_nodes; 69155210Srwatson 70183242Ssamstatic struct cgraph_edge *create_edge (struct cgraph_node *, 71183242Ssam struct cgraph_node *); 72183242Ssamstatic hashval_t hash_node (const void *); 73183242Ssamstatic int eq_node (const void *, const void *); 74183242Ssam 75183242Ssam/* Returns a hash code for P. */ 76183242Ssam 77183242Ssamstatic hashval_t 78183242Ssamhash_node (const void *p) 79183242Ssam{ 80183242Ssam return ((hashval_t) 81183242Ssam IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME 82183242Ssam (((struct cgraph_node *) p)->decl))); 83183242Ssam} 84183242Ssam 85183242Ssam/* Returns nonzero if P1 and P2 are equal. */ 86183242Ssam 87183242Ssamstatic int 88183242Ssameq_node (const void *p1, const void *p2) 89183242Ssam{ 90183242Ssam return ((DECL_ASSEMBLER_NAME (((struct cgraph_node *) p1)->decl)) == 91183242Ssam (tree) p2); 92156813Sru} 93183242Ssam 94121911Smarkm/* Return cgraph node assigned to DECL. Create new one when needed. */ 9537Srgrimesstruct cgraph_node * 96183242Ssamcgraph_node (tree decl) 97183242Ssam{ 98158115Sume struct cgraph_node *node; 99158115Sume struct cgraph_node **slot; 100193635Sedwin 101193635Sedwin if (TREE_CODE (decl) != FUNCTION_DECL) 102193635Sedwin abort (); 103193635Sedwin 104156813Sru if (!cgraph_hash) 10557488Speter cgraph_hash = htab_create_ggc (10, hash_node, eq_node, NULL); 10674837Sgreen 107124214Sdes slot = (struct cgraph_node **) 10857459Smarkm htab_find_slot_with_hash (cgraph_hash, DECL_ASSEMBLER_NAME (decl), 109156813Sru IDENTIFIER_HASH_VALUE 11060677Skris (DECL_ASSEMBLER_NAME (decl)), INSERT); 11160677Skris if (*slot) 11260677Skris return *slot; 113183242Ssam node = ggc_alloc_cleared (sizeof (*node)); 114183242Ssam node->decl = decl; 115183242Ssam node->next = cgraph_nodes; 116183242Ssam node->uid = cgraph_max_uid++; 117183242Ssam if (cgraph_nodes) 118183242Ssam cgraph_nodes->previous = node; 119183242Ssam node->previous = NULL; 120183242Ssam cgraph_nodes = node; 121183242Ssam cgraph_n_nodes++; 122183242Ssam *slot = node; 123183242Ssam if (DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL) 124183242Ssam { 125184343Ssam node->origin = cgraph_node (DECL_CONTEXT (decl)); 126184343Ssam node->next_nested = node->origin->nested; 127184343Ssam node->origin->nested = node; 128184343Ssam } 129183268Ssam return node; 130183268Ssam} 131183268Ssam 132183268Ssam/* Try to find existing function for identifier ID. */ 13382521Salexstruct cgraph_node * 134108002Sgreencgraph_node_for_identifier (tree id) 135147Srgrimes{ 136196767Sflz struct cgraph_node **slot; 137156813Sru 13895144Sgshapiro if (TREE_CODE (id) != IDENTIFIER_NODE) 13995144Sgshapiro abort (); 140156813Sru 141135851Sdougb if (!cgraph_hash) 142156813Sru return NULL; 143135851Sdougb 144135851Sdougb slot = (struct cgraph_node **) 145135851Sdougb htab_find_slot_with_hash (cgraph_hash, id, 14699451Sru IDENTIFIER_HASH_VALUE (id), NO_INSERT); 14799451Sru if (!slot) 14899451Sru return NULL; 149156813Sru return *slot; 150117292Sgshapiro} 151117292Sgshapiro 15264598Sgshapiro/* Create edge from CALLER to CALLEE in the cgraph. */ 15364598Sgshapiro 154117292Sgshapirostatic struct cgraph_edge * 15537Srgrimescreate_edge (struct cgraph_node *caller, struct cgraph_node *callee) 156263Srgrimes{ 15799449Sru struct cgraph_edge *edge = ggc_alloc (sizeof (struct cgraph_edge)); 158263Srgrimes struct cgraph_edge *edge2; 159124831Sru 160156813Sru if (!DECL_SAVED_TREE (callee->decl)) 161173135Syar edge->inline_failed = N_("function body not available"); 162124831Sru else if (callee->local.redefined_extern_inline) 163124831Sru edge->inline_failed = N_("redefined extern inline functions are not " 1644487Sphk "considered for inlining"); 165173135Syar else if (callee->local.inlinable) 166173135Syar edge->inline_failed = N_("function not considered for inlining"); 1675948Sjkh else 168142794Sru edge->inline_failed = N_("function not inlinable"); 169142794Sru 170152471Sru /* At the moment we don't associate calls with specific CALL_EXPRs 171152471Sru as we probably ought to, so we must preserve inline_call flags to 172142794Sru be the same in all copies of the same edge. */ 173152471Sru if (cgraph_global_info_ready) 174152471Sru for (edge2 = caller->callees; edge2; edge2 = edge2->next_callee) 175142794Sru if (edge2->callee == callee) 176149515Simp { 177149515Simp edge->inline_failed = edge2->inline_failed; 178142794Sru break; 179142794Sru } 1804487Sphk 181148282Sru edge->caller = caller; 182148282Sru edge->callee = callee; 183148282Sru edge->next_caller = callee->callers; 184148282Sru edge->next_callee = caller->callees; 18599449Sru caller->callees = edge; 186100872Sru callee->callers = edge; 18799451Sru return edge; 188142794Sru} 189100872Sru 19099451Sru/* Remove the edge from CALLER to CALLEE in the cgraph. */ 191100872Sru 192184343Ssamvoid 193205329Sedcgraph_remove_edge (struct cgraph_node *caller, struct cgraph_node *callee) 194205335Sed{ 195205329Sed struct cgraph_edge **edge, **edge2; 196184343Ssam 197184443Smp for (edge = &callee->callers; *edge && (*edge)->caller != caller; 198184343Ssam edge = &((*edge)->next_caller)) 199184343Ssam continue; 200184343Ssam if (!*edge) 201241823Smarcel abort (); 202241823Smarcel *edge = (*edge)->next_caller; 203241823Smarcel for (edge2 = &caller->callees; *edge2 && (*edge2)->callee != callee; 204183242Ssam edge2 = &(*edge2)->next_callee) 205173135Syar continue; 206183242Ssam if (!*edge2) 207173135Syar abort (); 208186249Sthompsa *edge2 = (*edge2)->next_callee; 209173135Syar} 210173135Syar 211173135Syar/* Remove the node from cgraph. */ 212173135Syar 213173135Syarvoid 214173135Syarcgraph_remove_node (struct cgraph_node *node) 215173135Syar{ 216155210Srwatson void **slot; 217155210Srwatson while (node->callers) 218155571Srwatson cgraph_remove_edge (node->callers->caller, node); 219155210Srwatson while (node->callees) 220155210Srwatson cgraph_remove_edge (node, node->callees->callee); 221155210Srwatson while (node->nested) 222170913Sdougb cgraph_remove_node (node->nested); 223243101Seadler if (node->origin) 224170913Sdougb { 225170913Sdougb struct cgraph_node **node2 = &node->origin->nested; 226170913Sdougb 227170913Sdougb while (*node2 != node) 228173135Syar node2 = &(*node2)->next_nested; 229170913Sdougb *node2 = node->next_nested; 230156813Sru } 231173135Syar if (node->previous) 23273251Sgshapiro node->previous->next = node->next; 233156813Sru else 234100872Sru cgraph_nodes = node->next; 23599451Sru if (node->next) 23657488Speter node->next->previous = node->previous; 237156813Sru DECL_SAVED_TREE (node->decl) = NULL; 238100872Sru DECL_SAVED_INSNS (node->decl) = NULL; 23999451Sru DECL_ARGUMENTS (node->decl) = NULL; 24060677Skris DECL_INITIAL (node->decl) = error_mark_node; 241156813Sru slot = 24299449Sru htab_find_slot_with_hash (cgraph_hash, DECL_ASSEMBLER_NAME (node->decl), 243100872Sru IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME 244120709Sphk (node->decl)), NO_INSERT); 245120709Sphk if (slot == 0) 246120709Sphk { 247120709Sphk /* We use DECL_ASSEMBLER_NAME as key, which may not work in 248184343Ssam all cases. See PR/15666. Gcc 3.5 uses DECL_UID as key, 249184343Ssam which doesn't have this problem. */ 250184343Ssam if (!DECL_BUILT_IN (node->decl)) 251184343Ssam abort (); 252184343Ssam } 253184343Ssam else 25499451Sru htab_clear_slot (cgraph_hash, slot); 255100872Sru /* Do not free the structure itself so the walk over chain can continue. */ 25699451Sru} 257184343Ssam 258184343Ssam/* Notify finalize_compilation_unit that given node is reachable. */ 259184343Ssam 260100872Sruvoid 2611731Sjkhcgraph_mark_reachable_node (struct cgraph_node *node) 262183242Ssam{ 263119058Sobrien if (!node->reachable && node->local.finalized) 2646177Samurai { 265183242Ssam notice_global_symbol (node->decl); 266183242Ssam node->reachable = 1; 267100872Sru 26864598Sgshapiro node->next_needed = cgraph_nodes_queue; 269243101Seadler cgraph_nodes_queue = node; 27064629Sgshapiro 27164629Sgshapiro /* At the moment frontend automatically emits all nested functions. */ 27264629Sgshapiro if (node->nested) 273183242Ssam { 274100872Sru struct cgraph_node *node2; 27537Srgrimes 276100872Sru for (node2 = node->nested; node2; node2 = node2->next_nested) 277147Srgrimes if (!node2->reachable) 278100872Sru cgraph_mark_reachable_node (node2); 2791759Sjkh } 280100872Sru } 28199451Sru} 282209228Savg 283171427Simp/* Likewise indicate that a node is needed, i.e. reachable via some 284126977Sru external means. */ 285126977Sru 286126977Sruvoid 287171427Simpcgraph_mark_needed_node (struct cgraph_node *node) 288209228Savg{ 289224765Sdougb node->needed = 1; 290224765Sdougb cgraph_mark_reachable_node (node); 291224765Sdougb} 292224765Sdougb 29337Srgrimes/* Record call from CALLER to CALLEE. */ 294245440Sbrooks 295245440Sbrooksstruct cgraph_edge * 296245565Sbrookscgraph_record_call (tree caller, tree callee) 297245565Sbrooks{ 298245565Sbrooks return create_edge (cgraph_node (caller), cgraph_node (callee)); 299245565Sbrooks} 300156813Sru 301245565Sbrooksvoid 302135875Sdougbcgraph_remove_call (tree caller, tree callee) 303156813Sru{ 304245565Sbrooks cgraph_remove_edge (cgraph_node (caller), cgraph_node (callee)); 305135875Sdougb} 306218941Suqs 307245565Sbrooks/* Return true when CALLER_DECL calls CALLEE_DECL. */ 308218941Suqs 309156813Srubool 310245565Sbrookscgraph_calls_p (tree caller_decl, tree callee_decl) 31195144Sgshapiro{ 312245565Sbrooks struct cgraph_node *caller = cgraph_node (caller_decl); 313245565Sbrooks struct cgraph_node *callee = cgraph_node (callee_decl); 314245565Sbrooks struct cgraph_edge *edge; 315245565Sbrooks 316245565Sbrooks for (edge = callee->callers; edge && (edge)->caller != caller; 317245565Sbrooks edge = (edge->next_caller)) 318245565Sbrooks continue; 319245565Sbrooks return edge != NULL; 320245565Sbrooks} 321245565Sbrooks 322245565Sbrooks/* Return local info for the compiled function. */ 323245565Sbrooks 324245565Sbrooksstruct cgraph_local_info * 325245565Sbrookscgraph_local_info (tree decl) 326245565Sbrooks{ 327245571Sbrooks struct cgraph_node *node; 32877993Sache if (TREE_CODE (decl) != FUNCTION_DECL) 329245571Sbrooks abort (); 330245571Sbrooks node = cgraph_node (decl); 331245571Sbrooks return &node->local; 33277993Sache} 333110663Sache 334245571Sbrooks/* Return local info for the compiled function. */ 335245571Sbrooks 336245571Sbrooksstruct cgraph_global_info * 337245571Sbrookscgraph_global_info (tree decl) 338110663Sache{ 339245571Sbrooks struct cgraph_node *node; 340245571Sbrooks if (TREE_CODE (decl) != FUNCTION_DECL || !cgraph_global_info_ready) 341245571Sbrooks abort (); 342110663Sache node = cgraph_node (decl); 343110663Sache return &node->global; 34477999Sache} 345245571Sbrooks 346245571Sbrooks/* Return local info for the compiled function. */ 34711635Sache 34877999Sachestruct cgraph_rtl_info * 349147Srgrimescgraph_rtl_info (tree decl) 35048185Ssheldonh{ 351100872Sru struct cgraph_node *node; 35299451Sru if (TREE_CODE (decl) != FUNCTION_DECL) 35399451Sru abort (); 354173135Syar node = cgraph_node (decl); 355119385Smtm if (decl != current_function_decl 35648185Ssheldonh && !TREE_ASM_WRITTEN (node->decl)) 35737Srgrimes return NULL; 358 return &node->rtl; 359} 360 361/* Return name of the node used in debug output. */ 362const char * 363cgraph_node_name (struct cgraph_node *node) 364{ 365 return (*lang_hooks.decl_printable_name) (node->decl, 2); 366} 367 368/* Dump the callgraph. */ 369 370void 371dump_cgraph (FILE *f) 372{ 373 struct cgraph_node *node; 374 375 fprintf (f, "callgraph:\n\n"); 376 for (node = cgraph_nodes; node; node = node->next) 377 { 378 struct cgraph_edge *edge; 379 fprintf (f, "%s:", cgraph_node_name (node)); 380 if (node->local.self_insns) 381 fprintf (f, " %i insns", node->local.self_insns); 382 if (node->global.insns && node->global.insns != node->local.self_insns) 383 fprintf (f, " (%i after inlining)", node->global.insns); 384 if (node->origin) 385 fprintf (f, " nested in: %s", cgraph_node_name (node->origin)); 386 if (node->needed) 387 fprintf (f, " needed"); 388 else if (node->reachable) 389 fprintf (f, " reachable"); 390 if (DECL_SAVED_TREE (node->decl)) 391 fprintf (f, " tree"); 392 393 if (node->local.local) 394 fprintf (f, " local"); 395 if (node->local.disregard_inline_limits) 396 fprintf (f, " always_inline"); 397 else if (node->local.inlinable) 398 fprintf (f, " inlinable"); 399 if (node->global.cloned_times > 1) 400 fprintf (f, " cloned %ix", node->global.cloned_times); 401 402 fprintf (f, "\n called by: "); 403 for (edge = node->callers; edge; edge = edge->next_caller) 404 { 405 fprintf (f, "%s ", cgraph_node_name (edge->caller)); 406 if (!edge->inline_failed) 407 fprintf(f, "(inlined) "); 408 } 409 410 fprintf (f, "\n calls: "); 411 for (edge = node->callees; edge; edge = edge->next_callee) 412 { 413 fprintf (f, "%s ", cgraph_node_name (edge->callee)); 414 if (!edge->inline_failed) 415 fprintf(f, "(inlined) "); 416 } 417 fprintf (f, "\n"); 418 } 419} 420 421/* Returns a hash code for P. */ 422 423static hashval_t 424cgraph_varpool_hash_node (const void *p) 425{ 426 return ((hashval_t) 427 IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME 428 (((struct cgraph_varpool_node *) p)->decl))); 429} 430 431/* Returns nonzero if P1 and P2 are equal. */ 432 433static int 434eq_cgraph_varpool_node (const void *p1, const void *p2) 435{ 436 return ((DECL_ASSEMBLER_NAME (((struct cgraph_varpool_node *) p1)->decl)) == 437 (tree) p2); 438} 439 440/* Return cgraph_varpool node assigned to DECL. Create new one when needed. */ 441struct cgraph_varpool_node * 442cgraph_varpool_node (tree decl) 443{ 444 struct cgraph_varpool_node *node; 445 struct cgraph_varpool_node **slot; 446 447 if (!DECL_P (decl) || TREE_CODE (decl) == FUNCTION_DECL) 448 abort (); 449 450 if (!cgraph_varpool_hash) 451 cgraph_varpool_hash = htab_create_ggc (10, cgraph_varpool_hash_node, 452 eq_cgraph_varpool_node, NULL); 453 slot = (struct cgraph_varpool_node **) 454 htab_find_slot_with_hash (cgraph_varpool_hash, DECL_ASSEMBLER_NAME (decl), 455 IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME (decl)), 456 INSERT); 457 if (*slot) 458 return *slot; 459 node = ggc_alloc_cleared (sizeof (*node)); 460 node->decl = decl; 461 cgraph_varpool_n_nodes++; 462 cgraph_varpool_nodes = node; 463 *slot = node; 464 return node; 465} 466 467/* Set the DECL_ASSEMBLER_NAME and update cgraph hashtables. */ 468void 469change_decl_assembler_name (tree decl, tree name) 470{ 471 struct cgraph_node *node = NULL; 472 struct cgraph_varpool_node *vnode = NULL; 473 void **slot; 474 475 if (!DECL_ASSEMBLER_NAME_SET_P (decl)) 476 { 477 SET_DECL_ASSEMBLER_NAME (decl, name); 478 return; 479 } 480 if (name == DECL_ASSEMBLER_NAME (decl)) 481 return; 482 483 if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) 484 && DECL_RTL_SET_P (decl)) 485 warning ("%D renamed after being referenced in assembly", decl); 486 487 if (TREE_CODE (decl) == FUNCTION_DECL && cgraph_hash) 488 { 489 /* Take a look whether declaration is in the cgraph structure. */ 490 slot = 491 htab_find_slot_with_hash (cgraph_hash, DECL_ASSEMBLER_NAME (decl), 492 IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME 493 (decl)), NO_INSERT); 494 if (slot) 495 node = *slot; 496 497 /* It is, verify that we are the canonical node for this decl. */ 498 if (node && node->decl == decl) 499 { 500 node = *slot; 501 htab_clear_slot (cgraph_hash, slot); 502 } 503 else 504 node = NULL; 505 } 506 if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl) && cgraph_varpool_hash) 507 { 508 /* Take a look whether declaration is in the cgraph structure. */ 509 slot = 510 htab_find_slot_with_hash (cgraph_varpool_hash, DECL_ASSEMBLER_NAME (decl), 511 IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME 512 (decl)), NO_INSERT); 513 if (slot) 514 vnode = *slot; 515 516 /* It is, verify that we are the canonical vnode for this decl. */ 517 if (vnode && vnode->decl == decl) 518 { 519 vnode = *slot; 520 htab_clear_slot (cgraph_varpool_hash, slot); 521 } 522 else 523 vnode = NULL; 524 } 525 SET_DECL_ASSEMBLER_NAME (decl, name); 526 if (node) 527 { 528 slot = 529 htab_find_slot_with_hash (cgraph_hash, name, 530 IDENTIFIER_HASH_VALUE (name), INSERT); 531 if (*slot) 532 abort (); 533 *slot = node; 534 } 535 if (vnode) 536 { 537 slot = 538 htab_find_slot_with_hash (cgraph_varpool_hash, name, 539 IDENTIFIER_HASH_VALUE (name), INSERT); 540 if (*slot) 541 abort (); 542 *slot = vnode; 543 } 544} 545 546/* Try to find existing function for identifier ID. */ 547struct cgraph_varpool_node * 548cgraph_varpool_node_for_identifier (tree id) 549{ 550 struct cgraph_varpool_node **slot; 551 552 if (TREE_CODE (id) != IDENTIFIER_NODE) 553 abort (); 554 555 if (!cgraph_varpool_hash) 556 return NULL; 557 558 slot = (struct cgraph_varpool_node **) 559 htab_find_slot_with_hash (cgraph_varpool_hash, id, 560 IDENTIFIER_HASH_VALUE (id), NO_INSERT); 561 if (!slot) 562 return NULL; 563 return *slot; 564} 565 566/* Notify finalize_compilation_unit that given node is reachable 567 or needed. */ 568void 569cgraph_varpool_mark_needed_node (struct cgraph_varpool_node *node) 570{ 571 if (!node->needed && node->finalized) 572 { 573 node->next_needed = cgraph_varpool_nodes_queue; 574 cgraph_varpool_nodes_queue = node; 575 notice_global_symbol (node->decl); 576 } 577 node->needed = 1; 578} 579 580void 581cgraph_varpool_finalize_decl (tree decl) 582{ 583 struct cgraph_varpool_node *node = cgraph_varpool_node (decl); 584 585 /* The first declaration of a variable that comes through this function 586 decides whether it is global (in C, has external linkage) 587 or local (in C, has internal linkage). So do nothing more 588 if this function has already run. */ 589 if (node->finalized) 590 return; 591 if (node->needed) 592 { 593 node->next_needed = cgraph_varpool_nodes_queue; 594 cgraph_varpool_nodes_queue = node; 595 notice_global_symbol (decl); 596 } 597 node->finalized = true; 598 599 if (/* Externally visible variables must be output. The exception are 600 COMDAT functions that must be output only when they are needed. */ 601 (TREE_PUBLIC (decl) && !DECL_COMDAT (decl)) 602 /* Function whose name is output to the assembler file must be produced. 603 It is possible to assemble the name later after finalizing the function 604 and the fact is noticed in assemble_name then. */ 605 || (DECL_ASSEMBLER_NAME_SET_P (decl) 606 && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))) 607 { 608 cgraph_varpool_mark_needed_node (node); 609 } 610} 611 612bool 613cgraph_varpool_assemble_pending_decls (void) 614{ 615 bool changed = false; 616 617 while (cgraph_varpool_nodes_queue) 618 { 619 tree decl = cgraph_varpool_nodes_queue->decl; 620 struct cgraph_varpool_node *node = cgraph_varpool_nodes_queue; 621 622 cgraph_varpool_nodes_queue = cgraph_varpool_nodes_queue->next_needed; 623 if (!TREE_ASM_WRITTEN (decl)) 624 { 625 assemble_variable (decl, 0, 1, 0); 626 changed = true; 627 } 628 node->next_needed = NULL; 629 } 630 return changed; 631} 632 633/* Return true when the DECL can possibly be inlined. */ 634bool 635cgraph_function_possibly_inlined_p (tree decl) 636{ 637 if (!cgraph_global_info_ready) 638 return (DECL_INLINE (decl) 639 && (!flag_really_no_inline 640 || (*lang_hooks.tree_inlining.disregard_inline_limits) (decl))); 641 return cgraph_node (decl)->global.inlined; 642} 643 644#include "gt-cgraph.h" 645