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