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