1132718Skan/* Callgraph handling code. 2169689Skan Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. 3132718Skan Contributed by Jan Hubicka 4132718Skan 5132718SkanThis file is part of GCC. 6132718Skan 7132718SkanGCC is free software; you can redistribute it and/or modify it under 8132718Skanthe terms of the GNU General Public License as published by the Free 9132718SkanSoftware Foundation; either version 2, or (at your option) any later 10132718Skanversion. 11132718Skan 12132718SkanGCC is distributed in the hope that it will be useful, but WITHOUT ANY 13132718SkanWARRANTY; without even the implied warranty of MERCHANTABILITY or 14132718SkanFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15132718Skanfor more details. 16132718Skan 17132718SkanYou should have received a copy of the GNU General Public License 18132718Skanalong with GCC; see the file COPYING. If not, write to the Free 19169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 20169689Skan02110-1301, USA. */ 21132718Skan 22169689Skan/* This file contains basic routines manipulating call graph and variable pool 23169689Skan 24169689SkanThe callgraph: 25169689Skan 26169689Skan The call-graph is data structure designed for intra-procedural optimization 27169689Skan but it is also used in non-unit-at-a-time compilation to allow easier code 28169689Skan sharing. 29169689Skan 30169689Skan The call-graph consist of nodes and edges represented via linked lists. 31169689Skan Each function (external or not) corresponds to the unique node (in 32169689Skan contrast to tree DECL nodes where we can have multiple nodes for each 33169689Skan function). 34169689Skan 35169689Skan The mapping from declarations to call-graph nodes is done using hash table 36169689Skan based on DECL_ASSEMBLER_NAME, so it is essential for assembler name to 37169689Skan not change once the declaration is inserted into the call-graph. 38169689Skan The call-graph nodes are created lazily using cgraph_node function when 39169689Skan called for unknown declaration. 40169689Skan 41169689Skan When built, there is one edge for each direct call. It is possible that 42169689Skan the reference will be later optimized out. The call-graph is built 43169689Skan conservatively in order to make conservative data flow analysis possible. 44169689Skan 45169689Skan The callgraph at the moment does not represent indirect calls or calls 46169689Skan from other compilation unit. Flag NEEDED is set for each node that may 47169689Skan be accessed in such an invisible way and it shall be considered an 48169689Skan entry point to the callgraph. 49169689Skan 50169689Skan Interprocedural information: 51169689Skan 52169689Skan Callgraph is place to store data needed for interprocedural optimization. 53169689Skan All data structures are divided into three components: local_info that 54169689Skan is produced while analyzing the function, global_info that is result 55169689Skan of global walking of the callgraph on the end of compilation and 56169689Skan rtl_info used by RTL backend to propagate data from already compiled 57169689Skan functions to their callers. 58169689Skan 59169689Skan Inlining plans: 60169689Skan 61169689Skan The function inlining information is decided in advance and maintained 62169689Skan in the callgraph as so called inline plan. 63169689Skan For each inlined call, the callee's node is cloned to represent the 64169689Skan new function copy produced by inliner. 65169689Skan Each inlined call gets a unique corresponding clone node of the callee 66169689Skan and the data structure is updated while inlining is performed, so 67169689Skan the clones are eliminated and their callee edges redirected to the 68169689Skan caller. 69169689Skan 70169689Skan Each edge has "inline_failed" field. When the field is set to NULL, 71169689Skan the call will be inlined. When it is non-NULL it contains a reason 72169689Skan why inlining wasn't performed. 73169689Skan 74169689Skan 75169689SkanThe varpool data structure: 76169689Skan 77169689Skan Varpool is used to maintain variables in similar manner as call-graph 78169689Skan is used for functions. Most of the API is symmetric replacing cgraph 79169689Skan function prefix by cgraph_varpool */ 80169689Skan 81169689Skan 82132718Skan#include "config.h" 83132718Skan#include "system.h" 84132718Skan#include "coretypes.h" 85132718Skan#include "tm.h" 86132718Skan#include "tree.h" 87169689Skan#include "tree-inline.h" 88132718Skan#include "langhooks.h" 89132718Skan#include "hashtab.h" 90132718Skan#include "toplev.h" 91132718Skan#include "flags.h" 92132718Skan#include "ggc.h" 93132718Skan#include "debug.h" 94132718Skan#include "target.h" 95169689Skan#include "basic-block.h" 96132718Skan#include "cgraph.h" 97132718Skan#include "varray.h" 98132718Skan#include "output.h" 99132718Skan#include "intl.h" 100169689Skan#include "tree-gimple.h" 101169689Skan#include "tree-dump.h" 102132718Skan 103169689Skanstatic void cgraph_node_remove_callers (struct cgraph_node *node); 104169689Skanstatic inline void cgraph_edge_remove_caller (struct cgraph_edge *e); 105169689Skanstatic inline void cgraph_edge_remove_callee (struct cgraph_edge *e); 106132718Skan 107132718Skan/* Hash table used to convert declarations into nodes. */ 108132718Skanstatic GTY((param_is (struct cgraph_node))) htab_t cgraph_hash; 109132718Skan 110132718Skan/* The linked list of cgraph nodes. */ 111132718Skanstruct cgraph_node *cgraph_nodes; 112132718Skan 113132718Skan/* Queue of cgraph nodes scheduled to be lowered. */ 114132718Skanstruct cgraph_node *cgraph_nodes_queue; 115132718Skan 116169689Skan/* Queue of cgraph nodes scheduled to be expanded. This is a 117169689Skan secondary queue used during optimization to accommodate passes that 118169689Skan may generate new functions that need to be optimized and expanded. */ 119169689Skanstruct cgraph_node *cgraph_expand_queue; 120169689Skan 121132718Skan/* Number of nodes in existence. */ 122132718Skanint cgraph_n_nodes; 123132718Skan 124132718Skan/* Maximal uid used in cgraph nodes. */ 125132718Skanint cgraph_max_uid; 126132718Skan 127132718Skan/* Set when whole unit has been analyzed so we can access global info. */ 128132718Skanbool cgraph_global_info_ready = false; 129132718Skan 130169689Skan/* Set when the cgraph is fully build and the basic flags are computed. */ 131169689Skanbool cgraph_function_flags_ready = false; 132169689Skan 133132718Skan/* Hash table used to convert declarations into nodes. */ 134132718Skanstatic GTY((param_is (struct cgraph_varpool_node))) htab_t cgraph_varpool_hash; 135132718Skan 136132718Skan/* Queue of cgraph nodes scheduled to be lowered and output. */ 137169689Skanstruct cgraph_varpool_node *cgraph_varpool_nodes_queue, *cgraph_varpool_first_unanalyzed_node; 138132718Skan 139132718Skan/* The linked list of cgraph varpool nodes. */ 140169689Skanstruct cgraph_varpool_node *cgraph_varpool_nodes; 141132718Skan 142169689Skan/* End of the varpool queue. */ 143169689Skanstruct cgraph_varpool_node *cgraph_varpool_last_needed_node; 144169689Skan 145169689Skan/* Linked list of cgraph asm nodes. */ 146169689Skanstruct cgraph_asm_node *cgraph_asm_nodes; 147169689Skan 148169689Skan/* Last node in cgraph_asm_nodes. */ 149169689Skanstatic GTY(()) struct cgraph_asm_node *cgraph_asm_last_node; 150169689Skan 151169689Skan/* The order index of the next cgraph node to be created. This is 152169689Skan used so that we can sort the cgraph nodes in order by when we saw 153169689Skan them, to support -fno-toplevel-reorder. */ 154169689Skanint cgraph_order; 155169689Skan 156132718Skanstatic hashval_t hash_node (const void *); 157132718Skanstatic int eq_node (const void *, const void *); 158132718Skan 159132718Skan/* Returns a hash code for P. */ 160132718Skan 161132718Skanstatic hashval_t 162132718Skanhash_node (const void *p) 163132718Skan{ 164169689Skan const struct cgraph_node *n = (const struct cgraph_node *) p; 165169689Skan return (hashval_t) DECL_UID (n->decl); 166132718Skan} 167132718Skan 168132718Skan/* Returns nonzero if P1 and P2 are equal. */ 169132718Skan 170132718Skanstatic int 171132718Skaneq_node (const void *p1, const void *p2) 172132718Skan{ 173169689Skan const struct cgraph_node *n1 = (const struct cgraph_node *) p1; 174169689Skan const struct cgraph_node *n2 = (const struct cgraph_node *) p2; 175169689Skan return DECL_UID (n1->decl) == DECL_UID (n2->decl); 176132718Skan} 177132718Skan 178169689Skan/* Allocate new callgraph node and insert it into basic data structures. */ 179169689Skanstatic struct cgraph_node * 180169689Skancgraph_create_node (void) 181169689Skan{ 182169689Skan struct cgraph_node *node; 183169689Skan 184169689Skan node = GGC_CNEW (struct cgraph_node); 185169689Skan node->next = cgraph_nodes; 186169689Skan node->uid = cgraph_max_uid++; 187169689Skan node->order = cgraph_order++; 188169689Skan if (cgraph_nodes) 189169689Skan cgraph_nodes->previous = node; 190169689Skan node->previous = NULL; 191169689Skan node->global.estimated_growth = INT_MIN; 192169689Skan cgraph_nodes = node; 193169689Skan cgraph_n_nodes++; 194169689Skan return node; 195169689Skan} 196169689Skan 197132718Skan/* Return cgraph node assigned to DECL. Create new one when needed. */ 198132718Skanstruct cgraph_node * 199132718Skancgraph_node (tree decl) 200132718Skan{ 201169689Skan struct cgraph_node key, *node, **slot; 202132718Skan 203169689Skan gcc_assert (TREE_CODE (decl) == FUNCTION_DECL); 204132718Skan 205132718Skan if (!cgraph_hash) 206132718Skan cgraph_hash = htab_create_ggc (10, hash_node, eq_node, NULL); 207132718Skan 208169689Skan key.decl = decl; 209169689Skan 210169689Skan slot = (struct cgraph_node **) htab_find_slot (cgraph_hash, &key, INSERT); 211169689Skan 212132718Skan if (*slot) 213169689Skan { 214169689Skan node = *slot; 215169689Skan if (!node->master_clone) 216169689Skan node->master_clone = node; 217169689Skan return node; 218169689Skan } 219169689Skan 220169689Skan node = cgraph_create_node (); 221132718Skan node->decl = decl; 222132718Skan *slot = node; 223132718Skan if (DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL) 224132718Skan { 225132718Skan node->origin = cgraph_node (DECL_CONTEXT (decl)); 226132718Skan node->next_nested = node->origin->nested; 227132718Skan node->origin->nested = node; 228169689Skan node->master_clone = node; 229132718Skan } 230132718Skan return node; 231132718Skan} 232132718Skan 233169689Skan/* Insert already constructed node into hashtable. */ 234169689Skan 235169689Skanvoid 236169689Skancgraph_insert_node_to_hashtable (struct cgraph_node *node) 237132718Skan{ 238132718Skan struct cgraph_node **slot; 239132718Skan 240169689Skan slot = (struct cgraph_node **) htab_find_slot (cgraph_hash, node, INSERT); 241132718Skan 242169689Skan gcc_assert (!*slot); 243169689Skan *slot = node; 244169689Skan} 245132718Skan 246169689Skan/* Compare ASMNAME with the DECL_ASSEMBLER_NAME of DECL. */ 247169689Skan 248169689Skanstatic bool 249169689Skandecl_assembler_name_equal (tree decl, tree asmname) 250169689Skan{ 251169689Skan tree decl_asmname = DECL_ASSEMBLER_NAME (decl); 252169689Skan 253169689Skan if (decl_asmname == asmname) 254169689Skan return true; 255169689Skan 256169689Skan /* If the target assembler name was set by the user, things are trickier. 257169689Skan We have a leading '*' to begin with. After that, it's arguable what 258169689Skan is the correct thing to do with -fleading-underscore. Arguably, we've 259169689Skan historically been doing the wrong thing in assemble_alias by always 260169689Skan printing the leading underscore. Since we're not changing that, make 261169689Skan sure user_label_prefix follows the '*' before matching. */ 262169689Skan if (IDENTIFIER_POINTER (decl_asmname)[0] == '*') 263169689Skan { 264169689Skan const char *decl_str = IDENTIFIER_POINTER (decl_asmname) + 1; 265169689Skan size_t ulp_len = strlen (user_label_prefix); 266169689Skan 267169689Skan if (ulp_len == 0) 268169689Skan ; 269169689Skan else if (strncmp (decl_str, user_label_prefix, ulp_len) == 0) 270169689Skan decl_str += ulp_len; 271169689Skan else 272169689Skan return false; 273169689Skan 274169689Skan return strcmp (decl_str, IDENTIFIER_POINTER (asmname)) == 0; 275169689Skan } 276169689Skan 277169689Skan return false; 278132718Skan} 279132718Skan 280169689Skan 281169689Skan/* Return the cgraph node that has ASMNAME for its DECL_ASSEMBLER_NAME. 282169689Skan Return NULL if there's no such node. */ 283169689Skan 284169689Skanstruct cgraph_node * 285169689Skancgraph_node_for_asm (tree asmname) 286169689Skan{ 287169689Skan struct cgraph_node *node; 288169689Skan 289169689Skan for (node = cgraph_nodes; node ; node = node->next) 290169689Skan if (decl_assembler_name_equal (node->decl, asmname)) 291169689Skan return node; 292169689Skan 293169689Skan return NULL; 294169689Skan} 295169689Skan 296169689Skan/* Returns a hash value for X (which really is a die_struct). */ 297169689Skan 298169689Skanstatic hashval_t 299169689Skanedge_hash (const void *x) 300169689Skan{ 301169689Skan return htab_hash_pointer (((struct cgraph_edge *) x)->call_stmt); 302169689Skan} 303169689Skan 304169689Skan/* Return nonzero if decl_id of die_struct X is the same as UID of decl *Y. */ 305169689Skan 306169689Skanstatic int 307169689Skanedge_eq (const void *x, const void *y) 308169689Skan{ 309169689Skan return ((struct cgraph_edge *) x)->call_stmt == y; 310169689Skan} 311169689Skan 312169689Skan/* Return callgraph edge representing CALL_EXPR statement. */ 313169689Skanstruct cgraph_edge * 314169689Skancgraph_edge (struct cgraph_node *node, tree call_stmt) 315169689Skan{ 316169689Skan struct cgraph_edge *e, *e2; 317169689Skan int n = 0; 318169689Skan 319169689Skan if (node->call_site_hash) 320169689Skan return htab_find_with_hash (node->call_site_hash, call_stmt, 321169689Skan htab_hash_pointer (call_stmt)); 322169689Skan 323169689Skan /* This loop may turn out to be performance problem. In such case adding 324169689Skan hashtables into call nodes with very many edges is probably best 325169689Skan solution. It is not good idea to add pointer into CALL_EXPR itself 326169689Skan because we want to make possible having multiple cgraph nodes representing 327169689Skan different clones of the same body before the body is actually cloned. */ 328169689Skan for (e = node->callees; e; e= e->next_callee) 329169689Skan { 330169689Skan if (e->call_stmt == call_stmt) 331169689Skan break; 332169689Skan n++; 333169689Skan } 334169689Skan if (n > 100) 335169689Skan { 336169689Skan node->call_site_hash = htab_create_ggc (120, edge_hash, edge_eq, NULL); 337169689Skan for (e2 = node->callees; e2; e2 = e2->next_callee) 338169689Skan { 339169689Skan void **slot; 340169689Skan slot = htab_find_slot_with_hash (node->call_site_hash, 341169689Skan e2->call_stmt, 342169689Skan htab_hash_pointer (e2->call_stmt), 343169689Skan INSERT); 344169689Skan gcc_assert (!*slot); 345169689Skan *slot = e2; 346169689Skan } 347169689Skan } 348169689Skan return e; 349169689Skan} 350169689Skan 351169689Skan/* Change call_smtt of edge E to NEW_STMT. */ 352169689Skanvoid 353169689Skancgraph_set_call_stmt (struct cgraph_edge *e, tree new_stmt) 354169689Skan{ 355169689Skan if (e->caller->call_site_hash) 356169689Skan { 357169689Skan htab_remove_elt_with_hash (e->caller->call_site_hash, 358169689Skan e->call_stmt, 359169689Skan htab_hash_pointer (e->call_stmt)); 360169689Skan } 361169689Skan e->call_stmt = new_stmt; 362169689Skan if (e->caller->call_site_hash) 363169689Skan { 364169689Skan void **slot; 365169689Skan slot = htab_find_slot_with_hash (e->caller->call_site_hash, 366169689Skan e->call_stmt, 367169689Skan htab_hash_pointer 368169689Skan (e->call_stmt), INSERT); 369169689Skan gcc_assert (!*slot); 370169689Skan *slot = e; 371169689Skan } 372169689Skan} 373169689Skan 374132718Skan/* Create edge from CALLER to CALLEE in the cgraph. */ 375132718Skan 376169689Skanstruct cgraph_edge * 377169689Skancgraph_create_edge (struct cgraph_node *caller, struct cgraph_node *callee, 378169689Skan tree call_stmt, gcov_type count, int nest) 379132718Skan{ 380169689Skan struct cgraph_edge *edge = GGC_NEW (struct cgraph_edge); 381169689Skan#ifdef ENABLE_CHECKING 382169689Skan struct cgraph_edge *e; 383132718Skan 384169689Skan for (e = caller->callees; e; e = e->next_callee) 385169689Skan gcc_assert (e->call_stmt != call_stmt); 386169689Skan#endif 387169689Skan 388169689Skan gcc_assert (get_call_expr_in (call_stmt)); 389169689Skan 390132718Skan if (!DECL_SAVED_TREE (callee->decl)) 391132718Skan edge->inline_failed = N_("function body not available"); 392132718Skan else if (callee->local.redefined_extern_inline) 393132718Skan edge->inline_failed = N_("redefined extern inline functions are not " 394132718Skan "considered for inlining"); 395132718Skan else if (callee->local.inlinable) 396132718Skan edge->inline_failed = N_("function not considered for inlining"); 397132718Skan else 398132718Skan edge->inline_failed = N_("function not inlinable"); 399132718Skan 400169689Skan edge->aux = NULL; 401132718Skan 402132718Skan edge->caller = caller; 403132718Skan edge->callee = callee; 404169689Skan edge->call_stmt = call_stmt; 405169689Skan edge->prev_caller = NULL; 406132718Skan edge->next_caller = callee->callers; 407169689Skan if (callee->callers) 408169689Skan callee->callers->prev_caller = edge; 409169689Skan edge->prev_callee = NULL; 410132718Skan edge->next_callee = caller->callees; 411169689Skan if (caller->callees) 412169689Skan caller->callees->prev_callee = edge; 413132718Skan caller->callees = edge; 414132718Skan callee->callers = edge; 415169689Skan edge->count = count; 416169689Skan edge->loop_nest = nest; 417169689Skan if (caller->call_site_hash) 418169689Skan { 419169689Skan void **slot; 420169689Skan slot = htab_find_slot_with_hash (caller->call_site_hash, 421169689Skan edge->call_stmt, 422169689Skan htab_hash_pointer 423169689Skan (edge->call_stmt), 424169689Skan INSERT); 425169689Skan gcc_assert (!*slot); 426169689Skan *slot = edge; 427169689Skan } 428132718Skan return edge; 429132718Skan} 430132718Skan 431169689Skan/* Remove the edge E from the list of the callers of the callee. */ 432132718Skan 433169689Skanstatic inline void 434169689Skancgraph_edge_remove_callee (struct cgraph_edge *e) 435169689Skan{ 436169689Skan if (e->prev_caller) 437169689Skan e->prev_caller->next_caller = e->next_caller; 438169689Skan if (e->next_caller) 439169689Skan e->next_caller->prev_caller = e->prev_caller; 440169689Skan if (!e->prev_caller) 441169689Skan e->callee->callers = e->next_caller; 442169689Skan} 443169689Skan 444169689Skan/* Remove the edge E from the list of the callees of the caller. */ 445169689Skan 446169689Skanstatic inline void 447169689Skancgraph_edge_remove_caller (struct cgraph_edge *e) 448169689Skan{ 449169689Skan if (e->prev_callee) 450169689Skan e->prev_callee->next_callee = e->next_callee; 451169689Skan if (e->next_callee) 452169689Skan e->next_callee->prev_callee = e->prev_callee; 453169689Skan if (!e->prev_callee) 454169689Skan e->caller->callees = e->next_callee; 455169689Skan if (e->caller->call_site_hash) 456169689Skan htab_remove_elt_with_hash (e->caller->call_site_hash, 457169689Skan e->call_stmt, 458169689Skan htab_hash_pointer (e->call_stmt)); 459169689Skan} 460169689Skan 461169689Skan/* Remove the edge E in the cgraph. */ 462169689Skan 463132718Skanvoid 464169689Skancgraph_remove_edge (struct cgraph_edge *e) 465132718Skan{ 466169689Skan /* Remove from callers list of the callee. */ 467169689Skan cgraph_edge_remove_callee (e); 468132718Skan 469169689Skan /* Remove from callees list of the callers. */ 470169689Skan cgraph_edge_remove_caller (e); 471132718Skan} 472132718Skan 473169689Skan/* Redirect callee of E to N. The function does not update underlying 474169689Skan call expression. */ 475169689Skan 476169689Skanvoid 477169689Skancgraph_redirect_edge_callee (struct cgraph_edge *e, struct cgraph_node *n) 478169689Skan{ 479169689Skan /* Remove from callers list of the current callee. */ 480169689Skan cgraph_edge_remove_callee (e); 481169689Skan 482169689Skan /* Insert to callers list of the new callee. */ 483169689Skan e->prev_caller = NULL; 484169689Skan if (n->callers) 485169689Skan n->callers->prev_caller = e; 486169689Skan e->next_caller = n->callers; 487169689Skan n->callers = e; 488169689Skan e->callee = n; 489169689Skan} 490169689Skan 491169689Skan/* Remove all callees from the node. */ 492169689Skan 493169689Skanvoid 494169689Skancgraph_node_remove_callees (struct cgraph_node *node) 495169689Skan{ 496169689Skan struct cgraph_edge *e; 497169689Skan 498169689Skan /* It is sufficient to remove the edges from the lists of callers of 499169689Skan the callees. The callee list of the node can be zapped with one 500169689Skan assignment. */ 501169689Skan for (e = node->callees; e; e = e->next_callee) 502169689Skan cgraph_edge_remove_callee (e); 503169689Skan node->callees = NULL; 504169689Skan if (node->call_site_hash) 505169689Skan { 506169689Skan htab_delete (node->call_site_hash); 507169689Skan node->call_site_hash = NULL; 508169689Skan } 509169689Skan} 510169689Skan 511169689Skan/* Remove all callers from the node. */ 512169689Skan 513169689Skanstatic void 514169689Skancgraph_node_remove_callers (struct cgraph_node *node) 515169689Skan{ 516169689Skan struct cgraph_edge *e; 517169689Skan 518169689Skan /* It is sufficient to remove the edges from the lists of callees of 519169689Skan the callers. The caller list of the node can be zapped with one 520169689Skan assignment. */ 521169689Skan for (e = node->callers; e; e = e->next_caller) 522169689Skan cgraph_edge_remove_caller (e); 523169689Skan node->callers = NULL; 524169689Skan} 525169689Skan 526132718Skan/* Remove the node from cgraph. */ 527132718Skan 528132718Skanvoid 529132718Skancgraph_remove_node (struct cgraph_node *node) 530132718Skan{ 531132718Skan void **slot; 532169689Skan bool kill_body = false; 533169689Skan 534169689Skan cgraph_node_remove_callers (node); 535169689Skan cgraph_node_remove_callees (node); 536169689Skan /* Incremental inlining access removed nodes stored in the postorder list. 537169689Skan */ 538169689Skan node->needed = node->reachable = false; 539132718Skan while (node->nested) 540132718Skan cgraph_remove_node (node->nested); 541132718Skan if (node->origin) 542132718Skan { 543132718Skan struct cgraph_node **node2 = &node->origin->nested; 544132718Skan 545132718Skan while (*node2 != node) 546132718Skan node2 = &(*node2)->next_nested; 547132718Skan *node2 = node->next_nested; 548132718Skan } 549132718Skan if (node->previous) 550132718Skan node->previous->next = node->next; 551132718Skan else 552132718Skan cgraph_nodes = node->next; 553132718Skan if (node->next) 554132718Skan node->next->previous = node->previous; 555169689Skan node->next = NULL; 556169689Skan node->previous = NULL; 557169689Skan slot = htab_find_slot (cgraph_hash, node, NO_INSERT); 558169689Skan if (*slot == node) 559132718Skan { 560169689Skan if (node->next_clone) 561169689Skan { 562169689Skan struct cgraph_node *new_node = node->next_clone; 563169689Skan struct cgraph_node *n; 564169689Skan 565169689Skan /* Make the next clone be the master clone */ 566169689Skan for (n = new_node; n; n = n->next_clone) 567169689Skan n->master_clone = new_node; 568169689Skan 569169689Skan *slot = new_node; 570169689Skan node->next_clone->prev_clone = NULL; 571169689Skan } 572169689Skan else 573169689Skan { 574169689Skan htab_clear_slot (cgraph_hash, slot); 575169689Skan kill_body = true; 576169689Skan } 577132718Skan } 578132718Skan else 579169689Skan { 580169689Skan node->prev_clone->next_clone = node->next_clone; 581169689Skan if (node->next_clone) 582169689Skan node->next_clone->prev_clone = node->prev_clone; 583169689Skan } 584169689Skan 585169689Skan /* While all the clones are removed after being proceeded, the function 586169689Skan itself is kept in the cgraph even after it is compiled. Check whether 587169689Skan we are done with this body and reclaim it proactively if this is the case. 588169689Skan */ 589169689Skan if (!kill_body && *slot) 590169689Skan { 591169689Skan struct cgraph_node *n = (struct cgraph_node *) *slot; 592169689Skan if (!n->next_clone && !n->global.inlined_to 593169689Skan && (cgraph_global_info_ready 594169689Skan && (TREE_ASM_WRITTEN (n->decl) || DECL_EXTERNAL (n->decl)))) 595169689Skan kill_body = true; 596169689Skan } 597169689Skan 598169689Skan if (kill_body && flag_unit_at_a_time) 599169689Skan { 600169689Skan DECL_SAVED_TREE (node->decl) = NULL; 601169689Skan DECL_STRUCT_FUNCTION (node->decl) = NULL; 602169689Skan DECL_INITIAL (node->decl) = error_mark_node; 603169689Skan } 604169689Skan node->decl = NULL; 605169689Skan if (node->call_site_hash) 606169689Skan { 607169689Skan htab_delete (node->call_site_hash); 608169689Skan node->call_site_hash = NULL; 609169689Skan } 610169689Skan cgraph_n_nodes--; 611132718Skan /* Do not free the structure itself so the walk over chain can continue. */ 612132718Skan} 613132718Skan 614132718Skan/* Notify finalize_compilation_unit that given node is reachable. */ 615132718Skan 616132718Skanvoid 617132718Skancgraph_mark_reachable_node (struct cgraph_node *node) 618132718Skan{ 619132718Skan if (!node->reachable && node->local.finalized) 620132718Skan { 621132718Skan notice_global_symbol (node->decl); 622132718Skan node->reachable = 1; 623169689Skan gcc_assert (!cgraph_global_info_ready); 624132718Skan 625132718Skan node->next_needed = cgraph_nodes_queue; 626132718Skan cgraph_nodes_queue = node; 627132718Skan } 628132718Skan} 629132718Skan 630132718Skan/* Likewise indicate that a node is needed, i.e. reachable via some 631132718Skan external means. */ 632132718Skan 633132718Skanvoid 634132718Skancgraph_mark_needed_node (struct cgraph_node *node) 635132718Skan{ 636132718Skan node->needed = 1; 637132718Skan cgraph_mark_reachable_node (node); 638132718Skan} 639132718Skan 640132718Skan/* Return local info for the compiled function. */ 641132718Skan 642132718Skanstruct cgraph_local_info * 643132718Skancgraph_local_info (tree decl) 644132718Skan{ 645132718Skan struct cgraph_node *node; 646169689Skan 647169689Skan gcc_assert (TREE_CODE (decl) == FUNCTION_DECL); 648132718Skan node = cgraph_node (decl); 649132718Skan return &node->local; 650132718Skan} 651132718Skan 652132718Skan/* Return local info for the compiled function. */ 653132718Skan 654132718Skanstruct cgraph_global_info * 655132718Skancgraph_global_info (tree decl) 656132718Skan{ 657132718Skan struct cgraph_node *node; 658169689Skan 659169689Skan gcc_assert (TREE_CODE (decl) == FUNCTION_DECL && cgraph_global_info_ready); 660132718Skan node = cgraph_node (decl); 661132718Skan return &node->global; 662132718Skan} 663132718Skan 664132718Skan/* Return local info for the compiled function. */ 665132718Skan 666132718Skanstruct cgraph_rtl_info * 667132718Skancgraph_rtl_info (tree decl) 668132718Skan{ 669132718Skan struct cgraph_node *node; 670169689Skan 671169689Skan gcc_assert (TREE_CODE (decl) == FUNCTION_DECL); 672132718Skan node = cgraph_node (decl); 673132718Skan if (decl != current_function_decl 674132718Skan && !TREE_ASM_WRITTEN (node->decl)) 675132718Skan return NULL; 676132718Skan return &node->rtl; 677132718Skan} 678132718Skan 679132718Skan/* Return name of the node used in debug output. */ 680132718Skanconst char * 681132718Skancgraph_node_name (struct cgraph_node *node) 682132718Skan{ 683169689Skan return lang_hooks.decl_printable_name (node->decl, 2); 684132718Skan} 685132718Skan 686169689Skan/* Return name of the node used in debug output. */ 687169689Skanstatic const char * 688169689Skancgraph_varpool_node_name (struct cgraph_varpool_node *node) 689169689Skan{ 690169689Skan return lang_hooks.decl_printable_name (node->decl, 2); 691169689Skan} 692169689Skan 693169689Skan/* Names used to print out the availability enum. */ 694169689Skanstatic const char * const availability_names[] = 695169689Skan {"unset", "not_available", "overwrittable", "available", "local"}; 696169689Skan 697169689Skan/* Dump given cgraph node. */ 698169689Skanvoid 699169689Skandump_cgraph_node (FILE *f, struct cgraph_node *node) 700169689Skan{ 701169689Skan struct cgraph_edge *edge; 702169689Skan fprintf (f, "%s/%i:", cgraph_node_name (node), node->uid); 703169689Skan if (node->global.inlined_to) 704169689Skan fprintf (f, " (inline copy in %s/%i)", 705169689Skan cgraph_node_name (node->global.inlined_to), 706169689Skan node->global.inlined_to->uid); 707169689Skan if (cgraph_function_flags_ready) 708169689Skan fprintf (f, " availability:%s", 709169689Skan availability_names [cgraph_function_body_availability (node)]); 710169689Skan if (node->master_clone && node->master_clone->uid != node->uid) 711169689Skan fprintf (f, "(%i)", node->master_clone->uid); 712169689Skan if (node->count) 713169689Skan fprintf (f, " executed "HOST_WIDEST_INT_PRINT_DEC"x", 714169689Skan (HOST_WIDEST_INT)node->count); 715169689Skan if (node->local.self_insns) 716169689Skan fprintf (f, " %i insns", node->local.self_insns); 717169689Skan if (node->global.insns && node->global.insns != node->local.self_insns) 718169689Skan fprintf (f, " (%i after inlining)", node->global.insns); 719169689Skan if (node->origin) 720169689Skan fprintf (f, " nested in: %s", cgraph_node_name (node->origin)); 721169689Skan if (node->needed) 722169689Skan fprintf (f, " needed"); 723169689Skan else if (node->reachable) 724169689Skan fprintf (f, " reachable"); 725169689Skan if (DECL_SAVED_TREE (node->decl)) 726169689Skan fprintf (f, " tree"); 727169689Skan if (node->output) 728169689Skan fprintf (f, " output"); 729169689Skan if (node->local.local) 730169689Skan fprintf (f, " local"); 731169689Skan if (node->local.externally_visible) 732169689Skan fprintf (f, " externally_visible"); 733169689Skan if (node->local.finalized) 734169689Skan fprintf (f, " finalized"); 735169689Skan if (node->local.disregard_inline_limits) 736169689Skan fprintf (f, " always_inline"); 737169689Skan else if (node->local.inlinable) 738169689Skan fprintf (f, " inlinable"); 739169689Skan if (node->local.redefined_extern_inline) 740169689Skan fprintf (f, " redefined_extern_inline"); 741169689Skan if (TREE_ASM_WRITTEN (node->decl)) 742169689Skan fprintf (f, " asm_written"); 743169689Skan 744169689Skan fprintf (f, "\n called by: "); 745169689Skan for (edge = node->callers; edge; edge = edge->next_caller) 746169689Skan { 747169689Skan fprintf (f, "%s/%i ", cgraph_node_name (edge->caller), 748169689Skan edge->caller->uid); 749169689Skan if (edge->count) 750169689Skan fprintf (f, "("HOST_WIDEST_INT_PRINT_DEC"x) ", 751169689Skan (HOST_WIDEST_INT)edge->count); 752169689Skan if (!edge->inline_failed) 753169689Skan fprintf(f, "(inlined) "); 754169689Skan } 755169689Skan 756169689Skan fprintf (f, "\n calls: "); 757169689Skan for (edge = node->callees; edge; edge = edge->next_callee) 758169689Skan { 759169689Skan fprintf (f, "%s/%i ", cgraph_node_name (edge->callee), 760169689Skan edge->callee->uid); 761169689Skan if (!edge->inline_failed) 762169689Skan fprintf(f, "(inlined) "); 763169689Skan if (edge->count) 764169689Skan fprintf (f, "("HOST_WIDEST_INT_PRINT_DEC"x) ", 765169689Skan (HOST_WIDEST_INT)edge->count); 766169689Skan if (edge->loop_nest) 767169689Skan fprintf (f, "(nested in %i loops) ", edge->loop_nest); 768169689Skan } 769169689Skan fprintf (f, "\n"); 770169689Skan} 771169689Skan 772132718Skan/* Dump the callgraph. */ 773132718Skan 774132718Skanvoid 775132718Skandump_cgraph (FILE *f) 776132718Skan{ 777132718Skan struct cgraph_node *node; 778132718Skan 779132718Skan fprintf (f, "callgraph:\n\n"); 780132718Skan for (node = cgraph_nodes; node; node = node->next) 781169689Skan dump_cgraph_node (f, node); 782169689Skan} 783132718Skan 784169689Skan/* Dump given cgraph node. */ 785169689Skanvoid 786169689Skandump_cgraph_varpool_node (FILE *f, struct cgraph_varpool_node *node) 787169689Skan{ 788169689Skan fprintf (f, "%s:", cgraph_varpool_node_name (node)); 789169689Skan fprintf (f, " availability:%s", 790169689Skan cgraph_function_flags_ready 791169689Skan ? availability_names[cgraph_variable_initializer_availability (node)] 792169689Skan : "not-ready"); 793169689Skan if (DECL_INITIAL (node->decl)) 794169689Skan fprintf (f, " initialized"); 795169689Skan if (node->needed) 796169689Skan fprintf (f, " needed"); 797169689Skan if (node->analyzed) 798169689Skan fprintf (f, " analyzed"); 799169689Skan if (node->finalized) 800169689Skan fprintf (f, " finalized"); 801169689Skan if (node->output) 802169689Skan fprintf (f, " output"); 803169689Skan if (node->externally_visible) 804169689Skan fprintf (f, " externally_visible"); 805169689Skan fprintf (f, "\n"); 806169689Skan} 807132718Skan 808169689Skan/* Dump the callgraph. */ 809132718Skan 810169689Skanvoid 811169689Skandump_varpool (FILE *f) 812169689Skan{ 813169689Skan struct cgraph_varpool_node *node; 814169689Skan 815169689Skan fprintf (f, "variable pool:\n\n"); 816169689Skan for (node = cgraph_varpool_nodes; node; node = node->next_needed) 817169689Skan dump_cgraph_varpool_node (f, node); 818132718Skan} 819132718Skan 820132718Skan/* Returns a hash code for P. */ 821132718Skan 822132718Skanstatic hashval_t 823169689Skanhash_varpool_node (const void *p) 824132718Skan{ 825169689Skan const struct cgraph_varpool_node *n = (const struct cgraph_varpool_node *) p; 826169689Skan return (hashval_t) DECL_UID (n->decl); 827132718Skan} 828132718Skan 829132718Skan/* Returns nonzero if P1 and P2 are equal. */ 830132718Skan 831132718Skanstatic int 832169689Skaneq_varpool_node (const void *p1, const void *p2) 833132718Skan{ 834169689Skan const struct cgraph_varpool_node *n1 = 835169689Skan (const struct cgraph_varpool_node *) p1; 836169689Skan const struct cgraph_varpool_node *n2 = 837169689Skan (const struct cgraph_varpool_node *) p2; 838169689Skan return DECL_UID (n1->decl) == DECL_UID (n2->decl); 839132718Skan} 840132718Skan 841132718Skan/* Return cgraph_varpool node assigned to DECL. Create new one when needed. */ 842132718Skanstruct cgraph_varpool_node * 843132718Skancgraph_varpool_node (tree decl) 844132718Skan{ 845169689Skan struct cgraph_varpool_node key, *node, **slot; 846132718Skan 847169689Skan gcc_assert (DECL_P (decl) && TREE_CODE (decl) != FUNCTION_DECL); 848132718Skan 849132718Skan if (!cgraph_varpool_hash) 850169689Skan cgraph_varpool_hash = htab_create_ggc (10, hash_varpool_node, 851169689Skan eq_varpool_node, NULL); 852169689Skan key.decl = decl; 853132718Skan slot = (struct cgraph_varpool_node **) 854169689Skan htab_find_slot (cgraph_varpool_hash, &key, INSERT); 855132718Skan if (*slot) 856132718Skan return *slot; 857169689Skan node = GGC_CNEW (struct cgraph_varpool_node); 858132718Skan node->decl = decl; 859169689Skan node->order = cgraph_order++; 860169689Skan node->next = cgraph_varpool_nodes; 861132718Skan cgraph_varpool_nodes = node; 862132718Skan *slot = node; 863132718Skan return node; 864132718Skan} 865132718Skan 866169689Skanstruct cgraph_varpool_node * 867169689Skancgraph_varpool_node_for_asm (tree asmname) 868169689Skan{ 869169689Skan struct cgraph_varpool_node *node; 870169689Skan 871169689Skan for (node = cgraph_varpool_nodes; node ; node = node->next) 872169689Skan if (decl_assembler_name_equal (node->decl, asmname)) 873169689Skan return node; 874169689Skan 875169689Skan return NULL; 876169689Skan} 877169689Skan 878132718Skan/* Set the DECL_ASSEMBLER_NAME and update cgraph hashtables. */ 879132718Skanvoid 880132718Skanchange_decl_assembler_name (tree decl, tree name) 881132718Skan{ 882132718Skan if (!DECL_ASSEMBLER_NAME_SET_P (decl)) 883132718Skan { 884132718Skan SET_DECL_ASSEMBLER_NAME (decl, name); 885132718Skan return; 886132718Skan } 887132718Skan if (name == DECL_ASSEMBLER_NAME (decl)) 888132718Skan return; 889132718Skan 890132718Skan if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) 891132718Skan && DECL_RTL_SET_P (decl)) 892169689Skan warning (0, "%D renamed after being referenced in assembly", decl); 893132718Skan 894132718Skan SET_DECL_ASSEMBLER_NAME (decl, name); 895132718Skan} 896132718Skan 897169689Skan/* Helper function for finalization code - add node into lists so it will 898169689Skan be analyzed and compiled. */ 899169689Skanvoid 900169689Skancgraph_varpool_enqueue_needed_node (struct cgraph_varpool_node *node) 901132718Skan{ 902169689Skan if (cgraph_varpool_last_needed_node) 903169689Skan cgraph_varpool_last_needed_node->next_needed = node; 904169689Skan cgraph_varpool_last_needed_node = node; 905169689Skan node->next_needed = NULL; 906169689Skan if (!cgraph_varpool_nodes_queue) 907169689Skan cgraph_varpool_nodes_queue = node; 908169689Skan if (!cgraph_varpool_first_unanalyzed_node) 909169689Skan cgraph_varpool_first_unanalyzed_node = node; 910169689Skan notice_global_symbol (node->decl); 911169689Skan} 912132718Skan 913169689Skan/* Reset the queue of needed nodes. */ 914169689Skanvoid 915169689Skancgraph_varpool_reset_queue (void) 916169689Skan{ 917169689Skan cgraph_varpool_last_needed_node = NULL; 918169689Skan cgraph_varpool_nodes_queue = NULL; 919169689Skan cgraph_varpool_first_unanalyzed_node = NULL; 920132718Skan} 921132718Skan 922132718Skan/* Notify finalize_compilation_unit that given node is reachable 923132718Skan or needed. */ 924132718Skanvoid 925132718Skancgraph_varpool_mark_needed_node (struct cgraph_varpool_node *node) 926132718Skan{ 927169689Skan if (!node->needed && node->finalized 928169689Skan && !TREE_ASM_WRITTEN (node->decl)) 929169689Skan cgraph_varpool_enqueue_needed_node (node); 930132718Skan node->needed = 1; 931132718Skan} 932132718Skan 933169689Skan/* Determine if variable DECL is needed. That is, visible to something 934169689Skan either outside this translation unit, something magic in the system 935169689Skan configury, or (if not doing unit-at-a-time) to something we haven't 936169689Skan seen yet. */ 937169689Skan 938169689Skanbool 939169689Skandecide_is_variable_needed (struct cgraph_varpool_node *node, tree decl) 940169689Skan{ 941169689Skan /* If the user told us it is used, then it must be so. */ 942169689Skan if (node->externally_visible) 943169689Skan return true; 944169689Skan if (!flag_unit_at_a_time 945169689Skan && lookup_attribute ("used", DECL_ATTRIBUTES (decl))) 946169689Skan return true; 947169689Skan 948169689Skan /* ??? If the assembler name is set by hand, it is possible to assemble 949169689Skan the name later after finalizing the function and the fact is noticed 950169689Skan in assemble_name then. This is arguably a bug. */ 951169689Skan if (DECL_ASSEMBLER_NAME_SET_P (decl) 952169689Skan && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) 953169689Skan return true; 954169689Skan 955169689Skan /* If we decided it was needed before, but at the time we didn't have 956169689Skan the definition available, then it's still needed. */ 957169689Skan if (node->needed) 958169689Skan return true; 959169689Skan 960169689Skan /* Externally visible variables must be output. The exception is 961169689Skan COMDAT variables that must be output only when they are needed. */ 962169689Skan if (TREE_PUBLIC (decl) && !flag_whole_program && !DECL_COMDAT (decl) 963169689Skan && !DECL_EXTERNAL (decl)) 964169689Skan return true; 965169689Skan 966169689Skan /* When not reordering top level variables, we have to assume that 967169689Skan we are going to keep everything. */ 968169689Skan if (flag_unit_at_a_time && flag_toplevel_reorder) 969169689Skan return false; 970169689Skan 971169689Skan /* We want to emit COMDAT variables only when absolutely necessary. */ 972169689Skan if (DECL_COMDAT (decl)) 973169689Skan return false; 974169689Skan return true; 975169689Skan} 976169689Skan 977132718Skanvoid 978132718Skancgraph_varpool_finalize_decl (tree decl) 979132718Skan{ 980132718Skan struct cgraph_varpool_node *node = cgraph_varpool_node (decl); 981169689Skan 982132718Skan /* The first declaration of a variable that comes through this function 983132718Skan decides whether it is global (in C, has external linkage) 984132718Skan or local (in C, has internal linkage). So do nothing more 985132718Skan if this function has already run. */ 986132718Skan if (node->finalized) 987132718Skan { 988169689Skan if (cgraph_global_info_ready || (!flag_unit_at_a_time && !flag_openmp)) 989169689Skan cgraph_varpool_assemble_pending_decls (); 990169689Skan return; 991132718Skan } 992169689Skan if (node->needed) 993169689Skan cgraph_varpool_enqueue_needed_node (node); 994132718Skan node->finalized = true; 995132718Skan 996169689Skan if (decide_is_variable_needed (node, decl)) 997169689Skan cgraph_varpool_mark_needed_node (node); 998169689Skan /* Since we reclaim unreachable nodes at the end of every language 999169689Skan level unit, we need to be conservative about possible entry points 1000169689Skan there. */ 1001169689Skan else if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl)) 1002169689Skan cgraph_varpool_mark_needed_node (node); 1003169689Skan if (cgraph_global_info_ready || (!flag_unit_at_a_time && !flag_openmp)) 1004169689Skan cgraph_varpool_assemble_pending_decls (); 1005169689Skan} 1006169689Skan 1007169689Skan/* Add a top-level asm statement to the list. */ 1008169689Skan 1009169689Skanstruct cgraph_asm_node * 1010169689Skancgraph_add_asm_node (tree asm_str) 1011169689Skan{ 1012169689Skan struct cgraph_asm_node *node; 1013169689Skan 1014169689Skan node = GGC_CNEW (struct cgraph_asm_node); 1015169689Skan node->asm_str = asm_str; 1016169689Skan node->order = cgraph_order++; 1017169689Skan node->next = NULL; 1018169689Skan if (cgraph_asm_nodes == NULL) 1019169689Skan cgraph_asm_nodes = node; 1020169689Skan else 1021169689Skan cgraph_asm_last_node->next = node; 1022169689Skan cgraph_asm_last_node = node; 1023169689Skan return node; 1024169689Skan} 1025169689Skan 1026169689Skan/* Return true when the DECL can possibly be inlined. */ 1027169689Skanbool 1028169689Skancgraph_function_possibly_inlined_p (tree decl) 1029169689Skan{ 1030169689Skan if (!cgraph_global_info_ready) 1031169689Skan return (DECL_INLINE (decl) && !flag_really_no_inline); 1032169689Skan return DECL_POSSIBLY_INLINED (decl); 1033169689Skan} 1034169689Skan 1035169689Skan/* Create clone of E in the node N represented by CALL_EXPR the callgraph. */ 1036169689Skanstruct cgraph_edge * 1037169689Skancgraph_clone_edge (struct cgraph_edge *e, struct cgraph_node *n, 1038169689Skan tree call_stmt, gcov_type count_scale, int loop_nest, 1039169689Skan bool update_original) 1040169689Skan{ 1041169689Skan struct cgraph_edge *new; 1042169689Skan 1043169689Skan new = cgraph_create_edge (n, e->callee, call_stmt, 1044169689Skan e->count * count_scale / REG_BR_PROB_BASE, 1045169689Skan e->loop_nest + loop_nest); 1046169689Skan 1047169689Skan new->inline_failed = e->inline_failed; 1048169689Skan if (update_original) 1049132718Skan { 1050169689Skan e->count -= new->count; 1051169689Skan if (e->count < 0) 1052169689Skan e->count = 0; 1053132718Skan } 1054169689Skan return new; 1055132718Skan} 1056132718Skan 1057169689Skan/* Create node representing clone of N executed COUNT times. Decrease 1058169689Skan the execution counts from original node too. 1059169689Skan 1060169689Skan When UPDATE_ORIGINAL is true, the counts are subtracted from the original 1061169689Skan function's profile to reflect the fact that part of execution is handled 1062169689Skan by node. */ 1063169689Skanstruct cgraph_node * 1064169689Skancgraph_clone_node (struct cgraph_node *n, gcov_type count, int loop_nest, 1065169689Skan bool update_original) 1066132718Skan{ 1067169689Skan struct cgraph_node *new = cgraph_create_node (); 1068169689Skan struct cgraph_edge *e; 1069169689Skan gcov_type count_scale; 1070132718Skan 1071169689Skan new->decl = n->decl; 1072169689Skan new->origin = n->origin; 1073169689Skan if (new->origin) 1074132718Skan { 1075169689Skan new->next_nested = new->origin->nested; 1076169689Skan new->origin->nested = new; 1077169689Skan } 1078169689Skan new->analyzed = n->analyzed; 1079169689Skan new->local = n->local; 1080169689Skan new->global = n->global; 1081169689Skan new->rtl = n->rtl; 1082169689Skan new->master_clone = n->master_clone; 1083169689Skan new->count = count; 1084169689Skan if (n->count) 1085169689Skan count_scale = new->count * REG_BR_PROB_BASE / n->count; 1086169689Skan else 1087169689Skan count_scale = 0; 1088169689Skan if (update_original) 1089169689Skan { 1090169689Skan n->count -= count; 1091169689Skan if (n->count < 0) 1092169689Skan n->count = 0; 1093169689Skan } 1094132718Skan 1095169689Skan for (e = n->callees;e; e=e->next_callee) 1096169689Skan cgraph_clone_edge (e, new, e->call_stmt, count_scale, loop_nest, 1097169689Skan update_original); 1098169689Skan 1099169689Skan new->next_clone = n->next_clone; 1100169689Skan new->prev_clone = n; 1101169689Skan n->next_clone = new; 1102169689Skan if (new->next_clone) 1103169689Skan new->next_clone->prev_clone = new; 1104169689Skan 1105169689Skan return new; 1106132718Skan} 1107132718Skan 1108169689Skan/* Return true if N is an master_clone, (see cgraph_master_clone). */ 1109169689Skan 1110132718Skanbool 1111169689Skancgraph_is_master_clone (struct cgraph_node *n) 1112132718Skan{ 1113169689Skan return (n == cgraph_master_clone (n)); 1114132718Skan} 1115132718Skan 1116169689Skanstruct cgraph_node * 1117169689Skancgraph_master_clone (struct cgraph_node *n) 1118169689Skan{ 1119169689Skan enum availability avail = cgraph_function_body_availability (n); 1120169689Skan 1121169689Skan if (avail == AVAIL_NOT_AVAILABLE || avail == AVAIL_OVERWRITABLE) 1122169689Skan return NULL; 1123169689Skan 1124169689Skan if (!n->master_clone) 1125169689Skan n->master_clone = cgraph_node (n->decl); 1126169689Skan 1127169689Skan return n->master_clone; 1128169689Skan} 1129169689Skan 1130169689Skan/* NODE is no longer nested function; update cgraph accordingly. */ 1131169689Skanvoid 1132169689Skancgraph_unnest_node (struct cgraph_node *node) 1133169689Skan{ 1134169689Skan struct cgraph_node **node2 = &node->origin->nested; 1135169689Skan gcc_assert (node->origin); 1136169689Skan 1137169689Skan while (*node2 != node) 1138169689Skan node2 = &(*node2)->next_nested; 1139169689Skan *node2 = node->next_nested; 1140169689Skan node->origin = NULL; 1141169689Skan} 1142169689Skan 1143169689Skan/* Return function availability. See cgraph.h for description of individual 1144169689Skan return values. */ 1145169689Skanenum availability 1146169689Skancgraph_function_body_availability (struct cgraph_node *node) 1147169689Skan{ 1148169689Skan enum availability avail; 1149169689Skan gcc_assert (cgraph_function_flags_ready); 1150169689Skan if (!node->analyzed) 1151169689Skan avail = AVAIL_NOT_AVAILABLE; 1152169689Skan else if (node->local.local) 1153169689Skan avail = AVAIL_LOCAL; 1154169689Skan else if (node->local.externally_visible) 1155169689Skan avail = AVAIL_AVAILABLE; 1156169689Skan 1157169689Skan /* If the function can be overwritten, return OVERWRITABLE. Take 1158169689Skan care at least of two notable extensions - the COMDAT functions 1159169689Skan used to share template instantiations in C++ (this is symmetric 1160169689Skan to code cp_cannot_inline_tree_fn and probably shall be shared and 1161169689Skan the inlinability hooks completely eliminated). 1162169689Skan 1163169689Skan ??? Does the C++ one definition rule allow us to always return 1164169689Skan AVAIL_AVAILABLE here? That would be good reason to preserve this 1165169689Skan hook Similarly deal with extern inline functions - this is again 1166169689Skan necessary to get C++ shared functions having keyed templates 1167169689Skan right and in the C extension documentation we probably should 1168169689Skan document the requirement of both versions of function (extern 1169169689Skan inline and offline) having same side effect characteristics as 1170169689Skan good optimization is what this optimization is about. */ 1171169689Skan 1172169689Skan else if (!(*targetm.binds_local_p) (node->decl) 1173169689Skan && !DECL_COMDAT (node->decl) && !DECL_EXTERNAL (node->decl)) 1174169689Skan avail = AVAIL_OVERWRITABLE; 1175169689Skan else avail = AVAIL_AVAILABLE; 1176169689Skan 1177169689Skan return avail; 1178169689Skan} 1179169689Skan 1180169689Skan/* Return variable availability. See cgraph.h for description of individual 1181169689Skan return values. */ 1182169689Skanenum availability 1183169689Skancgraph_variable_initializer_availability (struct cgraph_varpool_node *node) 1184169689Skan{ 1185169689Skan gcc_assert (cgraph_function_flags_ready); 1186169689Skan if (!node->finalized) 1187169689Skan return AVAIL_NOT_AVAILABLE; 1188169689Skan if (!TREE_PUBLIC (node->decl)) 1189169689Skan return AVAIL_AVAILABLE; 1190169689Skan /* If the variable can be overwritten, return OVERWRITABLE. Takes 1191169689Skan care of at least two notable extensions - the COMDAT variables 1192169689Skan used to share template instantiations in C++. */ 1193169689Skan if (!(*targetm.binds_local_p) (node->decl) && !DECL_COMDAT (node->decl)) 1194169689Skan return AVAIL_OVERWRITABLE; 1195169689Skan return AVAIL_AVAILABLE; 1196169689Skan} 1197169689Skan 1198169689Skan 1199169689Skan/* Add the function FNDECL to the call graph. FNDECL is assumed to be 1200169689Skan in low GIMPLE form and ready to be processed by cgraph_finalize_function. 1201169689Skan 1202169689Skan When operating in unit-at-a-time, a new callgraph node is added to 1203169689Skan CGRAPH_EXPAND_QUEUE, which is processed after all the original 1204169689Skan functions in the call graph . 1205169689Skan 1206169689Skan When not in unit-at-a-time, the new callgraph node is added to 1207169689Skan CGRAPH_NODES_QUEUE for cgraph_assemble_pending_functions to 1208169689Skan process. */ 1209169689Skan 1210169689Skanvoid 1211169689Skancgraph_add_new_function (tree fndecl) 1212169689Skan{ 1213169689Skan struct cgraph_node *n = cgraph_node (fndecl); 1214169689Skan n->next_needed = cgraph_expand_queue; 1215169689Skan cgraph_expand_queue = n; 1216169689Skan} 1217169689Skan 1218132718Skan#include "gt-cgraph.h" 1219