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