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