]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/cgraphunit.c
* doc/include/texinfo.tex: Update to version 2012-05-16.16.
[thirdparty/gcc.git] / gcc / cgraphunit.c
CommitLineData
da5e1e7c 1/* Driver of optimization process
aed6e608 2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
5c8ad8f5 3 2011, 2012 Free Software Foundation, Inc.
ae01b312 4 Contributed by Jan Hubicka
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
8c4c00c1 10Software Foundation; either version 3, or (at your option) any later
ae01b312 11version.
12
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License
8c4c00c1 19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
ae01b312 21
da5e1e7c 22/* This module implements main driver of compilation process.
b0cdf642 23
24 The main scope of this file is to act as an interface in between
da5e1e7c 25 tree based frontends and the backend.
b0cdf642 26
27 The front-end is supposed to use following functionality:
28
29 - cgraph_finalize_function
30
31 This function is called once front-end has parsed whole body of function
32 and it is certain that the function body nor the declaration will change.
33
b326746d 34 (There is one exception needed for implementing GCC extern inline
35 function.)
b0cdf642 36
1d416bd7 37 - varpool_finalize_variable
b0cdf642 38
7bd28bba 39 This function has same behavior as the above but is used for static
b0cdf642 40 variables.
41
cf951b1a 42 - add_asm_node
43
44 Insert new toplevel ASM statement
45
46 - finalize_compilation_unit
b0cdf642 47
b326746d 48 This function is called once (source level) compilation unit is finalized
49 and it will no longer change.
b0cdf642 50
da5e1e7c 51 The symbol table is constructed starting from the trivially needed
52 symbols finalized by the frontend. Functions are lowered into
53 GIMPLE representation and callgraph/reference lists are constructed.
54 Those are used to discover other neccesary functions and variables.
55
56 At the end the bodies of unreachable functions are removed.
b0cdf642 57
b326746d 58 The function can be called multiple times when multiple source level
da5e1e7c 59 compilation units are combined.
b0cdf642 60
cf951b1a 61 - compile
b0cdf642 62
da5e1e7c 63 This passes control to the back-end. Optimizations are performed and
64 final assembler is generated. This is done in the following way. Note
65 that with link time optimization the process is split into three
66 stages (compile time, linktime analysis and parallel linktime as
67 indicated bellow).
68
69 Compile time:
70
71 1) Inter-procedural optimization.
72 (ipa_passes)
73
74 This part is further split into:
75
76 a) early optimizations. These are local passes executed in
77 the topological order on the callgraph.
78
79 The purpose of early optimiations is to optimize away simple
80 things that may otherwise confuse IP analysis. Very simple
81 propagation across the callgraph is done i.e. to discover
82 functions without side effects and simple inlining is performed.
83
84 b) early small interprocedural passes.
85
86 Those are interprocedural passes executed only at compilation
87 time. These include, for exmaple, transational memory lowering,
88 unreachable code removal and other simple transformations.
89
90 c) IP analysis stage. All interprocedural passes do their
91 analysis.
92
93 Interprocedural passes differ from small interprocedural
94 passes by their ability to operate across whole program
95 at linktime. Their analysis stage is performed early to
96 both reduce linking times and linktime memory usage by
97 not having to represent whole program in memory.
98
99 d) LTO sreaming. When doing LTO, everything important gets
100 streamed into the object file.
101
102 Compile time and or linktime analysis stage (WPA):
103
104 At linktime units gets streamed back and symbol table is
105 merged. Function bodies are not streamed in and not
106 available.
107 e) IP propagation stage. All IP passes execute their
108 IP propagation. This is done based on the earlier analysis
109 without having function bodies at hand.
110 f) Ltrans streaming. When doing WHOPR LTO, the program
111 is partitioned and streamed into multple object files.
b0cdf642 112
da5e1e7c 113 Compile time and/or parallel linktime stage (ltrans)
b0cdf642 114
da5e1e7c 115 Each of the object files is streamed back and compiled
116 separately. Now the function bodies becomes available
117 again.
b0cdf642 118
da5e1e7c 119 2) Virtual clone materialization
120 (cgraph_materialize_clone)
b0cdf642 121
da5e1e7c 122 IP passes can produce copies of existing functoins (such
123 as versioned clones or inline clones) without actually
124 manipulating their bodies by creating virtual clones in
125 the callgraph. At this time the virtual clones are
126 turned into real functions
127 3) IP transformation
b0cdf642 128
da5e1e7c 129 All IP passes transform function bodies based on earlier
130 decision of the IP propagation.
b0cdf642 131
da5e1e7c 132 4) late small IP passes
b0cdf642 133
da5e1e7c 134 Simple IP passes working within single program partition.
b0cdf642 135
da5e1e7c 136 5) Expansion
cf951b1a 137 (expand_all_functions)
b0cdf642 138
da5e1e7c 139 At this stage functions that needs to be output into
140 assembler are identified and compiled in topological order
141 6) Output of variables and aliases
142 Now it is known what variable references was not optimized
143 out and thus all variables are output to the file.
b0cdf642 144
da5e1e7c 145 Note that with -fno-toplevel-reorder passes 5 and 6
146 are combined together in cgraph_output_in_order.
b0cdf642 147
da5e1e7c 148 Finally there are functions to manipulate the callgraph from
149 backend.
150 - cgraph_add_new_function is used to add backend produced
151 functions introduced after the unit is finalized.
152 The functions are enqueue for later processing and inserted
153 into callgraph with cgraph_process_new_functions.
121f3051 154
da5e1e7c 155 - cgraph_function_versioning
156
157 produces a copy of function into new one (a version)
158 and apply simple transformations
159*/
acc70efa 160
ae01b312 161#include "config.h"
162#include "system.h"
163#include "coretypes.h"
164#include "tm.h"
165#include "tree.h"
941366fd 166#include "output.h"
b5530559 167#include "rtl.h"
acc70efa 168#include "tree-flow.h"
ae01b312 169#include "tree-inline.h"
170#include "langhooks.h"
c6224531 171#include "pointer-set.h"
ae01b312 172#include "toplev.h"
173#include "flags.h"
174#include "ggc.h"
175#include "debug.h"
176#include "target.h"
177#include "cgraph.h"
80a85d8a 178#include "diagnostic.h"
f79b6507 179#include "timevar.h"
d7c6d889 180#include "params.h"
181#include "fibheap.h"
611e5405 182#include "intl.h"
b69eb0ff 183#include "function.h"
b5d36404 184#include "ipa-prop.h"
75a70cf9 185#include "gimple.h"
186#include "tree-iterator.h"
f1e2a033 187#include "tree-pass.h"
bfec3452 188#include "tree-dump.h"
da5e1e7c 189#include "gimple-pretty-print.h"
c1dcd13c 190#include "output.h"
9ed5b1f5 191#include "coverage.h"
c9036234 192#include "plugin.h"
a41f2a28 193#include "ipa-inline.h"
7771d558 194#include "ipa-utils.h"
a0605d65 195#include "lto-streamer.h"
3db65b62 196#include "except.h"
941366fd 197#include "regset.h" /* FIXME: For reg_obstack. */
d7c6d889 198
ff2a5ada 199/* Queue of cgraph nodes scheduled to be added into cgraph. This is a
200 secondary queue used during optimization to accommodate passes that
201 may generate new functions that need to be optimized and expanded. */
202cgraph_node_set cgraph_new_nodes;
203
cf951b1a 204static void expand_all_functions (void);
205static void mark_functions_to_output (void);
206static void expand_function (struct cgraph_node *);
da5e1e7c 207static void cgraph_analyze_function (struct cgraph_node *);
18a71d50 208static void handle_alias_pairs (void);
25bb88de 209
ecb08119 210FILE *cgraph_dump_file;
121f3051 211
cf951b1a 212/* Linked list of cgraph asm nodes. */
213struct asm_node *asm_nodes;
214
215/* Last node in cgraph_asm_nodes. */
216static GTY(()) struct asm_node *asm_last_node;
217
28454517 218/* Used for vtable lookup in thunk adjusting. */
219static GTY (()) tree vtable_entry_type;
220
8efa224a 221/* Determine if function DECL is trivially needed and should stay in the
222 compilation unit. This is used at the symbol table construction time
223 and differs from later logic removing unnecesary functions that can
224 take into account results of analysis, whole program info etc. */
2c0b522d 225
da5e1e7c 226static bool
7bfefa9d 227cgraph_decide_is_function_needed (struct cgraph_node *node, tree decl)
2c0b522d 228{
3f82b628 229 /* If the user told us it is used, then it must be so. */
8efa224a 230 if (node->symbol.force_output)
05806473 231 return true;
232
8efa224a 233 /* Double check that no one output the function into assembly file
234 early. */
235 gcc_checking_assert (!DECL_ASSEMBLER_NAME_SET_P (decl)
236 || (node->thunk.thunk_p || node->same_body_alias)
237 || !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)));
3f82b628 238
55680bef 239
8efa224a 240 /* Keep constructors, destructors and virtual functions. */
241 if (DECL_STATIC_CONSTRUCTOR (decl)
242 || DECL_STATIC_DESTRUCTOR (decl)
243 || (DECL_VIRTUAL_P (decl)
244 && optimize && (DECL_COMDAT (decl) || DECL_EXTERNAL (decl))))
245 return true;
2c0b522d 246
247 /* Externally visible functions must be output. The exception is
8efa224a 248 COMDAT functions that must be output only when they are needed. */
8baa9d15 249
8efa224a 250 if (TREE_PUBLIC (decl)
62eec3b4 251 && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
2c0b522d 252 return true;
253
2c0b522d 254 return false;
255}
256
ff2a5ada 257/* Head of the queue of nodes to be processed while building callgraph */
258
259static symtab_node first = (symtab_node)(void *)1;
260
261/* Add NODE to queue starting at FIRST.
262 The queue is linked via AUX pointers and terminated by pointer to 1. */
263
264static void
265enqueue_node (symtab_node node)
266{
267 if (node->symbol.aux)
268 return;
269 gcc_checking_assert (first);
270 node->symbol.aux = first;
271 first = node;
272}
273
bdc40eb8 274/* Process CGRAPH_NEW_FUNCTIONS and perform actions necessary to add these
523c1122 275 functions into callgraph in a way so they look like ordinary reachable
276 functions inserted into callgraph already at construction time. */
277
278bool
279cgraph_process_new_functions (void)
280{
281 bool output = false;
282 tree fndecl;
283 struct cgraph_node *node;
ff2a5ada 284 cgraph_node_set_iterator csi;
523c1122 285
ff2a5ada 286 if (!cgraph_new_nodes)
287 return false;
18a71d50 288 handle_alias_pairs ();
523c1122 289 /* Note that this queue may grow as its being processed, as the new
290 functions may generate new ones. */
ff2a5ada 291 for (csi = csi_start (cgraph_new_nodes); !csi_end_p (csi); csi_next (&csi))
523c1122 292 {
ff2a5ada 293 node = csi_node (csi);
7d0d0ce1 294 fndecl = node->symbol.decl;
523c1122 295 switch (cgraph_state)
296 {
297 case CGRAPH_STATE_CONSTRUCTION:
298 /* At construction time we just need to finalize function and move
299 it into reachable functions list. */
300
523c1122 301 cgraph_finalize_function (fndecl, false);
523c1122 302 output = true;
4f7a1122 303 cgraph_call_function_insertion_hooks (node);
ff2a5ada 304 enqueue_node ((symtab_node) node);
523c1122 305 break;
306
307 case CGRAPH_STATE_IPA:
f517b36e 308 case CGRAPH_STATE_IPA_SSA:
523c1122 309 /* When IPA optimization already started, do all essential
310 transformations that has been already performed on the whole
311 cgraph but not on this function. */
312
75a70cf9 313 gimple_register_cfg_hooks ();
523c1122 314 if (!node->analyzed)
315 cgraph_analyze_function (node);
316 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
317 current_function_decl = fndecl;
f517b36e 318 if ((cgraph_state == CGRAPH_STATE_IPA_SSA
319 && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
320 /* When not optimizing, be sure we run early local passes anyway
321 to expand OMP. */
322 || !optimize)
20099e35 323 execute_pass_list (pass_early_local_passes.pass.sub);
649597af 324 else
a41f2a28 325 compute_inline_parameters (node, true);
523c1122 326 free_dominance_info (CDI_POST_DOMINATORS);
327 free_dominance_info (CDI_DOMINATORS);
328 pop_cfun ();
329 current_function_decl = NULL;
4f7a1122 330 cgraph_call_function_insertion_hooks (node);
523c1122 331 break;
332
333 case CGRAPH_STATE_EXPANSION:
334 /* Functions created during expansion shall be compiled
335 directly. */
09fc9532 336 node->process = 0;
4f7a1122 337 cgraph_call_function_insertion_hooks (node);
cf951b1a 338 expand_function (node);
523c1122 339 break;
340
341 default:
342 gcc_unreachable ();
343 break;
344 }
345 }
ff2a5ada 346 free_cgraph_node_set (cgraph_new_nodes);
347 cgraph_new_nodes = NULL;
523c1122 348 return output;
349}
350
9b8fb23a 351/* As an GCC extension we allow redefinition of the function. The
352 semantics when both copies of bodies differ is not well defined.
353 We replace the old body with new body so in unit at a time mode
354 we always use new body, while in normal mode we may end up with
355 old body inlined into some functions and new body expanded and
356 inlined in others.
357
358 ??? It may make more sense to use one body for inlining and other
359 body for expanding the function but this is difficult to do. */
360
361static void
362cgraph_reset_node (struct cgraph_node *node)
363{
09fc9532 364 /* If node->process is set, then we have already begun whole-unit analysis.
6329636b 365 This is *not* testing for whether we've already emitted the function.
366 That case can be sort-of legitimately seen with real function redefinition
367 errors. I would argue that the front end should never present us with
368 such a case, but don't enforce that for now. */
09fc9532 369 gcc_assert (!node->process);
9b8fb23a 370
371 /* Reset our data structures so we can analyze the function again. */
372 memset (&node->local, 0, sizeof (node->local));
373 memset (&node->global, 0, sizeof (node->global));
374 memset (&node->rtl, 0, sizeof (node->rtl));
375 node->analyzed = false;
9b8fb23a 376 node->local.finalized = false;
377
9b8fb23a 378 cgraph_node_remove_callees (node);
9b8fb23a 379}
c08871a9 380
9a2639fc 381/* Return true when there are references to NODE. */
382
383static bool
384referred_to_p (symtab_node node)
385{
9a2639fc 386 struct ipa_ref *ref;
387
cf951b1a 388 /* See if there are any refrences at all. */
389 if (ipa_ref_list_referring_iterate (&node->symbol.ref_list, 0, ref))
9a2639fc 390 return true;
cf951b1a 391 /* For functions check also calls. */
9a2639fc 392 if (symtab_function_p (node) && cgraph (node)->callers)
393 return true;
394 return false;
395}
396
28df663b 397/* DECL has been parsed. Take it, queue it, compile it at the whim of the
398 logic in effect. If NESTED is true, then our caller cannot stand to have
399 the garbage collector run at the moment. We would need to either create
400 a new GC context, or just not compile right now. */
ae01b312 401
402void
28df663b 403cgraph_finalize_function (tree decl, bool nested)
ae01b312 404{
5a90471f 405 struct cgraph_node *node = cgraph_get_create_node (decl);
ae01b312 406
c08871a9 407 if (node->local.finalized)
443089c1 408 {
409 cgraph_reset_node (node);
410 node->local.redefined_extern_inline = true;
411 }
28df663b 412
c08871a9 413 notice_global_symbol (decl);
79bb87b4 414 node->local.finalized = true;
e27482aa 415 node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL;
ae01b312 416
8efa224a 417 /* With -fkeep-inline-functions we are keeping all inline functions except
418 for extern inline ones. */
419 if (flag_keep_inline_functions
420 && DECL_DECLARED_INLINE_P (decl)
421 && !DECL_EXTERNAL (decl)
422 && !DECL_DISREGARD_INLINE_LIMITS (decl))
423 node->symbol.force_output = 1;
2c0b522d 424
8efa224a 425 /* When not optimizing, also output the static functions. (see
426 PR24561), but don't do so for always_inline functions, functions
427 declared inline and nested functions. These were optimized out
428 in the original implementation and it is unclear whether we want
429 to change the behavior here. */
430 if ((!optimize
431 && !node->same_body_alias
432 && !DECL_DISREGARD_INLINE_LIMITS (decl)
433 && !DECL_DECLARED_INLINE_P (decl)
434 && !(DECL_CONTEXT (decl)
435 && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL))
436 && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
437 node->symbol.force_output = 1;
438
2c0b522d 439 /* If we've not yet emitted decl, tell the debug info about it. */
28df663b 440 if (!TREE_ASM_WRITTEN (decl))
2c0b522d 441 (*debug_hooks->deferred_inline_function) (decl);
4e8871a0 442
b69eb0ff 443 /* Possibly warn about unused parameters. */
444 if (warn_unused_parameter)
445 do_warn_unused_parameter (decl);
6329636b 446
447 if (!nested)
448 ggc_collect ();
9a2639fc 449
450 if (cgraph_state == CGRAPH_STATE_CONSTRUCTION
451 && (cgraph_decide_is_function_needed (node, decl)
452 || referred_to_p ((symtab_node)node)))
453 enqueue_node ((symtab_node)node);
ae01b312 454}
455
3db65b62 456/* Add the function FNDECL to the call graph.
457 Unlike cgraph_finalize_function, this function is intended to be used
458 by middle end and allows insertion of new function at arbitrary point
459 of compilation. The function can be either in high, low or SSA form
460 GIMPLE.
461
462 The function is assumed to be reachable and have address taken (so no
463 API breaking optimizations are performed on it).
464
465 Main work done by this function is to enqueue the function for later
466 processing to avoid need the passes to be re-entrant. */
467
468void
469cgraph_add_new_function (tree fndecl, bool lowered)
470{
471 struct cgraph_node *node;
472 switch (cgraph_state)
473 {
ff2a5ada 474 case CGRAPH_STATE_PARSING:
475 cgraph_finalize_function (fndecl, false);
476 break;
3db65b62 477 case CGRAPH_STATE_CONSTRUCTION:
478 /* Just enqueue function to be processed at nearest occurrence. */
479 node = cgraph_create_node (fndecl);
3db65b62 480 if (lowered)
481 node->lowered = true;
ff2a5ada 482 if (!cgraph_new_nodes)
483 cgraph_new_nodes = cgraph_node_set_new ();
484 cgraph_node_set_add (cgraph_new_nodes, node);
3db65b62 485 break;
486
487 case CGRAPH_STATE_IPA:
488 case CGRAPH_STATE_IPA_SSA:
489 case CGRAPH_STATE_EXPANSION:
490 /* Bring the function into finalized state and enqueue for later
491 analyzing and compilation. */
492 node = cgraph_get_create_node (fndecl);
493 node->local.local = false;
494 node->local.finalized = true;
da751785 495 node->symbol.force_output = true;
3db65b62 496 if (!lowered && cgraph_state == CGRAPH_STATE_EXPANSION)
497 {
498 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
499 current_function_decl = fndecl;
500 gimple_register_cfg_hooks ();
501 bitmap_obstack_initialize (NULL);
502 execute_pass_list (all_lowering_passes);
503 execute_pass_list (pass_early_local_passes.pass.sub);
504 bitmap_obstack_release (NULL);
505 pop_cfun ();
506 current_function_decl = NULL;
507
508 lowered = true;
509 }
510 if (lowered)
511 node->lowered = true;
ff2a5ada 512 if (!cgraph_new_nodes)
513 cgraph_new_nodes = cgraph_node_set_new ();
514 cgraph_node_set_add (cgraph_new_nodes, node);
3db65b62 515 break;
516
517 case CGRAPH_STATE_FINISHED:
518 /* At the very end of compilation we have to do all the work up
519 to expansion. */
520 node = cgraph_create_node (fndecl);
521 if (lowered)
522 node->lowered = true;
523 cgraph_analyze_function (node);
524 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
525 current_function_decl = fndecl;
526 gimple_register_cfg_hooks ();
527 bitmap_obstack_initialize (NULL);
528 if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
529 execute_pass_list (pass_early_local_passes.pass.sub);
530 bitmap_obstack_release (NULL);
3db65b62 531 pop_cfun ();
cf951b1a 532 expand_function (node);
3db65b62 533 current_function_decl = NULL;
534 break;
535
536 default:
537 gcc_unreachable ();
538 }
539
540 /* Set a personality if required and we already passed EH lowering. */
541 if (lowered
542 && (function_needs_eh_personality (DECL_STRUCT_FUNCTION (fndecl))
543 == eh_personality_lang))
544 DECL_FUNCTION_PERSONALITY (fndecl) = lang_hooks.eh_personality ();
545}
546
cf951b1a 547/* Add a top-level asm statement to the list. */
548
549struct asm_node *
550add_asm_node (tree asm_str)
551{
552 struct asm_node *node;
553
554 node = ggc_alloc_cleared_asm_node ();
555 node->asm_str = asm_str;
556 node->order = symtab_order++;
557 node->next = NULL;
558 if (asm_nodes == NULL)
559 asm_nodes = node;
560 else
561 asm_last_node->next = node;
562 asm_last_node = node;
563 return node;
564}
565
56af936e 566/* Output all asm statements we have stored up to be output. */
567
568static void
cf951b1a 569output_asm_statements (void)
56af936e 570{
cf951b1a 571 struct asm_node *can;
56af936e 572
852f689e 573 if (seen_error ())
56af936e 574 return;
575
cf951b1a 576 for (can = asm_nodes; can; can = can->next)
56af936e 577 assemble_asm (can->asm_str);
cf951b1a 578 asm_nodes = NULL;
579}
580
581/* C++ FE sometimes change linkage flags after producing same body aliases. */
582void
583fixup_same_cpp_alias_visibility (symtab_node node, symtab_node target, tree alias)
584{
585 DECL_VIRTUAL_P (node->symbol.decl) = DECL_VIRTUAL_P (alias);
586 if (TREE_PUBLIC (node->symbol.decl))
587 {
588 DECL_EXTERNAL (node->symbol.decl) = DECL_EXTERNAL (alias);
589 DECL_COMDAT (node->symbol.decl) = DECL_COMDAT (alias);
590 DECL_COMDAT_GROUP (node->symbol.decl) = DECL_COMDAT_GROUP (alias);
591 if (DECL_ONE_ONLY (alias)
592 && !node->symbol.same_comdat_group)
593 symtab_add_to_same_comdat_group ((symtab_node)node, (symtab_node)target);
594 }
56af936e 595}
596
0785e435 597/* Analyze the function scheduled to be output. */
da5e1e7c 598static void
0785e435 599cgraph_analyze_function (struct cgraph_node *node)
600{
bfec3452 601 tree save = current_function_decl;
7d0d0ce1 602 tree decl = node->symbol.decl;
da5e1e7c 603 location_t saved_loc = input_location;
604 input_location = DECL_SOURCE_LOCATION (decl);
0785e435 605
c70f46b0 606 if (node->alias && node->thunk.alias)
607 {
608 struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias);
b0898cb7 609 struct cgraph_node *n;
610
611 for (n = tgt; n && n->alias;
612 n = n->analyzed ? cgraph_alias_aliased_node (n) : NULL)
613 if (n == node)
614 {
7d0d0ce1 615 error ("function %q+D part of alias cycle", node->symbol.decl);
b0898cb7 616 node->alias = false;
da5e1e7c 617 input_location = saved_loc;
b0898cb7 618 return;
619 }
7d0d0ce1 620 if (!VEC_length (ipa_ref_t, node->symbol.ref_list.references))
04ec15fa 621 ipa_record_reference ((symtab_node)node, (symtab_node)tgt,
622 IPA_REF_ALIAS, NULL);
c70f46b0 623 if (node->same_body_alias)
624 {
7d0d0ce1 625 DECL_DECLARED_INLINE_P (node->symbol.decl)
c70f46b0 626 = DECL_DECLARED_INLINE_P (node->thunk.alias);
7d0d0ce1 627 DECL_DISREGARD_INLINE_LIMITS (node->symbol.decl)
c70f46b0 628 = DECL_DISREGARD_INLINE_LIMITS (node->thunk.alias);
cf951b1a 629 fixup_same_cpp_alias_visibility ((symtab_node) node, (symtab_node) tgt, node->thunk.alias);
c70f46b0 630 }
631
7d0d0ce1 632 if (node->symbol.address_taken)
c70f46b0 633 cgraph_mark_address_taken_node (cgraph_alias_aliased_node (node));
c70f46b0 634 }
635 else if (node->thunk.thunk_p)
91bf9d9a 636 {
637 cgraph_create_edge (node, cgraph_get_node (node->thunk.alias),
638 NULL, 0, CGRAPH_FREQ_BASE);
639 }
640 else
641 {
642 current_function_decl = decl;
643 push_cfun (DECL_STRUCT_FUNCTION (decl));
bfec3452 644
7d0d0ce1 645 assign_assembler_name_if_neeeded (node->symbol.decl);
6816d0c4 646
91bf9d9a 647 /* Make sure to gimplify bodies only once. During analyzing a
648 function we lower it, which will require gimplified nested
649 functions, so we can end up here with an already gimplified
650 body. */
e3a19533 651 if (!gimple_has_body_p (decl))
91bf9d9a 652 gimplify_function_tree (decl);
653 dump_function (TDI_generic, decl);
bfec3452 654
47199071 655 /* Lower the function. */
656 if (!node->lowered)
657 {
658 if (node->nested)
7d0d0ce1 659 lower_nested_functions (node->symbol.decl);
47199071 660 gcc_assert (!node->nested);
661
662 gimple_register_cfg_hooks ();
663 bitmap_obstack_initialize (NULL);
664 execute_pass_list (all_lowering_passes);
665 free_dominance_info (CDI_POST_DOMINATORS);
666 free_dominance_info (CDI_DOMINATORS);
667 compact_blocks ();
668 bitmap_obstack_release (NULL);
669 node->lowered = true;
670 }
671
91bf9d9a 672 pop_cfun ();
673 }
6e8d6e86 674 node->analyzed = true;
0785e435 675
bfec3452 676 current_function_decl = save;
da5e1e7c 677 input_location = saved_loc;
0785e435 678}
679
c70f46b0 680/* C++ frontend produce same body aliases all over the place, even before PCH
681 gets streamed out. It relies on us linking the aliases with their function
682 in order to do the fixups, but ipa-ref is not PCH safe. Consequentely we
683 first produce aliases without links, but once C++ FE is sure he won't sream
684 PCH we build the links via this function. */
685
686void
687cgraph_process_same_body_aliases (void)
688{
689 struct cgraph_node *node;
7c455d87 690 FOR_EACH_FUNCTION (node)
c70f46b0 691 if (node->same_body_alias
7d0d0ce1 692 && !VEC_length (ipa_ref_t, node->symbol.ref_list.references))
c70f46b0 693 {
694 struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias);
04ec15fa 695 ipa_record_reference ((symtab_node)node, (symtab_node)tgt,
696 IPA_REF_ALIAS, NULL);
c70f46b0 697 }
698 same_body_aliases_done = true;
699}
700
d05db70d 701/* Process attributes common for vars and functions. */
702
703static void
704process_common_attributes (tree decl)
705{
706 tree weakref = lookup_attribute ("weakref", DECL_ATTRIBUTES (decl));
707
708 if (weakref && !lookup_attribute ("alias", DECL_ATTRIBUTES (decl)))
709 {
710 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
711 "%<weakref%> attribute should be accompanied with"
712 " an %<alias%> attribute");
713 DECL_WEAK (decl) = 0;
40b32d93 714 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
715 DECL_ATTRIBUTES (decl));
d05db70d 716 }
717}
718
05806473 719/* Look for externally_visible and used attributes and mark cgraph nodes
720 accordingly.
721
722 We cannot mark the nodes at the point the attributes are processed (in
723 handle_*_attribute) because the copy of the declarations available at that
724 point may not be canonical. For example, in:
725
726 void f();
727 void f() __attribute__((used));
728
729 the declaration we see in handle_used_attribute will be the second
730 declaration -- but the front end will subsequently merge that declaration
731 with the original declaration and discard the second declaration.
732
733 Furthermore, we can't mark these nodes in cgraph_finalize_function because:
734
735 void f() {}
736 void f() __attribute__((externally_visible));
737
738 is valid.
739
740 So, we walk the nodes at the end of the translation unit, applying the
741 attributes at that point. */
742
743static void
744process_function_and_variable_attributes (struct cgraph_node *first,
1d416bd7 745 struct varpool_node *first_var)
05806473 746{
747 struct cgraph_node *node;
1d416bd7 748 struct varpool_node *vnode;
05806473 749
0704fb2e 750 for (node = cgraph_first_function (); node != first;
751 node = cgraph_next_function (node))
05806473 752 {
7d0d0ce1 753 tree decl = node->symbol.decl;
83a23b05 754 if (DECL_PRESERVE_P (decl))
8efa224a 755 cgraph_mark_force_output_node (node);
62433d51 756 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
05806473 757 {
7d0d0ce1 758 if (! TREE_PUBLIC (node->symbol.decl))
759 warning_at (DECL_SOURCE_LOCATION (node->symbol.decl), OPT_Wattributes,
712d2297 760 "%<externally_visible%>"
761 " attribute have effect only on public objects");
05806473 762 }
40b32d93 763 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
c70f46b0 764 && (node->local.finalized && !node->alias))
40b32d93 765 {
7d0d0ce1 766 warning_at (DECL_SOURCE_LOCATION (node->symbol.decl), OPT_Wattributes,
40b32d93 767 "%<weakref%> attribute ignored"
768 " because function is defined");
769 DECL_WEAK (decl) = 0;
770 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
771 DECL_ATTRIBUTES (decl));
772 }
a522e9eb 773
774 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl))
775 && !DECL_DECLARED_INLINE_P (decl)
776 /* redefining extern inline function makes it DECL_UNINLINABLE. */
777 && !DECL_UNINLINABLE (decl))
778 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
779 "always_inline function might not be inlinable");
780
d05db70d 781 process_common_attributes (decl);
05806473 782 }
0704fb2e 783 for (vnode = varpool_first_variable (); vnode != first_var;
784 vnode = varpool_next_variable (vnode))
05806473 785 {
7d0d0ce1 786 tree decl = vnode->symbol.decl;
aa419a52 787 if (DECL_EXTERNAL (decl)
788 && DECL_INITIAL (decl)
789 && const_value_known_p (decl))
790 varpool_finalize_decl (decl);
83a23b05 791 if (DECL_PRESERVE_P (decl))
ff2a5ada 792 vnode->symbol.force_output = true;
62433d51 793 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
05806473 794 {
7d0d0ce1 795 if (! TREE_PUBLIC (vnode->symbol.decl))
796 warning_at (DECL_SOURCE_LOCATION (vnode->symbol.decl), OPT_Wattributes,
712d2297 797 "%<externally_visible%>"
798 " attribute have effect only on public objects");
05806473 799 }
40b32d93 800 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
801 && vnode->finalized
802 && DECL_INITIAL (decl))
803 {
7d0d0ce1 804 warning_at (DECL_SOURCE_LOCATION (vnode->symbol.decl), OPT_Wattributes,
40b32d93 805 "%<weakref%> attribute ignored"
806 " because variable is initialized");
807 DECL_WEAK (decl) = 0;
808 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
809 DECL_ATTRIBUTES (decl));
810 }
d05db70d 811 process_common_attributes (decl);
05806473 812 }
813}
814
ff2a5ada 815/* Mark DECL as finalized. By finalizing the declaration, frontend instruct the
816 middle end to output the variable to asm file, if needed or externally
817 visible. */
818
819void
820varpool_finalize_decl (tree decl)
821{
822 struct varpool_node *node = varpool_node (decl);
823
2d4bf241 824 gcc_assert (TREE_STATIC (decl) || DECL_EXTERNAL (decl));
ff2a5ada 825
826 if (node->finalized)
827 return;
828 notice_global_symbol (decl);
829 node->finalized = true;
830 if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
831 /* Traditionally we do not eliminate static variables when not
832 optimizing and when not doing toplevel reoder. */
833 || (!flag_toplevel_reorder && !DECL_COMDAT (node->symbol.decl)
834 && !DECL_ARTIFICIAL (node->symbol.decl)))
835 node->symbol.force_output = true;
836
837 if (cgraph_state == CGRAPH_STATE_CONSTRUCTION
838 && (decide_is_variable_needed (node, decl)
839 || referred_to_p ((symtab_node)node)))
840 enqueue_node ((symtab_node)node);
841 if (cgraph_state >= CGRAPH_STATE_IPA_SSA)
842 varpool_analyze_node (node);
3d1c0354 843 /* Some frontends produce various interface variables after compilation
844 finished. */
845 if (cgraph_state == CGRAPH_STATE_FINISHED)
846 varpool_assemble_decl (node);
ff2a5ada 847}
848
849/* Discover all functions and variables that are trivially needed, analyze
850 them as well as all functions and variables referred by them */
ae01b312 851
aeeb194b 852static void
853cgraph_analyze_functions (void)
ae01b312 854{
c1dcd13c 855 /* Keep track of already processed nodes when called multiple times for
06b27565 856 intermodule optimization. */
c1dcd13c 857 static struct cgraph_node *first_analyzed;
ff2a5ada 858 struct cgraph_node *first_handled = first_analyzed;
1d416bd7 859 static struct varpool_node *first_analyzed_var;
ff2a5ada 860 struct varpool_node *first_handled_var = first_analyzed_var;
861
862 symtab_node node, next;
863 int i;
864 struct ipa_ref *ref;
865 bool changed = true;
ae01b312 866
f1c35659 867 bitmap_obstack_initialize (NULL);
ff2a5ada 868 cgraph_state = CGRAPH_STATE_CONSTRUCTION;
ae01b312 869
ff2a5ada 870 /* Analysis adds static variables that in turn adds references to new functions.
871 So we need to iterate the process until it stabilize. */
872 while (changed)
ae01b312 873 {
ff2a5ada 874 changed = false;
875 process_function_and_variable_attributes (first_analyzed,
876 first_analyzed_var);
877
878 /* First identify the trivially needed symbols. */
879 for (node = symtab_nodes;
880 node != (symtab_node)first_analyzed
881 && node != (symtab_node)first_analyzed_var; node = node->symbol.next)
9b8fb23a 882 {
ff2a5ada 883 if ((symtab_function_p (node)
884 && cgraph (node)->local.finalized
885 && cgraph_decide_is_function_needed (cgraph (node), node->symbol.decl))
886 || (symtab_variable_p (node)
887 && varpool (node)->finalized
888 && !DECL_EXTERNAL (node->symbol.decl)
889 && decide_is_variable_needed (varpool (node), node->symbol.decl)))
890 {
891 enqueue_node (node);
892 if (!changed && cgraph_dump_file)
893 fprintf (cgraph_dump_file, "Trivially needed symbols:");
894 changed = true;
895 if (cgraph_dump_file)
896 fprintf (cgraph_dump_file, " %s", symtab_node_asm_name (node));
897 }
898 if (node == (symtab_node)first_analyzed
899 || node == (symtab_node)first_analyzed_var)
900 break;
9b8fb23a 901 }
ff2a5ada 902 cgraph_process_new_functions ();
903 first_analyzed_var = varpool_first_variable ();
904 first_analyzed = cgraph_first_function ();
638531ad 905
ff2a5ada 906 if (changed && dump_file)
907 fprintf (cgraph_dump_file, "\n");
2c0b522d 908
ff2a5ada 909 /* Lower representation, build callgraph edges and references for all trivially
910 needed symbols and all symbols referred by them. */
911 while (first != (symtab_node)(void *)1)
61c2c7b1 912 {
ff2a5ada 913 changed = true;
914 node = first;
915 first = (symtab_node)first->symbol.aux;
916 if (symtab_function_p (node) && cgraph (node)->local.finalized)
917 {
918 struct cgraph_edge *edge;
919 struct cgraph_node *cnode;
920 tree decl;
921
922 cnode = cgraph (node);
923 decl = cnode->symbol.decl;
924
925 /* ??? It is possible to create extern inline function and later using
926 weak alias attribute to kill its body. See
927 gcc.c-torture/compile/20011119-1.c */
928 if (!DECL_STRUCT_FUNCTION (decl)
929 && (!cnode->alias || !cnode->thunk.alias)
930 && !cnode->thunk.thunk_p)
931 {
932 cgraph_reset_node (cnode);
933 cnode->local.redefined_extern_inline = true;
934 continue;
935 }
61c2c7b1 936
ff2a5ada 937 if (!cnode->analyzed)
938 cgraph_analyze_function (cnode);
d544ceff 939
ff2a5ada 940 for (edge = cnode->callees; edge; edge = edge->next_callee)
da751785 941 if (edge->callee->local.finalized)
942 enqueue_node ((symtab_node)edge->callee);
ff2a5ada 943
944 /* If decl is a clone of an abstract function, mark that abstract
945 function so that we don't release its body. The DECL_INITIAL() of that
946 abstract function declaration will be later needed to output debug
947 info. */
948 if (DECL_ABSTRACT_ORIGIN (decl))
949 {
950 struct cgraph_node *origin_node;
951 origin_node = cgraph_get_node (DECL_ABSTRACT_ORIGIN (decl));
952 origin_node->abstract_and_needed = true;
953 }
954
955 }
956 else if (symtab_variable_p (node)
957 && varpool (node)->finalized)
da751785 958 varpool_analyze_node (varpool (node));
ff2a5ada 959
960 if (node->symbol.same_comdat_group)
961 {
962 symtab_node next;
963 for (next = node->symbol.same_comdat_group;
964 next != node;
965 next = next->symbol.same_comdat_group)
966 enqueue_node (next);
967 }
968 for (i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list, i, ref); i++)
969 if ((symtab_function_p (ref->referred) && cgraph (ref->referred)->local.finalized)
970 || (symtab_variable_p (ref->referred) && varpool (ref->referred)->finalized))
971 enqueue_node (ref->referred);
972 cgraph_process_new_functions ();
973 }
ae01b312 974 }
2c0b522d 975
aa5e06c7 976 /* Collect entry points to the unit. */
f79b6507 977 if (cgraph_dump_file)
3d7bfc56 978 {
e4200070 979 fprintf (cgraph_dump_file, "\n\nInitial ");
18841b0c 980 dump_symtab (cgraph_dump_file);
3d7bfc56 981 }
e6d2b2d8 982
f79b6507 983 if (cgraph_dump_file)
ff2a5ada 984 fprintf (cgraph_dump_file, "\nRemoving unused symbols:");
ae01b312 985
ff2a5ada 986 for (node = symtab_nodes;
987 node != (symtab_node)first_handled
988 && node != (symtab_node)first_handled_var; node = next)
ae01b312 989 {
ff2a5ada 990 next = node->symbol.next;
991 if (!node->symbol.aux && !referred_to_p (node))
ae01b312 992 {
f79b6507 993 if (cgraph_dump_file)
ff2a5ada 994 fprintf (cgraph_dump_file, " %s", symtab_node_name (node));
995 symtab_remove_node (node);
9b8fb23a 996 continue;
ae01b312 997 }
ff2a5ada 998 if (symtab_function_p (node))
999 {
1000 tree decl = node->symbol.decl;
1001 struct cgraph_node *cnode = cgraph (node);
1002
1003 if (cnode->local.finalized && !gimple_has_body_p (decl)
1004 && (!cnode->alias || !cnode->thunk.alias)
1005 && !cnode->thunk.thunk_p)
1006 cgraph_reset_node (cnode);
1007
1008 gcc_assert (!cnode->local.finalized || cnode->thunk.thunk_p
1009 || cnode->alias
1010 || gimple_has_body_p (decl));
1011 gcc_assert (cnode->analyzed == cnode->local.finalized);
1012 }
1013 node->symbol.aux = NULL;
ae01b312 1014 }
ff2a5ada 1015 first_analyzed = cgraph_first_function ();
1016 first_analyzed_var = varpool_first_variable ();
f79b6507 1017 if (cgraph_dump_file)
e4200070 1018 {
1019 fprintf (cgraph_dump_file, "\n\nReclaimed ");
18841b0c 1020 dump_symtab (cgraph_dump_file);
e4200070 1021 }
f1c35659 1022 bitmap_obstack_release (NULL);
ae01b312 1023 ggc_collect ();
aeeb194b 1024}
1025
3a849bc1 1026/* Translate the ugly representation of aliases as alias pairs into nice
1027 representation in callgraph. We don't handle all cases yet,
1028 unforutnately. */
1029
1030static void
1031handle_alias_pairs (void)
1032{
1033 alias_pair *p;
1034 unsigned i;
3a849bc1 1035
1036 for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p);)
1037 {
48c84ee3 1038 symtab_node target_node = symtab_node_for_asm (p->target);
1039
badeded8 1040 /* Weakrefs with target not defined in current unit are easy to handle; they
1041 behave just as external variables except we need to note the alias flag
1042 to later output the weakref pseudo op into asm file. */
48c84ee3 1043 if (!target_node && lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL)
badeded8 1044 {
1045 if (TREE_CODE (p->decl) == FUNCTION_DECL)
1046 cgraph_get_create_node (p->decl)->alias = true;
1047 else
1048 varpool_get_node (p->decl)->alias = true;
1049 DECL_EXTERNAL (p->decl) = 1;
1050 VEC_unordered_remove (alias_pair, alias_pairs, i);
48c84ee3 1051 continue;
badeded8 1052 }
48c84ee3 1053 else if (!target_node)
3a849bc1 1054 {
48c84ee3 1055 error ("%q+D aliased to undefined symbol %qE", p->decl, p->target);
1056 VEC_unordered_remove (alias_pair, alias_pairs, i);
1057 continue;
1058 }
1059
1060 /* Normally EXTERNAL flag is used to mark external inlines,
1061 however for aliases it seems to be allowed to use it w/o
1062 any meaning. See gcc.dg/attr-alias-3.c
1063 However for weakref we insist on EXTERNAL flag being set.
1064 See gcc.dg/attr-alias-5.c */
1065 if (DECL_EXTERNAL (p->decl))
1066 DECL_EXTERNAL (p->decl)
1067 = lookup_attribute ("weakref",
1068 DECL_ATTRIBUTES (p->decl)) != NULL;
3a849bc1 1069
afea39ad 1070 if (DECL_EXTERNAL (target_node->symbol.decl)
1071 /* We use local aliases for C++ thunks to force the tailcall
1072 to bind locally. This is a hack - to keep it working do
1073 the following (which is not strictly correct). */
1074 && (! TREE_CODE (target_node->symbol.decl) == FUNCTION_DECL
1075 || ! DECL_VIRTUAL_P (target_node->symbol.decl))
1076 && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)))
1077 {
1078 error ("%q+D aliased to external symbol %qE",
1079 p->decl, p->target);
1080 }
1081
48c84ee3 1082 if (TREE_CODE (p->decl) == FUNCTION_DECL
1083 && target_node && symtab_function_p (target_node))
1084 {
1085 struct cgraph_node *src_node = cgraph_get_node (p->decl);
1086 if (src_node && src_node->local.finalized)
1087 cgraph_reset_node (src_node);
1088 cgraph_create_function_alias (p->decl, target_node->symbol.decl);
1089 VEC_unordered_remove (alias_pair, alias_pairs, i);
1090 }
1091 else if (TREE_CODE (p->decl) == VAR_DECL
1092 && target_node && symtab_variable_p (target_node))
1093 {
1094 varpool_create_variable_alias (p->decl, target_node->symbol.decl);
1095 VEC_unordered_remove (alias_pair, alias_pairs, i);
1096 }
1097 else
1098 {
1099 error ("%q+D alias in between function and variable is not supported",
1100 p->decl);
1101 warning (0, "%q+D aliased declaration",
1102 target_node->symbol.decl);
1103 VEC_unordered_remove (alias_pair, alias_pairs, i);
3a849bc1 1104 }
1105 }
18a71d50 1106 VEC_free (alias_pair, gc, alias_pairs);
3a849bc1 1107}
1108
8f69fd82 1109
ae01b312 1110/* Figure out what functions we want to assemble. */
1111
1112static void
cf951b1a 1113mark_functions_to_output (void)
ae01b312 1114{
1115 struct cgraph_node *node;
61c2c7b1 1116#ifdef ENABLE_CHECKING
1117 bool check_same_comdat_groups = false;
1118
7c455d87 1119 FOR_EACH_FUNCTION (node)
61c2c7b1 1120 gcc_assert (!node->process);
1121#endif
ae01b312 1122
7c455d87 1123 FOR_EACH_FUNCTION (node)
ae01b312 1124 {
7d0d0ce1 1125 tree decl = node->symbol.decl;
a0c938f0 1126
7d0d0ce1 1127 gcc_assert (!node->process || node->symbol.same_comdat_group);
61c2c7b1 1128 if (node->process)
1129 continue;
d7c6d889 1130
e6d2b2d8 1131 /* We need to output all local functions that are used and not
1132 always inlined, as well as those that are reachable from
1133 outside the current compilation unit. */
1a1a827a 1134 if (node->analyzed
91bf9d9a 1135 && !node->thunk.thunk_p
c70f46b0 1136 && !node->alias
b0cdf642 1137 && !node->global.inlined_to
4ee9c684 1138 && !TREE_ASM_WRITTEN (decl)
ae01b312 1139 && !DECL_EXTERNAL (decl))
61c2c7b1 1140 {
1141 node->process = 1;
7d0d0ce1 1142 if (node->symbol.same_comdat_group)
61c2c7b1 1143 {
1144 struct cgraph_node *next;
7d0d0ce1 1145 for (next = cgraph (node->symbol.same_comdat_group);
61c2c7b1 1146 next != node;
7d0d0ce1 1147 next = cgraph (next->symbol.same_comdat_group))
c70f46b0 1148 if (!next->thunk.thunk_p && !next->alias)
91bf9d9a 1149 next->process = 1;
61c2c7b1 1150 }
1151 }
7d0d0ce1 1152 else if (node->symbol.same_comdat_group)
61c2c7b1 1153 {
1154#ifdef ENABLE_CHECKING
1155 check_same_comdat_groups = true;
1156#endif
1157 }
cc636d56 1158 else
9cee7c3f 1159 {
1160 /* We should've reclaimed all functions that are not needed. */
1161#ifdef ENABLE_CHECKING
75a70cf9 1162 if (!node->global.inlined_to
1a1a827a 1163 && gimple_has_body_p (decl)
08843223 1164 /* FIXME: in ltrans unit when offline copy is outside partition but inline copies
1165 are inside partition, we can end up not removing the body since we no longer
1166 have analyzed node pointing to it. */
7d0d0ce1 1167 && !node->symbol.in_other_partition
c70f46b0 1168 && !node->alias
2d4bf241 1169 && !node->clones
9cee7c3f 1170 && !DECL_EXTERNAL (decl))
1171 {
1172 dump_cgraph_node (stderr, node);
1173 internal_error ("failed to reclaim unneeded function");
1174 }
1175#endif
75a70cf9 1176 gcc_assert (node->global.inlined_to
1a1a827a 1177 || !gimple_has_body_p (decl)
7d0d0ce1 1178 || node->symbol.in_other_partition
aa419a52 1179 || node->clones
1180 || DECL_ARTIFICIAL (decl)
9cee7c3f 1181 || DECL_EXTERNAL (decl));
1182
1183 }
a0c938f0 1184
961e3b13 1185 }
61c2c7b1 1186#ifdef ENABLE_CHECKING
1187 if (check_same_comdat_groups)
7c455d87 1188 FOR_EACH_FUNCTION (node)
7d0d0ce1 1189 if (node->symbol.same_comdat_group && !node->process)
61c2c7b1 1190 {
7d0d0ce1 1191 tree decl = node->symbol.decl;
61c2c7b1 1192 if (!node->global.inlined_to
1193 && gimple_has_body_p (decl)
6d36105a 1194 /* FIXME: in an ltrans unit when the offline copy is outside a
1195 partition but inline copies are inside a partition, we can
1196 end up not removing the body since we no longer have an
1197 analyzed node pointing to it. */
7d0d0ce1 1198 && !node->symbol.in_other_partition
afea39ad 1199 && !node->clones
61c2c7b1 1200 && !DECL_EXTERNAL (decl))
1201 {
1202 dump_cgraph_node (stderr, node);
6d36105a 1203 internal_error ("failed to reclaim unneeded function in same "
1204 "comdat group");
61c2c7b1 1205 }
1206 }
1207#endif
961e3b13 1208}
1209
28454517 1210/* DECL is FUNCTION_DECL. Initialize datastructures so DECL is a function
1211 in lowered gimple form.
1212
1213 Set current_function_decl and cfun to newly constructed empty function body.
1214 return basic block in the function body. */
1215
1216static basic_block
1217init_lowered_empty_function (tree decl)
1218{
1219 basic_block bb;
1220
1221 current_function_decl = decl;
1222 allocate_struct_function (decl, false);
1223 gimple_register_cfg_hooks ();
1224 init_empty_tree_cfg ();
1225 init_tree_ssa (cfun);
5084b2e4 1226 init_ssa_operands (cfun);
28454517 1227 cfun->gimple_df->in_ssa_p = true;
1228 DECL_INITIAL (decl) = make_node (BLOCK);
1229
1230 DECL_SAVED_TREE (decl) = error_mark_node;
1231 cfun->curr_properties |=
1232 (PROP_gimple_lcf | PROP_gimple_leh | PROP_cfg | PROP_referenced_vars |
657e3a56 1233 PROP_ssa | PROP_gimple_any);
28454517 1234
1235 /* Create BB for body of the function and connect it properly. */
1236 bb = create_basic_block (NULL, (void *) 0, ENTRY_BLOCK_PTR);
167ef6d9 1237 make_edge (ENTRY_BLOCK_PTR, bb, 0);
1238 make_edge (bb, EXIT_BLOCK_PTR, 0);
28454517 1239
1240 return bb;
1241}
1242
1243/* Adjust PTR by the constant FIXED_OFFSET, and by the vtable
1244 offset indicated by VIRTUAL_OFFSET, if that is
1245 non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and
1246 zero for a result adjusting thunk. */
1247
1248static tree
1249thunk_adjust (gimple_stmt_iterator * bsi,
1250 tree ptr, bool this_adjusting,
1251 HOST_WIDE_INT fixed_offset, tree virtual_offset)
1252{
1253 gimple stmt;
1254 tree ret;
1255
55d6cb23 1256 if (this_adjusting
1257 && fixed_offset != 0)
28454517 1258 {
2cc66f2a 1259 stmt = gimple_build_assign
1260 (ptr, fold_build_pointer_plus_hwi_loc (input_location,
1261 ptr,
1262 fixed_offset));
28454517 1263 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1264 }
1265
1266 /* If there's a virtual offset, look up that value in the vtable and
1267 adjust the pointer again. */
1268 if (virtual_offset)
1269 {
1270 tree vtabletmp;
1271 tree vtabletmp2;
1272 tree vtabletmp3;
28454517 1273
1274 if (!vtable_entry_type)
1275 {
1276 tree vfunc_type = make_node (FUNCTION_TYPE);
1277 TREE_TYPE (vfunc_type) = integer_type_node;
1278 TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
1279 layout_type (vfunc_type);
1280
1281 vtable_entry_type = build_pointer_type (vfunc_type);
1282 }
1283
1284 vtabletmp =
37ffa8fe 1285 make_rename_temp (build_pointer_type
1286 (build_pointer_type (vtable_entry_type)), "vptr");
28454517 1287
1288 /* The vptr is always at offset zero in the object. */
1289 stmt = gimple_build_assign (vtabletmp,
1290 build1 (NOP_EXPR, TREE_TYPE (vtabletmp),
1291 ptr));
1292 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
28454517 1293
1294 /* Form the vtable address. */
37ffa8fe 1295 vtabletmp2 = make_rename_temp (TREE_TYPE (TREE_TYPE (vtabletmp)),
1296 "vtableaddr");
28454517 1297 stmt = gimple_build_assign (vtabletmp2,
182cf5a9 1298 build_simple_mem_ref (vtabletmp));
28454517 1299 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
28454517 1300
1301 /* Find the entry with the vcall offset. */
1302 stmt = gimple_build_assign (vtabletmp2,
2cc66f2a 1303 fold_build_pointer_plus_loc (input_location,
1304 vtabletmp2,
1305 virtual_offset));
28454517 1306 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1307
1308 /* Get the offset itself. */
37ffa8fe 1309 vtabletmp3 = make_rename_temp (TREE_TYPE (TREE_TYPE (vtabletmp2)),
1310 "vcalloffset");
28454517 1311 stmt = gimple_build_assign (vtabletmp3,
182cf5a9 1312 build_simple_mem_ref (vtabletmp2));
28454517 1313 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
28454517 1314
28454517 1315 /* Adjust the `this' pointer. */
a0553bff 1316 ptr = fold_build_pointer_plus_loc (input_location, ptr, vtabletmp3);
1317 ptr = force_gimple_operand_gsi (bsi, ptr, true, NULL_TREE, false,
1318 GSI_CONTINUE_LINKING);
28454517 1319 }
1320
55d6cb23 1321 if (!this_adjusting
1322 && fixed_offset != 0)
28454517 1323 /* Adjust the pointer by the constant. */
1324 {
1325 tree ptrtmp;
1326
1327 if (TREE_CODE (ptr) == VAR_DECL)
1328 ptrtmp = ptr;
1329 else
1330 {
37ffa8fe 1331 ptrtmp = make_rename_temp (TREE_TYPE (ptr), "ptr");
28454517 1332 stmt = gimple_build_assign (ptrtmp, ptr);
1333 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
28454517 1334 }
2cc66f2a 1335 ptr = fold_build_pointer_plus_hwi_loc (input_location,
1336 ptrtmp, fixed_offset);
28454517 1337 }
1338
1339 /* Emit the statement and gimplify the adjustment expression. */
37ffa8fe 1340 ret = make_rename_temp (TREE_TYPE (ptr), "adjusted_this");
28454517 1341 stmt = gimple_build_assign (ret, ptr);
28454517 1342 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1343
1344 return ret;
1345}
1346
1347/* Produce assembler for thunk NODE. */
1348
1349static void
1350assemble_thunk (struct cgraph_node *node)
1351{
1352 bool this_adjusting = node->thunk.this_adjusting;
1353 HOST_WIDE_INT fixed_offset = node->thunk.fixed_offset;
1354 HOST_WIDE_INT virtual_value = node->thunk.virtual_value;
1355 tree virtual_offset = NULL;
1356 tree alias = node->thunk.alias;
7d0d0ce1 1357 tree thunk_fndecl = node->symbol.decl;
28454517 1358 tree a = DECL_ARGUMENTS (thunk_fndecl);
1359
1360 current_function_decl = thunk_fndecl;
1361
aed6e608 1362 /* Ensure thunks are emitted in their correct sections. */
1363 resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
1364
28454517 1365 if (this_adjusting
1366 && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
1367 virtual_value, alias))
1368 {
1369 const char *fnname;
1370 tree fn_block;
28b2c6a7 1371 tree restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
28454517 1372
1373 DECL_RESULT (thunk_fndecl)
1374 = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl),
28b2c6a7 1375 RESULT_DECL, 0, restype);
22ea3b47 1376 fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
28454517 1377
1378 /* The back end expects DECL_INITIAL to contain a BLOCK, so we
1379 create one. */
1380 fn_block = make_node (BLOCK);
1381 BLOCK_VARS (fn_block) = a;
1382 DECL_INITIAL (thunk_fndecl) = fn_block;
1383 init_function_start (thunk_fndecl);
1384 cfun->is_thunk = 1;
1385 assemble_start_function (thunk_fndecl, fnname);
1386
1387 targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl,
1388 fixed_offset, virtual_value, alias);
1389
1390 assemble_end_function (thunk_fndecl, fnname);
1391 init_insn_lengths ();
1392 free_after_compilation (cfun);
1393 set_cfun (NULL);
1394 TREE_ASM_WRITTEN (thunk_fndecl) = 1;
91bf9d9a 1395 node->thunk.thunk_p = false;
1396 node->analyzed = false;
28454517 1397 }
1398 else
1399 {
1400 tree restype;
1401 basic_block bb, then_bb, else_bb, return_bb;
1402 gimple_stmt_iterator bsi;
1403 int nargs = 0;
1404 tree arg;
1405 int i;
1406 tree resdecl;
1407 tree restmp = NULL;
1408 VEC(tree, heap) *vargs;
1409
1410 gimple call;
1411 gimple ret;
1412
1413 DECL_IGNORED_P (thunk_fndecl) = 1;
1414 bitmap_obstack_initialize (NULL);
1415
1416 if (node->thunk.virtual_offset_p)
1417 virtual_offset = size_int (virtual_value);
1418
1419 /* Build the return declaration for the function. */
1420 restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1421 if (DECL_RESULT (thunk_fndecl) == NULL_TREE)
1422 {
1423 resdecl = build_decl (input_location, RESULT_DECL, 0, restype);
1424 DECL_ARTIFICIAL (resdecl) = 1;
1425 DECL_IGNORED_P (resdecl) = 1;
1426 DECL_RESULT (thunk_fndecl) = resdecl;
1427 }
1428 else
1429 resdecl = DECL_RESULT (thunk_fndecl);
1430
1431 bb = then_bb = else_bb = return_bb = init_lowered_empty_function (thunk_fndecl);
1432
1433 bsi = gsi_start_bb (bb);
1434
1435 /* Build call to the function being thunked. */
1436 if (!VOID_TYPE_P (restype))
1437 {
1438 if (!is_gimple_reg_type (restype))
1439 {
1440 restmp = resdecl;
2ab2ce89 1441 add_local_decl (cfun, restmp);
28454517 1442 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp;
1443 }
1444 else
37ffa8fe 1445 restmp = make_rename_temp (restype, "retval");
28454517 1446 }
1447
1767a056 1448 for (arg = a; arg; arg = DECL_CHAIN (arg))
28454517 1449 nargs++;
1450 vargs = VEC_alloc (tree, heap, nargs);
1451 if (this_adjusting)
1452 VEC_quick_push (tree, vargs,
1453 thunk_adjust (&bsi,
1454 a, 1, fixed_offset,
1455 virtual_offset));
1456 else
1457 VEC_quick_push (tree, vargs, a);
37ffa8fe 1458 add_referenced_var (a);
1459 if (is_gimple_reg (a))
1460 mark_sym_for_renaming (a);
1767a056 1461 for (i = 1, arg = DECL_CHAIN (a); i < nargs; i++, arg = DECL_CHAIN (arg))
37ffa8fe 1462 {
1463 add_referenced_var (arg);
1464 if (is_gimple_reg (arg))
1465 mark_sym_for_renaming (arg);
1466 VEC_quick_push (tree, vargs, arg);
1467 }
28454517 1468 call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs);
1469 VEC_free (tree, heap, vargs);
28454517 1470 gimple_call_set_from_thunk (call, true);
1471 if (restmp)
1472 gimple_call_set_lhs (call, restmp);
1473 gsi_insert_after (&bsi, call, GSI_NEW_STMT);
28454517 1474
1475 if (restmp && !this_adjusting)
1476 {
57ab8ec3 1477 tree true_label = NULL_TREE;
28454517 1478
1479 if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE)
1480 {
1481 gimple stmt;
1482 /* If the return type is a pointer, we need to
1483 protect against NULL. We know there will be an
1484 adjustment, because that's why we're emitting a
1485 thunk. */
1486 then_bb = create_basic_block (NULL, (void *) 0, bb);
1487 return_bb = create_basic_block (NULL, (void *) 0, then_bb);
1488 else_bb = create_basic_block (NULL, (void *) 0, else_bb);
1489 remove_edge (single_succ_edge (bb));
1490 true_label = gimple_block_label (then_bb);
28454517 1491 stmt = gimple_build_cond (NE_EXPR, restmp,
385f3f36 1492 build_zero_cst (TREE_TYPE (restmp)),
28454517 1493 NULL_TREE, NULL_TREE);
1494 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1495 make_edge (bb, then_bb, EDGE_TRUE_VALUE);
1496 make_edge (bb, else_bb, EDGE_FALSE_VALUE);
1497 make_edge (return_bb, EXIT_BLOCK_PTR, 0);
1498 make_edge (then_bb, return_bb, EDGE_FALLTHRU);
1499 make_edge (else_bb, return_bb, EDGE_FALLTHRU);
1500 bsi = gsi_last_bb (then_bb);
1501 }
1502
1503 restmp = thunk_adjust (&bsi, restmp, /*this_adjusting=*/0,
1504 fixed_offset, virtual_offset);
1505 if (true_label)
1506 {
1507 gimple stmt;
1508 bsi = gsi_last_bb (else_bb);
385f3f36 1509 stmt = gimple_build_assign (restmp,
1510 build_zero_cst (TREE_TYPE (restmp)));
28454517 1511 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1512 bsi = gsi_last_bb (return_bb);
1513 }
1514 }
1515 else
1516 gimple_call_set_tail (call, true);
1517
1518 /* Build return value. */
1519 ret = gimple_build_return (restmp);
1520 gsi_insert_after (&bsi, ret, GSI_NEW_STMT);
1521
1522 delete_unreachable_blocks ();
1523 update_ssa (TODO_update_ssa);
1524
28454517 1525 /* Since we want to emit the thunk, we explicitly mark its name as
1526 referenced. */
91bf9d9a 1527 node->thunk.thunk_p = false;
1528 cgraph_node_remove_callees (node);
28454517 1529 cgraph_add_new_function (thunk_fndecl, true);
1530 bitmap_obstack_release (NULL);
1531 }
1532 current_function_decl = NULL;
1533}
1534
91bf9d9a 1535
c70f46b0 1536
1537/* Assemble thunks and aliases asociated to NODE. */
91bf9d9a 1538
1539static void
c70f46b0 1540assemble_thunks_and_aliases (struct cgraph_node *node)
91bf9d9a 1541{
1542 struct cgraph_edge *e;
c70f46b0 1543 int i;
1544 struct ipa_ref *ref;
1545
91bf9d9a 1546 for (e = node->callers; e;)
1547 if (e->caller->thunk.thunk_p)
1548 {
1549 struct cgraph_node *thunk = e->caller;
1550
1551 e = e->next_caller;
c70f46b0 1552 assemble_thunks_and_aliases (thunk);
91bf9d9a 1553 assemble_thunk (thunk);
1554 }
1555 else
1556 e = e->next_caller;
04ec15fa 1557 for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list,
7d0d0ce1 1558 i, ref); i++)
c70f46b0 1559 if (ref->use == IPA_REF_ALIAS)
1560 {
04ec15fa 1561 struct cgraph_node *alias = ipa_ref_referring_node (ref);
968b8c52 1562 bool saved_written = TREE_ASM_WRITTEN (alias->thunk.alias);
1563
1564 /* Force assemble_alias to really output the alias this time instead
1565 of buffering it in same alias pairs. */
1566 TREE_ASM_WRITTEN (alias->thunk.alias) = 1;
afea39ad 1567 do_assemble_alias (alias->symbol.decl,
1568 DECL_ASSEMBLER_NAME (alias->thunk.alias));
c70f46b0 1569 assemble_thunks_and_aliases (alias);
968b8c52 1570 TREE_ASM_WRITTEN (alias->thunk.alias) = saved_written;
c70f46b0 1571 }
91bf9d9a 1572}
1573
da5e1e7c 1574/* Expand function specified by NODE. */
941366fd 1575
3db65b62 1576static void
cf951b1a 1577expand_function (struct cgraph_node *node)
941366fd 1578{
da5e1e7c 1579 tree decl = node->symbol.decl;
941366fd 1580 location_t saved_loc;
1581
da5e1e7c 1582 /* We ought to not compile any inline clones. */
1583 gcc_assert (!node->global.inlined_to);
1584
1585 announce_function (decl);
1586 node->process = 0;
1587 gcc_assert (node->lowered);
1588
1589 /* Generate RTL for the body of DECL. */
1590
941366fd 1591 timevar_push (TV_REST_OF_COMPILATION);
1592
1593 gcc_assert (cgraph_global_info_ready);
1594
1595 /* Initialize the default bitmap obstack. */
1596 bitmap_obstack_initialize (NULL);
1597
1598 /* Initialize the RTL code for the function. */
da5e1e7c 1599 current_function_decl = decl;
941366fd 1600 saved_loc = input_location;
da5e1e7c 1601 input_location = DECL_SOURCE_LOCATION (decl);
1602 init_function_start (decl);
941366fd 1603
1604 gimple_register_cfg_hooks ();
1605
1606 bitmap_obstack_initialize (&reg_obstack); /* FIXME, only at RTL generation*/
1607
1608 execute_all_ipa_transforms ();
1609
1610 /* Perform all tree transforms and optimizations. */
1611
1612 /* Signal the start of passes. */
1613 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START, NULL);
1614
1615 execute_pass_list (all_passes);
1616
1617 /* Signal the end of passes. */
1618 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END, NULL);
1619
1620 bitmap_obstack_release (&reg_obstack);
1621
1622 /* Release the default bitmap obstack. */
1623 bitmap_obstack_release (NULL);
1624
1625 set_cfun (NULL);
1626
1627 /* If requested, warn about function definitions where the function will
1628 return a value (usually of some struct or union type) which itself will
1629 take up a lot of stack space. */
da5e1e7c 1630 if (warn_larger_than && !DECL_EXTERNAL (decl) && TREE_TYPE (decl))
941366fd 1631 {
da5e1e7c 1632 tree ret_type = TREE_TYPE (TREE_TYPE (decl));
941366fd 1633
1634 if (ret_type && TYPE_SIZE_UNIT (ret_type)
1635 && TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST
1636 && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type),
1637 larger_than_size))
1638 {
1639 unsigned int size_as_int
1640 = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type));
1641
1642 if (compare_tree_int (TYPE_SIZE_UNIT (ret_type), size_as_int) == 0)
1643 warning (OPT_Wlarger_than_, "size of return value of %q+D is %u bytes",
da5e1e7c 1644 decl, size_as_int);
941366fd 1645 else
1646 warning (OPT_Wlarger_than_, "size of return value of %q+D is larger than %wd bytes",
da5e1e7c 1647 decl, larger_than_size);
941366fd 1648 }
1649 }
1650
da5e1e7c 1651 gimple_set_body (decl, NULL);
1652 if (DECL_STRUCT_FUNCTION (decl) == 0
1653 && !cgraph_get_node (decl)->origin)
941366fd 1654 {
1655 /* Stop pointing to the local nodes about to be freed.
1656 But DECL_INITIAL must remain nonzero so we know this
1657 was an actual function definition.
1658 For a nested function, this is done in c_pop_function_context.
1659 If rest_of_compilation set this to 0, leave it 0. */
da5e1e7c 1660 if (DECL_INITIAL (decl) != 0)
1661 DECL_INITIAL (decl) = error_mark_node;
941366fd 1662 }
1663
1664 input_location = saved_loc;
1665
1666 ggc_collect ();
1667 timevar_pop (TV_REST_OF_COMPILATION);
f7777314 1668
1669 /* Make sure that BE didn't give up on compiling. */
1670 gcc_assert (TREE_ASM_WRITTEN (decl));
1671 current_function_decl = NULL;
f76f7453 1672
1673 /* It would make a lot more sense to output thunks before function body to get more
cf951b1a 1674 forward and lest backwarding jumps. This however would need solving problem
f76f7453 1675 with comdats. See PR48668. Also aliases must come after function itself to
cf951b1a 1676 make one pass assemblers, like one on AIX, happy. See PR 50689.
f76f7453 1677 FIXME: Perhaps thunks should be move before function IFF they are not in comdat
1678 groups. */
1679 assemble_thunks_and_aliases (node);
1a1a827a 1680 cgraph_release_function_body (node);
1681 /* Eliminate all call edges. This is important so the GIMPLE_CALL no longer
1682 points to the dead function body. */
1683 cgraph_node_remove_callees (node);
ae01b312 1684}
1685
acc70efa 1686
d9d9733a 1687/* Expand all functions that must be output.
1688
d7c6d889 1689 Attempt to topologically sort the nodes so function is output when
1690 all called functions are already assembled to allow data to be
91c82c20 1691 propagated across the callgraph. Use a stack to get smaller distance
3927afe0 1692 between a function and its callees (later we may choose to use a more
d7c6d889 1693 sophisticated algorithm for function reordering; we will likely want
1694 to use subsections to make the output functions appear in top-down
1695 order). */
1696
1697static void
cf951b1a 1698expand_all_functions (void)
d7c6d889 1699{
1700 struct cgraph_node *node;
4c36ffe6 1701 struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
c04e3894 1702 int order_pos, new_order_pos = 0;
d7c6d889 1703 int i;
1704
7771d558 1705 order_pos = ipa_reverse_postorder (order);
cc636d56 1706 gcc_assert (order_pos == cgraph_n_nodes);
d7c6d889 1707
7bd28bba 1708 /* Garbage collector may remove inline clones we eliminate during
b0cdf642 1709 optimization. So we must be sure to not reference them. */
1710 for (i = 0; i < order_pos; i++)
09fc9532 1711 if (order[i]->process)
b0cdf642 1712 order[new_order_pos++] = order[i];
1713
1714 for (i = new_order_pos - 1; i >= 0; i--)
d7c6d889 1715 {
1716 node = order[i];
09fc9532 1717 if (node->process)
d7c6d889 1718 {
09fc9532 1719 node->process = 0;
cf951b1a 1720 expand_function (node);
d7c6d889 1721 }
1722 }
523c1122 1723 cgraph_process_new_functions ();
773c5ba7 1724
d7c6d889 1725 free (order);
773c5ba7 1726
d7c6d889 1727}
1728
56af936e 1729/* This is used to sort the node types by the cgraph order number. */
1730
0b09525f 1731enum cgraph_order_sort_kind
1732{
1733 ORDER_UNDEFINED = 0,
1734 ORDER_FUNCTION,
1735 ORDER_VAR,
1736 ORDER_ASM
1737};
1738
56af936e 1739struct cgraph_order_sort
1740{
0b09525f 1741 enum cgraph_order_sort_kind kind;
56af936e 1742 union
1743 {
1744 struct cgraph_node *f;
1d416bd7 1745 struct varpool_node *v;
cf951b1a 1746 struct asm_node *a;
56af936e 1747 } u;
1748};
1749
1750/* Output all functions, variables, and asm statements in the order
1751 according to their order fields, which is the order in which they
1752 appeared in the file. This implements -fno-toplevel-reorder. In
1753 this mode we may output functions and variables which don't really
1754 need to be output. */
1755
1756static void
cf951b1a 1757output_in_order (void)
56af936e 1758{
1759 int max;
56af936e 1760 struct cgraph_order_sort *nodes;
1761 int i;
1762 struct cgraph_node *pf;
1d416bd7 1763 struct varpool_node *pv;
cf951b1a 1764 struct asm_node *pa;
56af936e 1765
0704fb2e 1766 max = symtab_order;
3e1cde87 1767 nodes = XCNEWVEC (struct cgraph_order_sort, max);
56af936e 1768
7c455d87 1769 FOR_EACH_DEFINED_FUNCTION (pf)
56af936e 1770 {
c70f46b0 1771 if (pf->process && !pf->thunk.thunk_p && !pf->alias)
56af936e 1772 {
7d0d0ce1 1773 i = pf->symbol.order;
56af936e 1774 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1775 nodes[i].kind = ORDER_FUNCTION;
1776 nodes[i].u.f = pf;
1777 }
1778 }
1779
7c455d87 1780 FOR_EACH_DEFINED_VARIABLE (pv)
aa419a52 1781 if (!DECL_EXTERNAL (pv->symbol.decl))
1782 {
1783 i = pv->symbol.order;
1784 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1785 nodes[i].kind = ORDER_VAR;
1786 nodes[i].u.v = pv;
1787 }
56af936e 1788
cf951b1a 1789 for (pa = asm_nodes; pa; pa = pa->next)
56af936e 1790 {
1791 i = pa->order;
1792 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1793 nodes[i].kind = ORDER_ASM;
1794 nodes[i].u.a = pa;
1795 }
56af936e 1796
304e5318 1797 /* In toplevel reorder mode we output all statics; mark them as needed. */
304e5318 1798
91da0f1c 1799 for (i = 0; i < max; ++i)
1800 if (nodes[i].kind == ORDER_VAR)
1801 varpool_finalize_named_section_flags (nodes[i].u.v);
1802
56af936e 1803 for (i = 0; i < max; ++i)
1804 {
1805 switch (nodes[i].kind)
1806 {
1807 case ORDER_FUNCTION:
09fc9532 1808 nodes[i].u.f->process = 0;
cf951b1a 1809 expand_function (nodes[i].u.f);
56af936e 1810 break;
1811
1812 case ORDER_VAR:
1d416bd7 1813 varpool_assemble_decl (nodes[i].u.v);
56af936e 1814 break;
1815
1816 case ORDER_ASM:
1817 assemble_asm (nodes[i].u.a->asm_str);
1818 break;
1819
1820 case ORDER_UNDEFINED:
1821 break;
1822
1823 default:
1824 gcc_unreachable ();
1825 }
1826 }
4b4ea2db 1827
cf951b1a 1828 asm_nodes = NULL;
3e1cde87 1829 free (nodes);
56af936e 1830}
1831
77fce4cd 1832static void
1833ipa_passes (void)
1834{
87d4aa85 1835 set_cfun (NULL);
4b14adf9 1836 current_function_decl = NULL;
75a70cf9 1837 gimple_register_cfg_hooks ();
77fce4cd 1838 bitmap_obstack_initialize (NULL);
59dd4830 1839
c9036234 1840 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START, NULL);
1841
59dd4830 1842 if (!in_lto_p)
7b2e8956 1843 {
1844 execute_ipa_pass_list (all_small_ipa_passes);
1845 if (seen_error ())
1846 return;
1847 }
9ed5b1f5 1848
941125aa 1849 /* We never run removal of unreachable nodes after early passes. This is
1850 because TODO is run before the subpasses. It is important to remove
1851 the unreachable functions to save works at IPA level and to get LTO
1852 symbol tables right. */
91f0ab48 1853 symtab_remove_unreachable_nodes (true, cgraph_dump_file);
941125aa 1854
7bfefa9d 1855 /* If pass_all_early_optimizations was not scheduled, the state of
1856 the cgraph will not be properly updated. Update it now. */
1857 if (cgraph_state < CGRAPH_STATE_IPA_SSA)
1858 cgraph_state = CGRAPH_STATE_IPA_SSA;
9ed5b1f5 1859
7bfefa9d 1860 if (!in_lto_p)
1861 {
1862 /* Generate coverage variables and constructors. */
1863 coverage_finish ();
1864
1865 /* Process new functions added. */
1866 set_cfun (NULL);
1867 current_function_decl = NULL;
1868 cgraph_process_new_functions ();
7bfefa9d 1869
c9036234 1870 execute_ipa_summary_passes
1871 ((struct ipa_opt_pass_d *) all_regular_ipa_passes);
8867b500 1872 }
23433d72 1873
1874 /* Some targets need to handle LTO assembler output specially. */
1875 if (flag_generate_lto)
1876 targetm.asm_out.lto_start ();
1877
7bfefa9d 1878 execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_lto_gen_passes);
1879
1880 if (!in_lto_p)
1881 ipa_write_summaries ();
1882
23433d72 1883 if (flag_generate_lto)
1884 targetm.asm_out.lto_end ();
1885
b33542ab 1886 if (!flag_ltrans && (in_lto_p || !flag_lto || flag_fat_lto_objects))
8867b500 1887 execute_ipa_pass_list (all_regular_ipa_passes);
c9036234 1888 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END, NULL);
9ed5b1f5 1889
77fce4cd 1890 bitmap_obstack_release (NULL);
1891}
1892
badeded8 1893
1894/* Return string alias is alias of. */
1895
1896static tree
1897get_alias_symbol (tree decl)
1898{
1899 tree alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
1900 return get_identifier (TREE_STRING_POINTER
1901 (TREE_VALUE (TREE_VALUE (alias))));
1902}
1903
1904
5e712541 1905/* Weakrefs may be associated to external decls and thus not output
1906 at expansion time. Emit all neccesary aliases. */
1907
5139ff04 1908static void
5e712541 1909output_weakrefs (void)
1910{
1911 struct cgraph_node *node;
1912 struct varpool_node *vnode;
7c455d87 1913 FOR_EACH_FUNCTION (node)
7d0d0ce1 1914 if (node->alias && DECL_EXTERNAL (node->symbol.decl)
1915 && !TREE_ASM_WRITTEN (node->symbol.decl)
1916 && lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
afea39ad 1917 do_assemble_alias (node->symbol.decl,
1918 node->thunk.alias ? DECL_ASSEMBLER_NAME (node->thunk.alias)
1919 : get_alias_symbol (node->symbol.decl));
7c455d87 1920 FOR_EACH_VARIABLE (vnode)
7d0d0ce1 1921 if (vnode->alias && DECL_EXTERNAL (vnode->symbol.decl)
1922 && !TREE_ASM_WRITTEN (vnode->symbol.decl)
1923 && lookup_attribute ("weakref", DECL_ATTRIBUTES (vnode->symbol.decl)))
afea39ad 1924 do_assemble_alias (vnode->symbol.decl,
1925 vnode->alias_of ? DECL_ASSEMBLER_NAME (vnode->alias_of)
1926 : get_alias_symbol (vnode->symbol.decl));
5e712541 1927}
1928
da5e1e7c 1929/* Initialize callgraph dump file. */
34e5cced 1930
121f3051 1931void
1932init_cgraph (void)
1933{
01ec0a6c 1934 if (!cgraph_dump_file)
1935 cgraph_dump_file = dump_begin (TDI_cgraph, NULL);
121f3051 1936}
b5d36404 1937
d2bb3f9d 1938
1939/* Perform simple optimizations based on callgraph. */
1940
1941void
cf951b1a 1942compile (void)
d2bb3f9d 1943{
1944 if (seen_error ())
1945 return;
1946
1947#ifdef ENABLE_CHECKING
3e7775f6 1948 verify_symtab ();
d2bb3f9d 1949#endif
1950
d2bb3f9d 1951 timevar_push (TV_CGRAPHOPT);
1952 if (pre_ipa_mem_report)
1953 {
1954 fprintf (stderr, "Memory consumption before IPA\n");
1955 dump_memory_report (false);
1956 }
1957 if (!quiet_flag)
1958 fprintf (stderr, "Performing interprocedural optimizations\n");
1959 cgraph_state = CGRAPH_STATE_IPA;
1960
cf951b1a 1961 /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE. */
1962 if (flag_lto)
1963 lto_streamer_hooks_init ();
1964
d2bb3f9d 1965 /* Don't run the IPA passes if there was any error or sorry messages. */
1966 if (!seen_error ())
1967 ipa_passes ();
1968
1969 /* Do nothing else if any IPA pass found errors or if we are just streaming LTO. */
1970 if (seen_error ()
1971 || (!in_lto_p && flag_lto && !flag_fat_lto_objects))
1972 {
1973 timevar_pop (TV_CGRAPHOPT);
1974 return;
1975 }
1976
1977 /* This pass remove bodies of extern inline functions we never inlined.
1978 Do this later so other IPA passes see what is really going on. */
91f0ab48 1979 symtab_remove_unreachable_nodes (false, dump_file);
d2bb3f9d 1980 cgraph_global_info_ready = true;
1981 if (cgraph_dump_file)
1982 {
1983 fprintf (cgraph_dump_file, "Optimized ");
18841b0c 1984 dump_symtab (cgraph_dump_file);
d2bb3f9d 1985 }
1986 if (post_ipa_mem_report)
1987 {
1988 fprintf (stderr, "Memory consumption after IPA\n");
1989 dump_memory_report (false);
1990 }
1991 timevar_pop (TV_CGRAPHOPT);
1992
1993 /* Output everything. */
1994 (*debug_hooks->assembly_start) ();
1995 if (!quiet_flag)
1996 fprintf (stderr, "Assembling functions:\n");
1997#ifdef ENABLE_CHECKING
3e7775f6 1998 verify_symtab ();
d2bb3f9d 1999#endif
2000
2001 cgraph_materialize_all_clones ();
2002 bitmap_obstack_initialize (NULL);
2003 execute_ipa_pass_list (all_late_ipa_passes);
91f0ab48 2004 symtab_remove_unreachable_nodes (true, dump_file);
d2bb3f9d 2005#ifdef ENABLE_CHECKING
3e7775f6 2006 verify_symtab ();
d2bb3f9d 2007#endif
2008 bitmap_obstack_release (NULL);
cf951b1a 2009 mark_functions_to_output ();
d2bb3f9d 2010
2011 cgraph_state = CGRAPH_STATE_EXPANSION;
2012 if (!flag_toplevel_reorder)
cf951b1a 2013 output_in_order ();
d2bb3f9d 2014 else
2015 {
cf951b1a 2016 output_asm_statements ();
d2bb3f9d 2017
cf951b1a 2018 expand_all_functions ();
2019 varpool_output_variables ();
d2bb3f9d 2020 }
2021
2022 cgraph_process_new_functions ();
2023 cgraph_state = CGRAPH_STATE_FINISHED;
afea39ad 2024 output_weakrefs ();
d2bb3f9d 2025
2026 if (cgraph_dump_file)
2027 {
2028 fprintf (cgraph_dump_file, "\nFinal ");
18841b0c 2029 dump_symtab (cgraph_dump_file);
d2bb3f9d 2030 }
2031#ifdef ENABLE_CHECKING
3e7775f6 2032 verify_symtab ();
d2bb3f9d 2033 /* Double check that all inline clones are gone and that all
2034 function bodies have been released from memory. */
2035 if (!seen_error ())
2036 {
2037 struct cgraph_node *node;
2038 bool error_found = false;
2039
7c455d87 2040 FOR_EACH_DEFINED_FUNCTION (node)
2041 if (node->global.inlined_to
2042 || gimple_has_body_p (node->symbol.decl))
d2bb3f9d 2043 {
2044 error_found = true;
2045 dump_cgraph_node (stderr, node);
2046 }
2047 if (error_found)
2048 internal_error ("nodes with unreleased memory found");
2049 }
2050#endif
2051}
2052
2053
2054/* Analyze the whole compilation unit once it is parsed completely. */
2055
2056void
cf951b1a 2057finalize_compilation_unit (void)
d2bb3f9d 2058{
2059 timevar_push (TV_CGRAPH);
2060
d2bb3f9d 2061 /* If we're here there's no current function anymore. Some frontends
2062 are lazy in clearing these. */
2063 current_function_decl = NULL;
2064 set_cfun (NULL);
2065
2066 /* Do not skip analyzing the functions if there were errors, we
2067 miss diagnostics for following functions otherwise. */
2068
2069 /* Emit size functions we didn't inline. */
2070 finalize_size_functions ();
2071
2072 /* Mark alias targets necessary and emit diagnostics. */
d2bb3f9d 2073 handle_alias_pairs ();
2074
2075 if (!quiet_flag)
2076 {
2077 fprintf (stderr, "\nAnalyzing compilation unit\n");
2078 fflush (stderr);
2079 }
2080
2081 if (flag_dump_passes)
2082 dump_passes ();
2083
2084 /* Gimplify and lower all functions, compute reachability and
2085 remove unreachable nodes. */
2086 cgraph_analyze_functions ();
2087
2088 /* Mark alias targets necessary and emit diagnostics. */
d2bb3f9d 2089 handle_alias_pairs ();
2090
2091 /* Gimplify and lower thunks. */
2092 cgraph_analyze_functions ();
2093
2094 /* Finally drive the pass manager. */
cf951b1a 2095 compile ();
d2bb3f9d 2096
2097 timevar_pop (TV_CGRAPH);
2098}
2099
2100
a861fe52 2101#include "gt-cgraphunit.h"