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