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