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