]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/cgraphunit.c
2013-09-28 Sandra Loosemore <sandra@codesourcery.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"
69ee5dbb 167#include "tree-ssa.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
6e1aa353 595 if (node->thunk.thunk_p)
91bf9d9a 596 {
597 cgraph_create_edge (node, cgraph_get_node (node->thunk.alias),
6e1aa353 598 NULL, 0, CGRAPH_FREQ_BASE);
599 if (!expand_thunk (node, false))
600 {
601 node->thunk.alias = NULL;
602 node->symbol.analyzed = true;
603 return;
604 }
48669653 605 node->thunk.alias = NULL;
91bf9d9a 606 }
6e1aa353 607 if (node->symbol.alias)
608 symtab_resolve_alias
609 ((symtab_node) node, (symtab_node) cgraph_get_node (node->symbol.alias_target));
cc8ef84f 610 else if (node->dispatcher_function)
611 {
612 /* Generate the dispatcher body of multi-versioned functions. */
613 struct cgraph_function_version_info *dispatcher_version_info
614 = get_cgraph_node_version (node);
615 if (dispatcher_version_info != NULL
616 && (dispatcher_version_info->dispatcher_resolver
617 == NULL_TREE))
618 {
619 tree resolver = NULL_TREE;
620 gcc_assert (targetm.generate_version_dispatcher_body);
621 resolver = targetm.generate_version_dispatcher_body (node);
622 gcc_assert (resolver != NULL_TREE);
623 }
624 }
91bf9d9a 625 else
626 {
91bf9d9a 627 push_cfun (DECL_STRUCT_FUNCTION (decl));
bfec3452 628
7d0d0ce1 629 assign_assembler_name_if_neeeded (node->symbol.decl);
6816d0c4 630
91bf9d9a 631 /* Make sure to gimplify bodies only once. During analyzing a
632 function we lower it, which will require gimplified nested
633 functions, so we can end up here with an already gimplified
634 body. */
e3a19533 635 if (!gimple_has_body_p (decl))
91bf9d9a 636 gimplify_function_tree (decl);
637 dump_function (TDI_generic, decl);
bfec3452 638
47199071 639 /* Lower the function. */
640 if (!node->lowered)
641 {
642 if (node->nested)
7d0d0ce1 643 lower_nested_functions (node->symbol.decl);
47199071 644 gcc_assert (!node->nested);
645
646 gimple_register_cfg_hooks ();
647 bitmap_obstack_initialize (NULL);
3ea50c01 648 execute_pass_list (g->get_passes ()->all_lowering_passes);
47199071 649 free_dominance_info (CDI_POST_DOMINATORS);
650 free_dominance_info (CDI_DOMINATORS);
651 compact_blocks ();
652 bitmap_obstack_release (NULL);
653 node->lowered = true;
654 }
655
91bf9d9a 656 pop_cfun ();
657 }
15ca8f90 658 node->symbol.analyzed = true;
0785e435 659
da5e1e7c 660 input_location = saved_loc;
0785e435 661}
662
c70f46b0 663/* C++ frontend produce same body aliases all over the place, even before PCH
664 gets streamed out. It relies on us linking the aliases with their function
665 in order to do the fixups, but ipa-ref is not PCH safe. Consequentely we
666 first produce aliases without links, but once C++ FE is sure he won't sream
667 PCH we build the links via this function. */
668
669void
670cgraph_process_same_body_aliases (void)
671{
48669653 672 symtab_node node;
673 FOR_EACH_SYMBOL (node)
674 if (node->symbol.cpp_implicit_alias && !node->symbol.analyzed)
a55453ec 675 symtab_resolve_alias
676 (node,
677 TREE_CODE (node->symbol.alias_target) == VAR_DECL
678 ? (symtab_node)varpool_node_for_decl (node->symbol.alias_target)
679 : (symtab_node)cgraph_get_create_node (node->symbol.alias_target));
48669653 680 cpp_implicit_aliases_done = true;
c70f46b0 681}
682
d05db70d 683/* Process attributes common for vars and functions. */
684
685static void
686process_common_attributes (tree decl)
687{
688 tree weakref = lookup_attribute ("weakref", DECL_ATTRIBUTES (decl));
689
690 if (weakref && !lookup_attribute ("alias", DECL_ATTRIBUTES (decl)))
691 {
692 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
693 "%<weakref%> attribute should be accompanied with"
694 " an %<alias%> attribute");
695 DECL_WEAK (decl) = 0;
40b32d93 696 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
697 DECL_ATTRIBUTES (decl));
d05db70d 698 }
699}
700
05806473 701/* Look for externally_visible and used attributes and mark cgraph nodes
702 accordingly.
703
704 We cannot mark the nodes at the point the attributes are processed (in
705 handle_*_attribute) because the copy of the declarations available at that
706 point may not be canonical. For example, in:
707
708 void f();
709 void f() __attribute__((used));
710
711 the declaration we see in handle_used_attribute will be the second
712 declaration -- but the front end will subsequently merge that declaration
713 with the original declaration and discard the second declaration.
714
715 Furthermore, we can't mark these nodes in cgraph_finalize_function because:
716
717 void f() {}
718 void f() __attribute__((externally_visible));
719
720 is valid.
721
722 So, we walk the nodes at the end of the translation unit, applying the
723 attributes at that point. */
724
725static void
726process_function_and_variable_attributes (struct cgraph_node *first,
1d416bd7 727 struct varpool_node *first_var)
05806473 728{
729 struct cgraph_node *node;
1d416bd7 730 struct varpool_node *vnode;
05806473 731
0704fb2e 732 for (node = cgraph_first_function (); node != first;
733 node = cgraph_next_function (node))
05806473 734 {
7d0d0ce1 735 tree decl = node->symbol.decl;
83a23b05 736 if (DECL_PRESERVE_P (decl))
8efa224a 737 cgraph_mark_force_output_node (node);
62433d51 738 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
05806473 739 {
7d0d0ce1 740 if (! TREE_PUBLIC (node->symbol.decl))
741 warning_at (DECL_SOURCE_LOCATION (node->symbol.decl), OPT_Wattributes,
712d2297 742 "%<externally_visible%>"
743 " attribute have effect only on public objects");
05806473 744 }
40b32d93 745 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
15ca8f90 746 && (node->symbol.definition && !node->symbol.alias))
40b32d93 747 {
7d0d0ce1 748 warning_at (DECL_SOURCE_LOCATION (node->symbol.decl), OPT_Wattributes,
40b32d93 749 "%<weakref%> attribute ignored"
750 " because function is defined");
751 DECL_WEAK (decl) = 0;
752 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
753 DECL_ATTRIBUTES (decl));
754 }
a522e9eb 755
756 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl))
757 && !DECL_DECLARED_INLINE_P (decl)
758 /* redefining extern inline function makes it DECL_UNINLINABLE. */
759 && !DECL_UNINLINABLE (decl))
760 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
761 "always_inline function might not be inlinable");
762
d05db70d 763 process_common_attributes (decl);
05806473 764 }
0704fb2e 765 for (vnode = varpool_first_variable (); vnode != first_var;
766 vnode = varpool_next_variable (vnode))
05806473 767 {
7d0d0ce1 768 tree decl = vnode->symbol.decl;
aa419a52 769 if (DECL_EXTERNAL (decl)
df8d3e89 770 && DECL_INITIAL (decl))
aa419a52 771 varpool_finalize_decl (decl);
83a23b05 772 if (DECL_PRESERVE_P (decl))
ff2a5ada 773 vnode->symbol.force_output = true;
62433d51 774 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
05806473 775 {
7d0d0ce1 776 if (! TREE_PUBLIC (vnode->symbol.decl))
777 warning_at (DECL_SOURCE_LOCATION (vnode->symbol.decl), OPT_Wattributes,
712d2297 778 "%<externally_visible%>"
779 " attribute have effect only on public objects");
05806473 780 }
40b32d93 781 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
15ca8f90 782 && vnode->symbol.definition
40b32d93 783 && DECL_INITIAL (decl))
784 {
7d0d0ce1 785 warning_at (DECL_SOURCE_LOCATION (vnode->symbol.decl), OPT_Wattributes,
40b32d93 786 "%<weakref%> attribute ignored"
787 " because variable is initialized");
788 DECL_WEAK (decl) = 0;
789 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
790 DECL_ATTRIBUTES (decl));
791 }
d05db70d 792 process_common_attributes (decl);
05806473 793 }
794}
795
ff2a5ada 796/* Mark DECL as finalized. By finalizing the declaration, frontend instruct the
797 middle end to output the variable to asm file, if needed or externally
798 visible. */
799
800void
801varpool_finalize_decl (tree decl)
802{
2dc9831f 803 struct varpool_node *node = varpool_node_for_decl (decl);
ff2a5ada 804
2d4bf241 805 gcc_assert (TREE_STATIC (decl) || DECL_EXTERNAL (decl));
ff2a5ada 806
15ca8f90 807 if (node->symbol.definition)
ff2a5ada 808 return;
809 notice_global_symbol (decl);
15ca8f90 810 node->symbol.definition = true;
ff2a5ada 811 if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
812 /* Traditionally we do not eliminate static variables when not
813 optimizing and when not doing toplevel reoder. */
814 || (!flag_toplevel_reorder && !DECL_COMDAT (node->symbol.decl)
815 && !DECL_ARTIFICIAL (node->symbol.decl)))
816 node->symbol.force_output = true;
817
818 if (cgraph_state == CGRAPH_STATE_CONSTRUCTION
6a1c0403 819 && (decide_is_symbol_needed ((symtab_node) node)
ff2a5ada 820 || referred_to_p ((symtab_node)node)))
821 enqueue_node ((symtab_node)node);
822 if (cgraph_state >= CGRAPH_STATE_IPA_SSA)
823 varpool_analyze_node (node);
3d1c0354 824 /* Some frontends produce various interface variables after compilation
825 finished. */
826 if (cgraph_state == CGRAPH_STATE_FINISHED)
827 varpool_assemble_decl (node);
ff2a5ada 828}
829
98e7a67f 830/* EDGE is an polymorphic call. Mark all possible targets as reachable
831 and if there is only one target, perform trivial devirtualization.
832 REACHABLE_CALL_TARGETS collects target lists we already walked to
833 avoid udplicate work. */
834
835static void
836walk_polymorphic_call_targets (pointer_set_t *reachable_call_targets,
837 struct cgraph_edge *edge)
838{
839 unsigned int i;
840 void *cache_token;
841 bool final;
842 vec <cgraph_node *>targets
843 = possible_polymorphic_call_targets
844 (edge, &final, &cache_token);
845
846 if (!pointer_set_insert (reachable_call_targets,
847 cache_token))
848 {
849 if (cgraph_dump_file)
850 dump_possible_polymorphic_call_targets
851 (cgraph_dump_file, edge);
852
853 for (i = 0; i < targets.length(); i++)
854 {
855 /* Do not bother to mark virtual methods in anonymous namespace;
856 either we will find use of virtual table defining it, or it is
857 unused. */
858 if (targets[i]->symbol.definition
859 && TREE_CODE
860 (TREE_TYPE (targets[i]->symbol.decl))
861 == METHOD_TYPE
862 && !type_in_anonymous_namespace_p
863 (method_class_type
864 (TREE_TYPE (targets[i]->symbol.decl))))
865 enqueue_node ((symtab_node) targets[i]);
866 }
867 }
868
869 /* Very trivial devirtualization; when the type is
870 final or anonymous (so we know all its derivation)
871 and there is only one possible virtual call target,
872 make the edge direct. */
873 if (final)
874 {
e2fa5d74 875 if (targets.length() <= 1)
98e7a67f 876 {
e2fa5d74 877 cgraph_node *target;
878 if (targets.length () == 1)
879 target = targets[0];
880 else
881 target = cgraph_get_create_node
882 (builtin_decl_implicit (BUILT_IN_UNREACHABLE));
883
98e7a67f 884 if (cgraph_dump_file)
885 {
886 fprintf (cgraph_dump_file,
887 "Devirtualizing call: ");
888 print_gimple_stmt (cgraph_dump_file,
889 edge->call_stmt, 0,
890 TDF_SLIM);
891 }
e2fa5d74 892 cgraph_make_edge_direct (edge, target);
98e7a67f 893 cgraph_redirect_edge_call_stmt_to_callee (edge);
894 if (cgraph_dump_file)
895 {
896 fprintf (cgraph_dump_file,
897 "Devirtualized as: ");
898 print_gimple_stmt (cgraph_dump_file,
899 edge->call_stmt, 0,
900 TDF_SLIM);
901 }
902 }
903 }
904}
905
2dc9831f 906
ff2a5ada 907/* Discover all functions and variables that are trivially needed, analyze
908 them as well as all functions and variables referred by them */
ae01b312 909
aeeb194b 910static void
15ca8f90 911analyze_functions (void)
ae01b312 912{
c1dcd13c 913 /* Keep track of already processed nodes when called multiple times for
06b27565 914 intermodule optimization. */
c1dcd13c 915 static struct cgraph_node *first_analyzed;
ff2a5ada 916 struct cgraph_node *first_handled = first_analyzed;
1d416bd7 917 static struct varpool_node *first_analyzed_var;
ff2a5ada 918 struct varpool_node *first_handled_var = first_analyzed_var;
5514adf9 919 struct pointer_set_t *reachable_call_targets = pointer_set_create ();
ff2a5ada 920
921 symtab_node node, next;
922 int i;
923 struct ipa_ref *ref;
924 bool changed = true;
fd9fde78 925 location_t saved_loc = input_location;
ae01b312 926
f1c35659 927 bitmap_obstack_initialize (NULL);
ff2a5ada 928 cgraph_state = CGRAPH_STATE_CONSTRUCTION;
fd9fde78 929 input_location = UNKNOWN_LOCATION;
ae01b312 930
48669653 931 /* Ugly, but the fixup can not happen at a time same body alias is created;
932 C++ FE is confused about the COMDAT groups being right. */
933 if (cpp_implicit_aliases_done)
934 FOR_EACH_SYMBOL (node)
935 if (node->symbol.cpp_implicit_alias)
936 fixup_same_cpp_alias_visibility (node, symtab_alias_target (node));
5514adf9 937 if (optimize && flag_devirtualize)
938 build_type_inheritance_graph ();
48669653 939
ff2a5ada 940 /* Analysis adds static variables that in turn adds references to new functions.
941 So we need to iterate the process until it stabilize. */
942 while (changed)
ae01b312 943 {
ff2a5ada 944 changed = false;
945 process_function_and_variable_attributes (first_analyzed,
946 first_analyzed_var);
947
948 /* First identify the trivially needed symbols. */
949 for (node = symtab_nodes;
950 node != (symtab_node)first_analyzed
951 && node != (symtab_node)first_analyzed_var; node = node->symbol.next)
9b8fb23a 952 {
6a1c0403 953 if (decide_is_symbol_needed (node))
ff2a5ada 954 {
955 enqueue_node (node);
956 if (!changed && cgraph_dump_file)
957 fprintf (cgraph_dump_file, "Trivially needed symbols:");
958 changed = true;
959 if (cgraph_dump_file)
960 fprintf (cgraph_dump_file, " %s", symtab_node_asm_name (node));
5514adf9 961 if (!changed && cgraph_dump_file)
962 fprintf (cgraph_dump_file, "\n");
ff2a5ada 963 }
964 if (node == (symtab_node)first_analyzed
965 || node == (symtab_node)first_analyzed_var)
966 break;
9b8fb23a 967 }
ff2a5ada 968 cgraph_process_new_functions ();
969 first_analyzed_var = varpool_first_variable ();
970 first_analyzed = cgraph_first_function ();
638531ad 971
ff2a5ada 972 if (changed && dump_file)
973 fprintf (cgraph_dump_file, "\n");
2c0b522d 974
ff2a5ada 975 /* Lower representation, build callgraph edges and references for all trivially
976 needed symbols and all symbols referred by them. */
977 while (first != (symtab_node)(void *)1)
61c2c7b1 978 {
ff2a5ada 979 changed = true;
980 node = first;
981 first = (symtab_node)first->symbol.aux;
2dc9831f 982 cgraph_node *cnode = dyn_cast <cgraph_node> (node);
15ca8f90 983 if (cnode && cnode->symbol.definition)
ff2a5ada 984 {
985 struct cgraph_edge *edge;
2dc9831f 986 tree decl = cnode->symbol.decl;
ff2a5ada 987
2dc9831f 988 /* ??? It is possible to create extern inline function
989 and later using weak alias attribute to kill its body.
990 See gcc.c-torture/compile/20011119-1.c */
ff2a5ada 991 if (!DECL_STRUCT_FUNCTION (decl)
48669653 992 && !cnode->symbol.alias
cc8ef84f 993 && !cnode->thunk.thunk_p
994 && !cnode->dispatcher_function)
ff2a5ada 995 {
996 cgraph_reset_node (cnode);
997 cnode->local.redefined_extern_inline = true;
998 continue;
999 }
61c2c7b1 1000
15ca8f90 1001 if (!cnode->symbol.analyzed)
1002 analyze_function (cnode);
d544ceff 1003
ff2a5ada 1004 for (edge = cnode->callees; edge; edge = edge->next_callee)
15ca8f90 1005 if (edge->callee->symbol.definition)
2dc9831f 1006 enqueue_node ((symtab_node)edge->callee);
5514adf9 1007 if (optimize && flag_devirtualize)
1008 {
1e4f4118 1009 struct cgraph_edge *next;
98e7a67f 1010
1011 for (edge = cnode->indirect_calls; edge; edge = next)
1e4f4118 1012 {
1013 next = edge->next_callee;
1014 if (edge->indirect_info->polymorphic)
98e7a67f 1015 walk_polymorphic_call_targets (reachable_call_targets,
1016 edge);
1e4f4118 1017 }
5514adf9 1018 }
ff2a5ada 1019
2dc9831f 1020 /* If decl is a clone of an abstract function,
1021 mark that abstract function so that we don't release its body.
1022 The DECL_INITIAL() of that abstract function declaration
1023 will be later needed to output debug info. */
ff2a5ada 1024 if (DECL_ABSTRACT_ORIGIN (decl))
1025 {
2dc9831f 1026 struct cgraph_node *origin_node
1027 = cgraph_get_node (DECL_ABSTRACT_ORIGIN (decl));
abb1a237 1028 origin_node->used_as_abstract_origin = true;
ff2a5ada 1029 }
ff2a5ada 1030 }
2dc9831f 1031 else
1032 {
1033 varpool_node *vnode = dyn_cast <varpool_node> (node);
48669653 1034 if (vnode && vnode->symbol.definition && !vnode->symbol.analyzed)
2dc9831f 1035 varpool_analyze_node (vnode);
1036 }
ff2a5ada 1037
1038 if (node->symbol.same_comdat_group)
1039 {
1040 symtab_node next;
1041 for (next = node->symbol.same_comdat_group;
1042 next != node;
1043 next = next->symbol.same_comdat_group)
1044 enqueue_node (next);
1045 }
1046 for (i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list, i, ref); i++)
15ca8f90 1047 if (ref->referred->symbol.definition)
ff2a5ada 1048 enqueue_node (ref->referred);
1049 cgraph_process_new_functions ();
1050 }
ae01b312 1051 }
07c6dcc3 1052 if (optimize && flag_devirtualize)
1053 update_type_inheritance_graph ();
2c0b522d 1054
aa5e06c7 1055 /* Collect entry points to the unit. */
f79b6507 1056 if (cgraph_dump_file)
3d7bfc56 1057 {
e4200070 1058 fprintf (cgraph_dump_file, "\n\nInitial ");
18841b0c 1059 dump_symtab (cgraph_dump_file);
3d7bfc56 1060 }
e6d2b2d8 1061
f79b6507 1062 if (cgraph_dump_file)
ff2a5ada 1063 fprintf (cgraph_dump_file, "\nRemoving unused symbols:");
ae01b312 1064
ff2a5ada 1065 for (node = symtab_nodes;
1066 node != (symtab_node)first_handled
1067 && node != (symtab_node)first_handled_var; node = next)
ae01b312 1068 {
ff2a5ada 1069 next = node->symbol.next;
1070 if (!node->symbol.aux && !referred_to_p (node))
ae01b312 1071 {
f79b6507 1072 if (cgraph_dump_file)
ff2a5ada 1073 fprintf (cgraph_dump_file, " %s", symtab_node_name (node));
1074 symtab_remove_node (node);
9b8fb23a 1075 continue;
ae01b312 1076 }
2dc9831f 1077 if (cgraph_node *cnode = dyn_cast <cgraph_node> (node))
ff2a5ada 1078 {
1079 tree decl = node->symbol.decl;
ff2a5ada 1080
15ca8f90 1081 if (cnode->symbol.definition && !gimple_has_body_p (decl)
48669653 1082 && !cnode->symbol.alias
ff2a5ada 1083 && !cnode->thunk.thunk_p)
1084 cgraph_reset_node (cnode);
1085
15ca8f90 1086 gcc_assert (!cnode->symbol.definition || cnode->thunk.thunk_p
1087 || cnode->symbol.alias
ff2a5ada 1088 || gimple_has_body_p (decl));
15ca8f90 1089 gcc_assert (cnode->symbol.analyzed == cnode->symbol.definition);
ff2a5ada 1090 }
1091 node->symbol.aux = NULL;
ae01b312 1092 }
d5b66e83 1093 for (;node; node = node->symbol.next)
1094 node->symbol.aux = NULL;
ff2a5ada 1095 first_analyzed = cgraph_first_function ();
1096 first_analyzed_var = varpool_first_variable ();
f79b6507 1097 if (cgraph_dump_file)
e4200070 1098 {
1099 fprintf (cgraph_dump_file, "\n\nReclaimed ");
18841b0c 1100 dump_symtab (cgraph_dump_file);
e4200070 1101 }
f1c35659 1102 bitmap_obstack_release (NULL);
5514adf9 1103 pointer_set_destroy (reachable_call_targets);
ae01b312 1104 ggc_collect ();
d5b66e83 1105 /* Initialize assembler name hash, in particular we want to trigger C++
1106 mangling and same body alias creation before we free DECL_ARGUMENTS
1107 used by it. */
1108 if (!seen_error ())
e2fa5d74 1109 symtab_initialize_asm_name_hash ();
fd9fde78 1110
1111 input_location = saved_loc;
aeeb194b 1112}
1113
3a849bc1 1114/* Translate the ugly representation of aliases as alias pairs into nice
1115 representation in callgraph. We don't handle all cases yet,
a3ddd82f 1116 unfortunately. */
3a849bc1 1117
1118static void
1119handle_alias_pairs (void)
1120{
1121 alias_pair *p;
1122 unsigned i;
3a849bc1 1123
f1f41a6c 1124 for (i = 0; alias_pairs && alias_pairs->iterate (i, &p);)
3a849bc1 1125 {
48c84ee3 1126 symtab_node target_node = symtab_node_for_asm (p->target);
1127
a3ddd82f 1128 /* Weakrefs with target not defined in current unit are easy to handle:
1129 they behave just as external variables except we need to note the
1130 alias flag to later output the weakref pseudo op into asm file. */
1131 if (!target_node
1132 && lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL)
badeded8 1133 {
48669653 1134 symtab_node node = symtab_get_node (p->decl);
1135 if (node)
fc8456b4 1136 {
48669653 1137 node->symbol.alias_target = p->target;
f2526cce 1138 node->symbol.weakref = true;
48669653 1139 node->symbol.alias = true;
fc8456b4 1140 }
f1f41a6c 1141 alias_pairs->unordered_remove (i);
48c84ee3 1142 continue;
badeded8 1143 }
48c84ee3 1144 else if (!target_node)
3a849bc1 1145 {
48c84ee3 1146 error ("%q+D aliased to undefined symbol %qE", p->decl, p->target);
a3ddd82f 1147 symtab_node node = symtab_get_node (p->decl);
1148 if (node)
1149 node->symbol.alias = false;
f1f41a6c 1150 alias_pairs->unordered_remove (i);
48c84ee3 1151 continue;
1152 }
1153
afea39ad 1154 if (DECL_EXTERNAL (target_node->symbol.decl)
1155 /* We use local aliases for C++ thunks to force the tailcall
1156 to bind locally. This is a hack - to keep it working do
1157 the following (which is not strictly correct). */
1158 && (! TREE_CODE (target_node->symbol.decl) == FUNCTION_DECL
1159 || ! DECL_VIRTUAL_P (target_node->symbol.decl))
1160 && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)))
1161 {
1162 error ("%q+D aliased to external symbol %qE",
1163 p->decl, p->target);
1164 }
1165
48c84ee3 1166 if (TREE_CODE (p->decl) == FUNCTION_DECL
2dc9831f 1167 && target_node && is_a <cgraph_node> (target_node))
48c84ee3 1168 {
1169 struct cgraph_node *src_node = cgraph_get_node (p->decl);
15ca8f90 1170 if (src_node && src_node->symbol.definition)
48c84ee3 1171 cgraph_reset_node (src_node);
1172 cgraph_create_function_alias (p->decl, target_node->symbol.decl);
f1f41a6c 1173 alias_pairs->unordered_remove (i);
48c84ee3 1174 }
1175 else if (TREE_CODE (p->decl) == VAR_DECL
2dc9831f 1176 && target_node && is_a <varpool_node> (target_node))
48c84ee3 1177 {
1178 varpool_create_variable_alias (p->decl, target_node->symbol.decl);
f1f41a6c 1179 alias_pairs->unordered_remove (i);
48c84ee3 1180 }
1181 else
1182 {
1183 error ("%q+D alias in between function and variable is not supported",
1184 p->decl);
1185 warning (0, "%q+D aliased declaration",
1186 target_node->symbol.decl);
f1f41a6c 1187 alias_pairs->unordered_remove (i);
3a849bc1 1188 }
1189 }
f1f41a6c 1190 vec_free (alias_pairs);
3a849bc1 1191}
1192
8f69fd82 1193
ae01b312 1194/* Figure out what functions we want to assemble. */
1195
1196static void
cf951b1a 1197mark_functions_to_output (void)
ae01b312 1198{
1199 struct cgraph_node *node;
61c2c7b1 1200#ifdef ENABLE_CHECKING
1201 bool check_same_comdat_groups = false;
1202
7c455d87 1203 FOR_EACH_FUNCTION (node)
61c2c7b1 1204 gcc_assert (!node->process);
1205#endif
ae01b312 1206
7c455d87 1207 FOR_EACH_FUNCTION (node)
ae01b312 1208 {
7d0d0ce1 1209 tree decl = node->symbol.decl;
a0c938f0 1210
7d0d0ce1 1211 gcc_assert (!node->process || node->symbol.same_comdat_group);
61c2c7b1 1212 if (node->process)
1213 continue;
d7c6d889 1214
e6d2b2d8 1215 /* We need to output all local functions that are used and not
1216 always inlined, as well as those that are reachable from
1217 outside the current compilation unit. */
15ca8f90 1218 if (node->symbol.analyzed
91bf9d9a 1219 && !node->thunk.thunk_p
15ca8f90 1220 && !node->symbol.alias
b0cdf642 1221 && !node->global.inlined_to
4ee9c684 1222 && !TREE_ASM_WRITTEN (decl)
ae01b312 1223 && !DECL_EXTERNAL (decl))
61c2c7b1 1224 {
1225 node->process = 1;
7d0d0ce1 1226 if (node->symbol.same_comdat_group)
61c2c7b1 1227 {
1228 struct cgraph_node *next;
7d0d0ce1 1229 for (next = cgraph (node->symbol.same_comdat_group);
61c2c7b1 1230 next != node;
7d0d0ce1 1231 next = cgraph (next->symbol.same_comdat_group))
15ca8f90 1232 if (!next->thunk.thunk_p && !next->symbol.alias)
91bf9d9a 1233 next->process = 1;
61c2c7b1 1234 }
1235 }
7d0d0ce1 1236 else if (node->symbol.same_comdat_group)
61c2c7b1 1237 {
1238#ifdef ENABLE_CHECKING
1239 check_same_comdat_groups = true;
1240#endif
1241 }
cc636d56 1242 else
9cee7c3f 1243 {
1244 /* We should've reclaimed all functions that are not needed. */
1245#ifdef ENABLE_CHECKING
75a70cf9 1246 if (!node->global.inlined_to
1a1a827a 1247 && gimple_has_body_p (decl)
08843223 1248 /* FIXME: in ltrans unit when offline copy is outside partition but inline copies
1249 are inside partition, we can end up not removing the body since we no longer
1250 have analyzed node pointing to it. */
7d0d0ce1 1251 && !node->symbol.in_other_partition
15ca8f90 1252 && !node->symbol.alias
2d4bf241 1253 && !node->clones
9cee7c3f 1254 && !DECL_EXTERNAL (decl))
1255 {
1256 dump_cgraph_node (stderr, node);
1257 internal_error ("failed to reclaim unneeded function");
1258 }
1259#endif
75a70cf9 1260 gcc_assert (node->global.inlined_to
1a1a827a 1261 || !gimple_has_body_p (decl)
7d0d0ce1 1262 || node->symbol.in_other_partition
aa419a52 1263 || node->clones
1264 || DECL_ARTIFICIAL (decl)
9cee7c3f 1265 || DECL_EXTERNAL (decl));
1266
1267 }
a0c938f0 1268
961e3b13 1269 }
61c2c7b1 1270#ifdef ENABLE_CHECKING
1271 if (check_same_comdat_groups)
7c455d87 1272 FOR_EACH_FUNCTION (node)
7d0d0ce1 1273 if (node->symbol.same_comdat_group && !node->process)
61c2c7b1 1274 {
7d0d0ce1 1275 tree decl = node->symbol.decl;
61c2c7b1 1276 if (!node->global.inlined_to
1277 && gimple_has_body_p (decl)
6d36105a 1278 /* FIXME: in an ltrans unit when the offline copy is outside a
1279 partition but inline copies are inside a partition, we can
1280 end up not removing the body since we no longer have an
1281 analyzed node pointing to it. */
7d0d0ce1 1282 && !node->symbol.in_other_partition
afea39ad 1283 && !node->clones
61c2c7b1 1284 && !DECL_EXTERNAL (decl))
1285 {
1286 dump_cgraph_node (stderr, node);
6d36105a 1287 internal_error ("failed to reclaim unneeded function in same "
1288 "comdat group");
61c2c7b1 1289 }
1290 }
1291#endif
961e3b13 1292}
1293
28454517 1294/* DECL is FUNCTION_DECL. Initialize datastructures so DECL is a function
cc8ef84f 1295 in lowered gimple form. IN_SSA is true if the gimple is in SSA.
28454517 1296
1297 Set current_function_decl and cfun to newly constructed empty function body.
1298 return basic block in the function body. */
1299
cc8ef84f 1300basic_block
1301init_lowered_empty_function (tree decl, bool in_ssa)
28454517 1302{
1303 basic_block bb;
1304
1305 current_function_decl = decl;
1306 allocate_struct_function (decl, false);
1307 gimple_register_cfg_hooks ();
1308 init_empty_tree_cfg ();
cc8ef84f 1309
1310 if (in_ssa)
1311 {
1312 init_tree_ssa (cfun);
1313 init_ssa_operands (cfun);
1314 cfun->gimple_df->in_ssa_p = true;
7eacb0dd 1315 cfun->curr_properties |= PROP_ssa;
cc8ef84f 1316 }
1317
28454517 1318 DECL_INITIAL (decl) = make_node (BLOCK);
1319
1320 DECL_SAVED_TREE (decl) = error_mark_node;
7eacb0dd 1321 cfun->curr_properties |= (PROP_gimple_lcf | PROP_gimple_leh | PROP_gimple_any
1322 | PROP_cfg | PROP_loops);
1323
1324 set_loops_for_fn (cfun, ggc_alloc_cleared_loops ());
1325 init_loops_structure (cfun, loops_for_fn (cfun), 1);
1326 loops_for_fn (cfun)->state |= LOOPS_MAY_HAVE_MULTIPLE_LATCHES;
28454517 1327
1328 /* Create BB for body of the function and connect it properly. */
1329 bb = create_basic_block (NULL, (void *) 0, ENTRY_BLOCK_PTR);
7eacb0dd 1330 make_edge (ENTRY_BLOCK_PTR, bb, EDGE_FALLTHRU);
167ef6d9 1331 make_edge (bb, EXIT_BLOCK_PTR, 0);
7eacb0dd 1332 add_bb_to_loop (bb, ENTRY_BLOCK_PTR->loop_father);
28454517 1333
1334 return bb;
1335}
1336
1337/* Adjust PTR by the constant FIXED_OFFSET, and by the vtable
1338 offset indicated by VIRTUAL_OFFSET, if that is
1339 non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and
1340 zero for a result adjusting thunk. */
1341
1342static tree
1343thunk_adjust (gimple_stmt_iterator * bsi,
1344 tree ptr, bool this_adjusting,
1345 HOST_WIDE_INT fixed_offset, tree virtual_offset)
1346{
1347 gimple stmt;
1348 tree ret;
1349
55d6cb23 1350 if (this_adjusting
1351 && fixed_offset != 0)
28454517 1352 {
2cc66f2a 1353 stmt = gimple_build_assign
1354 (ptr, fold_build_pointer_plus_hwi_loc (input_location,
1355 ptr,
1356 fixed_offset));
28454517 1357 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1358 }
1359
1360 /* If there's a virtual offset, look up that value in the vtable and
1361 adjust the pointer again. */
1362 if (virtual_offset)
1363 {
1364 tree vtabletmp;
1365 tree vtabletmp2;
1366 tree vtabletmp3;
28454517 1367
1368 if (!vtable_entry_type)
1369 {
1370 tree vfunc_type = make_node (FUNCTION_TYPE);
1371 TREE_TYPE (vfunc_type) = integer_type_node;
1372 TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
1373 layout_type (vfunc_type);
1374
1375 vtable_entry_type = build_pointer_type (vfunc_type);
1376 }
1377
1378 vtabletmp =
072f7ab1 1379 create_tmp_reg (build_pointer_type
37ffa8fe 1380 (build_pointer_type (vtable_entry_type)), "vptr");
28454517 1381
1382 /* The vptr is always at offset zero in the object. */
1383 stmt = gimple_build_assign (vtabletmp,
1384 build1 (NOP_EXPR, TREE_TYPE (vtabletmp),
1385 ptr));
1386 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
28454517 1387
1388 /* Form the vtable address. */
072f7ab1 1389 vtabletmp2 = create_tmp_reg (TREE_TYPE (TREE_TYPE (vtabletmp)),
37ffa8fe 1390 "vtableaddr");
28454517 1391 stmt = gimple_build_assign (vtabletmp2,
182cf5a9 1392 build_simple_mem_ref (vtabletmp));
28454517 1393 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
28454517 1394
1395 /* Find the entry with the vcall offset. */
1396 stmt = gimple_build_assign (vtabletmp2,
2cc66f2a 1397 fold_build_pointer_plus_loc (input_location,
1398 vtabletmp2,
1399 virtual_offset));
28454517 1400 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1401
1402 /* Get the offset itself. */
072f7ab1 1403 vtabletmp3 = create_tmp_reg (TREE_TYPE (TREE_TYPE (vtabletmp2)),
37ffa8fe 1404 "vcalloffset");
28454517 1405 stmt = gimple_build_assign (vtabletmp3,
182cf5a9 1406 build_simple_mem_ref (vtabletmp2));
28454517 1407 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
28454517 1408
28454517 1409 /* Adjust the `this' pointer. */
a0553bff 1410 ptr = fold_build_pointer_plus_loc (input_location, ptr, vtabletmp3);
1411 ptr = force_gimple_operand_gsi (bsi, ptr, true, NULL_TREE, false,
1412 GSI_CONTINUE_LINKING);
28454517 1413 }
1414
55d6cb23 1415 if (!this_adjusting
1416 && fixed_offset != 0)
28454517 1417 /* Adjust the pointer by the constant. */
1418 {
1419 tree ptrtmp;
1420
1421 if (TREE_CODE (ptr) == VAR_DECL)
1422 ptrtmp = ptr;
1423 else
1424 {
072f7ab1 1425 ptrtmp = create_tmp_reg (TREE_TYPE (ptr), "ptr");
28454517 1426 stmt = gimple_build_assign (ptrtmp, ptr);
1427 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
28454517 1428 }
2cc66f2a 1429 ptr = fold_build_pointer_plus_hwi_loc (input_location,
1430 ptrtmp, fixed_offset);
28454517 1431 }
1432
1433 /* Emit the statement and gimplify the adjustment expression. */
072f7ab1 1434 ret = create_tmp_reg (TREE_TYPE (ptr), "adjusted_this");
28454517 1435 stmt = gimple_build_assign (ret, ptr);
28454517 1436 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1437
1438 return ret;
1439}
1440
6e1aa353 1441/* Expand thunk NODE to gimple if possible.
1442 When OUTPUT_ASM_THUNK is true, also produce assembler for
1443 thunks that are not lowered. */
28454517 1444
6e1aa353 1445bool
1446expand_thunk (struct cgraph_node *node, bool output_asm_thunks)
28454517 1447{
1448 bool this_adjusting = node->thunk.this_adjusting;
1449 HOST_WIDE_INT fixed_offset = node->thunk.fixed_offset;
1450 HOST_WIDE_INT virtual_value = node->thunk.virtual_value;
1451 tree virtual_offset = NULL;
48669653 1452 tree alias = node->callees->callee->symbol.decl;
7d0d0ce1 1453 tree thunk_fndecl = node->symbol.decl;
bb251465 1454 tree a;
1455
aed6e608 1456
28454517 1457 if (this_adjusting
1458 && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
1459 virtual_value, alias))
1460 {
1461 const char *fnname;
1462 tree fn_block;
28b2c6a7 1463 tree restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
6e1aa353 1464
1465 if (!output_asm_thunks)
1466 return false;
1467
1468 if (in_lto_p)
1469 cgraph_get_body (node);
1470 a = DECL_ARGUMENTS (thunk_fndecl);
28454517 1471
6e1aa353 1472 current_function_decl = thunk_fndecl;
1473
1474 /* Ensure thunks are emitted in their correct sections. */
1475 resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
1476
28454517 1477 DECL_RESULT (thunk_fndecl)
1478 = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl),
28b2c6a7 1479 RESULT_DECL, 0, restype);
6e1aa353 1480 DECL_CONTEXT (DECL_RESULT (thunk_fndecl)) = thunk_fndecl;
22ea3b47 1481 fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
28454517 1482
1483 /* The back end expects DECL_INITIAL to contain a BLOCK, so we
1484 create one. */
1485 fn_block = make_node (BLOCK);
1486 BLOCK_VARS (fn_block) = a;
1487 DECL_INITIAL (thunk_fndecl) = fn_block;
1488 init_function_start (thunk_fndecl);
1489 cfun->is_thunk = 1;
32c7c682 1490 insn_locations_init ();
1491 set_curr_insn_location (DECL_SOURCE_LOCATION (thunk_fndecl));
1492 prologue_location = curr_insn_location ();
28454517 1493 assemble_start_function (thunk_fndecl, fnname);
1494
1495 targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl,
1496 fixed_offset, virtual_value, alias);
1497
1498 assemble_end_function (thunk_fndecl, fnname);
32c7c682 1499 insn_locations_finalize ();
28454517 1500 init_insn_lengths ();
1501 free_after_compilation (cfun);
1502 set_cfun (NULL);
1503 TREE_ASM_WRITTEN (thunk_fndecl) = 1;
91bf9d9a 1504 node->thunk.thunk_p = false;
15ca8f90 1505 node->symbol.analyzed = false;
28454517 1506 }
1507 else
1508 {
1509 tree restype;
1510 basic_block bb, then_bb, else_bb, return_bb;
1511 gimple_stmt_iterator bsi;
1512 int nargs = 0;
1513 tree arg;
1514 int i;
1515 tree resdecl;
1516 tree restmp = NULL;
f1f41a6c 1517 vec<tree> vargs;
28454517 1518
1519 gimple call;
1520 gimple ret;
1521
6e1aa353 1522 if (in_lto_p)
1523 cgraph_get_body (node);
1524 a = DECL_ARGUMENTS (thunk_fndecl);
1525
1526 current_function_decl = thunk_fndecl;
1527
1528 /* Ensure thunks are emitted in their correct sections. */
1529 resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
1530
28454517 1531 DECL_IGNORED_P (thunk_fndecl) = 1;
1532 bitmap_obstack_initialize (NULL);
1533
1534 if (node->thunk.virtual_offset_p)
1535 virtual_offset = size_int (virtual_value);
1536
1537 /* Build the return declaration for the function. */
1538 restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1539 if (DECL_RESULT (thunk_fndecl) == NULL_TREE)
1540 {
1541 resdecl = build_decl (input_location, RESULT_DECL, 0, restype);
1542 DECL_ARTIFICIAL (resdecl) = 1;
1543 DECL_IGNORED_P (resdecl) = 1;
1544 DECL_RESULT (thunk_fndecl) = resdecl;
6e1aa353 1545 DECL_CONTEXT (DECL_RESULT (thunk_fndecl)) = thunk_fndecl;
28454517 1546 }
1547 else
1548 resdecl = DECL_RESULT (thunk_fndecl);
1549
cc8ef84f 1550 bb = then_bb = else_bb = return_bb = init_lowered_empty_function (thunk_fndecl, true);
28454517 1551
1552 bsi = gsi_start_bb (bb);
1553
1554 /* Build call to the function being thunked. */
1555 if (!VOID_TYPE_P (restype))
1556 {
f2c6b33f 1557 if (DECL_BY_REFERENCE (resdecl))
1558 restmp = gimple_fold_indirect_ref (resdecl);
1559 else if (!is_gimple_reg_type (restype))
28454517 1560 {
1561 restmp = resdecl;
2ab2ce89 1562 add_local_decl (cfun, restmp);
28454517 1563 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp;
1564 }
1565 else
072f7ab1 1566 restmp = create_tmp_reg (restype, "retval");
28454517 1567 }
1568
1767a056 1569 for (arg = a; arg; arg = DECL_CHAIN (arg))
28454517 1570 nargs++;
f1f41a6c 1571 vargs.create (nargs);
28454517 1572 if (this_adjusting)
f1f41a6c 1573 vargs.quick_push (thunk_adjust (&bsi, a, 1, fixed_offset,
1574 virtual_offset));
f2c6b33f 1575 else if (nargs)
f1f41a6c 1576 vargs.quick_push (a);
f2c6b33f 1577
1578 if (nargs)
1579 for (i = 1, arg = DECL_CHAIN (a); i < nargs; i++, arg = DECL_CHAIN (arg))
1580 vargs.quick_push (arg);
28454517 1581 call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs);
6e1aa353 1582 node->callees->call_stmt = call;
f1f41a6c 1583 vargs.release ();
28454517 1584 gimple_call_set_from_thunk (call, true);
1585 if (restmp)
f2c6b33f 1586 {
1587 gimple_call_set_lhs (call, restmp);
1588 gcc_assert (useless_type_conversion_p (TREE_TYPE (restmp),
1589 TREE_TYPE (TREE_TYPE (alias))));
1590 }
28454517 1591 gsi_insert_after (&bsi, call, GSI_NEW_STMT);
f2c6b33f 1592 if (!(gimple_call_flags (call) & ECF_NORETURN))
1593 {
1594 if (restmp && !this_adjusting
1595 && (fixed_offset || virtual_offset))
1596 {
1597 tree true_label = NULL_TREE;
28454517 1598
f2c6b33f 1599 if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE)
1600 {
1601 gimple stmt;
1602 /* If the return type is a pointer, we need to
1603 protect against NULL. We know there will be an
1604 adjustment, because that's why we're emitting a
1605 thunk. */
1606 then_bb = create_basic_block (NULL, (void *) 0, bb);
1607 return_bb = create_basic_block (NULL, (void *) 0, then_bb);
1608 else_bb = create_basic_block (NULL, (void *) 0, else_bb);
1609 add_bb_to_loop (then_bb, bb->loop_father);
1610 add_bb_to_loop (return_bb, bb->loop_father);
1611 add_bb_to_loop (else_bb, bb->loop_father);
1612 remove_edge (single_succ_edge (bb));
1613 true_label = gimple_block_label (then_bb);
1614 stmt = gimple_build_cond (NE_EXPR, restmp,
1615 build_zero_cst (TREE_TYPE (restmp)),
1616 NULL_TREE, NULL_TREE);
1617 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1618 make_edge (bb, then_bb, EDGE_TRUE_VALUE);
1619 make_edge (bb, else_bb, EDGE_FALSE_VALUE);
1620 make_edge (return_bb, EXIT_BLOCK_PTR, 0);
1621 make_edge (then_bb, return_bb, EDGE_FALLTHRU);
1622 make_edge (else_bb, return_bb, EDGE_FALLTHRU);
1623 bsi = gsi_last_bb (then_bb);
1624 }
28454517 1625
f2c6b33f 1626 restmp = thunk_adjust (&bsi, restmp, /*this_adjusting=*/0,
1627 fixed_offset, virtual_offset);
1628 if (true_label)
1629 {
1630 gimple stmt;
1631 bsi = gsi_last_bb (else_bb);
1632 stmt = gimple_build_assign (restmp,
1633 build_zero_cst (TREE_TYPE (restmp)));
1634 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1635 bsi = gsi_last_bb (return_bb);
1636 }
28454517 1637 }
f2c6b33f 1638 else
1639 gimple_call_set_tail (call, true);
28454517 1640
f2c6b33f 1641 /* Build return value. */
1642 ret = gimple_build_return (restmp);
1643 gsi_insert_after (&bsi, ret, GSI_NEW_STMT);
28454517 1644 }
1645 else
f2c6b33f 1646 {
1647 gimple_call_set_tail (call, true);
1648 remove_edge (single_succ_edge (bb));
1649 }
28454517 1650
6e1aa353 1651 cfun->gimple_df->in_ssa_p = true;
1652 /* FIXME: C++ FE should stop setting TREE_ASM_WRITTEN on thunks. */
1653 TREE_ASM_WRITTEN (thunk_fndecl) = false;
28454517 1654 delete_unreachable_blocks ();
1655 update_ssa (TODO_update_ssa);
f2c6b33f 1656#ifdef ENABLE_CHECKING
1657 verify_flow_info ();
1658#endif
28454517 1659
28454517 1660 /* Since we want to emit the thunk, we explicitly mark its name as
1661 referenced. */
91bf9d9a 1662 node->thunk.thunk_p = false;
6e1aa353 1663 node->lowered = true;
28454517 1664 bitmap_obstack_release (NULL);
1665 }
1666 current_function_decl = NULL;
9078126c 1667 set_cfun (NULL);
6e1aa353 1668 return true;
28454517 1669}
1670
9d75589a 1671/* Assemble thunks and aliases associated to NODE. */
91bf9d9a 1672
1673static void
c70f46b0 1674assemble_thunks_and_aliases (struct cgraph_node *node)
91bf9d9a 1675{
1676 struct cgraph_edge *e;
c70f46b0 1677 int i;
1678 struct ipa_ref *ref;
1679
91bf9d9a 1680 for (e = node->callers; e;)
1681 if (e->caller->thunk.thunk_p)
1682 {
1683 struct cgraph_node *thunk = e->caller;
1684
1685 e = e->next_caller;
c70f46b0 1686 assemble_thunks_and_aliases (thunk);
6e1aa353 1687 expand_thunk (thunk, true);
91bf9d9a 1688 }
1689 else
1690 e = e->next_caller;
04ec15fa 1691 for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list,
7d0d0ce1 1692 i, ref); i++)
c70f46b0 1693 if (ref->use == IPA_REF_ALIAS)
1694 {
04ec15fa 1695 struct cgraph_node *alias = ipa_ref_referring_node (ref);
48669653 1696 bool saved_written = TREE_ASM_WRITTEN (node->symbol.decl);
968b8c52 1697
1698 /* Force assemble_alias to really output the alias this time instead
1699 of buffering it in same alias pairs. */
48669653 1700 TREE_ASM_WRITTEN (node->symbol.decl) = 1;
afea39ad 1701 do_assemble_alias (alias->symbol.decl,
48669653 1702 DECL_ASSEMBLER_NAME (node->symbol.decl));
c70f46b0 1703 assemble_thunks_and_aliases (alias);
48669653 1704 TREE_ASM_WRITTEN (node->symbol.decl) = saved_written;
c70f46b0 1705 }
91bf9d9a 1706}
1707
da5e1e7c 1708/* Expand function specified by NODE. */
941366fd 1709
3db65b62 1710static void
cf951b1a 1711expand_function (struct cgraph_node *node)
941366fd 1712{
da5e1e7c 1713 tree decl = node->symbol.decl;
941366fd 1714 location_t saved_loc;
1715
da5e1e7c 1716 /* We ought to not compile any inline clones. */
1717 gcc_assert (!node->global.inlined_to);
1718
1719 announce_function (decl);
1720 node->process = 0;
1721 gcc_assert (node->lowered);
eaad46f2 1722 cgraph_get_body (node);
da5e1e7c 1723
1724 /* Generate RTL for the body of DECL. */
1725
941366fd 1726 timevar_push (TV_REST_OF_COMPILATION);
1727
1728 gcc_assert (cgraph_global_info_ready);
1729
1730 /* Initialize the default bitmap obstack. */
1731 bitmap_obstack_initialize (NULL);
1732
1733 /* Initialize the RTL code for the function. */
da5e1e7c 1734 current_function_decl = decl;
941366fd 1735 saved_loc = input_location;
da5e1e7c 1736 input_location = DECL_SOURCE_LOCATION (decl);
1737 init_function_start (decl);
941366fd 1738
1739 gimple_register_cfg_hooks ();
1740
1741 bitmap_obstack_initialize (&reg_obstack); /* FIXME, only at RTL generation*/
1742
1743 execute_all_ipa_transforms ();
1744
1745 /* Perform all tree transforms and optimizations. */
1746
1747 /* Signal the start of passes. */
1748 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START, NULL);
1749
3ea50c01 1750 execute_pass_list (g->get_passes ()->all_passes);
941366fd 1751
1752 /* Signal the end of passes. */
1753 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END, NULL);
1754
1755 bitmap_obstack_release (&reg_obstack);
1756
1757 /* Release the default bitmap obstack. */
1758 bitmap_obstack_release (NULL);
1759
941366fd 1760 /* If requested, warn about function definitions where the function will
1761 return a value (usually of some struct or union type) which itself will
1762 take up a lot of stack space. */
da5e1e7c 1763 if (warn_larger_than && !DECL_EXTERNAL (decl) && TREE_TYPE (decl))
941366fd 1764 {
da5e1e7c 1765 tree ret_type = TREE_TYPE (TREE_TYPE (decl));
941366fd 1766
1767 if (ret_type && TYPE_SIZE_UNIT (ret_type)
1768 && TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST
1769 && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type),
1770 larger_than_size))
1771 {
1772 unsigned int size_as_int
1773 = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type));
1774
1775 if (compare_tree_int (TYPE_SIZE_UNIT (ret_type), size_as_int) == 0)
1776 warning (OPT_Wlarger_than_, "size of return value of %q+D is %u bytes",
da5e1e7c 1777 decl, size_as_int);
941366fd 1778 else
1779 warning (OPT_Wlarger_than_, "size of return value of %q+D is larger than %wd bytes",
da5e1e7c 1780 decl, larger_than_size);
941366fd 1781 }
1782 }
1783
da5e1e7c 1784 gimple_set_body (decl, NULL);
1785 if (DECL_STRUCT_FUNCTION (decl) == 0
1786 && !cgraph_get_node (decl)->origin)
941366fd 1787 {
1788 /* Stop pointing to the local nodes about to be freed.
1789 But DECL_INITIAL must remain nonzero so we know this
1790 was an actual function definition.
1791 For a nested function, this is done in c_pop_function_context.
1792 If rest_of_compilation set this to 0, leave it 0. */
da5e1e7c 1793 if (DECL_INITIAL (decl) != 0)
1794 DECL_INITIAL (decl) = error_mark_node;
941366fd 1795 }
1796
1797 input_location = saved_loc;
1798
1799 ggc_collect ();
1800 timevar_pop (TV_REST_OF_COMPILATION);
f7777314 1801
1802 /* Make sure that BE didn't give up on compiling. */
1803 gcc_assert (TREE_ASM_WRITTEN (decl));
9078126c 1804 set_cfun (NULL);
f7777314 1805 current_function_decl = NULL;
f76f7453 1806
1807 /* It would make a lot more sense to output thunks before function body to get more
cf951b1a 1808 forward and lest backwarding jumps. This however would need solving problem
f76f7453 1809 with comdats. See PR48668. Also aliases must come after function itself to
cf951b1a 1810 make one pass assemblers, like one on AIX, happy. See PR 50689.
f76f7453 1811 FIXME: Perhaps thunks should be move before function IFF they are not in comdat
1812 groups. */
1813 assemble_thunks_and_aliases (node);
1a1a827a 1814 cgraph_release_function_body (node);
1815 /* Eliminate all call edges. This is important so the GIMPLE_CALL no longer
1816 points to the dead function body. */
1817 cgraph_node_remove_callees (node);
9df17e79 1818 ipa_remove_all_references (&node->symbol.ref_list);
ae01b312 1819}
1820
acc70efa 1821
d9d9733a 1822/* Expand all functions that must be output.
1823
d7c6d889 1824 Attempt to topologically sort the nodes so function is output when
1825 all called functions are already assembled to allow data to be
91c82c20 1826 propagated across the callgraph. Use a stack to get smaller distance
3927afe0 1827 between a function and its callees (later we may choose to use a more
d7c6d889 1828 sophisticated algorithm for function reordering; we will likely want
1829 to use subsections to make the output functions appear in top-down
1830 order). */
1831
1832static void
cf951b1a 1833expand_all_functions (void)
d7c6d889 1834{
1835 struct cgraph_node *node;
4c36ffe6 1836 struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
c04e3894 1837 int order_pos, new_order_pos = 0;
d7c6d889 1838 int i;
1839
7771d558 1840 order_pos = ipa_reverse_postorder (order);
cc636d56 1841 gcc_assert (order_pos == cgraph_n_nodes);
d7c6d889 1842
7bd28bba 1843 /* Garbage collector may remove inline clones we eliminate during
b0cdf642 1844 optimization. So we must be sure to not reference them. */
1845 for (i = 0; i < order_pos; i++)
09fc9532 1846 if (order[i]->process)
b0cdf642 1847 order[new_order_pos++] = order[i];
1848
1849 for (i = new_order_pos - 1; i >= 0; i--)
d7c6d889 1850 {
1851 node = order[i];
09fc9532 1852 if (node->process)
d7c6d889 1853 {
09fc9532 1854 node->process = 0;
cf951b1a 1855 expand_function (node);
d7c6d889 1856 }
1857 }
523c1122 1858 cgraph_process_new_functions ();
773c5ba7 1859
d7c6d889 1860 free (order);
773c5ba7 1861
d7c6d889 1862}
1863
56af936e 1864/* This is used to sort the node types by the cgraph order number. */
1865
0b09525f 1866enum cgraph_order_sort_kind
1867{
1868 ORDER_UNDEFINED = 0,
1869 ORDER_FUNCTION,
1870 ORDER_VAR,
1871 ORDER_ASM
1872};
1873
56af936e 1874struct cgraph_order_sort
1875{
0b09525f 1876 enum cgraph_order_sort_kind kind;
56af936e 1877 union
1878 {
1879 struct cgraph_node *f;
1d416bd7 1880 struct varpool_node *v;
cf951b1a 1881 struct asm_node *a;
56af936e 1882 } u;
1883};
1884
1885/* Output all functions, variables, and asm statements in the order
1886 according to their order fields, which is the order in which they
1887 appeared in the file. This implements -fno-toplevel-reorder. In
1888 this mode we may output functions and variables which don't really
1889 need to be output. */
1890
1891static void
cf951b1a 1892output_in_order (void)
56af936e 1893{
1894 int max;
56af936e 1895 struct cgraph_order_sort *nodes;
1896 int i;
1897 struct cgraph_node *pf;
1d416bd7 1898 struct varpool_node *pv;
cf951b1a 1899 struct asm_node *pa;
56af936e 1900
0704fb2e 1901 max = symtab_order;
3e1cde87 1902 nodes = XCNEWVEC (struct cgraph_order_sort, max);
56af936e 1903
7c455d87 1904 FOR_EACH_DEFINED_FUNCTION (pf)
56af936e 1905 {
15ca8f90 1906 if (pf->process && !pf->thunk.thunk_p && !pf->symbol.alias)
56af936e 1907 {
7d0d0ce1 1908 i = pf->symbol.order;
56af936e 1909 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1910 nodes[i].kind = ORDER_FUNCTION;
1911 nodes[i].u.f = pf;
1912 }
1913 }
1914
7c455d87 1915 FOR_EACH_DEFINED_VARIABLE (pv)
aa419a52 1916 if (!DECL_EXTERNAL (pv->symbol.decl))
1917 {
1918 i = pv->symbol.order;
1919 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1920 nodes[i].kind = ORDER_VAR;
1921 nodes[i].u.v = pv;
1922 }
56af936e 1923
cf951b1a 1924 for (pa = asm_nodes; pa; pa = pa->next)
56af936e 1925 {
1926 i = pa->order;
1927 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1928 nodes[i].kind = ORDER_ASM;
1929 nodes[i].u.a = pa;
1930 }
56af936e 1931
304e5318 1932 /* In toplevel reorder mode we output all statics; mark them as needed. */
304e5318 1933
91da0f1c 1934 for (i = 0; i < max; ++i)
1935 if (nodes[i].kind == ORDER_VAR)
1936 varpool_finalize_named_section_flags (nodes[i].u.v);
1937
56af936e 1938 for (i = 0; i < max; ++i)
1939 {
1940 switch (nodes[i].kind)
1941 {
1942 case ORDER_FUNCTION:
09fc9532 1943 nodes[i].u.f->process = 0;
cf951b1a 1944 expand_function (nodes[i].u.f);
56af936e 1945 break;
1946
1947 case ORDER_VAR:
1d416bd7 1948 varpool_assemble_decl (nodes[i].u.v);
56af936e 1949 break;
1950
1951 case ORDER_ASM:
1952 assemble_asm (nodes[i].u.a->asm_str);
1953 break;
1954
1955 case ORDER_UNDEFINED:
1956 break;
1957
1958 default:
1959 gcc_unreachable ();
1960 }
1961 }
4b4ea2db 1962
cf951b1a 1963 asm_nodes = NULL;
3e1cde87 1964 free (nodes);
56af936e 1965}
1966
77fce4cd 1967static void
1968ipa_passes (void)
1969{
3ea50c01 1970 gcc::pass_manager *passes = g->get_passes ();
1971
87d4aa85 1972 set_cfun (NULL);
4b14adf9 1973 current_function_decl = NULL;
75a70cf9 1974 gimple_register_cfg_hooks ();
77fce4cd 1975 bitmap_obstack_initialize (NULL);
59dd4830 1976
c9036234 1977 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START, NULL);
1978
59dd4830 1979 if (!in_lto_p)
7b2e8956 1980 {
3ea50c01 1981 execute_ipa_pass_list (passes->all_small_ipa_passes);
7b2e8956 1982 if (seen_error ())
1983 return;
1984 }
9ed5b1f5 1985
941125aa 1986 /* We never run removal of unreachable nodes after early passes. This is
1987 because TODO is run before the subpasses. It is important to remove
1988 the unreachable functions to save works at IPA level and to get LTO
1989 symbol tables right. */
91f0ab48 1990 symtab_remove_unreachable_nodes (true, cgraph_dump_file);
941125aa 1991
7bfefa9d 1992 /* If pass_all_early_optimizations was not scheduled, the state of
1993 the cgraph will not be properly updated. Update it now. */
1994 if (cgraph_state < CGRAPH_STATE_IPA_SSA)
1995 cgraph_state = CGRAPH_STATE_IPA_SSA;
9ed5b1f5 1996
7bfefa9d 1997 if (!in_lto_p)
1998 {
1999 /* Generate coverage variables and constructors. */
2000 coverage_finish ();
2001
2002 /* Process new functions added. */
2003 set_cfun (NULL);
2004 current_function_decl = NULL;
2005 cgraph_process_new_functions ();
7bfefa9d 2006
c9036234 2007 execute_ipa_summary_passes
3ea50c01 2008 ((struct ipa_opt_pass_d *) passes->all_regular_ipa_passes);
8867b500 2009 }
23433d72 2010
2011 /* Some targets need to handle LTO assembler output specially. */
2012 if (flag_generate_lto)
2013 targetm.asm_out.lto_start ();
2014
3ea50c01 2015 execute_ipa_summary_passes ((struct ipa_opt_pass_d *)
2016 passes->all_lto_gen_passes);
7bfefa9d 2017
2018 if (!in_lto_p)
2019 ipa_write_summaries ();
2020
23433d72 2021 if (flag_generate_lto)
2022 targetm.asm_out.lto_end ();
2023
b33542ab 2024 if (!flag_ltrans && (in_lto_p || !flag_lto || flag_fat_lto_objects))
3ea50c01 2025 execute_ipa_pass_list (passes->all_regular_ipa_passes);
c9036234 2026 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END, NULL);
9ed5b1f5 2027
77fce4cd 2028 bitmap_obstack_release (NULL);
2029}
2030
badeded8 2031
2032/* Return string alias is alias of. */
2033
2034static tree
2035get_alias_symbol (tree decl)
2036{
2037 tree alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
2038 return get_identifier (TREE_STRING_POINTER
2039 (TREE_VALUE (TREE_VALUE (alias))));
2040}
2041
2042
5e712541 2043/* Weakrefs may be associated to external decls and thus not output
9d75589a 2044 at expansion time. Emit all necessary aliases. */
5e712541 2045
5139ff04 2046static void
5e712541 2047output_weakrefs (void)
2048{
48669653 2049 symtab_node node;
2050 FOR_EACH_SYMBOL (node)
f2526cce 2051 if (node->symbol.alias
7d0d0ce1 2052 && !TREE_ASM_WRITTEN (node->symbol.decl)
f2526cce 2053 && node->symbol.weakref)
48669653 2054 {
2055 tree target;
2056
2057 /* Weakrefs are special by not requiring target definition in current
2058 compilation unit. It is thus bit hard to work out what we want to
2059 alias.
2060 When alias target is defined, we need to fetch it from symtab reference,
2061 otherwise it is pointed to by alias_target. */
2062 if (node->symbol.alias_target)
2063 target = (DECL_P (node->symbol.alias_target)
2064 ? DECL_ASSEMBLER_NAME (node->symbol.alias_target)
2065 : node->symbol.alias_target);
2066 else if (node->symbol.analyzed)
2067 target = DECL_ASSEMBLER_NAME (symtab_alias_target (node)->symbol.decl);
2068 else
2069 {
2070 gcc_unreachable ();
2071 target = get_alias_symbol (node->symbol.decl);
2072 }
2073 do_assemble_alias (node->symbol.decl, target);
2074 }
5e712541 2075}
2076
da5e1e7c 2077/* Initialize callgraph dump file. */
34e5cced 2078
121f3051 2079void
2080init_cgraph (void)
2081{
01ec0a6c 2082 if (!cgraph_dump_file)
2083 cgraph_dump_file = dump_begin (TDI_cgraph, NULL);
121f3051 2084}
b5d36404 2085
d2bb3f9d 2086
2087/* Perform simple optimizations based on callgraph. */
2088
2089void
cf951b1a 2090compile (void)
d2bb3f9d 2091{
2092 if (seen_error ())
2093 return;
2094
2095#ifdef ENABLE_CHECKING
3e7775f6 2096 verify_symtab ();
d2bb3f9d 2097#endif
2098
d2bb3f9d 2099 timevar_push (TV_CGRAPHOPT);
2100 if (pre_ipa_mem_report)
2101 {
2102 fprintf (stderr, "Memory consumption before IPA\n");
2103 dump_memory_report (false);
2104 }
2105 if (!quiet_flag)
2106 fprintf (stderr, "Performing interprocedural optimizations\n");
2107 cgraph_state = CGRAPH_STATE_IPA;
2108
cf951b1a 2109 /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE. */
2110 if (flag_lto)
2111 lto_streamer_hooks_init ();
2112
d2bb3f9d 2113 /* Don't run the IPA passes if there was any error or sorry messages. */
2114 if (!seen_error ())
2115 ipa_passes ();
2116
2117 /* Do nothing else if any IPA pass found errors or if we are just streaming LTO. */
2118 if (seen_error ()
2119 || (!in_lto_p && flag_lto && !flag_fat_lto_objects))
2120 {
2121 timevar_pop (TV_CGRAPHOPT);
2122 return;
2123 }
2124
2125 /* This pass remove bodies of extern inline functions we never inlined.
2126 Do this later so other IPA passes see what is really going on. */
91f0ab48 2127 symtab_remove_unreachable_nodes (false, dump_file);
d2bb3f9d 2128 cgraph_global_info_ready = true;
2129 if (cgraph_dump_file)
2130 {
2131 fprintf (cgraph_dump_file, "Optimized ");
18841b0c 2132 dump_symtab (cgraph_dump_file);
d2bb3f9d 2133 }
2134 if (post_ipa_mem_report)
2135 {
2136 fprintf (stderr, "Memory consumption after IPA\n");
2137 dump_memory_report (false);
2138 }
2139 timevar_pop (TV_CGRAPHOPT);
2140
2141 /* Output everything. */
2142 (*debug_hooks->assembly_start) ();
2143 if (!quiet_flag)
2144 fprintf (stderr, "Assembling functions:\n");
2145#ifdef ENABLE_CHECKING
3e7775f6 2146 verify_symtab ();
d2bb3f9d 2147#endif
2148
2149 cgraph_materialize_all_clones ();
2150 bitmap_obstack_initialize (NULL);
3ea50c01 2151 execute_ipa_pass_list (g->get_passes ()->all_late_ipa_passes);
91f0ab48 2152 symtab_remove_unreachable_nodes (true, dump_file);
d2bb3f9d 2153#ifdef ENABLE_CHECKING
3e7775f6 2154 verify_symtab ();
d2bb3f9d 2155#endif
2156 bitmap_obstack_release (NULL);
cf951b1a 2157 mark_functions_to_output ();
d2bb3f9d 2158
4cd8ae4b 2159 /* When weakref support is missing, we autmatically translate all
2160 references to NODE to references to its ultimate alias target.
2161 The renaming mechanizm uses flag IDENTIFIER_TRANSPARENT_ALIAS and
2162 TREE_CHAIN.
2163
2164 Set up this mapping before we output any assembler but once we are sure
2165 that all symbol renaming is done.
2166
2167 FIXME: All this uglyness can go away if we just do renaming at gimple
2168 level by physically rewritting the IL. At the moment we can only redirect
2169 calls, so we need infrastructure for renaming references as well. */
2170#ifndef ASM_OUTPUT_WEAKREF
2171 symtab_node node;
2172
2173 FOR_EACH_SYMBOL (node)
2174 if (node->symbol.alias
2175 && lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
2176 {
2177 IDENTIFIER_TRANSPARENT_ALIAS
2178 (DECL_ASSEMBLER_NAME (node->symbol.decl)) = 1;
2179 TREE_CHAIN (DECL_ASSEMBLER_NAME (node->symbol.decl))
2180 = (node->symbol.alias_target ? node->symbol.alias_target
2181 : DECL_ASSEMBLER_NAME (symtab_alias_target (node)->symbol.decl));
2182 }
2183#endif
2184
d2bb3f9d 2185 cgraph_state = CGRAPH_STATE_EXPANSION;
2186 if (!flag_toplevel_reorder)
cf951b1a 2187 output_in_order ();
d2bb3f9d 2188 else
2189 {
cf951b1a 2190 output_asm_statements ();
d2bb3f9d 2191
cf951b1a 2192 expand_all_functions ();
2193 varpool_output_variables ();
d2bb3f9d 2194 }
2195
2196 cgraph_process_new_functions ();
2197 cgraph_state = CGRAPH_STATE_FINISHED;
afea39ad 2198 output_weakrefs ();
d2bb3f9d 2199
2200 if (cgraph_dump_file)
2201 {
2202 fprintf (cgraph_dump_file, "\nFinal ");
18841b0c 2203 dump_symtab (cgraph_dump_file);
d2bb3f9d 2204 }
2205#ifdef ENABLE_CHECKING
3e7775f6 2206 verify_symtab ();
d2bb3f9d 2207 /* Double check that all inline clones are gone and that all
2208 function bodies have been released from memory. */
2209 if (!seen_error ())
2210 {
2211 struct cgraph_node *node;
2212 bool error_found = false;
2213
7c455d87 2214 FOR_EACH_DEFINED_FUNCTION (node)
2215 if (node->global.inlined_to
2216 || gimple_has_body_p (node->symbol.decl))
d2bb3f9d 2217 {
2218 error_found = true;
2219 dump_cgraph_node (stderr, node);
2220 }
2221 if (error_found)
2222 internal_error ("nodes with unreleased memory found");
2223 }
2224#endif
2225}
2226
2227
2228/* Analyze the whole compilation unit once it is parsed completely. */
2229
2230void
cf951b1a 2231finalize_compilation_unit (void)
d2bb3f9d 2232{
2233 timevar_push (TV_CGRAPH);
2234
d2bb3f9d 2235 /* If we're here there's no current function anymore. Some frontends
2236 are lazy in clearing these. */
2237 current_function_decl = NULL;
2238 set_cfun (NULL);
2239
2240 /* Do not skip analyzing the functions if there were errors, we
2241 miss diagnostics for following functions otherwise. */
2242
2243 /* Emit size functions we didn't inline. */
2244 finalize_size_functions ();
2245
2246 /* Mark alias targets necessary and emit diagnostics. */
d2bb3f9d 2247 handle_alias_pairs ();
2248
2249 if (!quiet_flag)
2250 {
2251 fprintf (stderr, "\nAnalyzing compilation unit\n");
2252 fflush (stderr);
2253 }
2254
2255 if (flag_dump_passes)
2256 dump_passes ();
2257
2258 /* Gimplify and lower all functions, compute reachability and
2259 remove unreachable nodes. */
15ca8f90 2260 analyze_functions ();
d2bb3f9d 2261
2262 /* Mark alias targets necessary and emit diagnostics. */
d2bb3f9d 2263 handle_alias_pairs ();
2264
2265 /* Gimplify and lower thunks. */
15ca8f90 2266 analyze_functions ();
d2bb3f9d 2267
2268 /* Finally drive the pass manager. */
cf951b1a 2269 compile ();
d2bb3f9d 2270
2271 timevar_pop (TV_CGRAPH);
2272}
2273
2274
a861fe52 2275#include "gt-cgraphunit.h"