1169689Skan/* Callgraph based interprocedural optimizations. 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 module implements main driver of compilation process as well as 23169689Skan few basic interprocedural optimizers. 24169689Skan 25169689Skan The main scope of this file is to act as an interface in between 26169689Skan tree based frontends and the backend (and middle end) 27169689Skan 28169689Skan The front-end is supposed to use following functionality: 29169689Skan 30169689Skan - cgraph_finalize_function 31169689Skan 32169689Skan This function is called once front-end has parsed whole body of function 33169689Skan and it is certain that the function body nor the declaration will change. 34169689Skan 35169689Skan (There is one exception needed for implementing GCC extern inline function.) 36169689Skan 37169689Skan - cgraph_varpool_finalize_variable 38169689Skan 39169689Skan This function has same behavior as the above but is used for static 40169689Skan variables. 41169689Skan 42169689Skan - cgraph_finalize_compilation_unit 43169689Skan 44169689Skan This function is called once compilation unit is finalized and it will 45169689Skan no longer change. 46169689Skan 47169689Skan In the unit-at-a-time the call-graph construction and local function 48169689Skan analysis takes place here. Bodies of unreachable functions are released 49169689Skan to conserve memory usage. 50169689Skan 51169689Skan ??? The compilation unit in this point of view should be compilation 52169689Skan unit as defined by the language - for instance C frontend allows multiple 53169689Skan compilation units to be parsed at once and it should call function each 54169689Skan time parsing is done so we save memory. 55169689Skan 56169689Skan - cgraph_optimize 57169689Skan 58169689Skan In this unit-at-a-time compilation the intra procedural analysis takes 59169689Skan place here. In particular the static functions whose address is never 60169689Skan taken are marked as local. Backend can then use this information to 61169689Skan modify calling conventions, do better inlining or similar optimizations. 62169689Skan 63169689Skan - cgraph_assemble_pending_functions 64169689Skan - cgraph_varpool_assemble_pending_variables 65169689Skan 66169689Skan In non-unit-at-a-time mode these functions can be used to force compilation 67169689Skan of functions or variables that are known to be needed at given stage 68169689Skan of compilation 69169689Skan 70169689Skan - cgraph_mark_needed_node 71169689Skan - cgraph_varpool_mark_needed_node 72169689Skan 73169689Skan When function or variable is referenced by some hidden way (for instance 74169689Skan via assembly code and marked by attribute "used"), the call-graph data structure 75169689Skan must be updated accordingly by this function. 76169689Skan 77169689Skan - analyze_expr callback 78169689Skan 79169689Skan This function is responsible for lowering tree nodes not understood by 80169689Skan generic code into understandable ones or alternatively marking 81169689Skan callgraph and varpool nodes referenced by the as needed. 82169689Skan 83169689Skan ??? On the tree-ssa genericizing should take place here and we will avoid 84169689Skan need for these hooks (replacing them by genericizing hook) 85169689Skan 86169689Skan - expand_function callback 87169689Skan 88169689Skan This function is used to expand function and pass it into RTL back-end. 89169689Skan Front-end should not make any assumptions about when this function can be 90169689Skan called. In particular cgraph_assemble_pending_functions, 91169689Skan cgraph_varpool_assemble_pending_variables, cgraph_finalize_function, 92169689Skan cgraph_varpool_finalize_function, cgraph_optimize can cause arbitrarily 93169689Skan previously finalized functions to be expanded. 94169689Skan 95169689Skan We implement two compilation modes. 96169689Skan 97169689Skan - unit-at-a-time: In this mode analyzing of all functions is deferred 98169689Skan to cgraph_finalize_compilation_unit and expansion into cgraph_optimize. 99169689Skan 100169689Skan In cgraph_finalize_compilation_unit the reachable functions are 101169689Skan analyzed. During analysis the call-graph edges from reachable 102169689Skan functions are constructed and their destinations are marked as 103169689Skan reachable. References to functions and variables are discovered too 104169689Skan and variables found to be needed output to the assembly file. Via 105169689Skan mark_referenced call in assemble_variable functions referenced by 106169689Skan static variables are noticed too. 107169689Skan 108169689Skan The intra-procedural information is produced and its existence 109169689Skan indicated by global_info_ready. Once this flag is set it is impossible 110169689Skan to change function from !reachable to reachable and thus 111169689Skan assemble_variable no longer call mark_referenced. 112169689Skan 113169689Skan Finally the call-graph is topologically sorted and all reachable functions 114169689Skan that has not been completely inlined or are not external are output. 115169689Skan 116169689Skan ??? It is possible that reference to function or variable is optimized 117169689Skan out. We can not deal with this nicely because topological order is not 118169689Skan suitable for it. For tree-ssa we may consider another pass doing 119169689Skan optimization and re-discovering reachable functions. 120169689Skan 121169689Skan ??? Reorganize code so variables are output very last and only if they 122169689Skan really has been referenced by produced code, so we catch more cases 123169689Skan where reference has been optimized out. 124169689Skan 125169689Skan - non-unit-at-a-time 126169689Skan 127169689Skan All functions are variables are output as early as possible to conserve 128169689Skan memory consumption. This may or may not result in less memory used but 129169689Skan it is still needed for some legacy code that rely on particular ordering 130169689Skan of things output from the compiler. 131169689Skan 132169689Skan Varpool data structures are not used and variables are output directly. 133169689Skan 134169689Skan Functions are output early using call of 135169689Skan cgraph_assemble_pending_function from cgraph_finalize_function. The 136169689Skan decision on whether function is needed is made more conservative so 137169689Skan uninlininable static functions are needed too. During the call-graph 138169689Skan construction the edge destinations are not marked as reachable and it 139169689Skan is completely relied upn assemble_variable to mark them. */ 140169689Skan 141169689Skan 142132718Skan#include "config.h" 143132718Skan#include "system.h" 144132718Skan#include "coretypes.h" 145132718Skan#include "tm.h" 146132718Skan#include "tree.h" 147169689Skan#include "rtl.h" 148169689Skan#include "tree-flow.h" 149132718Skan#include "tree-inline.h" 150132718Skan#include "langhooks.h" 151169689Skan#include "pointer-set.h" 152132718Skan#include "toplev.h" 153132718Skan#include "flags.h" 154132718Skan#include "ggc.h" 155132718Skan#include "debug.h" 156132718Skan#include "target.h" 157132718Skan#include "cgraph.h" 158132718Skan#include "diagnostic.h" 159132718Skan#include "timevar.h" 160132718Skan#include "params.h" 161132718Skan#include "fibheap.h" 162132718Skan#include "c-common.h" 163132718Skan#include "intl.h" 164132718Skan#include "function.h" 165169689Skan#include "ipa-prop.h" 166169689Skan#include "tree-gimple.h" 167169689Skan#include "tree-pass.h" 168169689Skan#include "output.h" 169132718Skan 170132718Skanstatic void cgraph_expand_all_functions (void); 171132718Skanstatic void cgraph_mark_functions_to_output (void); 172132718Skanstatic void cgraph_expand_function (struct cgraph_node *); 173169689Skanstatic tree record_reference (tree *, int *, void *); 174169689Skanstatic void cgraph_output_pending_asms (void); 175169689Skanstatic void cgraph_increase_alignment (void); 176132718Skan 177169689Skan/* Lists all assembled variables to be sent to debugger output later on. */ 178169689Skanstatic GTY(()) struct cgraph_varpool_node *cgraph_varpool_assembled_nodes_queue; 179132718Skan 180169689Skan/* Records tree nodes seen in record_reference. Simply using 181132718Skan walk_tree_without_duplicates doesn't guarantee each node is visited 182132718Skan once because it gets a new htab upon each recursive call from 183169689Skan record_reference itself. */ 184169689Skanstatic struct pointer_set_t *visited_nodes; 185132718Skan 186169689Skanstatic FILE *cgraph_dump_file; 187169689Skan 188132718Skan/* Determine if function DECL is needed. That is, visible to something 189132718Skan either outside this translation unit, something magic in the system 190132718Skan configury, or (if not doing unit-at-a-time) to something we havn't 191132718Skan seen yet. */ 192132718Skan 193132718Skanstatic bool 194132718Skandecide_is_function_needed (struct cgraph_node *node, tree decl) 195132718Skan{ 196169689Skan tree origin; 197169689Skan if (MAIN_NAME_P (DECL_NAME (decl)) 198169689Skan && TREE_PUBLIC (decl)) 199169689Skan { 200169689Skan node->local.externally_visible = true; 201169689Skan return true; 202169689Skan } 203169689Skan 204169689Skan /* If the user told us it is used, then it must be so. */ 205169689Skan if (node->local.externally_visible) 206169689Skan return true; 207169689Skan 208169689Skan if (!flag_unit_at_a_time && lookup_attribute ("used", DECL_ATTRIBUTES (decl))) 209169689Skan return true; 210169689Skan 211169689Skan /* ??? If the assembler name is set by hand, it is possible to assemble 212169689Skan the name later after finalizing the function and the fact is noticed 213169689Skan in assemble_name then. This is arguably a bug. */ 214169689Skan if (DECL_ASSEMBLER_NAME_SET_P (decl) 215169689Skan && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) 216169689Skan return true; 217169689Skan 218132718Skan /* If we decided it was needed before, but at the time we didn't have 219132718Skan the body of the function available, then it's still needed. We have 220132718Skan to go back and re-check its dependencies now. */ 221132718Skan if (node->needed) 222132718Skan return true; 223132718Skan 224132718Skan /* Externally visible functions must be output. The exception is 225169689Skan COMDAT functions that must be output only when they are needed. 226169689Skan 227169689Skan When not optimizing, also output the static functions. (see 228169689Skan PR24561), but don't do so for always_inline functions, functions 229169689Skan declared inline and nested functions. These was optimized out 230169689Skan in the original implementation and it is unclear whether we want 231169689Skan to change the behavior here. */ 232169689Skan if (((TREE_PUBLIC (decl) 233169689Skan || (!optimize && !node->local.disregard_inline_limits 234169689Skan && !DECL_DECLARED_INLINE_P (decl) 235169689Skan && !node->origin)) 236169689Skan && !flag_whole_program) 237169689Skan && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl)) 238132718Skan return true; 239132718Skan 240132718Skan /* Constructors and destructors are reachable from the runtime by 241132718Skan some mechanism. */ 242132718Skan if (DECL_STATIC_CONSTRUCTOR (decl) || DECL_STATIC_DESTRUCTOR (decl)) 243132718Skan return true; 244132718Skan 245132718Skan if (flag_unit_at_a_time) 246132718Skan return false; 247132718Skan 248132718Skan /* If not doing unit at a time, then we'll only defer this function 249132718Skan if its marked for inlining. Otherwise we want to emit it now. */ 250132718Skan 251132718Skan /* "extern inline" functions are never output locally. */ 252132718Skan if (DECL_EXTERNAL (decl)) 253132718Skan return false; 254169689Skan /* Nested functions of extern inline function shall not be emit unless 255169689Skan we inlined the origin. */ 256169689Skan for (origin = decl_function_context (decl); origin; 257169689Skan origin = decl_function_context (origin)) 258169689Skan if (DECL_EXTERNAL (origin)) 259169689Skan return false; 260132718Skan /* We want to emit COMDAT functions only when absolutely necessary. */ 261132718Skan if (DECL_COMDAT (decl)) 262132718Skan return false; 263132718Skan if (!DECL_INLINE (decl) 264132718Skan || (!node->local.disregard_inline_limits 265132718Skan /* When declared inline, defer even the uninlinable functions. 266132718Skan This allows them to be eliminated when unused. */ 267169689Skan && !DECL_DECLARED_INLINE_P (decl) 268169689Skan && (!node->local.inlinable || !cgraph_default_inline_p (node, NULL)))) 269132718Skan return true; 270132718Skan 271132718Skan return false; 272132718Skan} 273132718Skan 274169689Skan/* Walk the decls we marked as necessary and see if they reference new 275169689Skan variables or functions and add them into the worklists. */ 276169689Skanstatic bool 277169689Skancgraph_varpool_analyze_pending_decls (void) 278169689Skan{ 279169689Skan bool changed = false; 280169689Skan timevar_push (TV_CGRAPH); 281169689Skan 282169689Skan while (cgraph_varpool_first_unanalyzed_node) 283169689Skan { 284169689Skan tree decl = cgraph_varpool_first_unanalyzed_node->decl; 285169689Skan 286169689Skan cgraph_varpool_first_unanalyzed_node->analyzed = true; 287169689Skan 288169689Skan cgraph_varpool_first_unanalyzed_node = cgraph_varpool_first_unanalyzed_node->next_needed; 289169689Skan 290169689Skan /* Compute the alignment early so function body expanders are 291169689Skan already informed about increased alignment. */ 292169689Skan align_variable (decl, 0); 293169689Skan 294169689Skan if (DECL_INITIAL (decl)) 295169689Skan { 296169689Skan visited_nodes = pointer_set_create (); 297169689Skan walk_tree (&DECL_INITIAL (decl), record_reference, NULL, visited_nodes); 298169689Skan pointer_set_destroy (visited_nodes); 299169689Skan visited_nodes = NULL; 300169689Skan } 301169689Skan changed = true; 302169689Skan } 303169689Skan timevar_pop (TV_CGRAPH); 304169689Skan return changed; 305169689Skan} 306169689Skan 307169689Skan/* Optimization of function bodies might've rendered some variables as 308169689Skan unnecessary so we want to avoid these from being compiled. 309169689Skan 310169689Skan This is done by pruning the queue and keeping only the variables that 311169689Skan really appear needed (ie they are either externally visible or referenced 312169689Skan by compiled function). Re-doing the reachability analysis on variables 313169689Skan brings back the remaining variables referenced by these. */ 314169689Skanstatic void 315169689Skancgraph_varpool_remove_unreferenced_decls (void) 316169689Skan{ 317169689Skan struct cgraph_varpool_node *next, *node = cgraph_varpool_nodes_queue; 318169689Skan 319169689Skan cgraph_varpool_reset_queue (); 320169689Skan 321169689Skan if (errorcount || sorrycount) 322169689Skan return; 323169689Skan 324169689Skan while (node) 325169689Skan { 326169689Skan tree decl = node->decl; 327169689Skan next = node->next_needed; 328169689Skan node->needed = 0; 329169689Skan 330169689Skan if (node->finalized 331169689Skan && ((DECL_ASSEMBLER_NAME_SET_P (decl) 332169689Skan && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) 333169689Skan || node->force_output 334169689Skan || decide_is_variable_needed (node, decl) 335169689Skan /* ??? Cgraph does not yet rule the world with an iron hand, 336169689Skan and does not control the emission of debug information. 337169689Skan After a variable has its DECL_RTL set, we must assume that 338169689Skan it may be referenced by the debug information, and we can 339169689Skan no longer elide it. */ 340169689Skan || DECL_RTL_SET_P (decl))) 341169689Skan cgraph_varpool_mark_needed_node (node); 342169689Skan 343169689Skan node = next; 344169689Skan } 345169689Skan /* Make sure we mark alias targets as used targets. */ 346169689Skan finish_aliases_1 (); 347169689Skan cgraph_varpool_analyze_pending_decls (); 348169689Skan} 349169689Skan 350169689Skan 351132718Skan/* When not doing unit-at-a-time, output all functions enqueued. 352132718Skan Return true when such a functions were found. */ 353132718Skan 354132718Skanbool 355132718Skancgraph_assemble_pending_functions (void) 356132718Skan{ 357132718Skan bool output = false; 358132718Skan 359132718Skan if (flag_unit_at_a_time) 360132718Skan return false; 361132718Skan 362169689Skan cgraph_output_pending_asms (); 363169689Skan 364132718Skan while (cgraph_nodes_queue) 365132718Skan { 366132718Skan struct cgraph_node *n = cgraph_nodes_queue; 367132718Skan 368132718Skan cgraph_nodes_queue = cgraph_nodes_queue->next_needed; 369169689Skan n->next_needed = NULL; 370169689Skan if (!n->global.inlined_to 371169689Skan && !n->alias 372169689Skan && !DECL_EXTERNAL (n->decl)) 373132718Skan { 374132718Skan cgraph_expand_function (n); 375132718Skan output = true; 376132718Skan } 377132718Skan } 378132718Skan 379169689Skan /* Process CGRAPH_EXPAND_QUEUE, these are functions created during 380169689Skan the expansion process. Note that this queue may grow as its 381169689Skan being processed, as the new functions may generate new ones. */ 382169689Skan while (cgraph_expand_queue) 383169689Skan { 384169689Skan struct cgraph_node *n = cgraph_expand_queue; 385169689Skan cgraph_expand_queue = cgraph_expand_queue->next_needed; 386169689Skan n->next_needed = NULL; 387169689Skan cgraph_finalize_function (n->decl, false); 388169689Skan output = true; 389169689Skan } 390169689Skan 391132718Skan return output; 392132718Skan} 393132718Skan 394169689Skan 395169689Skan/* As an GCC extension we allow redefinition of the function. The 396169689Skan semantics when both copies of bodies differ is not well defined. 397169689Skan We replace the old body with new body so in unit at a time mode 398169689Skan we always use new body, while in normal mode we may end up with 399169689Skan old body inlined into some functions and new body expanded and 400169689Skan inlined in others. 401169689Skan 402169689Skan ??? It may make more sense to use one body for inlining and other 403169689Skan body for expanding the function but this is difficult to do. */ 404169689Skan 405169689Skanstatic void 406169689Skancgraph_reset_node (struct cgraph_node *node) 407169689Skan{ 408169689Skan /* If node->output is set, then this is a unit-at-a-time compilation 409169689Skan and we have already begun whole-unit analysis. This is *not* 410169689Skan testing for whether we've already emitted the function. That 411169689Skan case can be sort-of legitimately seen with real function 412169689Skan redefinition errors. I would argue that the front end should 413169689Skan never present us with such a case, but don't enforce that for now. */ 414169689Skan gcc_assert (!node->output); 415169689Skan 416169689Skan /* Reset our data structures so we can analyze the function again. */ 417169689Skan memset (&node->local, 0, sizeof (node->local)); 418169689Skan memset (&node->global, 0, sizeof (node->global)); 419169689Skan memset (&node->rtl, 0, sizeof (node->rtl)); 420169689Skan node->analyzed = false; 421169689Skan node->local.redefined_extern_inline = true; 422169689Skan node->local.finalized = false; 423169689Skan 424169689Skan if (!flag_unit_at_a_time) 425169689Skan { 426169689Skan struct cgraph_node *n, *next; 427169689Skan 428169689Skan for (n = cgraph_nodes; n; n = next) 429169689Skan { 430169689Skan next = n->next; 431169689Skan if (n->global.inlined_to == node) 432169689Skan cgraph_remove_node (n); 433169689Skan } 434169689Skan } 435169689Skan 436169689Skan cgraph_node_remove_callees (node); 437169689Skan 438169689Skan /* We may need to re-queue the node for assembling in case 439169689Skan we already proceeded it and ignored as not needed. */ 440169689Skan if (node->reachable && !flag_unit_at_a_time) 441169689Skan { 442169689Skan struct cgraph_node *n; 443169689Skan 444169689Skan for (n = cgraph_nodes_queue; n; n = n->next_needed) 445169689Skan if (n == node) 446169689Skan break; 447169689Skan if (!n) 448169689Skan node->reachable = 0; 449169689Skan } 450169689Skan} 451169689Skan 452169689Skanstatic void 453169689Skancgraph_lower_function (struct cgraph_node *node) 454169689Skan{ 455169689Skan if (node->lowered) 456169689Skan return; 457169689Skan tree_lowering_passes (node->decl); 458169689Skan node->lowered = true; 459169689Skan} 460169689Skan 461261188Spfg/* APPLE LOCAL begin radar 6305545 */ 462261188Spfg/** lower_if_nested_functions - This routine is called from cplus side only. 463261188Spfg Its purpose is to lower block helper (or any other nested function) 464261188Spfg which may have been nested in a constructor or destructor. We have to 465261188Spfg do this because structors are cloned and are not lowered themselves (which 466261188Spfg is the only way to lower the nested functions). */ 467261188Spfgvoid 468261188Spfglower_if_nested_functions (tree decl) 469261188Spfg{ 470261188Spfg lower_nested_functions (decl, true); 471261188Spfg} 472261188Spfg/* APPLE LOCAL end radar 6305545 */ 473261188Spfg 474132718Skan/* DECL has been parsed. Take it, queue it, compile it at the whim of the 475132718Skan logic in effect. If NESTED is true, then our caller cannot stand to have 476132718Skan the garbage collector run at the moment. We would need to either create 477132718Skan a new GC context, or just not compile right now. */ 478132718Skan 479132718Skanvoid 480132718Skancgraph_finalize_function (tree decl, bool nested) 481132718Skan{ 482132718Skan struct cgraph_node *node = cgraph_node (decl); 483132718Skan 484132718Skan if (node->local.finalized) 485169689Skan cgraph_reset_node (node); 486132718Skan 487132718Skan notice_global_symbol (decl); 488132718Skan node->decl = decl; 489132718Skan node->local.finalized = true; 490169689Skan node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL; 491169689Skan if (node->nested) 492261188Spfg /* APPLE LOCAL radar 6305545 */ 493261188Spfg lower_nested_functions (decl, false); 494169689Skan gcc_assert (!node->nested); 495132718Skan 496132718Skan /* If not unit at a time, then we need to create the call graph 497132718Skan now, so that called functions can be queued and emitted now. */ 498132718Skan if (!flag_unit_at_a_time) 499132718Skan { 500132718Skan cgraph_analyze_function (node); 501169689Skan cgraph_decide_inlining_incrementally (node, false); 502132718Skan } 503132718Skan 504132718Skan if (decide_is_function_needed (node, decl)) 505132718Skan cgraph_mark_needed_node (node); 506132718Skan 507169689Skan /* Since we reclaim unreachable nodes at the end of every language 508169689Skan level unit, we need to be conservative about possible entry points 509169689Skan there. */ 510169689Skan if ((TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))) 511169689Skan cgraph_mark_reachable_node (node); 512169689Skan 513132718Skan /* If not unit at a time, go ahead and emit everything we've found 514132718Skan to be reachable at this time. */ 515132718Skan if (!nested) 516132718Skan { 517132718Skan if (!cgraph_assemble_pending_functions ()) 518132718Skan ggc_collect (); 519132718Skan } 520132718Skan 521132718Skan /* If we've not yet emitted decl, tell the debug info about it. */ 522132718Skan if (!TREE_ASM_WRITTEN (decl)) 523132718Skan (*debug_hooks->deferred_inline_function) (decl); 524132718Skan 525169689Skan /* Possibly warn about unused parameters. */ 526169689Skan if (warn_unused_parameter) 527169689Skan do_warn_unused_parameter (decl); 528132718Skan} 529132718Skan 530132718Skan/* Walk tree and record all calls. Called via walk_tree. */ 531132718Skanstatic tree 532169689Skanrecord_reference (tree *tp, int *walk_subtrees, void *data) 533132718Skan{ 534132718Skan tree t = *tp; 535132718Skan 536132718Skan switch (TREE_CODE (t)) 537132718Skan { 538132718Skan case VAR_DECL: 539132718Skan /* ??? Really, we should mark this decl as *potentially* referenced 540132718Skan by this function and re-examine whether the decl is actually used 541132718Skan after rtl has been generated. */ 542169689Skan if (TREE_STATIC (t) || DECL_EXTERNAL (t)) 543169689Skan { 544169689Skan cgraph_varpool_mark_needed_node (cgraph_varpool_node (t)); 545169689Skan if (lang_hooks.callgraph.analyze_expr) 546169689Skan return lang_hooks.callgraph.analyze_expr (tp, walk_subtrees, 547169689Skan data); 548169689Skan } 549132718Skan break; 550132718Skan 551169689Skan case FDESC_EXPR: 552132718Skan case ADDR_EXPR: 553132718Skan if (flag_unit_at_a_time) 554132718Skan { 555132718Skan /* Record dereferences to the functions. This makes the 556132718Skan functions reachable unconditionally. */ 557132718Skan tree decl = TREE_OPERAND (*tp, 0); 558132718Skan if (TREE_CODE (decl) == FUNCTION_DECL) 559132718Skan cgraph_mark_needed_node (cgraph_node (decl)); 560132718Skan } 561132718Skan break; 562132718Skan 563132718Skan default: 564132718Skan /* Save some cycles by not walking types and declaration as we 565132718Skan won't find anything useful there anyway. */ 566169689Skan if (IS_TYPE_OR_DECL_P (*tp)) 567132718Skan { 568132718Skan *walk_subtrees = 0; 569132718Skan break; 570132718Skan } 571132718Skan 572132718Skan if ((unsigned int) TREE_CODE (t) >= LAST_AND_UNUSED_TREE_CODE) 573169689Skan return lang_hooks.callgraph.analyze_expr (tp, walk_subtrees, data); 574132718Skan break; 575132718Skan } 576132718Skan 577132718Skan return NULL; 578132718Skan} 579132718Skan 580169689Skan/* Create cgraph edges for function calls inside BODY from NODE. */ 581132718Skan 582169689Skanstatic void 583169689Skancgraph_create_edges (struct cgraph_node *node, tree body) 584132718Skan{ 585169689Skan basic_block bb; 586169689Skan 587169689Skan struct function *this_cfun = DECL_STRUCT_FUNCTION (body); 588169689Skan block_stmt_iterator bsi; 589169689Skan tree step; 590169689Skan visited_nodes = pointer_set_create (); 591169689Skan 592169689Skan /* Reach the trees by walking over the CFG, and note the 593169689Skan enclosing basic-blocks in the call edges. */ 594169689Skan FOR_EACH_BB_FN (bb, this_cfun) 595169689Skan for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi)) 596169689Skan { 597169689Skan tree stmt = bsi_stmt (bsi); 598169689Skan tree call = get_call_expr_in (stmt); 599169689Skan tree decl; 600169689Skan 601169689Skan if (call && (decl = get_callee_fndecl (call))) 602169689Skan { 603169689Skan cgraph_create_edge (node, cgraph_node (decl), stmt, 604169689Skan bb->count, 605169689Skan bb->loop_depth); 606169689Skan walk_tree (&TREE_OPERAND (call, 1), 607169689Skan record_reference, node, visited_nodes); 608169689Skan if (TREE_CODE (stmt) == MODIFY_EXPR) 609169689Skan walk_tree (&TREE_OPERAND (stmt, 0), 610169689Skan record_reference, node, visited_nodes); 611169689Skan } 612169689Skan else 613169689Skan walk_tree (bsi_stmt_ptr (bsi), record_reference, node, visited_nodes); 614169689Skan } 615169689Skan 616169689Skan /* Look for initializers of constant variables and private statics. */ 617169689Skan for (step = DECL_STRUCT_FUNCTION (body)->unexpanded_var_list; 618169689Skan step; 619169689Skan step = TREE_CHAIN (step)) 620169689Skan { 621169689Skan tree decl = TREE_VALUE (step); 622169689Skan if (TREE_CODE (decl) == VAR_DECL 623169689Skan && (TREE_STATIC (decl) && !DECL_EXTERNAL (decl)) 624169689Skan && flag_unit_at_a_time) 625169689Skan cgraph_varpool_finalize_decl (decl); 626169689Skan else if (TREE_CODE (decl) == VAR_DECL && DECL_INITIAL (decl)) 627169689Skan walk_tree (&DECL_INITIAL (decl), record_reference, node, visited_nodes); 628169689Skan } 629169689Skan 630169689Skan pointer_set_destroy (visited_nodes); 631132718Skan visited_nodes = NULL; 632132718Skan} 633132718Skan 634169689Skan/* Give initial reasons why inlining would fail. Those gets 635169689Skan either NULLified or usually overwritten by more precise reason 636169689Skan later. */ 637169689Skanstatic void 638169689Skaninitialize_inline_failed (struct cgraph_node *node) 639169689Skan{ 640169689Skan struct cgraph_edge *e; 641169689Skan 642169689Skan for (e = node->callers; e; e = e->next_caller) 643169689Skan { 644169689Skan gcc_assert (!e->callee->global.inlined_to); 645169689Skan gcc_assert (e->inline_failed); 646169689Skan if (node->local.redefined_extern_inline) 647169689Skan e->inline_failed = N_("redefined extern inline functions are not " 648169689Skan "considered for inlining"); 649169689Skan else if (!node->local.inlinable) 650169689Skan e->inline_failed = N_("function not inlinable"); 651169689Skan else 652169689Skan e->inline_failed = N_("function not considered for inlining"); 653169689Skan } 654169689Skan} 655169689Skan 656169689Skan/* Rebuild call edges from current function after a passes not aware 657169689Skan of cgraph updating. */ 658169689Skanstatic unsigned int 659169689Skanrebuild_cgraph_edges (void) 660169689Skan{ 661169689Skan basic_block bb; 662169689Skan struct cgraph_node *node = cgraph_node (current_function_decl); 663169689Skan block_stmt_iterator bsi; 664169689Skan 665169689Skan cgraph_node_remove_callees (node); 666169689Skan 667169689Skan node->count = ENTRY_BLOCK_PTR->count; 668169689Skan 669169689Skan FOR_EACH_BB (bb) 670169689Skan for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi)) 671169689Skan { 672169689Skan tree stmt = bsi_stmt (bsi); 673169689Skan tree call = get_call_expr_in (stmt); 674169689Skan tree decl; 675169689Skan 676169689Skan if (call && (decl = get_callee_fndecl (call))) 677169689Skan cgraph_create_edge (node, cgraph_node (decl), stmt, 678169689Skan bb->count, 679169689Skan bb->loop_depth); 680169689Skan } 681169689Skan initialize_inline_failed (node); 682169689Skan gcc_assert (!node->global.inlined_to); 683169689Skan return 0; 684169689Skan} 685169689Skan 686169689Skanstruct tree_opt_pass pass_rebuild_cgraph_edges = 687169689Skan{ 688169689Skan NULL, /* name */ 689169689Skan NULL, /* gate */ 690169689Skan rebuild_cgraph_edges, /* execute */ 691169689Skan NULL, /* sub */ 692169689Skan NULL, /* next */ 693169689Skan 0, /* static_pass_number */ 694169689Skan 0, /* tv_id */ 695169689Skan PROP_cfg, /* properties_required */ 696169689Skan 0, /* properties_provided */ 697169689Skan 0, /* properties_destroyed */ 698169689Skan 0, /* todo_flags_start */ 699169689Skan 0, /* todo_flags_finish */ 700169689Skan 0 /* letter */ 701169689Skan}; 702169689Skan 703169689Skan/* Verify cgraph nodes of given cgraph node. */ 704169689Skanvoid 705169689Skanverify_cgraph_node (struct cgraph_node *node) 706169689Skan{ 707169689Skan struct cgraph_edge *e; 708169689Skan struct cgraph_node *main_clone; 709169689Skan struct function *this_cfun = DECL_STRUCT_FUNCTION (node->decl); 710169689Skan basic_block this_block; 711169689Skan block_stmt_iterator bsi; 712169689Skan bool error_found = false; 713169689Skan 714169689Skan if (errorcount || sorrycount) 715169689Skan return; 716169689Skan 717169689Skan timevar_push (TV_CGRAPH_VERIFY); 718169689Skan for (e = node->callees; e; e = e->next_callee) 719169689Skan if (e->aux) 720169689Skan { 721169689Skan error ("aux field set for edge %s->%s", 722169689Skan cgraph_node_name (e->caller), cgraph_node_name (e->callee)); 723169689Skan error_found = true; 724169689Skan } 725169689Skan if (node->count < 0) 726169689Skan { 727169689Skan error ("Execution count is negative"); 728169689Skan error_found = true; 729169689Skan } 730169689Skan for (e = node->callers; e; e = e->next_caller) 731169689Skan { 732169689Skan if (e->count < 0) 733169689Skan { 734169689Skan error ("caller edge count is negative"); 735169689Skan error_found = true; 736169689Skan } 737169689Skan if (!e->inline_failed) 738169689Skan { 739169689Skan if (node->global.inlined_to 740169689Skan != (e->caller->global.inlined_to 741169689Skan ? e->caller->global.inlined_to : e->caller)) 742169689Skan { 743169689Skan error ("inlined_to pointer is wrong"); 744169689Skan error_found = true; 745169689Skan } 746169689Skan if (node->callers->next_caller) 747169689Skan { 748169689Skan error ("multiple inline callers"); 749169689Skan error_found = true; 750169689Skan } 751169689Skan } 752169689Skan else 753169689Skan if (node->global.inlined_to) 754169689Skan { 755169689Skan error ("inlined_to pointer set for noninline callers"); 756169689Skan error_found = true; 757169689Skan } 758169689Skan } 759169689Skan if (!node->callers && node->global.inlined_to) 760169689Skan { 761169689Skan error ("inlined_to pointer is set but no predecessors found"); 762169689Skan error_found = true; 763169689Skan } 764169689Skan if (node->global.inlined_to == node) 765169689Skan { 766169689Skan error ("inlined_to pointer refers to itself"); 767169689Skan error_found = true; 768169689Skan } 769169689Skan 770169689Skan for (main_clone = cgraph_node (node->decl); main_clone; 771169689Skan main_clone = main_clone->next_clone) 772169689Skan if (main_clone == node) 773169689Skan break; 774169689Skan if (!cgraph_node (node->decl)) 775169689Skan { 776169689Skan error ("node not found in cgraph_hash"); 777169689Skan error_found = true; 778169689Skan } 779169689Skan 780169689Skan if (node->analyzed 781169689Skan && DECL_SAVED_TREE (node->decl) && !TREE_ASM_WRITTEN (node->decl) 782169689Skan && (!DECL_EXTERNAL (node->decl) || node->global.inlined_to)) 783169689Skan { 784169689Skan if (this_cfun->cfg) 785169689Skan { 786169689Skan /* The nodes we're interested in are never shared, so walk 787169689Skan the tree ignoring duplicates. */ 788169689Skan visited_nodes = pointer_set_create (); 789169689Skan /* Reach the trees by walking over the CFG, and note the 790169689Skan enclosing basic-blocks in the call edges. */ 791169689Skan FOR_EACH_BB_FN (this_block, this_cfun) 792169689Skan for (bsi = bsi_start (this_block); !bsi_end_p (bsi); bsi_next (&bsi)) 793169689Skan { 794169689Skan tree stmt = bsi_stmt (bsi); 795169689Skan tree call = get_call_expr_in (stmt); 796169689Skan tree decl; 797169689Skan if (call && (decl = get_callee_fndecl (call))) 798169689Skan { 799169689Skan struct cgraph_edge *e = cgraph_edge (node, stmt); 800169689Skan if (e) 801169689Skan { 802169689Skan if (e->aux) 803169689Skan { 804169689Skan error ("shared call_stmt:"); 805169689Skan debug_generic_stmt (stmt); 806169689Skan error_found = true; 807169689Skan } 808169689Skan if (e->callee->decl != cgraph_node (decl)->decl 809169689Skan && e->inline_failed) 810169689Skan { 811169689Skan error ("edge points to wrong declaration:"); 812169689Skan debug_tree (e->callee->decl); 813169689Skan fprintf (stderr," Instead of:"); 814169689Skan debug_tree (decl); 815169689Skan } 816169689Skan e->aux = (void *)1; 817169689Skan } 818169689Skan else 819169689Skan { 820169689Skan error ("missing callgraph edge for call stmt:"); 821169689Skan debug_generic_stmt (stmt); 822169689Skan error_found = true; 823169689Skan } 824169689Skan } 825169689Skan } 826169689Skan pointer_set_destroy (visited_nodes); 827169689Skan visited_nodes = NULL; 828169689Skan } 829169689Skan else 830169689Skan /* No CFG available?! */ 831169689Skan gcc_unreachable (); 832169689Skan 833169689Skan for (e = node->callees; e; e = e->next_callee) 834169689Skan { 835169689Skan if (!e->aux) 836169689Skan { 837169689Skan error ("edge %s->%s has no corresponding call_stmt", 838169689Skan cgraph_node_name (e->caller), 839169689Skan cgraph_node_name (e->callee)); 840169689Skan debug_generic_stmt (e->call_stmt); 841169689Skan error_found = true; 842169689Skan } 843169689Skan e->aux = 0; 844169689Skan } 845169689Skan } 846169689Skan if (error_found) 847169689Skan { 848169689Skan dump_cgraph_node (stderr, node); 849169689Skan internal_error ("verify_cgraph_node failed"); 850169689Skan } 851169689Skan timevar_pop (TV_CGRAPH_VERIFY); 852169689Skan} 853169689Skan 854169689Skan/* Verify whole cgraph structure. */ 855169689Skanvoid 856169689Skanverify_cgraph (void) 857169689Skan{ 858169689Skan struct cgraph_node *node; 859169689Skan 860169689Skan if (sorrycount || errorcount) 861169689Skan return; 862169689Skan 863169689Skan for (node = cgraph_nodes; node; node = node->next) 864169689Skan verify_cgraph_node (node); 865169689Skan} 866169689Skan 867169689Skan/* Output one variable, if necessary. Return whether we output it. */ 868169689Skanstatic bool 869169689Skancgraph_varpool_assemble_decl (struct cgraph_varpool_node *node) 870169689Skan{ 871169689Skan tree decl = node->decl; 872169689Skan 873169689Skan if (!TREE_ASM_WRITTEN (decl) 874169689Skan && !node->alias 875169689Skan && !DECL_EXTERNAL (decl) 876169689Skan && (TREE_CODE (decl) != VAR_DECL || !DECL_HAS_VALUE_EXPR_P (decl))) 877169689Skan { 878169689Skan assemble_variable (decl, 0, 1, 0); 879169689Skan return TREE_ASM_WRITTEN (decl); 880169689Skan } 881169689Skan 882169689Skan return false; 883169689Skan} 884169689Skan 885169689Skan/* Output all variables enqueued to be assembled. */ 886169689Skanbool 887169689Skancgraph_varpool_assemble_pending_decls (void) 888169689Skan{ 889169689Skan bool changed = false; 890169689Skan 891169689Skan if (errorcount || sorrycount) 892169689Skan return false; 893169689Skan 894169689Skan /* EH might mark decls as needed during expansion. This should be safe since 895169689Skan we don't create references to new function, but it should not be used 896169689Skan elsewhere. */ 897169689Skan cgraph_varpool_analyze_pending_decls (); 898169689Skan 899169689Skan while (cgraph_varpool_nodes_queue) 900169689Skan { 901169689Skan struct cgraph_varpool_node *node = cgraph_varpool_nodes_queue; 902169689Skan 903169689Skan cgraph_varpool_nodes_queue = cgraph_varpool_nodes_queue->next_needed; 904169689Skan if (cgraph_varpool_assemble_decl (node)) 905169689Skan { 906169689Skan changed = true; 907169689Skan node->next_needed = cgraph_varpool_assembled_nodes_queue; 908169689Skan cgraph_varpool_assembled_nodes_queue = node; 909169689Skan node->finalized = 1; 910169689Skan } 911169689Skan else 912169689Skan node->next_needed = NULL; 913169689Skan } 914169689Skan /* cgraph_varpool_nodes_queue is now empty, clear the pointer to the last 915169689Skan element in the queue. */ 916169689Skan cgraph_varpool_last_needed_node = NULL; 917169689Skan return changed; 918169689Skan} 919169689Skan/* Output all variables enqueued to be assembled. */ 920169689Skanstatic void 921169689Skancgraph_varpool_output_debug_info (void) 922169689Skan{ 923169689Skan timevar_push (TV_SYMOUT); 924169689Skan if (errorcount == 0 && sorrycount == 0) 925169689Skan while (cgraph_varpool_assembled_nodes_queue) 926169689Skan { 927169689Skan struct cgraph_varpool_node *node = cgraph_varpool_assembled_nodes_queue; 928169689Skan 929169689Skan /* Local static variables are never seen by check_global_declarations 930169689Skan so we need to output debug info by hand. */ 931169689Skan if (DECL_CONTEXT (node->decl) 932169689Skan && (TREE_CODE (DECL_CONTEXT (node->decl)) == BLOCK 933169689Skan || TREE_CODE (DECL_CONTEXT (node->decl)) == FUNCTION_DECL) 934169689Skan && errorcount == 0 && sorrycount == 0) 935169689Skan (*debug_hooks->global_decl) (node->decl); 936169689Skan cgraph_varpool_assembled_nodes_queue = node->next_needed; 937169689Skan node->next_needed = 0; 938169689Skan } 939169689Skan timevar_pop (TV_SYMOUT); 940169689Skan} 941169689Skan 942169689Skan/* Output all asm statements we have stored up to be output. */ 943169689Skan 944169689Skanstatic void 945169689Skancgraph_output_pending_asms (void) 946169689Skan{ 947169689Skan struct cgraph_asm_node *can; 948169689Skan 949169689Skan if (errorcount || sorrycount) 950169689Skan return; 951169689Skan 952169689Skan for (can = cgraph_asm_nodes; can; can = can->next) 953169689Skan assemble_asm (can->asm_str); 954169689Skan cgraph_asm_nodes = NULL; 955169689Skan} 956169689Skan 957132718Skan/* Analyze the function scheduled to be output. */ 958169689Skanvoid 959132718Skancgraph_analyze_function (struct cgraph_node *node) 960132718Skan{ 961132718Skan tree decl = node->decl; 962132718Skan 963132718Skan current_function_decl = decl; 964169689Skan push_cfun (DECL_STRUCT_FUNCTION (decl)); 965169689Skan cgraph_lower_function (node); 966132718Skan 967132718Skan /* First kill forward declaration so reverse inlining works properly. */ 968169689Skan cgraph_create_edges (node, decl); 969132718Skan 970132718Skan node->local.inlinable = tree_inlinable_function_p (decl); 971169689Skan if (!flag_unit_at_a_time) 972169689Skan node->local.self_insns = estimate_num_insns (decl); 973132718Skan if (node->local.inlinable) 974132718Skan node->local.disregard_inline_limits 975169689Skan = lang_hooks.tree_inlining.disregard_inline_limits (decl); 976169689Skan initialize_inline_failed (node); 977132718Skan if (flag_really_no_inline && !node->local.disregard_inline_limits) 978132718Skan node->local.inlinable = 0; 979132718Skan /* Inlining characteristics are maintained by the cgraph_mark_inline. */ 980132718Skan node->global.insns = node->local.self_insns; 981132718Skan 982132718Skan node->analyzed = true; 983169689Skan pop_cfun (); 984132718Skan current_function_decl = NULL; 985169689Skan} 986132718Skan 987169689Skan/* Look for externally_visible and used attributes and mark cgraph nodes 988169689Skan accordingly. 989169689Skan 990169689Skan We cannot mark the nodes at the point the attributes are processed (in 991169689Skan handle_*_attribute) because the copy of the declarations available at that 992169689Skan point may not be canonical. For example, in: 993169689Skan 994169689Skan void f(); 995169689Skan void f() __attribute__((used)); 996169689Skan 997169689Skan the declaration we see in handle_used_attribute will be the second 998169689Skan declaration -- but the front end will subsequently merge that declaration 999169689Skan with the original declaration and discard the second declaration. 1000169689Skan 1001169689Skan Furthermore, we can't mark these nodes in cgraph_finalize_function because: 1002169689Skan 1003169689Skan void f() {} 1004169689Skan void f() __attribute__((externally_visible)); 1005169689Skan 1006169689Skan is valid. 1007169689Skan 1008169689Skan So, we walk the nodes at the end of the translation unit, applying the 1009169689Skan attributes at that point. */ 1010169689Skan 1011169689Skanstatic void 1012169689Skanprocess_function_and_variable_attributes (struct cgraph_node *first, 1013169689Skan struct cgraph_varpool_node *first_var) 1014169689Skan{ 1015169689Skan struct cgraph_node *node; 1016169689Skan struct cgraph_varpool_node *vnode; 1017169689Skan 1018169689Skan for (node = cgraph_nodes; node != first; node = node->next) 1019169689Skan { 1020169689Skan tree decl = node->decl; 1021169689Skan if (lookup_attribute ("used", DECL_ATTRIBUTES (decl))) 1022169689Skan { 1023169689Skan mark_decl_referenced (decl); 1024169689Skan if (node->local.finalized) 1025169689Skan cgraph_mark_needed_node (node); 1026169689Skan } 1027169689Skan if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl))) 1028169689Skan { 1029169689Skan if (! TREE_PUBLIC (node->decl)) 1030169689Skan warning (OPT_Wattributes, 1031169689Skan "%J%<externally_visible%> attribute have effect only on public objects", 1032169689Skan node->decl); 1033169689Skan else 1034169689Skan { 1035169689Skan if (node->local.finalized) 1036169689Skan cgraph_mark_needed_node (node); 1037169689Skan node->local.externally_visible = true; 1038169689Skan } 1039169689Skan } 1040169689Skan } 1041169689Skan for (vnode = cgraph_varpool_nodes; vnode != first_var; vnode = vnode->next) 1042169689Skan { 1043169689Skan tree decl = vnode->decl; 1044169689Skan if (lookup_attribute ("used", DECL_ATTRIBUTES (decl))) 1045169689Skan { 1046169689Skan mark_decl_referenced (decl); 1047169689Skan if (vnode->finalized) 1048169689Skan cgraph_varpool_mark_needed_node (vnode); 1049169689Skan } 1050169689Skan if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl))) 1051169689Skan { 1052169689Skan if (! TREE_PUBLIC (vnode->decl)) 1053169689Skan warning (OPT_Wattributes, 1054169689Skan "%J%<externally_visible%> attribute have effect only on public objects", 1055169689Skan vnode->decl); 1056169689Skan else 1057169689Skan { 1058169689Skan if (vnode->finalized) 1059169689Skan cgraph_varpool_mark_needed_node (vnode); 1060169689Skan vnode->externally_visible = true; 1061169689Skan } 1062169689Skan } 1063169689Skan } 1064132718Skan} 1065132718Skan 1066132718Skan/* Analyze the whole compilation unit once it is parsed completely. */ 1067132718Skan 1068132718Skanvoid 1069132718Skancgraph_finalize_compilation_unit (void) 1070132718Skan{ 1071169689Skan struct cgraph_node *node, *next; 1072169689Skan /* Keep track of already processed nodes when called multiple times for 1073169689Skan intermodule optimization. */ 1074169689Skan static struct cgraph_node *first_analyzed; 1075169689Skan struct cgraph_node *first_processed = first_analyzed; 1076169689Skan static struct cgraph_varpool_node *first_analyzed_var; 1077132718Skan 1078169689Skan if (errorcount || sorrycount) 1079169689Skan return; 1080169689Skan 1081169689Skan finish_aliases_1 (); 1082169689Skan 1083132718Skan if (!flag_unit_at_a_time) 1084132718Skan { 1085169689Skan cgraph_output_pending_asms (); 1086132718Skan cgraph_assemble_pending_functions (); 1087169689Skan cgraph_varpool_output_debug_info (); 1088132718Skan return; 1089132718Skan } 1090132718Skan 1091132718Skan if (!quiet_flag) 1092169689Skan { 1093169689Skan fprintf (stderr, "\nAnalyzing compilation unit"); 1094169689Skan fflush (stderr); 1095169689Skan } 1096132718Skan 1097132718Skan timevar_push (TV_CGRAPH); 1098169689Skan process_function_and_variable_attributes (first_processed, 1099169689Skan first_analyzed_var); 1100169689Skan first_processed = cgraph_nodes; 1101169689Skan first_analyzed_var = cgraph_varpool_nodes; 1102169689Skan cgraph_varpool_analyze_pending_decls (); 1103132718Skan if (cgraph_dump_file) 1104132718Skan { 1105132718Skan fprintf (cgraph_dump_file, "Initial entry points:"); 1106169689Skan for (node = cgraph_nodes; node != first_analyzed; node = node->next) 1107132718Skan if (node->needed && DECL_SAVED_TREE (node->decl)) 1108132718Skan fprintf (cgraph_dump_file, " %s", cgraph_node_name (node)); 1109132718Skan fprintf (cgraph_dump_file, "\n"); 1110132718Skan } 1111132718Skan 1112132718Skan /* Propagate reachability flag and lower representation of all reachable 1113132718Skan functions. In the future, lowering will introduce new functions and 1114132718Skan new entry points on the way (by template instantiation and virtual 1115132718Skan method table generation for instance). */ 1116132718Skan while (cgraph_nodes_queue) 1117132718Skan { 1118132718Skan struct cgraph_edge *edge; 1119132718Skan tree decl = cgraph_nodes_queue->decl; 1120132718Skan 1121132718Skan node = cgraph_nodes_queue; 1122132718Skan cgraph_nodes_queue = cgraph_nodes_queue->next_needed; 1123169689Skan node->next_needed = NULL; 1124132718Skan 1125132718Skan /* ??? It is possible to create extern inline function and later using 1126169689Skan weak alias attribute to kill its body. See 1127132718Skan gcc.c-torture/compile/20011119-1.c */ 1128132718Skan if (!DECL_SAVED_TREE (decl)) 1129169689Skan { 1130169689Skan cgraph_reset_node (node); 1131169689Skan continue; 1132169689Skan } 1133132718Skan 1134169689Skan gcc_assert (!node->analyzed && node->reachable); 1135169689Skan gcc_assert (DECL_SAVED_TREE (decl)); 1136132718Skan 1137132718Skan cgraph_analyze_function (node); 1138132718Skan 1139132718Skan for (edge = node->callees; edge; edge = edge->next_callee) 1140132718Skan if (!edge->callee->reachable) 1141132718Skan cgraph_mark_reachable_node (edge->callee); 1142132718Skan 1143169689Skan /* We finalize local static variables during constructing callgraph 1144169689Skan edges. Process their attributes too. */ 1145169689Skan process_function_and_variable_attributes (first_processed, 1146169689Skan first_analyzed_var); 1147169689Skan first_processed = cgraph_nodes; 1148169689Skan first_analyzed_var = cgraph_varpool_nodes; 1149169689Skan cgraph_varpool_analyze_pending_decls (); 1150132718Skan } 1151132718Skan 1152132718Skan /* Collect entry points to the unit. */ 1153132718Skan if (cgraph_dump_file) 1154132718Skan { 1155132718Skan fprintf (cgraph_dump_file, "Unit entry points:"); 1156169689Skan for (node = cgraph_nodes; node != first_analyzed; node = node->next) 1157132718Skan if (node->needed && DECL_SAVED_TREE (node->decl)) 1158132718Skan fprintf (cgraph_dump_file, " %s", cgraph_node_name (node)); 1159132718Skan fprintf (cgraph_dump_file, "\n\nInitial "); 1160132718Skan dump_cgraph (cgraph_dump_file); 1161132718Skan } 1162132718Skan 1163132718Skan if (cgraph_dump_file) 1164132718Skan fprintf (cgraph_dump_file, "\nReclaiming functions:"); 1165132718Skan 1166169689Skan for (node = cgraph_nodes; node != first_analyzed; node = next) 1167132718Skan { 1168132718Skan tree decl = node->decl; 1169169689Skan next = node->next; 1170132718Skan 1171169689Skan if (node->local.finalized && !DECL_SAVED_TREE (decl)) 1172169689Skan cgraph_reset_node (node); 1173169689Skan 1174132718Skan if (!node->reachable && DECL_SAVED_TREE (decl)) 1175132718Skan { 1176132718Skan if (cgraph_dump_file) 1177132718Skan fprintf (cgraph_dump_file, " %s", cgraph_node_name (node)); 1178169689Skan cgraph_remove_node (node); 1179169689Skan continue; 1180132718Skan } 1181132718Skan else 1182132718Skan node->next_needed = NULL; 1183169689Skan gcc_assert (!node->local.finalized || DECL_SAVED_TREE (decl)); 1184169689Skan gcc_assert (node->analyzed == node->local.finalized); 1185132718Skan } 1186132718Skan if (cgraph_dump_file) 1187132718Skan { 1188132718Skan fprintf (cgraph_dump_file, "\n\nReclaimed "); 1189132718Skan dump_cgraph (cgraph_dump_file); 1190132718Skan } 1191169689Skan first_analyzed = cgraph_nodes; 1192132718Skan ggc_collect (); 1193132718Skan timevar_pop (TV_CGRAPH); 1194132718Skan} 1195132718Skan/* Figure out what functions we want to assemble. */ 1196132718Skan 1197132718Skanstatic void 1198132718Skancgraph_mark_functions_to_output (void) 1199132718Skan{ 1200132718Skan struct cgraph_node *node; 1201132718Skan 1202132718Skan for (node = cgraph_nodes; node; node = node->next) 1203132718Skan { 1204132718Skan tree decl = node->decl; 1205132718Skan struct cgraph_edge *e; 1206132718Skan 1207169689Skan gcc_assert (!node->output); 1208132718Skan 1209132718Skan for (e = node->callers; e; e = e->next_caller) 1210132718Skan if (e->inline_failed) 1211132718Skan break; 1212132718Skan 1213132718Skan /* We need to output all local functions that are used and not 1214132718Skan always inlined, as well as those that are reachable from 1215132718Skan outside the current compilation unit. */ 1216132718Skan if (DECL_SAVED_TREE (decl) 1217169689Skan && !node->global.inlined_to 1218132718Skan && (node->needed 1219132718Skan || (e && node->reachable)) 1220169689Skan && !TREE_ASM_WRITTEN (decl) 1221132718Skan && !DECL_EXTERNAL (decl)) 1222132718Skan node->output = 1; 1223132718Skan else 1224169689Skan { 1225169689Skan /* We should've reclaimed all functions that are not needed. */ 1226169689Skan#ifdef ENABLE_CHECKING 1227169689Skan if (!node->global.inlined_to && DECL_SAVED_TREE (decl) 1228169689Skan && !DECL_EXTERNAL (decl)) 1229169689Skan { 1230169689Skan dump_cgraph_node (stderr, node); 1231169689Skan internal_error ("failed to reclaim unneeded function"); 1232169689Skan } 1233169689Skan#endif 1234169689Skan gcc_assert (node->global.inlined_to || !DECL_SAVED_TREE (decl) 1235169689Skan || DECL_EXTERNAL (decl)); 1236132718Skan 1237169689Skan } 1238132718Skan 1239132718Skan } 1240132718Skan} 1241132718Skan 1242132718Skan/* Expand function specified by NODE. */ 1243132718Skan 1244132718Skanstatic void 1245132718Skancgraph_expand_function (struct cgraph_node *node) 1246132718Skan{ 1247132718Skan tree decl = node->decl; 1248132718Skan 1249169689Skan /* We ought to not compile any inline clones. */ 1250169689Skan gcc_assert (!node->global.inlined_to); 1251169689Skan 1252132718Skan if (flag_unit_at_a_time) 1253132718Skan announce_function (decl); 1254132718Skan 1255169689Skan cgraph_lower_function (node); 1256132718Skan 1257169689Skan /* Generate RTL for the body of DECL. */ 1258169689Skan lang_hooks.callgraph.expand_function (decl); 1259132718Skan 1260169689Skan /* Make sure that BE didn't give up on compiling. */ 1261169689Skan /* ??? Can happen with nested function of extern inline. */ 1262169689Skan gcc_assert (TREE_ASM_WRITTEN (node->decl)); 1263169689Skan 1264132718Skan current_function_decl = NULL; 1265169689Skan if (!cgraph_preserve_function_body_p (node->decl)) 1266169689Skan { 1267169689Skan DECL_SAVED_TREE (node->decl) = NULL; 1268169689Skan DECL_STRUCT_FUNCTION (node->decl) = NULL; 1269169689Skan DECL_INITIAL (node->decl) = error_mark_node; 1270169689Skan /* Eliminate all call edges. This is important so the call_expr no longer 1271169689Skan points to the dead function body. */ 1272169689Skan cgraph_node_remove_callees (node); 1273169689Skan } 1274169689Skan 1275169689Skan cgraph_function_flags_ready = true; 1276132718Skan} 1277132718Skan 1278169689Skan/* Return true when CALLER_DECL should be inlined into CALLEE_DECL. */ 1279132718Skan 1280169689Skanbool 1281169689Skancgraph_inline_p (struct cgraph_edge *e, const char **reason) 1282132718Skan{ 1283169689Skan *reason = e->inline_failed; 1284169689Skan return !e->inline_failed; 1285169689Skan} 1286132718Skan 1287132718Skan 1288132718Skan 1289169689Skan/* Expand all functions that must be output. 1290132718Skan 1291169689Skan Attempt to topologically sort the nodes so function is output when 1292169689Skan all called functions are already assembled to allow data to be 1293169689Skan propagated across the callgraph. Use a stack to get smaller distance 1294169689Skan between a function and its callees (later we may choose to use a more 1295169689Skan sophisticated algorithm for function reordering; we will likely want 1296169689Skan to use subsections to make the output functions appear in top-down 1297169689Skan order). */ 1298132718Skan 1299169689Skanstatic void 1300169689Skancgraph_expand_all_functions (void) 1301132718Skan{ 1302169689Skan struct cgraph_node *node; 1303169689Skan struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes); 1304169689Skan int order_pos = 0, new_order_pos = 0; 1305132718Skan int i; 1306132718Skan 1307169689Skan order_pos = cgraph_postorder (order); 1308169689Skan gcc_assert (order_pos == cgraph_n_nodes); 1309132718Skan 1310169689Skan /* Garbage collector may remove inline clones we eliminate during 1311169689Skan optimization. So we must be sure to not reference them. */ 1312169689Skan for (i = 0; i < order_pos; i++) 1313169689Skan if (order[i]->output) 1314169689Skan order[new_order_pos++] = order[i]; 1315132718Skan 1316169689Skan for (i = new_order_pos - 1; i >= 0; i--) 1317132718Skan { 1318169689Skan node = order[i]; 1319169689Skan if (node->output) 1320132718Skan { 1321169689Skan gcc_assert (node->reachable); 1322169689Skan node->output = 0; 1323169689Skan cgraph_expand_function (node); 1324132718Skan } 1325132718Skan } 1326132718Skan 1327169689Skan free (order); 1328132718Skan 1329169689Skan /* Process CGRAPH_EXPAND_QUEUE, these are functions created during 1330169689Skan the expansion process. Note that this queue may grow as its 1331169689Skan being processed, as the new functions may generate new ones. */ 1332169689Skan while (cgraph_expand_queue) 1333132718Skan { 1334169689Skan node = cgraph_expand_queue; 1335169689Skan cgraph_expand_queue = cgraph_expand_queue->next_needed; 1336169689Skan node->next_needed = NULL; 1337169689Skan node->output = 0; 1338169689Skan node->lowered = DECL_STRUCT_FUNCTION (node->decl)->cfg != NULL; 1339169689Skan cgraph_expand_function (node); 1340132718Skan } 1341132718Skan} 1342132718Skan 1343169689Skan/* This is used to sort the node types by the cgraph order number. */ 1344132718Skan 1345169689Skanstruct cgraph_order_sort 1346169689Skan{ 1347169689Skan enum { ORDER_UNDEFINED = 0, ORDER_FUNCTION, ORDER_VAR, ORDER_ASM } kind; 1348169689Skan union 1349169689Skan { 1350169689Skan struct cgraph_node *f; 1351169689Skan struct cgraph_varpool_node *v; 1352169689Skan struct cgraph_asm_node *a; 1353169689Skan } u; 1354169689Skan}; 1355132718Skan 1356169689Skan/* Output all functions, variables, and asm statements in the order 1357169689Skan according to their order fields, which is the order in which they 1358169689Skan appeared in the file. This implements -fno-toplevel-reorder. In 1359169689Skan this mode we may output functions and variables which don't really 1360169689Skan need to be output. */ 1361169689Skan 1362169689Skanstatic void 1363169689Skancgraph_output_in_order (void) 1364132718Skan{ 1365169689Skan int max; 1366169689Skan size_t size; 1367169689Skan struct cgraph_order_sort *nodes; 1368132718Skan int i; 1369169689Skan struct cgraph_node *pf; 1370169689Skan struct cgraph_varpool_node *pv; 1371169689Skan struct cgraph_asm_node *pa; 1372132718Skan 1373169689Skan max = cgraph_order; 1374169689Skan size = max * sizeof (struct cgraph_order_sort); 1375169689Skan nodes = (struct cgraph_order_sort *) alloca (size); 1376169689Skan memset (nodes, 0, size); 1377132718Skan 1378169689Skan cgraph_varpool_analyze_pending_decls (); 1379132718Skan 1380169689Skan for (pf = cgraph_nodes; pf; pf = pf->next) 1381132718Skan { 1382169689Skan if (pf->output) 1383132718Skan { 1384169689Skan i = pf->order; 1385169689Skan gcc_assert (nodes[i].kind == ORDER_UNDEFINED); 1386169689Skan nodes[i].kind = ORDER_FUNCTION; 1387169689Skan nodes[i].u.f = pf; 1388132718Skan } 1389132718Skan } 1390132718Skan 1391169689Skan for (pv = cgraph_varpool_nodes_queue; pv; pv = pv->next_needed) 1392132718Skan { 1393169689Skan i = pv->order; 1394169689Skan gcc_assert (nodes[i].kind == ORDER_UNDEFINED); 1395169689Skan nodes[i].kind = ORDER_VAR; 1396169689Skan nodes[i].u.v = pv; 1397132718Skan } 1398132718Skan 1399169689Skan for (pa = cgraph_asm_nodes; pa; pa = pa->next) 1400132718Skan { 1401169689Skan i = pa->order; 1402169689Skan gcc_assert (nodes[i].kind == ORDER_UNDEFINED); 1403169689Skan nodes[i].kind = ORDER_ASM; 1404169689Skan nodes[i].u.a = pa; 1405132718Skan } 1406132718Skan 1407169689Skan for (i = 0; i < max; ++i) 1408132718Skan { 1409169689Skan switch (nodes[i].kind) 1410132718Skan { 1411169689Skan case ORDER_FUNCTION: 1412169689Skan nodes[i].u.f->output = 0; 1413169689Skan cgraph_expand_function (nodes[i].u.f); 1414169689Skan break; 1415132718Skan 1416169689Skan case ORDER_VAR: 1417169689Skan cgraph_varpool_assemble_decl (nodes[i].u.v); 1418169689Skan break; 1419132718Skan 1420169689Skan case ORDER_ASM: 1421169689Skan assemble_asm (nodes[i].u.a->asm_str); 1422169689Skan break; 1423169689Skan 1424169689Skan case ORDER_UNDEFINED: 1425169689Skan break; 1426169689Skan 1427169689Skan default: 1428169689Skan gcc_unreachable (); 1429132718Skan } 1430132718Skan } 1431132718Skan 1432169689Skan cgraph_asm_nodes = NULL; 1433132718Skan} 1434132718Skan 1435169689Skan/* Mark visibility of all functions. 1436132718Skan 1437169689Skan A local function is one whose calls can occur only in the current 1438169689Skan compilation unit and all its calls are explicit, so we can change 1439169689Skan its calling convention. We simply mark all static functions whose 1440169689Skan address is not taken as local. 1441132718Skan 1442169689Skan We also change the TREE_PUBLIC flag of all declarations that are public 1443169689Skan in language point of view but we want to overwrite this default 1444169689Skan via visibilities for the backend point of view. */ 1445132718Skan 1446132718Skanstatic void 1447169689Skancgraph_function_and_variable_visibility (void) 1448132718Skan{ 1449169689Skan struct cgraph_node *node; 1450169689Skan struct cgraph_varpool_node *vnode; 1451132718Skan 1452169689Skan for (node = cgraph_nodes; node; node = node->next) 1453132718Skan { 1454169689Skan if (node->reachable 1455169689Skan && (DECL_COMDAT (node->decl) 1456169689Skan || (!flag_whole_program 1457169689Skan && TREE_PUBLIC (node->decl) && !DECL_EXTERNAL (node->decl)))) 1458169689Skan node->local.externally_visible = true; 1459169689Skan if (!node->local.externally_visible && node->analyzed 1460169689Skan && !DECL_EXTERNAL (node->decl)) 1461132718Skan { 1462169689Skan gcc_assert (flag_whole_program || !TREE_PUBLIC (node->decl)); 1463169689Skan TREE_PUBLIC (node->decl) = 0; 1464132718Skan } 1465169689Skan node->local.local = (!node->needed 1466169689Skan && node->analyzed 1467169689Skan && !DECL_EXTERNAL (node->decl) 1468169689Skan && !node->local.externally_visible); 1469132718Skan } 1470169689Skan for (vnode = cgraph_varpool_nodes_queue; vnode; vnode = vnode->next_needed) 1471169689Skan { 1472169689Skan if (vnode->needed 1473169689Skan && !flag_whole_program 1474169689Skan && (DECL_COMDAT (vnode->decl) || TREE_PUBLIC (vnode->decl))) 1475169689Skan vnode->externally_visible = 1; 1476169689Skan if (!vnode->externally_visible) 1477169689Skan { 1478169689Skan gcc_assert (flag_whole_program || !TREE_PUBLIC (vnode->decl)); 1479169689Skan TREE_PUBLIC (vnode->decl) = 0; 1480169689Skan } 1481169689Skan gcc_assert (TREE_STATIC (vnode->decl)); 1482169689Skan } 1483132718Skan 1484169689Skan /* Because we have to be conservative on the boundaries of source 1485169689Skan level units, it is possible that we marked some functions in 1486169689Skan reachable just because they might be used later via external 1487169689Skan linkage, but after making them local they are really unreachable 1488169689Skan now. */ 1489169689Skan cgraph_remove_unreachable_nodes (true, cgraph_dump_file); 1490132718Skan 1491169689Skan if (cgraph_dump_file) 1492132718Skan { 1493169689Skan fprintf (cgraph_dump_file, "\nMarking local functions:"); 1494169689Skan for (node = cgraph_nodes; node; node = node->next) 1495169689Skan if (node->local.local) 1496169689Skan fprintf (cgraph_dump_file, " %s", cgraph_node_name (node)); 1497169689Skan fprintf (cgraph_dump_file, "\n\n"); 1498169689Skan fprintf (cgraph_dump_file, "\nMarking externally visible functions:"); 1499169689Skan for (node = cgraph_nodes; node; node = node->next) 1500169689Skan if (node->local.externally_visible) 1501169689Skan fprintf (cgraph_dump_file, " %s", cgraph_node_name (node)); 1502169689Skan fprintf (cgraph_dump_file, "\n\n"); 1503132718Skan } 1504169689Skan cgraph_function_flags_ready = true; 1505132718Skan} 1506132718Skan 1507169689Skan/* Return true when function body of DECL still needs to be kept around 1508169689Skan for later re-use. */ 1509169689Skanbool 1510169689Skancgraph_preserve_function_body_p (tree decl) 1511169689Skan{ 1512169689Skan struct cgraph_node *node; 1513169689Skan if (!cgraph_global_info_ready) 1514169689Skan return (flag_really_no_inline 1515169689Skan ? lang_hooks.tree_inlining.disregard_inline_limits (decl) 1516169689Skan : DECL_INLINE (decl)); 1517169689Skan /* Look if there is any clone around. */ 1518169689Skan for (node = cgraph_node (decl); node; node = node->next_clone) 1519169689Skan if (node->global.inlined_to) 1520169689Skan return true; 1521169689Skan return false; 1522169689Skan} 1523132718Skan 1524169689Skanstatic void 1525169689Skanipa_passes (void) 1526132718Skan{ 1527169689Skan cfun = NULL; 1528169689Skan tree_register_cfg_hooks (); 1529169689Skan bitmap_obstack_initialize (NULL); 1530169689Skan execute_ipa_pass_list (all_ipa_passes); 1531169689Skan bitmap_obstack_release (NULL); 1532169689Skan} 1533132718Skan 1534169689Skan/* Perform simple optimizations based on callgraph. */ 1535132718Skan 1536169689Skanvoid 1537169689Skancgraph_optimize (void) 1538169689Skan{ 1539169689Skan if (errorcount || sorrycount) 1540169689Skan return; 1541132718Skan 1542169689Skan#ifdef ENABLE_CHECKING 1543169689Skan verify_cgraph (); 1544169689Skan#endif 1545169689Skan if (!flag_unit_at_a_time) 1546132718Skan { 1547169689Skan cgraph_output_pending_asms (); 1548169689Skan cgraph_varpool_assemble_pending_decls (); 1549169689Skan cgraph_varpool_output_debug_info (); 1550169689Skan return; 1551132718Skan } 1552132718Skan 1553169689Skan /* Frontend may output common variables after the unit has been finalized. 1554169689Skan It is safe to deal with them here as they are always zero initialized. */ 1555169689Skan cgraph_varpool_analyze_pending_decls (); 1556132718Skan 1557169689Skan timevar_push (TV_CGRAPHOPT); 1558169689Skan if (!quiet_flag) 1559169689Skan fprintf (stderr, "Performing interprocedural optimizations\n"); 1560132718Skan 1561169689Skan cgraph_function_and_variable_visibility (); 1562169689Skan if (cgraph_dump_file) 1563169689Skan { 1564169689Skan fprintf (cgraph_dump_file, "Marked "); 1565169689Skan dump_cgraph (cgraph_dump_file); 1566169689Skan } 1567169689Skan 1568169689Skan /* Don't run the IPA passes if there was any error or sorry messages. */ 1569169689Skan if (errorcount == 0 && sorrycount == 0) 1570169689Skan ipa_passes (); 1571132718Skan 1572169689Skan /* This pass remove bodies of extern inline functions we never inlined. 1573169689Skan Do this later so other IPA passes see what is really going on. */ 1574169689Skan cgraph_remove_unreachable_nodes (false, dump_file); 1575169689Skan cgraph_increase_alignment (); 1576169689Skan cgraph_global_info_ready = true; 1577132718Skan if (cgraph_dump_file) 1578169689Skan { 1579169689Skan fprintf (cgraph_dump_file, "Optimized "); 1580169689Skan dump_cgraph (cgraph_dump_file); 1581169689Skan dump_varpool (cgraph_dump_file); 1582169689Skan } 1583169689Skan timevar_pop (TV_CGRAPHOPT); 1584132718Skan 1585169689Skan /* Output everything. */ 1586169689Skan if (!quiet_flag) 1587169689Skan fprintf (stderr, "Assembling functions:\n"); 1588169689Skan#ifdef ENABLE_CHECKING 1589169689Skan verify_cgraph (); 1590169689Skan#endif 1591132718Skan 1592169689Skan cgraph_mark_functions_to_output (); 1593132718Skan 1594169689Skan if (!flag_toplevel_reorder) 1595169689Skan cgraph_output_in_order (); 1596169689Skan else 1597169689Skan { 1598169689Skan cgraph_output_pending_asms (); 1599132718Skan 1600169689Skan cgraph_expand_all_functions (); 1601169689Skan cgraph_varpool_remove_unreferenced_decls (); 1602132718Skan 1603169689Skan cgraph_varpool_assemble_pending_decls (); 1604169689Skan cgraph_varpool_output_debug_info (); 1605132718Skan } 1606132718Skan 1607132718Skan if (cgraph_dump_file) 1608132718Skan { 1609169689Skan fprintf (cgraph_dump_file, "\nFinal "); 1610169689Skan dump_cgraph (cgraph_dump_file); 1611169689Skan } 1612169689Skan#ifdef ENABLE_CHECKING 1613169689Skan verify_cgraph (); 1614169689Skan /* Double check that all inline clones are gone and that all 1615169689Skan function bodies have been released from memory. */ 1616169689Skan if (flag_unit_at_a_time 1617169689Skan && !(sorrycount || errorcount)) 1618169689Skan { 1619169689Skan struct cgraph_node *node; 1620169689Skan bool error_found = false; 1621132718Skan 1622169689Skan for (node = cgraph_nodes; node; node = node->next) 1623169689Skan if (node->analyzed 1624169689Skan && (node->global.inlined_to 1625169689Skan || DECL_SAVED_TREE (node->decl))) 1626132718Skan { 1627169689Skan error_found = true; 1628169689Skan dump_cgraph_node (stderr, node); 1629132718Skan } 1630169689Skan if (error_found) 1631169689Skan internal_error ("nodes with no released memory found"); 1632169689Skan } 1633169689Skan#endif 1634169689Skan} 1635132718Skan 1636169689Skan/* Increase alignment of global arrays to improve vectorization potential. 1637169689Skan TODO: 1638169689Skan - Consider also structs that have an array field. 1639169689Skan - Use ipa analysis to prune arrays that can't be vectorized? 1640169689Skan This should involve global alignment analysis and in the future also 1641169689Skan array padding. */ 1642132718Skan 1643169689Skanstatic void 1644169689Skancgraph_increase_alignment (void) 1645169689Skan{ 1646169689Skan if (flag_section_anchors && flag_tree_vectorize) 1647169689Skan { 1648169689Skan struct cgraph_varpool_node *vnode; 1649132718Skan 1650169689Skan /* Increase the alignment of all global arrays for vectorization. */ 1651169689Skan for (vnode = cgraph_varpool_nodes_queue; 1652169689Skan vnode; 1653169689Skan vnode = vnode->next_needed) 1654169689Skan { 1655169689Skan tree vectype, decl = vnode->decl; 1656169689Skan unsigned int alignment; 1657132718Skan 1658169689Skan if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE) 1659169689Skan continue; 1660169689Skan vectype = get_vectype_for_scalar_type (TREE_TYPE (TREE_TYPE (decl))); 1661169689Skan if (!vectype) 1662169689Skan continue; 1663169689Skan alignment = TYPE_ALIGN (vectype); 1664169689Skan if (DECL_ALIGN (decl) >= alignment) 1665169689Skan continue; 1666132718Skan 1667169689Skan if (vect_can_force_dr_alignment_p (decl, alignment)) 1668169689Skan { 1669169689Skan DECL_ALIGN (decl) = TYPE_ALIGN (vectype); 1670169689Skan DECL_USER_ALIGN (decl) = 1; 1671169689Skan if (cgraph_dump_file) 1672169689Skan { 1673169689Skan fprintf (cgraph_dump_file, "Increasing alignment of decl: "); 1674169689Skan print_generic_expr (cgraph_dump_file, decl, TDF_SLIM); 1675169689Skan } 1676169689Skan } 1677169689Skan } 1678132718Skan } 1679132718Skan} 1680132718Skan 1681169689Skan/* Generate and emit a static constructor or destructor. WHICH must be 1682169689Skan one of 'I' or 'D'. BODY should be a STATEMENT_LIST containing 1683169689Skan GENERIC statements. */ 1684132718Skan 1685169689Skanvoid 1686169689Skancgraph_build_static_cdtor (char which, tree body, int priority) 1687132718Skan{ 1688169689Skan static int counter = 0; 1689169689Skan char which_buf[16]; 1690169689Skan tree decl, name, resdecl; 1691132718Skan 1692169689Skan sprintf (which_buf, "%c_%d", which, counter++); 1693259563Spfg name = get_file_function_name (which_buf); 1694132718Skan 1695169689Skan decl = build_decl (FUNCTION_DECL, name, 1696169689Skan build_function_type (void_type_node, void_list_node)); 1697169689Skan current_function_decl = decl; 1698132718Skan 1699169689Skan resdecl = build_decl (RESULT_DECL, NULL_TREE, void_type_node); 1700169689Skan DECL_ARTIFICIAL (resdecl) = 1; 1701169689Skan DECL_IGNORED_P (resdecl) = 1; 1702169689Skan DECL_RESULT (decl) = resdecl; 1703132718Skan 1704169689Skan allocate_struct_function (decl); 1705132718Skan 1706169689Skan TREE_STATIC (decl) = 1; 1707169689Skan TREE_USED (decl) = 1; 1708169689Skan DECL_ARTIFICIAL (decl) = 1; 1709169689Skan DECL_IGNORED_P (decl) = 1; 1710169689Skan DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1; 1711169689Skan DECL_SAVED_TREE (decl) = body; 1712169689Skan TREE_PUBLIC (decl) = ! targetm.have_ctors_dtors; 1713169689Skan DECL_UNINLINABLE (decl) = 1; 1714132718Skan 1715169689Skan DECL_INITIAL (decl) = make_node (BLOCK); 1716169689Skan TREE_USED (DECL_INITIAL (decl)) = 1; 1717169689Skan 1718169689Skan DECL_SOURCE_LOCATION (decl) = input_location; 1719169689Skan cfun->function_end_locus = input_location; 1720169689Skan 1721169689Skan switch (which) 1722132718Skan { 1723169689Skan case 'I': 1724169689Skan DECL_STATIC_CONSTRUCTOR (decl) = 1; 1725169689Skan break; 1726169689Skan case 'D': 1727169689Skan DECL_STATIC_DESTRUCTOR (decl) = 1; 1728169689Skan break; 1729169689Skan default: 1730169689Skan gcc_unreachable (); 1731169689Skan } 1732132718Skan 1733169689Skan gimplify_function_tree (decl); 1734132718Skan 1735169689Skan /* ??? We will get called LATE in the compilation process. */ 1736169689Skan if (cgraph_global_info_ready) 1737169689Skan { 1738169689Skan tree_lowering_passes (decl); 1739169689Skan tree_rest_of_compilation (decl); 1740132718Skan } 1741169689Skan else 1742169689Skan cgraph_finalize_function (decl, 0); 1743132718Skan 1744169689Skan if (targetm.have_ctors_dtors) 1745132718Skan { 1746169689Skan void (*fn) (rtx, int); 1747132718Skan 1748169689Skan if (which == 'I') 1749169689Skan fn = targetm.asm_out.constructor; 1750169689Skan else 1751169689Skan fn = targetm.asm_out.destructor; 1752169689Skan fn (XEXP (DECL_RTL (decl), 0), priority); 1753132718Skan } 1754169689Skan} 1755132718Skan 1756169689Skanvoid 1757169689Skaninit_cgraph (void) 1758169689Skan{ 1759169689Skan cgraph_dump_file = dump_begin (TDI_cgraph, NULL); 1760132718Skan} 1761132718Skan 1762169689Skan/* The edges representing the callers of the NEW_VERSION node were 1763169689Skan fixed by cgraph_function_versioning (), now the call_expr in their 1764169689Skan respective tree code should be updated to call the NEW_VERSION. */ 1765132718Skan 1766132718Skanstatic void 1767169689Skanupdate_call_expr (struct cgraph_node *new_version) 1768132718Skan{ 1769132718Skan struct cgraph_edge *e; 1770132718Skan 1771169689Skan gcc_assert (new_version); 1772169689Skan for (e = new_version->callers; e; e = e->next_caller) 1773169689Skan /* Update the call expr on the edges 1774169689Skan to call the new version. */ 1775169689Skan TREE_OPERAND (TREE_OPERAND (get_call_expr_in (e->call_stmt), 0), 0) = new_version->decl; 1776169689Skan} 1777132718Skan 1778132718Skan 1779169689Skan/* Create a new cgraph node which is the new version of 1780169689Skan OLD_VERSION node. REDIRECT_CALLERS holds the callers 1781169689Skan edges which should be redirected to point to 1782169689Skan NEW_VERSION. ALL the callees edges of OLD_VERSION 1783169689Skan are cloned to the new version node. Return the new 1784169689Skan version node. */ 1785132718Skan 1786169689Skanstatic struct cgraph_node * 1787169689Skancgraph_copy_node_for_versioning (struct cgraph_node *old_version, 1788169689Skan tree new_decl, 1789169689Skan VEC(cgraph_edge_p,heap) *redirect_callers) 1790169689Skan { 1791169689Skan struct cgraph_node *new_version; 1792169689Skan struct cgraph_edge *e, *new_e; 1793169689Skan struct cgraph_edge *next_callee; 1794169689Skan unsigned i; 1795132718Skan 1796169689Skan gcc_assert (old_version); 1797132718Skan 1798169689Skan new_version = cgraph_node (new_decl); 1799132718Skan 1800169689Skan new_version->analyzed = true; 1801169689Skan new_version->local = old_version->local; 1802169689Skan new_version->global = old_version->global; 1803169689Skan new_version->rtl = new_version->rtl; 1804169689Skan new_version->reachable = true; 1805169689Skan new_version->count = old_version->count; 1806132718Skan 1807169689Skan /* Clone the old node callees. Recursive calls are 1808169689Skan also cloned. */ 1809169689Skan for (e = old_version->callees;e; e=e->next_callee) 1810169689Skan { 1811169689Skan new_e = cgraph_clone_edge (e, new_version, e->call_stmt, 0, e->loop_nest, true); 1812169689Skan new_e->count = e->count; 1813169689Skan } 1814169689Skan /* Fix recursive calls. 1815169689Skan If OLD_VERSION has a recursive call after the 1816169689Skan previous edge cloning, the new version will have an edge 1817169689Skan pointing to the old version, which is wrong; 1818169689Skan Redirect it to point to the new version. */ 1819169689Skan for (e = new_version->callees ; e; e = next_callee) 1820169689Skan { 1821169689Skan next_callee = e->next_callee; 1822169689Skan if (e->callee == old_version) 1823169689Skan cgraph_redirect_edge_callee (e, new_version); 1824132718Skan 1825169689Skan if (!next_callee) 1826169689Skan break; 1827169689Skan } 1828169689Skan for (i = 0; VEC_iterate (cgraph_edge_p, redirect_callers, i, e); i++) 1829169689Skan { 1830169689Skan /* Redirect calls to the old version node to point to its new 1831169689Skan version. */ 1832169689Skan cgraph_redirect_edge_callee (e, new_version); 1833169689Skan } 1834132718Skan 1835169689Skan return new_version; 1836169689Skan } 1837132718Skan 1838169689Skan /* Perform function versioning. 1839169689Skan Function versioning includes copying of the tree and 1840169689Skan a callgraph update (creating a new cgraph node and updating 1841169689Skan its callees and callers). 1842169689Skan 1843169689Skan REDIRECT_CALLERS varray includes the edges to be redirected 1844169689Skan to the new version. 1845169689Skan 1846169689Skan TREE_MAP is a mapping of tree nodes we want to replace with 1847169689Skan new ones (according to results of prior analysis). 1848169689Skan OLD_VERSION_NODE is the node that is versioned. 1849169689Skan It returns the new version's cgraph node. */ 1850169689Skan 1851169689Skanstruct cgraph_node * 1852169689Skancgraph_function_versioning (struct cgraph_node *old_version_node, 1853169689Skan VEC(cgraph_edge_p,heap) *redirect_callers, 1854169689Skan varray_type tree_map) 1855132718Skan{ 1856169689Skan tree old_decl = old_version_node->decl; 1857169689Skan struct cgraph_node *new_version_node = NULL; 1858169689Skan tree new_decl; 1859132718Skan 1860169689Skan if (!tree_versionable_function_p (old_decl)) 1861169689Skan return NULL; 1862132718Skan 1863169689Skan /* Make a new FUNCTION_DECL tree node for the 1864169689Skan new version. */ 1865169689Skan new_decl = copy_node (old_decl); 1866132718Skan 1867169689Skan /* Create the new version's call-graph node. 1868169689Skan and update the edges of the new node. */ 1869169689Skan new_version_node = 1870169689Skan cgraph_copy_node_for_versioning (old_version_node, new_decl, 1871169689Skan redirect_callers); 1872132718Skan 1873169689Skan /* Copy the OLD_VERSION_NODE function tree to the new version. */ 1874169689Skan tree_function_versioning (old_decl, new_decl, tree_map, false); 1875169689Skan /* Update the call_expr on the edges to call the new version node. */ 1876169689Skan update_call_expr (new_version_node); 1877132718Skan 1878169689Skan /* Update the new version's properties. 1879169689Skan Make The new version visible only within this translation unit. 1880169689Skan ??? We cannot use COMDAT linkage because there is no 1881169689Skan ABI support for this. */ 1882169689Skan DECL_EXTERNAL (new_version_node->decl) = 0; 1883169689Skan DECL_ONE_ONLY (new_version_node->decl) = 0; 1884169689Skan TREE_PUBLIC (new_version_node->decl) = 0; 1885169689Skan DECL_COMDAT (new_version_node->decl) = 0; 1886169689Skan new_version_node->local.externally_visible = 0; 1887169689Skan new_version_node->local.local = 1; 1888169689Skan new_version_node->lowered = true; 1889169689Skan return new_version_node; 1890169689Skan} 1891132718Skan 1892169689Skan/* Produce separate function body for inline clones so the offline copy can be 1893169689Skan modified without affecting them. */ 1894169689Skanstruct cgraph_node * 1895169689Skansave_inline_function_body (struct cgraph_node *node) 1896132718Skan{ 1897169689Skan struct cgraph_node *first_clone; 1898132718Skan 1899169689Skan gcc_assert (node == cgraph_node (node->decl)); 1900132718Skan 1901169689Skan cgraph_lower_function (node); 1902169689Skan 1903169689Skan /* In non-unit-at-a-time we construct full fledged clone we never output to 1904169689Skan assembly file. This clone is pointed out by inline_decl of original function 1905169689Skan and inlining infrastructure knows how to deal with this. */ 1906169689Skan if (!flag_unit_at_a_time) 1907132718Skan { 1908169689Skan struct cgraph_edge *e; 1909169689Skan 1910169689Skan first_clone = cgraph_clone_node (node, node->count, 0, false); 1911169689Skan first_clone->needed = 0; 1912169689Skan first_clone->reachable = 1; 1913169689Skan /* Recursively clone all bodies. */ 1914169689Skan for (e = first_clone->callees; e; e = e->next_callee) 1915169689Skan if (!e->inline_failed) 1916169689Skan cgraph_clone_inlined_nodes (e, true, false); 1917132718Skan } 1918169689Skan else 1919169689Skan first_clone = node->next_clone; 1920132718Skan 1921169689Skan first_clone->decl = copy_node (node->decl); 1922169689Skan node->next_clone = NULL; 1923132718Skan if (!flag_unit_at_a_time) 1924169689Skan node->inline_decl = first_clone->decl; 1925169689Skan first_clone->prev_clone = NULL; 1926169689Skan cgraph_insert_node_to_hashtable (first_clone); 1927169689Skan gcc_assert (first_clone == cgraph_node (first_clone->decl)); 1928132718Skan 1929169689Skan /* Copy the OLD_VERSION_NODE function tree to the new version. */ 1930169689Skan tree_function_versioning (node->decl, first_clone->decl, NULL, true); 1931132718Skan 1932169689Skan DECL_EXTERNAL (first_clone->decl) = 0; 1933169689Skan DECL_ONE_ONLY (first_clone->decl) = 0; 1934169689Skan TREE_PUBLIC (first_clone->decl) = 0; 1935169689Skan DECL_COMDAT (first_clone->decl) = 0; 1936132718Skan 1937169689Skan for (node = first_clone->next_clone; node; node = node->next_clone) 1938169689Skan node->decl = first_clone->decl; 1939169689Skan#ifdef ENABLE_CHECKING 1940169689Skan verify_cgraph_node (first_clone); 1941169689Skan#endif 1942169689Skan return first_clone; 1943132718Skan} 1944169689Skan 1945169689Skan#include "gt-cgraphunit.h" 1946