]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/cgraphunit.c
mksysinfo: More fixes to emulate master Go library.
[thirdparty/gcc.git] / gcc / cgraphunit.c
CommitLineData
a418679d 1/* Callgraph based interprocedural optimizations.
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
18c6ada9 22/* This module implements main driver of compilation process as well as
a418679d 23 few basic interprocedural optimizers.
18c6ada9
JH
24
25 The main scope of this file is to act as an interface in between
26 tree based frontends and the backend (and middle end)
27
28 The front-end is supposed to use following functionality:
29
30 - cgraph_finalize_function
31
32 This function is called once front-end has parsed whole body of function
33 and it is certain that the function body nor the declaration will change.
34
efe75b6f
JH
35 (There is one exception needed for implementing GCC extern inline
36 function.)
18c6ada9 37
8a4a83ed 38 - varpool_finalize_variable
18c6ada9 39
1ae58c30 40 This function has same behavior as the above but is used for static
18c6ada9
JH
41 variables.
42
43 - cgraph_finalize_compilation_unit
44
efe75b6f
JH
45 This function is called once (source level) compilation unit is finalized
46 and it will no longer change.
18c6ada9 47
dd5a833e
MS
48 In the call-graph construction and local function analysis takes
49 place here. Bodies of unreachable functions are released to
50 conserve memory usage.
18c6ada9 51
efe75b6f
JH
52 The function can be called multiple times when multiple source level
53 compilation units are combined (such as in C frontend)
18c6ada9
JH
54
55 - cgraph_optimize
56
57 In this unit-at-a-time compilation the intra procedural analysis takes
58 place here. In particular the static functions whose address is never
59 taken are marked as local. Backend can then use this information to
60 modify calling conventions, do better inlining or similar optimizations.
61
18c6ada9 62 - cgraph_mark_needed_node
8a4a83ed 63 - varpool_mark_needed_node
18c6ada9 64
efe75b6f
JH
65 When function or variable is referenced by some hidden way the call-graph
66 data structure must be updated accordingly by this function.
67 There should be little need to call this function and all the references
68 should be made explicit to cgraph code. At present these functions are
dbb23ff7 69 used by C++ frontend to explicitly mark the keyed methods.
18c6ada9
JH
70
71 - analyze_expr callback
72
73 This function is responsible for lowering tree nodes not understood by
74 generic code into understandable ones or alternatively marking
75 callgraph and varpool nodes referenced by the as needed.
76
77 ??? On the tree-ssa genericizing should take place here and we will avoid
78 need for these hooks (replacing them by genericizing hook)
79
7e8b322a 80 Analyzing of all functions is deferred
18c6ada9
JH
81 to cgraph_finalize_compilation_unit and expansion into cgraph_optimize.
82
83 In cgraph_finalize_compilation_unit the reachable functions are
84 analyzed. During analysis the call-graph edges from reachable
85 functions are constructed and their destinations are marked as
86 reachable. References to functions and variables are discovered too
87 and variables found to be needed output to the assembly file. Via
88 mark_referenced call in assemble_variable functions referenced by
89 static variables are noticed too.
90
e1990f69 91 The intra-procedural information is produced and its existence
18c6ada9
JH
92 indicated by global_info_ready. Once this flag is set it is impossible
93 to change function from !reachable to reachable and thus
94 assemble_variable no longer call mark_referenced.
95
96 Finally the call-graph is topologically sorted and all reachable functions
97 that has not been completely inlined or are not external are output.
98
99 ??? It is possible that reference to function or variable is optimized
100 out. We can not deal with this nicely because topological order is not
101 suitable for it. For tree-ssa we may consider another pass doing
102 optimization and re-discovering reachable functions.
103
104 ??? Reorganize code so variables are output very last and only if they
105 really has been referenced by produced code, so we catch more cases
7e8b322a 106 where reference has been optimized out. */
9b3e897d 107
6674a6ce 108
1c4a429a
JH
109#include "config.h"
110#include "system.h"
111#include "coretypes.h"
112#include "tm.h"
113#include "tree.h"
0878843f 114#include "output.h"
c9b9aa64 115#include "rtl.h"
6674a6ce 116#include "tree-flow.h"
1c4a429a
JH
117#include "tree-inline.h"
118#include "langhooks.h"
0c58f841 119#include "pointer-set.h"
1c4a429a
JH
120#include "toplev.h"
121#include "flags.h"
122#include "ggc.h"
123#include "debug.h"
124#include "target.h"
125#include "cgraph.h"
dafc5b82 126#include "diagnostic.h"
cf835838
JM
127#include "tree-pretty-print.h"
128#include "gimple-pretty-print.h"
a194aa56 129#include "timevar.h"
b58b1157
JH
130#include "params.h"
131#include "fibheap.h"
dc0bfe6a 132#include "intl.h"
902edd36 133#include "function.h"
57fb5341 134#include "ipa-prop.h"
726a989a
RB
135#include "gimple.h"
136#include "tree-iterator.h"
b4861090 137#include "tree-pass.h"
a406865a 138#include "tree-dump.h"
cd9c7bd2 139#include "output.h"
3baf459d 140#include "coverage.h"
090fa0ab 141#include "plugin.h"
632b4f8e 142#include "ipa-inline.h"
af8bca3c 143#include "ipa-utils.h"
47c79d56 144#include "lto-streamer.h"
452aa9c5 145#include "except.h"
0878843f 146#include "regset.h" /* FIXME: For reg_obstack. */
b58b1157 147
a20af5b8 148static void cgraph_expand_all_functions (void);
db0e878d
AJ
149static void cgraph_mark_functions_to_output (void);
150static void cgraph_expand_function (struct cgraph_node *);
21c4a6a7 151static void cgraph_output_pending_asms (void);
452aa9c5 152static void tree_rest_of_compilation (struct cgraph_node *);
7dff32e6 153
0a5fa5a1 154FILE *cgraph_dump_file;
9b3e897d 155
6744a6ab
JH
156/* Used for vtable lookup in thunk adjusting. */
157static GTY (()) tree vtable_entry_type;
158
ead84f73
JH
159/* Determine if function DECL is trivially needed and should stay in the
160 compilation unit. This is used at the symbol table construction time
161 and differs from later logic removing unnecesary functions that can
162 take into account results of analysis, whole program info etc. */
8dafba3c 163
d7f09764
DN
164bool
165cgraph_decide_is_function_needed (struct cgraph_node *node, tree decl)
8dafba3c 166{
e7d6beb0 167 /* If the user told us it is used, then it must be so. */
ead84f73 168 if (node->symbol.force_output)
386b46cf
JH
169 return true;
170
ead84f73
JH
171 /* Double check that no one output the function into assembly file
172 early. */
173 gcc_checking_assert (!DECL_ASSEMBLER_NAME_SET_P (decl)
174 || (node->thunk.thunk_p || node->same_body_alias)
175 || !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)));
e7d6beb0 176
a1d31187 177
ead84f73
JH
178 /* Keep constructors, destructors and virtual functions. */
179 if (DECL_STATIC_CONSTRUCTOR (decl)
180 || DECL_STATIC_DESTRUCTOR (decl)
181 || (DECL_VIRTUAL_P (decl)
182 && optimize && (DECL_COMDAT (decl) || DECL_EXTERNAL (decl))))
183 return true;
8dafba3c
RH
184
185 /* Externally visible functions must be output. The exception is
ead84f73 186 COMDAT functions that must be output only when they are needed. */
04f77d0f 187
ead84f73 188 if (TREE_PUBLIC (decl)
ce91e74c 189 && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
8dafba3c
RH
190 return true;
191
8dafba3c
RH
192 return false;
193}
194
d60ab196 195/* Process CGRAPH_NEW_FUNCTIONS and perform actions necessary to add these
f45e0ad1
JH
196 functions into callgraph in a way so they look like ordinary reachable
197 functions inserted into callgraph already at construction time. */
198
199bool
200cgraph_process_new_functions (void)
201{
202 bool output = false;
203 tree fndecl;
204 struct cgraph_node *node;
205
2942c502 206 varpool_analyze_pending_decls ();
f45e0ad1
JH
207 /* Note that this queue may grow as its being processed, as the new
208 functions may generate new ones. */
209 while (cgraph_new_nodes)
210 {
211 node = cgraph_new_nodes;
960bfb69 212 fndecl = node->symbol.decl;
f45e0ad1
JH
213 cgraph_new_nodes = cgraph_new_nodes->next_needed;
214 switch (cgraph_state)
215 {
216 case CGRAPH_STATE_CONSTRUCTION:
217 /* At construction time we just need to finalize function and move
218 it into reachable functions list. */
219
220 node->next_needed = NULL;
221 cgraph_finalize_function (fndecl, false);
222 cgraph_mark_reachable_node (node);
223 output = true;
4d5dcfb2 224 cgraph_call_function_insertion_hooks (node);
f45e0ad1
JH
225 break;
226
227 case CGRAPH_STATE_IPA:
7a388ee4 228 case CGRAPH_STATE_IPA_SSA:
f45e0ad1
JH
229 /* When IPA optimization already started, do all essential
230 transformations that has been already performed on the whole
231 cgraph but not on this function. */
232
726a989a 233 gimple_register_cfg_hooks ();
f45e0ad1
JH
234 if (!node->analyzed)
235 cgraph_analyze_function (node);
236 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
237 current_function_decl = fndecl;
7a388ee4
JH
238 if ((cgraph_state == CGRAPH_STATE_IPA_SSA
239 && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
240 /* When not optimizing, be sure we run early local passes anyway
241 to expand OMP. */
242 || !optimize)
8ddbbcae 243 execute_pass_list (pass_early_local_passes.pass.sub);
bb7e6d55 244 else
632b4f8e 245 compute_inline_parameters (node, true);
f45e0ad1
JH
246 free_dominance_info (CDI_POST_DOMINATORS);
247 free_dominance_info (CDI_DOMINATORS);
248 pop_cfun ();
249 current_function_decl = NULL;
4d5dcfb2 250 cgraph_call_function_insertion_hooks (node);
f45e0ad1
JH
251 break;
252
253 case CGRAPH_STATE_EXPANSION:
254 /* Functions created during expansion shall be compiled
255 directly. */
257eb6e3 256 node->process = 0;
4d5dcfb2 257 cgraph_call_function_insertion_hooks (node);
f45e0ad1
JH
258 cgraph_expand_function (node);
259 break;
260
261 default:
262 gcc_unreachable ();
263 break;
264 }
2942c502 265 varpool_analyze_pending_decls ();
f45e0ad1
JH
266 }
267 return output;
268}
269
d71cc23f
JH
270/* As an GCC extension we allow redefinition of the function. The
271 semantics when both copies of bodies differ is not well defined.
272 We replace the old body with new body so in unit at a time mode
273 we always use new body, while in normal mode we may end up with
274 old body inlined into some functions and new body expanded and
275 inlined in others.
276
277 ??? It may make more sense to use one body for inlining and other
278 body for expanding the function but this is difficult to do. */
279
280static void
281cgraph_reset_node (struct cgraph_node *node)
282{
257eb6e3 283 /* If node->process is set, then we have already begun whole-unit analysis.
7e8b322a
JH
284 This is *not* testing for whether we've already emitted the function.
285 That case can be sort-of legitimately seen with real function redefinition
286 errors. I would argue that the front end should never present us with
287 such a case, but don't enforce that for now. */
257eb6e3 288 gcc_assert (!node->process);
d71cc23f
JH
289
290 /* Reset our data structures so we can analyze the function again. */
291 memset (&node->local, 0, sizeof (node->local));
292 memset (&node->global, 0, sizeof (node->global));
293 memset (&node->rtl, 0, sizeof (node->rtl));
294 node->analyzed = false;
d71cc23f
JH
295 node->local.finalized = false;
296
d71cc23f 297 cgraph_node_remove_callees (node);
d71cc23f 298}
d853a20e 299
6b00c969
RH
300/* DECL has been parsed. Take it, queue it, compile it at the whim of the
301 logic in effect. If NESTED is true, then our caller cannot stand to have
302 the garbage collector run at the moment. We would need to either create
303 a new GC context, or just not compile right now. */
1c4a429a
JH
304
305void
6b00c969 306cgraph_finalize_function (tree decl, bool nested)
1c4a429a 307{
a358e188 308 struct cgraph_node *node = cgraph_get_create_node (decl);
1c4a429a 309
d853a20e 310 if (node->local.finalized)
b125ad45
JH
311 {
312 cgraph_reset_node (node);
313 node->local.redefined_extern_inline = true;
314 }
6b00c969 315
d853a20e 316 notice_global_symbol (decl);
f6981e16 317 node->local.finalized = true;
e21aff8a 318 node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL;
1c4a429a 319
ead84f73
JH
320 /* With -fkeep-inline-functions we are keeping all inline functions except
321 for extern inline ones. */
322 if (flag_keep_inline_functions
323 && DECL_DECLARED_INLINE_P (decl)
324 && !DECL_EXTERNAL (decl)
325 && !DECL_DISREGARD_INLINE_LIMITS (decl))
326 node->symbol.force_output = 1;
8dafba3c 327
ead84f73
JH
328 /* When not optimizing, also output the static functions. (see
329 PR24561), but don't do so for always_inline functions, functions
330 declared inline and nested functions. These were optimized out
331 in the original implementation and it is unclear whether we want
332 to change the behavior here. */
333 if ((!optimize
334 && !node->same_body_alias
335 && !DECL_DISREGARD_INLINE_LIMITS (decl)
336 && !DECL_DECLARED_INLINE_P (decl)
337 && !(DECL_CONTEXT (decl)
338 && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL))
339 && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
340 node->symbol.force_output = 1;
341
342 if (cgraph_decide_is_function_needed (node, decl))
e7d6beb0
JH
343 cgraph_mark_reachable_node (node);
344
8dafba3c 345 /* If we've not yet emitted decl, tell the debug info about it. */
6b00c969 346 if (!TREE_ASM_WRITTEN (decl))
8dafba3c 347 (*debug_hooks->deferred_inline_function) (decl);
d173e685 348
902edd36
JH
349 /* Possibly warn about unused parameters. */
350 if (warn_unused_parameter)
351 do_warn_unused_parameter (decl);
7e8b322a
JH
352
353 if (!nested)
354 ggc_collect ();
1c4a429a
JH
355}
356
452aa9c5
RG
357/* Add the function FNDECL to the call graph.
358 Unlike cgraph_finalize_function, this function is intended to be used
359 by middle end and allows insertion of new function at arbitrary point
360 of compilation. The function can be either in high, low or SSA form
361 GIMPLE.
362
363 The function is assumed to be reachable and have address taken (so no
364 API breaking optimizations are performed on it).
365
366 Main work done by this function is to enqueue the function for later
367 processing to avoid need the passes to be re-entrant. */
368
369void
370cgraph_add_new_function (tree fndecl, bool lowered)
371{
372 struct cgraph_node *node;
373 switch (cgraph_state)
374 {
375 case CGRAPH_STATE_CONSTRUCTION:
376 /* Just enqueue function to be processed at nearest occurrence. */
377 node = cgraph_create_node (fndecl);
378 node->next_needed = cgraph_new_nodes;
379 if (lowered)
380 node->lowered = true;
381 cgraph_new_nodes = node;
382 break;
383
384 case CGRAPH_STATE_IPA:
385 case CGRAPH_STATE_IPA_SSA:
386 case CGRAPH_STATE_EXPANSION:
387 /* Bring the function into finalized state and enqueue for later
388 analyzing and compilation. */
389 node = cgraph_get_create_node (fndecl);
390 node->local.local = false;
391 node->local.finalized = true;
ead84f73 392 node->reachable = node->symbol.force_output = true;
452aa9c5
RG
393 if (!lowered && cgraph_state == CGRAPH_STATE_EXPANSION)
394 {
395 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
396 current_function_decl = fndecl;
397 gimple_register_cfg_hooks ();
398 bitmap_obstack_initialize (NULL);
399 execute_pass_list (all_lowering_passes);
400 execute_pass_list (pass_early_local_passes.pass.sub);
401 bitmap_obstack_release (NULL);
402 pop_cfun ();
403 current_function_decl = NULL;
404
405 lowered = true;
406 }
407 if (lowered)
408 node->lowered = true;
409 node->next_needed = cgraph_new_nodes;
410 cgraph_new_nodes = node;
411 break;
412
413 case CGRAPH_STATE_FINISHED:
414 /* At the very end of compilation we have to do all the work up
415 to expansion. */
416 node = cgraph_create_node (fndecl);
417 if (lowered)
418 node->lowered = true;
419 cgraph_analyze_function (node);
420 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
421 current_function_decl = fndecl;
422 gimple_register_cfg_hooks ();
423 bitmap_obstack_initialize (NULL);
424 if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
425 execute_pass_list (pass_early_local_passes.pass.sub);
426 bitmap_obstack_release (NULL);
427 tree_rest_of_compilation (node);
428 pop_cfun ();
429 current_function_decl = NULL;
430 break;
431
432 default:
433 gcc_unreachable ();
434 }
435
436 /* Set a personality if required and we already passed EH lowering. */
437 if (lowered
438 && (function_needs_eh_personality (DECL_STRUCT_FUNCTION (fndecl))
439 == eh_personality_lang))
440 DECL_FUNCTION_PERSONALITY (fndecl) = lang_hooks.eh_personality ();
441}
442
f0c882ab
JH
443/* C99 extern inline keywords allow changing of declaration after function
444 has been finalized. We need to re-decide if we want to mark the function as
445 needed then. */
446
447void
448cgraph_mark_if_needed (tree decl)
449{
581985d7 450 struct cgraph_node *node = cgraph_get_node (decl);
d7f09764 451 if (node->local.finalized && cgraph_decide_is_function_needed (node, decl))
ead84f73 452 cgraph_mark_reachable_node (node);
f0c882ab
JH
453}
454
9187e02d
JH
455/* Return TRUE if NODE2 is equivalent to NODE or its clone. */
456static bool
457clone_of_p (struct cgraph_node *node, struct cgraph_node *node2)
458{
39e2db00
JH
459 node = cgraph_function_or_thunk_node (node, NULL);
460 node2 = cgraph_function_or_thunk_node (node2, NULL);
9187e02d
JH
461 while (node != node2 && node2)
462 node2 = node2->clone_of;
463 return node2 != NULL;
464}
465
02ec6988
MJ
466/* Verify edge E count and frequency. */
467
468static bool
469verify_edge_count_and_frequency (struct cgraph_edge *e)
470{
471 bool error_found = false;
472 if (e->count < 0)
473 {
474 error ("caller edge count is negative");
475 error_found = true;
476 }
477 if (e->frequency < 0)
478 {
479 error ("caller edge frequency is negative");
480 error_found = true;
481 }
482 if (e->frequency > CGRAPH_FREQ_MAX)
483 {
484 error ("caller edge frequency is too large");
485 error_found = true;
486 }
960bfb69 487 if (gimple_has_body_p (e->caller->symbol.decl)
02ec6988 488 && !e->caller->global.inlined_to
74605a11
JH
489 /* FIXME: Inline-analysis sets frequency to 0 when edge is optimized out.
490 Remove this once edges are actualy removed from the function at that time. */
491 && (e->frequency
492 || (inline_edge_summary_vec
4762f561
JH
493 && ((VEC_length(inline_edge_summary_t, inline_edge_summary_vec)
494 <= (unsigned) e->uid)
495 || !inline_edge_summary (e)->predicate)))
02ec6988 496 && (e->frequency
960bfb69 497 != compute_call_stmt_bb_frequency (e->caller->symbol.decl,
02ec6988
MJ
498 gimple_bb (e->call_stmt))))
499 {
61502ca8 500 error ("caller edge frequency %i does not match BB frequency %i",
02ec6988 501 e->frequency,
960bfb69 502 compute_call_stmt_bb_frequency (e->caller->symbol.decl,
02ec6988
MJ
503 gimple_bb (e->call_stmt)));
504 error_found = true;
505 }
506 return error_found;
507}
508
89843f5d
JJ
509/* Switch to THIS_CFUN if needed and print STMT to stderr. */
510static void
511cgraph_debug_gimple_stmt (struct function *this_cfun, gimple stmt)
512{
513 /* debug_gimple_stmt needs correct cfun */
514 if (cfun != this_cfun)
515 set_cfun (this_cfun);
516 debug_gimple_stmt (stmt);
517}
518
81361831
MJ
519/* Verify that call graph edge E corresponds to DECL from the associated
520 statement. Return true if the verification should fail. */
521
522static bool
523verify_edge_corresponds_to_fndecl (struct cgraph_edge *e, tree decl)
524{
b75d1e21
MJ
525 struct cgraph_node *node;
526
527 if (!decl || e->callee->global.inlined_to)
528 return false;
529 node = cgraph_get_node (decl);
530
531 /* We do not know if a node from a different partition is an alias or what it
532 aliases and therefore cannot do the former_clone_of check reliably. */
960bfb69 533 if (!node || node->symbol.in_other_partition)
b75d1e21
MJ
534 return false;
535 node = cgraph_function_or_thunk_node (node, NULL);
536
960bfb69 537 if ((e->callee->former_clone_of != node->symbol.decl
183d6db2
JJ
538 && (!node->same_body_alias
539 || e->callee->former_clone_of != node->thunk.alias))
81361831 540 /* IPA-CP sometimes redirect edge to clone and then back to the former
183d6db2 541 function. This ping-pong has to go, eventually. */
b75d1e21 542 && (node != cgraph_function_or_thunk_node (e->callee, NULL))
183d6db2
JJ
543 && !clone_of_p (node, e->callee)
544 /* If decl is a same body alias of some other decl, allow e->callee to be
545 a clone of a clone of that other decl too. */
546 && (!node->same_body_alias
547 || !clone_of_p (cgraph_get_node (node->thunk.alias), e->callee)))
81361831
MJ
548 return true;
549 else
550 return false;
551}
552
18c6ada9 553/* Verify cgraph nodes of given cgraph node. */
24e47c76 554DEBUG_FUNCTION void
18c6ada9
JH
555verify_cgraph_node (struct cgraph_node *node)
556{
557 struct cgraph_edge *e;
960bfb69 558 struct function *this_cfun = DECL_STRUCT_FUNCTION (node->symbol.decl);
e21aff8a 559 basic_block this_block;
726a989a 560 gimple_stmt_iterator gsi;
e0704a46 561 bool error_found = false;
18c6ada9 562
1da2ed5f 563 if (seen_error ())
5771bd91
RG
564 return;
565
18c6ada9 566 timevar_push (TV_CGRAPH_VERIFY);
474ffc72 567 error_found |= verify_symtab_base ((symtab_node) node);
18c6ada9
JH
568 for (e = node->callees; e; e = e->next_callee)
569 if (e->aux)
570 {
ab532386 571 error ("aux field set for edge %s->%s",
4f1e4960
JM
572 identifier_to_locale (cgraph_node_name (e->caller)),
573 identifier_to_locale (cgraph_node_name (e->callee)));
18c6ada9
JH
574 error_found = true;
575 }
06191a23
JH
576 if (node->count < 0)
577 {
d8a07487 578 error ("execution count is negative");
06191a23
JH
579 error_found = true;
580 }
960bfb69 581 if (node->global.inlined_to && node->symbol.externally_visible)
b20996ff 582 {
d8a07487 583 error ("externally visible inline clone");
b20996ff
JH
584 error_found = true;
585 }
960bfb69 586 if (node->global.inlined_to && node->symbol.address_taken)
b20996ff 587 {
d8a07487 588 error ("inline clone with address taken");
b20996ff
JH
589 error_found = true;
590 }
ead84f73 591 if (node->global.inlined_to && node->symbol.force_output)
b20996ff 592 {
ead84f73 593 error ("inline clone is forced to output");
b20996ff
JH
594 error_found = true;
595 }
e33c6cd6
MJ
596 for (e = node->indirect_calls; e; e = e->next_callee)
597 {
598 if (e->aux)
599 {
600 error ("aux field set for indirect edge from %s",
601 identifier_to_locale (cgraph_node_name (e->caller)));
602 error_found = true;
603 }
604 if (!e->indirect_unknown_callee
605 || !e->indirect_info)
606 {
607 error ("An indirect edge from %s is not marked as indirect or has "
608 "associated indirect_info, the corresponding statement is: ",
609 identifier_to_locale (cgraph_node_name (e->caller)));
89843f5d 610 cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
e33c6cd6
MJ
611 error_found = true;
612 }
613 }
18c6ada9
JH
614 for (e = node->callers; e; e = e->next_caller)
615 {
02ec6988
MJ
616 if (verify_edge_count_and_frequency (e))
617 error_found = true;
18c6ada9
JH
618 if (!e->inline_failed)
619 {
620 if (node->global.inlined_to
621 != (e->caller->global.inlined_to
622 ? e->caller->global.inlined_to : e->caller))
623 {
ab532386 624 error ("inlined_to pointer is wrong");
18c6ada9
JH
625 error_found = true;
626 }
627 if (node->callers->next_caller)
628 {
ab532386 629 error ("multiple inline callers");
18c6ada9
JH
630 error_found = true;
631 }
632 }
633 else
634 if (node->global.inlined_to)
635 {
ab532386 636 error ("inlined_to pointer set for noninline callers");
18c6ada9
JH
637 error_found = true;
638 }
639 }
02ec6988
MJ
640 for (e = node->indirect_calls; e; e = e->next_callee)
641 if (verify_edge_count_and_frequency (e))
642 error_found = true;
18c6ada9
JH
643 if (!node->callers && node->global.inlined_to)
644 {
95a52ebb 645 error ("inlined_to pointer is set but no predecessors found");
18c6ada9
JH
646 error_found = true;
647 }
648 if (node->global.inlined_to == node)
649 {
ab532386 650 error ("inlined_to pointer refers to itself");
18c6ada9
JH
651 error_found = true;
652 }
653
9187e02d
JH
654 if (node->clone_of)
655 {
656 struct cgraph_node *n;
657 for (n = node->clone_of->clones; n; n = n->next_sibling_clone)
658 if (n == node)
659 break;
660 if (!n)
661 {
662 error ("node has wrong clone_of");
663 error_found = true;
664 }
665 }
666 if (node->clones)
667 {
668 struct cgraph_node *n;
669 for (n = node->clones; n; n = n->next_sibling_clone)
670 if (n->clone_of != node)
671 break;
672 if (n)
673 {
674 error ("node has wrong clone list");
675 error_found = true;
676 }
677 }
678 if ((node->prev_sibling_clone || node->next_sibling_clone) && !node->clone_of)
679 {
680 error ("node is in clone list but it is not clone");
681 error_found = true;
682 }
683 if (!node->prev_sibling_clone && node->clone_of && node->clone_of->clones != node)
684 {
685 error ("node has wrong prev_clone pointer");
686 error_found = true;
687 }
688 if (node->prev_sibling_clone && node->prev_sibling_clone->next_sibling_clone != node)
689 {
690 error ("double linked list of clones corrupted");
691 error_found = true;
692 }
693
39e2db00
JH
694 if (node->analyzed && node->alias)
695 {
696 bool ref_found = false;
697 int i;
698 struct ipa_ref *ref;
699
700 if (node->callees)
701 {
702 error ("Alias has call edges");
703 error_found = true;
704 }
960bfb69
JH
705 for (i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list,
706 i, ref); i++)
39e2db00
JH
707 if (ref->use != IPA_REF_ALIAS)
708 {
cc8b9c31 709 error ("Alias has non-alias reference");
39e2db00
JH
710 error_found = true;
711 }
712 else if (ref_found)
713 {
714 error ("Alias has more than one alias reference");
715 error_found = true;
716 }
717 else
718 ref_found = true;
719 if (!ref_found)
720 {
721 error ("Analyzed alias has no reference");
722 error_found = true;
723 }
724 }
c47d0034
JH
725 if (node->analyzed && node->thunk.thunk_p)
726 {
727 if (!node->callees)
728 {
729 error ("No edge out of thunk node");
730 error_found = true;
731 }
732 else if (node->callees->next_callee)
733 {
734 error ("More than one edge out of thunk node");
735 error_found = true;
736 }
960bfb69 737 if (gimple_has_body_p (node->symbol.decl))
c47d0034
JH
738 {
739 error ("Thunk is not supposed to have body");
740 error_found = true;
741 }
742 }
960bfb69
JH
743 else if (node->analyzed && gimple_has_body_p (node->symbol.decl)
744 && !TREE_ASM_WRITTEN (node->symbol.decl)
745 && (!DECL_EXTERNAL (node->symbol.decl) || node->global.inlined_to)
c47d0034 746 && !flag_wpa)
18c6ada9 747 {
e21aff8a
SB
748 if (this_cfun->cfg)
749 {
750 /* The nodes we're interested in are never shared, so walk
751 the tree ignoring duplicates. */
2dee695b 752 struct pointer_set_t *visited_nodes = pointer_set_create ();
e21aff8a
SB
753 /* Reach the trees by walking over the CFG, and note the
754 enclosing basic-blocks in the call edges. */
755 FOR_EACH_BB_FN (this_block, this_cfun)
726a989a
RB
756 for (gsi = gsi_start_bb (this_block);
757 !gsi_end_p (gsi);
758 gsi_next (&gsi))
e0704a46 759 {
726a989a 760 gimple stmt = gsi_stmt (gsi);
e33c6cd6 761 if (is_gimple_call (stmt))
e0704a46
JH
762 {
763 struct cgraph_edge *e = cgraph_edge (node, stmt);
e33c6cd6 764 tree decl = gimple_call_fndecl (stmt);
e0704a46
JH
765 if (e)
766 {
767 if (e->aux)
768 {
ab532386 769 error ("shared call_stmt:");
89843f5d 770 cgraph_debug_gimple_stmt (this_cfun, stmt);
e0704a46
JH
771 error_found = true;
772 }
e33c6cd6 773 if (!e->indirect_unknown_callee)
6744a6ab 774 {
81361831 775 if (verify_edge_corresponds_to_fndecl (e, decl))
e33c6cd6
MJ
776 {
777 error ("edge points to wrong declaration:");
960bfb69 778 debug_tree (e->callee->symbol.decl);
e33c6cd6
MJ
779 fprintf (stderr," Instead of:");
780 debug_tree (decl);
781 error_found = true;
782 }
6744a6ab 783 }
e33c6cd6 784 else if (decl)
e0704a46 785 {
e33c6cd6
MJ
786 error ("an indirect edge with unknown callee "
787 "corresponding to a call_stmt with "
788 "a known declaration:");
47cb0d7d 789 error_found = true;
89843f5d 790 cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
e0704a46
JH
791 }
792 e->aux = (void *)1;
793 }
e33c6cd6 794 else if (decl)
e0704a46 795 {
ab532386 796 error ("missing callgraph edge for call stmt:");
89843f5d 797 cgraph_debug_gimple_stmt (this_cfun, stmt);
e0704a46
JH
798 error_found = true;
799 }
800 }
801 }
e21aff8a 802 pointer_set_destroy (visited_nodes);
e21aff8a
SB
803 }
804 else
805 /* No CFG available?! */
806 gcc_unreachable ();
807
18c6ada9
JH
808 for (e = node->callees; e; e = e->next_callee)
809 {
e33c6cd6 810 if (!e->aux)
18c6ada9 811 {
ab532386 812 error ("edge %s->%s has no corresponding call_stmt",
4f1e4960
JM
813 identifier_to_locale (cgraph_node_name (e->caller)),
814 identifier_to_locale (cgraph_node_name (e->callee)));
89843f5d 815 cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
18c6ada9
JH
816 error_found = true;
817 }
818 e->aux = 0;
819 }
e33c6cd6
MJ
820 for (e = node->indirect_calls; e; e = e->next_callee)
821 {
822 if (!e->aux)
823 {
824 error ("an indirect edge from %s has no corresponding call_stmt",
825 identifier_to_locale (cgraph_node_name (e->caller)));
89843f5d 826 cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
e33c6cd6
MJ
827 error_found = true;
828 }
829 e->aux = 0;
830 }
18c6ada9
JH
831 }
832 if (error_found)
833 {
834 dump_cgraph_node (stderr, node);
ab532386 835 internal_error ("verify_cgraph_node failed");
18c6ada9
JH
836 }
837 timevar_pop (TV_CGRAPH_VERIFY);
838}
839
840/* Verify whole cgraph structure. */
24e47c76 841DEBUG_FUNCTION void
18c6ada9
JH
842verify_cgraph (void)
843{
844 struct cgraph_node *node;
845
1da2ed5f 846 if (seen_error ())
89480522
JH
847 return;
848
65c70e6b 849 FOR_EACH_FUNCTION (node)
18c6ada9
JH
850 verify_cgraph_node (node);
851}
852
474eccc6
ILT
853/* Output all asm statements we have stored up to be output. */
854
855static void
856cgraph_output_pending_asms (void)
857{
858 struct cgraph_asm_node *can;
859
1da2ed5f 860 if (seen_error ())
474eccc6
ILT
861 return;
862
863 for (can = cgraph_asm_nodes; can; can = can->next)
864 assemble_asm (can->asm_str);
865 cgraph_asm_nodes = NULL;
866}
867
e767b5be 868/* Analyze the function scheduled to be output. */
322dd859 869void
e767b5be
JH
870cgraph_analyze_function (struct cgraph_node *node)
871{
a406865a 872 tree save = current_function_decl;
960bfb69 873 tree decl = node->symbol.decl;
e767b5be 874
39e2db00
JH
875 if (node->alias && node->thunk.alias)
876 {
877 struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias);
5ee770bf
JH
878 struct cgraph_node *n;
879
880 for (n = tgt; n && n->alias;
881 n = n->analyzed ? cgraph_alias_aliased_node (n) : NULL)
882 if (n == node)
883 {
960bfb69 884 error ("function %q+D part of alias cycle", node->symbol.decl);
5ee770bf
JH
885 node->alias = false;
886 return;
887 }
960bfb69 888 if (!VEC_length (ipa_ref_t, node->symbol.ref_list.references))
5932a4d4
JH
889 ipa_record_reference ((symtab_node)node, (symtab_node)tgt,
890 IPA_REF_ALIAS, NULL);
ead84f73 891 cgraph_mark_reachable_node (tgt);
39e2db00
JH
892 if (node->same_body_alias)
893 {
960bfb69
JH
894 DECL_VIRTUAL_P (node->symbol.decl) = DECL_VIRTUAL_P (node->thunk.alias);
895 DECL_DECLARED_INLINE_P (node->symbol.decl)
39e2db00 896 = DECL_DECLARED_INLINE_P (node->thunk.alias);
960bfb69 897 DECL_DISREGARD_INLINE_LIMITS (node->symbol.decl)
39e2db00
JH
898 = DECL_DISREGARD_INLINE_LIMITS (node->thunk.alias);
899 }
900
901 /* Fixup visibility nonsences C++ frontend produce on same body aliases. */
960bfb69 902 if (TREE_PUBLIC (node->symbol.decl) && node->same_body_alias)
39e2db00 903 {
960bfb69 904 DECL_EXTERNAL (node->symbol.decl) = DECL_EXTERNAL (node->thunk.alias);
ee6f1177 905 if (DECL_ONE_ONLY (node->thunk.alias))
39e2db00 906 {
960bfb69
JH
907 DECL_COMDAT (node->symbol.decl) = DECL_COMDAT (node->thunk.alias);
908 DECL_COMDAT_GROUP (node->symbol.decl) = DECL_COMDAT_GROUP (node->thunk.alias);
909 if (DECL_ONE_ONLY (node->thunk.alias) && !node->symbol.same_comdat_group)
39e2db00
JH
910 {
911 struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias);
960bfb69
JH
912 node->symbol.same_comdat_group = (symtab_node)tgt;
913 if (!tgt->symbol.same_comdat_group)
914 tgt->symbol.same_comdat_group = (symtab_node)node;
39e2db00
JH
915 else
916 {
960bfb69
JH
917 symtab_node n;
918 for (n = tgt->symbol.same_comdat_group;
919 n->symbol.same_comdat_group != (symtab_node)tgt;
920 n = n->symbol.same_comdat_group)
39e2db00 921 ;
960bfb69 922 n->symbol.same_comdat_group = (symtab_node)node;
39e2db00
JH
923 }
924 }
925 }
926 }
927 cgraph_mark_reachable_node (cgraph_alias_aliased_node (node));
960bfb69 928 if (node->symbol.address_taken)
39e2db00 929 cgraph_mark_address_taken_node (cgraph_alias_aliased_node (node));
960bfb69 930 if (cgraph_decide_is_function_needed (node, node->symbol.decl))
ead84f73 931 cgraph_mark_reachable_node (node);
39e2db00
JH
932 }
933 else if (node->thunk.thunk_p)
c47d0034
JH
934 {
935 cgraph_create_edge (node, cgraph_get_node (node->thunk.alias),
936 NULL, 0, CGRAPH_FREQ_BASE);
937 }
938 else
939 {
940 current_function_decl = decl;
941 push_cfun (DECL_STRUCT_FUNCTION (decl));
a406865a 942
960bfb69 943 assign_assembler_name_if_neeeded (node->symbol.decl);
0e0a1359 944
c47d0034
JH
945 /* Make sure to gimplify bodies only once. During analyzing a
946 function we lower it, which will require gimplified nested
947 functions, so we can end up here with an already gimplified
948 body. */
949 if (!gimple_body (decl))
950 gimplify_function_tree (decl);
951 dump_function (TDI_generic, decl);
a406865a 952
26eb69c6
RG
953 /* Lower the function. */
954 if (!node->lowered)
955 {
956 if (node->nested)
960bfb69 957 lower_nested_functions (node->symbol.decl);
26eb69c6
RG
958 gcc_assert (!node->nested);
959
960 gimple_register_cfg_hooks ();
961 bitmap_obstack_initialize (NULL);
962 execute_pass_list (all_lowering_passes);
963 free_dominance_info (CDI_POST_DOMINATORS);
964 free_dominance_info (CDI_DOMINATORS);
965 compact_blocks ();
966 bitmap_obstack_release (NULL);
967 node->lowered = true;
968 }
969
c47d0034
JH
970 pop_cfun ();
971 }
6a84c098 972 node->analyzed = true;
e767b5be 973
a406865a 974 current_function_decl = save;
e767b5be
JH
975}
976
39e2db00
JH
977/* C++ frontend produce same body aliases all over the place, even before PCH
978 gets streamed out. It relies on us linking the aliases with their function
979 in order to do the fixups, but ipa-ref is not PCH safe. Consequentely we
980 first produce aliases without links, but once C++ FE is sure he won't sream
981 PCH we build the links via this function. */
982
983void
984cgraph_process_same_body_aliases (void)
985{
986 struct cgraph_node *node;
65c70e6b 987 FOR_EACH_FUNCTION (node)
39e2db00 988 if (node->same_body_alias
960bfb69 989 && !VEC_length (ipa_ref_t, node->symbol.ref_list.references))
39e2db00
JH
990 {
991 struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias);
5932a4d4
JH
992 ipa_record_reference ((symtab_node)node, (symtab_node)tgt,
993 IPA_REF_ALIAS, NULL);
39e2db00
JH
994 }
995 same_body_aliases_done = true;
996}
997
768e3c60
RG
998/* Process attributes common for vars and functions. */
999
1000static void
1001process_common_attributes (tree decl)
1002{
1003 tree weakref = lookup_attribute ("weakref", DECL_ATTRIBUTES (decl));
1004
1005 if (weakref && !lookup_attribute ("alias", DECL_ATTRIBUTES (decl)))
1006 {
1007 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
1008 "%<weakref%> attribute should be accompanied with"
1009 " an %<alias%> attribute");
1010 DECL_WEAK (decl) = 0;
779d4b91
JH
1011 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
1012 DECL_ATTRIBUTES (decl));
768e3c60
RG
1013 }
1014}
1015
386b46cf
JH
1016/* Look for externally_visible and used attributes and mark cgraph nodes
1017 accordingly.
1018
1019 We cannot mark the nodes at the point the attributes are processed (in
1020 handle_*_attribute) because the copy of the declarations available at that
1021 point may not be canonical. For example, in:
1022
1023 void f();
1024 void f() __attribute__((used));
1025
1026 the declaration we see in handle_used_attribute will be the second
1027 declaration -- but the front end will subsequently merge that declaration
1028 with the original declaration and discard the second declaration.
1029
1030 Furthermore, we can't mark these nodes in cgraph_finalize_function because:
1031
1032 void f() {}
1033 void f() __attribute__((externally_visible));
1034
1035 is valid.
1036
1037 So, we walk the nodes at the end of the translation unit, applying the
1038 attributes at that point. */
1039
1040static void
1041process_function_and_variable_attributes (struct cgraph_node *first,
8a4a83ed 1042 struct varpool_node *first_var)
386b46cf
JH
1043{
1044 struct cgraph_node *node;
8a4a83ed 1045 struct varpool_node *vnode;
386b46cf 1046
2aae7680
JH
1047 for (node = cgraph_first_function (); node != first;
1048 node = cgraph_next_function (node))
386b46cf 1049 {
960bfb69 1050 tree decl = node->symbol.decl;
b42186f1 1051 if (DECL_PRESERVE_P (decl))
ead84f73 1052 cgraph_mark_force_output_node (node);
9d602c59
KT
1053 if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
1054 && lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl))
960bfb69 1055 && TREE_PUBLIC (node->symbol.decl))
9d602c59
KT
1056 {
1057 if (node->local.finalized)
ead84f73 1058 cgraph_mark_reachable_node (node);
9d602c59
KT
1059 }
1060 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
386b46cf 1061 {
960bfb69
JH
1062 if (! TREE_PUBLIC (node->symbol.decl))
1063 warning_at (DECL_SOURCE_LOCATION (node->symbol.decl), OPT_Wattributes,
c5d75364
MLI
1064 "%<externally_visible%>"
1065 " attribute have effect only on public objects");
b20996ff 1066 else if (node->local.finalized)
ead84f73 1067 cgraph_mark_reachable_node (node);
386b46cf 1068 }
779d4b91 1069 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
39e2db00 1070 && (node->local.finalized && !node->alias))
779d4b91 1071 {
960bfb69 1072 warning_at (DECL_SOURCE_LOCATION (node->symbol.decl), OPT_Wattributes,
779d4b91
JH
1073 "%<weakref%> attribute ignored"
1074 " because function is defined");
1075 DECL_WEAK (decl) = 0;
1076 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
1077 DECL_ATTRIBUTES (decl));
1078 }
c9fc06dc
CB
1079
1080 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl))
1081 && !DECL_DECLARED_INLINE_P (decl)
1082 /* redefining extern inline function makes it DECL_UNINLINABLE. */
1083 && !DECL_UNINLINABLE (decl))
1084 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
1085 "always_inline function might not be inlinable");
1086
768e3c60 1087 process_common_attributes (decl);
386b46cf 1088 }
2aae7680
JH
1089 for (vnode = varpool_first_variable (); vnode != first_var;
1090 vnode = varpool_next_variable (vnode))
386b46cf 1091 {
960bfb69 1092 tree decl = vnode->symbol.decl;
b42186f1 1093 if (DECL_PRESERVE_P (decl))
386b46cf 1094 {
ead84f73 1095 vnode->symbol.force_output = true;
386b46cf 1096 if (vnode->finalized)
8a4a83ed 1097 varpool_mark_needed_node (vnode);
386b46cf 1098 }
9d602c59
KT
1099 if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
1100 && lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl))
960bfb69 1101 && TREE_PUBLIC (vnode->symbol.decl))
9d602c59
KT
1102 {
1103 if (vnode->finalized)
1104 varpool_mark_needed_node (vnode);
1105 }
1106 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
386b46cf 1107 {
960bfb69
JH
1108 if (! TREE_PUBLIC (vnode->symbol.decl))
1109 warning_at (DECL_SOURCE_LOCATION (vnode->symbol.decl), OPT_Wattributes,
c5d75364
MLI
1110 "%<externally_visible%>"
1111 " attribute have effect only on public objects");
b20996ff
JH
1112 else if (vnode->finalized)
1113 varpool_mark_needed_node (vnode);
386b46cf 1114 }
779d4b91
JH
1115 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
1116 && vnode->finalized
1117 && DECL_INITIAL (decl))
1118 {
960bfb69 1119 warning_at (DECL_SOURCE_LOCATION (vnode->symbol.decl), OPT_Wattributes,
779d4b91
JH
1120 "%<weakref%> attribute ignored"
1121 " because variable is initialized");
1122 DECL_WEAK (decl) = 0;
1123 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
1124 DECL_ATTRIBUTES (decl));
1125 }
768e3c60 1126 process_common_attributes (decl);
386b46cf
JH
1127 }
1128}
1129
151e6f24
JH
1130/* Process CGRAPH_NODES_NEEDED queue, analyze each function (and transitively
1131 each reachable functions) and build cgraph.
1132 The function can be called multiple times after inserting new nodes
88512ba0 1133 into beginning of queue. Just the new part of queue is re-scanned then. */
1c4a429a 1134
151e6f24
JH
1135static void
1136cgraph_analyze_functions (void)
1c4a429a 1137{
cd9c7bd2 1138 /* Keep track of already processed nodes when called multiple times for
aabcd309 1139 intermodule optimization. */
cd9c7bd2 1140 static struct cgraph_node *first_analyzed;
61e00a5e 1141 struct cgraph_node *first_processed = first_analyzed;
8a4a83ed 1142 static struct varpool_node *first_analyzed_var;
151e6f24 1143 struct cgraph_node *node, *next;
1c4a429a 1144
1389294c 1145 bitmap_obstack_initialize (NULL);
61e00a5e
JH
1146 process_function_and_variable_attributes (first_processed,
1147 first_analyzed_var);
2aae7680
JH
1148 first_processed = cgraph_first_function ();
1149 first_analyzed_var = varpool_first_variable ();
8a4a83ed 1150 varpool_analyze_pending_decls ();
a194aa56 1151 if (cgraph_dump_file)
1c4a429a 1152 {
7d82fe7c 1153 fprintf (cgraph_dump_file, "Initial entry points:");
2aae7680
JH
1154 for (node = cgraph_first_function (); node != first_analyzed;
1155 node = cgraph_next_function (node))
ead84f73 1156 if (cgraph_decide_is_function_needed (node, node->symbol.decl))
a194aa56
JH
1157 fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
1158 fprintf (cgraph_dump_file, "\n");
1c4a429a 1159 }
151e6f24 1160 cgraph_process_new_functions ();
1c4a429a 1161
7660e67e
SB
1162 /* Propagate reachability flag and lower representation of all reachable
1163 functions. In the future, lowering will introduce new functions and
1164 new entry points on the way (by template instantiation and virtual
1165 method table generation for instance). */
1668aabc 1166 while (cgraph_nodes_queue)
1c4a429a 1167 {
e767b5be 1168 struct cgraph_edge *edge;
960bfb69 1169 tree decl = cgraph_nodes_queue->symbol.decl;
1668aabc
JH
1170
1171 node = cgraph_nodes_queue;
960bfb69 1172 x_cgraph_nodes_queue = (symtab_node)cgraph_nodes_queue->next_needed;
18c6ada9 1173 node->next_needed = NULL;
1c4a429a 1174
cd4dea62 1175 /* ??? It is possible to create extern inline function and later using
9d203871 1176 weak alias attribute to kill its body. See
cd4dea62 1177 gcc.c-torture/compile/20011119-1.c */
c47d0034 1178 if (!DECL_STRUCT_FUNCTION (decl)
39e2db00 1179 && (!node->alias || !node->thunk.alias)
c47d0034 1180 && !node->thunk.thunk_p)
d71cc23f
JH
1181 {
1182 cgraph_reset_node (node);
b125ad45 1183 node->local.redefined_extern_inline = true;
d71cc23f
JH
1184 continue;
1185 }
cd4dea62 1186
d7f09764
DN
1187 if (!node->analyzed)
1188 cgraph_analyze_function (node);
8dafba3c 1189
1c4a429a 1190 for (edge = node->callees; edge; edge = edge->next_callee)
e767b5be 1191 if (!edge->callee->reachable)
8dafba3c 1192 cgraph_mark_reachable_node (edge->callee);
c47d0034
JH
1193 for (edge = node->callers; edge; edge = edge->next_caller)
1194 if (!edge->caller->reachable && edge->caller->thunk.thunk_p)
1195 cgraph_mark_reachable_node (edge->caller);
8dafba3c 1196
960bfb69 1197 if (node->symbol.same_comdat_group)
b66887e4 1198 {
960bfb69 1199 for (next = cgraph (node->symbol.same_comdat_group);
b66887e4 1200 next != node;
960bfb69 1201 next = cgraph (next->symbol.same_comdat_group))
b66887e4
JJ
1202 cgraph_mark_reachable_node (next);
1203 }
1204
6b20f353
DS
1205 /* If decl is a clone of an abstract function, mark that abstract
1206 function so that we don't release its body. The DECL_INITIAL() of that
581985d7
MJ
1207 abstract function declaration will be later needed to output debug
1208 info. */
6b20f353
DS
1209 if (DECL_ABSTRACT_ORIGIN (decl))
1210 {
581985d7
MJ
1211 struct cgraph_node *origin_node;
1212 origin_node = cgraph_get_node (DECL_ABSTRACT_ORIGIN (decl));
6b20f353
DS
1213 origin_node->abstract_and_needed = true;
1214 }
1215
61e00a5e
JH
1216 /* We finalize local static variables during constructing callgraph
1217 edges. Process their attributes too. */
1218 process_function_and_variable_attributes (first_processed,
1219 first_analyzed_var);
2aae7680
JH
1220 first_processed = cgraph_first_function ();
1221 first_analyzed_var = varpool_first_variable ();
8a4a83ed 1222 varpool_analyze_pending_decls ();
151e6f24 1223 cgraph_process_new_functions ();
1c4a429a 1224 }
8dafba3c 1225
564738df 1226 /* Collect entry points to the unit. */
a194aa56 1227 if (cgraph_dump_file)
1668aabc 1228 {
7d82fe7c 1229 fprintf (cgraph_dump_file, "Unit entry points:");
2aae7680
JH
1230 for (node = cgraph_first_function (); node != first_analyzed;
1231 node = cgraph_next_function (node))
ead84f73 1232 if (cgraph_decide_is_function_needed (node, node->symbol.decl))
a194aa56 1233 fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
7d82fe7c 1234 fprintf (cgraph_dump_file, "\n\nInitial ");
8f940ee6 1235 dump_symtab (cgraph_dump_file);
1668aabc 1236 }
7660e67e 1237
a194aa56
JH
1238 if (cgraph_dump_file)
1239 fprintf (cgraph_dump_file, "\nReclaiming functions:");
1c4a429a 1240
2aae7680
JH
1241 for (node = cgraph_first_function (); node != first_analyzed;
1242 node = next)
1c4a429a 1243 {
960bfb69 1244 tree decl = node->symbol.decl;
2aae7680 1245 next = cgraph_next_function (node);
1c4a429a 1246
c47d0034 1247 if (node->local.finalized && !gimple_has_body_p (decl)
39e2db00 1248 && (!node->alias || !node->thunk.alias)
c47d0034 1249 && !node->thunk.thunk_p)
c22cacf3 1250 cgraph_reset_node (node);
d71cc23f 1251
c47d0034 1252 if (!node->reachable
39e2db00
JH
1253 && (gimple_has_body_p (decl) || node->thunk.thunk_p
1254 || (node->alias && node->thunk.alias)))
1c4a429a 1255 {
a194aa56
JH
1256 if (cgraph_dump_file)
1257 fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
18c6ada9 1258 cgraph_remove_node (node);
d71cc23f 1259 continue;
1c4a429a 1260 }
9b0436b7
JH
1261 else
1262 node->next_needed = NULL;
c47d0034 1263 gcc_assert (!node->local.finalized || node->thunk.thunk_p
39e2db00 1264 || node->alias
c47d0034 1265 || gimple_has_body_p (decl));
d71cc23f 1266 gcc_assert (node->analyzed == node->local.finalized);
1c4a429a 1267 }
a194aa56 1268 if (cgraph_dump_file)
7d82fe7c
KC
1269 {
1270 fprintf (cgraph_dump_file, "\n\nReclaimed ");
8f940ee6 1271 dump_symtab (cgraph_dump_file);
7d82fe7c 1272 }
1389294c 1273 bitmap_obstack_release (NULL);
2aae7680 1274 first_analyzed = cgraph_first_function ();
1c4a429a 1275 ggc_collect ();
151e6f24
JH
1276}
1277
85ce9375
JH
1278/* Translate the ugly representation of aliases as alias pairs into nice
1279 representation in callgraph. We don't handle all cases yet,
1280 unforutnately. */
1281
1282static void
1283handle_alias_pairs (void)
1284{
1285 alias_pair *p;
1286 unsigned i;
1287 struct cgraph_node *target_node;
1288 struct cgraph_node *src_node;
cd35bcf7 1289 struct varpool_node *target_vnode;
85ce9375
JH
1290
1291 for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p);)
1292 {
1293 if (TREE_CODE (p->decl) == FUNCTION_DECL
85ce9375
JH
1294 && (target_node = cgraph_node_for_asm (p->target)) != NULL)
1295 {
1296 src_node = cgraph_get_node (p->decl);
1297 if (src_node && src_node->local.finalized)
1298 cgraph_reset_node (src_node);
1299 /* Normally EXTERNAL flag is used to mark external inlines,
1300 however for aliases it seems to be allowed to use it w/o
1301 any meaning. See gcc.dg/attr-alias-3.c
1302 However for weakref we insist on EXTERNAL flag being set.
1303 See gcc.dg/attr-alias-5.c */
1304 if (DECL_EXTERNAL (p->decl))
960bfb69
JH
1305 DECL_EXTERNAL (p->decl)
1306 = lookup_attribute ("weakref",
1307 DECL_ATTRIBUTES (p->decl)) != NULL;
1308 cgraph_create_function_alias (p->decl, target_node->symbol.decl);
85ce9375
JH
1309 VEC_unordered_remove (alias_pair, alias_pairs, i);
1310 }
cd35bcf7 1311 else if (TREE_CODE (p->decl) == VAR_DECL
cd35bcf7
JH
1312 && (target_vnode = varpool_node_for_asm (p->target)) != NULL)
1313 {
1314 /* Normally EXTERNAL flag is used to mark external inlines,
1315 however for aliases it seems to be allowed to use it w/o
1316 any meaning. See gcc.dg/attr-alias-3.c
1317 However for weakref we insist on EXTERNAL flag being set.
1318 See gcc.dg/attr-alias-5.c */
1319 if (DECL_EXTERNAL (p->decl))
960bfb69
JH
1320 DECL_EXTERNAL (p->decl)
1321 = lookup_attribute ("weakref",
1322 DECL_ATTRIBUTES (p->decl)) != NULL;
1323 varpool_create_variable_alias (p->decl, target_vnode->symbol.decl);
cd35bcf7
JH
1324 VEC_unordered_remove (alias_pair, alias_pairs, i);
1325 }
25e2c40d
JH
1326 /* Weakrefs with target not defined in current unit are easy to handle; they
1327 behave just as external variables except we need to note the alias flag
1328 to later output the weakref pseudo op into asm file. */
1329 else if (lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL
1330 && (TREE_CODE (p->decl) == FUNCTION_DECL
1331 ? (varpool_node_for_asm (p->target) == NULL)
1332 : (cgraph_node_for_asm (p->target) == NULL)))
1333 {
1334 if (TREE_CODE (p->decl) == FUNCTION_DECL)
1335 cgraph_get_create_node (p->decl)->alias = true;
1336 else
1337 varpool_get_node (p->decl)->alias = true;
1338 DECL_EXTERNAL (p->decl) = 1;
1339 VEC_unordered_remove (alias_pair, alias_pairs, i);
1340 }
85ce9375
JH
1341 else
1342 {
1343 if (dump_file)
1344 fprintf (dump_file, "Unhandled alias %s->%s\n",
1345 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (p->decl)),
1346 IDENTIFIER_POINTER (p->target));
1347
1348 i++;
1349 }
1350 }
1351}
1352
5f1a9ebb 1353
1c4a429a
JH
1354/* Figure out what functions we want to assemble. */
1355
1356static void
db0e878d 1357cgraph_mark_functions_to_output (void)
1c4a429a
JH
1358{
1359 struct cgraph_node *node;
b66887e4
JJ
1360#ifdef ENABLE_CHECKING
1361 bool check_same_comdat_groups = false;
1362
65c70e6b 1363 FOR_EACH_FUNCTION (node)
b66887e4
JJ
1364 gcc_assert (!node->process);
1365#endif
1c4a429a 1366
65c70e6b 1367 FOR_EACH_FUNCTION (node)
1c4a429a 1368 {
960bfb69 1369 tree decl = node->symbol.decl;
b58b1157 1370 struct cgraph_edge *e;
c22cacf3 1371
960bfb69 1372 gcc_assert (!node->process || node->symbol.same_comdat_group);
b66887e4
JJ
1373 if (node->process)
1374 continue;
b58b1157
JH
1375
1376 for (e = node->callers; e; e = e->next_caller)
dc0bfe6a 1377 if (e->inline_failed)
b58b1157 1378 break;
1c4a429a 1379
7660e67e
SB
1380 /* We need to output all local functions that are used and not
1381 always inlined, as well as those that are reachable from
1382 outside the current compilation unit. */
39ecc018 1383 if (node->analyzed
c47d0034 1384 && !node->thunk.thunk_p
39e2db00 1385 && !node->alias
18c6ada9 1386 && !node->global.inlined_to
508e4757 1387 && (!cgraph_only_called_directly_p (node)
960bfb69 1388 || ((e || ipa_ref_has_aliases_p (&node->symbol.ref_list))
39e2db00 1389 && node->reachable))
6de9cd9a 1390 && !TREE_ASM_WRITTEN (decl)
1c4a429a 1391 && !DECL_EXTERNAL (decl))
b66887e4
JJ
1392 {
1393 node->process = 1;
960bfb69 1394 if (node->symbol.same_comdat_group)
b66887e4
JJ
1395 {
1396 struct cgraph_node *next;
960bfb69 1397 for (next = cgraph (node->symbol.same_comdat_group);
b66887e4 1398 next != node;
960bfb69 1399 next = cgraph (next->symbol.same_comdat_group))
39e2db00 1400 if (!next->thunk.thunk_p && !next->alias)
c47d0034 1401 next->process = 1;
b66887e4
JJ
1402 }
1403 }
960bfb69 1404 else if (node->symbol.same_comdat_group)
b66887e4
JJ
1405 {
1406#ifdef ENABLE_CHECKING
1407 check_same_comdat_groups = true;
1408#endif
1409 }
341c100f 1410 else
1a2caa7a
NS
1411 {
1412 /* We should've reclaimed all functions that are not needed. */
1413#ifdef ENABLE_CHECKING
726a989a 1414 if (!node->global.inlined_to
39ecc018 1415 && gimple_has_body_p (decl)
a837268b
JH
1416 /* FIXME: in ltrans unit when offline copy is outside partition but inline copies
1417 are inside partition, we can end up not removing the body since we no longer
1418 have analyzed node pointing to it. */
960bfb69 1419 && !node->symbol.in_other_partition
39e2db00 1420 && !node->alias
1a2caa7a
NS
1421 && !DECL_EXTERNAL (decl))
1422 {
1423 dump_cgraph_node (stderr, node);
1424 internal_error ("failed to reclaim unneeded function");
1425 }
1426#endif
726a989a 1427 gcc_assert (node->global.inlined_to
39ecc018 1428 || !gimple_has_body_p (decl)
960bfb69 1429 || node->symbol.in_other_partition
1a2caa7a
NS
1430 || DECL_EXTERNAL (decl));
1431
1432 }
c22cacf3 1433
18d13f34 1434 }
b66887e4
JJ
1435#ifdef ENABLE_CHECKING
1436 if (check_same_comdat_groups)
65c70e6b 1437 FOR_EACH_FUNCTION (node)
960bfb69 1438 if (node->symbol.same_comdat_group && !node->process)
b66887e4 1439 {
960bfb69 1440 tree decl = node->symbol.decl;
b66887e4
JJ
1441 if (!node->global.inlined_to
1442 && gimple_has_body_p (decl)
7cbf224d
RG
1443 /* FIXME: in an ltrans unit when the offline copy is outside a
1444 partition but inline copies are inside a partition, we can
1445 end up not removing the body since we no longer have an
1446 analyzed node pointing to it. */
960bfb69 1447 && !node->symbol.in_other_partition
b66887e4
JJ
1448 && !DECL_EXTERNAL (decl))
1449 {
1450 dump_cgraph_node (stderr, node);
7cbf224d
RG
1451 internal_error ("failed to reclaim unneeded function in same "
1452 "comdat group");
b66887e4
JJ
1453 }
1454 }
1455#endif
18d13f34
JH
1456}
1457
6744a6ab
JH
1458/* DECL is FUNCTION_DECL. Initialize datastructures so DECL is a function
1459 in lowered gimple form.
1460
1461 Set current_function_decl and cfun to newly constructed empty function body.
1462 return basic block in the function body. */
1463
1464static basic_block
1465init_lowered_empty_function (tree decl)
1466{
1467 basic_block bb;
1468
1469 current_function_decl = decl;
1470 allocate_struct_function (decl, false);
1471 gimple_register_cfg_hooks ();
1472 init_empty_tree_cfg ();
1473 init_tree_ssa (cfun);
1474 init_ssa_operands ();
1475 cfun->gimple_df->in_ssa_p = true;
1476 DECL_INITIAL (decl) = make_node (BLOCK);
1477
1478 DECL_SAVED_TREE (decl) = error_mark_node;
1479 cfun->curr_properties |=
1480 (PROP_gimple_lcf | PROP_gimple_leh | PROP_cfg | PROP_referenced_vars |
febb1302 1481 PROP_ssa | PROP_gimple_any);
6744a6ab
JH
1482
1483 /* Create BB for body of the function and connect it properly. */
1484 bb = create_basic_block (NULL, (void *) 0, ENTRY_BLOCK_PTR);
4f9c574a
DV
1485 make_edge (ENTRY_BLOCK_PTR, bb, 0);
1486 make_edge (bb, EXIT_BLOCK_PTR, 0);
6744a6ab
JH
1487
1488 return bb;
1489}
1490
1491/* Adjust PTR by the constant FIXED_OFFSET, and by the vtable
1492 offset indicated by VIRTUAL_OFFSET, if that is
1493 non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and
1494 zero for a result adjusting thunk. */
1495
1496static tree
1497thunk_adjust (gimple_stmt_iterator * bsi,
1498 tree ptr, bool this_adjusting,
1499 HOST_WIDE_INT fixed_offset, tree virtual_offset)
1500{
1501 gimple stmt;
1502 tree ret;
1503
313333a6
RG
1504 if (this_adjusting
1505 && fixed_offset != 0)
6744a6ab 1506 {
5d49b6a7
RG
1507 stmt = gimple_build_assign
1508 (ptr, fold_build_pointer_plus_hwi_loc (input_location,
1509 ptr,
1510 fixed_offset));
6744a6ab
JH
1511 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1512 }
1513
1514 /* If there's a virtual offset, look up that value in the vtable and
1515 adjust the pointer again. */
1516 if (virtual_offset)
1517 {
1518 tree vtabletmp;
1519 tree vtabletmp2;
1520 tree vtabletmp3;
6744a6ab
JH
1521
1522 if (!vtable_entry_type)
1523 {
1524 tree vfunc_type = make_node (FUNCTION_TYPE);
1525 TREE_TYPE (vfunc_type) = integer_type_node;
1526 TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
1527 layout_type (vfunc_type);
1528
1529 vtable_entry_type = build_pointer_type (vfunc_type);
1530 }
1531
1532 vtabletmp =
1533 create_tmp_var (build_pointer_type
1534 (build_pointer_type (vtable_entry_type)), "vptr");
1535
1536 /* The vptr is always at offset zero in the object. */
1537 stmt = gimple_build_assign (vtabletmp,
1538 build1 (NOP_EXPR, TREE_TYPE (vtabletmp),
1539 ptr));
1540 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1541 mark_symbols_for_renaming (stmt);
1542 find_referenced_vars_in (stmt);
1543
1544 /* Form the vtable address. */
1545 vtabletmp2 = create_tmp_var (TREE_TYPE (TREE_TYPE (vtabletmp)),
1546 "vtableaddr");
1547 stmt = gimple_build_assign (vtabletmp2,
70f34814 1548 build_simple_mem_ref (vtabletmp));
6744a6ab
JH
1549 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1550 mark_symbols_for_renaming (stmt);
1551 find_referenced_vars_in (stmt);
1552
1553 /* Find the entry with the vcall offset. */
1554 stmt = gimple_build_assign (vtabletmp2,
5d49b6a7
RG
1555 fold_build_pointer_plus_loc (input_location,
1556 vtabletmp2,
1557 virtual_offset));
6744a6ab
JH
1558 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1559
1560 /* Get the offset itself. */
1561 vtabletmp3 = create_tmp_var (TREE_TYPE (TREE_TYPE (vtabletmp2)),
1562 "vcalloffset");
1563 stmt = gimple_build_assign (vtabletmp3,
70f34814 1564 build_simple_mem_ref (vtabletmp2));
6744a6ab
JH
1565 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1566 mark_symbols_for_renaming (stmt);
1567 find_referenced_vars_in (stmt);
1568
6744a6ab 1569 /* Adjust the `this' pointer. */
0d82a1c8
RG
1570 ptr = fold_build_pointer_plus_loc (input_location, ptr, vtabletmp3);
1571 ptr = force_gimple_operand_gsi (bsi, ptr, true, NULL_TREE, false,
1572 GSI_CONTINUE_LINKING);
6744a6ab
JH
1573 }
1574
313333a6
RG
1575 if (!this_adjusting
1576 && fixed_offset != 0)
6744a6ab
JH
1577 /* Adjust the pointer by the constant. */
1578 {
1579 tree ptrtmp;
1580
1581 if (TREE_CODE (ptr) == VAR_DECL)
1582 ptrtmp = ptr;
1583 else
1584 {
1585 ptrtmp = create_tmp_var (TREE_TYPE (ptr), "ptr");
1586 stmt = gimple_build_assign (ptrtmp, ptr);
1587 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1588 mark_symbols_for_renaming (stmt);
1589 find_referenced_vars_in (stmt);
1590 }
5d49b6a7
RG
1591 ptr = fold_build_pointer_plus_hwi_loc (input_location,
1592 ptrtmp, fixed_offset);
6744a6ab
JH
1593 }
1594
1595 /* Emit the statement and gimplify the adjustment expression. */
1596 ret = create_tmp_var (TREE_TYPE (ptr), "adjusted_this");
1597 stmt = gimple_build_assign (ret, ptr);
1598 mark_symbols_for_renaming (stmt);
1599 find_referenced_vars_in (stmt);
1600 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1601
1602 return ret;
1603}
1604
1605/* Produce assembler for thunk NODE. */
1606
1607static void
1608assemble_thunk (struct cgraph_node *node)
1609{
1610 bool this_adjusting = node->thunk.this_adjusting;
1611 HOST_WIDE_INT fixed_offset = node->thunk.fixed_offset;
1612 HOST_WIDE_INT virtual_value = node->thunk.virtual_value;
1613 tree virtual_offset = NULL;
1614 tree alias = node->thunk.alias;
960bfb69 1615 tree thunk_fndecl = node->symbol.decl;
6744a6ab
JH
1616 tree a = DECL_ARGUMENTS (thunk_fndecl);
1617
1618 current_function_decl = thunk_fndecl;
1619
d06865bf
DK
1620 /* Ensure thunks are emitted in their correct sections. */
1621 resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
1622
6744a6ab
JH
1623 if (this_adjusting
1624 && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
1625 virtual_value, alias))
1626 {
1627 const char *fnname;
1628 tree fn_block;
4399cf59 1629 tree restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
6744a6ab
JH
1630
1631 DECL_RESULT (thunk_fndecl)
1632 = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl),
4399cf59 1633 RESULT_DECL, 0, restype);
15488554 1634 fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
6744a6ab
JH
1635
1636 /* The back end expects DECL_INITIAL to contain a BLOCK, so we
1637 create one. */
1638 fn_block = make_node (BLOCK);
1639 BLOCK_VARS (fn_block) = a;
1640 DECL_INITIAL (thunk_fndecl) = fn_block;
1641 init_function_start (thunk_fndecl);
1642 cfun->is_thunk = 1;
1643 assemble_start_function (thunk_fndecl, fnname);
1644
1645 targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl,
1646 fixed_offset, virtual_value, alias);
1647
1648 assemble_end_function (thunk_fndecl, fnname);
1649 init_insn_lengths ();
1650 free_after_compilation (cfun);
1651 set_cfun (NULL);
1652 TREE_ASM_WRITTEN (thunk_fndecl) = 1;
c47d0034
JH
1653 node->thunk.thunk_p = false;
1654 node->analyzed = false;
6744a6ab
JH
1655 }
1656 else
1657 {
1658 tree restype;
1659 basic_block bb, then_bb, else_bb, return_bb;
1660 gimple_stmt_iterator bsi;
1661 int nargs = 0;
1662 tree arg;
1663 int i;
1664 tree resdecl;
1665 tree restmp = NULL;
1666 VEC(tree, heap) *vargs;
1667
1668 gimple call;
1669 gimple ret;
1670
1671 DECL_IGNORED_P (thunk_fndecl) = 1;
1672 bitmap_obstack_initialize (NULL);
1673
1674 if (node->thunk.virtual_offset_p)
1675 virtual_offset = size_int (virtual_value);
1676
1677 /* Build the return declaration for the function. */
1678 restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1679 if (DECL_RESULT (thunk_fndecl) == NULL_TREE)
1680 {
1681 resdecl = build_decl (input_location, RESULT_DECL, 0, restype);
1682 DECL_ARTIFICIAL (resdecl) = 1;
1683 DECL_IGNORED_P (resdecl) = 1;
1684 DECL_RESULT (thunk_fndecl) = resdecl;
1685 }
1686 else
1687 resdecl = DECL_RESULT (thunk_fndecl);
1688
1689 bb = then_bb = else_bb = return_bb = init_lowered_empty_function (thunk_fndecl);
1690
1691 bsi = gsi_start_bb (bb);
1692
1693 /* Build call to the function being thunked. */
1694 if (!VOID_TYPE_P (restype))
1695 {
1696 if (!is_gimple_reg_type (restype))
1697 {
1698 restmp = resdecl;
c021f10b 1699 add_local_decl (cfun, restmp);
6744a6ab
JH
1700 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp;
1701 }
1702 else
1703 restmp = create_tmp_var_raw (restype, "retval");
1704 }
1705
910ad8de 1706 for (arg = a; arg; arg = DECL_CHAIN (arg))
6744a6ab
JH
1707 nargs++;
1708 vargs = VEC_alloc (tree, heap, nargs);
1709 if (this_adjusting)
1710 VEC_quick_push (tree, vargs,
1711 thunk_adjust (&bsi,
1712 a, 1, fixed_offset,
1713 virtual_offset));
1714 else
1715 VEC_quick_push (tree, vargs, a);
910ad8de 1716 for (i = 1, arg = DECL_CHAIN (a); i < nargs; i++, arg = DECL_CHAIN (arg))
6744a6ab
JH
1717 VEC_quick_push (tree, vargs, arg);
1718 call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs);
1719 VEC_free (tree, heap, vargs);
6744a6ab
JH
1720 gimple_call_set_from_thunk (call, true);
1721 if (restmp)
1722 gimple_call_set_lhs (call, restmp);
1723 gsi_insert_after (&bsi, call, GSI_NEW_STMT);
1724 mark_symbols_for_renaming (call);
1725 find_referenced_vars_in (call);
1726 update_stmt (call);
1727
1728 if (restmp && !this_adjusting)
1729 {
1124098b 1730 tree true_label = NULL_TREE;
6744a6ab
JH
1731
1732 if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE)
1733 {
1734 gimple stmt;
1735 /* If the return type is a pointer, we need to
1736 protect against NULL. We know there will be an
1737 adjustment, because that's why we're emitting a
1738 thunk. */
1739 then_bb = create_basic_block (NULL, (void *) 0, bb);
1740 return_bb = create_basic_block (NULL, (void *) 0, then_bb);
1741 else_bb = create_basic_block (NULL, (void *) 0, else_bb);
1742 remove_edge (single_succ_edge (bb));
1743 true_label = gimple_block_label (then_bb);
6744a6ab 1744 stmt = gimple_build_cond (NE_EXPR, restmp,
e8160c9a 1745 build_zero_cst (TREE_TYPE (restmp)),
6744a6ab
JH
1746 NULL_TREE, NULL_TREE);
1747 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1748 make_edge (bb, then_bb, EDGE_TRUE_VALUE);
1749 make_edge (bb, else_bb, EDGE_FALSE_VALUE);
1750 make_edge (return_bb, EXIT_BLOCK_PTR, 0);
1751 make_edge (then_bb, return_bb, EDGE_FALLTHRU);
1752 make_edge (else_bb, return_bb, EDGE_FALLTHRU);
1753 bsi = gsi_last_bb (then_bb);
1754 }
1755
1756 restmp = thunk_adjust (&bsi, restmp, /*this_adjusting=*/0,
1757 fixed_offset, virtual_offset);
1758 if (true_label)
1759 {
1760 gimple stmt;
1761 bsi = gsi_last_bb (else_bb);
e8160c9a
NF
1762 stmt = gimple_build_assign (restmp,
1763 build_zero_cst (TREE_TYPE (restmp)));
6744a6ab
JH
1764 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1765 bsi = gsi_last_bb (return_bb);
1766 }
1767 }
1768 else
1769 gimple_call_set_tail (call, true);
1770
1771 /* Build return value. */
1772 ret = gimple_build_return (restmp);
1773 gsi_insert_after (&bsi, ret, GSI_NEW_STMT);
1774
1775 delete_unreachable_blocks ();
1776 update_ssa (TODO_update_ssa);
1777
6744a6ab
JH
1778 /* Since we want to emit the thunk, we explicitly mark its name as
1779 referenced. */
c47d0034
JH
1780 node->thunk.thunk_p = false;
1781 cgraph_node_remove_callees (node);
6744a6ab
JH
1782 cgraph_add_new_function (thunk_fndecl, true);
1783 bitmap_obstack_release (NULL);
1784 }
1785 current_function_decl = NULL;
1786}
1787
c47d0034 1788
39e2db00
JH
1789
1790/* Assemble thunks and aliases asociated to NODE. */
c47d0034
JH
1791
1792static void
39e2db00 1793assemble_thunks_and_aliases (struct cgraph_node *node)
c47d0034
JH
1794{
1795 struct cgraph_edge *e;
39e2db00
JH
1796 int i;
1797 struct ipa_ref *ref;
1798
c47d0034
JH
1799 for (e = node->callers; e;)
1800 if (e->caller->thunk.thunk_p)
1801 {
1802 struct cgraph_node *thunk = e->caller;
1803
1804 e = e->next_caller;
39e2db00 1805 assemble_thunks_and_aliases (thunk);
c47d0034
JH
1806 assemble_thunk (thunk);
1807 }
1808 else
1809 e = e->next_caller;
5932a4d4 1810 for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list,
960bfb69 1811 i, ref); i++)
39e2db00
JH
1812 if (ref->use == IPA_REF_ALIAS)
1813 {
5932a4d4 1814 struct cgraph_node *alias = ipa_ref_referring_node (ref);
42f833bc
JH
1815 bool saved_written = TREE_ASM_WRITTEN (alias->thunk.alias);
1816
1817 /* Force assemble_alias to really output the alias this time instead
1818 of buffering it in same alias pairs. */
1819 TREE_ASM_WRITTEN (alias->thunk.alias) = 1;
960bfb69 1820 assemble_alias (alias->symbol.decl,
39e2db00
JH
1821 DECL_ASSEMBLER_NAME (alias->thunk.alias));
1822 assemble_thunks_and_aliases (alias);
42f833bc 1823 TREE_ASM_WRITTEN (alias->thunk.alias) = saved_written;
39e2db00 1824 }
c47d0034
JH
1825}
1826
452aa9c5
RG
1827/* Perform IPA transforms and all further optimizations and compilation
1828 for FNDECL. */
0878843f 1829
452aa9c5 1830static void
0878843f
RG
1831tree_rest_of_compilation (struct cgraph_node *node)
1832{
960bfb69 1833 tree fndecl = node->symbol.decl;
0878843f
RG
1834 location_t saved_loc;
1835
1836 timevar_push (TV_REST_OF_COMPILATION);
1837
1838 gcc_assert (cgraph_global_info_ready);
1839
1840 /* Initialize the default bitmap obstack. */
1841 bitmap_obstack_initialize (NULL);
1842
1843 /* Initialize the RTL code for the function. */
1844 current_function_decl = fndecl;
1845 saved_loc = input_location;
1846 input_location = DECL_SOURCE_LOCATION (fndecl);
1847 init_function_start (fndecl);
1848
1849 gimple_register_cfg_hooks ();
1850
1851 bitmap_obstack_initialize (&reg_obstack); /* FIXME, only at RTL generation*/
1852
1853 execute_all_ipa_transforms ();
1854
1855 /* Perform all tree transforms and optimizations. */
1856
1857 /* Signal the start of passes. */
1858 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START, NULL);
1859
1860 execute_pass_list (all_passes);
1861
1862 /* Signal the end of passes. */
1863 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END, NULL);
1864
1865 bitmap_obstack_release (&reg_obstack);
1866
1867 /* Release the default bitmap obstack. */
1868 bitmap_obstack_release (NULL);
1869
1870 set_cfun (NULL);
1871
1872 /* If requested, warn about function definitions where the function will
1873 return a value (usually of some struct or union type) which itself will
1874 take up a lot of stack space. */
1875 if (warn_larger_than && !DECL_EXTERNAL (fndecl) && TREE_TYPE (fndecl))
1876 {
1877 tree ret_type = TREE_TYPE (TREE_TYPE (fndecl));
1878
1879 if (ret_type && TYPE_SIZE_UNIT (ret_type)
1880 && TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST
1881 && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type),
1882 larger_than_size))
1883 {
1884 unsigned int size_as_int
1885 = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type));
1886
1887 if (compare_tree_int (TYPE_SIZE_UNIT (ret_type), size_as_int) == 0)
1888 warning (OPT_Wlarger_than_, "size of return value of %q+D is %u bytes",
1889 fndecl, size_as_int);
1890 else
1891 warning (OPT_Wlarger_than_, "size of return value of %q+D is larger than %wd bytes",
1892 fndecl, larger_than_size);
1893 }
1894 }
1895
1896 gimple_set_body (fndecl, NULL);
1897 if (DECL_STRUCT_FUNCTION (fndecl) == 0
1898 && !cgraph_get_node (fndecl)->origin)
1899 {
1900 /* Stop pointing to the local nodes about to be freed.
1901 But DECL_INITIAL must remain nonzero so we know this
1902 was an actual function definition.
1903 For a nested function, this is done in c_pop_function_context.
1904 If rest_of_compilation set this to 0, leave it 0. */
1905 if (DECL_INITIAL (fndecl) != 0)
1906 DECL_INITIAL (fndecl) = error_mark_node;
1907 }
1908
1909 input_location = saved_loc;
1910
1911 ggc_collect ();
1912 timevar_pop (TV_REST_OF_COMPILATION);
1913}
1914
1c4a429a 1915/* Expand function specified by NODE. */
7660e67e 1916
1c4a429a 1917static void
db0e878d 1918cgraph_expand_function (struct cgraph_node *node)
1c4a429a 1919{
960bfb69 1920 tree decl = node->symbol.decl;
1c4a429a 1921
18c6ada9 1922 /* We ought to not compile any inline clones. */
341c100f 1923 gcc_assert (!node->global.inlined_to);
18c6ada9 1924
7e8b322a 1925 announce_function (decl);
257eb6e3 1926 node->process = 0;
5806d9ac
JH
1927 gcc_assert (node->lowered);
1928
1929 /* Generate RTL for the body of DECL. */
0878843f 1930 tree_rest_of_compilation (node);
5806d9ac
JH
1931
1932 /* Make sure that BE didn't give up on compiling. */
1933 gcc_assert (TREE_ASM_WRITTEN (decl));
1934 current_function_decl = NULL;
85ad2ef5 1935 gcc_assert (!cgraph_preserve_function_body_p (node));
1bb7e8f8
JH
1936
1937 /* It would make a lot more sense to output thunks before function body to get more
1938 forward and lest backwarding jumps. This is however would need solving problem
1939 with comdats. See PR48668. Also aliases must come after function itself to
1940 make one pass assemblers, like one on AIX happy. See PR 50689.
1941 FIXME: Perhaps thunks should be move before function IFF they are not in comdat
1942 groups. */
1943 assemble_thunks_and_aliases (node);
39ecc018
JH
1944 cgraph_release_function_body (node);
1945 /* Eliminate all call edges. This is important so the GIMPLE_CALL no longer
1946 points to the dead function body. */
1947 cgraph_node_remove_callees (node);
1c4a429a
JH
1948}
1949
18c6ada9 1950/* Return true when CALLER_DECL should be inlined into CALLEE_DECL. */
b58b1157
JH
1951
1952bool
61a05df1 1953cgraph_inline_p (struct cgraph_edge *e, cgraph_inline_failed_t *reason)
b58b1157 1954{
18c6ada9
JH
1955 *reason = e->inline_failed;
1956 return !e->inline_failed;
b58b1157 1957}
18c6ada9 1958
6674a6ce 1959
6674a6ce 1960
db0e878d
AJ
1961/* Expand all functions that must be output.
1962
b58b1157
JH
1963 Attempt to topologically sort the nodes so function is output when
1964 all called functions are already assembled to allow data to be
a98ebe2e 1965 propagated across the callgraph. Use a stack to get smaller distance
d1a6adeb 1966 between a function and its callees (later we may choose to use a more
b58b1157
JH
1967 sophisticated algorithm for function reordering; we will likely want
1968 to use subsections to make the output functions appear in top-down
1969 order). */
1970
1971static void
a20af5b8 1972cgraph_expand_all_functions (void)
b58b1157
JH
1973{
1974 struct cgraph_node *node;
5ed6ace5 1975 struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
f30cfcb1 1976 int order_pos, new_order_pos = 0;
b58b1157
JH
1977 int i;
1978
af8bca3c 1979 order_pos = ipa_reverse_postorder (order);
341c100f 1980 gcc_assert (order_pos == cgraph_n_nodes);
b58b1157 1981
1ae58c30 1982 /* Garbage collector may remove inline clones we eliminate during
18c6ada9
JH
1983 optimization. So we must be sure to not reference them. */
1984 for (i = 0; i < order_pos; i++)
257eb6e3 1985 if (order[i]->process)
18c6ada9
JH
1986 order[new_order_pos++] = order[i];
1987
1988 for (i = new_order_pos - 1; i >= 0; i--)
b58b1157
JH
1989 {
1990 node = order[i];
257eb6e3 1991 if (node->process)
b58b1157 1992 {
341c100f 1993 gcc_assert (node->reachable);
257eb6e3 1994 node->process = 0;
b58b1157
JH
1995 cgraph_expand_function (node);
1996 }
1997 }
f45e0ad1 1998 cgraph_process_new_functions ();
50674e96 1999
b58b1157 2000 free (order);
50674e96 2001
b58b1157
JH
2002}
2003
474eccc6
ILT
2004/* This is used to sort the node types by the cgraph order number. */
2005
24b97832
ILT
2006enum cgraph_order_sort_kind
2007{
2008 ORDER_UNDEFINED = 0,
2009 ORDER_FUNCTION,
2010 ORDER_VAR,
2011 ORDER_ASM
2012};
2013
474eccc6
ILT
2014struct cgraph_order_sort
2015{
24b97832 2016 enum cgraph_order_sort_kind kind;
474eccc6
ILT
2017 union
2018 {
2019 struct cgraph_node *f;
8a4a83ed 2020 struct varpool_node *v;
474eccc6
ILT
2021 struct cgraph_asm_node *a;
2022 } u;
2023};
2024
2025/* Output all functions, variables, and asm statements in the order
2026 according to their order fields, which is the order in which they
2027 appeared in the file. This implements -fno-toplevel-reorder. In
2028 this mode we may output functions and variables which don't really
2029 need to be output. */
2030
2031static void
2032cgraph_output_in_order (void)
2033{
2034 int max;
474eccc6
ILT
2035 struct cgraph_order_sort *nodes;
2036 int i;
2037 struct cgraph_node *pf;
8a4a83ed 2038 struct varpool_node *pv;
474eccc6
ILT
2039 struct cgraph_asm_node *pa;
2040
2aae7680 2041 max = symtab_order;
33283dad 2042 nodes = XCNEWVEC (struct cgraph_order_sort, max);
474eccc6 2043
8a4a83ed 2044 varpool_analyze_pending_decls ();
474eccc6 2045
65c70e6b 2046 FOR_EACH_DEFINED_FUNCTION (pf)
474eccc6 2047 {
39e2db00 2048 if (pf->process && !pf->thunk.thunk_p && !pf->alias)
474eccc6 2049 {
960bfb69 2050 i = pf->symbol.order;
474eccc6
ILT
2051 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
2052 nodes[i].kind = ORDER_FUNCTION;
2053 nodes[i].u.f = pf;
2054 }
2055 }
2056
65c70e6b 2057 FOR_EACH_DEFINED_VARIABLE (pv)
474eccc6 2058 {
960bfb69 2059 i = pv->symbol.order;
474eccc6
ILT
2060 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
2061 nodes[i].kind = ORDER_VAR;
2062 nodes[i].u.v = pv;
2063 }
2064
2065 for (pa = cgraph_asm_nodes; pa; pa = pa->next)
2066 {
2067 i = pa->order;
2068 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
2069 nodes[i].kind = ORDER_ASM;
2070 nodes[i].u.a = pa;
2071 }
474eccc6 2072
7386e3ee
JH
2073 /* In toplevel reorder mode we output all statics; mark them as needed. */
2074 for (i = 0; i < max; ++i)
2075 {
2076 if (nodes[i].kind == ORDER_VAR)
2077 {
2078 varpool_mark_needed_node (nodes[i].u.v);
2079 }
2080 }
2081 varpool_empty_needed_queue ();
2082
7fece979
JJ
2083 for (i = 0; i < max; ++i)
2084 if (nodes[i].kind == ORDER_VAR)
2085 varpool_finalize_named_section_flags (nodes[i].u.v);
2086
474eccc6
ILT
2087 for (i = 0; i < max; ++i)
2088 {
2089 switch (nodes[i].kind)
2090 {
2091 case ORDER_FUNCTION:
257eb6e3 2092 nodes[i].u.f->process = 0;
474eccc6
ILT
2093 cgraph_expand_function (nodes[i].u.f);
2094 break;
2095
2096 case ORDER_VAR:
8a4a83ed 2097 varpool_assemble_decl (nodes[i].u.v);
474eccc6
ILT
2098 break;
2099
2100 case ORDER_ASM:
2101 assemble_asm (nodes[i].u.a->asm_str);
2102 break;
2103
2104 case ORDER_UNDEFINED:
2105 break;
2106
2107 default:
2108 gcc_unreachable ();
2109 }
2110 }
e7b9eb2c
ILT
2111
2112 cgraph_asm_nodes = NULL;
33283dad 2113 free (nodes);
474eccc6
ILT
2114}
2115
18c6ada9
JH
2116/* Return true when function body of DECL still needs to be kept around
2117 for later re-use. */
2118bool
85ad2ef5 2119cgraph_preserve_function_body_p (struct cgraph_node *node)
18c6ada9 2120{
c37f4ba4 2121 gcc_assert (cgraph_global_info_ready);
39e2db00 2122 gcc_assert (!node->alias && !node->thunk.thunk_p);
85ad2ef5 2123
18c6ada9 2124 /* Look if there is any clone around. */
9187e02d
JH
2125 if (node->clones)
2126 return true;
18c6ada9
JH
2127 return false;
2128}
2129
ef330312
PB
2130static void
2131ipa_passes (void)
2132{
db2960f4 2133 set_cfun (NULL);
04b201a2 2134 current_function_decl = NULL;
726a989a 2135 gimple_register_cfg_hooks ();
ef330312 2136 bitmap_obstack_initialize (NULL);
b20996ff 2137
090fa0ab
GF
2138 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START, NULL);
2139
b20996ff 2140 if (!in_lto_p)
0430f80c
RG
2141 {
2142 execute_ipa_pass_list (all_small_ipa_passes);
2143 if (seen_error ())
2144 return;
2145 }
3baf459d 2146
467a8db0
JH
2147 /* We never run removal of unreachable nodes after early passes. This is
2148 because TODO is run before the subpasses. It is important to remove
2149 the unreachable functions to save works at IPA level and to get LTO
2150 symbol tables right. */
2151 cgraph_remove_unreachable_nodes (true, cgraph_dump_file);
2152
d7f09764
DN
2153 /* If pass_all_early_optimizations was not scheduled, the state of
2154 the cgraph will not be properly updated. Update it now. */
2155 if (cgraph_state < CGRAPH_STATE_IPA_SSA)
2156 cgraph_state = CGRAPH_STATE_IPA_SSA;
3baf459d 2157
d7f09764
DN
2158 if (!in_lto_p)
2159 {
2160 /* Generate coverage variables and constructors. */
2161 coverage_finish ();
2162
2163 /* Process new functions added. */
2164 set_cfun (NULL);
2165 current_function_decl = NULL;
2166 cgraph_process_new_functions ();
d7f09764 2167
090fa0ab
GF
2168 execute_ipa_summary_passes
2169 ((struct ipa_opt_pass_d *) all_regular_ipa_passes);
fb3f88cc 2170 }
c082f9f3
SB
2171
2172 /* Some targets need to handle LTO assembler output specially. */
2173 if (flag_generate_lto)
2174 targetm.asm_out.lto_start ();
2175
d7f09764
DN
2176 execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_lto_gen_passes);
2177
2178 if (!in_lto_p)
2179 ipa_write_summaries ();
2180
c082f9f3
SB
2181 if (flag_generate_lto)
2182 targetm.asm_out.lto_end ();
2183
cc8547a7 2184 if (!flag_ltrans && (in_lto_p || !flag_lto || flag_fat_lto_objects))
fb3f88cc 2185 execute_ipa_pass_list (all_regular_ipa_passes);
090fa0ab 2186 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END, NULL);
3baf459d 2187
ef330312
PB
2188 bitmap_obstack_release (NULL);
2189}
2190
25e2c40d
JH
2191
2192/* Return string alias is alias of. */
2193
2194static tree
2195get_alias_symbol (tree decl)
2196{
2197 tree alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
2198 return get_identifier (TREE_STRING_POINTER
2199 (TREE_VALUE (TREE_VALUE (alias))));
2200}
2201
2202
c9552bff
JH
2203/* Weakrefs may be associated to external decls and thus not output
2204 at expansion time. Emit all neccesary aliases. */
2205
a66f86bb 2206static void
c9552bff
JH
2207output_weakrefs (void)
2208{
2209 struct cgraph_node *node;
2210 struct varpool_node *vnode;
65c70e6b 2211 FOR_EACH_FUNCTION (node)
960bfb69
JH
2212 if (node->alias && DECL_EXTERNAL (node->symbol.decl)
2213 && !TREE_ASM_WRITTEN (node->symbol.decl)
2214 && lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
2215 assemble_alias (node->symbol.decl,
25e2c40d 2216 node->thunk.alias ? DECL_ASSEMBLER_NAME (node->thunk.alias)
960bfb69 2217 : get_alias_symbol (node->symbol.decl));
65c70e6b 2218 FOR_EACH_VARIABLE (vnode)
960bfb69
JH
2219 if (vnode->alias && DECL_EXTERNAL (vnode->symbol.decl)
2220 && !TREE_ASM_WRITTEN (vnode->symbol.decl)
2221 && lookup_attribute ("weakref", DECL_ATTRIBUTES (vnode->symbol.decl)))
2222 assemble_alias (vnode->symbol.decl,
25e2c40d 2223 vnode->alias_of ? DECL_ASSEMBLER_NAME (vnode->alias_of)
960bfb69 2224 : get_alias_symbol (vnode->symbol.decl));
c9552bff
JH
2225}
2226
4537ec0c 2227
4537ec0c 2228
9b3e897d
PB
2229void
2230init_cgraph (void)
2231{
a05541a9
JH
2232 if (!cgraph_dump_file)
2233 cgraph_dump_file = dump_begin (TDI_cgraph, NULL);
9b3e897d 2234}
57fb5341 2235
c22cacf3 2236/* The edges representing the callers of the NEW_VERSION node were
57fb5341
RL
2237 fixed by cgraph_function_versioning (), now the call_expr in their
2238 respective tree code should be updated to call the NEW_VERSION. */
2239
2240static void
2241update_call_expr (struct cgraph_node *new_version)
2242{
2243 struct cgraph_edge *e;
2244
2245 gcc_assert (new_version);
726a989a
RB
2246
2247 /* Update the call expr on the edges to call the new version. */
57fb5341 2248 for (e = new_version->callers; e; e = e->next_caller)
c0ab1df3 2249 {
960bfb69
JH
2250 struct function *inner_function = DECL_STRUCT_FUNCTION (e->caller->symbol.decl);
2251 gimple_call_set_fndecl (e->call_stmt, new_version->symbol.decl);
1d65f45c 2252 maybe_clean_eh_stmt_fn (inner_function, e->call_stmt);
c0ab1df3 2253 }
57fb5341
RL
2254}
2255
2256
2257/* Create a new cgraph node which is the new version of
2258 OLD_VERSION node. REDIRECT_CALLERS holds the callers
2259 edges which should be redirected to point to
2260 NEW_VERSION. ALL the callees edges of OLD_VERSION
2261 are cloned to the new version node. Return the new
91382288
JH
2262 version node.
2263
2264 If non-NULL BLOCK_TO_COPY determine what basic blocks
2265 was copied to prevent duplications of calls that are dead
2266 in the clone. */
57fb5341 2267
0a35513e 2268struct cgraph_node *
57fb5341 2269cgraph_copy_node_for_versioning (struct cgraph_node *old_version,
b2c0ad40 2270 tree new_decl,
91382288
JH
2271 VEC(cgraph_edge_p,heap) *redirect_callers,
2272 bitmap bbs_to_copy)
2273 {
57fb5341 2274 struct cgraph_node *new_version;
ae2b0888 2275 struct cgraph_edge *e;
57fb5341
RL
2276 unsigned i;
2277
2278 gcc_assert (old_version);
c22cacf3 2279
a358e188 2280 new_version = cgraph_create_node (new_decl);
57fb5341 2281
0a35513e 2282 new_version->analyzed = old_version->analyzed;
57fb5341 2283 new_version->local = old_version->local;
960bfb69 2284 new_version->symbol.externally_visible = false;
65c70e6b 2285 new_version->local.local = old_version->analyzed;
57fb5341 2286 new_version->global = old_version->global;
8cf9feca 2287 new_version->rtl = old_version->rtl;
57fb5341
RL
2288 new_version->reachable = true;
2289 new_version->count = old_version->count;
2290
036546e5 2291 for (e = old_version->callees; e; e=e->next_callee)
91382288
JH
2292 if (!bbs_to_copy
2293 || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
2294 cgraph_clone_edge (e, new_version, e->call_stmt,
2295 e->lto_stmt_uid, REG_BR_PROB_BASE,
2296 CGRAPH_FREQ_BASE,
898b8927 2297 true);
036546e5 2298 for (e = old_version->indirect_calls; e; e=e->next_callee)
91382288
JH
2299 if (!bbs_to_copy
2300 || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
2301 cgraph_clone_edge (e, new_version, e->call_stmt,
2302 e->lto_stmt_uid, REG_BR_PROB_BASE,
2303 CGRAPH_FREQ_BASE,
898b8927 2304 true);
ac47786e 2305 FOR_EACH_VEC_ELT (cgraph_edge_p, redirect_callers, i, e)
b2c0ad40
KH
2306 {
2307 /* Redirect calls to the old version node to point to its new
2308 version. */
2309 cgraph_redirect_edge_callee (e, new_version);
2310 }
57fb5341 2311
b0d0a291
PM
2312 cgraph_call_node_duplication_hooks (old_version, new_version);
2313
57fb5341
RL
2314 return new_version;
2315 }
2316
2317 /* Perform function versioning.
c22cacf3 2318 Function versioning includes copying of the tree and
57fb5341
RL
2319 a callgraph update (creating a new cgraph node and updating
2320 its callees and callers).
2321
2322 REDIRECT_CALLERS varray includes the edges to be redirected
2323 to the new version.
2324
2325 TREE_MAP is a mapping of tree nodes we want to replace with
2326 new ones (according to results of prior analysis).
2327 OLD_VERSION_NODE is the node that is versioned.
1a2c27e9 2328
91382288
JH
2329 If non-NULL ARGS_TO_SKIP determine function parameters to remove
2330 from new version.
1a2c27e9 2331 If SKIP_RETURN is true, the new version will return void.
91382288 2332 If non-NULL BLOCK_TO_COPY determine what basic blocks to copy.
1a2c27e9
EB
2333 If non_NULL NEW_ENTRY determine new entry BB of the clone.
2334
2335 Return the new version's cgraph node. */
57fb5341
RL
2336
2337struct cgraph_node *
2338cgraph_function_versioning (struct cgraph_node *old_version_node,
b2c0ad40 2339 VEC(cgraph_edge_p,heap) *redirect_callers,
9187e02d 2340 VEC (ipa_replace_map_p,gc)* tree_map,
036546e5 2341 bitmap args_to_skip,
1a2c27e9 2342 bool skip_return,
91382288
JH
2343 bitmap bbs_to_copy,
2344 basic_block new_entry_block,
036546e5 2345 const char *clone_name)
57fb5341 2346{
960bfb69 2347 tree old_decl = old_version_node->symbol.decl;
57fb5341
RL
2348 struct cgraph_node *new_version_node = NULL;
2349 tree new_decl;
2350
2351 if (!tree_versionable_function_p (old_decl))
2352 return NULL;
2353
61e03ffc
JH
2354 gcc_assert (old_version_node->local.can_change_signature || !args_to_skip);
2355
1a2c27e9
EB
2356 /* Make a new FUNCTION_DECL tree node for the new version. */
2357 if (!args_to_skip && !skip_return)
c6f7cfc1
JH
2358 new_decl = copy_node (old_decl);
2359 else
1a2c27e9
EB
2360 new_decl
2361 = build_function_decl_skip_args (old_decl, args_to_skip, skip_return);
57fb5341 2362
9990e02a
JH
2363 /* Generate a new name for the new version. */
2364 DECL_NAME (new_decl) = clone_function_name (old_decl, clone_name);
2365 SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
2366 SET_DECL_RTL (new_decl, NULL);
2367
2062f77b
PB
2368 /* When the old decl was a con-/destructor make sure the clone isn't. */
2369 DECL_STATIC_CONSTRUCTOR(new_decl) = 0;
2370 DECL_STATIC_DESTRUCTOR(new_decl) = 0;
2371
57fb5341
RL
2372 /* Create the new version's call-graph node.
2373 and update the edges of the new node. */
2374 new_version_node =
2375 cgraph_copy_node_for_versioning (old_version_node, new_decl,
91382288 2376 redirect_callers, bbs_to_copy);
57fb5341
RL
2377
2378 /* Copy the OLD_VERSION_NODE function tree to the new version. */
91382288 2379 tree_function_versioning (old_decl, new_decl, tree_map, false, args_to_skip,
1a2c27e9 2380 skip_return, bbs_to_copy, new_entry_block);
57fb5341 2381
c22cacf3 2382 /* Update the new version's properties.
c0ab1df3
AP
2383 Make The new version visible only within this translation unit. Make sure
2384 that is not weak also.
c22cacf3 2385 ??? We cannot use COMDAT linkage because there is no
57fb5341 2386 ABI support for this. */
960bfb69
JH
2387 cgraph_make_decl_local (new_version_node->symbol.decl);
2388 DECL_VIRTUAL_P (new_version_node->symbol.decl) = 0;
2389 new_version_node->symbol.externally_visible = 0;
57fb5341
RL
2390 new_version_node->local.local = 1;
2391 new_version_node->lowered = true;
e6e1c050 2392
c0ab1df3
AP
2393 /* Update the call_expr on the edges to call the new version node. */
2394 update_call_expr (new_version_node);
b8698a0f 2395
129a37fc 2396 cgraph_call_function_insertion_hooks (new_version_node);
57fb5341
RL
2397 return new_version_node;
2398}
ea99e0be 2399
9187e02d
JH
2400/* Given virtual clone, turn it into actual clone. */
2401static void
2402cgraph_materialize_clone (struct cgraph_node *node)
2403{
2404 bitmap_obstack_initialize (NULL);
960bfb69 2405 node->former_clone_of = node->clone_of->symbol.decl;
e466e2ce
JH
2406 if (node->clone_of->former_clone_of)
2407 node->former_clone_of = node->clone_of->former_clone_of;
9187e02d 2408 /* Copy the OLD_VERSION_NODE function tree to the new version. */
960bfb69 2409 tree_function_versioning (node->clone_of->symbol.decl, node->symbol.decl,
9187e02d 2410 node->clone.tree_map, true,
1a2c27e9
EB
2411 node->clone.args_to_skip, false,
2412 NULL, NULL);
08ad1d6d
JH
2413 if (cgraph_dump_file)
2414 {
960bfb69
JH
2415 dump_function_to_file (node->clone_of->symbol.decl, cgraph_dump_file, dump_flags);
2416 dump_function_to_file (node->symbol.decl, cgraph_dump_file, dump_flags);
08ad1d6d 2417 }
9187e02d
JH
2418
2419 /* Function is no longer clone. */
2420 if (node->next_sibling_clone)
2421 node->next_sibling_clone->prev_sibling_clone = node->prev_sibling_clone;
2422 if (node->prev_sibling_clone)
2423 node->prev_sibling_clone->next_sibling_clone = node->next_sibling_clone;
2424 else
2425 node->clone_of->clones = node->next_sibling_clone;
2426 node->next_sibling_clone = NULL;
2427 node->prev_sibling_clone = NULL;
0e3776db 2428 if (!node->clone_of->analyzed && !node->clone_of->clones)
f0c418dc
JH
2429 {
2430 cgraph_release_function_body (node->clone_of);
2431 cgraph_node_remove_callees (node->clone_of);
960bfb69 2432 ipa_remove_all_references (&node->clone_of->symbol.ref_list);
f0c418dc 2433 }
9187e02d
JH
2434 node->clone_of = NULL;
2435 bitmap_obstack_release (NULL);
2436}
2437
8132a837
MJ
2438/* If necessary, change the function declaration in the call statement
2439 associated with E so that it corresponds to the edge callee. */
2440
2441gimple
2442cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *e)
2443{
2444 tree decl = gimple_call_fndecl (e->call_stmt);
2445 gimple new_stmt;
ceeffab0 2446 gimple_stmt_iterator gsi;
437ffe7b
JH
2447#ifdef ENABLE_CHECKING
2448 struct cgraph_node *node;
2449#endif
8132a837 2450
3949c4a7 2451 if (e->indirect_unknown_callee
960bfb69 2452 || decl == e->callee->symbol.decl)
8132a837
MJ
2453 return e->call_stmt;
2454
437ffe7b 2455#ifdef ENABLE_CHECKING
3949c4a7
MJ
2456 if (decl)
2457 {
2458 node = cgraph_get_node (decl);
2459 gcc_assert (!node || !node->clone.combined_args_to_skip);
2460 }
437ffe7b 2461#endif
e466e2ce 2462
8132a837
MJ
2463 if (cgraph_dump_file)
2464 {
2465 fprintf (cgraph_dump_file, "updating call of %s/%i -> %s/%i: ",
2466 cgraph_node_name (e->caller), e->caller->uid,
2467 cgraph_node_name (e->callee), e->callee->uid);
2468 print_gimple_stmt (cgraph_dump_file, e->call_stmt, 0, dump_flags);
e466e2ce 2469 if (e->callee->clone.combined_args_to_skip)
8d2adc24
EB
2470 {
2471 fprintf (cgraph_dump_file, " combined args to skip: ");
2472 dump_bitmap (cgraph_dump_file,
2473 e->callee->clone.combined_args_to_skip);
e466e2ce 2474 }
8132a837
MJ
2475 }
2476
2477 if (e->callee->clone.combined_args_to_skip)
8d2adc24 2478 {
1b7d2dd1 2479 int lp_nr;
8d2adc24
EB
2480
2481 new_stmt
2482 = gimple_call_copy_skip_args (e->call_stmt,
2483 e->callee->clone.combined_args_to_skip);
960bfb69 2484 gimple_call_set_fndecl (new_stmt, e->callee->symbol.decl);
8d2adc24
EB
2485
2486 if (gimple_vdef (new_stmt)
2487 && TREE_CODE (gimple_vdef (new_stmt)) == SSA_NAME)
2488 SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt;
2489
81fa35bd 2490 gsi = gsi_for_stmt (e->call_stmt);
72351fa3 2491 gsi_replace (&gsi, new_stmt, false);
1b7d2dd1
RG
2492 /* We need to defer cleaning EH info on the new statement to
2493 fixup-cfg. We may not have dominator information at this point
2494 and thus would end up with unreachable blocks and have no way
2495 to communicate that we need to run CFG cleanup then. */
2496 lp_nr = lookup_stmt_eh_lp (e->call_stmt);
2497 if (lp_nr != 0)
2498 {
2499 remove_stmt_from_eh_lp (e->call_stmt);
2500 add_stmt_to_eh_lp (new_stmt, lp_nr);
2501 }
8d2adc24 2502 }
8132a837 2503 else
3d113394
RG
2504 {
2505 new_stmt = e->call_stmt;
960bfb69 2506 gimple_call_set_fndecl (new_stmt, e->callee->symbol.decl);
3d113394
RG
2507 update_stmt (new_stmt);
2508 }
8132a837 2509
8132a837
MJ
2510 cgraph_set_call_stmt_including_clones (e->caller, e->call_stmt, new_stmt);
2511
2512 if (cgraph_dump_file)
2513 {
2514 fprintf (cgraph_dump_file, " updated to:");
2515 print_gimple_stmt (cgraph_dump_file, e->call_stmt, 0, dump_flags);
2516 }
2517 return new_stmt;
2518}
2519
9187e02d 2520/* Once all functions from compilation unit are in memory, produce all clones
8132a837
MJ
2521 and update all calls. We might also do this on demand if we don't want to
2522 bring all functions to memory prior compilation, but current WHOPR
2523 implementation does that and it is is bit easier to keep everything right in
2524 this order. */
711417cd 2525static void
9187e02d
JH
2526cgraph_materialize_all_clones (void)
2527{
2528 struct cgraph_node *node;
2529 bool stabilized = false;
2530
2531 if (cgraph_dump_file)
2532 fprintf (cgraph_dump_file, "Materializing clones\n");
2533#ifdef ENABLE_CHECKING
2534 verify_cgraph ();
2535#endif
2536
2537 /* We can also do topological order, but number of iterations should be
2538 bounded by number of IPA passes since single IPA pass is probably not
2539 going to create clones of clones it created itself. */
2540 while (!stabilized)
2541 {
2542 stabilized = true;
65c70e6b 2543 FOR_EACH_FUNCTION (node)
9187e02d 2544 {
960bfb69
JH
2545 if (node->clone_of && node->symbol.decl != node->clone_of->symbol.decl
2546 && !gimple_has_body_p (node->symbol.decl))
9187e02d 2547 {
960bfb69 2548 if (gimple_has_body_p (node->clone_of->symbol.decl))
9187e02d
JH
2549 {
2550 if (cgraph_dump_file)
08ad1d6d 2551 {
61502ca8 2552 fprintf (cgraph_dump_file, "cloning %s to %s\n",
08ad1d6d
JH
2553 cgraph_node_name (node->clone_of),
2554 cgraph_node_name (node));
2555 if (node->clone.tree_map)
2556 {
2557 unsigned int i;
2558 fprintf (cgraph_dump_file, " replace map: ");
2559 for (i = 0; i < VEC_length (ipa_replace_map_p,
2560 node->clone.tree_map);
2561 i++)
2562 {
2563 struct ipa_replace_map *replace_info;
2564 replace_info = VEC_index (ipa_replace_map_p,
2565 node->clone.tree_map,
2566 i);
2567 print_generic_expr (cgraph_dump_file, replace_info->old_tree, 0);
2568 fprintf (cgraph_dump_file, " -> ");
2569 print_generic_expr (cgraph_dump_file, replace_info->new_tree, 0);
2570 fprintf (cgraph_dump_file, "%s%s;",
2571 replace_info->replace_p ? "(replace)":"",
2572 replace_info->ref_p ? "(ref)":"");
2573 }
2574 fprintf (cgraph_dump_file, "\n");
2575 }
2576 if (node->clone.args_to_skip)
2577 {
2578 fprintf (cgraph_dump_file, " args_to_skip: ");
2579 dump_bitmap (cgraph_dump_file, node->clone.args_to_skip);
2580 }
2581 if (node->clone.args_to_skip)
2582 {
2583 fprintf (cgraph_dump_file, " combined_args_to_skip:");
2584 dump_bitmap (cgraph_dump_file, node->clone.combined_args_to_skip);
2585 }
2586 }
9187e02d 2587 cgraph_materialize_clone (node);
36576655 2588 stabilized = false;
9187e02d 2589 }
9187e02d
JH
2590 }
2591 }
2592 }
65c70e6b 2593 FOR_EACH_FUNCTION (node)
47cb0d7d
JH
2594 if (!node->analyzed && node->callees)
2595 cgraph_node_remove_callees (node);
8132a837
MJ
2596 if (cgraph_dump_file)
2597 fprintf (cgraph_dump_file, "Materialization Call site updates done.\n");
9a23acef
JH
2598#ifdef ENABLE_CHECKING
2599 verify_cgraph ();
2600#endif
9187e02d
JH
2601 cgraph_remove_unreachable_nodes (false, cgraph_dump_file);
2602}
2603
711417cd
RG
2604
2605/* Perform simple optimizations based on callgraph. */
2606
2607void
2608cgraph_optimize (void)
2609{
2610 if (seen_error ())
2611 return;
2612
2613#ifdef ENABLE_CHECKING
474ffc72 2614 verify_symtab ();
711417cd
RG
2615#endif
2616
2617 /* Frontend may output common variables after the unit has been finalized.
2618 It is safe to deal with them here as they are always zero initialized. */
2619 varpool_analyze_pending_decls ();
2620
2621 timevar_push (TV_CGRAPHOPT);
2622 if (pre_ipa_mem_report)
2623 {
2624 fprintf (stderr, "Memory consumption before IPA\n");
2625 dump_memory_report (false);
2626 }
2627 if (!quiet_flag)
2628 fprintf (stderr, "Performing interprocedural optimizations\n");
2629 cgraph_state = CGRAPH_STATE_IPA;
2630
2631 /* Don't run the IPA passes if there was any error or sorry messages. */
2632 if (!seen_error ())
2633 ipa_passes ();
2634
2635 /* Do nothing else if any IPA pass found errors or if we are just streaming LTO. */
2636 if (seen_error ()
2637 || (!in_lto_p && flag_lto && !flag_fat_lto_objects))
2638 {
2639 timevar_pop (TV_CGRAPHOPT);
2640 return;
2641 }
2642
2643 /* This pass remove bodies of extern inline functions we never inlined.
2644 Do this later so other IPA passes see what is really going on. */
2645 cgraph_remove_unreachable_nodes (false, dump_file);
2646 cgraph_global_info_ready = true;
2647 if (cgraph_dump_file)
2648 {
2649 fprintf (cgraph_dump_file, "Optimized ");
8f940ee6 2650 dump_symtab (cgraph_dump_file);
711417cd
RG
2651 }
2652 if (post_ipa_mem_report)
2653 {
2654 fprintf (stderr, "Memory consumption after IPA\n");
2655 dump_memory_report (false);
2656 }
2657 timevar_pop (TV_CGRAPHOPT);
2658
2659 /* Output everything. */
2660 (*debug_hooks->assembly_start) ();
2661 if (!quiet_flag)
2662 fprintf (stderr, "Assembling functions:\n");
2663#ifdef ENABLE_CHECKING
474ffc72 2664 verify_symtab ();
711417cd
RG
2665#endif
2666
2667 cgraph_materialize_all_clones ();
2668 bitmap_obstack_initialize (NULL);
2669 execute_ipa_pass_list (all_late_ipa_passes);
2670 cgraph_remove_unreachable_nodes (true, dump_file);
2671#ifdef ENABLE_CHECKING
474ffc72 2672 verify_symtab ();
711417cd
RG
2673#endif
2674 bitmap_obstack_release (NULL);
2675 cgraph_mark_functions_to_output ();
2676 output_weakrefs ();
2677
2678 cgraph_state = CGRAPH_STATE_EXPANSION;
2679 if (!flag_toplevel_reorder)
2680 cgraph_output_in_order ();
2681 else
2682 {
2683 cgraph_output_pending_asms ();
2684
2685 cgraph_expand_all_functions ();
2686 varpool_remove_unreferenced_decls ();
2687
2688 varpool_assemble_pending_decls ();
2689 }
2690
2691 cgraph_process_new_functions ();
2692 cgraph_state = CGRAPH_STATE_FINISHED;
2693
2694 if (cgraph_dump_file)
2695 {
2696 fprintf (cgraph_dump_file, "\nFinal ");
8f940ee6 2697 dump_symtab (cgraph_dump_file);
711417cd
RG
2698 }
2699#ifdef ENABLE_CHECKING
474ffc72 2700 verify_symtab ();
711417cd
RG
2701 /* Double check that all inline clones are gone and that all
2702 function bodies have been released from memory. */
2703 if (!seen_error ())
2704 {
2705 struct cgraph_node *node;
2706 bool error_found = false;
2707
65c70e6b
JH
2708 FOR_EACH_DEFINED_FUNCTION (node)
2709 if (node->global.inlined_to
2710 || gimple_has_body_p (node->symbol.decl))
711417cd
RG
2711 {
2712 error_found = true;
2713 dump_cgraph_node (stderr, node);
2714 }
2715 if (error_found)
2716 internal_error ("nodes with unreleased memory found");
2717 }
2718#endif
2719}
2720
2721
2722/* Analyze the whole compilation unit once it is parsed completely. */
2723
2724void
2725cgraph_finalize_compilation_unit (void)
2726{
2727 timevar_push (TV_CGRAPH);
2728
2729 /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE. */
2730 if (flag_lto)
2731 lto_streamer_hooks_init ();
2732
2733 /* If we're here there's no current function anymore. Some frontends
2734 are lazy in clearing these. */
2735 current_function_decl = NULL;
2736 set_cfun (NULL);
2737
2738 /* Do not skip analyzing the functions if there were errors, we
2739 miss diagnostics for following functions otherwise. */
2740
2741 /* Emit size functions we didn't inline. */
2742 finalize_size_functions ();
2743
2744 /* Mark alias targets necessary and emit diagnostics. */
2745 finish_aliases_1 ();
2746 handle_alias_pairs ();
2747
2748 if (!quiet_flag)
2749 {
2750 fprintf (stderr, "\nAnalyzing compilation unit\n");
2751 fflush (stderr);
2752 }
2753
2754 if (flag_dump_passes)
2755 dump_passes ();
2756
2757 /* Gimplify and lower all functions, compute reachability and
2758 remove unreachable nodes. */
2759 cgraph_analyze_functions ();
2760
2761 /* Mark alias targets necessary and emit diagnostics. */
2762 finish_aliases_1 ();
2763 handle_alias_pairs ();
2764
2765 /* Gimplify and lower thunks. */
2766 cgraph_analyze_functions ();
2767
2768 /* Finally drive the pass manager. */
2769 cgraph_optimize ();
2770
2771 timevar_pop (TV_CGRAPH);
2772}
2773
2774
7be82279 2775#include "gt-cgraphunit.h"