]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/cgraphunit.c
tree-flow.h (mark_symbols_for_renaming): Remove.
[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
822 gcc_assert (TREE_STATIC (decl));
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;
1033 struct cgraph_node *target_node;
1034 struct cgraph_node *src_node;
cd35bcf7 1035 struct varpool_node *target_vnode;
85ce9375
JH
1036
1037 for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p);)
1038 {
1039 if (TREE_CODE (p->decl) == FUNCTION_DECL
85ce9375
JH
1040 && (target_node = cgraph_node_for_asm (p->target)) != NULL)
1041 {
1042 src_node = cgraph_get_node (p->decl);
1043 if (src_node && src_node->local.finalized)
1044 cgraph_reset_node (src_node);
1045 /* Normally EXTERNAL flag is used to mark external inlines,
1046 however for aliases it seems to be allowed to use it w/o
1047 any meaning. See gcc.dg/attr-alias-3.c
1048 However for weakref we insist on EXTERNAL flag being set.
1049 See gcc.dg/attr-alias-5.c */
1050 if (DECL_EXTERNAL (p->decl))
960bfb69
JH
1051 DECL_EXTERNAL (p->decl)
1052 = lookup_attribute ("weakref",
1053 DECL_ATTRIBUTES (p->decl)) != NULL;
1054 cgraph_create_function_alias (p->decl, target_node->symbol.decl);
85ce9375
JH
1055 VEC_unordered_remove (alias_pair, alias_pairs, i);
1056 }
cd35bcf7 1057 else if (TREE_CODE (p->decl) == VAR_DECL
cd35bcf7
JH
1058 && (target_vnode = varpool_node_for_asm (p->target)) != NULL)
1059 {
1060 /* Normally EXTERNAL flag is used to mark external inlines,
1061 however for aliases it seems to be allowed to use it w/o
1062 any meaning. See gcc.dg/attr-alias-3.c
1063 However for weakref we insist on EXTERNAL flag being set.
1064 See gcc.dg/attr-alias-5.c */
1065 if (DECL_EXTERNAL (p->decl))
960bfb69
JH
1066 DECL_EXTERNAL (p->decl)
1067 = lookup_attribute ("weakref",
1068 DECL_ATTRIBUTES (p->decl)) != NULL;
1069 varpool_create_variable_alias (p->decl, target_vnode->symbol.decl);
cd35bcf7
JH
1070 VEC_unordered_remove (alias_pair, alias_pairs, i);
1071 }
25e2c40d
JH
1072 /* Weakrefs with target not defined in current unit are easy to handle; they
1073 behave just as external variables except we need to note the alias flag
1074 to later output the weakref pseudo op into asm file. */
1075 else if (lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL
1076 && (TREE_CODE (p->decl) == FUNCTION_DECL
1077 ? (varpool_node_for_asm (p->target) == NULL)
1078 : (cgraph_node_for_asm (p->target) == NULL)))
1079 {
1080 if (TREE_CODE (p->decl) == FUNCTION_DECL)
1081 cgraph_get_create_node (p->decl)->alias = true;
1082 else
1083 varpool_get_node (p->decl)->alias = true;
1084 DECL_EXTERNAL (p->decl) = 1;
1085 VEC_unordered_remove (alias_pair, alias_pairs, i);
1086 }
85ce9375
JH
1087 else
1088 {
1089 if (dump_file)
1090 fprintf (dump_file, "Unhandled alias %s->%s\n",
1091 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (p->decl)),
1092 IDENTIFIER_POINTER (p->target));
1093
1094 i++;
1095 }
1096 }
1097}
1098
5f1a9ebb 1099
1c4a429a
JH
1100/* Figure out what functions we want to assemble. */
1101
1102static void
65d630d4 1103mark_functions_to_output (void)
1c4a429a
JH
1104{
1105 struct cgraph_node *node;
b66887e4
JJ
1106#ifdef ENABLE_CHECKING
1107 bool check_same_comdat_groups = false;
1108
65c70e6b 1109 FOR_EACH_FUNCTION (node)
b66887e4
JJ
1110 gcc_assert (!node->process);
1111#endif
1c4a429a 1112
65c70e6b 1113 FOR_EACH_FUNCTION (node)
1c4a429a 1114 {
960bfb69 1115 tree decl = node->symbol.decl;
c22cacf3 1116
960bfb69 1117 gcc_assert (!node->process || node->symbol.same_comdat_group);
b66887e4
JJ
1118 if (node->process)
1119 continue;
b58b1157 1120
7660e67e
SB
1121 /* We need to output all local functions that are used and not
1122 always inlined, as well as those that are reachable from
1123 outside the current compilation unit. */
39ecc018 1124 if (node->analyzed
c47d0034 1125 && !node->thunk.thunk_p
39e2db00 1126 && !node->alias
18c6ada9 1127 && !node->global.inlined_to
6de9cd9a 1128 && !TREE_ASM_WRITTEN (decl)
1c4a429a 1129 && !DECL_EXTERNAL (decl))
b66887e4
JJ
1130 {
1131 node->process = 1;
960bfb69 1132 if (node->symbol.same_comdat_group)
b66887e4
JJ
1133 {
1134 struct cgraph_node *next;
960bfb69 1135 for (next = cgraph (node->symbol.same_comdat_group);
b66887e4 1136 next != node;
960bfb69 1137 next = cgraph (next->symbol.same_comdat_group))
39e2db00 1138 if (!next->thunk.thunk_p && !next->alias)
c47d0034 1139 next->process = 1;
b66887e4
JJ
1140 }
1141 }
960bfb69 1142 else if (node->symbol.same_comdat_group)
b66887e4
JJ
1143 {
1144#ifdef ENABLE_CHECKING
1145 check_same_comdat_groups = true;
1146#endif
1147 }
341c100f 1148 else
1a2caa7a
NS
1149 {
1150 /* We should've reclaimed all functions that are not needed. */
1151#ifdef ENABLE_CHECKING
726a989a 1152 if (!node->global.inlined_to
39ecc018 1153 && gimple_has_body_p (decl)
a837268b
JH
1154 /* FIXME: in ltrans unit when offline copy is outside partition but inline copies
1155 are inside partition, we can end up not removing the body since we no longer
1156 have analyzed node pointing to it. */
960bfb69 1157 && !node->symbol.in_other_partition
39e2db00 1158 && !node->alias
1a2caa7a
NS
1159 && !DECL_EXTERNAL (decl))
1160 {
1161 dump_cgraph_node (stderr, node);
1162 internal_error ("failed to reclaim unneeded function");
1163 }
1164#endif
726a989a 1165 gcc_assert (node->global.inlined_to
39ecc018 1166 || !gimple_has_body_p (decl)
960bfb69 1167 || node->symbol.in_other_partition
6649df51
JH
1168 || node->clones
1169 || DECL_ARTIFICIAL (decl)
1a2caa7a
NS
1170 || DECL_EXTERNAL (decl));
1171
1172 }
c22cacf3 1173
18d13f34 1174 }
b66887e4
JJ
1175#ifdef ENABLE_CHECKING
1176 if (check_same_comdat_groups)
65c70e6b 1177 FOR_EACH_FUNCTION (node)
960bfb69 1178 if (node->symbol.same_comdat_group && !node->process)
b66887e4 1179 {
960bfb69 1180 tree decl = node->symbol.decl;
b66887e4
JJ
1181 if (!node->global.inlined_to
1182 && gimple_has_body_p (decl)
7cbf224d
RG
1183 /* FIXME: in an ltrans unit when the offline copy is outside a
1184 partition but inline copies are inside a partition, we can
1185 end up not removing the body since we no longer have an
1186 analyzed node pointing to it. */
960bfb69 1187 && !node->symbol.in_other_partition
b66887e4
JJ
1188 && !DECL_EXTERNAL (decl))
1189 {
1190 dump_cgraph_node (stderr, node);
7cbf224d
RG
1191 internal_error ("failed to reclaim unneeded function in same "
1192 "comdat group");
b66887e4
JJ
1193 }
1194 }
1195#endif
18d13f34
JH
1196}
1197
6744a6ab
JH
1198/* DECL is FUNCTION_DECL. Initialize datastructures so DECL is a function
1199 in lowered gimple form.
1200
1201 Set current_function_decl and cfun to newly constructed empty function body.
1202 return basic block in the function body. */
1203
1204static basic_block
1205init_lowered_empty_function (tree decl)
1206{
1207 basic_block bb;
1208
1209 current_function_decl = decl;
1210 allocate_struct_function (decl, false);
1211 gimple_register_cfg_hooks ();
1212 init_empty_tree_cfg ();
1213 init_tree_ssa (cfun);
1214 init_ssa_operands ();
1215 cfun->gimple_df->in_ssa_p = true;
1216 DECL_INITIAL (decl) = make_node (BLOCK);
1217
1218 DECL_SAVED_TREE (decl) = error_mark_node;
1219 cfun->curr_properties |=
1220 (PROP_gimple_lcf | PROP_gimple_leh | PROP_cfg | PROP_referenced_vars |
febb1302 1221 PROP_ssa | PROP_gimple_any);
6744a6ab
JH
1222
1223 /* Create BB for body of the function and connect it properly. */
1224 bb = create_basic_block (NULL, (void *) 0, ENTRY_BLOCK_PTR);
4f9c574a
DV
1225 make_edge (ENTRY_BLOCK_PTR, bb, 0);
1226 make_edge (bb, EXIT_BLOCK_PTR, 0);
6744a6ab
JH
1227
1228 return bb;
1229}
1230
1231/* Adjust PTR by the constant FIXED_OFFSET, and by the vtable
1232 offset indicated by VIRTUAL_OFFSET, if that is
1233 non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and
1234 zero for a result adjusting thunk. */
1235
1236static tree
1237thunk_adjust (gimple_stmt_iterator * bsi,
1238 tree ptr, bool this_adjusting,
1239 HOST_WIDE_INT fixed_offset, tree virtual_offset)
1240{
1241 gimple stmt;
1242 tree ret;
1243
313333a6
RG
1244 if (this_adjusting
1245 && fixed_offset != 0)
6744a6ab 1246 {
5d49b6a7
RG
1247 stmt = gimple_build_assign
1248 (ptr, fold_build_pointer_plus_hwi_loc (input_location,
1249 ptr,
1250 fixed_offset));
6744a6ab
JH
1251 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1252 }
1253
1254 /* If there's a virtual offset, look up that value in the vtable and
1255 adjust the pointer again. */
1256 if (virtual_offset)
1257 {
1258 tree vtabletmp;
1259 tree vtabletmp2;
1260 tree vtabletmp3;
6744a6ab
JH
1261
1262 if (!vtable_entry_type)
1263 {
1264 tree vfunc_type = make_node (FUNCTION_TYPE);
1265 TREE_TYPE (vfunc_type) = integer_type_node;
1266 TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
1267 layout_type (vfunc_type);
1268
1269 vtable_entry_type = build_pointer_type (vfunc_type);
1270 }
1271
1272 vtabletmp =
7d80ca1f
RG
1273 make_rename_temp (build_pointer_type
1274 (build_pointer_type (vtable_entry_type)), "vptr");
6744a6ab
JH
1275
1276 /* The vptr is always at offset zero in the object. */
1277 stmt = gimple_build_assign (vtabletmp,
1278 build1 (NOP_EXPR, TREE_TYPE (vtabletmp),
1279 ptr));
1280 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
6744a6ab
JH
1281
1282 /* Form the vtable address. */
7d80ca1f
RG
1283 vtabletmp2 = make_rename_temp (TREE_TYPE (TREE_TYPE (vtabletmp)),
1284 "vtableaddr");
6744a6ab 1285 stmt = gimple_build_assign (vtabletmp2,
70f34814 1286 build_simple_mem_ref (vtabletmp));
6744a6ab 1287 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
6744a6ab
JH
1288
1289 /* Find the entry with the vcall offset. */
1290 stmt = gimple_build_assign (vtabletmp2,
5d49b6a7
RG
1291 fold_build_pointer_plus_loc (input_location,
1292 vtabletmp2,
1293 virtual_offset));
6744a6ab
JH
1294 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1295
1296 /* Get the offset itself. */
7d80ca1f
RG
1297 vtabletmp3 = make_rename_temp (TREE_TYPE (TREE_TYPE (vtabletmp2)),
1298 "vcalloffset");
6744a6ab 1299 stmt = gimple_build_assign (vtabletmp3,
70f34814 1300 build_simple_mem_ref (vtabletmp2));
6744a6ab 1301 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
6744a6ab 1302
6744a6ab 1303 /* Adjust the `this' pointer. */
0d82a1c8
RG
1304 ptr = fold_build_pointer_plus_loc (input_location, ptr, vtabletmp3);
1305 ptr = force_gimple_operand_gsi (bsi, ptr, true, NULL_TREE, false,
1306 GSI_CONTINUE_LINKING);
6744a6ab
JH
1307 }
1308
313333a6
RG
1309 if (!this_adjusting
1310 && fixed_offset != 0)
6744a6ab
JH
1311 /* Adjust the pointer by the constant. */
1312 {
1313 tree ptrtmp;
1314
1315 if (TREE_CODE (ptr) == VAR_DECL)
1316 ptrtmp = ptr;
1317 else
1318 {
7d80ca1f 1319 ptrtmp = make_rename_temp (TREE_TYPE (ptr), "ptr");
6744a6ab
JH
1320 stmt = gimple_build_assign (ptrtmp, ptr);
1321 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
6744a6ab 1322 }
5d49b6a7
RG
1323 ptr = fold_build_pointer_plus_hwi_loc (input_location,
1324 ptrtmp, fixed_offset);
6744a6ab
JH
1325 }
1326
1327 /* Emit the statement and gimplify the adjustment expression. */
7d80ca1f 1328 ret = make_rename_temp (TREE_TYPE (ptr), "adjusted_this");
6744a6ab 1329 stmt = gimple_build_assign (ret, ptr);
6744a6ab
JH
1330 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1331
1332 return ret;
1333}
1334
1335/* Produce assembler for thunk NODE. */
1336
1337static void
1338assemble_thunk (struct cgraph_node *node)
1339{
1340 bool this_adjusting = node->thunk.this_adjusting;
1341 HOST_WIDE_INT fixed_offset = node->thunk.fixed_offset;
1342 HOST_WIDE_INT virtual_value = node->thunk.virtual_value;
1343 tree virtual_offset = NULL;
1344 tree alias = node->thunk.alias;
960bfb69 1345 tree thunk_fndecl = node->symbol.decl;
6744a6ab
JH
1346 tree a = DECL_ARGUMENTS (thunk_fndecl);
1347
1348 current_function_decl = thunk_fndecl;
1349
d06865bf
DK
1350 /* Ensure thunks are emitted in their correct sections. */
1351 resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
1352
6744a6ab
JH
1353 if (this_adjusting
1354 && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
1355 virtual_value, alias))
1356 {
1357 const char *fnname;
1358 tree fn_block;
4399cf59 1359 tree restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
6744a6ab
JH
1360
1361 DECL_RESULT (thunk_fndecl)
1362 = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl),
4399cf59 1363 RESULT_DECL, 0, restype);
15488554 1364 fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
6744a6ab
JH
1365
1366 /* The back end expects DECL_INITIAL to contain a BLOCK, so we
1367 create one. */
1368 fn_block = make_node (BLOCK);
1369 BLOCK_VARS (fn_block) = a;
1370 DECL_INITIAL (thunk_fndecl) = fn_block;
1371 init_function_start (thunk_fndecl);
1372 cfun->is_thunk = 1;
1373 assemble_start_function (thunk_fndecl, fnname);
1374
1375 targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl,
1376 fixed_offset, virtual_value, alias);
1377
1378 assemble_end_function (thunk_fndecl, fnname);
1379 init_insn_lengths ();
1380 free_after_compilation (cfun);
1381 set_cfun (NULL);
1382 TREE_ASM_WRITTEN (thunk_fndecl) = 1;
c47d0034
JH
1383 node->thunk.thunk_p = false;
1384 node->analyzed = false;
6744a6ab
JH
1385 }
1386 else
1387 {
1388 tree restype;
1389 basic_block bb, then_bb, else_bb, return_bb;
1390 gimple_stmt_iterator bsi;
1391 int nargs = 0;
1392 tree arg;
1393 int i;
1394 tree resdecl;
1395 tree restmp = NULL;
1396 VEC(tree, heap) *vargs;
1397
1398 gimple call;
1399 gimple ret;
1400
1401 DECL_IGNORED_P (thunk_fndecl) = 1;
1402 bitmap_obstack_initialize (NULL);
1403
1404 if (node->thunk.virtual_offset_p)
1405 virtual_offset = size_int (virtual_value);
1406
1407 /* Build the return declaration for the function. */
1408 restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1409 if (DECL_RESULT (thunk_fndecl) == NULL_TREE)
1410 {
1411 resdecl = build_decl (input_location, RESULT_DECL, 0, restype);
1412 DECL_ARTIFICIAL (resdecl) = 1;
1413 DECL_IGNORED_P (resdecl) = 1;
1414 DECL_RESULT (thunk_fndecl) = resdecl;
1415 }
1416 else
1417 resdecl = DECL_RESULT (thunk_fndecl);
1418
1419 bb = then_bb = else_bb = return_bb = init_lowered_empty_function (thunk_fndecl);
1420
1421 bsi = gsi_start_bb (bb);
1422
1423 /* Build call to the function being thunked. */
1424 if (!VOID_TYPE_P (restype))
1425 {
1426 if (!is_gimple_reg_type (restype))
1427 {
1428 restmp = resdecl;
c021f10b 1429 add_local_decl (cfun, restmp);
6744a6ab
JH
1430 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp;
1431 }
1432 else
7d80ca1f 1433 restmp = make_rename_temp (restype, "retval");
6744a6ab
JH
1434 }
1435
910ad8de 1436 for (arg = a; arg; arg = DECL_CHAIN (arg))
6744a6ab
JH
1437 nargs++;
1438 vargs = VEC_alloc (tree, heap, nargs);
1439 if (this_adjusting)
1440 VEC_quick_push (tree, vargs,
1441 thunk_adjust (&bsi,
1442 a, 1, fixed_offset,
1443 virtual_offset));
1444 else
1445 VEC_quick_push (tree, vargs, a);
7d80ca1f
RG
1446 add_referenced_var (a);
1447 if (is_gimple_reg (a))
1448 mark_sym_for_renaming (a);
910ad8de 1449 for (i = 1, arg = DECL_CHAIN (a); i < nargs; i++, arg = DECL_CHAIN (arg))
7d80ca1f
RG
1450 {
1451 add_referenced_var (arg);
1452 if (is_gimple_reg (arg))
1453 mark_sym_for_renaming (arg);
1454 VEC_quick_push (tree, vargs, arg);
1455 }
6744a6ab
JH
1456 call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs);
1457 VEC_free (tree, heap, vargs);
6744a6ab
JH
1458 gimple_call_set_from_thunk (call, true);
1459 if (restmp)
1460 gimple_call_set_lhs (call, restmp);
1461 gsi_insert_after (&bsi, call, GSI_NEW_STMT);
6744a6ab
JH
1462
1463 if (restmp && !this_adjusting)
1464 {
1124098b 1465 tree true_label = NULL_TREE;
6744a6ab
JH
1466
1467 if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE)
1468 {
1469 gimple stmt;
1470 /* If the return type is a pointer, we need to
1471 protect against NULL. We know there will be an
1472 adjustment, because that's why we're emitting a
1473 thunk. */
1474 then_bb = create_basic_block (NULL, (void *) 0, bb);
1475 return_bb = create_basic_block (NULL, (void *) 0, then_bb);
1476 else_bb = create_basic_block (NULL, (void *) 0, else_bb);
1477 remove_edge (single_succ_edge (bb));
1478 true_label = gimple_block_label (then_bb);
6744a6ab 1479 stmt = gimple_build_cond (NE_EXPR, restmp,
e8160c9a 1480 build_zero_cst (TREE_TYPE (restmp)),
6744a6ab
JH
1481 NULL_TREE, NULL_TREE);
1482 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1483 make_edge (bb, then_bb, EDGE_TRUE_VALUE);
1484 make_edge (bb, else_bb, EDGE_FALSE_VALUE);
1485 make_edge (return_bb, EXIT_BLOCK_PTR, 0);
1486 make_edge (then_bb, return_bb, EDGE_FALLTHRU);
1487 make_edge (else_bb, return_bb, EDGE_FALLTHRU);
1488 bsi = gsi_last_bb (then_bb);
1489 }
1490
1491 restmp = thunk_adjust (&bsi, restmp, /*this_adjusting=*/0,
1492 fixed_offset, virtual_offset);
1493 if (true_label)
1494 {
1495 gimple stmt;
1496 bsi = gsi_last_bb (else_bb);
e8160c9a
NF
1497 stmt = gimple_build_assign (restmp,
1498 build_zero_cst (TREE_TYPE (restmp)));
6744a6ab
JH
1499 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1500 bsi = gsi_last_bb (return_bb);
1501 }
1502 }
1503 else
1504 gimple_call_set_tail (call, true);
1505
1506 /* Build return value. */
1507 ret = gimple_build_return (restmp);
1508 gsi_insert_after (&bsi, ret, GSI_NEW_STMT);
1509
1510 delete_unreachable_blocks ();
1511 update_ssa (TODO_update_ssa);
1512
6744a6ab
JH
1513 /* Since we want to emit the thunk, we explicitly mark its name as
1514 referenced. */
c47d0034
JH
1515 node->thunk.thunk_p = false;
1516 cgraph_node_remove_callees (node);
6744a6ab
JH
1517 cgraph_add_new_function (thunk_fndecl, true);
1518 bitmap_obstack_release (NULL);
1519 }
1520 current_function_decl = NULL;
1521}
1522
c47d0034 1523
39e2db00
JH
1524
1525/* Assemble thunks and aliases asociated to NODE. */
c47d0034
JH
1526
1527static void
39e2db00 1528assemble_thunks_and_aliases (struct cgraph_node *node)
c47d0034
JH
1529{
1530 struct cgraph_edge *e;
39e2db00
JH
1531 int i;
1532 struct ipa_ref *ref;
1533
c47d0034
JH
1534 for (e = node->callers; e;)
1535 if (e->caller->thunk.thunk_p)
1536 {
1537 struct cgraph_node *thunk = e->caller;
1538
1539 e = e->next_caller;
39e2db00 1540 assemble_thunks_and_aliases (thunk);
c47d0034
JH
1541 assemble_thunk (thunk);
1542 }
1543 else
1544 e = e->next_caller;
5932a4d4 1545 for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list,
960bfb69 1546 i, ref); i++)
39e2db00
JH
1547 if (ref->use == IPA_REF_ALIAS)
1548 {
5932a4d4 1549 struct cgraph_node *alias = ipa_ref_referring_node (ref);
42f833bc
JH
1550 bool saved_written = TREE_ASM_WRITTEN (alias->thunk.alias);
1551
1552 /* Force assemble_alias to really output the alias this time instead
1553 of buffering it in same alias pairs. */
1554 TREE_ASM_WRITTEN (alias->thunk.alias) = 1;
960bfb69 1555 assemble_alias (alias->symbol.decl,
39e2db00
JH
1556 DECL_ASSEMBLER_NAME (alias->thunk.alias));
1557 assemble_thunks_and_aliases (alias);
42f833bc 1558 TREE_ASM_WRITTEN (alias->thunk.alias) = saved_written;
39e2db00 1559 }
c47d0034
JH
1560}
1561
9c8305f8 1562/* Expand function specified by NODE. */
0878843f 1563
452aa9c5 1564static void
65d630d4 1565expand_function (struct cgraph_node *node)
0878843f 1566{
9c8305f8 1567 tree decl = node->symbol.decl;
0878843f
RG
1568 location_t saved_loc;
1569
9c8305f8
JH
1570 /* We ought to not compile any inline clones. */
1571 gcc_assert (!node->global.inlined_to);
1572
1573 announce_function (decl);
1574 node->process = 0;
1575 gcc_assert (node->lowered);
1576
1577 /* Generate RTL for the body of DECL. */
1578
0878843f
RG
1579 timevar_push (TV_REST_OF_COMPILATION);
1580
1581 gcc_assert (cgraph_global_info_ready);
1582
1583 /* Initialize the default bitmap obstack. */
1584 bitmap_obstack_initialize (NULL);
1585
1586 /* Initialize the RTL code for the function. */
9c8305f8 1587 current_function_decl = decl;
0878843f 1588 saved_loc = input_location;
9c8305f8
JH
1589 input_location = DECL_SOURCE_LOCATION (decl);
1590 init_function_start (decl);
0878843f
RG
1591
1592 gimple_register_cfg_hooks ();
1593
1594 bitmap_obstack_initialize (&reg_obstack); /* FIXME, only at RTL generation*/
1595
1596 execute_all_ipa_transforms ();
1597
1598 /* Perform all tree transforms and optimizations. */
1599
1600 /* Signal the start of passes. */
1601 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START, NULL);
1602
1603 execute_pass_list (all_passes);
1604
1605 /* Signal the end of passes. */
1606 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END, NULL);
1607
1608 bitmap_obstack_release (&reg_obstack);
1609
1610 /* Release the default bitmap obstack. */
1611 bitmap_obstack_release (NULL);
1612
1613 set_cfun (NULL);
1614
1615 /* If requested, warn about function definitions where the function will
1616 return a value (usually of some struct or union type) which itself will
1617 take up a lot of stack space. */
9c8305f8 1618 if (warn_larger_than && !DECL_EXTERNAL (decl) && TREE_TYPE (decl))
0878843f 1619 {
9c8305f8 1620 tree ret_type = TREE_TYPE (TREE_TYPE (decl));
0878843f
RG
1621
1622 if (ret_type && TYPE_SIZE_UNIT (ret_type)
1623 && TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST
1624 && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type),
1625 larger_than_size))
1626 {
1627 unsigned int size_as_int
1628 = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type));
1629
1630 if (compare_tree_int (TYPE_SIZE_UNIT (ret_type), size_as_int) == 0)
1631 warning (OPT_Wlarger_than_, "size of return value of %q+D is %u bytes",
9c8305f8 1632 decl, size_as_int);
0878843f
RG
1633 else
1634 warning (OPT_Wlarger_than_, "size of return value of %q+D is larger than %wd bytes",
9c8305f8 1635 decl, larger_than_size);
0878843f
RG
1636 }
1637 }
1638
9c8305f8
JH
1639 gimple_set_body (decl, NULL);
1640 if (DECL_STRUCT_FUNCTION (decl) == 0
1641 && !cgraph_get_node (decl)->origin)
0878843f
RG
1642 {
1643 /* Stop pointing to the local nodes about to be freed.
1644 But DECL_INITIAL must remain nonzero so we know this
1645 was an actual function definition.
1646 For a nested function, this is done in c_pop_function_context.
1647 If rest_of_compilation set this to 0, leave it 0. */
9c8305f8
JH
1648 if (DECL_INITIAL (decl) != 0)
1649 DECL_INITIAL (decl) = error_mark_node;
0878843f
RG
1650 }
1651
1652 input_location = saved_loc;
1653
1654 ggc_collect ();
1655 timevar_pop (TV_REST_OF_COMPILATION);
5806d9ac
JH
1656
1657 /* Make sure that BE didn't give up on compiling. */
1658 gcc_assert (TREE_ASM_WRITTEN (decl));
1659 current_function_decl = NULL;
1bb7e8f8
JH
1660
1661 /* It would make a lot more sense to output thunks before function body to get more
65d630d4 1662 forward and lest backwarding jumps. This however would need solving problem
1bb7e8f8 1663 with comdats. See PR48668. Also aliases must come after function itself to
65d630d4 1664 make one pass assemblers, like one on AIX, happy. See PR 50689.
1bb7e8f8
JH
1665 FIXME: Perhaps thunks should be move before function IFF they are not in comdat
1666 groups. */
1667 assemble_thunks_and_aliases (node);
39ecc018
JH
1668 cgraph_release_function_body (node);
1669 /* Eliminate all call edges. This is important so the GIMPLE_CALL no longer
1670 points to the dead function body. */
1671 cgraph_node_remove_callees (node);
1c4a429a
JH
1672}
1673
6674a6ce 1674
db0e878d
AJ
1675/* Expand all functions that must be output.
1676
b58b1157
JH
1677 Attempt to topologically sort the nodes so function is output when
1678 all called functions are already assembled to allow data to be
a98ebe2e 1679 propagated across the callgraph. Use a stack to get smaller distance
d1a6adeb 1680 between a function and its callees (later we may choose to use a more
b58b1157
JH
1681 sophisticated algorithm for function reordering; we will likely want
1682 to use subsections to make the output functions appear in top-down
1683 order). */
1684
1685static void
65d630d4 1686expand_all_functions (void)
b58b1157
JH
1687{
1688 struct cgraph_node *node;
5ed6ace5 1689 struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
f30cfcb1 1690 int order_pos, new_order_pos = 0;
b58b1157
JH
1691 int i;
1692
af8bca3c 1693 order_pos = ipa_reverse_postorder (order);
341c100f 1694 gcc_assert (order_pos == cgraph_n_nodes);
b58b1157 1695
1ae58c30 1696 /* Garbage collector may remove inline clones we eliminate during
18c6ada9
JH
1697 optimization. So we must be sure to not reference them. */
1698 for (i = 0; i < order_pos; i++)
257eb6e3 1699 if (order[i]->process)
18c6ada9
JH
1700 order[new_order_pos++] = order[i];
1701
1702 for (i = new_order_pos - 1; i >= 0; i--)
b58b1157
JH
1703 {
1704 node = order[i];
257eb6e3 1705 if (node->process)
b58b1157 1706 {
257eb6e3 1707 node->process = 0;
65d630d4 1708 expand_function (node);
b58b1157
JH
1709 }
1710 }
f45e0ad1 1711 cgraph_process_new_functions ();
50674e96 1712
b58b1157 1713 free (order);
50674e96 1714
b58b1157
JH
1715}
1716
474eccc6
ILT
1717/* This is used to sort the node types by the cgraph order number. */
1718
24b97832
ILT
1719enum cgraph_order_sort_kind
1720{
1721 ORDER_UNDEFINED = 0,
1722 ORDER_FUNCTION,
1723 ORDER_VAR,
1724 ORDER_ASM
1725};
1726
474eccc6
ILT
1727struct cgraph_order_sort
1728{
24b97832 1729 enum cgraph_order_sort_kind kind;
474eccc6
ILT
1730 union
1731 {
1732 struct cgraph_node *f;
8a4a83ed 1733 struct varpool_node *v;
65d630d4 1734 struct asm_node *a;
474eccc6
ILT
1735 } u;
1736};
1737
1738/* Output all functions, variables, and asm statements in the order
1739 according to their order fields, which is the order in which they
1740 appeared in the file. This implements -fno-toplevel-reorder. In
1741 this mode we may output functions and variables which don't really
1742 need to be output. */
1743
1744static void
65d630d4 1745output_in_order (void)
474eccc6
ILT
1746{
1747 int max;
474eccc6
ILT
1748 struct cgraph_order_sort *nodes;
1749 int i;
1750 struct cgraph_node *pf;
8a4a83ed 1751 struct varpool_node *pv;
65d630d4 1752 struct asm_node *pa;
474eccc6 1753
2aae7680 1754 max = symtab_order;
33283dad 1755 nodes = XCNEWVEC (struct cgraph_order_sort, max);
474eccc6 1756
65c70e6b 1757 FOR_EACH_DEFINED_FUNCTION (pf)
474eccc6 1758 {
39e2db00 1759 if (pf->process && !pf->thunk.thunk_p && !pf->alias)
474eccc6 1760 {
960bfb69 1761 i = pf->symbol.order;
474eccc6
ILT
1762 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1763 nodes[i].kind = ORDER_FUNCTION;
1764 nodes[i].u.f = pf;
1765 }
1766 }
1767
65c70e6b 1768 FOR_EACH_DEFINED_VARIABLE (pv)
6649df51
JH
1769 if (!DECL_EXTERNAL (pv->symbol.decl))
1770 {
1771 i = pv->symbol.order;
1772 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1773 nodes[i].kind = ORDER_VAR;
1774 nodes[i].u.v = pv;
1775 }
474eccc6 1776
65d630d4 1777 for (pa = asm_nodes; pa; pa = pa->next)
474eccc6
ILT
1778 {
1779 i = pa->order;
1780 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1781 nodes[i].kind = ORDER_ASM;
1782 nodes[i].u.a = pa;
1783 }
474eccc6 1784
7386e3ee 1785 /* In toplevel reorder mode we output all statics; mark them as needed. */
7386e3ee 1786
7fece979
JJ
1787 for (i = 0; i < max; ++i)
1788 if (nodes[i].kind == ORDER_VAR)
1789 varpool_finalize_named_section_flags (nodes[i].u.v);
1790
474eccc6
ILT
1791 for (i = 0; i < max; ++i)
1792 {
1793 switch (nodes[i].kind)
1794 {
1795 case ORDER_FUNCTION:
257eb6e3 1796 nodes[i].u.f->process = 0;
65d630d4 1797 expand_function (nodes[i].u.f);
474eccc6
ILT
1798 break;
1799
1800 case ORDER_VAR:
8a4a83ed 1801 varpool_assemble_decl (nodes[i].u.v);
474eccc6
ILT
1802 break;
1803
1804 case ORDER_ASM:
1805 assemble_asm (nodes[i].u.a->asm_str);
1806 break;
1807
1808 case ORDER_UNDEFINED:
1809 break;
1810
1811 default:
1812 gcc_unreachable ();
1813 }
1814 }
e7b9eb2c 1815
65d630d4 1816 asm_nodes = NULL;
33283dad 1817 free (nodes);
474eccc6
ILT
1818}
1819
ef330312
PB
1820static void
1821ipa_passes (void)
1822{
db2960f4 1823 set_cfun (NULL);
04b201a2 1824 current_function_decl = NULL;
726a989a 1825 gimple_register_cfg_hooks ();
ef330312 1826 bitmap_obstack_initialize (NULL);
b20996ff 1827
090fa0ab
GF
1828 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START, NULL);
1829
b20996ff 1830 if (!in_lto_p)
0430f80c
RG
1831 {
1832 execute_ipa_pass_list (all_small_ipa_passes);
1833 if (seen_error ())
1834 return;
1835 }
3baf459d 1836
467a8db0
JH
1837 /* We never run removal of unreachable nodes after early passes. This is
1838 because TODO is run before the subpasses. It is important to remove
1839 the unreachable functions to save works at IPA level and to get LTO
1840 symbol tables right. */
04142cc3 1841 symtab_remove_unreachable_nodes (true, cgraph_dump_file);
467a8db0 1842
d7f09764
DN
1843 /* If pass_all_early_optimizations was not scheduled, the state of
1844 the cgraph will not be properly updated. Update it now. */
1845 if (cgraph_state < CGRAPH_STATE_IPA_SSA)
1846 cgraph_state = CGRAPH_STATE_IPA_SSA;
3baf459d 1847
d7f09764
DN
1848 if (!in_lto_p)
1849 {
1850 /* Generate coverage variables and constructors. */
1851 coverage_finish ();
1852
1853 /* Process new functions added. */
1854 set_cfun (NULL);
1855 current_function_decl = NULL;
1856 cgraph_process_new_functions ();
d7f09764 1857
090fa0ab
GF
1858 execute_ipa_summary_passes
1859 ((struct ipa_opt_pass_d *) all_regular_ipa_passes);
fb3f88cc 1860 }
c082f9f3
SB
1861
1862 /* Some targets need to handle LTO assembler output specially. */
1863 if (flag_generate_lto)
1864 targetm.asm_out.lto_start ();
1865
d7f09764
DN
1866 execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_lto_gen_passes);
1867
1868 if (!in_lto_p)
1869 ipa_write_summaries ();
1870
c082f9f3
SB
1871 if (flag_generate_lto)
1872 targetm.asm_out.lto_end ();
1873
cc8547a7 1874 if (!flag_ltrans && (in_lto_p || !flag_lto || flag_fat_lto_objects))
fb3f88cc 1875 execute_ipa_pass_list (all_regular_ipa_passes);
090fa0ab 1876 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END, NULL);
3baf459d 1877
ef330312
PB
1878 bitmap_obstack_release (NULL);
1879}
1880
25e2c40d
JH
1881
1882/* Return string alias is alias of. */
1883
1884static tree
1885get_alias_symbol (tree decl)
1886{
1887 tree alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
1888 return get_identifier (TREE_STRING_POINTER
1889 (TREE_VALUE (TREE_VALUE (alias))));
1890}
1891
1892
c9552bff
JH
1893/* Weakrefs may be associated to external decls and thus not output
1894 at expansion time. Emit all neccesary aliases. */
1895
a66f86bb 1896static void
c9552bff
JH
1897output_weakrefs (void)
1898{
1899 struct cgraph_node *node;
1900 struct varpool_node *vnode;
65c70e6b 1901 FOR_EACH_FUNCTION (node)
960bfb69
JH
1902 if (node->alias && DECL_EXTERNAL (node->symbol.decl)
1903 && !TREE_ASM_WRITTEN (node->symbol.decl)
1904 && lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
1905 assemble_alias (node->symbol.decl,
25e2c40d 1906 node->thunk.alias ? DECL_ASSEMBLER_NAME (node->thunk.alias)
960bfb69 1907 : get_alias_symbol (node->symbol.decl));
65c70e6b 1908 FOR_EACH_VARIABLE (vnode)
960bfb69
JH
1909 if (vnode->alias && DECL_EXTERNAL (vnode->symbol.decl)
1910 && !TREE_ASM_WRITTEN (vnode->symbol.decl)
1911 && lookup_attribute ("weakref", DECL_ATTRIBUTES (vnode->symbol.decl)))
1912 assemble_alias (vnode->symbol.decl,
25e2c40d 1913 vnode->alias_of ? DECL_ASSEMBLER_NAME (vnode->alias_of)
960bfb69 1914 : get_alias_symbol (vnode->symbol.decl));
c9552bff
JH
1915}
1916
9c8305f8 1917/* Initialize callgraph dump file. */
4537ec0c 1918
9b3e897d
PB
1919void
1920init_cgraph (void)
1921{
a05541a9
JH
1922 if (!cgraph_dump_file)
1923 cgraph_dump_file = dump_begin (TDI_cgraph, NULL);
9b3e897d 1924}
57fb5341 1925
711417cd
RG
1926
1927/* Perform simple optimizations based on callgraph. */
1928
1929void
65d630d4 1930compile (void)
711417cd
RG
1931{
1932 if (seen_error ())
1933 return;
1934
1935#ifdef ENABLE_CHECKING
474ffc72 1936 verify_symtab ();
711417cd
RG
1937#endif
1938
711417cd
RG
1939 timevar_push (TV_CGRAPHOPT);
1940 if (pre_ipa_mem_report)
1941 {
1942 fprintf (stderr, "Memory consumption before IPA\n");
1943 dump_memory_report (false);
1944 }
1945 if (!quiet_flag)
1946 fprintf (stderr, "Performing interprocedural optimizations\n");
1947 cgraph_state = CGRAPH_STATE_IPA;
1948
65d630d4
JH
1949 /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE. */
1950 if (flag_lto)
1951 lto_streamer_hooks_init ();
1952
711417cd
RG
1953 /* Don't run the IPA passes if there was any error or sorry messages. */
1954 if (!seen_error ())
1955 ipa_passes ();
1956
1957 /* Do nothing else if any IPA pass found errors or if we are just streaming LTO. */
1958 if (seen_error ()
1959 || (!in_lto_p && flag_lto && !flag_fat_lto_objects))
1960 {
1961 timevar_pop (TV_CGRAPHOPT);
1962 return;
1963 }
1964
1965 /* This pass remove bodies of extern inline functions we never inlined.
1966 Do this later so other IPA passes see what is really going on. */
04142cc3 1967 symtab_remove_unreachable_nodes (false, dump_file);
711417cd
RG
1968 cgraph_global_info_ready = true;
1969 if (cgraph_dump_file)
1970 {
1971 fprintf (cgraph_dump_file, "Optimized ");
8f940ee6 1972 dump_symtab (cgraph_dump_file);
711417cd
RG
1973 }
1974 if (post_ipa_mem_report)
1975 {
1976 fprintf (stderr, "Memory consumption after IPA\n");
1977 dump_memory_report (false);
1978 }
1979 timevar_pop (TV_CGRAPHOPT);
1980
1981 /* Output everything. */
1982 (*debug_hooks->assembly_start) ();
1983 if (!quiet_flag)
1984 fprintf (stderr, "Assembling functions:\n");
1985#ifdef ENABLE_CHECKING
474ffc72 1986 verify_symtab ();
711417cd
RG
1987#endif
1988
1989 cgraph_materialize_all_clones ();
1990 bitmap_obstack_initialize (NULL);
1991 execute_ipa_pass_list (all_late_ipa_passes);
04142cc3 1992 symtab_remove_unreachable_nodes (true, dump_file);
711417cd 1993#ifdef ENABLE_CHECKING
474ffc72 1994 verify_symtab ();
711417cd
RG
1995#endif
1996 bitmap_obstack_release (NULL);
65d630d4 1997 mark_functions_to_output ();
711417cd
RG
1998 output_weakrefs ();
1999
2000 cgraph_state = CGRAPH_STATE_EXPANSION;
2001 if (!flag_toplevel_reorder)
65d630d4 2002 output_in_order ();
711417cd
RG
2003 else
2004 {
65d630d4 2005 output_asm_statements ();
711417cd 2006
65d630d4
JH
2007 expand_all_functions ();
2008 varpool_output_variables ();
711417cd
RG
2009 }
2010
2011 cgraph_process_new_functions ();
2012 cgraph_state = CGRAPH_STATE_FINISHED;
2013
2014 if (cgraph_dump_file)
2015 {
2016 fprintf (cgraph_dump_file, "\nFinal ");
8f940ee6 2017 dump_symtab (cgraph_dump_file);
711417cd
RG
2018 }
2019#ifdef ENABLE_CHECKING
474ffc72 2020 verify_symtab ();
711417cd
RG
2021 /* Double check that all inline clones are gone and that all
2022 function bodies have been released from memory. */
2023 if (!seen_error ())
2024 {
2025 struct cgraph_node *node;
2026 bool error_found = false;
2027
65c70e6b
JH
2028 FOR_EACH_DEFINED_FUNCTION (node)
2029 if (node->global.inlined_to
2030 || gimple_has_body_p (node->symbol.decl))
711417cd
RG
2031 {
2032 error_found = true;
2033 dump_cgraph_node (stderr, node);
2034 }
2035 if (error_found)
2036 internal_error ("nodes with unreleased memory found");
2037 }
2038#endif
2039}
2040
2041
2042/* Analyze the whole compilation unit once it is parsed completely. */
2043
2044void
65d630d4 2045finalize_compilation_unit (void)
711417cd
RG
2046{
2047 timevar_push (TV_CGRAPH);
2048
711417cd
RG
2049 /* If we're here there's no current function anymore. Some frontends
2050 are lazy in clearing these. */
2051 current_function_decl = NULL;
2052 set_cfun (NULL);
2053
2054 /* Do not skip analyzing the functions if there were errors, we
2055 miss diagnostics for following functions otherwise. */
2056
2057 /* Emit size functions we didn't inline. */
2058 finalize_size_functions ();
2059
2060 /* Mark alias targets necessary and emit diagnostics. */
2061 finish_aliases_1 ();
2062 handle_alias_pairs ();
2063
2064 if (!quiet_flag)
2065 {
2066 fprintf (stderr, "\nAnalyzing compilation unit\n");
2067 fflush (stderr);
2068 }
2069
2070 if (flag_dump_passes)
2071 dump_passes ();
2072
2073 /* Gimplify and lower all functions, compute reachability and
2074 remove unreachable nodes. */
2075 cgraph_analyze_functions ();
2076
2077 /* Mark alias targets necessary and emit diagnostics. */
2078 finish_aliases_1 ();
2079 handle_alias_pairs ();
2080
2081 /* Gimplify and lower thunks. */
2082 cgraph_analyze_functions ();
2083
2084 /* Finally drive the pass manager. */
65d630d4 2085 compile ();
711417cd
RG
2086
2087 timevar_pop (TV_CGRAPH);
2088}
2089
2090
7be82279 2091#include "gt-cgraphunit.h"