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