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