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