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