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