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