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