]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/cgraphunit.c
Daily bump.
[thirdparty/gcc.git] / gcc / cgraphunit.c
CommitLineData
da5e1e7c 1/* Driver of optimization process
3aea1f79 2 Copyright (C) 2003-2014 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
35ee1c66 28 - finalize_function
b0cdf642 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"
9ed99284 165#include "varasm.h"
166#include "stor-layout.h"
167#include "stringpool.h"
941366fd 168#include "output.h"
b5530559 169#include "rtl.h"
bc61cadb 170#include "basic-block.h"
171#include "tree-ssa-alias.h"
172#include "internal-fn.h"
173#include "gimple-fold.h"
174#include "gimple-expr.h"
175#include "is-a.h"
e795d6e1 176#include "gimple.h"
a8783bee 177#include "gimplify.h"
dcf1a1ec 178#include "gimple-iterator.h"
e795d6e1 179#include "gimplify-me.h"
073c1fd5 180#include "gimple-ssa.h"
181#include "tree-cfg.h"
182#include "tree-into-ssa.h"
69ee5dbb 183#include "tree-ssa.h"
ae01b312 184#include "tree-inline.h"
185#include "langhooks.h"
ae01b312 186#include "toplev.h"
187#include "flags.h"
ae01b312 188#include "debug.h"
189#include "target.h"
80a85d8a 190#include "diagnostic.h"
d7c6d889 191#include "params.h"
192#include "fibheap.h"
611e5405 193#include "intl.h"
b69eb0ff 194#include "function.h"
b5d36404 195#include "ipa-prop.h"
75a70cf9 196#include "tree-iterator.h"
f1e2a033 197#include "tree-pass.h"
bfec3452 198#include "tree-dump.h"
da5e1e7c 199#include "gimple-pretty-print.h"
c1dcd13c 200#include "output.h"
9ed5b1f5 201#include "coverage.h"
c9036234 202#include "plugin.h"
a41f2a28 203#include "ipa-inline.h"
7771d558 204#include "ipa-utils.h"
a0605d65 205#include "lto-streamer.h"
3db65b62 206#include "except.h"
7eacb0dd 207#include "cfgloop.h"
941366fd 208#include "regset.h" /* FIXME: For reg_obstack. */
3ea50c01 209#include "context.h"
210#include "pass_manager.h"
e797f49f 211#include "tree-nested.h"
8a4a28a8 212#include "gimplify.h"
ceb49bba 213#include "dbgcnt.h"
d7c6d889 214
ff2a5ada 215/* Queue of cgraph nodes scheduled to be added into cgraph. This is a
216 secondary queue used during optimization to accommodate passes that
217 may generate new functions that need to be optimized and expanded. */
347a47cb 218vec<cgraph_node *> cgraph_new_nodes;
ff2a5ada 219
cf951b1a 220static void expand_all_functions (void);
221static void mark_functions_to_output (void);
18a71d50 222static void handle_alias_pairs (void);
25bb88de 223
28454517 224/* Used for vtable lookup in thunk adjusting. */
225static GTY (()) tree vtable_entry_type;
226
35ee1c66 227/* Determine if symbol declaration is needed. That is, visible to something
6a1c0403 228 either outside this translation unit, something magic in the system
229 configury */
230bool
35ee1c66 231symtab_node::needed_p (void)
2c0b522d 232{
8efa224a 233 /* Double check that no one output the function into assembly file
234 early. */
235 gcc_checking_assert (!DECL_ASSEMBLER_NAME_SET_P (decl)
48669653 236 || !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)));
3f82b628 237
35ee1c66 238 if (!definition)
6a1c0403 239 return false;
55680bef 240
6a1c0403 241 if (DECL_EXTERNAL (decl))
242 return false;
8baa9d15 243
6a1c0403 244 /* If the user told us it is used, then it must be so. */
35ee1c66 245 if (force_output)
6a1c0403 246 return true;
247
248 /* ABI forced symbols are needed when they are external. */
35ee1c66 249 if (forced_by_abi && TREE_PUBLIC (decl))
6a1c0403 250 return true;
251
252 /* Keep constructors, destructors and virtual functions. */
253 if (TREE_CODE (decl) == FUNCTION_DECL
254 && (DECL_STATIC_CONSTRUCTOR (decl) || DECL_STATIC_DESTRUCTOR (decl)))
255 return true;
256
257 /* Externally visible variables must be output. The exception is
258 COMDAT variables that must be output only when they are needed. */
259 if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
2c0b522d 260 return true;
261
2c0b522d 262 return false;
263}
264
3cb3fce5 265/* Head and terminator of the queue of nodes to be processed while building
266 callgraph. */
ff2a5ada 267
3cb3fce5 268static symtab_node symtab_terminator;
269static symtab_node *queued_nodes = &symtab_terminator;
ff2a5ada 270
3cb3fce5 271/* Add NODE to queue starting at QUEUED_NODES.
ff2a5ada 272 The queue is linked via AUX pointers and terminated by pointer to 1. */
273
274static void
452659af 275enqueue_node (symtab_node *node)
ff2a5ada 276{
02774f2d 277 if (node->aux)
ff2a5ada 278 return;
3cb3fce5 279 gcc_checking_assert (queued_nodes);
280 node->aux = queued_nodes;
281 queued_nodes = node;
ff2a5ada 282}
283
bdc40eb8 284/* Process CGRAPH_NEW_FUNCTIONS and perform actions necessary to add these
523c1122 285 functions into callgraph in a way so they look like ordinary reachable
286 functions inserted into callgraph already at construction time. */
287
3cb3fce5 288void
35ee1c66 289symbol_table::process_new_functions (void)
523c1122 290{
523c1122 291 tree fndecl;
523c1122 292
347a47cb 293 if (!cgraph_new_nodes.exists ())
3cb3fce5 294 return;
347a47cb 295
18a71d50 296 handle_alias_pairs ();
523c1122 297 /* Note that this queue may grow as its being processed, as the new
298 functions may generate new ones. */
347a47cb 299 for (unsigned i = 0; i < cgraph_new_nodes.length (); i++)
523c1122 300 {
347a47cb 301 cgraph_node *node = cgraph_new_nodes[i];
02774f2d 302 fndecl = node->decl;
35ee1c66 303 switch (state)
523c1122 304 {
35ee1c66 305 case CONSTRUCTION:
523c1122 306 /* At construction time we just need to finalize function and move
307 it into reachable functions list. */
308
35ee1c66 309 cgraph_node::finalize_function (fndecl, false);
310 call_cgraph_insertion_hooks (node);
02774f2d 311 enqueue_node (node);
523c1122 312 break;
313
35ee1c66 314 case IPA:
315 case IPA_SSA:
523c1122 316 /* When IPA optimization already started, do all essential
317 transformations that has been already performed on the whole
318 cgraph but not on this function. */
319
75a70cf9 320 gimple_register_cfg_hooks ();
02774f2d 321 if (!node->analyzed)
415d1b9a 322 node->analyze ();
523c1122 323 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
35ee1c66 324 if (state == IPA_SSA
f517b36e 325 && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
bcfddb5b 326 g->get_passes ()->execute_early_local_passes ();
f2c6b33f 327 else if (inline_summary_vec != NULL)
a41f2a28 328 compute_inline_parameters (node, true);
523c1122 329 free_dominance_info (CDI_POST_DOMINATORS);
330 free_dominance_info (CDI_DOMINATORS);
331 pop_cfun ();
523c1122 332 break;
333
35ee1c66 334 case EXPANSION:
523c1122 335 /* Functions created during expansion shall be compiled
336 directly. */
09fc9532 337 node->process = 0;
35ee1c66 338 call_cgraph_insertion_hooks (node);
339 node->expand ();
523c1122 340 break;
341
342 default:
343 gcc_unreachable ();
344 break;
345 }
346 }
347a47cb 347
348 cgraph_new_nodes.release ();
523c1122 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
415d1b9a 362cgraph_node::reset (void)
9b8fb23a 363{
415d1b9a 364 /* If 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. */
415d1b9a 369 gcc_assert (!process);
9b8fb23a 370
371 /* Reset our data structures so we can analyze the function again. */
415d1b9a 372 memset (&local, 0, sizeof (local));
373 memset (&global, 0, sizeof (global));
374 memset (&rtl, 0, sizeof (rtl));
375 analyzed = false;
376 definition = false;
377 alias = false;
378 weakref = false;
379 cpp_implicit_alias = false;
380
381 remove_callees ();
382 remove_all_references ();
9b8fb23a 383}
c08871a9 384
35ee1c66 385/* Return true when there are references to the node. */
9a2639fc 386
35ee1c66 387bool
388symtab_node::referred_to_p (void)
9a2639fc 389{
35ee1c66 390 ipa_ref *ref = NULL;
9a2639fc 391
9d75589a 392 /* See if there are any references at all. */
35ee1c66 393 if (iterate_referring (0, ref))
9a2639fc 394 return true;
cf951b1a 395 /* For functions check also calls. */
35ee1c66 396 cgraph_node *cn = dyn_cast <cgraph_node *> (this);
2dc9831f 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
35ee1c66 408cgraph_node::finalize_function (tree decl, bool no_collect)
ae01b312 409{
35ee1c66 410 cgraph_node *node = cgraph_node::get_create (decl);
ae01b312 411
02774f2d 412 if (node->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);
415d1b9a 417 node->reset ();
443089c1 418 node->local.redefined_extern_inline = true;
419 }
28df663b 420
c08871a9 421 notice_global_symbol (decl);
02774f2d 422 node->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))
02774f2d 431 node->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
02774f2d 439 && !node->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))
02774f2d 445 node->force_output = 1;
8efa224a 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
35ee1c66 458 if (symtab->state == CONSTRUCTION
459 && (node->needed_p () || node->referred_to_p ()))
02774f2d 460 enqueue_node (node);
ae01b312 461}
462
3db65b62 463/* Add the function FNDECL to the call graph.
35ee1c66 464 Unlike finalize_function, this function is intended to be used
3db65b62 465 by middle end and allows insertion of new function at arbitrary point
466 of compilation. The function can be either in high, low or SSA form
467 GIMPLE.
468
469 The function is assumed to be reachable and have address taken (so no
470 API breaking optimizations are performed on it).
471
472 Main work done by this function is to enqueue the function for later
473 processing to avoid need the passes to be re-entrant. */
474
475void
415d1b9a 476cgraph_node::add_new_function (tree fndecl, bool lowered)
3db65b62 477{
3ea50c01 478 gcc::pass_manager *passes = g->get_passes ();
35ee1c66 479 cgraph_node *node;
480 switch (symtab->state)
3db65b62 481 {
35ee1c66 482 case PARSING:
483 cgraph_node::finalize_function (fndecl, false);
ff2a5ada 484 break;
35ee1c66 485 case CONSTRUCTION:
3db65b62 486 /* Just enqueue function to be processed at nearest occurrence. */
415d1b9a 487 node = cgraph_node::get_create (fndecl);
3db65b62 488 if (lowered)
489 node->lowered = true;
347a47cb 490 cgraph_new_nodes.safe_push (node);
3db65b62 491 break;
492
35ee1c66 493 case IPA:
494 case IPA_SSA:
495 case EXPANSION:
3db65b62 496 /* Bring the function into finalized state and enqueue for later
497 analyzing and compilation. */
415d1b9a 498 node = cgraph_node::get_create (fndecl);
3db65b62 499 node->local.local = false;
02774f2d 500 node->definition = true;
501 node->force_output = true;
35ee1c66 502 if (!lowered && symtab->state == EXPANSION)
3db65b62 503 {
504 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
3db65b62 505 gimple_register_cfg_hooks ();
506 bitmap_obstack_initialize (NULL);
3538ae0d 507 execute_pass_list (cfun, passes->all_lowering_passes);
bcfddb5b 508 passes->execute_early_local_passes ();
3db65b62 509 bitmap_obstack_release (NULL);
510 pop_cfun ();
3db65b62 511
512 lowered = true;
513 }
514 if (lowered)
515 node->lowered = true;
347a47cb 516 cgraph_new_nodes.safe_push (node);
3db65b62 517 break;
518
35ee1c66 519 case FINISHED:
3db65b62 520 /* At the very end of compilation we have to do all the work up
521 to expansion. */
415d1b9a 522 node = cgraph_node::create (fndecl);
3db65b62 523 if (lowered)
524 node->lowered = true;
02774f2d 525 node->definition = true;
415d1b9a 526 node->analyze ();
3db65b62 527 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
3db65b62 528 gimple_register_cfg_hooks ();
529 bitmap_obstack_initialize (NULL);
530 if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
bcfddb5b 531 g->get_passes ()->execute_early_local_passes ();
3db65b62 532 bitmap_obstack_release (NULL);
3db65b62 533 pop_cfun ();
35ee1c66 534 node->expand ();
3db65b62 535 break;
536
537 default:
538 gcc_unreachable ();
539 }
540
541 /* Set a personality if required and we already passed EH lowering. */
542 if (lowered
543 && (function_needs_eh_personality (DECL_STRUCT_FUNCTION (fndecl))
544 == eh_personality_lang))
545 DECL_FUNCTION_PERSONALITY (fndecl) = lang_hooks.eh_personality ();
546}
547
56af936e 548/* Output all asm statements we have stored up to be output. */
549
35ee1c66 550void
551symbol_table::output_asm_statements (void)
56af936e 552{
35ee1c66 553 asm_node *can;
56af936e 554
852f689e 555 if (seen_error ())
56af936e 556 return;
557
35ee1c66 558 for (can = first_asm_symbol (); can; can = can->next)
56af936e 559 assemble_asm (can->asm_str);
35ee1c66 560
561 clear_asm_symbols ();
cf951b1a 562}
563
0785e435 564/* Analyze the function scheduled to be output. */
415d1b9a 565void
566cgraph_node::analyze (void)
0785e435 567{
415d1b9a 568 tree decl = this->decl;
da5e1e7c 569 location_t saved_loc = input_location;
570 input_location = DECL_SOURCE_LOCATION (decl);
0785e435 571
415d1b9a 572 if (thunk.thunk_p)
91bf9d9a 573 {
415d1b9a 574 create_edge (cgraph_node::get (thunk.alias),
575 NULL, 0, CGRAPH_FREQ_BASE);
576 if (!expand_thunk (false, false))
6e1aa353 577 {
415d1b9a 578 thunk.alias = NULL;
6e1aa353 579 return;
580 }
415d1b9a 581 thunk.alias = NULL;
91bf9d9a 582 }
415d1b9a 583 if (alias)
584 resolve_alias (cgraph_node::get (alias_target));
585 else if (dispatcher_function)
cc8ef84f 586 {
587 /* Generate the dispatcher body of multi-versioned functions. */
35ee1c66 588 cgraph_function_version_info *dispatcher_version_info
415d1b9a 589 = function_version ();
cc8ef84f 590 if (dispatcher_version_info != NULL
591 && (dispatcher_version_info->dispatcher_resolver
592 == NULL_TREE))
593 {
594 tree resolver = NULL_TREE;
595 gcc_assert (targetm.generate_version_dispatcher_body);
415d1b9a 596 resolver = targetm.generate_version_dispatcher_body (this);
cc8ef84f 597 gcc_assert (resolver != NULL_TREE);
598 }
599 }
91bf9d9a 600 else
601 {
91bf9d9a 602 push_cfun (DECL_STRUCT_FUNCTION (decl));
bfec3452 603
415d1b9a 604 assign_assembler_name_if_neeeded (decl);
6816d0c4 605
91bf9d9a 606 /* Make sure to gimplify bodies only once. During analyzing a
607 function we lower it, which will require gimplified nested
608 functions, so we can end up here with an already gimplified
609 body. */
e3a19533 610 if (!gimple_has_body_p (decl))
91bf9d9a 611 gimplify_function_tree (decl);
612 dump_function (TDI_generic, decl);
bfec3452 613
47199071 614 /* Lower the function. */
415d1b9a 615 if (!lowered)
47199071 616 {
415d1b9a 617 if (nested)
618 lower_nested_functions (decl);
619 gcc_assert (!nested);
47199071 620
621 gimple_register_cfg_hooks ();
622 bitmap_obstack_initialize (NULL);
3538ae0d 623 execute_pass_list (cfun, g->get_passes ()->all_lowering_passes);
47199071 624 free_dominance_info (CDI_POST_DOMINATORS);
625 free_dominance_info (CDI_DOMINATORS);
626 compact_blocks ();
627 bitmap_obstack_release (NULL);
415d1b9a 628 lowered = true;
47199071 629 }
630
91bf9d9a 631 pop_cfun ();
632 }
415d1b9a 633 analyzed = true;
0785e435 634
da5e1e7c 635 input_location = saved_loc;
0785e435 636}
637
c70f46b0 638/* C++ frontend produce same body aliases all over the place, even before PCH
639 gets streamed out. It relies on us linking the aliases with their function
640 in order to do the fixups, but ipa-ref is not PCH safe. Consequentely we
641 first produce aliases without links, but once C++ FE is sure he won't sream
642 PCH we build the links via this function. */
643
644void
35ee1c66 645symbol_table::process_same_body_aliases (void)
c70f46b0 646{
452659af 647 symtab_node *node;
48669653 648 FOR_EACH_SYMBOL (node)
02774f2d 649 if (node->cpp_implicit_alias && !node->analyzed)
415d1b9a 650 node->resolve_alias
651 (TREE_CODE (node->alias_target) == VAR_DECL
97221fd7 652 ? (symtab_node *)varpool_node::get_create (node->alias_target)
415d1b9a 653 : (symtab_node *)cgraph_node::get_create (node->alias_target));
48669653 654 cpp_implicit_aliases_done = true;
c70f46b0 655}
656
d05db70d 657/* Process attributes common for vars and functions. */
658
659static void
660process_common_attributes (tree decl)
661{
662 tree weakref = lookup_attribute ("weakref", DECL_ATTRIBUTES (decl));
663
664 if (weakref && !lookup_attribute ("alias", DECL_ATTRIBUTES (decl)))
665 {
666 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
667 "%<weakref%> attribute should be accompanied with"
668 " an %<alias%> attribute");
669 DECL_WEAK (decl) = 0;
40b32d93 670 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
671 DECL_ATTRIBUTES (decl));
d05db70d 672 }
673}
674
05806473 675/* Look for externally_visible and used attributes and mark cgraph nodes
676 accordingly.
677
678 We cannot mark the nodes at the point the attributes are processed (in
679 handle_*_attribute) because the copy of the declarations available at that
680 point may not be canonical. For example, in:
681
682 void f();
683 void f() __attribute__((used));
684
685 the declaration we see in handle_used_attribute will be the second
686 declaration -- but the front end will subsequently merge that declaration
687 with the original declaration and discard the second declaration.
688
35ee1c66 689 Furthermore, we can't mark these nodes in finalize_function because:
05806473 690
691 void f() {}
692 void f() __attribute__((externally_visible));
693
694 is valid.
695
696 So, we walk the nodes at the end of the translation unit, applying the
697 attributes at that point. */
698
699static void
35ee1c66 700process_function_and_variable_attributes (cgraph_node *first,
098f44bc 701 varpool_node *first_var)
05806473 702{
35ee1c66 703 cgraph_node *node;
098f44bc 704 varpool_node *vnode;
05806473 705
35ee1c66 706 for (node = symtab->first_function (); node != first;
707 node = symtab->next_function (node))
05806473 708 {
02774f2d 709 tree decl = node->decl;
83a23b05 710 if (DECL_PRESERVE_P (decl))
415d1b9a 711 node->mark_force_output ();
62433d51 712 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
05806473 713 {
02774f2d 714 if (! TREE_PUBLIC (node->decl))
715 warning_at (DECL_SOURCE_LOCATION (node->decl), OPT_Wattributes,
712d2297 716 "%<externally_visible%>"
717 " attribute have effect only on public objects");
05806473 718 }
40b32d93 719 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
02774f2d 720 && (node->definition && !node->alias))
40b32d93 721 {
02774f2d 722 warning_at (DECL_SOURCE_LOCATION (node->decl), OPT_Wattributes,
40b32d93 723 "%<weakref%> attribute ignored"
724 " because function is defined");
725 DECL_WEAK (decl) = 0;
726 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
727 DECL_ATTRIBUTES (decl));
728 }
a522e9eb 729
730 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl))
731 && !DECL_DECLARED_INLINE_P (decl)
732 /* redefining extern inline function makes it DECL_UNINLINABLE. */
733 && !DECL_UNINLINABLE (decl))
734 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
735 "always_inline function might not be inlinable");
736
d05db70d 737 process_common_attributes (decl);
05806473 738 }
35ee1c66 739 for (vnode = symtab->first_variable (); vnode != first_var;
740 vnode = symtab->next_variable (vnode))
05806473 741 {
02774f2d 742 tree decl = vnode->decl;
aa419a52 743 if (DECL_EXTERNAL (decl)
df8d3e89 744 && DECL_INITIAL (decl))
97221fd7 745 varpool_node::finalize_decl (decl);
83a23b05 746 if (DECL_PRESERVE_P (decl))
02774f2d 747 vnode->force_output = true;
62433d51 748 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
05806473 749 {
02774f2d 750 if (! TREE_PUBLIC (vnode->decl))
751 warning_at (DECL_SOURCE_LOCATION (vnode->decl), OPT_Wattributes,
712d2297 752 "%<externally_visible%>"
753 " attribute have effect only on public objects");
05806473 754 }
40b32d93 755 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
02774f2d 756 && vnode->definition
40b32d93 757 && DECL_INITIAL (decl))
758 {
02774f2d 759 warning_at (DECL_SOURCE_LOCATION (vnode->decl), OPT_Wattributes,
40b32d93 760 "%<weakref%> attribute ignored"
761 " because variable is initialized");
762 DECL_WEAK (decl) = 0;
763 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
764 DECL_ATTRIBUTES (decl));
765 }
d05db70d 766 process_common_attributes (decl);
05806473 767 }
768}
769
ff2a5ada 770/* Mark DECL as finalized. By finalizing the declaration, frontend instruct the
771 middle end to output the variable to asm file, if needed or externally
772 visible. */
773
774void
97221fd7 775varpool_node::finalize_decl (tree decl)
ff2a5ada 776{
97221fd7 777 varpool_node *node = varpool_node::get_create (decl);
ff2a5ada 778
2d4bf241 779 gcc_assert (TREE_STATIC (decl) || DECL_EXTERNAL (decl));
ff2a5ada 780
02774f2d 781 if (node->definition)
ff2a5ada 782 return;
783 notice_global_symbol (decl);
02774f2d 784 node->definition = true;
ff2a5ada 785 if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
786 /* Traditionally we do not eliminate static variables when not
787 optimizing and when not doing toplevel reoder. */
02774f2d 788 || (!flag_toplevel_reorder && !DECL_COMDAT (node->decl)
789 && !DECL_ARTIFICIAL (node->decl)))
790 node->force_output = true;
ff2a5ada 791
35ee1c66 792 if (symtab->state == CONSTRUCTION
793 && (node->needed_p () || node->referred_to_p ()))
02774f2d 794 enqueue_node (node);
35ee1c66 795 if (symtab->state >= IPA_SSA)
97221fd7 796 node->analyze ();
3d1c0354 797 /* Some frontends produce various interface variables after compilation
798 finished. */
35ee1c66 799 if (symtab->state == FINISHED
800 || (!flag_toplevel_reorder
801 && symtab->state == EXPANSION))
97221fd7 802 node->assemble_decl ();
ff2a5ada 803}
804
98e7a67f 805/* EDGE is an polymorphic call. Mark all possible targets as reachable
806 and if there is only one target, perform trivial devirtualization.
807 REACHABLE_CALL_TARGETS collects target lists we already walked to
808 avoid udplicate work. */
809
810static void
431205b7 811walk_polymorphic_call_targets (hash_set<void *> *reachable_call_targets,
35ee1c66 812 cgraph_edge *edge)
98e7a67f 813{
814 unsigned int i;
815 void *cache_token;
816 bool final;
817 vec <cgraph_node *>targets
818 = possible_polymorphic_call_targets
819 (edge, &final, &cache_token);
820
431205b7 821 if (!reachable_call_targets->add (cache_token))
98e7a67f 822 {
35ee1c66 823 if (symtab->dump_file)
98e7a67f 824 dump_possible_polymorphic_call_targets
35ee1c66 825 (symtab->dump_file, edge);
98e7a67f 826
9af5ce0c 827 for (i = 0; i < targets.length (); i++)
98e7a67f 828 {
829 /* Do not bother to mark virtual methods in anonymous namespace;
830 either we will find use of virtual table defining it, or it is
831 unused. */
02774f2d 832 if (targets[i]->definition
98e7a67f 833 && TREE_CODE
02774f2d 834 (TREE_TYPE (targets[i]->decl))
98e7a67f 835 == METHOD_TYPE
836 && !type_in_anonymous_namespace_p
837 (method_class_type
02774f2d 838 (TREE_TYPE (targets[i]->decl))))
839 enqueue_node (targets[i]);
98e7a67f 840 }
841 }
842
843 /* Very trivial devirtualization; when the type is
844 final or anonymous (so we know all its derivation)
845 and there is only one possible virtual call target,
846 make the edge direct. */
847 if (final)
848 {
ceb49bba 849 if (targets.length () <= 1 && dbg_cnt (devirt))
98e7a67f 850 {
e2fa5d74 851 cgraph_node *target;
852 if (targets.length () == 1)
853 target = targets[0];
854 else
415d1b9a 855 target = cgraph_node::create
856 (builtin_decl_implicit (BUILT_IN_UNREACHABLE));
e2fa5d74 857
35ee1c66 858 if (symtab->dump_file)
98e7a67f 859 {
35ee1c66 860 fprintf (symtab->dump_file,
98e7a67f 861 "Devirtualizing call: ");
35ee1c66 862 print_gimple_stmt (symtab->dump_file,
98e7a67f 863 edge->call_stmt, 0,
864 TDF_SLIM);
865 }
ceb49bba 866 if (dump_enabled_p ())
867 {
4c8041d7 868 location_t locus = gimple_location_safe (edge->call_stmt);
ceb49bba 869 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, locus,
870 "devirtualizing call in %s to %s\n",
871 edge->caller->name (), target->name ());
872 }
873
35ee1c66 874 edge->make_direct (target);
875 edge->redirect_call_stmt_to_callee ();
876 if (symtab->dump_file)
98e7a67f 877 {
35ee1c66 878 fprintf (symtab->dump_file,
98e7a67f 879 "Devirtualized as: ");
35ee1c66 880 print_gimple_stmt (symtab->dump_file,
98e7a67f 881 edge->call_stmt, 0,
882 TDF_SLIM);
883 }
884 }
885 }
886}
887
2dc9831f 888
ff2a5ada 889/* Discover all functions and variables that are trivially needed, analyze
890 them as well as all functions and variables referred by them */
ae01b312 891
aeeb194b 892static void
15ca8f90 893analyze_functions (void)
ae01b312 894{
c1dcd13c 895 /* Keep track of already processed nodes when called multiple times for
06b27565 896 intermodule optimization. */
35ee1c66 897 static cgraph_node *first_analyzed;
898 cgraph_node *first_handled = first_analyzed;
098f44bc 899 static varpool_node *first_analyzed_var;
900 varpool_node *first_handled_var = first_analyzed_var;
431205b7 901 hash_set<void *> reachable_call_targets;
ff2a5ada 902
452659af 903 symtab_node *node;
904 symtab_node *next;
ff2a5ada 905 int i;
35ee1c66 906 ipa_ref *ref;
ff2a5ada 907 bool changed = true;
fd9fde78 908 location_t saved_loc = input_location;
ae01b312 909
f1c35659 910 bitmap_obstack_initialize (NULL);
35ee1c66 911 symtab->state = CONSTRUCTION;
fd9fde78 912 input_location = UNKNOWN_LOCATION;
ae01b312 913
48669653 914 /* Ugly, but the fixup can not happen at a time same body alias is created;
915 C++ FE is confused about the COMDAT groups being right. */
35ee1c66 916 if (symtab->cpp_implicit_aliases_done)
48669653 917 FOR_EACH_SYMBOL (node)
02774f2d 918 if (node->cpp_implicit_alias)
415d1b9a 919 node->fixup_same_cpp_alias_visibility (node->get_alias_target ());
5514adf9 920 if (optimize && flag_devirtualize)
921 build_type_inheritance_graph ();
48669653 922
ff2a5ada 923 /* Analysis adds static variables that in turn adds references to new functions.
924 So we need to iterate the process until it stabilize. */
925 while (changed)
ae01b312 926 {
ff2a5ada 927 changed = false;
928 process_function_and_variable_attributes (first_analyzed,
929 first_analyzed_var);
930
931 /* First identify the trivially needed symbols. */
35ee1c66 932 for (node = symtab->first_symbol ();
02774f2d 933 node != first_analyzed
934 && node != first_analyzed_var; node = node->next)
9b8fb23a 935 {
1d9ca4f0 936 /* Convert COMDAT group designators to IDENTIFIER_NODEs. */
937 node->get_comdat_group_id ();
35ee1c66 938 if (node->needed_p ())
ff2a5ada 939 {
940 enqueue_node (node);
35ee1c66 941 if (!changed && symtab->dump_file)
942 fprintf (symtab->dump_file, "Trivially needed symbols:");
ff2a5ada 943 changed = true;
35ee1c66 944 if (symtab->dump_file)
945 fprintf (symtab->dump_file, " %s", node->asm_name ());
946 if (!changed && symtab->dump_file)
947 fprintf (symtab->dump_file, "\n");
ff2a5ada 948 }
02774f2d 949 if (node == first_analyzed
950 || node == first_analyzed_var)
ff2a5ada 951 break;
9b8fb23a 952 }
35ee1c66 953 symtab->process_new_functions ();
954 first_analyzed_var = symtab->first_variable ();
955 first_analyzed = symtab->first_function ();
638531ad 956
35ee1c66 957 if (changed && symtab->dump_file)
958 fprintf (symtab->dump_file, "\n");
2c0b522d 959
ff2a5ada 960 /* Lower representation, build callgraph edges and references for all trivially
961 needed symbols and all symbols referred by them. */
3cb3fce5 962 while (queued_nodes != &symtab_terminator)
61c2c7b1 963 {
ff2a5ada 964 changed = true;
3cb3fce5 965 node = queued_nodes;
966 queued_nodes = (symtab_node *)queued_nodes->aux;
13cbeaac 967 cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
02774f2d 968 if (cnode && cnode->definition)
ff2a5ada 969 {
35ee1c66 970 cgraph_edge *edge;
02774f2d 971 tree decl = cnode->decl;
ff2a5ada 972
2dc9831f 973 /* ??? It is possible to create extern inline function
974 and later using weak alias attribute to kill its body.
975 See gcc.c-torture/compile/20011119-1.c */
ff2a5ada 976 if (!DECL_STRUCT_FUNCTION (decl)
02774f2d 977 && !cnode->alias
cc8ef84f 978 && !cnode->thunk.thunk_p
979 && !cnode->dispatcher_function)
ff2a5ada 980 {
415d1b9a 981 cnode->reset ();
ff2a5ada 982 cnode->local.redefined_extern_inline = true;
983 continue;
984 }
61c2c7b1 985
02774f2d 986 if (!cnode->analyzed)
415d1b9a 987 cnode->analyze ();
d544ceff 988
ff2a5ada 989 for (edge = cnode->callees; edge; edge = edge->next_callee)
02774f2d 990 if (edge->callee->definition)
991 enqueue_node (edge->callee);
5514adf9 992 if (optimize && flag_devirtualize)
993 {
35ee1c66 994 cgraph_edge *next;
98e7a67f 995
996 for (edge = cnode->indirect_calls; edge; edge = next)
1e4f4118 997 {
998 next = edge->next_callee;
999 if (edge->indirect_info->polymorphic)
431205b7 1000 walk_polymorphic_call_targets (&reachable_call_targets,
98e7a67f 1001 edge);
1e4f4118 1002 }
5514adf9 1003 }
ff2a5ada 1004
2dc9831f 1005 /* If decl is a clone of an abstract function,
1006 mark that abstract function so that we don't release its body.
1007 The DECL_INITIAL() of that abstract function declaration
1008 will be later needed to output debug info. */
ff2a5ada 1009 if (DECL_ABSTRACT_ORIGIN (decl))
1010 {
35ee1c66 1011 cgraph_node *origin_node
b3a78a8c 1012 = cgraph_node::get_create (DECL_ABSTRACT_ORIGIN (decl));
abb1a237 1013 origin_node->used_as_abstract_origin = true;
ff2a5ada 1014 }
ff2a5ada 1015 }
2dc9831f 1016 else
1017 {
13cbeaac 1018 varpool_node *vnode = dyn_cast <varpool_node *> (node);
02774f2d 1019 if (vnode && vnode->definition && !vnode->analyzed)
97221fd7 1020 vnode->analyze ();
2dc9831f 1021 }
ff2a5ada 1022
02774f2d 1023 if (node->same_comdat_group)
ff2a5ada 1024 {
452659af 1025 symtab_node *next;
02774f2d 1026 for (next = node->same_comdat_group;
ff2a5ada 1027 next != node;
02774f2d 1028 next = next->same_comdat_group)
ff2a5ada 1029 enqueue_node (next);
1030 }
51ce5652 1031 for (i = 0; node->iterate_reference (i, ref); i++)
02774f2d 1032 if (ref->referred->definition)
ff2a5ada 1033 enqueue_node (ref->referred);
35ee1c66 1034 symtab->process_new_functions ();
ff2a5ada 1035 }
ae01b312 1036 }
07c6dcc3 1037 if (optimize && flag_devirtualize)
1038 update_type_inheritance_graph ();
2c0b522d 1039
aa5e06c7 1040 /* Collect entry points to the unit. */
35ee1c66 1041 if (symtab->dump_file)
3d7bfc56 1042 {
35ee1c66 1043 fprintf (symtab->dump_file, "\n\nInitial ");
1044 symtab_node::dump_table (symtab->dump_file);
3d7bfc56 1045 }
e6d2b2d8 1046
35ee1c66 1047 if (symtab->dump_file)
1048 fprintf (symtab->dump_file, "\nRemoving unused symbols:");
ae01b312 1049
35ee1c66 1050 for (node = symtab->first_symbol ();
02774f2d 1051 node != first_handled
1052 && node != first_handled_var; node = next)
ae01b312 1053 {
02774f2d 1054 next = node->next;
35ee1c66 1055 if (!node->aux && !node->referred_to_p ())
ae01b312 1056 {
35ee1c66 1057 if (symtab->dump_file)
1058 fprintf (symtab->dump_file, " %s", node->name ());
415d1b9a 1059 node->remove ();
9b8fb23a 1060 continue;
ae01b312 1061 }
13cbeaac 1062 if (cgraph_node *cnode = dyn_cast <cgraph_node *> (node))
ff2a5ada 1063 {
02774f2d 1064 tree decl = node->decl;
ff2a5ada 1065
02774f2d 1066 if (cnode->definition && !gimple_has_body_p (decl)
1067 && !cnode->alias
ff2a5ada 1068 && !cnode->thunk.thunk_p)
415d1b9a 1069 cnode->reset ();
ff2a5ada 1070
02774f2d 1071 gcc_assert (!cnode->definition || cnode->thunk.thunk_p
1072 || cnode->alias
ff2a5ada 1073 || gimple_has_body_p (decl));
02774f2d 1074 gcc_assert (cnode->analyzed == cnode->definition);
ff2a5ada 1075 }
02774f2d 1076 node->aux = NULL;
ae01b312 1077 }
02774f2d 1078 for (;node; node = node->next)
1079 node->aux = NULL;
35ee1c66 1080 first_analyzed = symtab->first_function ();
1081 first_analyzed_var = symtab->first_variable ();
1082 if (symtab->dump_file)
e4200070 1083 {
35ee1c66 1084 fprintf (symtab->dump_file, "\n\nReclaimed ");
1085 symtab_node::dump_table (symtab->dump_file);
e4200070 1086 }
f1c35659 1087 bitmap_obstack_release (NULL);
ae01b312 1088 ggc_collect ();
d5b66e83 1089 /* Initialize assembler name hash, in particular we want to trigger C++
1090 mangling and same body alias creation before we free DECL_ARGUMENTS
1091 used by it. */
1092 if (!seen_error ())
35ee1c66 1093 symtab->symtab_initialize_asm_name_hash ();
fd9fde78 1094
1095 input_location = saved_loc;
aeeb194b 1096}
1097
3a849bc1 1098/* Translate the ugly representation of aliases as alias pairs into nice
1099 representation in callgraph. We don't handle all cases yet,
a3ddd82f 1100 unfortunately. */
3a849bc1 1101
1102static void
1103handle_alias_pairs (void)
1104{
1105 alias_pair *p;
1106 unsigned i;
3a849bc1 1107
f1f41a6c 1108 for (i = 0; alias_pairs && alias_pairs->iterate (i, &p);)
3a849bc1 1109 {
35ee1c66 1110 symtab_node *target_node = symtab_node::get_for_asmname (p->target);
48c84ee3 1111
a3ddd82f 1112 /* Weakrefs with target not defined in current unit are easy to handle:
1113 they behave just as external variables except we need to note the
1114 alias flag to later output the weakref pseudo op into asm file. */
1115 if (!target_node
1116 && lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL)
badeded8 1117 {
415d1b9a 1118 symtab_node *node = symtab_node::get (p->decl);
48669653 1119 if (node)
fc8456b4 1120 {
02774f2d 1121 node->alias_target = p->target;
1122 node->weakref = true;
1123 node->alias = true;
fc8456b4 1124 }
f1f41a6c 1125 alias_pairs->unordered_remove (i);
48c84ee3 1126 continue;
badeded8 1127 }
48c84ee3 1128 else if (!target_node)
3a849bc1 1129 {
48c84ee3 1130 error ("%q+D aliased to undefined symbol %qE", p->decl, p->target);
415d1b9a 1131 symtab_node *node = symtab_node::get (p->decl);
a3ddd82f 1132 if (node)
02774f2d 1133 node->alias = false;
f1f41a6c 1134 alias_pairs->unordered_remove (i);
48c84ee3 1135 continue;
1136 }
1137
02774f2d 1138 if (DECL_EXTERNAL (target_node->decl)
afea39ad 1139 /* We use local aliases for C++ thunks to force the tailcall
1140 to bind locally. This is a hack - to keep it working do
1141 the following (which is not strictly correct). */
e4b77b71 1142 && (TREE_CODE (target_node->decl) != FUNCTION_DECL
02774f2d 1143 || ! DECL_VIRTUAL_P (target_node->decl))
afea39ad 1144 && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)))
1145 {
1146 error ("%q+D aliased to external symbol %qE",
1147 p->decl, p->target);
1148 }
1149
48c84ee3 1150 if (TREE_CODE (p->decl) == FUNCTION_DECL
13cbeaac 1151 && target_node && is_a <cgraph_node *> (target_node))
48c84ee3 1152 {
35ee1c66 1153 cgraph_node *src_node = cgraph_node::get (p->decl);
02774f2d 1154 if (src_node && src_node->definition)
415d1b9a 1155 src_node->reset ();
1156 cgraph_node::create_alias (p->decl, target_node->decl);
f1f41a6c 1157 alias_pairs->unordered_remove (i);
48c84ee3 1158 }
1159 else if (TREE_CODE (p->decl) == VAR_DECL
13cbeaac 1160 && target_node && is_a <varpool_node *> (target_node))
48c84ee3 1161 {
97221fd7 1162 varpool_node::create_alias (p->decl, target_node->decl);
f1f41a6c 1163 alias_pairs->unordered_remove (i);
48c84ee3 1164 }
1165 else
1166 {
1167 error ("%q+D alias in between function and variable is not supported",
1168 p->decl);
1169 warning (0, "%q+D aliased declaration",
02774f2d 1170 target_node->decl);
f1f41a6c 1171 alias_pairs->unordered_remove (i);
3a849bc1 1172 }
1173 }
f1f41a6c 1174 vec_free (alias_pairs);
3a849bc1 1175}
1176
8f69fd82 1177
ae01b312 1178/* Figure out what functions we want to assemble. */
1179
1180static void
cf951b1a 1181mark_functions_to_output (void)
ae01b312 1182{
35ee1c66 1183 cgraph_node *node;
61c2c7b1 1184#ifdef ENABLE_CHECKING
1185 bool check_same_comdat_groups = false;
1186
7c455d87 1187 FOR_EACH_FUNCTION (node)
61c2c7b1 1188 gcc_assert (!node->process);
1189#endif
ae01b312 1190
7c455d87 1191 FOR_EACH_FUNCTION (node)
ae01b312 1192 {
02774f2d 1193 tree decl = node->decl;
a0c938f0 1194
02774f2d 1195 gcc_assert (!node->process || node->same_comdat_group);
61c2c7b1 1196 if (node->process)
1197 continue;
d7c6d889 1198
e6d2b2d8 1199 /* We need to output all local functions that are used and not
1200 always inlined, as well as those that are reachable from
1201 outside the current compilation unit. */
02774f2d 1202 if (node->analyzed
91bf9d9a 1203 && !node->thunk.thunk_p
02774f2d 1204 && !node->alias
b0cdf642 1205 && !node->global.inlined_to
4ee9c684 1206 && !TREE_ASM_WRITTEN (decl)
ae01b312 1207 && !DECL_EXTERNAL (decl))
61c2c7b1 1208 {
1209 node->process = 1;
02774f2d 1210 if (node->same_comdat_group)
61c2c7b1 1211 {
35ee1c66 1212 cgraph_node *next;
415d1b9a 1213 for (next = dyn_cast<cgraph_node *> (node->same_comdat_group);
61c2c7b1 1214 next != node;
415d1b9a 1215 next = dyn_cast<cgraph_node *> (next->same_comdat_group))
468088ac 1216 if (!next->thunk.thunk_p && !next->alias
415d1b9a 1217 && !next->comdat_local_p ())
91bf9d9a 1218 next->process = 1;
61c2c7b1 1219 }
1220 }
02774f2d 1221 else if (node->same_comdat_group)
61c2c7b1 1222 {
1223#ifdef ENABLE_CHECKING
1224 check_same_comdat_groups = true;
1225#endif
1226 }
cc636d56 1227 else
9cee7c3f 1228 {
1229 /* We should've reclaimed all functions that are not needed. */
1230#ifdef ENABLE_CHECKING
75a70cf9 1231 if (!node->global.inlined_to
1a1a827a 1232 && gimple_has_body_p (decl)
08843223 1233 /* FIXME: in ltrans unit when offline copy is outside partition but inline copies
1234 are inside partition, we can end up not removing the body since we no longer
1235 have analyzed node pointing to it. */
02774f2d 1236 && !node->in_other_partition
1237 && !node->alias
2d4bf241 1238 && !node->clones
9cee7c3f 1239 && !DECL_EXTERNAL (decl))
1240 {
415d1b9a 1241 node->debug ();
9cee7c3f 1242 internal_error ("failed to reclaim unneeded function");
1243 }
1244#endif
75a70cf9 1245 gcc_assert (node->global.inlined_to
1a1a827a 1246 || !gimple_has_body_p (decl)
02774f2d 1247 || node->in_other_partition
aa419a52 1248 || node->clones
1249 || DECL_ARTIFICIAL (decl)
9cee7c3f 1250 || DECL_EXTERNAL (decl));
1251
1252 }
a0c938f0 1253
961e3b13 1254 }
61c2c7b1 1255#ifdef ENABLE_CHECKING
1256 if (check_same_comdat_groups)
7c455d87 1257 FOR_EACH_FUNCTION (node)
02774f2d 1258 if (node->same_comdat_group && !node->process)
61c2c7b1 1259 {
02774f2d 1260 tree decl = node->decl;
61c2c7b1 1261 if (!node->global.inlined_to
1262 && gimple_has_body_p (decl)
6d36105a 1263 /* FIXME: in an ltrans unit when the offline copy is outside a
1264 partition but inline copies are inside a partition, we can
1265 end up not removing the body since we no longer have an
1266 analyzed node pointing to it. */
02774f2d 1267 && !node->in_other_partition
afea39ad 1268 && !node->clones
61c2c7b1 1269 && !DECL_EXTERNAL (decl))
1270 {
415d1b9a 1271 node->debug ();
6d36105a 1272 internal_error ("failed to reclaim unneeded function in same "
1273 "comdat group");
61c2c7b1 1274 }
1275 }
1276#endif
961e3b13 1277}
1278
28454517 1279/* DECL is FUNCTION_DECL. Initialize datastructures so DECL is a function
cc8ef84f 1280 in lowered gimple form. IN_SSA is true if the gimple is in SSA.
28454517 1281
1282 Set current_function_decl and cfun to newly constructed empty function body.
1283 return basic block in the function body. */
1284
cc8ef84f 1285basic_block
1286init_lowered_empty_function (tree decl, bool in_ssa)
28454517 1287{
1288 basic_block bb;
1289
1290 current_function_decl = decl;
1291 allocate_struct_function (decl, false);
1292 gimple_register_cfg_hooks ();
1293 init_empty_tree_cfg ();
cc8ef84f 1294
1295 if (in_ssa)
1296 {
1297 init_tree_ssa (cfun);
1298 init_ssa_operands (cfun);
1299 cfun->gimple_df->in_ssa_p = true;
7eacb0dd 1300 cfun->curr_properties |= PROP_ssa;
cc8ef84f 1301 }
1302
28454517 1303 DECL_INITIAL (decl) = make_node (BLOCK);
1304
1305 DECL_SAVED_TREE (decl) = error_mark_node;
7eacb0dd 1306 cfun->curr_properties |= (PROP_gimple_lcf | PROP_gimple_leh | PROP_gimple_any
1307 | PROP_cfg | PROP_loops);
1308
25a27413 1309 set_loops_for_fn (cfun, ggc_cleared_alloc<loops> ());
7eacb0dd 1310 init_loops_structure (cfun, loops_for_fn (cfun), 1);
1311 loops_for_fn (cfun)->state |= LOOPS_MAY_HAVE_MULTIPLE_LATCHES;
28454517 1312
1313 /* Create BB for body of the function and connect it properly. */
34154e27 1314 bb = create_basic_block (NULL, (void *) 0, ENTRY_BLOCK_PTR_FOR_FN (cfun));
1315 make_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun), bb, EDGE_FALLTHRU);
1316 make_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
1317 add_bb_to_loop (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun)->loop_father);
28454517 1318
1319 return bb;
1320}
1321
1322/* Adjust PTR by the constant FIXED_OFFSET, and by the vtable
1323 offset indicated by VIRTUAL_OFFSET, if that is
1324 non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and
1325 zero for a result adjusting thunk. */
1326
1327static tree
1328thunk_adjust (gimple_stmt_iterator * bsi,
1329 tree ptr, bool this_adjusting,
1330 HOST_WIDE_INT fixed_offset, tree virtual_offset)
1331{
1332 gimple stmt;
1333 tree ret;
1334
55d6cb23 1335 if (this_adjusting
1336 && fixed_offset != 0)
28454517 1337 {
2cc66f2a 1338 stmt = gimple_build_assign
1339 (ptr, fold_build_pointer_plus_hwi_loc (input_location,
1340 ptr,
1341 fixed_offset));
28454517 1342 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1343 }
1344
1345 /* If there's a virtual offset, look up that value in the vtable and
1346 adjust the pointer again. */
1347 if (virtual_offset)
1348 {
1349 tree vtabletmp;
1350 tree vtabletmp2;
1351 tree vtabletmp3;
28454517 1352
1353 if (!vtable_entry_type)
1354 {
1355 tree vfunc_type = make_node (FUNCTION_TYPE);
1356 TREE_TYPE (vfunc_type) = integer_type_node;
1357 TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
1358 layout_type (vfunc_type);
1359
1360 vtable_entry_type = build_pointer_type (vfunc_type);
1361 }
1362
1363 vtabletmp =
072f7ab1 1364 create_tmp_reg (build_pointer_type
37ffa8fe 1365 (build_pointer_type (vtable_entry_type)), "vptr");
28454517 1366
1367 /* The vptr is always at offset zero in the object. */
1368 stmt = gimple_build_assign (vtabletmp,
1369 build1 (NOP_EXPR, TREE_TYPE (vtabletmp),
1370 ptr));
1371 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
28454517 1372
1373 /* Form the vtable address. */
072f7ab1 1374 vtabletmp2 = create_tmp_reg (TREE_TYPE (TREE_TYPE (vtabletmp)),
37ffa8fe 1375 "vtableaddr");
28454517 1376 stmt = gimple_build_assign (vtabletmp2,
182cf5a9 1377 build_simple_mem_ref (vtabletmp));
28454517 1378 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
28454517 1379
1380 /* Find the entry with the vcall offset. */
1381 stmt = gimple_build_assign (vtabletmp2,
2cc66f2a 1382 fold_build_pointer_plus_loc (input_location,
1383 vtabletmp2,
1384 virtual_offset));
28454517 1385 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1386
1387 /* Get the offset itself. */
072f7ab1 1388 vtabletmp3 = create_tmp_reg (TREE_TYPE (TREE_TYPE (vtabletmp2)),
37ffa8fe 1389 "vcalloffset");
28454517 1390 stmt = gimple_build_assign (vtabletmp3,
182cf5a9 1391 build_simple_mem_ref (vtabletmp2));
28454517 1392 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
28454517 1393
28454517 1394 /* Adjust the `this' pointer. */
a0553bff 1395 ptr = fold_build_pointer_plus_loc (input_location, ptr, vtabletmp3);
1396 ptr = force_gimple_operand_gsi (bsi, ptr, true, NULL_TREE, false,
1397 GSI_CONTINUE_LINKING);
28454517 1398 }
1399
55d6cb23 1400 if (!this_adjusting
1401 && fixed_offset != 0)
28454517 1402 /* Adjust the pointer by the constant. */
1403 {
1404 tree ptrtmp;
1405
1406 if (TREE_CODE (ptr) == VAR_DECL)
1407 ptrtmp = ptr;
1408 else
1409 {
072f7ab1 1410 ptrtmp = create_tmp_reg (TREE_TYPE (ptr), "ptr");
28454517 1411 stmt = gimple_build_assign (ptrtmp, ptr);
1412 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
28454517 1413 }
2cc66f2a 1414 ptr = fold_build_pointer_plus_hwi_loc (input_location,
1415 ptrtmp, fixed_offset);
28454517 1416 }
1417
1418 /* Emit the statement and gimplify the adjustment expression. */
072f7ab1 1419 ret = create_tmp_reg (TREE_TYPE (ptr), "adjusted_this");
28454517 1420 stmt = gimple_build_assign (ret, ptr);
28454517 1421 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1422
1423 return ret;
1424}
1425
6e1aa353 1426/* Expand thunk NODE to gimple if possible.
46e5ad0c 1427 When FORCE_GIMPLE_THUNK is true, gimple thunk is created and
1428 no assembler is produced.
6e1aa353 1429 When OUTPUT_ASM_THUNK is true, also produce assembler for
1430 thunks that are not lowered. */
28454517 1431
6e1aa353 1432bool
415d1b9a 1433cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk)
28454517 1434{
415d1b9a 1435 bool this_adjusting = thunk.this_adjusting;
1436 HOST_WIDE_INT fixed_offset = thunk.fixed_offset;
1437 HOST_WIDE_INT virtual_value = thunk.virtual_value;
28454517 1438 tree virtual_offset = NULL;
415d1b9a 1439 tree alias = callees->callee->decl;
1440 tree thunk_fndecl = decl;
bb251465 1441 tree a;
1442
aed6e608 1443
46e5ad0c 1444 if (!force_gimple_thunk && this_adjusting
28454517 1445 && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
1446 virtual_value, alias))
1447 {
1448 const char *fnname;
1449 tree fn_block;
28b2c6a7 1450 tree restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
6e1aa353 1451
1452 if (!output_asm_thunks)
ae949f2f 1453 {
1454 analyzed = true;
1455 return false;
1456 }
6e1aa353 1457
1458 if (in_lto_p)
415d1b9a 1459 get_body ();
6e1aa353 1460 a = DECL_ARGUMENTS (thunk_fndecl);
28454517 1461
6e1aa353 1462 current_function_decl = thunk_fndecl;
1463
1464 /* Ensure thunks are emitted in their correct sections. */
1465 resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
1466
28454517 1467 DECL_RESULT (thunk_fndecl)
1468 = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl),
28b2c6a7 1469 RESULT_DECL, 0, restype);
6e1aa353 1470 DECL_CONTEXT (DECL_RESULT (thunk_fndecl)) = thunk_fndecl;
22ea3b47 1471 fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
28454517 1472
1473 /* The back end expects DECL_INITIAL to contain a BLOCK, so we
1474 create one. */
1475 fn_block = make_node (BLOCK);
1476 BLOCK_VARS (fn_block) = a;
1477 DECL_INITIAL (thunk_fndecl) = fn_block;
1478 init_function_start (thunk_fndecl);
1479 cfun->is_thunk = 1;
32c7c682 1480 insn_locations_init ();
1481 set_curr_insn_location (DECL_SOURCE_LOCATION (thunk_fndecl));
1482 prologue_location = curr_insn_location ();
28454517 1483 assemble_start_function (thunk_fndecl, fnname);
1484
1485 targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl,
1486 fixed_offset, virtual_value, alias);
1487
1488 assemble_end_function (thunk_fndecl, fnname);
32c7c682 1489 insn_locations_finalize ();
28454517 1490 init_insn_lengths ();
1491 free_after_compilation (cfun);
1492 set_cfun (NULL);
1493 TREE_ASM_WRITTEN (thunk_fndecl) = 1;
415d1b9a 1494 thunk.thunk_p = false;
1495 analyzed = false;
28454517 1496 }
1497 else
1498 {
1499 tree restype;
1500 basic_block bb, then_bb, else_bb, return_bb;
1501 gimple_stmt_iterator bsi;
1502 int nargs = 0;
1503 tree arg;
1504 int i;
1505 tree resdecl;
1506 tree restmp = NULL;
28454517 1507
1508 gimple call;
1509 gimple ret;
1510
6e1aa353 1511 if (in_lto_p)
415d1b9a 1512 get_body ();
6e1aa353 1513 a = DECL_ARGUMENTS (thunk_fndecl);
1514
1515 current_function_decl = thunk_fndecl;
1516
1517 /* Ensure thunks are emitted in their correct sections. */
1518 resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
1519
28454517 1520 DECL_IGNORED_P (thunk_fndecl) = 1;
1521 bitmap_obstack_initialize (NULL);
1522
415d1b9a 1523 if (thunk.virtual_offset_p)
28454517 1524 virtual_offset = size_int (virtual_value);
1525
1526 /* Build the return declaration for the function. */
1527 restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1528 if (DECL_RESULT (thunk_fndecl) == NULL_TREE)
1529 {
1530 resdecl = build_decl (input_location, RESULT_DECL, 0, restype);
1531 DECL_ARTIFICIAL (resdecl) = 1;
1532 DECL_IGNORED_P (resdecl) = 1;
1533 DECL_RESULT (thunk_fndecl) = resdecl;
6e1aa353 1534 DECL_CONTEXT (DECL_RESULT (thunk_fndecl)) = thunk_fndecl;
28454517 1535 }
1536 else
1537 resdecl = DECL_RESULT (thunk_fndecl);
1538
cc8ef84f 1539 bb = then_bb = else_bb = return_bb = init_lowered_empty_function (thunk_fndecl, true);
28454517 1540
1541 bsi = gsi_start_bb (bb);
1542
1543 /* Build call to the function being thunked. */
1544 if (!VOID_TYPE_P (restype))
1545 {
f2c6b33f 1546 if (DECL_BY_REFERENCE (resdecl))
1547 restmp = gimple_fold_indirect_ref (resdecl);
1548 else if (!is_gimple_reg_type (restype))
28454517 1549 {
1550 restmp = resdecl;
2ab2ce89 1551 add_local_decl (cfun, restmp);
28454517 1552 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp;
1553 }
1554 else
072f7ab1 1555 restmp = create_tmp_reg (restype, "retval");
28454517 1556 }
1557
1767a056 1558 for (arg = a; arg; arg = DECL_CHAIN (arg))
28454517 1559 nargs++;
c2078b80 1560 auto_vec<tree> vargs (nargs);
28454517 1561 if (this_adjusting)
f1f41a6c 1562 vargs.quick_push (thunk_adjust (&bsi, a, 1, fixed_offset,
1563 virtual_offset));
f2c6b33f 1564 else if (nargs)
f1f41a6c 1565 vargs.quick_push (a);
f2c6b33f 1566
1567 if (nargs)
1568 for (i = 1, arg = DECL_CHAIN (a); i < nargs; i++, arg = DECL_CHAIN (arg))
08a057fa 1569 {
1570 tree tmp = arg;
1571 if (!is_gimple_val (arg))
1572 {
1573 tmp = create_tmp_reg (TYPE_MAIN_VARIANT
1574 (TREE_TYPE (arg)), "arg");
1575 gimple stmt = gimple_build_assign (tmp, arg);
1576 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1577 }
1578 vargs.quick_push (tmp);
1579 }
28454517 1580 call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs);
415d1b9a 1581 callees->call_stmt = call;
28454517 1582 gimple_call_set_from_thunk (call, true);
1583 if (restmp)
f2c6b33f 1584 {
1585 gimple_call_set_lhs (call, restmp);
1586 gcc_assert (useless_type_conversion_p (TREE_TYPE (restmp),
1587 TREE_TYPE (TREE_TYPE (alias))));
1588 }
28454517 1589 gsi_insert_after (&bsi, call, GSI_NEW_STMT);
f2c6b33f 1590 if (!(gimple_call_flags (call) & ECF_NORETURN))
1591 {
1592 if (restmp && !this_adjusting
1593 && (fixed_offset || virtual_offset))
1594 {
1595 tree true_label = NULL_TREE;
28454517 1596
f2c6b33f 1597 if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE)
1598 {
1599 gimple stmt;
1600 /* If the return type is a pointer, we need to
1601 protect against NULL. We know there will be an
1602 adjustment, because that's why we're emitting a
1603 thunk. */
1604 then_bb = create_basic_block (NULL, (void *) 0, bb);
1605 return_bb = create_basic_block (NULL, (void *) 0, then_bb);
1606 else_bb = create_basic_block (NULL, (void *) 0, else_bb);
1607 add_bb_to_loop (then_bb, bb->loop_father);
1608 add_bb_to_loop (return_bb, bb->loop_father);
1609 add_bb_to_loop (else_bb, bb->loop_father);
1610 remove_edge (single_succ_edge (bb));
1611 true_label = gimple_block_label (then_bb);
1612 stmt = gimple_build_cond (NE_EXPR, restmp,
1613 build_zero_cst (TREE_TYPE (restmp)),
1614 NULL_TREE, NULL_TREE);
1615 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1616 make_edge (bb, then_bb, EDGE_TRUE_VALUE);
1617 make_edge (bb, else_bb, EDGE_FALSE_VALUE);
34154e27 1618 make_edge (return_bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
f2c6b33f 1619 make_edge (then_bb, return_bb, EDGE_FALLTHRU);
1620 make_edge (else_bb, return_bb, EDGE_FALLTHRU);
1621 bsi = gsi_last_bb (then_bb);
1622 }
28454517 1623
f2c6b33f 1624 restmp = thunk_adjust (&bsi, restmp, /*this_adjusting=*/0,
1625 fixed_offset, virtual_offset);
1626 if (true_label)
1627 {
1628 gimple stmt;
1629 bsi = gsi_last_bb (else_bb);
1630 stmt = gimple_build_assign (restmp,
1631 build_zero_cst (TREE_TYPE (restmp)));
1632 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1633 bsi = gsi_last_bb (return_bb);
1634 }
28454517 1635 }
f2c6b33f 1636 else
1637 gimple_call_set_tail (call, true);
28454517 1638
f2c6b33f 1639 /* Build return value. */
1640 ret = gimple_build_return (restmp);
1641 gsi_insert_after (&bsi, ret, GSI_NEW_STMT);
28454517 1642 }
1643 else
f2c6b33f 1644 {
1645 gimple_call_set_tail (call, true);
1646 remove_edge (single_succ_edge (bb));
1647 }
28454517 1648
6e1aa353 1649 cfun->gimple_df->in_ssa_p = true;
1650 /* FIXME: C++ FE should stop setting TREE_ASM_WRITTEN on thunks. */
1651 TREE_ASM_WRITTEN (thunk_fndecl) = false;
28454517 1652 delete_unreachable_blocks ();
1653 update_ssa (TODO_update_ssa);
f2c6b33f 1654#ifdef ENABLE_CHECKING
1655 verify_flow_info ();
1656#endif
ba4dc75f 1657 free_dominance_info (CDI_DOMINATORS);
28454517 1658
28454517 1659 /* Since we want to emit the thunk, we explicitly mark its name as
1660 referenced. */
415d1b9a 1661 thunk.thunk_p = false;
1662 lowered = true;
28454517 1663 bitmap_obstack_release (NULL);
1664 }
1665 current_function_decl = NULL;
9078126c 1666 set_cfun (NULL);
6e1aa353 1667 return true;
28454517 1668}
1669
35ee1c66 1670/* Assemble thunks and aliases associated to node. */
91bf9d9a 1671
35ee1c66 1672void
1673cgraph_node::assemble_thunks_and_aliases (void)
91bf9d9a 1674{
35ee1c66 1675 cgraph_edge *e;
1676 ipa_ref *ref;
c70f46b0 1677
35ee1c66 1678 for (e = callers; e;)
91bf9d9a 1679 if (e->caller->thunk.thunk_p)
1680 {
35ee1c66 1681 cgraph_node *thunk = e->caller;
91bf9d9a 1682
1683 e = e->next_caller;
415d1b9a 1684 thunk->expand_thunk (true, false);
35ee1c66 1685 thunk->assemble_thunks_and_aliases ();
91bf9d9a 1686 }
1687 else
1688 e = e->next_caller;
e4a2b488 1689
35ee1c66 1690 FOR_EACH_ALIAS (this, ref)
e4a2b488 1691 {
35ee1c66 1692 cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
1693 bool saved_written = TREE_ASM_WRITTEN (decl);
e4a2b488 1694
1695 /* Force assemble_alias to really output the alias this time instead
1696 of buffering it in same alias pairs. */
35ee1c66 1697 TREE_ASM_WRITTEN (decl) = 1;
e4a2b488 1698 do_assemble_alias (alias->decl,
35ee1c66 1699 DECL_ASSEMBLER_NAME (decl));
1700 alias->assemble_thunks_and_aliases ();
1701 TREE_ASM_WRITTEN (decl) = saved_written;
e4a2b488 1702 }
91bf9d9a 1703}
1704
35ee1c66 1705/* Expand function specified by node. */
941366fd 1706
35ee1c66 1707void
1708cgraph_node::expand (void)
941366fd 1709{
941366fd 1710 location_t saved_loc;
1711
da5e1e7c 1712 /* We ought to not compile any inline clones. */
35ee1c66 1713 gcc_assert (!global.inlined_to);
da5e1e7c 1714
1715 announce_function (decl);
35ee1c66 1716 process = 0;
1717 gcc_assert (lowered);
1718 get_body ();
da5e1e7c 1719
1720 /* Generate RTL for the body of DECL. */
1721
941366fd 1722 timevar_push (TV_REST_OF_COMPILATION);
1723
35ee1c66 1724 gcc_assert (symtab->global_info_ready);
941366fd 1725
1726 /* Initialize the default bitmap obstack. */
1727 bitmap_obstack_initialize (NULL);
1728
1729 /* Initialize the RTL code for the function. */
da5e1e7c 1730 current_function_decl = decl;
941366fd 1731 saved_loc = input_location;
da5e1e7c 1732 input_location = DECL_SOURCE_LOCATION (decl);
1733 init_function_start (decl);
941366fd 1734
1735 gimple_register_cfg_hooks ();
1736
1737 bitmap_obstack_initialize (&reg_obstack); /* FIXME, only at RTL generation*/
1738
1739 execute_all_ipa_transforms ();
1740
1741 /* Perform all tree transforms and optimizations. */
1742
1743 /* Signal the start of passes. */
1744 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START, NULL);
1745
3538ae0d 1746 execute_pass_list (cfun, g->get_passes ()->all_passes);
941366fd 1747
1748 /* Signal the end of passes. */
1749 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END, NULL);
1750
1751 bitmap_obstack_release (&reg_obstack);
1752
1753 /* Release the default bitmap obstack. */
1754 bitmap_obstack_release (NULL);
1755
941366fd 1756 /* If requested, warn about function definitions where the function will
1757 return a value (usually of some struct or union type) which itself will
1758 take up a lot of stack space. */
da5e1e7c 1759 if (warn_larger_than && !DECL_EXTERNAL (decl) && TREE_TYPE (decl))
941366fd 1760 {
da5e1e7c 1761 tree ret_type = TREE_TYPE (TREE_TYPE (decl));
941366fd 1762
1763 if (ret_type && TYPE_SIZE_UNIT (ret_type)
1764 && TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST
1765 && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type),
1766 larger_than_size))
1767 {
1768 unsigned int size_as_int
1769 = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type));
1770
1771 if (compare_tree_int (TYPE_SIZE_UNIT (ret_type), size_as_int) == 0)
1772 warning (OPT_Wlarger_than_, "size of return value of %q+D is %u bytes",
da5e1e7c 1773 decl, size_as_int);
941366fd 1774 else
1775 warning (OPT_Wlarger_than_, "size of return value of %q+D is larger than %wd bytes",
da5e1e7c 1776 decl, larger_than_size);
941366fd 1777 }
1778 }
1779
da5e1e7c 1780 gimple_set_body (decl, NULL);
1781 if (DECL_STRUCT_FUNCTION (decl) == 0
415d1b9a 1782 && !cgraph_node::get (decl)->origin)
941366fd 1783 {
1784 /* Stop pointing to the local nodes about to be freed.
1785 But DECL_INITIAL must remain nonzero so we know this
1786 was an actual function definition.
1787 For a nested function, this is done in c_pop_function_context.
1788 If rest_of_compilation set this to 0, leave it 0. */
da5e1e7c 1789 if (DECL_INITIAL (decl) != 0)
1790 DECL_INITIAL (decl) = error_mark_node;
941366fd 1791 }
1792
1793 input_location = saved_loc;
1794
1795 ggc_collect ();
1796 timevar_pop (TV_REST_OF_COMPILATION);
f7777314 1797
1798 /* Make sure that BE didn't give up on compiling. */
1799 gcc_assert (TREE_ASM_WRITTEN (decl));
9078126c 1800 set_cfun (NULL);
f7777314 1801 current_function_decl = NULL;
f76f7453 1802
1803 /* It would make a lot more sense to output thunks before function body to get more
cf951b1a 1804 forward and lest backwarding jumps. This however would need solving problem
f76f7453 1805 with comdats. See PR48668. Also aliases must come after function itself to
cf951b1a 1806 make one pass assemblers, like one on AIX, happy. See PR 50689.
f76f7453 1807 FIXME: Perhaps thunks should be move before function IFF they are not in comdat
1808 groups. */
35ee1c66 1809 assemble_thunks_and_aliases ();
1810 release_body ();
1a1a827a 1811 /* Eliminate all call edges. This is important so the GIMPLE_CALL no longer
1812 points to the dead function body. */
35ee1c66 1813 remove_callees ();
1814 remove_all_references ();
ae01b312 1815}
1816
af48f0b1 1817/* Node comparer that is responsible for the order that corresponds
1818 to time when a function was launched for the first time. */
1819
1820static int
1821node_cmp (const void *pa, const void *pb)
1822{
35ee1c66 1823 const cgraph_node *a = *(const cgraph_node * const *) pa;
1824 const cgraph_node *b = *(const cgraph_node * const *) pb;
af48f0b1 1825
1826 /* Functions with time profile must be before these without profile. */
1827 if (!a->tp_first_run || !b->tp_first_run)
1828 return a->tp_first_run - b->tp_first_run;
1829
1830 return a->tp_first_run != b->tp_first_run
1831 ? b->tp_first_run - a->tp_first_run
1832 : b->order - a->order;
1833}
acc70efa 1834
d9d9733a 1835/* Expand all functions that must be output.
1836
d7c6d889 1837 Attempt to topologically sort the nodes so function is output when
1838 all called functions are already assembled to allow data to be
91c82c20 1839 propagated across the callgraph. Use a stack to get smaller distance
3927afe0 1840 between a function and its callees (later we may choose to use a more
d7c6d889 1841 sophisticated algorithm for function reordering; we will likely want
1842 to use subsections to make the output functions appear in top-down
1843 order). */
1844
1845static void
cf951b1a 1846expand_all_functions (void)
d7c6d889 1847{
35ee1c66 1848 cgraph_node *node;
1849 cgraph_node **order = XCNEWVEC (cgraph_node *,
1850 symtab->cgraph_count);
af48f0b1 1851 unsigned int expanded_func_count = 0, profiled_func_count = 0;
c04e3894 1852 int order_pos, new_order_pos = 0;
d7c6d889 1853 int i;
1854
7771d558 1855 order_pos = ipa_reverse_postorder (order);
35ee1c66 1856 gcc_assert (order_pos == symtab->cgraph_count);
d7c6d889 1857
7bd28bba 1858 /* Garbage collector may remove inline clones we eliminate during
b0cdf642 1859 optimization. So we must be sure to not reference them. */
1860 for (i = 0; i < order_pos; i++)
09fc9532 1861 if (order[i]->process)
b0cdf642 1862 order[new_order_pos++] = order[i];
1863
af48f0b1 1864 if (flag_profile_reorder_functions)
35ee1c66 1865 qsort (order, new_order_pos, sizeof (cgraph_node *), node_cmp);
af48f0b1 1866
b0cdf642 1867 for (i = new_order_pos - 1; i >= 0; i--)
d7c6d889 1868 {
1869 node = order[i];
af48f0b1 1870
09fc9532 1871 if (node->process)
d7c6d889 1872 {
af48f0b1 1873 expanded_func_count++;
1874 if(node->tp_first_run)
1875 profiled_func_count++;
1876
35ee1c66 1877 if (symtab->dump_file)
1878 fprintf (symtab->dump_file,
1879 "Time profile order in expand_all_functions:%s:%d\n",
1880 node->asm_name (), node->tp_first_run);
09fc9532 1881 node->process = 0;
35ee1c66 1882 node->expand ();
d7c6d889 1883 }
1884 }
af48f0b1 1885
1886 if (dump_file)
1887 fprintf (dump_file, "Expanded functions with time profile (%s):%u/%u\n",
1888 main_input_filename, profiled_func_count, expanded_func_count);
1889
35ee1c66 1890 if (symtab->dump_file && flag_profile_reorder_functions)
1891 fprintf (symtab->dump_file, "Expanded functions with time profile:%u/%u\n",
af48f0b1 1892 profiled_func_count, expanded_func_count);
1893
35ee1c66 1894 symtab->process_new_functions ();
8a4a28a8 1895 free_gimplify_stack ();
773c5ba7 1896
d7c6d889 1897 free (order);
1898}
1899
56af936e 1900/* This is used to sort the node types by the cgraph order number. */
1901
0b09525f 1902enum cgraph_order_sort_kind
1903{
1904 ORDER_UNDEFINED = 0,
1905 ORDER_FUNCTION,
1906 ORDER_VAR,
1907 ORDER_ASM
1908};
1909
56af936e 1910struct cgraph_order_sort
1911{
0b09525f 1912 enum cgraph_order_sort_kind kind;
56af936e 1913 union
1914 {
35ee1c66 1915 cgraph_node *f;
098f44bc 1916 varpool_node *v;
35ee1c66 1917 asm_node *a;
56af936e 1918 } u;
1919};
1920
1921/* Output all functions, variables, and asm statements in the order
1922 according to their order fields, which is the order in which they
1923 appeared in the file. This implements -fno-toplevel-reorder. In
1924 this mode we may output functions and variables which don't really
1925 need to be output. */
1926
1927static void
cf951b1a 1928output_in_order (void)
56af936e 1929{
1930 int max;
35ee1c66 1931 cgraph_order_sort *nodes;
56af936e 1932 int i;
35ee1c66 1933 cgraph_node *pf;
098f44bc 1934 varpool_node *pv;
35ee1c66 1935 asm_node *pa;
1936 max = symtab->order;
1937 nodes = XCNEWVEC (cgraph_order_sort, max);
56af936e 1938
7c455d87 1939 FOR_EACH_DEFINED_FUNCTION (pf)
56af936e 1940 {
02774f2d 1941 if (pf->process && !pf->thunk.thunk_p && !pf->alias)
56af936e 1942 {
02774f2d 1943 i = pf->order;
56af936e 1944 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1945 nodes[i].kind = ORDER_FUNCTION;
1946 nodes[i].u.f = pf;
1947 }
1948 }
1949
7c455d87 1950 FOR_EACH_DEFINED_VARIABLE (pv)
02774f2d 1951 if (!DECL_EXTERNAL (pv->decl))
aa419a52 1952 {
02774f2d 1953 i = pv->order;
aa419a52 1954 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1955 nodes[i].kind = ORDER_VAR;
1956 nodes[i].u.v = pv;
1957 }
56af936e 1958
35ee1c66 1959 for (pa = symtab->first_asm_symbol (); pa; pa = pa->next)
56af936e 1960 {
1961 i = pa->order;
1962 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1963 nodes[i].kind = ORDER_ASM;
1964 nodes[i].u.a = pa;
1965 }
56af936e 1966
304e5318 1967 /* In toplevel reorder mode we output all statics; mark them as needed. */
304e5318 1968
91da0f1c 1969 for (i = 0; i < max; ++i)
1970 if (nodes[i].kind == ORDER_VAR)
97221fd7 1971 nodes[i].u.v->finalize_named_section_flags ();
91da0f1c 1972
56af936e 1973 for (i = 0; i < max; ++i)
1974 {
1975 switch (nodes[i].kind)
1976 {
1977 case ORDER_FUNCTION:
09fc9532 1978 nodes[i].u.f->process = 0;
35ee1c66 1979 nodes[i].u.f->expand ();
56af936e 1980 break;
1981
1982 case ORDER_VAR:
97221fd7 1983 nodes[i].u.v->assemble_decl ();
56af936e 1984 break;
1985
1986 case ORDER_ASM:
1987 assemble_asm (nodes[i].u.a->asm_str);
1988 break;
1989
1990 case ORDER_UNDEFINED:
1991 break;
1992
1993 default:
1994 gcc_unreachable ();
1995 }
1996 }
4b4ea2db 1997
35ee1c66 1998 symtab->clear_asm_symbols ();
1999
3e1cde87 2000 free (nodes);
56af936e 2001}
2002
77fce4cd 2003static void
2004ipa_passes (void)
2005{
3ea50c01 2006 gcc::pass_manager *passes = g->get_passes ();
2007
87d4aa85 2008 set_cfun (NULL);
4b14adf9 2009 current_function_decl = NULL;
75a70cf9 2010 gimple_register_cfg_hooks ();
77fce4cd 2011 bitmap_obstack_initialize (NULL);
59dd4830 2012
c9036234 2013 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START, NULL);
2014
59dd4830 2015 if (!in_lto_p)
7b2e8956 2016 {
3ea50c01 2017 execute_ipa_pass_list (passes->all_small_ipa_passes);
7b2e8956 2018 if (seen_error ())
2019 return;
2020 }
9ed5b1f5 2021
289c4db4 2022 /* This extra symtab_remove_unreachable_nodes pass tends to catch some
2023 devirtualization and other changes where removal iterate. */
35ee1c66 2024 symtab->remove_unreachable_nodes (true, symtab->dump_file);
941125aa 2025
7bfefa9d 2026 /* If pass_all_early_optimizations was not scheduled, the state of
2027 the cgraph will not be properly updated. Update it now. */
35ee1c66 2028 if (symtab->state < IPA_SSA)
2029 symtab->state = IPA_SSA;
9ed5b1f5 2030
7bfefa9d 2031 if (!in_lto_p)
2032 {
2033 /* Generate coverage variables and constructors. */
2034 coverage_finish ();
2035
2036 /* Process new functions added. */
2037 set_cfun (NULL);
2038 current_function_decl = NULL;
35ee1c66 2039 symtab->process_new_functions ();
7bfefa9d 2040
c9036234 2041 execute_ipa_summary_passes
b23e5d49 2042 ((ipa_opt_pass_d *) passes->all_regular_ipa_passes);
8867b500 2043 }
23433d72 2044
2045 /* Some targets need to handle LTO assembler output specially. */
2046 if (flag_generate_lto)
2047 targetm.asm_out.lto_start ();
2048
7bfefa9d 2049 if (!in_lto_p)
2050 ipa_write_summaries ();
2051
23433d72 2052 if (flag_generate_lto)
2053 targetm.asm_out.lto_end ();
2054
b33542ab 2055 if (!flag_ltrans && (in_lto_p || !flag_lto || flag_fat_lto_objects))
3ea50c01 2056 execute_ipa_pass_list (passes->all_regular_ipa_passes);
c9036234 2057 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END, NULL);
9ed5b1f5 2058
77fce4cd 2059 bitmap_obstack_release (NULL);
2060}
2061
badeded8 2062
2063/* Return string alias is alias of. */
2064
2065static tree
2066get_alias_symbol (tree decl)
2067{
2068 tree alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
2069 return get_identifier (TREE_STRING_POINTER
2070 (TREE_VALUE (TREE_VALUE (alias))));
2071}
2072
2073
5e712541 2074/* Weakrefs may be associated to external decls and thus not output
9d75589a 2075 at expansion time. Emit all necessary aliases. */
5e712541 2076
35ee1c66 2077void
2078symbol_table::output_weakrefs (void)
5e712541 2079{
452659af 2080 symtab_node *node;
48669653 2081 FOR_EACH_SYMBOL (node)
02774f2d 2082 if (node->alias
2083 && !TREE_ASM_WRITTEN (node->decl)
2084 && node->weakref)
48669653 2085 {
2086 tree target;
2087
2088 /* Weakrefs are special by not requiring target definition in current
2089 compilation unit. It is thus bit hard to work out what we want to
2090 alias.
2091 When alias target is defined, we need to fetch it from symtab reference,
2092 otherwise it is pointed to by alias_target. */
02774f2d 2093 if (node->alias_target)
2094 target = (DECL_P (node->alias_target)
2095 ? DECL_ASSEMBLER_NAME (node->alias_target)
2096 : node->alias_target);
2097 else if (node->analyzed)
415d1b9a 2098 target = DECL_ASSEMBLER_NAME (node->get_alias_target ()->decl);
48669653 2099 else
2100 {
2101 gcc_unreachable ();
02774f2d 2102 target = get_alias_symbol (node->decl);
48669653 2103 }
02774f2d 2104 do_assemble_alias (node->decl, target);
48669653 2105 }
5e712541 2106}
2107
d2bb3f9d 2108/* Perform simple optimizations based on callgraph. */
2109
2110void
35ee1c66 2111symbol_table::compile (void)
d2bb3f9d 2112{
2113 if (seen_error ())
2114 return;
2115
2116#ifdef ENABLE_CHECKING
415d1b9a 2117 symtab_node::verify_symtab_nodes ();
d2bb3f9d 2118#endif
2119
d2bb3f9d 2120 timevar_push (TV_CGRAPHOPT);
2121 if (pre_ipa_mem_report)
2122 {
2123 fprintf (stderr, "Memory consumption before IPA\n");
2124 dump_memory_report (false);
2125 }
2126 if (!quiet_flag)
2127 fprintf (stderr, "Performing interprocedural optimizations\n");
35ee1c66 2128 state = IPA;
d2bb3f9d 2129
cf951b1a 2130 /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE. */
2131 if (flag_lto)
2132 lto_streamer_hooks_init ();
2133
d2bb3f9d 2134 /* Don't run the IPA passes if there was any error or sorry messages. */
2135 if (!seen_error ())
2136 ipa_passes ();
2137
2138 /* Do nothing else if any IPA pass found errors or if we are just streaming LTO. */
2139 if (seen_error ()
2140 || (!in_lto_p && flag_lto && !flag_fat_lto_objects))
2141 {
2142 timevar_pop (TV_CGRAPHOPT);
2143 return;
2144 }
2145
2146 /* This pass remove bodies of extern inline functions we never inlined.
289c4db4 2147 Do this later so other IPA passes see what is really going on.
2148 FIXME: This should be run just after inlining by pasmanager. */
35ee1c66 2149 remove_unreachable_nodes (false, dump_file);
2150 global_info_ready = true;
2151 if (dump_file)
d2bb3f9d 2152 {
35ee1c66 2153 fprintf (dump_file, "Optimized ");
2154 symtab_node:: dump_table (dump_file);
d2bb3f9d 2155 }
2156 if (post_ipa_mem_report)
2157 {
2158 fprintf (stderr, "Memory consumption after IPA\n");
2159 dump_memory_report (false);
2160 }
2161 timevar_pop (TV_CGRAPHOPT);
2162
2163 /* Output everything. */
2164 (*debug_hooks->assembly_start) ();
2165 if (!quiet_flag)
2166 fprintf (stderr, "Assembling functions:\n");
2167#ifdef ENABLE_CHECKING
415d1b9a 2168 symtab_node::verify_symtab_nodes ();
d2bb3f9d 2169#endif
2170
35ee1c66 2171 materialize_all_clones ();
d2bb3f9d 2172 bitmap_obstack_initialize (NULL);
3ea50c01 2173 execute_ipa_pass_list (g->get_passes ()->all_late_ipa_passes);
d2bb3f9d 2174 bitmap_obstack_release (NULL);
cf951b1a 2175 mark_functions_to_output ();
d2bb3f9d 2176
4cd8ae4b 2177 /* When weakref support is missing, we autmatically translate all
2178 references to NODE to references to its ultimate alias target.
2179 The renaming mechanizm uses flag IDENTIFIER_TRANSPARENT_ALIAS and
2180 TREE_CHAIN.
2181
2182 Set up this mapping before we output any assembler but once we are sure
2183 that all symbol renaming is done.
2184
2185 FIXME: All this uglyness can go away if we just do renaming at gimple
2186 level by physically rewritting the IL. At the moment we can only redirect
2187 calls, so we need infrastructure for renaming references as well. */
2188#ifndef ASM_OUTPUT_WEAKREF
452659af 2189 symtab_node *node;
4cd8ae4b 2190
2191 FOR_EACH_SYMBOL (node)
02774f2d 2192 if (node->alias
2193 && lookup_attribute ("weakref", DECL_ATTRIBUTES (node->decl)))
4cd8ae4b 2194 {
2195 IDENTIFIER_TRANSPARENT_ALIAS
02774f2d 2196 (DECL_ASSEMBLER_NAME (node->decl)) = 1;
2197 TREE_CHAIN (DECL_ASSEMBLER_NAME (node->decl))
2198 = (node->alias_target ? node->alias_target
448d76c7 2199 : DECL_ASSEMBLER_NAME (node->get_alias_target ()->decl));
4cd8ae4b 2200 }
2201#endif
2202
35ee1c66 2203 state = EXPANSION;
af48f0b1 2204
d2bb3f9d 2205 if (!flag_toplevel_reorder)
cf951b1a 2206 output_in_order ();
d2bb3f9d 2207 else
2208 {
cf951b1a 2209 output_asm_statements ();
d2bb3f9d 2210
cf951b1a 2211 expand_all_functions ();
35ee1c66 2212 output_variables ();
d2bb3f9d 2213 }
2214
35ee1c66 2215 process_new_functions ();
2216 state = FINISHED;
afea39ad 2217 output_weakrefs ();
d2bb3f9d 2218
35ee1c66 2219 if (dump_file)
d2bb3f9d 2220 {
35ee1c66 2221 fprintf (dump_file, "\nFinal ");
2222 symtab_node::dump_table (dump_file);
d2bb3f9d 2223 }
2224#ifdef ENABLE_CHECKING
415d1b9a 2225 symtab_node::verify_symtab_nodes ();
d2bb3f9d 2226 /* Double check that all inline clones are gone and that all
2227 function bodies have been released from memory. */
2228 if (!seen_error ())
2229 {
35ee1c66 2230 cgraph_node *node;
d2bb3f9d 2231 bool error_found = false;
2232
7c455d87 2233 FOR_EACH_DEFINED_FUNCTION (node)
2234 if (node->global.inlined_to
02774f2d 2235 || gimple_has_body_p (node->decl))
d2bb3f9d 2236 {
2237 error_found = true;
415d1b9a 2238 node->debug ();
d2bb3f9d 2239 }
2240 if (error_found)
2241 internal_error ("nodes with unreleased memory found");
2242 }
2243#endif
2244}
2245
2246
2247/* Analyze the whole compilation unit once it is parsed completely. */
2248
2249void
35ee1c66 2250symbol_table::finalize_compilation_unit (void)
d2bb3f9d 2251{
2252 timevar_push (TV_CGRAPH);
2253
d2bb3f9d 2254 /* If we're here there's no current function anymore. Some frontends
2255 are lazy in clearing these. */
2256 current_function_decl = NULL;
2257 set_cfun (NULL);
2258
2259 /* Do not skip analyzing the functions if there were errors, we
2260 miss diagnostics for following functions otherwise. */
2261
2262 /* Emit size functions we didn't inline. */
2263 finalize_size_functions ();
2264
2265 /* Mark alias targets necessary and emit diagnostics. */
d2bb3f9d 2266 handle_alias_pairs ();
2267
2268 if (!quiet_flag)
2269 {
2270 fprintf (stderr, "\nAnalyzing compilation unit\n");
2271 fflush (stderr);
2272 }
2273
2274 if (flag_dump_passes)
2275 dump_passes ();
2276
2277 /* Gimplify and lower all functions, compute reachability and
2278 remove unreachable nodes. */
15ca8f90 2279 analyze_functions ();
d2bb3f9d 2280
2281 /* Mark alias targets necessary and emit diagnostics. */
d2bb3f9d 2282 handle_alias_pairs ();
2283
2284 /* Gimplify and lower thunks. */
15ca8f90 2285 analyze_functions ();
d2bb3f9d 2286
2287 /* Finally drive the pass manager. */
cf951b1a 2288 compile ();
d2bb3f9d 2289
2290 timevar_pop (TV_CGRAPH);
2291}
2292
415d1b9a 2293/* Creates a wrapper from cgraph_node to TARGET node. Thunk is used for this
cb8994e9 2294 kind of wrapper method. */
2295
2296void
35ee1c66 2297cgraph_node::create_wrapper (cgraph_node *target)
cb8994e9 2298{
2299 /* Preserve DECL_RESULT so we get right by reference flag. */
415d1b9a 2300 tree decl_result = DECL_RESULT (decl);
cb8994e9 2301
2302 /* Remove the function's body. */
415d1b9a 2303 release_body ();
2304 reset ();
cb8994e9 2305
415d1b9a 2306 DECL_RESULT (decl) = decl_result;
2307 DECL_INITIAL (decl) = NULL;
2308 allocate_struct_function (decl, false);
cb8994e9 2309 set_cfun (NULL);
2310
2311 /* Turn alias into thunk and expand it into GIMPLE representation. */
415d1b9a 2312 definition = true;
2313 thunk.thunk_p = true;
2314 thunk.this_adjusting = false;
cb8994e9 2315
35ee1c66 2316 cgraph_edge *e = create_edge (target, NULL, 0, CGRAPH_FREQ_BASE);
cb8994e9 2317
ae949f2f 2318 expand_thunk (false, true);
cb8994e9 2319 e->call_stmt_cannot_inline_p = true;
2320
2321 /* Inline summary set-up. */
415d1b9a 2322 analyze ();
2323 inline_analyze_function (this);
cb8994e9 2324}
d2bb3f9d 2325
a861fe52 2326#include "gt-cgraphunit.h"