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