]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/cgraphunit.c
Daily bump.
[thirdparty/gcc.git] / gcc / cgraphunit.c
CommitLineData
9c8305f8 1/* Driver of optimization process
d06865bf 2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
0850f694 3 2011, 2012 Free Software Foundation, Inc.
1c4a429a
JH
4 Contributed by Jan Hubicka
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
9dcd6f09 10Software Foundation; either version 3, or (at your option) any later
1c4a429a
JH
11version.
12
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License
9dcd6f09
NC
19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
1c4a429a 21
9c8305f8 22/* This module implements main driver of compilation process.
18c6ada9
JH
23
24 The main scope of this file is to act as an interface in between
9c8305f8 25 tree based frontends and the backend.
18c6ada9
JH
26
27 The front-end is supposed to use following functionality:
28
29 - cgraph_finalize_function
30
31 This function is called once front-end has parsed whole body of function
32 and it is certain that the function body nor the declaration will change.
33
efe75b6f
JH
34 (There is one exception needed for implementing GCC extern inline
35 function.)
18c6ada9 36
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 *);
877ab5e9 208static void handle_alias_pairs (void);
7dff32e6 209
0a5fa5a1 210FILE *cgraph_dump_file;
9b3e897d 211
65d630d4
JH
212/* Linked list of cgraph asm nodes. */
213struct asm_node *asm_nodes;
214
215/* Last node in cgraph_asm_nodes. */
216static GTY(()) struct asm_node *asm_last_node;
217
6744a6ab
JH
218/* Used for vtable lookup in thunk adjusting. */
219static GTY (()) tree vtable_entry_type;
220
ead84f73
JH
221/* Determine if function DECL is trivially needed and should stay in the
222 compilation unit. This is used at the symbol table construction time
223 and differs from later logic removing unnecesary functions that can
224 take into account results of analysis, whole program info etc. */
8dafba3c 225
9c8305f8 226static bool
d7f09764 227cgraph_decide_is_function_needed (struct cgraph_node *node, tree decl)
8dafba3c 228{
e7d6beb0 229 /* If the user told us it is used, then it must be so. */
ead84f73 230 if (node->symbol.force_output)
386b46cf
JH
231 return true;
232
ead84f73
JH
233 /* Double check that no one output the function into assembly file
234 early. */
235 gcc_checking_assert (!DECL_ASSEMBLER_NAME_SET_P (decl)
236 || (node->thunk.thunk_p || node->same_body_alias)
237 || !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)));
e7d6beb0 238
a1d31187 239
ead84f73
JH
240 /* Keep constructors, destructors and virtual functions. */
241 if (DECL_STATIC_CONSTRUCTOR (decl)
242 || DECL_STATIC_DESTRUCTOR (decl)
243 || (DECL_VIRTUAL_P (decl)
244 && optimize && (DECL_COMDAT (decl) || DECL_EXTERNAL (decl))))
245 return true;
8dafba3c
RH
246
247 /* Externally visible functions must be output. The exception is
ead84f73 248 COMDAT functions that must be output only when they are needed. */
04f77d0f 249
ead84f73 250 if (TREE_PUBLIC (decl)
ce91e74c 251 && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
8dafba3c
RH
252 return true;
253
8dafba3c
RH
254 return false;
255}
256
66058468
JH
257/* Head of the queue of nodes to be processed while building callgraph */
258
259static symtab_node first = (symtab_node)(void *)1;
260
261/* Add NODE to queue starting at FIRST.
262 The queue is linked via AUX pointers and terminated by pointer to 1. */
263
264static void
265enqueue_node (symtab_node node)
266{
267 if (node->symbol.aux)
268 return;
269 gcc_checking_assert (first);
270 node->symbol.aux = first;
271 first = node;
272}
273
d60ab196 274/* Process CGRAPH_NEW_FUNCTIONS and perform actions necessary to add these
f45e0ad1
JH
275 functions into callgraph in a way so they look like ordinary reachable
276 functions inserted into callgraph already at construction time. */
277
278bool
279cgraph_process_new_functions (void)
280{
281 bool output = false;
282 tree fndecl;
283 struct cgraph_node *node;
66058468 284 cgraph_node_set_iterator csi;
f45e0ad1 285
66058468
JH
286 if (!cgraph_new_nodes)
287 return false;
877ab5e9
JH
288 finish_aliases_1 ();
289 handle_alias_pairs ();
f45e0ad1
JH
290 /* Note that this queue may grow as its being processed, as the new
291 functions may generate new ones. */
66058468 292 for (csi = csi_start (cgraph_new_nodes); !csi_end_p (csi); csi_next (&csi))
f45e0ad1 293 {
66058468 294 node = csi_node (csi);
960bfb69 295 fndecl = node->symbol.decl;
f45e0ad1
JH
296 switch (cgraph_state)
297 {
298 case CGRAPH_STATE_CONSTRUCTION:
299 /* At construction time we just need to finalize function and move
300 it into reachable functions list. */
301
f45e0ad1 302 cgraph_finalize_function (fndecl, false);
f45e0ad1 303 output = true;
4d5dcfb2 304 cgraph_call_function_insertion_hooks (node);
66058468 305 enqueue_node ((symtab_node) node);
f45e0ad1
JH
306 break;
307
308 case CGRAPH_STATE_IPA:
7a388ee4 309 case CGRAPH_STATE_IPA_SSA:
f45e0ad1
JH
310 /* When IPA optimization already started, do all essential
311 transformations that has been already performed on the whole
312 cgraph but not on this function. */
313
726a989a 314 gimple_register_cfg_hooks ();
f45e0ad1
JH
315 if (!node->analyzed)
316 cgraph_analyze_function (node);
317 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
318 current_function_decl = fndecl;
7a388ee4
JH
319 if ((cgraph_state == CGRAPH_STATE_IPA_SSA
320 && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
321 /* When not optimizing, be sure we run early local passes anyway
322 to expand OMP. */
323 || !optimize)
8ddbbcae 324 execute_pass_list (pass_early_local_passes.pass.sub);
bb7e6d55 325 else
632b4f8e 326 compute_inline_parameters (node, true);
f45e0ad1
JH
327 free_dominance_info (CDI_POST_DOMINATORS);
328 free_dominance_info (CDI_DOMINATORS);
329 pop_cfun ();
330 current_function_decl = NULL;
4d5dcfb2 331 cgraph_call_function_insertion_hooks (node);
f45e0ad1
JH
332 break;
333
334 case CGRAPH_STATE_EXPANSION:
335 /* Functions created during expansion shall be compiled
336 directly. */
257eb6e3 337 node->process = 0;
4d5dcfb2 338 cgraph_call_function_insertion_hooks (node);
65d630d4 339 expand_function (node);
f45e0ad1
JH
340 break;
341
342 default:
343 gcc_unreachable ();
344 break;
345 }
346 }
66058468
JH
347 free_cgraph_node_set (cgraph_new_nodes);
348 cgraph_new_nodes = NULL;
f45e0ad1
JH
349 return output;
350}
351
d71cc23f
JH
352/* As an GCC extension we allow redefinition of the function. The
353 semantics when both copies of bodies differ is not well defined.
354 We replace the old body with new body so in unit at a time mode
355 we always use new body, while in normal mode we may end up with
356 old body inlined into some functions and new body expanded and
357 inlined in others.
358
359 ??? It may make more sense to use one body for inlining and other
360 body for expanding the function but this is difficult to do. */
361
362static void
363cgraph_reset_node (struct cgraph_node *node)
364{
257eb6e3 365 /* If node->process is set, then we have already begun whole-unit analysis.
7e8b322a
JH
366 This is *not* testing for whether we've already emitted the function.
367 That case can be sort-of legitimately seen with real function redefinition
368 errors. I would argue that the front end should never present us with
369 such a case, but don't enforce that for now. */
257eb6e3 370 gcc_assert (!node->process);
d71cc23f
JH
371
372 /* Reset our data structures so we can analyze the function again. */
373 memset (&node->local, 0, sizeof (node->local));
374 memset (&node->global, 0, sizeof (node->global));
375 memset (&node->rtl, 0, sizeof (node->rtl));
376 node->analyzed = false;
d71cc23f
JH
377 node->local.finalized = false;
378
d71cc23f 379 cgraph_node_remove_callees (node);
d71cc23f 380}
d853a20e 381
838ff415
JH
382/* Return true when there are references to NODE. */
383
384static bool
385referred_to_p (symtab_node node)
386{
838ff415
JH
387 struct ipa_ref *ref;
388
65d630d4
JH
389 /* See if there are any refrences at all. */
390 if (ipa_ref_list_referring_iterate (&node->symbol.ref_list, 0, ref))
838ff415 391 return true;
65d630d4 392 /* For functions check also calls. */
838ff415
JH
393 if (symtab_function_p (node) && cgraph (node)->callers)
394 return true;
395 return false;
396}
397
6b00c969
RH
398/* DECL has been parsed. Take it, queue it, compile it at the whim of the
399 logic in effect. If NESTED is true, then our caller cannot stand to have
400 the garbage collector run at the moment. We would need to either create
401 a new GC context, or just not compile right now. */
1c4a429a
JH
402
403void
6b00c969 404cgraph_finalize_function (tree decl, bool nested)
1c4a429a 405{
a358e188 406 struct cgraph_node *node = cgraph_get_create_node (decl);
1c4a429a 407
d853a20e 408 if (node->local.finalized)
b125ad45
JH
409 {
410 cgraph_reset_node (node);
411 node->local.redefined_extern_inline = true;
412 }
6b00c969 413
d853a20e 414 notice_global_symbol (decl);
f6981e16 415 node->local.finalized = true;
e21aff8a 416 node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL;
1c4a429a 417
ead84f73
JH
418 /* With -fkeep-inline-functions we are keeping all inline functions except
419 for extern inline ones. */
420 if (flag_keep_inline_functions
421 && DECL_DECLARED_INLINE_P (decl)
422 && !DECL_EXTERNAL (decl)
423 && !DECL_DISREGARD_INLINE_LIMITS (decl))
424 node->symbol.force_output = 1;
8dafba3c 425
ead84f73
JH
426 /* When not optimizing, also output the static functions. (see
427 PR24561), but don't do so for always_inline functions, functions
428 declared inline and nested functions. These were optimized out
429 in the original implementation and it is unclear whether we want
430 to change the behavior here. */
431 if ((!optimize
432 && !node->same_body_alias
433 && !DECL_DISREGARD_INLINE_LIMITS (decl)
434 && !DECL_DECLARED_INLINE_P (decl)
435 && !(DECL_CONTEXT (decl)
436 && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL))
437 && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
438 node->symbol.force_output = 1;
439
8dafba3c 440 /* If we've not yet emitted decl, tell the debug info about it. */
6b00c969 441 if (!TREE_ASM_WRITTEN (decl))
8dafba3c 442 (*debug_hooks->deferred_inline_function) (decl);
d173e685 443
902edd36
JH
444 /* Possibly warn about unused parameters. */
445 if (warn_unused_parameter)
446 do_warn_unused_parameter (decl);
7e8b322a
JH
447
448 if (!nested)
449 ggc_collect ();
838ff415
JH
450
451 if (cgraph_state == CGRAPH_STATE_CONSTRUCTION
452 && (cgraph_decide_is_function_needed (node, decl)
453 || referred_to_p ((symtab_node)node)))
454 enqueue_node ((symtab_node)node);
1c4a429a
JH
455}
456
452aa9c5
RG
457/* Add the function FNDECL to the call graph.
458 Unlike cgraph_finalize_function, this function is intended to be used
459 by middle end and allows insertion of new function at arbitrary point
460 of compilation. The function can be either in high, low or SSA form
461 GIMPLE.
462
463 The function is assumed to be reachable and have address taken (so no
464 API breaking optimizations are performed on it).
465
466 Main work done by this function is to enqueue the function for later
467 processing to avoid need the passes to be re-entrant. */
468
469void
470cgraph_add_new_function (tree fndecl, bool lowered)
471{
472 struct cgraph_node *node;
473 switch (cgraph_state)
474 {
66058468
JH
475 case CGRAPH_STATE_PARSING:
476 cgraph_finalize_function (fndecl, false);
477 break;
452aa9c5
RG
478 case CGRAPH_STATE_CONSTRUCTION:
479 /* Just enqueue function to be processed at nearest occurrence. */
480 node = cgraph_create_node (fndecl);
452aa9c5
RG
481 if (lowered)
482 node->lowered = true;
66058468
JH
483 if (!cgraph_new_nodes)
484 cgraph_new_nodes = cgraph_node_set_new ();
485 cgraph_node_set_add (cgraph_new_nodes, node);
452aa9c5
RG
486 break;
487
488 case CGRAPH_STATE_IPA:
489 case CGRAPH_STATE_IPA_SSA:
490 case CGRAPH_STATE_EXPANSION:
491 /* Bring the function into finalized state and enqueue for later
492 analyzing and compilation. */
493 node = cgraph_get_create_node (fndecl);
494 node->local.local = false;
495 node->local.finalized = true;
93a18a70 496 node->symbol.force_output = true;
452aa9c5
RG
497 if (!lowered && cgraph_state == CGRAPH_STATE_EXPANSION)
498 {
499 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
500 current_function_decl = fndecl;
501 gimple_register_cfg_hooks ();
502 bitmap_obstack_initialize (NULL);
503 execute_pass_list (all_lowering_passes);
504 execute_pass_list (pass_early_local_passes.pass.sub);
505 bitmap_obstack_release (NULL);
506 pop_cfun ();
507 current_function_decl = NULL;
508
509 lowered = true;
510 }
511 if (lowered)
512 node->lowered = true;
66058468
JH
513 if (!cgraph_new_nodes)
514 cgraph_new_nodes = cgraph_node_set_new ();
515 cgraph_node_set_add (cgraph_new_nodes, node);
452aa9c5
RG
516 break;
517
518 case CGRAPH_STATE_FINISHED:
519 /* At the very end of compilation we have to do all the work up
520 to expansion. */
521 node = cgraph_create_node (fndecl);
522 if (lowered)
523 node->lowered = true;
524 cgraph_analyze_function (node);
525 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
526 current_function_decl = fndecl;
527 gimple_register_cfg_hooks ();
528 bitmap_obstack_initialize (NULL);
529 if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
530 execute_pass_list (pass_early_local_passes.pass.sub);
531 bitmap_obstack_release (NULL);
452aa9c5 532 pop_cfun ();
65d630d4 533 expand_function (node);
452aa9c5
RG
534 current_function_decl = NULL;
535 break;
536
537 default:
538 gcc_unreachable ();
539 }
540
541 /* Set a personality if required and we already passed EH lowering. */
542 if (lowered
543 && (function_needs_eh_personality (DECL_STRUCT_FUNCTION (fndecl))
544 == eh_personality_lang))
545 DECL_FUNCTION_PERSONALITY (fndecl) = lang_hooks.eh_personality ();
546}
547
65d630d4
JH
548/* Add a top-level asm statement to the list. */
549
550struct asm_node *
551add_asm_node (tree asm_str)
552{
553 struct asm_node *node;
554
555 node = ggc_alloc_cleared_asm_node ();
556 node->asm_str = asm_str;
557 node->order = symtab_order++;
558 node->next = NULL;
559 if (asm_nodes == NULL)
560 asm_nodes = node;
561 else
562 asm_last_node->next = node;
563 asm_last_node = node;
564 return node;
565}
566
474eccc6
ILT
567/* Output all asm statements we have stored up to be output. */
568
569static void
65d630d4 570output_asm_statements (void)
474eccc6 571{
65d630d4 572 struct asm_node *can;
474eccc6 573
1da2ed5f 574 if (seen_error ())
474eccc6
ILT
575 return;
576
65d630d4 577 for (can = asm_nodes; can; can = can->next)
474eccc6 578 assemble_asm (can->asm_str);
65d630d4
JH
579 asm_nodes = NULL;
580}
581
582/* C++ FE sometimes change linkage flags after producing same body aliases. */
583void
584fixup_same_cpp_alias_visibility (symtab_node node, symtab_node target, tree alias)
585{
586 DECL_VIRTUAL_P (node->symbol.decl) = DECL_VIRTUAL_P (alias);
587 if (TREE_PUBLIC (node->symbol.decl))
588 {
589 DECL_EXTERNAL (node->symbol.decl) = DECL_EXTERNAL (alias);
590 DECL_COMDAT (node->symbol.decl) = DECL_COMDAT (alias);
591 DECL_COMDAT_GROUP (node->symbol.decl) = DECL_COMDAT_GROUP (alias);
592 if (DECL_ONE_ONLY (alias)
593 && !node->symbol.same_comdat_group)
594 symtab_add_to_same_comdat_group ((symtab_node)node, (symtab_node)target);
595 }
474eccc6
ILT
596}
597
e767b5be 598/* Analyze the function scheduled to be output. */
9c8305f8 599static void
e767b5be
JH
600cgraph_analyze_function (struct cgraph_node *node)
601{
a406865a 602 tree save = current_function_decl;
960bfb69 603 tree decl = node->symbol.decl;
9c8305f8
JH
604 location_t saved_loc = input_location;
605 input_location = DECL_SOURCE_LOCATION (decl);
e767b5be 606
39e2db00
JH
607 if (node->alias && node->thunk.alias)
608 {
609 struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias);
5ee770bf
JH
610 struct cgraph_node *n;
611
612 for (n = tgt; n && n->alias;
613 n = n->analyzed ? cgraph_alias_aliased_node (n) : NULL)
614 if (n == node)
615 {
960bfb69 616 error ("function %q+D part of alias cycle", node->symbol.decl);
5ee770bf 617 node->alias = false;
9c8305f8 618 input_location = saved_loc;
5ee770bf
JH
619 return;
620 }
960bfb69 621 if (!VEC_length (ipa_ref_t, node->symbol.ref_list.references))
5932a4d4
JH
622 ipa_record_reference ((symtab_node)node, (symtab_node)tgt,
623 IPA_REF_ALIAS, NULL);
39e2db00
JH
624 if (node->same_body_alias)
625 {
960bfb69 626 DECL_DECLARED_INLINE_P (node->symbol.decl)
39e2db00 627 = DECL_DECLARED_INLINE_P (node->thunk.alias);
960bfb69 628 DECL_DISREGARD_INLINE_LIMITS (node->symbol.decl)
39e2db00 629 = DECL_DISREGARD_INLINE_LIMITS (node->thunk.alias);
65d630d4 630 fixup_same_cpp_alias_visibility ((symtab_node) node, (symtab_node) tgt, node->thunk.alias);
39e2db00
JH
631 }
632
960bfb69 633 if (node->symbol.address_taken)
39e2db00 634 cgraph_mark_address_taken_node (cgraph_alias_aliased_node (node));
39e2db00
JH
635 }
636 else if (node->thunk.thunk_p)
c47d0034
JH
637 {
638 cgraph_create_edge (node, cgraph_get_node (node->thunk.alias),
639 NULL, 0, CGRAPH_FREQ_BASE);
640 }
641 else
642 {
643 current_function_decl = decl;
644 push_cfun (DECL_STRUCT_FUNCTION (decl));
a406865a 645
960bfb69 646 assign_assembler_name_if_neeeded (node->symbol.decl);
0e0a1359 647
c47d0034
JH
648 /* Make sure to gimplify bodies only once. During analyzing a
649 function we lower it, which will require gimplified nested
650 functions, so we can end up here with an already gimplified
651 body. */
355a7673 652 if (!gimple_has_body_p (decl))
c47d0034
JH
653 gimplify_function_tree (decl);
654 dump_function (TDI_generic, decl);
a406865a 655
26eb69c6
RG
656 /* Lower the function. */
657 if (!node->lowered)
658 {
659 if (node->nested)
960bfb69 660 lower_nested_functions (node->symbol.decl);
26eb69c6
RG
661 gcc_assert (!node->nested);
662
663 gimple_register_cfg_hooks ();
664 bitmap_obstack_initialize (NULL);
665 execute_pass_list (all_lowering_passes);
666 free_dominance_info (CDI_POST_DOMINATORS);
667 free_dominance_info (CDI_DOMINATORS);
668 compact_blocks ();
669 bitmap_obstack_release (NULL);
670 node->lowered = true;
671 }
672
c47d0034
JH
673 pop_cfun ();
674 }
6a84c098 675 node->analyzed = true;
e767b5be 676
a406865a 677 current_function_decl = save;
9c8305f8 678 input_location = saved_loc;
e767b5be
JH
679}
680
39e2db00
JH
681/* C++ frontend produce same body aliases all over the place, even before PCH
682 gets streamed out. It relies on us linking the aliases with their function
683 in order to do the fixups, but ipa-ref is not PCH safe. Consequentely we
684 first produce aliases without links, but once C++ FE is sure he won't sream
685 PCH we build the links via this function. */
686
687void
688cgraph_process_same_body_aliases (void)
689{
690 struct cgraph_node *node;
65c70e6b 691 FOR_EACH_FUNCTION (node)
39e2db00 692 if (node->same_body_alias
960bfb69 693 && !VEC_length (ipa_ref_t, node->symbol.ref_list.references))
39e2db00
JH
694 {
695 struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias);
5932a4d4
JH
696 ipa_record_reference ((symtab_node)node, (symtab_node)tgt,
697 IPA_REF_ALIAS, NULL);
39e2db00
JH
698 }
699 same_body_aliases_done = true;
700}
701
768e3c60
RG
702/* Process attributes common for vars and functions. */
703
704static void
705process_common_attributes (tree decl)
706{
707 tree weakref = lookup_attribute ("weakref", DECL_ATTRIBUTES (decl));
708
709 if (weakref && !lookup_attribute ("alias", DECL_ATTRIBUTES (decl)))
710 {
711 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
712 "%<weakref%> attribute should be accompanied with"
713 " an %<alias%> attribute");
714 DECL_WEAK (decl) = 0;
779d4b91
JH
715 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
716 DECL_ATTRIBUTES (decl));
768e3c60
RG
717 }
718}
719
386b46cf
JH
720/* Look for externally_visible and used attributes and mark cgraph nodes
721 accordingly.
722
723 We cannot mark the nodes at the point the attributes are processed (in
724 handle_*_attribute) because the copy of the declarations available at that
725 point may not be canonical. For example, in:
726
727 void f();
728 void f() __attribute__((used));
729
730 the declaration we see in handle_used_attribute will be the second
731 declaration -- but the front end will subsequently merge that declaration
732 with the original declaration and discard the second declaration.
733
734 Furthermore, we can't mark these nodes in cgraph_finalize_function because:
735
736 void f() {}
737 void f() __attribute__((externally_visible));
738
739 is valid.
740
741 So, we walk the nodes at the end of the translation unit, applying the
742 attributes at that point. */
743
744static void
745process_function_and_variable_attributes (struct cgraph_node *first,
8a4a83ed 746 struct varpool_node *first_var)
386b46cf
JH
747{
748 struct cgraph_node *node;
8a4a83ed 749 struct varpool_node *vnode;
386b46cf 750
2aae7680
JH
751 for (node = cgraph_first_function (); node != first;
752 node = cgraph_next_function (node))
386b46cf 753 {
960bfb69 754 tree decl = node->symbol.decl;
b42186f1 755 if (DECL_PRESERVE_P (decl))
ead84f73 756 cgraph_mark_force_output_node (node);
9d602c59 757 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
386b46cf 758 {
960bfb69
JH
759 if (! TREE_PUBLIC (node->symbol.decl))
760 warning_at (DECL_SOURCE_LOCATION (node->symbol.decl), OPT_Wattributes,
c5d75364
MLI
761 "%<externally_visible%>"
762 " attribute have effect only on public objects");
386b46cf 763 }
779d4b91 764 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
39e2db00 765 && (node->local.finalized && !node->alias))
779d4b91 766 {
960bfb69 767 warning_at (DECL_SOURCE_LOCATION (node->symbol.decl), OPT_Wattributes,
779d4b91
JH
768 "%<weakref%> attribute ignored"
769 " because function is defined");
770 DECL_WEAK (decl) = 0;
771 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
772 DECL_ATTRIBUTES (decl));
773 }
c9fc06dc
CB
774
775 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl))
776 && !DECL_DECLARED_INLINE_P (decl)
777 /* redefining extern inline function makes it DECL_UNINLINABLE. */
778 && !DECL_UNINLINABLE (decl))
779 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
780 "always_inline function might not be inlinable");
781
768e3c60 782 process_common_attributes (decl);
386b46cf 783 }
2aae7680
JH
784 for (vnode = varpool_first_variable (); vnode != first_var;
785 vnode = varpool_next_variable (vnode))
386b46cf 786 {
960bfb69 787 tree decl = vnode->symbol.decl;
6649df51
JH
788 if (DECL_EXTERNAL (decl)
789 && DECL_INITIAL (decl)
790 && const_value_known_p (decl))
791 varpool_finalize_decl (decl);
b42186f1 792 if (DECL_PRESERVE_P (decl))
66058468 793 vnode->symbol.force_output = true;
9d602c59 794 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
386b46cf 795 {
960bfb69
JH
796 if (! TREE_PUBLIC (vnode->symbol.decl))
797 warning_at (DECL_SOURCE_LOCATION (vnode->symbol.decl), OPT_Wattributes,
c5d75364
MLI
798 "%<externally_visible%>"
799 " attribute have effect only on public objects");
386b46cf 800 }
779d4b91
JH
801 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
802 && vnode->finalized
803 && DECL_INITIAL (decl))
804 {
960bfb69 805 warning_at (DECL_SOURCE_LOCATION (vnode->symbol.decl), OPT_Wattributes,
779d4b91
JH
806 "%<weakref%> attribute ignored"
807 " because variable is initialized");
808 DECL_WEAK (decl) = 0;
809 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
810 DECL_ATTRIBUTES (decl));
811 }
768e3c60 812 process_common_attributes (decl);
386b46cf
JH
813 }
814}
815
66058468
JH
816/* Mark DECL as finalized. By finalizing the declaration, frontend instruct the
817 middle end to output the variable to asm file, if needed or externally
818 visible. */
819
820void
821varpool_finalize_decl (tree decl)
822{
823 struct varpool_node *node = varpool_node (decl);
824
387df871 825 gcc_assert (TREE_STATIC (decl) || DECL_EXTERNAL (decl));
66058468
JH
826
827 if (node->finalized)
828 return;
829 notice_global_symbol (decl);
830 node->finalized = true;
831 if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
832 /* Traditionally we do not eliminate static variables when not
833 optimizing and when not doing toplevel reoder. */
834 || (!flag_toplevel_reorder && !DECL_COMDAT (node->symbol.decl)
835 && !DECL_ARTIFICIAL (node->symbol.decl)))
836 node->symbol.force_output = true;
837
838 if (cgraph_state == CGRAPH_STATE_CONSTRUCTION
839 && (decide_is_variable_needed (node, decl)
840 || referred_to_p ((symtab_node)node)))
841 enqueue_node ((symtab_node)node);
842 if (cgraph_state >= CGRAPH_STATE_IPA_SSA)
843 varpool_analyze_node (node);
0d6bf48c
JH
844 /* Some frontends produce various interface variables after compilation
845 finished. */
846 if (cgraph_state == CGRAPH_STATE_FINISHED)
847 varpool_assemble_decl (node);
66058468
JH
848}
849
850/* Discover all functions and variables that are trivially needed, analyze
851 them as well as all functions and variables referred by them */
1c4a429a 852
151e6f24
JH
853static void
854cgraph_analyze_functions (void)
1c4a429a 855{
cd9c7bd2 856 /* Keep track of already processed nodes when called multiple times for
aabcd309 857 intermodule optimization. */
cd9c7bd2 858 static struct cgraph_node *first_analyzed;
66058468 859 struct cgraph_node *first_handled = first_analyzed;
8a4a83ed 860 static struct varpool_node *first_analyzed_var;
66058468
JH
861 struct varpool_node *first_handled_var = first_analyzed_var;
862
863 symtab_node node, next;
864 int i;
865 struct ipa_ref *ref;
866 bool changed = true;
1c4a429a 867
1389294c 868 bitmap_obstack_initialize (NULL);
66058468 869 cgraph_state = CGRAPH_STATE_CONSTRUCTION;
1c4a429a 870
66058468
JH
871 /* Analysis adds static variables that in turn adds references to new functions.
872 So we need to iterate the process until it stabilize. */
873 while (changed)
1c4a429a 874 {
66058468
JH
875 changed = false;
876 process_function_and_variable_attributes (first_analyzed,
877 first_analyzed_var);
878
879 /* First identify the trivially needed symbols. */
880 for (node = symtab_nodes;
881 node != (symtab_node)first_analyzed
882 && node != (symtab_node)first_analyzed_var; node = node->symbol.next)
d71cc23f 883 {
66058468
JH
884 if ((symtab_function_p (node)
885 && cgraph (node)->local.finalized
886 && cgraph_decide_is_function_needed (cgraph (node), node->symbol.decl))
887 || (symtab_variable_p (node)
888 && varpool (node)->finalized
889 && !DECL_EXTERNAL (node->symbol.decl)
890 && decide_is_variable_needed (varpool (node), node->symbol.decl)))
891 {
892 enqueue_node (node);
893 if (!changed && cgraph_dump_file)
894 fprintf (cgraph_dump_file, "Trivially needed symbols:");
895 changed = true;
896 if (cgraph_dump_file)
897 fprintf (cgraph_dump_file, " %s", symtab_node_asm_name (node));
898 }
899 if (node == (symtab_node)first_analyzed
900 || node == (symtab_node)first_analyzed_var)
901 break;
d71cc23f 902 }
66058468
JH
903 cgraph_process_new_functions ();
904 first_analyzed_var = varpool_first_variable ();
905 first_analyzed = cgraph_first_function ();
cd4dea62 906
66058468
JH
907 if (changed && dump_file)
908 fprintf (cgraph_dump_file, "\n");
8dafba3c 909
66058468
JH
910 /* Lower representation, build callgraph edges and references for all trivially
911 needed symbols and all symbols referred by them. */
912 while (first != (symtab_node)(void *)1)
b66887e4 913 {
66058468
JH
914 changed = true;
915 node = first;
916 first = (symtab_node)first->symbol.aux;
917 if (symtab_function_p (node) && cgraph (node)->local.finalized)
918 {
919 struct cgraph_edge *edge;
920 struct cgraph_node *cnode;
921 tree decl;
922
923 cnode = cgraph (node);
924 decl = cnode->symbol.decl;
925
926 /* ??? It is possible to create extern inline function and later using
927 weak alias attribute to kill its body. See
928 gcc.c-torture/compile/20011119-1.c */
929 if (!DECL_STRUCT_FUNCTION (decl)
930 && (!cnode->alias || !cnode->thunk.alias)
931 && !cnode->thunk.thunk_p)
932 {
933 cgraph_reset_node (cnode);
934 cnode->local.redefined_extern_inline = true;
935 continue;
936 }
b66887e4 937
66058468
JH
938 if (!cnode->analyzed)
939 cgraph_analyze_function (cnode);
6b20f353 940
66058468 941 for (edge = cnode->callees; edge; edge = edge->next_callee)
93a18a70
JH
942 if (edge->callee->local.finalized)
943 enqueue_node ((symtab_node)edge->callee);
66058468
JH
944
945 /* If decl is a clone of an abstract function, mark that abstract
946 function so that we don't release its body. The DECL_INITIAL() of that
947 abstract function declaration will be later needed to output debug
948 info. */
949 if (DECL_ABSTRACT_ORIGIN (decl))
950 {
951 struct cgraph_node *origin_node;
952 origin_node = cgraph_get_node (DECL_ABSTRACT_ORIGIN (decl));
953 origin_node->abstract_and_needed = true;
954 }
955
956 }
957 else if (symtab_variable_p (node)
958 && varpool (node)->finalized)
93a18a70 959 varpool_analyze_node (varpool (node));
66058468
JH
960
961 if (node->symbol.same_comdat_group)
962 {
963 symtab_node next;
964 for (next = node->symbol.same_comdat_group;
965 next != node;
966 next = next->symbol.same_comdat_group)
967 enqueue_node (next);
968 }
969 for (i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list, i, ref); i++)
970 if ((symtab_function_p (ref->referred) && cgraph (ref->referred)->local.finalized)
971 || (symtab_variable_p (ref->referred) && varpool (ref->referred)->finalized))
972 enqueue_node (ref->referred);
973 cgraph_process_new_functions ();
974 }
1c4a429a 975 }
8dafba3c 976
564738df 977 /* Collect entry points to the unit. */
a194aa56 978 if (cgraph_dump_file)
1668aabc 979 {
7d82fe7c 980 fprintf (cgraph_dump_file, "\n\nInitial ");
8f940ee6 981 dump_symtab (cgraph_dump_file);
1668aabc 982 }
7660e67e 983
a194aa56 984 if (cgraph_dump_file)
66058468 985 fprintf (cgraph_dump_file, "\nRemoving unused symbols:");
1c4a429a 986
66058468
JH
987 for (node = symtab_nodes;
988 node != (symtab_node)first_handled
989 && node != (symtab_node)first_handled_var; node = next)
1c4a429a 990 {
66058468
JH
991 next = node->symbol.next;
992 if (!node->symbol.aux && !referred_to_p (node))
1c4a429a 993 {
a194aa56 994 if (cgraph_dump_file)
66058468
JH
995 fprintf (cgraph_dump_file, " %s", symtab_node_name (node));
996 symtab_remove_node (node);
d71cc23f 997 continue;
1c4a429a 998 }
66058468
JH
999 if (symtab_function_p (node))
1000 {
1001 tree decl = node->symbol.decl;
1002 struct cgraph_node *cnode = cgraph (node);
1003
1004 if (cnode->local.finalized && !gimple_has_body_p (decl)
1005 && (!cnode->alias || !cnode->thunk.alias)
1006 && !cnode->thunk.thunk_p)
1007 cgraph_reset_node (cnode);
1008
1009 gcc_assert (!cnode->local.finalized || cnode->thunk.thunk_p
1010 || cnode->alias
1011 || gimple_has_body_p (decl));
1012 gcc_assert (cnode->analyzed == cnode->local.finalized);
1013 }
1014 node->symbol.aux = NULL;
1c4a429a 1015 }
66058468
JH
1016 first_analyzed = cgraph_first_function ();
1017 first_analyzed_var = varpool_first_variable ();
a194aa56 1018 if (cgraph_dump_file)
7d82fe7c
KC
1019 {
1020 fprintf (cgraph_dump_file, "\n\nReclaimed ");
8f940ee6 1021 dump_symtab (cgraph_dump_file);
7d82fe7c 1022 }
1389294c 1023 bitmap_obstack_release (NULL);
1c4a429a 1024 ggc_collect ();
151e6f24
JH
1025}
1026
85ce9375
JH
1027/* Translate the ugly representation of aliases as alias pairs into nice
1028 representation in callgraph. We don't handle all cases yet,
1029 unforutnately. */
1030
1031static void
1032handle_alias_pairs (void)
1033{
1034 alias_pair *p;
1035 unsigned i;
85ce9375
JH
1036
1037 for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p);)
1038 {
38e55ac9
JH
1039 symtab_node target_node = symtab_node_for_asm (p->target);
1040
25e2c40d
JH
1041 /* Weakrefs with target not defined in current unit are easy to handle; they
1042 behave just as external variables except we need to note the alias flag
1043 to later output the weakref pseudo op into asm file. */
38e55ac9 1044 if (!target_node && lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL)
25e2c40d
JH
1045 {
1046 if (TREE_CODE (p->decl) == FUNCTION_DECL)
1047 cgraph_get_create_node (p->decl)->alias = true;
1048 else
1049 varpool_get_node (p->decl)->alias = true;
1050 DECL_EXTERNAL (p->decl) = 1;
1051 VEC_unordered_remove (alias_pair, alias_pairs, i);
38e55ac9 1052 continue;
25e2c40d 1053 }
38e55ac9 1054 else if (!target_node)
85ce9375 1055 {
38e55ac9
JH
1056 error ("%q+D aliased to undefined symbol %qE", p->decl, p->target);
1057 VEC_unordered_remove (alias_pair, alias_pairs, i);
1058 continue;
1059 }
1060
1061 /* Normally EXTERNAL flag is used to mark external inlines,
1062 however for aliases it seems to be allowed to use it w/o
1063 any meaning. See gcc.dg/attr-alias-3.c
1064 However for weakref we insist on EXTERNAL flag being set.
1065 See gcc.dg/attr-alias-5.c */
1066 if (DECL_EXTERNAL (p->decl))
1067 DECL_EXTERNAL (p->decl)
1068 = lookup_attribute ("weakref",
1069 DECL_ATTRIBUTES (p->decl)) != NULL;
85ce9375 1070
38e55ac9
JH
1071 if (TREE_CODE (p->decl) == FUNCTION_DECL
1072 && target_node && symtab_function_p (target_node))
1073 {
1074 struct cgraph_node *src_node = cgraph_get_node (p->decl);
1075 if (src_node && src_node->local.finalized)
1076 cgraph_reset_node (src_node);
1077 cgraph_create_function_alias (p->decl, target_node->symbol.decl);
1078 VEC_unordered_remove (alias_pair, alias_pairs, i);
1079 }
1080 else if (TREE_CODE (p->decl) == VAR_DECL
1081 && target_node && symtab_variable_p (target_node))
1082 {
1083 varpool_create_variable_alias (p->decl, target_node->symbol.decl);
1084 VEC_unordered_remove (alias_pair, alias_pairs, i);
1085 }
1086 else
1087 {
1088 error ("%q+D alias in between function and variable is not supported",
1089 p->decl);
1090 warning (0, "%q+D aliased declaration",
1091 target_node->symbol.decl);
1092 VEC_unordered_remove (alias_pair, alias_pairs, i);
85ce9375
JH
1093 }
1094 }
877ab5e9 1095 VEC_free (alias_pair, gc, alias_pairs);
85ce9375
JH
1096}
1097
5f1a9ebb 1098
1c4a429a
JH
1099/* Figure out what functions we want to assemble. */
1100
1101static void
65d630d4 1102mark_functions_to_output (void)
1c4a429a
JH
1103{
1104 struct cgraph_node *node;
b66887e4
JJ
1105#ifdef ENABLE_CHECKING
1106 bool check_same_comdat_groups = false;
1107
65c70e6b 1108 FOR_EACH_FUNCTION (node)
b66887e4
JJ
1109 gcc_assert (!node->process);
1110#endif
1c4a429a 1111
65c70e6b 1112 FOR_EACH_FUNCTION (node)
1c4a429a 1113 {
960bfb69 1114 tree decl = node->symbol.decl;
c22cacf3 1115
960bfb69 1116 gcc_assert (!node->process || node->symbol.same_comdat_group);
b66887e4
JJ
1117 if (node->process)
1118 continue;
b58b1157 1119
7660e67e
SB
1120 /* We need to output all local functions that are used and not
1121 always inlined, as well as those that are reachable from
1122 outside the current compilation unit. */
39ecc018 1123 if (node->analyzed
c47d0034 1124 && !node->thunk.thunk_p
39e2db00 1125 && !node->alias
18c6ada9 1126 && !node->global.inlined_to
6de9cd9a 1127 && !TREE_ASM_WRITTEN (decl)
1c4a429a 1128 && !DECL_EXTERNAL (decl))
b66887e4
JJ
1129 {
1130 node->process = 1;
960bfb69 1131 if (node->symbol.same_comdat_group)
b66887e4
JJ
1132 {
1133 struct cgraph_node *next;
960bfb69 1134 for (next = cgraph (node->symbol.same_comdat_group);
b66887e4 1135 next != node;
960bfb69 1136 next = cgraph (next->symbol.same_comdat_group))
39e2db00 1137 if (!next->thunk.thunk_p && !next->alias)
c47d0034 1138 next->process = 1;
b66887e4
JJ
1139 }
1140 }
960bfb69 1141 else if (node->symbol.same_comdat_group)
b66887e4
JJ
1142 {
1143#ifdef ENABLE_CHECKING
1144 check_same_comdat_groups = true;
1145#endif
1146 }
341c100f 1147 else
1a2caa7a
NS
1148 {
1149 /* We should've reclaimed all functions that are not needed. */
1150#ifdef ENABLE_CHECKING
726a989a 1151 if (!node->global.inlined_to
39ecc018 1152 && gimple_has_body_p (decl)
a837268b
JH
1153 /* FIXME: in ltrans unit when offline copy is outside partition but inline copies
1154 are inside partition, we can end up not removing the body since we no longer
1155 have analyzed node pointing to it. */
960bfb69 1156 && !node->symbol.in_other_partition
39e2db00 1157 && !node->alias
387df871 1158 && !node->clones
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);
3828719a 1214 init_ssa_operands (cfun);
6744a6ab
JH
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"