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