]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/cgraphunit.c
re PR rtl-optimization/70467 (Useless "and [esp],-1" emitted on AND with uint64_t...
[thirdparty/gcc.git] / gcc / cgraphunit.c
CommitLineData
9c8305f8 1/* Driver of optimization process
818ab71a 2 Copyright (C) 2003-2016 Free Software Foundation, Inc.
1c4a429a
JH
3 Contributed by Jan Hubicka
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9dcd6f09 9Software Foundation; either version 3, or (at your option) any later
1c4a429a
JH
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
9dcd6f09
NC
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
1c4a429a 20
9c8305f8 21/* This module implements main driver of compilation process.
18c6ada9
JH
22
23 The main scope of this file is to act as an interface in between
9c8305f8 24 tree based frontends and the backend.
18c6ada9
JH
25
26 The front-end is supposed to use following functionality:
27
3dafb85c 28 - finalize_function
18c6ada9
JH
29
30 This function is called once front-end has parsed whole body of function
31 and it is certain that the function body nor the declaration will change.
32
efe75b6f
JH
33 (There is one exception needed for implementing GCC extern inline
34 function.)
18c6ada9 35
047ae098 36 - varpool_finalize_decl
18c6ada9 37
1ae58c30 38 This function has same behavior as the above but is used for static
18c6ada9
JH
39 variables.
40
65d630d4
JH
41 - add_asm_node
42
43 Insert new toplevel ASM statement
44
45 - finalize_compilation_unit
18c6ada9 46
efe75b6f
JH
47 This function is called once (source level) compilation unit is finalized
48 and it will no longer change.
18c6ada9 49
9c8305f8
JH
50 The symbol table is constructed starting from the trivially needed
51 symbols finalized by the frontend. Functions are lowered into
52 GIMPLE representation and callgraph/reference lists are constructed.
073a8998 53 Those are used to discover other necessary functions and variables.
9c8305f8
JH
54
55 At the end the bodies of unreachable functions are removed.
18c6ada9 56
efe75b6f 57 The function can be called multiple times when multiple source level
9c8305f8 58 compilation units are combined.
18c6ada9 59
65d630d4 60 - compile
18c6ada9 61
9c8305f8
JH
62 This passes control to the back-end. Optimizations are performed and
63 final assembler is generated. This is done in the following way. Note
64 that with link time optimization the process is split into three
65 stages (compile time, linktime analysis and parallel linktime as
66 indicated bellow).
67
68 Compile time:
69
70 1) Inter-procedural optimization.
71 (ipa_passes)
72
73 This part is further split into:
74
75 a) early optimizations. These are local passes executed in
76 the topological order on the callgraph.
77
78 The purpose of early optimiations is to optimize away simple
79 things that may otherwise confuse IP analysis. Very simple
80 propagation across the callgraph is done i.e. to discover
81 functions without side effects and simple inlining is performed.
82
83 b) early small interprocedural passes.
84
85 Those are interprocedural passes executed only at compilation
688010ba 86 time. These include, for example, transational memory lowering,
9c8305f8
JH
87 unreachable code removal and other simple transformations.
88
89 c) IP analysis stage. All interprocedural passes do their
90 analysis.
91
92 Interprocedural passes differ from small interprocedural
93 passes by their ability to operate across whole program
94 at linktime. Their analysis stage is performed early to
95 both reduce linking times and linktime memory usage by
96 not having to represent whole program in memory.
97
98 d) LTO sreaming. When doing LTO, everything important gets
99 streamed into the object file.
100
101 Compile time and or linktime analysis stage (WPA):
102
103 At linktime units gets streamed back and symbol table is
104 merged. Function bodies are not streamed in and not
105 available.
106 e) IP propagation stage. All IP passes execute their
107 IP propagation. This is done based on the earlier analysis
108 without having function bodies at hand.
109 f) Ltrans streaming. When doing WHOPR LTO, the program
110 is partitioned and streamed into multple object files.
18c6ada9 111
9c8305f8 112 Compile time and/or parallel linktime stage (ltrans)
18c6ada9 113
9c8305f8
JH
114 Each of the object files is streamed back and compiled
115 separately. Now the function bodies becomes available
116 again.
18c6ada9 117
9c8305f8
JH
118 2) Virtual clone materialization
119 (cgraph_materialize_clone)
18c6ada9 120
9c8305f8
JH
121 IP passes can produce copies of existing functoins (such
122 as versioned clones or inline clones) without actually
123 manipulating their bodies by creating virtual clones in
124 the callgraph. At this time the virtual clones are
125 turned into real functions
126 3) IP transformation
18c6ada9 127
9c8305f8
JH
128 All IP passes transform function bodies based on earlier
129 decision of the IP propagation.
18c6ada9 130
9c8305f8 131 4) late small IP passes
18c6ada9 132
9c8305f8 133 Simple IP passes working within single program partition.
18c6ada9 134
9c8305f8 135 5) Expansion
65d630d4 136 (expand_all_functions)
18c6ada9 137
9c8305f8
JH
138 At this stage functions that needs to be output into
139 assembler are identified and compiled in topological order
140 6) Output of variables and aliases
141 Now it is known what variable references was not optimized
142 out and thus all variables are output to the file.
18c6ada9 143
9c8305f8
JH
144 Note that with -fno-toplevel-reorder passes 5 and 6
145 are combined together in cgraph_output_in_order.
18c6ada9 146
9c8305f8
JH
147 Finally there are functions to manipulate the callgraph from
148 backend.
149 - cgraph_add_new_function is used to add backend produced
150 functions introduced after the unit is finalized.
151 The functions are enqueue for later processing and inserted
152 into callgraph with cgraph_process_new_functions.
9b3e897d 153
9c8305f8
JH
154 - cgraph_function_versioning
155
156 produces a copy of function into new one (a version)
157 and apply simple transformations
158*/
6674a6ce 159
1c4a429a
JH
160#include "config.h"
161#include "system.h"
162#include "coretypes.h"
c7131fb2 163#include "backend.h"
957060b5
AM
164#include "target.h"
165#include "rtl.h"
1c4a429a 166#include "tree.h"
c7131fb2 167#include "gimple.h"
957060b5
AM
168#include "cfghooks.h"
169#include "regset.h" /* FIXME: For reg_obstack. */
170#include "alloc-pool.h"
171#include "tree-pass.h"
172#include "stringpool.h"
173#include "gimple-ssa.h"
174#include "cgraph.h"
175#include "coverage.h"
176#include "lto-streamer.h"
40e23961 177#include "fold-const.h"
d8a2d370
DN
178#include "varasm.h"
179#include "stor-layout.h"
0878843f 180#include "output.h"
e677a9d4 181#include "cfgcleanup.h"
2fb9a547 182#include "gimple-fold.h"
45b0be94 183#include "gimplify.h"
5be5c238 184#include "gimple-iterator.h"
18f429e2 185#include "gimplify-me.h"
442b4905
AM
186#include "tree-cfg.h"
187#include "tree-into-ssa.h"
7a300452 188#include "tree-ssa.h"
1c4a429a 189#include "langhooks.h"
1c4a429a 190#include "toplev.h"
1c4a429a 191#include "debug.h"
dd912cb8 192#include "symbol-summary.h"
57fb5341 193#include "ipa-prop.h"
9c8305f8 194#include "gimple-pretty-print.h"
090fa0ab 195#include "plugin.h"
632b4f8e 196#include "ipa-inline.h"
af8bca3c 197#include "ipa-utils.h"
452aa9c5 198#include "except.h"
31ee20ba 199#include "cfgloop.h"
315f8c0e
DM
200#include "context.h"
201#include "pass_manager.h"
1fe37220 202#include "tree-nested.h"
2b5f0895 203#include "dbgcnt.h"
d5e254e1 204#include "tree-chkp.h"
1f6be682 205#include "lto-section-names.h"
b58b1157 206
66058468
JH
207/* Queue of cgraph nodes scheduled to be added into cgraph. This is a
208 secondary queue used during optimization to accommodate passes that
209 may generate new functions that need to be optimized and expanded. */
31acf1bb 210vec<cgraph_node *> cgraph_new_nodes;
66058468 211
65d630d4
JH
212static void expand_all_functions (void);
213static void mark_functions_to_output (void);
877ab5e9 214static void handle_alias_pairs (void);
7dff32e6 215
6744a6ab
JH
216/* Used for vtable lookup in thunk adjusting. */
217static GTY (()) tree vtable_entry_type;
218
3dafb85c 219/* Determine if symbol declaration is needed. That is, visible to something
edb983b2
JH
220 either outside this translation unit, something magic in the system
221 configury */
222bool
3dafb85c 223symtab_node::needed_p (void)
8dafba3c 224{
ead84f73
JH
225 /* Double check that no one output the function into assembly file
226 early. */
227 gcc_checking_assert (!DECL_ASSEMBLER_NAME_SET_P (decl)
40a7fe1e 228 || !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)));
e7d6beb0 229
3dafb85c 230 if (!definition)
edb983b2 231 return false;
a1d31187 232
edb983b2
JH
233 if (DECL_EXTERNAL (decl))
234 return false;
04f77d0f 235
edb983b2 236 /* If the user told us it is used, then it must be so. */
3dafb85c 237 if (force_output)
edb983b2
JH
238 return true;
239
240 /* ABI forced symbols are needed when they are external. */
3dafb85c 241 if (forced_by_abi && TREE_PUBLIC (decl))
edb983b2
JH
242 return true;
243
1bf7c324 244 /* Keep constructors, destructors and virtual functions. */
edb983b2
JH
245 if (TREE_CODE (decl) == FUNCTION_DECL
246 && (DECL_STATIC_CONSTRUCTOR (decl) || DECL_STATIC_DESTRUCTOR (decl)))
247 return true;
248
249 /* Externally visible variables must be output. The exception is
250 COMDAT variables that must be output only when they are needed. */
251 if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
8dafba3c
RH
252 return true;
253
8dafba3c
RH
254 return false;
255}
256
b4d05578
BS
257/* Head and terminator of the queue of nodes to be processed while building
258 callgraph. */
66058468 259
b4d05578
BS
260static symtab_node symtab_terminator;
261static symtab_node *queued_nodes = &symtab_terminator;
66058468 262
b4d05578 263/* Add NODE to queue starting at QUEUED_NODES.
66058468
JH
264 The queue is linked via AUX pointers and terminated by pointer to 1. */
265
266static void
5e20cdc9 267enqueue_node (symtab_node *node)
66058468 268{
67348ccc 269 if (node->aux)
66058468 270 return;
b4d05578
BS
271 gcc_checking_assert (queued_nodes);
272 node->aux = queued_nodes;
273 queued_nodes = node;
66058468
JH
274}
275
d60ab196 276/* Process CGRAPH_NEW_FUNCTIONS and perform actions necessary to add these
f45e0ad1
JH
277 functions into callgraph in a way so they look like ordinary reachable
278 functions inserted into callgraph already at construction time. */
279
b4d05578 280void
3dafb85c 281symbol_table::process_new_functions (void)
f45e0ad1 282{
f45e0ad1 283 tree fndecl;
f45e0ad1 284
31acf1bb 285 if (!cgraph_new_nodes.exists ())
b4d05578 286 return;
31acf1bb 287
877ab5e9 288 handle_alias_pairs ();
f45e0ad1
JH
289 /* Note that this queue may grow as its being processed, as the new
290 functions may generate new ones. */
31acf1bb 291 for (unsigned i = 0; i < cgraph_new_nodes.length (); i++)
f45e0ad1 292 {
31acf1bb 293 cgraph_node *node = cgraph_new_nodes[i];
67348ccc 294 fndecl = node->decl;
3dafb85c 295 switch (state)
f45e0ad1 296 {
3dafb85c 297 case CONSTRUCTION:
f45e0ad1
JH
298 /* At construction time we just need to finalize function and move
299 it into reachable functions list. */
300
3dafb85c
ML
301 cgraph_node::finalize_function (fndecl, false);
302 call_cgraph_insertion_hooks (node);
67348ccc 303 enqueue_node (node);
f45e0ad1
JH
304 break;
305
3dafb85c
ML
306 case IPA:
307 case IPA_SSA:
17e0fc92 308 case IPA_SSA_AFTER_INLINING:
f45e0ad1
JH
309 /* When IPA optimization already started, do all essential
310 transformations that has been already performed on the whole
311 cgraph but not on this function. */
312
726a989a 313 gimple_register_cfg_hooks ();
67348ccc 314 if (!node->analyzed)
d52f5295 315 node->analyze ();
f45e0ad1 316 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
17e0fc92 317 if ((state == IPA_SSA || state == IPA_SSA_AFTER_INLINING)
7a388ee4 318 && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
f7695dbf 319 g->get_passes ()->execute_early_local_passes ();
9a1e784a 320 else if (inline_summaries != NULL)
632b4f8e 321 compute_inline_parameters (node, true);
f45e0ad1
JH
322 free_dominance_info (CDI_POST_DOMINATORS);
323 free_dominance_info (CDI_DOMINATORS);
324 pop_cfun ();
82afdc6f 325 call_cgraph_insertion_hooks (node);
f45e0ad1
JH
326 break;
327
3dafb85c 328 case EXPANSION:
f45e0ad1
JH
329 /* Functions created during expansion shall be compiled
330 directly. */
257eb6e3 331 node->process = 0;
3dafb85c
ML
332 call_cgraph_insertion_hooks (node);
333 node->expand ();
f45e0ad1
JH
334 break;
335
336 default:
337 gcc_unreachable ();
338 break;
339 }
340 }
31acf1bb
ML
341
342 cgraph_new_nodes.release ();
f45e0ad1
JH
343}
344
d71cc23f
JH
345/* As an GCC extension we allow redefinition of the function. The
346 semantics when both copies of bodies differ is not well defined.
347 We replace the old body with new body so in unit at a time mode
348 we always use new body, while in normal mode we may end up with
349 old body inlined into some functions and new body expanded and
350 inlined in others.
351
352 ??? It may make more sense to use one body for inlining and other
353 body for expanding the function but this is difficult to do. */
354
e70670cf 355void
d52f5295 356cgraph_node::reset (void)
d71cc23f 357{
d52f5295 358 /* If process is set, then we have already begun whole-unit analysis.
7e8b322a
JH
359 This is *not* testing for whether we've already emitted the function.
360 That case can be sort-of legitimately seen with real function redefinition
361 errors. I would argue that the front end should never present us with
362 such a case, but don't enforce that for now. */
d52f5295 363 gcc_assert (!process);
d71cc23f
JH
364
365 /* Reset our data structures so we can analyze the function again. */
d52f5295
ML
366 memset (&local, 0, sizeof (local));
367 memset (&global, 0, sizeof (global));
368 memset (&rtl, 0, sizeof (rtl));
369 analyzed = false;
370 definition = false;
371 alias = false;
71e54687 372 transparent_alias = false;
d52f5295
ML
373 weakref = false;
374 cpp_implicit_alias = false;
375
376 remove_callees ();
377 remove_all_references ();
d71cc23f 378}
d853a20e 379
d7438551
AH
380/* Return true when there are references to the node. INCLUDE_SELF is
381 true if a self reference counts as a reference. */
838ff415 382
3dafb85c 383bool
d7438551 384symtab_node::referred_to_p (bool include_self)
838ff415 385{
3dafb85c 386 ipa_ref *ref = NULL;
838ff415 387
073a8998 388 /* See if there are any references at all. */
3dafb85c 389 if (iterate_referring (0, ref))
838ff415 390 return true;
65d630d4 391 /* For functions check also calls. */
3dafb85c 392 cgraph_node *cn = dyn_cast <cgraph_node *> (this);
5d59b5e1 393 if (cn && cn->callers)
d7438551
AH
394 {
395 if (include_self)
396 return true;
397 for (cgraph_edge *e = cn->callers; e; e = e->next_caller)
398 if (e->caller != this)
399 return true;
400 }
838ff415
JH
401 return false;
402}
403
6b00c969 404/* DECL has been parsed. Take it, queue it, compile it at the whim of the
15682f24 405 logic in effect. If NO_COLLECT is true, then our caller cannot stand to have
6b00c969
RH
406 the garbage collector run at the moment. We would need to either create
407 a new GC context, or just not compile right now. */
1c4a429a
JH
408
409void
3dafb85c 410cgraph_node::finalize_function (tree decl, bool no_collect)
1c4a429a 411{
3dafb85c 412 cgraph_node *node = cgraph_node::get_create (decl);
1c4a429a 413
67348ccc 414 if (node->definition)
b125ad45 415 {
15682f24
MJ
416 /* Nested functions should only be defined once. */
417 gcc_assert (!DECL_CONTEXT (decl)
418 || TREE_CODE (DECL_CONTEXT (decl)) != FUNCTION_DECL);
d52f5295 419 node->reset ();
b125ad45
JH
420 node->local.redefined_extern_inline = true;
421 }
6b00c969 422
6a1e352e
L
423 /* Set definition first before calling notice_global_symbol so that
424 it is available to notice_global_symbol. */
67348ccc 425 node->definition = true;
6a1e352e 426 notice_global_symbol (decl);
e21aff8a 427 node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL;
1c4a429a 428
ead84f73
JH
429 /* With -fkeep-inline-functions we are keeping all inline functions except
430 for extern inline ones. */
431 if (flag_keep_inline_functions
432 && DECL_DECLARED_INLINE_P (decl)
433 && !DECL_EXTERNAL (decl)
434 && !DECL_DISREGARD_INLINE_LIMITS (decl))
67348ccc 435 node->force_output = 1;
8dafba3c 436
ead84f73
JH
437 /* When not optimizing, also output the static functions. (see
438 PR24561), but don't do so for always_inline functions, functions
439 declared inline and nested functions. These were optimized out
440 in the original implementation and it is unclear whether we want
441 to change the behavior here. */
787da5fd 442 if (((!opt_for_fn (decl, optimize) || flag_keep_static_functions)
67348ccc 443 && !node->cpp_implicit_alias
ead84f73
JH
444 && !DECL_DISREGARD_INLINE_LIMITS (decl)
445 && !DECL_DECLARED_INLINE_P (decl)
446 && !(DECL_CONTEXT (decl)
447 && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL))
448 && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
67348ccc 449 node->force_output = 1;
ead84f73 450
8dafba3c 451 /* If we've not yet emitted decl, tell the debug info about it. */
6b00c969 452 if (!TREE_ASM_WRITTEN (decl))
8dafba3c 453 (*debug_hooks->deferred_inline_function) (decl);
d173e685 454
15682f24 455 if (!no_collect)
7e8b322a 456 ggc_collect ();
838ff415 457
3dafb85c
ML
458 if (symtab->state == CONSTRUCTION
459 && (node->needed_p () || node->referred_to_p ()))
67348ccc 460 enqueue_node (node);
1c4a429a
JH
461}
462
452aa9c5 463/* Add the function FNDECL to the call graph.
3dafb85c 464 Unlike finalize_function, this function is intended to be used
452aa9c5
RG
465 by middle end and allows insertion of new function at arbitrary point
466 of compilation. The function can be either in high, low or SSA form
467 GIMPLE.
468
469 The function is assumed to be reachable and have address taken (so no
470 API breaking optimizations are performed on it).
471
472 Main work done by this function is to enqueue the function for later
473 processing to avoid need the passes to be re-entrant. */
474
475void
d52f5295 476cgraph_node::add_new_function (tree fndecl, bool lowered)
452aa9c5 477{
315f8c0e 478 gcc::pass_manager *passes = g->get_passes ();
3dafb85c 479 cgraph_node *node;
9452ef06
TV
480
481 if (dump_file)
482 {
483 struct function *fn = DECL_STRUCT_FUNCTION (fndecl);
484 const char *function_type = ((gimple_has_body_p (fndecl))
485 ? (lowered
486 ? (gimple_in_ssa_p (fn)
487 ? "ssa gimple"
488 : "low gimple")
489 : "high gimple")
490 : "to-be-gimplified");
491 fprintf (dump_file,
492 "Added new %s function %s to callgraph\n",
493 function_type,
494 fndecl_name (fndecl));
495 }
496
3dafb85c 497 switch (symtab->state)
452aa9c5 498 {
3dafb85c
ML
499 case PARSING:
500 cgraph_node::finalize_function (fndecl, false);
66058468 501 break;
3dafb85c 502 case CONSTRUCTION:
452aa9c5 503 /* Just enqueue function to be processed at nearest occurrence. */
d52f5295 504 node = cgraph_node::get_create (fndecl);
452aa9c5
RG
505 if (lowered)
506 node->lowered = true;
31acf1bb 507 cgraph_new_nodes.safe_push (node);
452aa9c5
RG
508 break;
509
3dafb85c
ML
510 case IPA:
511 case IPA_SSA:
17e0fc92 512 case IPA_SSA_AFTER_INLINING:
3dafb85c 513 case EXPANSION:
452aa9c5
RG
514 /* Bring the function into finalized state and enqueue for later
515 analyzing and compilation. */
d52f5295 516 node = cgraph_node::get_create (fndecl);
452aa9c5 517 node->local.local = false;
67348ccc
DM
518 node->definition = true;
519 node->force_output = true;
3dafb85c 520 if (!lowered && symtab->state == EXPANSION)
452aa9c5
RG
521 {
522 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
452aa9c5
RG
523 gimple_register_cfg_hooks ();
524 bitmap_obstack_initialize (NULL);
2cbf2d95 525 execute_pass_list (cfun, passes->all_lowering_passes);
f7695dbf 526 passes->execute_early_local_passes ();
452aa9c5
RG
527 bitmap_obstack_release (NULL);
528 pop_cfun ();
452aa9c5
RG
529
530 lowered = true;
531 }
532 if (lowered)
533 node->lowered = true;
31acf1bb 534 cgraph_new_nodes.safe_push (node);
452aa9c5
RG
535 break;
536
3dafb85c 537 case FINISHED:
452aa9c5
RG
538 /* At the very end of compilation we have to do all the work up
539 to expansion. */
d52f5295 540 node = cgraph_node::create (fndecl);
452aa9c5
RG
541 if (lowered)
542 node->lowered = true;
67348ccc 543 node->definition = true;
d52f5295 544 node->analyze ();
452aa9c5 545 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
452aa9c5
RG
546 gimple_register_cfg_hooks ();
547 bitmap_obstack_initialize (NULL);
548 if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
f7695dbf 549 g->get_passes ()->execute_early_local_passes ();
452aa9c5 550 bitmap_obstack_release (NULL);
452aa9c5 551 pop_cfun ();
3dafb85c 552 node->expand ();
452aa9c5
RG
553 break;
554
555 default:
556 gcc_unreachable ();
557 }
558
559 /* Set a personality if required and we already passed EH lowering. */
560 if (lowered
561 && (function_needs_eh_personality (DECL_STRUCT_FUNCTION (fndecl))
562 == eh_personality_lang))
563 DECL_FUNCTION_PERSONALITY (fndecl) = lang_hooks.eh_personality ();
564}
565
e767b5be 566/* Analyze the function scheduled to be output. */
d52f5295
ML
567void
568cgraph_node::analyze (void)
e767b5be 569{
d52f5295 570 tree decl = this->decl;
9c8305f8
JH
571 location_t saved_loc = input_location;
572 input_location = DECL_SOURCE_LOCATION (decl);
e767b5be 573
d52f5295 574 if (thunk.thunk_p)
c47d0034 575 {
9641fab3
JH
576 cgraph_node *t = cgraph_node::get (thunk.alias);
577
578 create_edge (t, NULL, 0, CGRAPH_FREQ_BASE);
89bbe9ba 579 callees->can_throw_external = !TREE_NOTHROW (t->decl);
9641fab3
JH
580 /* Target code in expand_thunk may need the thunk's target
581 to be analyzed, so recurse here. */
582 if (!t->analyzed)
583 t->analyze ();
584 if (t->alias)
585 {
586 t = t->get_alias_target ();
587 if (!t->analyzed)
588 t->analyze ();
589 }
d52f5295 590 if (!expand_thunk (false, false))
afdec9bd 591 {
d52f5295 592 thunk.alias = NULL;
afdec9bd
JH
593 return;
594 }
d52f5295 595 thunk.alias = NULL;
c47d0034 596 }
d52f5295 597 if (alias)
71e54687 598 resolve_alias (cgraph_node::get (alias_target), transparent_alias);
d52f5295 599 else if (dispatcher_function)
3649b9b7
ST
600 {
601 /* Generate the dispatcher body of multi-versioned functions. */
3dafb85c 602 cgraph_function_version_info *dispatcher_version_info
d52f5295 603 = function_version ();
3649b9b7
ST
604 if (dispatcher_version_info != NULL
605 && (dispatcher_version_info->dispatcher_resolver
606 == NULL_TREE))
607 {
608 tree resolver = NULL_TREE;
609 gcc_assert (targetm.generate_version_dispatcher_body);
d52f5295 610 resolver = targetm.generate_version_dispatcher_body (this);
3649b9b7
ST
611 gcc_assert (resolver != NULL_TREE);
612 }
613 }
c47d0034
JH
614 else
615 {
c47d0034 616 push_cfun (DECL_STRUCT_FUNCTION (decl));
a406865a 617
d52f5295 618 assign_assembler_name_if_neeeded (decl);
0e0a1359 619
c47d0034
JH
620 /* Make sure to gimplify bodies only once. During analyzing a
621 function we lower it, which will require gimplified nested
622 functions, so we can end up here with an already gimplified
623 body. */
355a7673 624 if (!gimple_has_body_p (decl))
c47d0034 625 gimplify_function_tree (decl);
a406865a 626
26eb69c6 627 /* Lower the function. */
d52f5295 628 if (!lowered)
26eb69c6 629 {
d52f5295
ML
630 if (nested)
631 lower_nested_functions (decl);
632 gcc_assert (!nested);
26eb69c6
RG
633
634 gimple_register_cfg_hooks ();
635 bitmap_obstack_initialize (NULL);
2cbf2d95 636 execute_pass_list (cfun, g->get_passes ()->all_lowering_passes);
26eb69c6
RG
637 free_dominance_info (CDI_POST_DOMINATORS);
638 free_dominance_info (CDI_DOMINATORS);
639 compact_blocks ();
640 bitmap_obstack_release (NULL);
d52f5295 641 lowered = true;
26eb69c6
RG
642 }
643
c47d0034
JH
644 pop_cfun ();
645 }
d52f5295 646 analyzed = true;
e767b5be 647
9c8305f8 648 input_location = saved_loc;
e767b5be
JH
649}
650
39e2db00
JH
651/* C++ frontend produce same body aliases all over the place, even before PCH
652 gets streamed out. It relies on us linking the aliases with their function
653 in order to do the fixups, but ipa-ref is not PCH safe. Consequentely we
654 first produce aliases without links, but once C++ FE is sure he won't sream
655 PCH we build the links via this function. */
656
657void
3dafb85c 658symbol_table::process_same_body_aliases (void)
39e2db00 659{
5e20cdc9 660 symtab_node *node;
40a7fe1e 661 FOR_EACH_SYMBOL (node)
67348ccc 662 if (node->cpp_implicit_alias && !node->analyzed)
d52f5295
ML
663 node->resolve_alias
664 (TREE_CODE (node->alias_target) == VAR_DECL
9041d2e6 665 ? (symtab_node *)varpool_node::get_create (node->alias_target)
d52f5295 666 : (symtab_node *)cgraph_node::get_create (node->alias_target));
40a7fe1e 667 cpp_implicit_aliases_done = true;
39e2db00
JH
668}
669
768e3c60
RG
670/* Process attributes common for vars and functions. */
671
672static void
7861b648 673process_common_attributes (symtab_node *node, tree decl)
768e3c60
RG
674{
675 tree weakref = lookup_attribute ("weakref", DECL_ATTRIBUTES (decl));
676
677 if (weakref && !lookup_attribute ("alias", DECL_ATTRIBUTES (decl)))
678 {
679 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
680 "%<weakref%> attribute should be accompanied with"
681 " an %<alias%> attribute");
682 DECL_WEAK (decl) = 0;
779d4b91
JH
683 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
684 DECL_ATTRIBUTES (decl));
768e3c60 685 }
7861b648
AK
686
687 if (lookup_attribute ("no_reorder", DECL_ATTRIBUTES (decl)))
688 node->no_reorder = 1;
768e3c60
RG
689}
690
386b46cf
JH
691/* Look for externally_visible and used attributes and mark cgraph nodes
692 accordingly.
693
694 We cannot mark the nodes at the point the attributes are processed (in
695 handle_*_attribute) because the copy of the declarations available at that
696 point may not be canonical. For example, in:
697
698 void f();
699 void f() __attribute__((used));
700
701 the declaration we see in handle_used_attribute will be the second
702 declaration -- but the front end will subsequently merge that declaration
703 with the original declaration and discard the second declaration.
704
3dafb85c 705 Furthermore, we can't mark these nodes in finalize_function because:
386b46cf
JH
706
707 void f() {}
708 void f() __attribute__((externally_visible));
709
710 is valid.
711
712 So, we walk the nodes at the end of the translation unit, applying the
713 attributes at that point. */
714
715static void
3dafb85c 716process_function_and_variable_attributes (cgraph_node *first,
2c8326a5 717 varpool_node *first_var)
386b46cf 718{
3dafb85c 719 cgraph_node *node;
2c8326a5 720 varpool_node *vnode;
386b46cf 721
3dafb85c
ML
722 for (node = symtab->first_function (); node != first;
723 node = symtab->next_function (node))
386b46cf 724 {
67348ccc 725 tree decl = node->decl;
b42186f1 726 if (DECL_PRESERVE_P (decl))
d52f5295 727 node->mark_force_output ();
9d602c59 728 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
386b46cf 729 {
67348ccc
DM
730 if (! TREE_PUBLIC (node->decl))
731 warning_at (DECL_SOURCE_LOCATION (node->decl), OPT_Wattributes,
c5d75364
MLI
732 "%<externally_visible%>"
733 " attribute have effect only on public objects");
386b46cf 734 }
779d4b91 735 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
67348ccc 736 && (node->definition && !node->alias))
779d4b91 737 {
67348ccc 738 warning_at (DECL_SOURCE_LOCATION (node->decl), OPT_Wattributes,
779d4b91
JH
739 "%<weakref%> attribute ignored"
740 " because function is defined");
741 DECL_WEAK (decl) = 0;
742 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
743 DECL_ATTRIBUTES (decl));
744 }
c9fc06dc
CB
745
746 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl))
747 && !DECL_DECLARED_INLINE_P (decl)
748 /* redefining extern inline function makes it DECL_UNINLINABLE. */
749 && !DECL_UNINLINABLE (decl))
750 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
751 "always_inline function might not be inlinable");
752
7861b648 753 process_common_attributes (node, decl);
386b46cf 754 }
3dafb85c
ML
755 for (vnode = symtab->first_variable (); vnode != first_var;
756 vnode = symtab->next_variable (vnode))
386b46cf 757 {
67348ccc 758 tree decl = vnode->decl;
6649df51 759 if (DECL_EXTERNAL (decl)
6a6dac52 760 && DECL_INITIAL (decl))
9041d2e6 761 varpool_node::finalize_decl (decl);
b42186f1 762 if (DECL_PRESERVE_P (decl))
67348ccc 763 vnode->force_output = true;
9d602c59 764 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
386b46cf 765 {
67348ccc
DM
766 if (! TREE_PUBLIC (vnode->decl))
767 warning_at (DECL_SOURCE_LOCATION (vnode->decl), OPT_Wattributes,
c5d75364
MLI
768 "%<externally_visible%>"
769 " attribute have effect only on public objects");
386b46cf 770 }
779d4b91 771 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
67348ccc 772 && vnode->definition
779d4b91
JH
773 && DECL_INITIAL (decl))
774 {
67348ccc 775 warning_at (DECL_SOURCE_LOCATION (vnode->decl), OPT_Wattributes,
779d4b91
JH
776 "%<weakref%> attribute ignored"
777 " because variable is initialized");
778 DECL_WEAK (decl) = 0;
779 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
780 DECL_ATTRIBUTES (decl));
781 }
7861b648 782 process_common_attributes (vnode, decl);
386b46cf
JH
783 }
784}
785
66058468
JH
786/* Mark DECL as finalized. By finalizing the declaration, frontend instruct the
787 middle end to output the variable to asm file, if needed or externally
788 visible. */
789
790void
9041d2e6 791varpool_node::finalize_decl (tree decl)
66058468 792{
9041d2e6 793 varpool_node *node = varpool_node::get_create (decl);
66058468 794
387df871 795 gcc_assert (TREE_STATIC (decl) || DECL_EXTERNAL (decl));
66058468 796
67348ccc 797 if (node->definition)
66058468 798 return;
6a1e352e
L
799 /* Set definition first before calling notice_global_symbol so that
800 it is available to notice_global_symbol. */
67348ccc 801 node->definition = true;
6a1e352e 802 notice_global_symbol (decl);
66058468
JH
803 if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
804 /* Traditionally we do not eliminate static variables when not
805 optimizing and when not doing toplevel reoder. */
7861b648
AK
806 || node->no_reorder
807 || ((!flag_toplevel_reorder
808 && !DECL_COMDAT (node->decl)
809 && !DECL_ARTIFICIAL (node->decl))))
67348ccc 810 node->force_output = true;
66058468 811
3dafb85c
ML
812 if (symtab->state == CONSTRUCTION
813 && (node->needed_p () || node->referred_to_p ()))
67348ccc 814 enqueue_node (node);
3dafb85c 815 if (symtab->state >= IPA_SSA)
9041d2e6 816 node->analyze ();
0d6bf48c
JH
817 /* Some frontends produce various interface variables after compilation
818 finished. */
3dafb85c
ML
819 if (symtab->state == FINISHED
820 || (!flag_toplevel_reorder
821 && symtab->state == EXPANSION))
9041d2e6 822 node->assemble_decl ();
d5e254e1
IE
823
824 if (DECL_INITIAL (decl))
825 chkp_register_var_initializer (decl);
66058468
JH
826}
827
e18412fc
JH
828/* EDGE is an polymorphic call. Mark all possible targets as reachable
829 and if there is only one target, perform trivial devirtualization.
830 REACHABLE_CALL_TARGETS collects target lists we already walked to
831 avoid udplicate work. */
832
833static void
6e2830c3 834walk_polymorphic_call_targets (hash_set<void *> *reachable_call_targets,
3dafb85c 835 cgraph_edge *edge)
e18412fc
JH
836{
837 unsigned int i;
838 void *cache_token;
839 bool final;
840 vec <cgraph_node *>targets
841 = possible_polymorphic_call_targets
842 (edge, &final, &cache_token);
843
6e2830c3 844 if (!reachable_call_targets->add (cache_token))
e18412fc 845 {
3dafb85c 846 if (symtab->dump_file)
e18412fc 847 dump_possible_polymorphic_call_targets
3dafb85c 848 (symtab->dump_file, edge);
e18412fc 849
c3284718 850 for (i = 0; i < targets.length (); i++)
e18412fc
JH
851 {
852 /* Do not bother to mark virtual methods in anonymous namespace;
853 either we will find use of virtual table defining it, or it is
854 unused. */
67348ccc 855 if (targets[i]->definition
e18412fc 856 && TREE_CODE
67348ccc 857 (TREE_TYPE (targets[i]->decl))
e18412fc
JH
858 == METHOD_TYPE
859 && !type_in_anonymous_namespace_p
70e7f2a2
JH
860 (TYPE_METHOD_BASETYPE (TREE_TYPE (targets[i]->decl))))
861 enqueue_node (targets[i]);
e18412fc
JH
862 }
863 }
864
865 /* Very trivial devirtualization; when the type is
866 final or anonymous (so we know all its derivation)
867 and there is only one possible virtual call target,
868 make the edge direct. */
869 if (final)
870 {
2b5f0895 871 if (targets.length () <= 1 && dbg_cnt (devirt))
e18412fc 872 {
3462aa02
JH
873 cgraph_node *target;
874 if (targets.length () == 1)
875 target = targets[0];
876 else
d52f5295
ML
877 target = cgraph_node::create
878 (builtin_decl_implicit (BUILT_IN_UNREACHABLE));
3462aa02 879
3dafb85c 880 if (symtab->dump_file)
e18412fc 881 {
3dafb85c 882 fprintf (symtab->dump_file,
e18412fc 883 "Devirtualizing call: ");
3dafb85c 884 print_gimple_stmt (symtab->dump_file,
e18412fc
JH
885 edge->call_stmt, 0,
886 TDF_SLIM);
887 }
2b5f0895
XDL
888 if (dump_enabled_p ())
889 {
807b7d62 890 location_t locus = gimple_location_safe (edge->call_stmt);
2b5f0895
XDL
891 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, locus,
892 "devirtualizing call in %s to %s\n",
893 edge->caller->name (), target->name ());
894 }
895
3dafb85c
ML
896 edge->make_direct (target);
897 edge->redirect_call_stmt_to_callee ();
d5e254e1
IE
898
899 /* Call to __builtin_unreachable shouldn't be instrumented. */
900 if (!targets.length ())
901 gimple_call_set_with_bounds (edge->call_stmt, false);
902
3dafb85c 903 if (symtab->dump_file)
e18412fc 904 {
3dafb85c 905 fprintf (symtab->dump_file,
e18412fc 906 "Devirtualized as: ");
3dafb85c 907 print_gimple_stmt (symtab->dump_file,
e18412fc
JH
908 edge->call_stmt, 0,
909 TDF_SLIM);
910 }
911 }
912 }
913}
914
4ec39494
MLI
915/* Issue appropriate warnings for the global declaration DECL. */
916
917static void
918check_global_declaration (symtab_node *snode)
919{
261e741f 920 const char *decl_file;
4ec39494
MLI
921 tree decl = snode->decl;
922
923 /* Warn about any function declared static but not defined. We don't
924 warn about variables, because many programs have static variables
925 that exist only to get some text into the object file. */
926 if (TREE_CODE (decl) == FUNCTION_DECL
927 && DECL_INITIAL (decl) == 0
928 && DECL_EXTERNAL (decl)
929 && ! DECL_ARTIFICIAL (decl)
930 && ! TREE_NO_WARNING (decl)
931 && ! TREE_PUBLIC (decl)
932 && (warn_unused_function
933 || snode->referred_to_p (/*include_self=*/false)))
934 {
935 if (snode->referred_to_p (/*include_self=*/false))
936 pedwarn (input_location, 0, "%q+F used but never defined", decl);
937 else
938 warning (OPT_Wunused_function, "%q+F declared %<static%> but never defined", decl);
939 /* This symbol is effectively an "extern" declaration now. */
940 TREE_PUBLIC (decl) = 1;
941 }
942
943 /* Warn about static fns or vars defined but not used. */
944 if (((warn_unused_function && TREE_CODE (decl) == FUNCTION_DECL)
945 || (((warn_unused_variable && ! TREE_READONLY (decl))
4246c8da
MW
946 || (warn_unused_const_variable > 0 && TREE_READONLY (decl)
947 && (warn_unused_const_variable == 2
261e741f
MW
948 || (main_input_filename != NULL
949 && (decl_file = DECL_SOURCE_FILE (decl)) != NULL
950 && filename_cmp (main_input_filename,
951 decl_file) == 0))))
4ec39494
MLI
952 && TREE_CODE (decl) == VAR_DECL))
953 && ! DECL_IN_SYSTEM_HEADER (decl)
954 && ! snode->referred_to_p (/*include_self=*/false)
955 /* This TREE_USED check is needed in addition to referred_to_p
956 above, because the `__unused__' attribute is not being
957 considered for referred_to_p. */
958 && ! TREE_USED (decl)
959 /* The TREE_USED bit for file-scope decls is kept in the identifier,
960 to handle multiple external decls in different scopes. */
961 && ! (DECL_NAME (decl) && TREE_USED (DECL_NAME (decl)))
962 && ! DECL_EXTERNAL (decl)
963 && ! DECL_ARTIFICIAL (decl)
964 && ! DECL_ABSTRACT_ORIGIN (decl)
965 && ! TREE_PUBLIC (decl)
966 /* A volatile variable might be used in some non-obvious way. */
8b6ab677 967 && (! VAR_P (decl) || ! TREE_THIS_VOLATILE (decl))
4ec39494
MLI
968 /* Global register variables must be declared to reserve them. */
969 && ! (TREE_CODE (decl) == VAR_DECL && DECL_REGISTER (decl))
970 /* Global ctors and dtors are called by the runtime. */
971 && (TREE_CODE (decl) != FUNCTION_DECL
972 || (!DECL_STATIC_CONSTRUCTOR (decl)
973 && !DECL_STATIC_DESTRUCTOR (decl)))
974 /* Otherwise, ask the language. */
975 && lang_hooks.decls.warn_unused_global (decl))
976 warning_at (DECL_SOURCE_LOCATION (decl),
977 (TREE_CODE (decl) == FUNCTION_DECL)
978 ? OPT_Wunused_function
979 : (TREE_READONLY (decl)
4246c8da 980 ? OPT_Wunused_const_variable_
4ec39494
MLI
981 : OPT_Wunused_variable),
982 "%qD defined but not used", decl);
983}
5d59b5e1 984
66058468
JH
985/* Discover all functions and variables that are trivially needed, analyze
986 them as well as all functions and variables referred by them */
3edf64aa
DM
987static cgraph_node *first_analyzed;
988static varpool_node *first_analyzed_var;
1c4a429a 989
d7438551
AH
990/* FIRST_TIME is set to TRUE for the first time we are called for a
991 translation unit from finalize_compilation_unit() or false
992 otherwise. */
993
151e6f24 994static void
d7438551 995analyze_functions (bool first_time)
1c4a429a 996{
cd9c7bd2 997 /* Keep track of already processed nodes when called multiple times for
aabcd309 998 intermodule optimization. */
3dafb85c 999 cgraph_node *first_handled = first_analyzed;
2c8326a5 1000 varpool_node *first_handled_var = first_analyzed_var;
6e2830c3 1001 hash_set<void *> reachable_call_targets;
66058468 1002
5e20cdc9
DM
1003 symtab_node *node;
1004 symtab_node *next;
66058468 1005 int i;
3dafb85c 1006 ipa_ref *ref;
66058468 1007 bool changed = true;
4f90d3e0 1008 location_t saved_loc = input_location;
1c4a429a 1009
1389294c 1010 bitmap_obstack_initialize (NULL);
3dafb85c 1011 symtab->state = CONSTRUCTION;
4f90d3e0 1012 input_location = UNKNOWN_LOCATION;
1c4a429a 1013
40a7fe1e
JH
1014 /* Ugly, but the fixup can not happen at a time same body alias is created;
1015 C++ FE is confused about the COMDAT groups being right. */
3dafb85c 1016 if (symtab->cpp_implicit_aliases_done)
40a7fe1e 1017 FOR_EACH_SYMBOL (node)
67348ccc 1018 if (node->cpp_implicit_alias)
d52f5295 1019 node->fixup_same_cpp_alias_visibility (node->get_alias_target ());
2bf86c84 1020 build_type_inheritance_graph ();
40a7fe1e 1021
66058468
JH
1022 /* Analysis adds static variables that in turn adds references to new functions.
1023 So we need to iterate the process until it stabilize. */
1024 while (changed)
1c4a429a 1025 {
66058468
JH
1026 changed = false;
1027 process_function_and_variable_attributes (first_analyzed,
1028 first_analyzed_var);
1029
1030 /* First identify the trivially needed symbols. */
3dafb85c 1031 for (node = symtab->first_symbol ();
67348ccc
DM
1032 node != first_analyzed
1033 && node != first_analyzed_var; node = node->next)
d71cc23f 1034 {
d67ff7b7
JM
1035 /* Convert COMDAT group designators to IDENTIFIER_NODEs. */
1036 node->get_comdat_group_id ();
3dafb85c 1037 if (node->needed_p ())
66058468
JH
1038 {
1039 enqueue_node (node);
3dafb85c
ML
1040 if (!changed && symtab->dump_file)
1041 fprintf (symtab->dump_file, "Trivially needed symbols:");
66058468 1042 changed = true;
3dafb85c
ML
1043 if (symtab->dump_file)
1044 fprintf (symtab->dump_file, " %s", node->asm_name ());
1045 if (!changed && symtab->dump_file)
1046 fprintf (symtab->dump_file, "\n");
66058468 1047 }
67348ccc
DM
1048 if (node == first_analyzed
1049 || node == first_analyzed_var)
66058468 1050 break;
d71cc23f 1051 }
3dafb85c
ML
1052 symtab->process_new_functions ();
1053 first_analyzed_var = symtab->first_variable ();
1054 first_analyzed = symtab->first_function ();
cd4dea62 1055
3dafb85c
ML
1056 if (changed && symtab->dump_file)
1057 fprintf (symtab->dump_file, "\n");
8dafba3c 1058
66058468
JH
1059 /* Lower representation, build callgraph edges and references for all trivially
1060 needed symbols and all symbols referred by them. */
b4d05578 1061 while (queued_nodes != &symtab_terminator)
b66887e4 1062 {
66058468 1063 changed = true;
b4d05578
BS
1064 node = queued_nodes;
1065 queued_nodes = (symtab_node *)queued_nodes->aux;
7de90a6c 1066 cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
67348ccc 1067 if (cnode && cnode->definition)
66058468 1068 {
3dafb85c 1069 cgraph_edge *edge;
67348ccc 1070 tree decl = cnode->decl;
66058468 1071
5d59b5e1
LC
1072 /* ??? It is possible to create extern inline function
1073 and later using weak alias attribute to kill its body.
1074 See gcc.c-torture/compile/20011119-1.c */
66058468 1075 if (!DECL_STRUCT_FUNCTION (decl)
67348ccc 1076 && !cnode->alias
3649b9b7
ST
1077 && !cnode->thunk.thunk_p
1078 && !cnode->dispatcher_function)
66058468 1079 {
d52f5295 1080 cnode->reset ();
66058468
JH
1081 cnode->local.redefined_extern_inline = true;
1082 continue;
1083 }
b66887e4 1084
67348ccc 1085 if (!cnode->analyzed)
d52f5295 1086 cnode->analyze ();
6b20f353 1087
66058468 1088 for (edge = cnode->callees; edge; edge = edge->next_callee)
1bf7c324
JH
1089 if (edge->callee->definition
1090 && (!DECL_EXTERNAL (edge->callee->decl)
1091 /* When not optimizing, do not try to analyze extern
1092 inline functions. Doing so is pointless. */
1093 || opt_for_fn (edge->callee->decl, optimize)
1094 /* Weakrefs needs to be preserved. */
1095 || edge->callee->alias
1096 /* always_inline functions are inlined aven at -O0. */
1097 || lookup_attribute
1098 ("always_inline",
1099 DECL_ATTRIBUTES (edge->callee->decl))
1100 /* Multiversioned functions needs the dispatcher to
1101 be produced locally even for extern functions. */
1102 || edge->callee->function_version ()))
67348ccc 1103 enqueue_node (edge->callee);
2bf86c84
JH
1104 if (opt_for_fn (cnode->decl, optimize)
1105 && opt_for_fn (cnode->decl, flag_devirtualize))
eefe9a99 1106 {
3dafb85c 1107 cgraph_edge *next;
e18412fc
JH
1108
1109 for (edge = cnode->indirect_calls; edge; edge = next)
c4be6568
JH
1110 {
1111 next = edge->next_callee;
1112 if (edge->indirect_info->polymorphic)
6e2830c3 1113 walk_polymorphic_call_targets (&reachable_call_targets,
e18412fc 1114 edge);
c4be6568 1115 }
eefe9a99 1116 }
66058468 1117
5d59b5e1
LC
1118 /* If decl is a clone of an abstract function,
1119 mark that abstract function so that we don't release its body.
1120 The DECL_INITIAL() of that abstract function declaration
1121 will be later needed to output debug info. */
66058468
JH
1122 if (DECL_ABSTRACT_ORIGIN (decl))
1123 {
3dafb85c 1124 cgraph_node *origin_node
c84495c0 1125 = cgraph_node::get_create (DECL_ABSTRACT_ORIGIN (decl));
c0c123ef 1126 origin_node->used_as_abstract_origin = true;
66058468 1127 }
66058468 1128 }
5d59b5e1
LC
1129 else
1130 {
7de90a6c 1131 varpool_node *vnode = dyn_cast <varpool_node *> (node);
67348ccc 1132 if (vnode && vnode->definition && !vnode->analyzed)
9041d2e6 1133 vnode->analyze ();
5d59b5e1 1134 }
66058468 1135
67348ccc 1136 if (node->same_comdat_group)
66058468 1137 {
5e20cdc9 1138 symtab_node *next;
67348ccc 1139 for (next = node->same_comdat_group;
66058468 1140 next != node;
67348ccc 1141 next = next->same_comdat_group)
1bf7c324
JH
1142 if (!next->comdat_local_p ())
1143 enqueue_node (next);
66058468 1144 }
d122681a 1145 for (i = 0; node->iterate_reference (i, ref); i++)
1bf7c324
JH
1146 if (ref->referred->definition
1147 && (!DECL_EXTERNAL (ref->referred->decl)
1148 || ((TREE_CODE (ref->referred->decl) != FUNCTION_DECL
1149 && optimize)
1150 || (TREE_CODE (ref->referred->decl) == FUNCTION_DECL
1151 && opt_for_fn (ref->referred->decl, optimize))
38c1b72f 1152 || node->alias
1bf7c324 1153 || ref->referred->alias)))
66058468 1154 enqueue_node (ref->referred);
3dafb85c 1155 symtab->process_new_functions ();
66058468 1156 }
1c4a429a 1157 }
2bf86c84 1158 update_type_inheritance_graph ();
8dafba3c 1159
564738df 1160 /* Collect entry points to the unit. */
3dafb85c 1161 if (symtab->dump_file)
1668aabc 1162 {
3dafb85c
ML
1163 fprintf (symtab->dump_file, "\n\nInitial ");
1164 symtab_node::dump_table (symtab->dump_file);
1668aabc 1165 }
7660e67e 1166
d7438551
AH
1167 if (first_time)
1168 {
1169 symtab_node *snode;
1170 FOR_EACH_SYMBOL (snode)
4ec39494 1171 check_global_declaration (snode);
d7438551
AH
1172 }
1173
3dafb85c
ML
1174 if (symtab->dump_file)
1175 fprintf (symtab->dump_file, "\nRemoving unused symbols:");
1c4a429a 1176
3dafb85c 1177 for (node = symtab->first_symbol ();
67348ccc
DM
1178 node != first_handled
1179 && node != first_handled_var; node = next)
1c4a429a 1180 {
67348ccc 1181 next = node->next;
3dafb85c 1182 if (!node->aux && !node->referred_to_p ())
1c4a429a 1183 {
3dafb85c
ML
1184 if (symtab->dump_file)
1185 fprintf (symtab->dump_file, " %s", node->name ());
d7438551
AH
1186
1187 /* See if the debugger can use anything before the DECL
1188 passes away. Perhaps it can notice a DECL that is now a
1189 constant and can tag the early DIE with an appropriate
1190 attribute.
1191
1192 Otherwise, this is the last chance the debug_hooks have
1193 at looking at optimized away DECLs, since
1194 late_global_decl will subsequently be called from the
1195 contents of the now pruned symbol table. */
1196 if (!decl_function_context (node->decl))
1197 (*debug_hooks->late_global_decl) (node->decl);
1198
d52f5295 1199 node->remove ();
d71cc23f 1200 continue;
1c4a429a 1201 }
7de90a6c 1202 if (cgraph_node *cnode = dyn_cast <cgraph_node *> (node))
66058468 1203 {
67348ccc 1204 tree decl = node->decl;
66058468 1205
67348ccc
DM
1206 if (cnode->definition && !gimple_has_body_p (decl)
1207 && !cnode->alias
66058468 1208 && !cnode->thunk.thunk_p)
d52f5295 1209 cnode->reset ();
66058468 1210
67348ccc
DM
1211 gcc_assert (!cnode->definition || cnode->thunk.thunk_p
1212 || cnode->alias
66058468 1213 || gimple_has_body_p (decl));
67348ccc 1214 gcc_assert (cnode->analyzed == cnode->definition);
66058468 1215 }
67348ccc 1216 node->aux = NULL;
1c4a429a 1217 }
67348ccc
DM
1218 for (;node; node = node->next)
1219 node->aux = NULL;
3dafb85c
ML
1220 first_analyzed = symtab->first_function ();
1221 first_analyzed_var = symtab->first_variable ();
1222 if (symtab->dump_file)
7d82fe7c 1223 {
3dafb85c
ML
1224 fprintf (symtab->dump_file, "\n\nReclaimed ");
1225 symtab_node::dump_table (symtab->dump_file);
7d82fe7c 1226 }
1389294c 1227 bitmap_obstack_release (NULL);
1c4a429a 1228 ggc_collect ();
d352b245
JH
1229 /* Initialize assembler name hash, in particular we want to trigger C++
1230 mangling and same body alias creation before we free DECL_ARGUMENTS
1231 used by it. */
1232 if (!seen_error ())
3dafb85c 1233 symtab->symtab_initialize_asm_name_hash ();
4f90d3e0
JH
1234
1235 input_location = saved_loc;
151e6f24
JH
1236}
1237
85ce9375
JH
1238/* Translate the ugly representation of aliases as alias pairs into nice
1239 representation in callgraph. We don't handle all cases yet,
4f219961 1240 unfortunately. */
85ce9375
JH
1241
1242static void
1243handle_alias_pairs (void)
1244{
1245 alias_pair *p;
1246 unsigned i;
85ce9375 1247
9771b263 1248 for (i = 0; alias_pairs && alias_pairs->iterate (i, &p);)
85ce9375 1249 {
3dafb85c 1250 symtab_node *target_node = symtab_node::get_for_asmname (p->target);
38e55ac9 1251
4f219961
EB
1252 /* Weakrefs with target not defined in current unit are easy to handle:
1253 they behave just as external variables except we need to note the
1254 alias flag to later output the weakref pseudo op into asm file. */
1255 if (!target_node
1256 && lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL)
25e2c40d 1257 {
d52f5295 1258 symtab_node *node = symtab_node::get (p->decl);
40a7fe1e 1259 if (node)
e01c7cca 1260 {
67348ccc
DM
1261 node->alias_target = p->target;
1262 node->weakref = true;
1263 node->alias = true;
71e54687 1264 node->transparent_alias = true;
e01c7cca 1265 }
9771b263 1266 alias_pairs->unordered_remove (i);
38e55ac9 1267 continue;
25e2c40d 1268 }
38e55ac9 1269 else if (!target_node)
85ce9375 1270 {
38e55ac9 1271 error ("%q+D aliased to undefined symbol %qE", p->decl, p->target);
d52f5295 1272 symtab_node *node = symtab_node::get (p->decl);
4f219961 1273 if (node)
67348ccc 1274 node->alias = false;
9771b263 1275 alias_pairs->unordered_remove (i);
38e55ac9
JH
1276 continue;
1277 }
1278
67348ccc 1279 if (DECL_EXTERNAL (target_node->decl)
07250f0e
JH
1280 /* We use local aliases for C++ thunks to force the tailcall
1281 to bind locally. This is a hack - to keep it working do
1282 the following (which is not strictly correct). */
abbb94e6 1283 && (TREE_CODE (target_node->decl) != FUNCTION_DECL
67348ccc 1284 || ! DECL_VIRTUAL_P (target_node->decl))
07250f0e
JH
1285 && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)))
1286 {
1287 error ("%q+D aliased to external symbol %qE",
1288 p->decl, p->target);
1289 }
1290
38e55ac9 1291 if (TREE_CODE (p->decl) == FUNCTION_DECL
7de90a6c 1292 && target_node && is_a <cgraph_node *> (target_node))
38e55ac9 1293 {
3dafb85c 1294 cgraph_node *src_node = cgraph_node::get (p->decl);
67348ccc 1295 if (src_node && src_node->definition)
d52f5295
ML
1296 src_node->reset ();
1297 cgraph_node::create_alias (p->decl, target_node->decl);
9771b263 1298 alias_pairs->unordered_remove (i);
38e55ac9
JH
1299 }
1300 else if (TREE_CODE (p->decl) == VAR_DECL
7de90a6c 1301 && target_node && is_a <varpool_node *> (target_node))
38e55ac9 1302 {
9041d2e6 1303 varpool_node::create_alias (p->decl, target_node->decl);
9771b263 1304 alias_pairs->unordered_remove (i);
38e55ac9
JH
1305 }
1306 else
1307 {
1308 error ("%q+D alias in between function and variable is not supported",
1309 p->decl);
1310 warning (0, "%q+D aliased declaration",
67348ccc 1311 target_node->decl);
9771b263 1312 alias_pairs->unordered_remove (i);
85ce9375
JH
1313 }
1314 }
9771b263 1315 vec_free (alias_pairs);
85ce9375
JH
1316}
1317
5f1a9ebb 1318
1c4a429a
JH
1319/* Figure out what functions we want to assemble. */
1320
1321static void
65d630d4 1322mark_functions_to_output (void)
1c4a429a 1323{
b66887e4 1324 bool check_same_comdat_groups = false;
b2b29377 1325 cgraph_node *node;
b66887e4 1326
b2b29377
MM
1327 if (flag_checking)
1328 FOR_EACH_FUNCTION (node)
1329 gcc_assert (!node->process);
1c4a429a 1330
65c70e6b 1331 FOR_EACH_FUNCTION (node)
1c4a429a 1332 {
67348ccc 1333 tree decl = node->decl;
c22cacf3 1334
67348ccc 1335 gcc_assert (!node->process || node->same_comdat_group);
b66887e4
JJ
1336 if (node->process)
1337 continue;
b58b1157 1338
7660e67e
SB
1339 /* We need to output all local functions that are used and not
1340 always inlined, as well as those that are reachable from
1341 outside the current compilation unit. */
67348ccc 1342 if (node->analyzed
c47d0034 1343 && !node->thunk.thunk_p
67348ccc 1344 && !node->alias
18c6ada9 1345 && !node->global.inlined_to
6de9cd9a 1346 && !TREE_ASM_WRITTEN (decl)
1c4a429a 1347 && !DECL_EXTERNAL (decl))
b66887e4
JJ
1348 {
1349 node->process = 1;
67348ccc 1350 if (node->same_comdat_group)
b66887e4 1351 {
3dafb85c 1352 cgraph_node *next;
d52f5295 1353 for (next = dyn_cast<cgraph_node *> (node->same_comdat_group);
b66887e4 1354 next != node;
d52f5295 1355 next = dyn_cast<cgraph_node *> (next->same_comdat_group))
1f26ac87 1356 if (!next->thunk.thunk_p && !next->alias
d52f5295 1357 && !next->comdat_local_p ())
c47d0034 1358 next->process = 1;
b66887e4
JJ
1359 }
1360 }
67348ccc 1361 else if (node->same_comdat_group)
b66887e4 1362 {
b2b29377
MM
1363 if (flag_checking)
1364 check_same_comdat_groups = true;
b66887e4 1365 }
341c100f 1366 else
1a2caa7a
NS
1367 {
1368 /* We should've reclaimed all functions that are not needed. */
b2b29377
MM
1369 if (flag_checking
1370 && !node->global.inlined_to
39ecc018 1371 && gimple_has_body_p (decl)
a837268b
JH
1372 /* FIXME: in ltrans unit when offline copy is outside partition but inline copies
1373 are inside partition, we can end up not removing the body since we no longer
1374 have analyzed node pointing to it. */
67348ccc
DM
1375 && !node->in_other_partition
1376 && !node->alias
387df871 1377 && !node->clones
1a2caa7a
NS
1378 && !DECL_EXTERNAL (decl))
1379 {
d52f5295 1380 node->debug ();
1a2caa7a
NS
1381 internal_error ("failed to reclaim unneeded function");
1382 }
726a989a 1383 gcc_assert (node->global.inlined_to
39ecc018 1384 || !gimple_has_body_p (decl)
67348ccc 1385 || node->in_other_partition
6649df51
JH
1386 || node->clones
1387 || DECL_ARTIFICIAL (decl)
1a2caa7a
NS
1388 || DECL_EXTERNAL (decl));
1389
1390 }
c22cacf3 1391
18d13f34 1392 }
b2b29377 1393 if (flag_checking && check_same_comdat_groups)
65c70e6b 1394 FOR_EACH_FUNCTION (node)
67348ccc 1395 if (node->same_comdat_group && !node->process)
b66887e4 1396 {
67348ccc 1397 tree decl = node->decl;
b66887e4
JJ
1398 if (!node->global.inlined_to
1399 && gimple_has_body_p (decl)
7cbf224d
RG
1400 /* FIXME: in an ltrans unit when the offline copy is outside a
1401 partition but inline copies are inside a partition, we can
1402 end up not removing the body since we no longer have an
1403 analyzed node pointing to it. */
67348ccc 1404 && !node->in_other_partition
07250f0e 1405 && !node->clones
b66887e4
JJ
1406 && !DECL_EXTERNAL (decl))
1407 {
d52f5295 1408 node->debug ();
7cbf224d
RG
1409 internal_error ("failed to reclaim unneeded function in same "
1410 "comdat group");
b66887e4
JJ
1411 }
1412 }
18d13f34
JH
1413}
1414
6744a6ab 1415/* DECL is FUNCTION_DECL. Initialize datastructures so DECL is a function
3649b9b7 1416 in lowered gimple form. IN_SSA is true if the gimple is in SSA.
6744a6ab
JH
1417
1418 Set current_function_decl and cfun to newly constructed empty function body.
1419 return basic block in the function body. */
1420
3649b9b7 1421basic_block
10881cff 1422init_lowered_empty_function (tree decl, bool in_ssa, gcov_type count)
6744a6ab
JH
1423{
1424 basic_block bb;
10881cff 1425 edge e;
6744a6ab
JH
1426
1427 current_function_decl = decl;
1428 allocate_struct_function (decl, false);
1429 gimple_register_cfg_hooks ();
1430 init_empty_tree_cfg ();
3649b9b7
ST
1431
1432 if (in_ssa)
1433 {
1434 init_tree_ssa (cfun);
1435 init_ssa_operands (cfun);
1436 cfun->gimple_df->in_ssa_p = true;
31ee20ba 1437 cfun->curr_properties |= PROP_ssa;
3649b9b7
ST
1438 }
1439
6744a6ab
JH
1440 DECL_INITIAL (decl) = make_node (BLOCK);
1441
1442 DECL_SAVED_TREE (decl) = error_mark_node;
31ee20ba
RB
1443 cfun->curr_properties |= (PROP_gimple_lcf | PROP_gimple_leh | PROP_gimple_any
1444 | PROP_cfg | PROP_loops);
1445
766090c2 1446 set_loops_for_fn (cfun, ggc_cleared_alloc<loops> ());
31ee20ba
RB
1447 init_loops_structure (cfun, loops_for_fn (cfun), 1);
1448 loops_for_fn (cfun)->state |= LOOPS_MAY_HAVE_MULTIPLE_LATCHES;
6744a6ab
JH
1449
1450 /* Create BB for body of the function and connect it properly. */
10881cff
JH
1451 ENTRY_BLOCK_PTR_FOR_FN (cfun)->count = count;
1452 ENTRY_BLOCK_PTR_FOR_FN (cfun)->frequency = REG_BR_PROB_BASE;
1453 EXIT_BLOCK_PTR_FOR_FN (cfun)->count = count;
1454 EXIT_BLOCK_PTR_FOR_FN (cfun)->frequency = REG_BR_PROB_BASE;
c4d281b2 1455 bb = create_basic_block (NULL, ENTRY_BLOCK_PTR_FOR_FN (cfun));
10881cff
JH
1456 bb->count = count;
1457 bb->frequency = BB_FREQ_MAX;
1458 e = make_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun), bb, EDGE_FALLTHRU);
1459 e->count = count;
1460 e->probability = REG_BR_PROB_BASE;
1461 e = make_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
1462 e->count = count;
1463 e->probability = REG_BR_PROB_BASE;
fefa31b5 1464 add_bb_to_loop (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun)->loop_father);
6744a6ab
JH
1465
1466 return bb;
1467}
1468
1469/* Adjust PTR by the constant FIXED_OFFSET, and by the vtable
1470 offset indicated by VIRTUAL_OFFSET, if that is
1471 non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and
1472 zero for a result adjusting thunk. */
1473
1474static tree
1475thunk_adjust (gimple_stmt_iterator * bsi,
1476 tree ptr, bool this_adjusting,
1477 HOST_WIDE_INT fixed_offset, tree virtual_offset)
1478{
538dd0b7 1479 gassign *stmt;
6744a6ab
JH
1480 tree ret;
1481
313333a6
RG
1482 if (this_adjusting
1483 && fixed_offset != 0)
6744a6ab 1484 {
5d49b6a7
RG
1485 stmt = gimple_build_assign
1486 (ptr, fold_build_pointer_plus_hwi_loc (input_location,
1487 ptr,
1488 fixed_offset));
6744a6ab
JH
1489 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1490 }
1491
1492 /* If there's a virtual offset, look up that value in the vtable and
1493 adjust the pointer again. */
1494 if (virtual_offset)
1495 {
1496 tree vtabletmp;
1497 tree vtabletmp2;
1498 tree vtabletmp3;
6744a6ab
JH
1499
1500 if (!vtable_entry_type)
1501 {
1502 tree vfunc_type = make_node (FUNCTION_TYPE);
1503 TREE_TYPE (vfunc_type) = integer_type_node;
1504 TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
1505 layout_type (vfunc_type);
1506
1507 vtable_entry_type = build_pointer_type (vfunc_type);
1508 }
1509
1510 vtabletmp =
7cc434a3 1511 create_tmp_reg (build_pointer_type
7d80ca1f 1512 (build_pointer_type (vtable_entry_type)), "vptr");
6744a6ab
JH
1513
1514 /* The vptr is always at offset zero in the object. */
1515 stmt = gimple_build_assign (vtabletmp,
1516 build1 (NOP_EXPR, TREE_TYPE (vtabletmp),
1517 ptr));
1518 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
6744a6ab
JH
1519
1520 /* Form the vtable address. */
7cc434a3 1521 vtabletmp2 = create_tmp_reg (TREE_TYPE (TREE_TYPE (vtabletmp)),
7d80ca1f 1522 "vtableaddr");
6744a6ab 1523 stmt = gimple_build_assign (vtabletmp2,
70f34814 1524 build_simple_mem_ref (vtabletmp));
6744a6ab 1525 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
6744a6ab
JH
1526
1527 /* Find the entry with the vcall offset. */
1528 stmt = gimple_build_assign (vtabletmp2,
5d49b6a7
RG
1529 fold_build_pointer_plus_loc (input_location,
1530 vtabletmp2,
1531 virtual_offset));
6744a6ab
JH
1532 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1533
1534 /* Get the offset itself. */
7cc434a3 1535 vtabletmp3 = create_tmp_reg (TREE_TYPE (TREE_TYPE (vtabletmp2)),
7d80ca1f 1536 "vcalloffset");
6744a6ab 1537 stmt = gimple_build_assign (vtabletmp3,
70f34814 1538 build_simple_mem_ref (vtabletmp2));
6744a6ab 1539 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
6744a6ab 1540
6744a6ab 1541 /* Adjust the `this' pointer. */
0d82a1c8
RG
1542 ptr = fold_build_pointer_plus_loc (input_location, ptr, vtabletmp3);
1543 ptr = force_gimple_operand_gsi (bsi, ptr, true, NULL_TREE, false,
1544 GSI_CONTINUE_LINKING);
6744a6ab
JH
1545 }
1546
313333a6
RG
1547 if (!this_adjusting
1548 && fixed_offset != 0)
6744a6ab
JH
1549 /* Adjust the pointer by the constant. */
1550 {
1551 tree ptrtmp;
1552
1553 if (TREE_CODE (ptr) == VAR_DECL)
1554 ptrtmp = ptr;
1555 else
1556 {
7cc434a3 1557 ptrtmp = create_tmp_reg (TREE_TYPE (ptr), "ptr");
6744a6ab
JH
1558 stmt = gimple_build_assign (ptrtmp, ptr);
1559 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
6744a6ab 1560 }
5d49b6a7
RG
1561 ptr = fold_build_pointer_plus_hwi_loc (input_location,
1562 ptrtmp, fixed_offset);
6744a6ab
JH
1563 }
1564
1565 /* Emit the statement and gimplify the adjustment expression. */
7cc434a3 1566 ret = create_tmp_reg (TREE_TYPE (ptr), "adjusted_this");
6744a6ab 1567 stmt = gimple_build_assign (ret, ptr);
6744a6ab
JH
1568 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1569
1570 return ret;
1571}
1572
afdec9bd 1573/* Expand thunk NODE to gimple if possible.
d211e471
ML
1574 When FORCE_GIMPLE_THUNK is true, gimple thunk is created and
1575 no assembler is produced.
afdec9bd
JH
1576 When OUTPUT_ASM_THUNK is true, also produce assembler for
1577 thunks that are not lowered. */
6744a6ab 1578
afdec9bd 1579bool
d52f5295 1580cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk)
6744a6ab 1581{
d52f5295
ML
1582 bool this_adjusting = thunk.this_adjusting;
1583 HOST_WIDE_INT fixed_offset = thunk.fixed_offset;
1584 HOST_WIDE_INT virtual_value = thunk.virtual_value;
6744a6ab 1585 tree virtual_offset = NULL;
d52f5295
ML
1586 tree alias = callees->callee->decl;
1587 tree thunk_fndecl = decl;
bcb650cb
JH
1588 tree a;
1589
a115251c
IE
1590 /* Instrumentation thunk is the same function with
1591 a different signature. Never need to expand it. */
1592 if (thunk.add_pointer_bounds_args)
1593 return false;
d06865bf 1594
d211e471 1595 if (!force_gimple_thunk && this_adjusting
6744a6ab
JH
1596 && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
1597 virtual_value, alias))
1598 {
1599 const char *fnname;
1600 tree fn_block;
4399cf59 1601 tree restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
afdec9bd
JH
1602
1603 if (!output_asm_thunks)
77b7d74b
MJ
1604 {
1605 analyzed = true;
1606 return false;
1607 }
afdec9bd
JH
1608
1609 if (in_lto_p)
70486010 1610 get_untransformed_body ();
afdec9bd 1611 a = DECL_ARGUMENTS (thunk_fndecl);
6744a6ab 1612
afdec9bd
JH
1613 current_function_decl = thunk_fndecl;
1614
1615 /* Ensure thunks are emitted in their correct sections. */
9641fab3
JH
1616 resolve_unique_section (thunk_fndecl, 0,
1617 flag_function_sections);
afdec9bd 1618
6744a6ab
JH
1619 DECL_RESULT (thunk_fndecl)
1620 = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl),
4399cf59 1621 RESULT_DECL, 0, restype);
afdec9bd 1622 DECL_CONTEXT (DECL_RESULT (thunk_fndecl)) = thunk_fndecl;
15488554 1623 fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
6744a6ab
JH
1624
1625 /* The back end expects DECL_INITIAL to contain a BLOCK, so we
1626 create one. */
1627 fn_block = make_node (BLOCK);
1628 BLOCK_VARS (fn_block) = a;
1629 DECL_INITIAL (thunk_fndecl) = fn_block;
be373510 1630 allocate_struct_function (thunk_fndecl, false);
6744a6ab
JH
1631 init_function_start (thunk_fndecl);
1632 cfun->is_thunk = 1;
68a55980
JJ
1633 insn_locations_init ();
1634 set_curr_insn_location (DECL_SOURCE_LOCATION (thunk_fndecl));
1635 prologue_location = curr_insn_location ();
6744a6ab
JH
1636 assemble_start_function (thunk_fndecl, fnname);
1637
1638 targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl,
1639 fixed_offset, virtual_value, alias);
1640
1641 assemble_end_function (thunk_fndecl, fnname);
68a55980 1642 insn_locations_finalize ();
6744a6ab
JH
1643 init_insn_lengths ();
1644 free_after_compilation (cfun);
6744a6ab 1645 TREE_ASM_WRITTEN (thunk_fndecl) = 1;
d52f5295
ML
1646 thunk.thunk_p = false;
1647 analyzed = false;
6744a6ab 1648 }
d90cae08
JH
1649 else if (stdarg_p (TREE_TYPE (thunk_fndecl)))
1650 {
1651 error ("generic thunk code fails for method %qD which uses %<...%>",
1652 thunk_fndecl);
1653 TREE_ASM_WRITTEN (thunk_fndecl) = 1;
1654 analyzed = true;
1655 return false;
1656 }
6744a6ab
JH
1657 else
1658 {
1659 tree restype;
1660 basic_block bb, then_bb, else_bb, return_bb;
1661 gimple_stmt_iterator bsi;
1662 int nargs = 0;
1663 tree arg;
1664 int i;
1665 tree resdecl;
1666 tree restmp = NULL;
4f5a53cc 1667 tree resbnd = NULL;
6744a6ab 1668
538dd0b7
DM
1669 gcall *call;
1670 greturn *ret;
c43ade80 1671 bool alias_is_noreturn = TREE_THIS_VOLATILE (alias);
6744a6ab 1672
e9191ad3
JH
1673 /* We may be called from expand_thunk that releses body except for
1674 DECL_ARGUMENTS. In this case force_gimple_thunk is true. */
1675 if (in_lto_p && !force_gimple_thunk)
70486010 1676 get_untransformed_body ();
afdec9bd 1677 a = DECL_ARGUMENTS (thunk_fndecl);
b84d4347 1678
afdec9bd
JH
1679 current_function_decl = thunk_fndecl;
1680
1681 /* Ensure thunks are emitted in their correct sections. */
9641fab3
JH
1682 resolve_unique_section (thunk_fndecl, 0,
1683 flag_function_sections);
afdec9bd 1684
6744a6ab
JH
1685 DECL_IGNORED_P (thunk_fndecl) = 1;
1686 bitmap_obstack_initialize (NULL);
1687
d52f5295 1688 if (thunk.virtual_offset_p)
6744a6ab
JH
1689 virtual_offset = size_int (virtual_value);
1690
1691 /* Build the return declaration for the function. */
1692 restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1693 if (DECL_RESULT (thunk_fndecl) == NULL_TREE)
1694 {
1695 resdecl = build_decl (input_location, RESULT_DECL, 0, restype);
1696 DECL_ARTIFICIAL (resdecl) = 1;
1697 DECL_IGNORED_P (resdecl) = 1;
1698 DECL_RESULT (thunk_fndecl) = resdecl;
afdec9bd 1699 DECL_CONTEXT (DECL_RESULT (thunk_fndecl)) = thunk_fndecl;
6744a6ab
JH
1700 }
1701 else
1702 resdecl = DECL_RESULT (thunk_fndecl);
1703
10881cff
JH
1704 bb = then_bb = else_bb = return_bb
1705 = init_lowered_empty_function (thunk_fndecl, true, count);
6744a6ab
JH
1706
1707 bsi = gsi_start_bb (bb);
1708
1709 /* Build call to the function being thunked. */
e199dd0a 1710 if (!VOID_TYPE_P (restype)
ab4c578f
MP
1711 && (!alias_is_noreturn
1712 || TREE_ADDRESSABLE (restype)
1713 || TREE_CODE (TYPE_SIZE_UNIT (restype)) != INTEGER_CST))
6744a6ab 1714 {
bc0ec027 1715 if (DECL_BY_REFERENCE (resdecl))
8c14c817
ML
1716 {
1717 restmp = gimple_fold_indirect_ref (resdecl);
1718 if (!restmp)
1719 restmp = build2 (MEM_REF,
1720 TREE_TYPE (TREE_TYPE (DECL_RESULT (alias))),
1721 resdecl,
1722 build_int_cst (TREE_TYPE
1723 (DECL_RESULT (alias)), 0));
1724 }
bc0ec027 1725 else if (!is_gimple_reg_type (restype))
6744a6ab 1726 {
bbd1bae2
JJ
1727 if (aggregate_value_p (resdecl, TREE_TYPE (thunk_fndecl)))
1728 {
1729 restmp = resdecl;
5cf18d25 1730
bbd1bae2
JJ
1731 if (TREE_CODE (restmp) == VAR_DECL)
1732 add_local_decl (cfun, restmp);
1733 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp;
1734 }
1735 else
1736 restmp = create_tmp_var (restype, "retval");
6744a6ab
JH
1737 }
1738 else
7cc434a3 1739 restmp = create_tmp_reg (restype, "retval");
6744a6ab
JH
1740 }
1741
910ad8de 1742 for (arg = a; arg; arg = DECL_CHAIN (arg))
6744a6ab 1743 nargs++;
ef062b13 1744 auto_vec<tree> vargs (nargs);
4eaf52aa
JJ
1745 i = 0;
1746 arg = a;
6744a6ab 1747 if (this_adjusting)
4eaf52aa
JJ
1748 {
1749 vargs.quick_push (thunk_adjust (&bsi, a, 1, fixed_offset,
1750 virtual_offset));
1751 arg = DECL_CHAIN (a);
1752 i = 1;
1753 }
bc0ec027
JH
1754
1755 if (nargs)
4eaf52aa 1756 for (; i < nargs; i++, arg = DECL_CHAIN (arg))
fc044323
JM
1757 {
1758 tree tmp = arg;
1759 if (!is_gimple_val (arg))
1760 {
1761 tmp = create_tmp_reg (TYPE_MAIN_VARIANT
1762 (TREE_TYPE (arg)), "arg");
355fe088 1763 gimple *stmt = gimple_build_assign (tmp, arg);
fc044323
JM
1764 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1765 }
1766 vargs.quick_push (tmp);
1767 }
6744a6ab 1768 call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs);
d52f5295 1769 callees->call_stmt = call;
6744a6ab 1770 gimple_call_set_from_thunk (call, true);
d5e254e1 1771 gimple_call_set_with_bounds (call, instrumentation_clone);
b7aa4a3a
JH
1772
1773 /* Return slot optimization is always possible and in fact requred to
1774 return values with DECL_BY_REFERENCE. */
1775 if (aggregate_value_p (resdecl, TREE_TYPE (thunk_fndecl))
1776 && (!is_gimple_reg_type (TREE_TYPE (resdecl))
1777 || DECL_BY_REFERENCE (resdecl)))
1778 gimple_call_set_return_slot_opt (call, true);
1779
e199dd0a 1780 if (restmp)
bc0ec027
JH
1781 {
1782 gimple_call_set_lhs (call, restmp);
1783 gcc_assert (useless_type_conversion_p (TREE_TYPE (restmp),
1784 TREE_TYPE (TREE_TYPE (alias))));
1785 }
6744a6ab 1786 gsi_insert_after (&bsi, call, GSI_NEW_STMT);
c43ade80 1787 if (!alias_is_noreturn)
bc0ec027 1788 {
4f5a53cc
IE
1789 if (instrumentation_clone
1790 && !DECL_BY_REFERENCE (resdecl)
1791 && restmp
1792 && BOUNDED_P (restmp))
1793 {
1794 resbnd = chkp_insert_retbnd_call (NULL, restmp, &bsi);
1795 create_edge (get_create (gimple_call_fndecl (gsi_stmt (bsi))),
1796 as_a <gcall *> (gsi_stmt (bsi)),
1797 callees->count, callees->frequency);
1798 }
1799
bc0ec027
JH
1800 if (restmp && !this_adjusting
1801 && (fixed_offset || virtual_offset))
1802 {
1803 tree true_label = NULL_TREE;
6744a6ab 1804
bc0ec027
JH
1805 if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE)
1806 {
355fe088 1807 gimple *stmt;
10881cff 1808 edge e;
bc0ec027
JH
1809 /* If the return type is a pointer, we need to
1810 protect against NULL. We know there will be an
1811 adjustment, because that's why we're emitting a
1812 thunk. */
c4d281b2 1813 then_bb = create_basic_block (NULL, bb);
10881cff
JH
1814 then_bb->count = count - count / 16;
1815 then_bb->frequency = BB_FREQ_MAX - BB_FREQ_MAX / 16;
c4d281b2 1816 return_bb = create_basic_block (NULL, then_bb);
10881cff
JH
1817 return_bb->count = count;
1818 return_bb->frequency = BB_FREQ_MAX;
c4d281b2 1819 else_bb = create_basic_block (NULL, else_bb);
10881cff
JH
1820 then_bb->count = count / 16;
1821 then_bb->frequency = BB_FREQ_MAX / 16;
bc0ec027
JH
1822 add_bb_to_loop (then_bb, bb->loop_father);
1823 add_bb_to_loop (return_bb, bb->loop_father);
1824 add_bb_to_loop (else_bb, bb->loop_father);
1825 remove_edge (single_succ_edge (bb));
1826 true_label = gimple_block_label (then_bb);
1827 stmt = gimple_build_cond (NE_EXPR, restmp,
1828 build_zero_cst (TREE_TYPE (restmp)),
1829 NULL_TREE, NULL_TREE);
1830 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
10881cff
JH
1831 e = make_edge (bb, then_bb, EDGE_TRUE_VALUE);
1832 e->probability = REG_BR_PROB_BASE - REG_BR_PROB_BASE / 16;
1833 e->count = count - count / 16;
1834 e = make_edge (bb, else_bb, EDGE_FALSE_VALUE);
1835 e->probability = REG_BR_PROB_BASE / 16;
1836 e->count = count / 16;
1837 e = make_edge (return_bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
1838 e->probability = REG_BR_PROB_BASE;
1839 e->count = count;
1840 e = make_edge (then_bb, return_bb, EDGE_FALLTHRU);
1841 e->probability = REG_BR_PROB_BASE;
1842 e->count = count - count / 16;
1843 e = make_edge (else_bb, return_bb, EDGE_FALLTHRU);
1844 e->probability = REG_BR_PROB_BASE;
1845 e->count = count / 16;
bc0ec027
JH
1846 bsi = gsi_last_bb (then_bb);
1847 }
6744a6ab 1848
bc0ec027
JH
1849 restmp = thunk_adjust (&bsi, restmp, /*this_adjusting=*/0,
1850 fixed_offset, virtual_offset);
1851 if (true_label)
1852 {
355fe088 1853 gimple *stmt;
bc0ec027
JH
1854 bsi = gsi_last_bb (else_bb);
1855 stmt = gimple_build_assign (restmp,
1856 build_zero_cst (TREE_TYPE (restmp)));
1857 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1858 bsi = gsi_last_bb (return_bb);
1859 }
6744a6ab 1860 }
bc0ec027
JH
1861 else
1862 gimple_call_set_tail (call, true);
6744a6ab 1863
bc0ec027 1864 /* Build return value. */
8c14c817
ML
1865 if (!DECL_BY_REFERENCE (resdecl))
1866 ret = gimple_build_return (restmp);
1867 else
1868 ret = gimple_build_return (resdecl);
4f5a53cc 1869 gimple_return_set_retbnd (ret, resbnd);
8c14c817 1870
bc0ec027 1871 gsi_insert_after (&bsi, ret, GSI_NEW_STMT);
6744a6ab
JH
1872 }
1873 else
bc0ec027
JH
1874 {
1875 gimple_call_set_tail (call, true);
1876 remove_edge (single_succ_edge (bb));
1877 }
6744a6ab 1878
afdec9bd 1879 cfun->gimple_df->in_ssa_p = true;
10881cff
JH
1880 profile_status_for_fn (cfun)
1881 = count ? PROFILE_READ : PROFILE_GUESSED;
afdec9bd
JH
1882 /* FIXME: C++ FE should stop setting TREE_ASM_WRITTEN on thunks. */
1883 TREE_ASM_WRITTEN (thunk_fndecl) = false;
6744a6ab
JH
1884 delete_unreachable_blocks ();
1885 update_ssa (TODO_update_ssa);
b2b29377 1886 checking_verify_flow_info ();
253eab4f 1887 free_dominance_info (CDI_DOMINATORS);
6744a6ab 1888
6744a6ab
JH
1889 /* Since we want to emit the thunk, we explicitly mark its name as
1890 referenced. */
d52f5295
ML
1891 thunk.thunk_p = false;
1892 lowered = true;
6744a6ab
JH
1893 bitmap_obstack_release (NULL);
1894 }
1895 current_function_decl = NULL;
af16bc76 1896 set_cfun (NULL);
afdec9bd 1897 return true;
6744a6ab
JH
1898}
1899
3dafb85c 1900/* Assemble thunks and aliases associated to node. */
c47d0034 1901
3dafb85c
ML
1902void
1903cgraph_node::assemble_thunks_and_aliases (void)
c47d0034 1904{
3dafb85c
ML
1905 cgraph_edge *e;
1906 ipa_ref *ref;
39e2db00 1907
3dafb85c 1908 for (e = callers; e;)
d5e254e1
IE
1909 if (e->caller->thunk.thunk_p
1910 && !e->caller->thunk.add_pointer_bounds_args)
c47d0034 1911 {
3dafb85c 1912 cgraph_node *thunk = e->caller;
c47d0034
JH
1913
1914 e = e->next_caller;
d52f5295 1915 thunk->expand_thunk (true, false);
3dafb85c 1916 thunk->assemble_thunks_and_aliases ();
c47d0034
JH
1917 }
1918 else
1919 e = e->next_caller;
e55637b7 1920
3dafb85c 1921 FOR_EACH_ALIAS (this, ref)
e55637b7 1922 {
3dafb85c 1923 cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
71e54687
JH
1924 if (!alias->transparent_alias)
1925 {
1926 bool saved_written = TREE_ASM_WRITTEN (decl);
1927
1928 /* Force assemble_alias to really output the alias this time instead
1929 of buffering it in same alias pairs. */
1930 TREE_ASM_WRITTEN (decl) = 1;
1931 do_assemble_alias (alias->decl,
1932 DECL_ASSEMBLER_NAME (decl));
1933 alias->assemble_thunks_and_aliases ();
1934 TREE_ASM_WRITTEN (decl) = saved_written;
1935 }
e55637b7 1936 }
c47d0034
JH
1937}
1938
3dafb85c 1939/* Expand function specified by node. */
0878843f 1940
3dafb85c
ML
1941void
1942cgraph_node::expand (void)
0878843f 1943{
0878843f
RG
1944 location_t saved_loc;
1945
9c8305f8 1946 /* We ought to not compile any inline clones. */
3dafb85c 1947 gcc_assert (!global.inlined_to);
9c8305f8
JH
1948
1949 announce_function (decl);
3dafb85c
ML
1950 process = 0;
1951 gcc_assert (lowered);
70486010 1952 get_untransformed_body ();
9c8305f8
JH
1953
1954 /* Generate RTL for the body of DECL. */
1955
0878843f
RG
1956 timevar_push (TV_REST_OF_COMPILATION);
1957
3dafb85c 1958 gcc_assert (symtab->global_info_ready);
0878843f
RG
1959
1960 /* Initialize the default bitmap obstack. */
1961 bitmap_obstack_initialize (NULL);
1962
1963 /* Initialize the RTL code for the function. */
0878843f 1964 saved_loc = input_location;
9c8305f8 1965 input_location = DECL_SOURCE_LOCATION (decl);
be373510
ML
1966
1967 gcc_assert (DECL_STRUCT_FUNCTION (decl));
1968 push_cfun (DECL_STRUCT_FUNCTION (decl));
9c8305f8 1969 init_function_start (decl);
0878843f
RG
1970
1971 gimple_register_cfg_hooks ();
1972
1973 bitmap_obstack_initialize (&reg_obstack); /* FIXME, only at RTL generation*/
1974
1975 execute_all_ipa_transforms ();
1976
1977 /* Perform all tree transforms and optimizations. */
1978
1979 /* Signal the start of passes. */
1980 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START, NULL);
1981
2cbf2d95 1982 execute_pass_list (cfun, g->get_passes ()->all_passes);
0878843f
RG
1983
1984 /* Signal the end of passes. */
1985 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END, NULL);
1986
1987 bitmap_obstack_release (&reg_obstack);
1988
1989 /* Release the default bitmap obstack. */
1990 bitmap_obstack_release (NULL);
1991
0878843f
RG
1992 /* If requested, warn about function definitions where the function will
1993 return a value (usually of some struct or union type) which itself will
1994 take up a lot of stack space. */
9c8305f8 1995 if (warn_larger_than && !DECL_EXTERNAL (decl) && TREE_TYPE (decl))
0878843f 1996 {
9c8305f8 1997 tree ret_type = TREE_TYPE (TREE_TYPE (decl));
0878843f
RG
1998
1999 if (ret_type && TYPE_SIZE_UNIT (ret_type)
2000 && TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST
2001 && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type),
2002 larger_than_size))
2003 {
2004 unsigned int size_as_int
2005 = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type));
2006
2007 if (compare_tree_int (TYPE_SIZE_UNIT (ret_type), size_as_int) == 0)
2008 warning (OPT_Wlarger_than_, "size of return value of %q+D is %u bytes",
9c8305f8 2009 decl, size_as_int);
0878843f
RG
2010 else
2011 warning (OPT_Wlarger_than_, "size of return value of %q+D is larger than %wd bytes",
9c8305f8 2012 decl, larger_than_size);
0878843f
RG
2013 }
2014 }
2015
9c8305f8
JH
2016 gimple_set_body (decl, NULL);
2017 if (DECL_STRUCT_FUNCTION (decl) == 0
d52f5295 2018 && !cgraph_node::get (decl)->origin)
0878843f
RG
2019 {
2020 /* Stop pointing to the local nodes about to be freed.
2021 But DECL_INITIAL must remain nonzero so we know this
2022 was an actual function definition.
2023 For a nested function, this is done in c_pop_function_context.
2024 If rest_of_compilation set this to 0, leave it 0. */
9c8305f8
JH
2025 if (DECL_INITIAL (decl) != 0)
2026 DECL_INITIAL (decl) = error_mark_node;
0878843f
RG
2027 }
2028
2029 input_location = saved_loc;
2030
2031 ggc_collect ();
2032 timevar_pop (TV_REST_OF_COMPILATION);
5806d9ac
JH
2033
2034 /* Make sure that BE didn't give up on compiling. */
2035 gcc_assert (TREE_ASM_WRITTEN (decl));
be373510
ML
2036 if (cfun)
2037 pop_cfun ();
1bb7e8f8
JH
2038
2039 /* It would make a lot more sense to output thunks before function body to get more
65d630d4 2040 forward and lest backwarding jumps. This however would need solving problem
1bb7e8f8 2041 with comdats. See PR48668. Also aliases must come after function itself to
65d630d4 2042 make one pass assemblers, like one on AIX, happy. See PR 50689.
1bb7e8f8
JH
2043 FIXME: Perhaps thunks should be move before function IFF they are not in comdat
2044 groups. */
3dafb85c
ML
2045 assemble_thunks_and_aliases ();
2046 release_body ();
39ecc018
JH
2047 /* Eliminate all call edges. This is important so the GIMPLE_CALL no longer
2048 points to the dead function body. */
3dafb85c
ML
2049 remove_callees ();
2050 remove_all_references ();
1c4a429a
JH
2051}
2052
9cec31f4
ML
2053/* Node comparer that is responsible for the order that corresponds
2054 to time when a function was launched for the first time. */
2055
2056static int
2057node_cmp (const void *pa, const void *pb)
2058{
3dafb85c
ML
2059 const cgraph_node *a = *(const cgraph_node * const *) pa;
2060 const cgraph_node *b = *(const cgraph_node * const *) pb;
9cec31f4
ML
2061
2062 /* Functions with time profile must be before these without profile. */
2063 if (!a->tp_first_run || !b->tp_first_run)
2064 return a->tp_first_run - b->tp_first_run;
2065
2066 return a->tp_first_run != b->tp_first_run
2067 ? b->tp_first_run - a->tp_first_run
2068 : b->order - a->order;
2069}
6674a6ce 2070
db0e878d
AJ
2071/* Expand all functions that must be output.
2072
b58b1157
JH
2073 Attempt to topologically sort the nodes so function is output when
2074 all called functions are already assembled to allow data to be
a98ebe2e 2075 propagated across the callgraph. Use a stack to get smaller distance
d1a6adeb 2076 between a function and its callees (later we may choose to use a more
b58b1157
JH
2077 sophisticated algorithm for function reordering; we will likely want
2078 to use subsections to make the output functions appear in top-down
2079 order). */
2080
2081static void
65d630d4 2082expand_all_functions (void)
b58b1157 2083{
3dafb85c
ML
2084 cgraph_node *node;
2085 cgraph_node **order = XCNEWVEC (cgraph_node *,
2086 symtab->cgraph_count);
9cec31f4 2087 unsigned int expanded_func_count = 0, profiled_func_count = 0;
f30cfcb1 2088 int order_pos, new_order_pos = 0;
b58b1157
JH
2089 int i;
2090
af8bca3c 2091 order_pos = ipa_reverse_postorder (order);
3dafb85c 2092 gcc_assert (order_pos == symtab->cgraph_count);
b58b1157 2093
1ae58c30 2094 /* Garbage collector may remove inline clones we eliminate during
18c6ada9
JH
2095 optimization. So we must be sure to not reference them. */
2096 for (i = 0; i < order_pos; i++)
257eb6e3 2097 if (order[i]->process)
18c6ada9
JH
2098 order[new_order_pos++] = order[i];
2099
9cec31f4 2100 if (flag_profile_reorder_functions)
3dafb85c 2101 qsort (order, new_order_pos, sizeof (cgraph_node *), node_cmp);
9cec31f4 2102
18c6ada9 2103 for (i = new_order_pos - 1; i >= 0; i--)
b58b1157
JH
2104 {
2105 node = order[i];
9cec31f4 2106
257eb6e3 2107 if (node->process)
b58b1157 2108 {
21c0a521
DM
2109 expanded_func_count++;
2110 if(node->tp_first_run)
2111 profiled_func_count++;
2112
2113 if (symtab->dump_file)
2114 fprintf (symtab->dump_file,
2115 "Time profile order in expand_all_functions:%s:%d\n",
2116 node->asm_name (), node->tp_first_run);
257eb6e3 2117 node->process = 0;
3dafb85c 2118 node->expand ();
b58b1157
JH
2119 }
2120 }
9cec31f4
ML
2121
2122 if (dump_file)
2123 fprintf (dump_file, "Expanded functions with time profile (%s):%u/%u\n",
2124 main_input_filename, profiled_func_count, expanded_func_count);
2125
3dafb85c
ML
2126 if (symtab->dump_file && flag_profile_reorder_functions)
2127 fprintf (symtab->dump_file, "Expanded functions with time profile:%u/%u\n",
9cec31f4
ML
2128 profiled_func_count, expanded_func_count);
2129
3dafb85c 2130 symtab->process_new_functions ();
45852dcc 2131 free_gimplify_stack ();
50674e96 2132
b58b1157
JH
2133 free (order);
2134}
2135
474eccc6
ILT
2136/* This is used to sort the node types by the cgraph order number. */
2137
24b97832
ILT
2138enum cgraph_order_sort_kind
2139{
2140 ORDER_UNDEFINED = 0,
2141 ORDER_FUNCTION,
2142 ORDER_VAR,
2143 ORDER_ASM
2144};
2145
474eccc6
ILT
2146struct cgraph_order_sort
2147{
24b97832 2148 enum cgraph_order_sort_kind kind;
474eccc6
ILT
2149 union
2150 {
3dafb85c 2151 cgraph_node *f;
2c8326a5 2152 varpool_node *v;
3dafb85c 2153 asm_node *a;
474eccc6
ILT
2154 } u;
2155};
2156
2157/* Output all functions, variables, and asm statements in the order
2158 according to their order fields, which is the order in which they
2159 appeared in the file. This implements -fno-toplevel-reorder. In
2160 this mode we may output functions and variables which don't really
7861b648
AK
2161 need to be output.
2162 When NO_REORDER is true only do this for symbols marked no reorder. */
474eccc6
ILT
2163
2164static void
7861b648 2165output_in_order (bool no_reorder)
474eccc6
ILT
2166{
2167 int max;
3dafb85c 2168 cgraph_order_sort *nodes;
474eccc6 2169 int i;
3dafb85c 2170 cgraph_node *pf;
2c8326a5 2171 varpool_node *pv;
3dafb85c
ML
2172 asm_node *pa;
2173 max = symtab->order;
2174 nodes = XCNEWVEC (cgraph_order_sort, max);
474eccc6 2175
65c70e6b 2176 FOR_EACH_DEFINED_FUNCTION (pf)
474eccc6 2177 {
67348ccc 2178 if (pf->process && !pf->thunk.thunk_p && !pf->alias)
474eccc6 2179 {
7861b648
AK
2180 if (no_reorder && !pf->no_reorder)
2181 continue;
67348ccc 2182 i = pf->order;
474eccc6
ILT
2183 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
2184 nodes[i].kind = ORDER_FUNCTION;
2185 nodes[i].u.f = pf;
2186 }
2187 }
2188
65c70e6b 2189 FOR_EACH_DEFINED_VARIABLE (pv)
67348ccc 2190 if (!DECL_EXTERNAL (pv->decl))
6649df51 2191 {
7861b648
AK
2192 if (no_reorder && !pv->no_reorder)
2193 continue;
67348ccc 2194 i = pv->order;
6649df51
JH
2195 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
2196 nodes[i].kind = ORDER_VAR;
2197 nodes[i].u.v = pv;
2198 }
474eccc6 2199
3dafb85c 2200 for (pa = symtab->first_asm_symbol (); pa; pa = pa->next)
474eccc6
ILT
2201 {
2202 i = pa->order;
2203 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
2204 nodes[i].kind = ORDER_ASM;
2205 nodes[i].u.a = pa;
2206 }
474eccc6 2207
7386e3ee 2208 /* In toplevel reorder mode we output all statics; mark them as needed. */
7386e3ee 2209
7fece979
JJ
2210 for (i = 0; i < max; ++i)
2211 if (nodes[i].kind == ORDER_VAR)
9041d2e6 2212 nodes[i].u.v->finalize_named_section_flags ();
7fece979 2213
474eccc6
ILT
2214 for (i = 0; i < max; ++i)
2215 {
2216 switch (nodes[i].kind)
2217 {
2218 case ORDER_FUNCTION:
257eb6e3 2219 nodes[i].u.f->process = 0;
3dafb85c 2220 nodes[i].u.f->expand ();
474eccc6
ILT
2221 break;
2222
2223 case ORDER_VAR:
4a38b02b
IV
2224#ifdef ACCEL_COMPILER
2225 /* Do not assemble "omp declare target link" vars. */
2226 if (DECL_HAS_VALUE_EXPR_P (nodes[i].u.v->decl)
2227 && lookup_attribute ("omp declare target link",
2228 DECL_ATTRIBUTES (nodes[i].u.v->decl)))
2229 break;
2230#endif
9041d2e6 2231 nodes[i].u.v->assemble_decl ();
474eccc6
ILT
2232 break;
2233
2234 case ORDER_ASM:
2235 assemble_asm (nodes[i].u.a->asm_str);
2236 break;
2237
2238 case ORDER_UNDEFINED:
2239 break;
2240
2241 default:
2242 gcc_unreachable ();
2243 }
2244 }
e7b9eb2c 2245
3dafb85c
ML
2246 symtab->clear_asm_symbols ();
2247
33283dad 2248 free (nodes);
474eccc6
ILT
2249}
2250
ef330312
PB
2251static void
2252ipa_passes (void)
2253{
315f8c0e
DM
2254 gcc::pass_manager *passes = g->get_passes ();
2255
db2960f4 2256 set_cfun (NULL);
04b201a2 2257 current_function_decl = NULL;
726a989a 2258 gimple_register_cfg_hooks ();
ef330312 2259 bitmap_obstack_initialize (NULL);
b20996ff 2260
090fa0ab
GF
2261 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START, NULL);
2262
b20996ff 2263 if (!in_lto_p)
0430f80c 2264 {
315f8c0e 2265 execute_ipa_pass_list (passes->all_small_ipa_passes);
0430f80c
RG
2266 if (seen_error ())
2267 return;
2268 }
3baf459d 2269
8605403e
JH
2270 /* This extra symtab_remove_unreachable_nodes pass tends to catch some
2271 devirtualization and other changes where removal iterate. */
17e0fc92 2272 symtab->remove_unreachable_nodes (symtab->dump_file);
467a8db0 2273
d7f09764
DN
2274 /* If pass_all_early_optimizations was not scheduled, the state of
2275 the cgraph will not be properly updated. Update it now. */
3dafb85c
ML
2276 if (symtab->state < IPA_SSA)
2277 symtab->state = IPA_SSA;
3baf459d 2278
d7f09764
DN
2279 if (!in_lto_p)
2280 {
2281 /* Generate coverage variables and constructors. */
2282 coverage_finish ();
2283
2284 /* Process new functions added. */
2285 set_cfun (NULL);
2286 current_function_decl = NULL;
3dafb85c 2287 symtab->process_new_functions ();
d7f09764 2288
090fa0ab 2289 execute_ipa_summary_passes
6a5ac314 2290 ((ipa_opt_pass_d *) passes->all_regular_ipa_passes);
fb3f88cc 2291 }
c082f9f3
SB
2292
2293 /* Some targets need to handle LTO assembler output specially. */
f0d78df9 2294 if (flag_generate_lto || flag_generate_offload)
c082f9f3
SB
2295 targetm.asm_out.lto_start ();
2296
d7f09764 2297 if (!in_lto_p)
1f6be682
IV
2298 {
2299 if (g->have_offload)
2300 {
2301 section_name_prefix = OFFLOAD_SECTION_NAME_PREFIX;
1b34e6e2 2302 lto_stream_offload_p = true;
837bac8c 2303 ipa_write_summaries ();
1b34e6e2 2304 lto_stream_offload_p = false;
1f6be682
IV
2305 }
2306 if (flag_lto)
2307 {
2308 section_name_prefix = LTO_SECTION_NAME_PREFIX;
1b34e6e2 2309 lto_stream_offload_p = false;
837bac8c 2310 ipa_write_summaries ();
1f6be682
IV
2311 }
2312 }
d7f09764 2313
f0d78df9 2314 if (flag_generate_lto || flag_generate_offload)
c082f9f3
SB
2315 targetm.asm_out.lto_end ();
2316
cc8547a7 2317 if (!flag_ltrans && (in_lto_p || !flag_lto || flag_fat_lto_objects))
315f8c0e 2318 execute_ipa_pass_list (passes->all_regular_ipa_passes);
090fa0ab 2319 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END, NULL);
3baf459d 2320
ef330312
PB
2321 bitmap_obstack_release (NULL);
2322}
2323
25e2c40d
JH
2324
2325/* Return string alias is alias of. */
2326
2327static tree
2328get_alias_symbol (tree decl)
2329{
2330 tree alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
2331 return get_identifier (TREE_STRING_POINTER
2332 (TREE_VALUE (TREE_VALUE (alias))));
2333}
2334
2335
c9552bff 2336/* Weakrefs may be associated to external decls and thus not output
073a8998 2337 at expansion time. Emit all necessary aliases. */
c9552bff 2338
3dafb85c
ML
2339void
2340symbol_table::output_weakrefs (void)
c9552bff 2341{
5e20cdc9 2342 symtab_node *node;
d5e254e1 2343 cgraph_node *cnode;
40a7fe1e 2344 FOR_EACH_SYMBOL (node)
67348ccc
DM
2345 if (node->alias
2346 && !TREE_ASM_WRITTEN (node->decl)
d5e254e1
IE
2347 && (!(cnode = dyn_cast <cgraph_node *> (node))
2348 || !cnode->instrumented_version
2349 || !TREE_ASM_WRITTEN (cnode->instrumented_version->decl))
67348ccc 2350 && node->weakref)
40a7fe1e
JH
2351 {
2352 tree target;
2353
2354 /* Weakrefs are special by not requiring target definition in current
2355 compilation unit. It is thus bit hard to work out what we want to
2356 alias.
2357 When alias target is defined, we need to fetch it from symtab reference,
2358 otherwise it is pointed to by alias_target. */
67348ccc
DM
2359 if (node->alias_target)
2360 target = (DECL_P (node->alias_target)
2361 ? DECL_ASSEMBLER_NAME (node->alias_target)
2362 : node->alias_target);
2363 else if (node->analyzed)
d52f5295 2364 target = DECL_ASSEMBLER_NAME (node->get_alias_target ()->decl);
40a7fe1e
JH
2365 else
2366 {
2367 gcc_unreachable ();
67348ccc 2368 target = get_alias_symbol (node->decl);
40a7fe1e 2369 }
67348ccc 2370 do_assemble_alias (node->decl, target);
40a7fe1e 2371 }
c9552bff
JH
2372}
2373
711417cd
RG
2374/* Perform simple optimizations based on callgraph. */
2375
2376void
3dafb85c 2377symbol_table::compile (void)
711417cd
RG
2378{
2379 if (seen_error ())
2380 return;
2381
b2b29377 2382 symtab_node::checking_verify_symtab_nodes ();
711417cd 2383
711417cd
RG
2384 timevar_push (TV_CGRAPHOPT);
2385 if (pre_ipa_mem_report)
2386 {
2387 fprintf (stderr, "Memory consumption before IPA\n");
2388 dump_memory_report (false);
2389 }
2390 if (!quiet_flag)
2391 fprintf (stderr, "Performing interprocedural optimizations\n");
3dafb85c 2392 state = IPA;
711417cd 2393
1f6be682
IV
2394 /* Offloading requires LTO infrastructure. */
2395 if (!in_lto_p && g->have_offload)
f0d78df9 2396 flag_generate_offload = 1;
1f6be682 2397
65d630d4 2398 /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE. */
f0d78df9 2399 if (flag_generate_lto || flag_generate_offload)
65d630d4
JH
2400 lto_streamer_hooks_init ();
2401
711417cd
RG
2402 /* Don't run the IPA passes if there was any error or sorry messages. */
2403 if (!seen_error ())
2404 ipa_passes ();
2405
2406 /* Do nothing else if any IPA pass found errors or if we are just streaming LTO. */
2407 if (seen_error ()
2408 || (!in_lto_p && flag_lto && !flag_fat_lto_objects))
2409 {
2410 timevar_pop (TV_CGRAPHOPT);
2411 return;
2412 }
2413
3dafb85c
ML
2414 global_info_ready = true;
2415 if (dump_file)
711417cd 2416 {
3dafb85c
ML
2417 fprintf (dump_file, "Optimized ");
2418 symtab_node:: dump_table (dump_file);
711417cd
RG
2419 }
2420 if (post_ipa_mem_report)
2421 {
2422 fprintf (stderr, "Memory consumption after IPA\n");
2423 dump_memory_report (false);
2424 }
2425 timevar_pop (TV_CGRAPHOPT);
2426
2427 /* Output everything. */
2428 (*debug_hooks->assembly_start) ();
2429 if (!quiet_flag)
2430 fprintf (stderr, "Assembling functions:\n");
b2b29377 2431 symtab_node::checking_verify_symtab_nodes ();
711417cd 2432
3dafb85c 2433 materialize_all_clones ();
711417cd 2434 bitmap_obstack_initialize (NULL);
315f8c0e 2435 execute_ipa_pass_list (g->get_passes ()->all_late_ipa_passes);
711417cd 2436 bitmap_obstack_release (NULL);
65d630d4 2437 mark_functions_to_output ();
711417cd 2438
38e55e5c
JH
2439 /* When weakref support is missing, we autmatically translate all
2440 references to NODE to references to its ultimate alias target.
2441 The renaming mechanizm uses flag IDENTIFIER_TRANSPARENT_ALIAS and
2442 TREE_CHAIN.
2443
2444 Set up this mapping before we output any assembler but once we are sure
2445 that all symbol renaming is done.
2446
2447 FIXME: All this uglyness can go away if we just do renaming at gimple
2448 level by physically rewritting the IL. At the moment we can only redirect
2449 calls, so we need infrastructure for renaming references as well. */
2450#ifndef ASM_OUTPUT_WEAKREF
5e20cdc9 2451 symtab_node *node;
38e55e5c
JH
2452
2453 FOR_EACH_SYMBOL (node)
67348ccc
DM
2454 if (node->alias
2455 && lookup_attribute ("weakref", DECL_ATTRIBUTES (node->decl)))
38e55e5c
JH
2456 {
2457 IDENTIFIER_TRANSPARENT_ALIAS
67348ccc
DM
2458 (DECL_ASSEMBLER_NAME (node->decl)) = 1;
2459 TREE_CHAIN (DECL_ASSEMBLER_NAME (node->decl))
2460 = (node->alias_target ? node->alias_target
dacd445e 2461 : DECL_ASSEMBLER_NAME (node->get_alias_target ()->decl));
38e55e5c
JH
2462 }
2463#endif
2464
3dafb85c 2465 state = EXPANSION;
9cec31f4 2466
711417cd 2467 if (!flag_toplevel_reorder)
7861b648 2468 output_in_order (false);
711417cd
RG
2469 else
2470 {
7861b648
AK
2471 /* Output first asm statements and anything ordered. The process
2472 flag is cleared for these nodes, so we skip them later. */
2473 output_in_order (true);
65d630d4 2474 expand_all_functions ();
3dafb85c 2475 output_variables ();
711417cd
RG
2476 }
2477
3dafb85c
ML
2478 process_new_functions ();
2479 state = FINISHED;
07250f0e 2480 output_weakrefs ();
711417cd 2481
3dafb85c 2482 if (dump_file)
711417cd 2483 {
3dafb85c
ML
2484 fprintf (dump_file, "\nFinal ");
2485 symtab_node::dump_table (dump_file);
711417cd 2486 }
b2b29377
MM
2487 if (!flag_checking)
2488 return;
d52f5295 2489 symtab_node::verify_symtab_nodes ();
711417cd
RG
2490 /* Double check that all inline clones are gone and that all
2491 function bodies have been released from memory. */
2492 if (!seen_error ())
2493 {
3dafb85c 2494 cgraph_node *node;
711417cd
RG
2495 bool error_found = false;
2496
65c70e6b
JH
2497 FOR_EACH_DEFINED_FUNCTION (node)
2498 if (node->global.inlined_to
67348ccc 2499 || gimple_has_body_p (node->decl))
711417cd
RG
2500 {
2501 error_found = true;
d52f5295 2502 node->debug ();
711417cd
RG
2503 }
2504 if (error_found)
2505 internal_error ("nodes with unreleased memory found");
2506 }
711417cd
RG
2507}
2508
2509
2510/* Analyze the whole compilation unit once it is parsed completely. */
2511
2512void
3dafb85c 2513symbol_table::finalize_compilation_unit (void)
711417cd
RG
2514{
2515 timevar_push (TV_CGRAPH);
2516
711417cd
RG
2517 /* If we're here there's no current function anymore. Some frontends
2518 are lazy in clearing these. */
2519 current_function_decl = NULL;
2520 set_cfun (NULL);
2521
2522 /* Do not skip analyzing the functions if there were errors, we
2523 miss diagnostics for following functions otherwise. */
2524
2525 /* Emit size functions we didn't inline. */
2526 finalize_size_functions ();
2527
2528 /* Mark alias targets necessary and emit diagnostics. */
711417cd
RG
2529 handle_alias_pairs ();
2530
2531 if (!quiet_flag)
2532 {
2533 fprintf (stderr, "\nAnalyzing compilation unit\n");
2534 fflush (stderr);
2535 }
2536
2537 if (flag_dump_passes)
2538 dump_passes ();
2539
2540 /* Gimplify and lower all functions, compute reachability and
2541 remove unreachable nodes. */
d7438551 2542 analyze_functions (/*first_time=*/true);
711417cd
RG
2543
2544 /* Mark alias targets necessary and emit diagnostics. */
711417cd
RG
2545 handle_alias_pairs ();
2546
2547 /* Gimplify and lower thunks. */
d7438551
AH
2548 analyze_functions (/*first_time=*/false);
2549
9ba01f82
RB
2550 if (!seen_error ())
2551 {
2552 /* Emit early debug for reachable functions, and by consequence,
2553 locally scoped symbols. */
2554 struct cgraph_node *cnode;
2555 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (cnode)
2556 (*debug_hooks->early_global_decl) (cnode->decl);
2557
2558 /* Clean up anything that needs cleaning up after initial debug
2559 generation. */
2560 (*debug_hooks->early_finish) ();
2561 }
2562
711417cd 2563 /* Finally drive the pass manager. */
65d630d4 2564 compile ();
711417cd
RG
2565
2566 timevar_pop (TV_CGRAPH);
2567}
2568
3edf64aa
DM
2569/* Reset all state within cgraphunit.c so that we can rerun the compiler
2570 within the same process. For use by toplev::finalize. */
2571
2572void
2573cgraphunit_c_finalize (void)
2574{
2575 gcc_assert (cgraph_new_nodes.length () == 0);
2576 cgraph_new_nodes.truncate (0);
2577
2578 vtable_entry_type = NULL;
2579 queued_nodes = &symtab_terminator;
2580
2581 first_analyzed = NULL;
2582 first_analyzed_var = NULL;
2583}
2584
d52f5295 2585/* Creates a wrapper from cgraph_node to TARGET node. Thunk is used for this
8be2dc8c
ML
2586 kind of wrapper method. */
2587
2588void
3dafb85c 2589cgraph_node::create_wrapper (cgraph_node *target)
8be2dc8c 2590{
3f9f4ae7
ML
2591 /* Preserve DECL_RESULT so we get right by reference flag. */
2592 tree decl_result = DECL_RESULT (decl);
8be2dc8c 2593
3f9f4ae7
ML
2594 /* Remove the function's body but keep arguments to be reused
2595 for thunk. */
2596 release_body (true);
2597 reset ();
8be2dc8c 2598
0a7246ee 2599 DECL_UNINLINABLE (decl) = false;
3f9f4ae7
ML
2600 DECL_RESULT (decl) = decl_result;
2601 DECL_INITIAL (decl) = NULL;
2602 allocate_struct_function (decl, false);
2603 set_cfun (NULL);
8be2dc8c 2604
3f9f4ae7
ML
2605 /* Turn alias into thunk and expand it into GIMPLE representation. */
2606 definition = true;
e68287df
ML
2607
2608 memset (&thunk, 0, sizeof (cgraph_thunk_info));
3f9f4ae7 2609 thunk.thunk_p = true;
10881cff 2610 create_edge (target, NULL, count, CGRAPH_FREQ_BASE);
ce8bdcef 2611 callees->can_throw_external = !TREE_NOTHROW (target->decl);
8be2dc8c 2612
3f9f4ae7 2613 tree arguments = DECL_ARGUMENTS (decl);
d862b343 2614
3f9f4ae7
ML
2615 while (arguments)
2616 {
2617 TREE_ADDRESSABLE (arguments) = false;
2618 arguments = TREE_CHAIN (arguments);
2619 }
d862b343 2620
3f9f4ae7 2621 expand_thunk (false, true);
8be2dc8c 2622
3f9f4ae7
ML
2623 /* Inline summary set-up. */
2624 analyze ();
2625 inline_analyze_function (this);
8be2dc8c 2626}
711417cd 2627
7be82279 2628#include "gt-cgraphunit.h"