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