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