* testsuite/17_intro/static.cc: Ignore AIX TOC reload warnings.
[official-gcc.git] / gcc / cgraphunit.c
blobfb23abed8daa859f452c063a0c5a695e8f0a45ca
1 /* Driver of optimization process
2 Copyright (C) 2003-2013 Free Software Foundation, Inc.
3 Contributed by Jan Hubicka
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 /* This module implements main driver of compilation process.
23 The main scope of this file is to act as an interface in between
24 tree based frontends and the backend.
26 The front-end is supposed to use following functionality:
28 - cgraph_finalize_function
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.
33 (There is one exception needed for implementing GCC extern inline
34 function.)
36 - varpool_finalize_decl
38 This function has same behavior as the above but is used for static
39 variables.
41 - add_asm_node
43 Insert new toplevel ASM statement
45 - finalize_compilation_unit
47 This function is called once (source level) compilation unit is finalized
48 and it will no longer change.
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.
53 Those are used to discover other necessary functions and variables.
55 At the end the bodies of unreachable functions are removed.
57 The function can be called multiple times when multiple source level
58 compilation units are combined.
60 - compile
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).
68 Compile time:
70 1) Inter-procedural optimization.
71 (ipa_passes)
73 This part is further split into:
75 a) early optimizations. These are local passes executed in
76 the topological order on the callgraph.
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.
83 b) early small interprocedural passes.
85 Those are interprocedural passes executed only at compilation
86 time. These include, for example, transational memory lowering,
87 unreachable code removal and other simple transformations.
89 c) IP analysis stage. All interprocedural passes do their
90 analysis.
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.
98 d) LTO sreaming. When doing LTO, everything important gets
99 streamed into the object file.
101 Compile time and or linktime analysis stage (WPA):
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.
112 Compile time and/or parallel linktime stage (ltrans)
114 Each of the object files is streamed back and compiled
115 separately. Now the function bodies becomes available
116 again.
118 2) Virtual clone materialization
119 (cgraph_materialize_clone)
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
128 All IP passes transform function bodies based on earlier
129 decision of the IP propagation.
131 4) late small IP passes
133 Simple IP passes working within single program partition.
135 5) Expansion
136 (expand_all_functions)
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.
144 Note that with -fno-toplevel-reorder passes 5 and 6
145 are combined together in cgraph_output_in_order.
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.
154 - cgraph_function_versioning
156 produces a copy of function into new one (a version)
157 and apply simple transformations
160 #include "config.h"
161 #include "system.h"
162 #include "coretypes.h"
163 #include "tm.h"
164 #include "tree.h"
165 #include "varasm.h"
166 #include "stor-layout.h"
167 #include "stringpool.h"
168 #include "output.h"
169 #include "rtl.h"
170 #include "gimple.h"
171 #include "gimplify.h"
172 #include "gimple-iterator.h"
173 #include "gimplify-me.h"
174 #include "gimple-ssa.h"
175 #include "tree-cfg.h"
176 #include "tree-into-ssa.h"
177 #include "tree-ssa.h"
178 #include "tree-inline.h"
179 #include "langhooks.h"
180 #include "pointer-set.h"
181 #include "toplev.h"
182 #include "flags.h"
183 #include "ggc.h"
184 #include "debug.h"
185 #include "target.h"
186 #include "diagnostic.h"
187 #include "params.h"
188 #include "fibheap.h"
189 #include "intl.h"
190 #include "function.h"
191 #include "ipa-prop.h"
192 #include "tree-iterator.h"
193 #include "tree-pass.h"
194 #include "tree-dump.h"
195 #include "gimple-pretty-print.h"
196 #include "output.h"
197 #include "coverage.h"
198 #include "plugin.h"
199 #include "ipa-inline.h"
200 #include "ipa-utils.h"
201 #include "lto-streamer.h"
202 #include "except.h"
203 #include "cfgloop.h"
204 #include "regset.h" /* FIXME: For reg_obstack. */
205 #include "context.h"
206 #include "pass_manager.h"
207 #include "tree-nested.h"
209 /* Queue of cgraph nodes scheduled to be added into cgraph. This is a
210 secondary queue used during optimization to accommodate passes that
211 may generate new functions that need to be optimized and expanded. */
212 cgraph_node_set cgraph_new_nodes;
214 static void expand_all_functions (void);
215 static void mark_functions_to_output (void);
216 static void expand_function (struct cgraph_node *);
217 static void analyze_function (struct cgraph_node *);
218 static void handle_alias_pairs (void);
220 FILE *cgraph_dump_file;
222 /* Linked list of cgraph asm nodes. */
223 struct asm_node *asm_nodes;
225 /* Last node in cgraph_asm_nodes. */
226 static GTY(()) struct asm_node *asm_last_node;
228 /* Used for vtable lookup in thunk adjusting. */
229 static GTY (()) tree vtable_entry_type;
231 /* Determine if symbol DECL is needed. That is, visible to something
232 either outside this translation unit, something magic in the system
233 configury */
234 bool
235 decide_is_symbol_needed (symtab_node *node)
237 tree decl = node->decl;
239 /* Double check that no one output the function into assembly file
240 early. */
241 gcc_checking_assert (!DECL_ASSEMBLER_NAME_SET_P (decl)
242 || !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)));
244 if (!node->definition)
245 return false;
247 if (DECL_EXTERNAL (decl))
248 return false;
250 /* If the user told us it is used, then it must be so. */
251 if (node->force_output)
252 return true;
254 /* ABI forced symbols are needed when they are external. */
255 if (node->forced_by_abi && TREE_PUBLIC (decl))
256 return true;
258 /* Keep constructors, destructors and virtual functions. */
259 if (TREE_CODE (decl) == FUNCTION_DECL
260 && (DECL_STATIC_CONSTRUCTOR (decl) || DECL_STATIC_DESTRUCTOR (decl)))
261 return true;
263 /* Externally visible variables must be output. The exception is
264 COMDAT variables that must be output only when they are needed. */
265 if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
266 return true;
268 return false;
271 /* Head and terminator of the queue of nodes to be processed while building
272 callgraph. */
274 static symtab_node symtab_terminator;
275 static symtab_node *queued_nodes = &symtab_terminator;
277 /* Add NODE to queue starting at QUEUED_NODES.
278 The queue is linked via AUX pointers and terminated by pointer to 1. */
280 static void
281 enqueue_node (symtab_node *node)
283 if (node->aux)
284 return;
285 gcc_checking_assert (queued_nodes);
286 node->aux = queued_nodes;
287 queued_nodes = node;
290 /* Process CGRAPH_NEW_FUNCTIONS and perform actions necessary to add these
291 functions into callgraph in a way so they look like ordinary reachable
292 functions inserted into callgraph already at construction time. */
294 void
295 cgraph_process_new_functions (void)
297 tree fndecl;
298 struct cgraph_node *node;
299 cgraph_node_set_iterator csi;
301 if (!cgraph_new_nodes)
302 return;
303 handle_alias_pairs ();
304 /* Note that this queue may grow as its being processed, as the new
305 functions may generate new ones. */
306 for (csi = csi_start (cgraph_new_nodes); !csi_end_p (csi); csi_next (&csi))
308 node = csi_node (csi);
309 fndecl = node->decl;
310 switch (cgraph_state)
312 case CGRAPH_STATE_CONSTRUCTION:
313 /* At construction time we just need to finalize function and move
314 it into reachable functions list. */
316 cgraph_finalize_function (fndecl, false);
317 cgraph_call_function_insertion_hooks (node);
318 enqueue_node (node);
319 break;
321 case CGRAPH_STATE_IPA:
322 case CGRAPH_STATE_IPA_SSA:
323 /* When IPA optimization already started, do all essential
324 transformations that has been already performed on the whole
325 cgraph but not on this function. */
327 gimple_register_cfg_hooks ();
328 if (!node->analyzed)
329 analyze_function (node);
330 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
331 if (cgraph_state == CGRAPH_STATE_IPA_SSA
332 && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
333 g->get_passes ()->execute_early_local_passes ();
334 else if (inline_summary_vec != NULL)
335 compute_inline_parameters (node, true);
336 free_dominance_info (CDI_POST_DOMINATORS);
337 free_dominance_info (CDI_DOMINATORS);
338 pop_cfun ();
339 cgraph_call_function_insertion_hooks (node);
340 break;
342 case CGRAPH_STATE_EXPANSION:
343 /* Functions created during expansion shall be compiled
344 directly. */
345 node->process = 0;
346 cgraph_call_function_insertion_hooks (node);
347 expand_function (node);
348 break;
350 default:
351 gcc_unreachable ();
352 break;
355 free_cgraph_node_set (cgraph_new_nodes);
356 cgraph_new_nodes = NULL;
359 /* As an GCC extension we allow redefinition of the function. The
360 semantics when both copies of bodies differ is not well defined.
361 We replace the old body with new body so in unit at a time mode
362 we always use new body, while in normal mode we may end up with
363 old body inlined into some functions and new body expanded and
364 inlined in others.
366 ??? It may make more sense to use one body for inlining and other
367 body for expanding the function but this is difficult to do. */
369 void
370 cgraph_reset_node (struct cgraph_node *node)
372 /* If node->process is set, then we have already begun whole-unit analysis.
373 This is *not* testing for whether we've already emitted the function.
374 That case can be sort-of legitimately seen with real function redefinition
375 errors. I would argue that the front end should never present us with
376 such a case, but don't enforce that for now. */
377 gcc_assert (!node->process);
379 /* Reset our data structures so we can analyze the function again. */
380 memset (&node->local, 0, sizeof (node->local));
381 memset (&node->global, 0, sizeof (node->global));
382 memset (&node->rtl, 0, sizeof (node->rtl));
383 node->analyzed = false;
384 node->definition = false;
385 node->alias = false;
386 node->weakref = false;
387 node->cpp_implicit_alias = false;
389 cgraph_node_remove_callees (node);
390 ipa_remove_all_references (&node->ref_list);
393 /* Return true when there are references to NODE. */
395 static bool
396 referred_to_p (symtab_node *node)
398 struct ipa_ref *ref;
400 /* See if there are any references at all. */
401 if (ipa_ref_list_referring_iterate (&node->ref_list, 0, ref))
402 return true;
403 /* For functions check also calls. */
404 cgraph_node *cn = dyn_cast <cgraph_node> (node);
405 if (cn && cn->callers)
406 return true;
407 return false;
410 /* DECL has been parsed. Take it, queue it, compile it at the whim of the
411 logic in effect. If NO_COLLECT is true, then our caller cannot stand to have
412 the garbage collector run at the moment. We would need to either create
413 a new GC context, or just not compile right now. */
415 void
416 cgraph_finalize_function (tree decl, bool no_collect)
418 struct cgraph_node *node = cgraph_get_create_node (decl);
420 if (node->definition)
422 /* Nested functions should only be defined once. */
423 gcc_assert (!DECL_CONTEXT (decl)
424 || TREE_CODE (DECL_CONTEXT (decl)) != FUNCTION_DECL);
425 cgraph_reset_node (node);
426 node->local.redefined_extern_inline = true;
429 notice_global_symbol (decl);
430 node->definition = true;
431 node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL;
433 /* With -fkeep-inline-functions we are keeping all inline functions except
434 for extern inline ones. */
435 if (flag_keep_inline_functions
436 && DECL_DECLARED_INLINE_P (decl)
437 && !DECL_EXTERNAL (decl)
438 && !DECL_DISREGARD_INLINE_LIMITS (decl))
439 node->force_output = 1;
441 /* When not optimizing, also output the static functions. (see
442 PR24561), but don't do so for always_inline functions, functions
443 declared inline and nested functions. These were optimized out
444 in the original implementation and it is unclear whether we want
445 to change the behavior here. */
446 if ((!optimize
447 && !node->cpp_implicit_alias
448 && !DECL_DISREGARD_INLINE_LIMITS (decl)
449 && !DECL_DECLARED_INLINE_P (decl)
450 && !(DECL_CONTEXT (decl)
451 && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL))
452 && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
453 node->force_output = 1;
455 /* If we've not yet emitted decl, tell the debug info about it. */
456 if (!TREE_ASM_WRITTEN (decl))
457 (*debug_hooks->deferred_inline_function) (decl);
459 /* Possibly warn about unused parameters. */
460 if (warn_unused_parameter)
461 do_warn_unused_parameter (decl);
463 if (!no_collect)
464 ggc_collect ();
466 if (cgraph_state == CGRAPH_STATE_CONSTRUCTION
467 && (decide_is_symbol_needed (node)
468 || referred_to_p (node)))
469 enqueue_node (node);
472 /* Add the function FNDECL to the call graph.
473 Unlike cgraph_finalize_function, this function is intended to be used
474 by middle end and allows insertion of new function at arbitrary point
475 of compilation. The function can be either in high, low or SSA form
476 GIMPLE.
478 The function is assumed to be reachable and have address taken (so no
479 API breaking optimizations are performed on it).
481 Main work done by this function is to enqueue the function for later
482 processing to avoid need the passes to be re-entrant. */
484 void
485 cgraph_add_new_function (tree fndecl, bool lowered)
487 gcc::pass_manager *passes = g->get_passes ();
488 struct cgraph_node *node;
489 switch (cgraph_state)
491 case CGRAPH_STATE_PARSING:
492 cgraph_finalize_function (fndecl, false);
493 break;
494 case CGRAPH_STATE_CONSTRUCTION:
495 /* Just enqueue function to be processed at nearest occurrence. */
496 node = cgraph_create_node (fndecl);
497 if (lowered)
498 node->lowered = true;
499 if (!cgraph_new_nodes)
500 cgraph_new_nodes = cgraph_node_set_new ();
501 cgraph_node_set_add (cgraph_new_nodes, node);
502 break;
504 case CGRAPH_STATE_IPA:
505 case CGRAPH_STATE_IPA_SSA:
506 case CGRAPH_STATE_EXPANSION:
507 /* Bring the function into finalized state and enqueue for later
508 analyzing and compilation. */
509 node = cgraph_get_create_node (fndecl);
510 node->local.local = false;
511 node->definition = true;
512 node->force_output = true;
513 if (!lowered && cgraph_state == CGRAPH_STATE_EXPANSION)
515 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
516 gimple_register_cfg_hooks ();
517 bitmap_obstack_initialize (NULL);
518 execute_pass_list (passes->all_lowering_passes);
519 passes->execute_early_local_passes ();
520 bitmap_obstack_release (NULL);
521 pop_cfun ();
523 lowered = true;
525 if (lowered)
526 node->lowered = true;
527 if (!cgraph_new_nodes)
528 cgraph_new_nodes = cgraph_node_set_new ();
529 cgraph_node_set_add (cgraph_new_nodes, node);
530 break;
532 case CGRAPH_STATE_FINISHED:
533 /* At the very end of compilation we have to do all the work up
534 to expansion. */
535 node = cgraph_create_node (fndecl);
536 if (lowered)
537 node->lowered = true;
538 node->definition = true;
539 analyze_function (node);
540 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
541 gimple_register_cfg_hooks ();
542 bitmap_obstack_initialize (NULL);
543 if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
544 g->get_passes ()->execute_early_local_passes ();
545 bitmap_obstack_release (NULL);
546 pop_cfun ();
547 expand_function (node);
548 break;
550 default:
551 gcc_unreachable ();
554 /* Set a personality if required and we already passed EH lowering. */
555 if (lowered
556 && (function_needs_eh_personality (DECL_STRUCT_FUNCTION (fndecl))
557 == eh_personality_lang))
558 DECL_FUNCTION_PERSONALITY (fndecl) = lang_hooks.eh_personality ();
561 /* Add a top-level asm statement to the list. */
563 struct asm_node *
564 add_asm_node (tree asm_str)
566 struct asm_node *node;
568 node = ggc_alloc_cleared_asm_node ();
569 node->asm_str = asm_str;
570 node->order = symtab_order++;
571 node->next = NULL;
572 if (asm_nodes == NULL)
573 asm_nodes = node;
574 else
575 asm_last_node->next = node;
576 asm_last_node = node;
577 return node;
580 /* Output all asm statements we have stored up to be output. */
582 static void
583 output_asm_statements (void)
585 struct asm_node *can;
587 if (seen_error ())
588 return;
590 for (can = asm_nodes; can; can = can->next)
591 assemble_asm (can->asm_str);
592 asm_nodes = NULL;
595 /* Analyze the function scheduled to be output. */
596 static void
597 analyze_function (struct cgraph_node *node)
599 tree decl = node->decl;
600 location_t saved_loc = input_location;
601 input_location = DECL_SOURCE_LOCATION (decl);
603 if (node->thunk.thunk_p)
605 cgraph_create_edge (node, cgraph_get_node (node->thunk.alias),
606 NULL, 0, CGRAPH_FREQ_BASE);
607 if (!expand_thunk (node, false))
609 node->thunk.alias = NULL;
610 node->analyzed = true;
611 return;
613 node->thunk.alias = NULL;
615 if (node->alias)
616 symtab_resolve_alias
617 (node, cgraph_get_node (node->alias_target));
618 else if (node->dispatcher_function)
620 /* Generate the dispatcher body of multi-versioned functions. */
621 struct cgraph_function_version_info *dispatcher_version_info
622 = get_cgraph_node_version (node);
623 if (dispatcher_version_info != NULL
624 && (dispatcher_version_info->dispatcher_resolver
625 == NULL_TREE))
627 tree resolver = NULL_TREE;
628 gcc_assert (targetm.generate_version_dispatcher_body);
629 resolver = targetm.generate_version_dispatcher_body (node);
630 gcc_assert (resolver != NULL_TREE);
633 else
635 push_cfun (DECL_STRUCT_FUNCTION (decl));
637 assign_assembler_name_if_neeeded (node->decl);
639 /* Make sure to gimplify bodies only once. During analyzing a
640 function we lower it, which will require gimplified nested
641 functions, so we can end up here with an already gimplified
642 body. */
643 if (!gimple_has_body_p (decl))
644 gimplify_function_tree (decl);
645 dump_function (TDI_generic, decl);
647 /* Lower the function. */
648 if (!node->lowered)
650 if (node->nested)
651 lower_nested_functions (node->decl);
652 gcc_assert (!node->nested);
654 gimple_register_cfg_hooks ();
655 bitmap_obstack_initialize (NULL);
656 execute_pass_list (g->get_passes ()->all_lowering_passes);
657 free_dominance_info (CDI_POST_DOMINATORS);
658 free_dominance_info (CDI_DOMINATORS);
659 compact_blocks ();
660 bitmap_obstack_release (NULL);
661 node->lowered = true;
664 pop_cfun ();
666 node->analyzed = true;
668 input_location = saved_loc;
671 /* C++ frontend produce same body aliases all over the place, even before PCH
672 gets streamed out. It relies on us linking the aliases with their function
673 in order to do the fixups, but ipa-ref is not PCH safe. Consequentely we
674 first produce aliases without links, but once C++ FE is sure he won't sream
675 PCH we build the links via this function. */
677 void
678 cgraph_process_same_body_aliases (void)
680 symtab_node *node;
681 FOR_EACH_SYMBOL (node)
682 if (node->cpp_implicit_alias && !node->analyzed)
683 symtab_resolve_alias
684 (node,
685 TREE_CODE (node->alias_target) == VAR_DECL
686 ? (symtab_node *)varpool_node_for_decl (node->alias_target)
687 : (symtab_node *)cgraph_get_create_node (node->alias_target));
688 cpp_implicit_aliases_done = true;
691 /* Process attributes common for vars and functions. */
693 static void
694 process_common_attributes (tree decl)
696 tree weakref = lookup_attribute ("weakref", DECL_ATTRIBUTES (decl));
698 if (weakref && !lookup_attribute ("alias", DECL_ATTRIBUTES (decl)))
700 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
701 "%<weakref%> attribute should be accompanied with"
702 " an %<alias%> attribute");
703 DECL_WEAK (decl) = 0;
704 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
705 DECL_ATTRIBUTES (decl));
709 /* Look for externally_visible and used attributes and mark cgraph nodes
710 accordingly.
712 We cannot mark the nodes at the point the attributes are processed (in
713 handle_*_attribute) because the copy of the declarations available at that
714 point may not be canonical. For example, in:
716 void f();
717 void f() __attribute__((used));
719 the declaration we see in handle_used_attribute will be the second
720 declaration -- but the front end will subsequently merge that declaration
721 with the original declaration and discard the second declaration.
723 Furthermore, we can't mark these nodes in cgraph_finalize_function because:
725 void f() {}
726 void f() __attribute__((externally_visible));
728 is valid.
730 So, we walk the nodes at the end of the translation unit, applying the
731 attributes at that point. */
733 static void
734 process_function_and_variable_attributes (struct cgraph_node *first,
735 struct varpool_node *first_var)
737 struct cgraph_node *node;
738 struct varpool_node *vnode;
740 for (node = cgraph_first_function (); node != first;
741 node = cgraph_next_function (node))
743 tree decl = node->decl;
744 if (DECL_PRESERVE_P (decl))
745 cgraph_mark_force_output_node (node);
746 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
748 if (! TREE_PUBLIC (node->decl))
749 warning_at (DECL_SOURCE_LOCATION (node->decl), OPT_Wattributes,
750 "%<externally_visible%>"
751 " attribute have effect only on public objects");
753 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
754 && (node->definition && !node->alias))
756 warning_at (DECL_SOURCE_LOCATION (node->decl), OPT_Wattributes,
757 "%<weakref%> attribute ignored"
758 " because function is defined");
759 DECL_WEAK (decl) = 0;
760 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
761 DECL_ATTRIBUTES (decl));
764 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl))
765 && !DECL_DECLARED_INLINE_P (decl)
766 /* redefining extern inline function makes it DECL_UNINLINABLE. */
767 && !DECL_UNINLINABLE (decl))
768 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
769 "always_inline function might not be inlinable");
771 process_common_attributes (decl);
773 for (vnode = varpool_first_variable (); vnode != first_var;
774 vnode = varpool_next_variable (vnode))
776 tree decl = vnode->decl;
777 if (DECL_EXTERNAL (decl)
778 && DECL_INITIAL (decl))
779 varpool_finalize_decl (decl);
780 if (DECL_PRESERVE_P (decl))
781 vnode->force_output = true;
782 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
784 if (! TREE_PUBLIC (vnode->decl))
785 warning_at (DECL_SOURCE_LOCATION (vnode->decl), OPT_Wattributes,
786 "%<externally_visible%>"
787 " attribute have effect only on public objects");
789 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
790 && vnode->definition
791 && DECL_INITIAL (decl))
793 warning_at (DECL_SOURCE_LOCATION (vnode->decl), OPT_Wattributes,
794 "%<weakref%> attribute ignored"
795 " because variable is initialized");
796 DECL_WEAK (decl) = 0;
797 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
798 DECL_ATTRIBUTES (decl));
800 process_common_attributes (decl);
804 /* Mark DECL as finalized. By finalizing the declaration, frontend instruct the
805 middle end to output the variable to asm file, if needed or externally
806 visible. */
808 void
809 varpool_finalize_decl (tree decl)
811 struct varpool_node *node = varpool_node_for_decl (decl);
813 gcc_assert (TREE_STATIC (decl) || DECL_EXTERNAL (decl));
815 if (node->definition)
816 return;
817 notice_global_symbol (decl);
818 node->definition = true;
819 if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
820 /* Traditionally we do not eliminate static variables when not
821 optimizing and when not doing toplevel reoder. */
822 || (!flag_toplevel_reorder && !DECL_COMDAT (node->decl)
823 && !DECL_ARTIFICIAL (node->decl)))
824 node->force_output = true;
826 if (cgraph_state == CGRAPH_STATE_CONSTRUCTION
827 && (decide_is_symbol_needed (node)
828 || referred_to_p (node)))
829 enqueue_node (node);
830 if (cgraph_state >= CGRAPH_STATE_IPA_SSA)
831 varpool_analyze_node (node);
832 /* Some frontends produce various interface variables after compilation
833 finished. */
834 if (cgraph_state == CGRAPH_STATE_FINISHED
835 || (!flag_toplevel_reorder && cgraph_state == CGRAPH_STATE_EXPANSION))
836 varpool_assemble_decl (node);
839 /* EDGE is an polymorphic call. Mark all possible targets as reachable
840 and if there is only one target, perform trivial devirtualization.
841 REACHABLE_CALL_TARGETS collects target lists we already walked to
842 avoid udplicate work. */
844 static void
845 walk_polymorphic_call_targets (pointer_set_t *reachable_call_targets,
846 struct cgraph_edge *edge)
848 unsigned int i;
849 void *cache_token;
850 bool final;
851 vec <cgraph_node *>targets
852 = possible_polymorphic_call_targets
853 (edge, &final, &cache_token);
855 if (!pointer_set_insert (reachable_call_targets,
856 cache_token))
858 if (cgraph_dump_file)
859 dump_possible_polymorphic_call_targets
860 (cgraph_dump_file, edge);
862 for (i = 0; i < targets.length (); i++)
864 /* Do not bother to mark virtual methods in anonymous namespace;
865 either we will find use of virtual table defining it, or it is
866 unused. */
867 if (targets[i]->definition
868 && TREE_CODE
869 (TREE_TYPE (targets[i]->decl))
870 == METHOD_TYPE
871 && !type_in_anonymous_namespace_p
872 (method_class_type
873 (TREE_TYPE (targets[i]->decl))))
874 enqueue_node (targets[i]);
878 /* Very trivial devirtualization; when the type is
879 final or anonymous (so we know all its derivation)
880 and there is only one possible virtual call target,
881 make the edge direct. */
882 if (final)
884 if (targets.length () <= 1)
886 cgraph_node *target;
887 if (targets.length () == 1)
888 target = targets[0];
889 else
890 target = cgraph_get_create_node
891 (builtin_decl_implicit (BUILT_IN_UNREACHABLE));
893 if (cgraph_dump_file)
895 fprintf (cgraph_dump_file,
896 "Devirtualizing call: ");
897 print_gimple_stmt (cgraph_dump_file,
898 edge->call_stmt, 0,
899 TDF_SLIM);
901 cgraph_make_edge_direct (edge, target);
902 cgraph_redirect_edge_call_stmt_to_callee (edge);
903 if (cgraph_dump_file)
905 fprintf (cgraph_dump_file,
906 "Devirtualized as: ");
907 print_gimple_stmt (cgraph_dump_file,
908 edge->call_stmt, 0,
909 TDF_SLIM);
916 /* Discover all functions and variables that are trivially needed, analyze
917 them as well as all functions and variables referred by them */
919 static void
920 analyze_functions (void)
922 /* Keep track of already processed nodes when called multiple times for
923 intermodule optimization. */
924 static struct cgraph_node *first_analyzed;
925 struct cgraph_node *first_handled = first_analyzed;
926 static struct varpool_node *first_analyzed_var;
927 struct varpool_node *first_handled_var = first_analyzed_var;
928 struct pointer_set_t *reachable_call_targets = pointer_set_create ();
930 symtab_node *node;
931 symtab_node *next;
932 int i;
933 struct ipa_ref *ref;
934 bool changed = true;
935 location_t saved_loc = input_location;
937 bitmap_obstack_initialize (NULL);
938 cgraph_state = CGRAPH_STATE_CONSTRUCTION;
939 input_location = UNKNOWN_LOCATION;
941 /* Ugly, but the fixup can not happen at a time same body alias is created;
942 C++ FE is confused about the COMDAT groups being right. */
943 if (cpp_implicit_aliases_done)
944 FOR_EACH_SYMBOL (node)
945 if (node->cpp_implicit_alias)
946 fixup_same_cpp_alias_visibility (node, symtab_alias_target (node));
947 if (optimize && flag_devirtualize)
948 build_type_inheritance_graph ();
950 /* Analysis adds static variables that in turn adds references to new functions.
951 So we need to iterate the process until it stabilize. */
952 while (changed)
954 changed = false;
955 process_function_and_variable_attributes (first_analyzed,
956 first_analyzed_var);
958 /* First identify the trivially needed symbols. */
959 for (node = symtab_nodes;
960 node != first_analyzed
961 && node != first_analyzed_var; node = node->next)
963 if (decide_is_symbol_needed (node))
965 enqueue_node (node);
966 if (!changed && cgraph_dump_file)
967 fprintf (cgraph_dump_file, "Trivially needed symbols:");
968 changed = true;
969 if (cgraph_dump_file)
970 fprintf (cgraph_dump_file, " %s", node->asm_name ());
971 if (!changed && cgraph_dump_file)
972 fprintf (cgraph_dump_file, "\n");
974 if (node == first_analyzed
975 || node == first_analyzed_var)
976 break;
978 cgraph_process_new_functions ();
979 first_analyzed_var = varpool_first_variable ();
980 first_analyzed = cgraph_first_function ();
982 if (changed && dump_file)
983 fprintf (cgraph_dump_file, "\n");
985 /* Lower representation, build callgraph edges and references for all trivially
986 needed symbols and all symbols referred by them. */
987 while (queued_nodes != &symtab_terminator)
989 changed = true;
990 node = queued_nodes;
991 queued_nodes = (symtab_node *)queued_nodes->aux;
992 cgraph_node *cnode = dyn_cast <cgraph_node> (node);
993 if (cnode && cnode->definition)
995 struct cgraph_edge *edge;
996 tree decl = cnode->decl;
998 /* ??? It is possible to create extern inline function
999 and later using weak alias attribute to kill its body.
1000 See gcc.c-torture/compile/20011119-1.c */
1001 if (!DECL_STRUCT_FUNCTION (decl)
1002 && !cnode->alias
1003 && !cnode->thunk.thunk_p
1004 && !cnode->dispatcher_function)
1006 cgraph_reset_node (cnode);
1007 cnode->local.redefined_extern_inline = true;
1008 continue;
1011 if (!cnode->analyzed)
1012 analyze_function (cnode);
1014 for (edge = cnode->callees; edge; edge = edge->next_callee)
1015 if (edge->callee->definition)
1016 enqueue_node (edge->callee);
1017 if (optimize && flag_devirtualize)
1019 struct cgraph_edge *next;
1021 for (edge = cnode->indirect_calls; edge; edge = next)
1023 next = edge->next_callee;
1024 if (edge->indirect_info->polymorphic)
1025 walk_polymorphic_call_targets (reachable_call_targets,
1026 edge);
1030 /* If decl is a clone of an abstract function,
1031 mark that abstract function so that we don't release its body.
1032 The DECL_INITIAL() of that abstract function declaration
1033 will be later needed to output debug info. */
1034 if (DECL_ABSTRACT_ORIGIN (decl))
1036 struct cgraph_node *origin_node
1037 = cgraph_get_node (DECL_ABSTRACT_ORIGIN (decl));
1038 origin_node->used_as_abstract_origin = true;
1041 else
1043 varpool_node *vnode = dyn_cast <varpool_node> (node);
1044 if (vnode && vnode->definition && !vnode->analyzed)
1045 varpool_analyze_node (vnode);
1048 if (node->same_comdat_group)
1050 symtab_node *next;
1051 for (next = node->same_comdat_group;
1052 next != node;
1053 next = next->same_comdat_group)
1054 enqueue_node (next);
1056 for (i = 0; ipa_ref_list_reference_iterate (&node->ref_list, i, ref); i++)
1057 if (ref->referred->definition)
1058 enqueue_node (ref->referred);
1059 cgraph_process_new_functions ();
1062 if (optimize && flag_devirtualize)
1063 update_type_inheritance_graph ();
1065 /* Collect entry points to the unit. */
1066 if (cgraph_dump_file)
1068 fprintf (cgraph_dump_file, "\n\nInitial ");
1069 dump_symtab (cgraph_dump_file);
1072 if (cgraph_dump_file)
1073 fprintf (cgraph_dump_file, "\nRemoving unused symbols:");
1075 for (node = symtab_nodes;
1076 node != first_handled
1077 && node != first_handled_var; node = next)
1079 next = node->next;
1080 if (!node->aux && !referred_to_p (node))
1082 if (cgraph_dump_file)
1083 fprintf (cgraph_dump_file, " %s", node->name ());
1084 symtab_remove_node (node);
1085 continue;
1087 if (cgraph_node *cnode = dyn_cast <cgraph_node> (node))
1089 tree decl = node->decl;
1091 if (cnode->definition && !gimple_has_body_p (decl)
1092 && !cnode->alias
1093 && !cnode->thunk.thunk_p)
1094 cgraph_reset_node (cnode);
1096 gcc_assert (!cnode->definition || cnode->thunk.thunk_p
1097 || cnode->alias
1098 || gimple_has_body_p (decl));
1099 gcc_assert (cnode->analyzed == cnode->definition);
1101 node->aux = NULL;
1103 for (;node; node = node->next)
1104 node->aux = NULL;
1105 first_analyzed = cgraph_first_function ();
1106 first_analyzed_var = varpool_first_variable ();
1107 if (cgraph_dump_file)
1109 fprintf (cgraph_dump_file, "\n\nReclaimed ");
1110 dump_symtab (cgraph_dump_file);
1112 bitmap_obstack_release (NULL);
1113 pointer_set_destroy (reachable_call_targets);
1114 ggc_collect ();
1115 /* Initialize assembler name hash, in particular we want to trigger C++
1116 mangling and same body alias creation before we free DECL_ARGUMENTS
1117 used by it. */
1118 if (!seen_error ())
1119 symtab_initialize_asm_name_hash ();
1121 input_location = saved_loc;
1124 /* Translate the ugly representation of aliases as alias pairs into nice
1125 representation in callgraph. We don't handle all cases yet,
1126 unfortunately. */
1128 static void
1129 handle_alias_pairs (void)
1131 alias_pair *p;
1132 unsigned i;
1134 for (i = 0; alias_pairs && alias_pairs->iterate (i, &p);)
1136 symtab_node *target_node = symtab_node_for_asm (p->target);
1138 /* Weakrefs with target not defined in current unit are easy to handle:
1139 they behave just as external variables except we need to note the
1140 alias flag to later output the weakref pseudo op into asm file. */
1141 if (!target_node
1142 && lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL)
1144 symtab_node *node = symtab_get_node (p->decl);
1145 if (node)
1147 node->alias_target = p->target;
1148 node->weakref = true;
1149 node->alias = true;
1151 alias_pairs->unordered_remove (i);
1152 continue;
1154 else if (!target_node)
1156 error ("%q+D aliased to undefined symbol %qE", p->decl, p->target);
1157 symtab_node *node = symtab_get_node (p->decl);
1158 if (node)
1159 node->alias = false;
1160 alias_pairs->unordered_remove (i);
1161 continue;
1164 if (DECL_EXTERNAL (target_node->decl)
1165 /* We use local aliases for C++ thunks to force the tailcall
1166 to bind locally. This is a hack - to keep it working do
1167 the following (which is not strictly correct). */
1168 && (! TREE_CODE (target_node->decl) == FUNCTION_DECL
1169 || ! DECL_VIRTUAL_P (target_node->decl))
1170 && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)))
1172 error ("%q+D aliased to external symbol %qE",
1173 p->decl, p->target);
1176 if (TREE_CODE (p->decl) == FUNCTION_DECL
1177 && target_node && is_a <cgraph_node> (target_node))
1179 struct cgraph_node *src_node = cgraph_get_node (p->decl);
1180 if (src_node && src_node->definition)
1181 cgraph_reset_node (src_node);
1182 cgraph_create_function_alias (p->decl, target_node->decl);
1183 alias_pairs->unordered_remove (i);
1185 else if (TREE_CODE (p->decl) == VAR_DECL
1186 && target_node && is_a <varpool_node> (target_node))
1188 varpool_create_variable_alias (p->decl, target_node->decl);
1189 alias_pairs->unordered_remove (i);
1191 else
1193 error ("%q+D alias in between function and variable is not supported",
1194 p->decl);
1195 warning (0, "%q+D aliased declaration",
1196 target_node->decl);
1197 alias_pairs->unordered_remove (i);
1200 vec_free (alias_pairs);
1204 /* Figure out what functions we want to assemble. */
1206 static void
1207 mark_functions_to_output (void)
1209 struct cgraph_node *node;
1210 #ifdef ENABLE_CHECKING
1211 bool check_same_comdat_groups = false;
1213 FOR_EACH_FUNCTION (node)
1214 gcc_assert (!node->process);
1215 #endif
1217 FOR_EACH_FUNCTION (node)
1219 tree decl = node->decl;
1221 gcc_assert (!node->process || node->same_comdat_group);
1222 if (node->process)
1223 continue;
1225 /* We need to output all local functions that are used and not
1226 always inlined, as well as those that are reachable from
1227 outside the current compilation unit. */
1228 if (node->analyzed
1229 && !node->thunk.thunk_p
1230 && !node->alias
1231 && !node->global.inlined_to
1232 && !TREE_ASM_WRITTEN (decl)
1233 && !DECL_EXTERNAL (decl))
1235 node->process = 1;
1236 if (node->same_comdat_group)
1238 struct cgraph_node *next;
1239 for (next = cgraph (node->same_comdat_group);
1240 next != node;
1241 next = cgraph (next->same_comdat_group))
1242 if (!next->thunk.thunk_p && !next->alias)
1243 next->process = 1;
1246 else if (node->same_comdat_group)
1248 #ifdef ENABLE_CHECKING
1249 check_same_comdat_groups = true;
1250 #endif
1252 else
1254 /* We should've reclaimed all functions that are not needed. */
1255 #ifdef ENABLE_CHECKING
1256 if (!node->global.inlined_to
1257 && gimple_has_body_p (decl)
1258 /* FIXME: in ltrans unit when offline copy is outside partition but inline copies
1259 are inside partition, we can end up not removing the body since we no longer
1260 have analyzed node pointing to it. */
1261 && !node->in_other_partition
1262 && !node->alias
1263 && !node->clones
1264 && !DECL_EXTERNAL (decl))
1266 dump_cgraph_node (stderr, node);
1267 internal_error ("failed to reclaim unneeded function");
1269 #endif
1270 gcc_assert (node->global.inlined_to
1271 || !gimple_has_body_p (decl)
1272 || node->in_other_partition
1273 || node->clones
1274 || DECL_ARTIFICIAL (decl)
1275 || DECL_EXTERNAL (decl));
1280 #ifdef ENABLE_CHECKING
1281 if (check_same_comdat_groups)
1282 FOR_EACH_FUNCTION (node)
1283 if (node->same_comdat_group && !node->process)
1285 tree decl = node->decl;
1286 if (!node->global.inlined_to
1287 && gimple_has_body_p (decl)
1288 /* FIXME: in an ltrans unit when the offline copy is outside a
1289 partition but inline copies are inside a partition, we can
1290 end up not removing the body since we no longer have an
1291 analyzed node pointing to it. */
1292 && !node->in_other_partition
1293 && !node->clones
1294 && !DECL_EXTERNAL (decl))
1296 dump_cgraph_node (stderr, node);
1297 internal_error ("failed to reclaim unneeded function in same "
1298 "comdat group");
1301 #endif
1304 /* DECL is FUNCTION_DECL. Initialize datastructures so DECL is a function
1305 in lowered gimple form. IN_SSA is true if the gimple is in SSA.
1307 Set current_function_decl and cfun to newly constructed empty function body.
1308 return basic block in the function body. */
1310 basic_block
1311 init_lowered_empty_function (tree decl, bool in_ssa)
1313 basic_block bb;
1315 current_function_decl = decl;
1316 allocate_struct_function (decl, false);
1317 gimple_register_cfg_hooks ();
1318 init_empty_tree_cfg ();
1320 if (in_ssa)
1322 init_tree_ssa (cfun);
1323 init_ssa_operands (cfun);
1324 cfun->gimple_df->in_ssa_p = true;
1325 cfun->curr_properties |= PROP_ssa;
1328 DECL_INITIAL (decl) = make_node (BLOCK);
1330 DECL_SAVED_TREE (decl) = error_mark_node;
1331 cfun->curr_properties |= (PROP_gimple_lcf | PROP_gimple_leh | PROP_gimple_any
1332 | PROP_cfg | PROP_loops);
1334 set_loops_for_fn (cfun, ggc_alloc_cleared_loops ());
1335 init_loops_structure (cfun, loops_for_fn (cfun), 1);
1336 loops_for_fn (cfun)->state |= LOOPS_MAY_HAVE_MULTIPLE_LATCHES;
1338 /* Create BB for body of the function and connect it properly. */
1339 bb = create_basic_block (NULL, (void *) 0, ENTRY_BLOCK_PTR_FOR_FN (cfun));
1340 make_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun), bb, EDGE_FALLTHRU);
1341 make_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
1342 add_bb_to_loop (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun)->loop_father);
1344 return bb;
1347 /* Adjust PTR by the constant FIXED_OFFSET, and by the vtable
1348 offset indicated by VIRTUAL_OFFSET, if that is
1349 non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and
1350 zero for a result adjusting thunk. */
1352 static tree
1353 thunk_adjust (gimple_stmt_iterator * bsi,
1354 tree ptr, bool this_adjusting,
1355 HOST_WIDE_INT fixed_offset, tree virtual_offset)
1357 gimple stmt;
1358 tree ret;
1360 if (this_adjusting
1361 && fixed_offset != 0)
1363 stmt = gimple_build_assign
1364 (ptr, fold_build_pointer_plus_hwi_loc (input_location,
1365 ptr,
1366 fixed_offset));
1367 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1370 /* If there's a virtual offset, look up that value in the vtable and
1371 adjust the pointer again. */
1372 if (virtual_offset)
1374 tree vtabletmp;
1375 tree vtabletmp2;
1376 tree vtabletmp3;
1378 if (!vtable_entry_type)
1380 tree vfunc_type = make_node (FUNCTION_TYPE);
1381 TREE_TYPE (vfunc_type) = integer_type_node;
1382 TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
1383 layout_type (vfunc_type);
1385 vtable_entry_type = build_pointer_type (vfunc_type);
1388 vtabletmp =
1389 create_tmp_reg (build_pointer_type
1390 (build_pointer_type (vtable_entry_type)), "vptr");
1392 /* The vptr is always at offset zero in the object. */
1393 stmt = gimple_build_assign (vtabletmp,
1394 build1 (NOP_EXPR, TREE_TYPE (vtabletmp),
1395 ptr));
1396 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1398 /* Form the vtable address. */
1399 vtabletmp2 = create_tmp_reg (TREE_TYPE (TREE_TYPE (vtabletmp)),
1400 "vtableaddr");
1401 stmt = gimple_build_assign (vtabletmp2,
1402 build_simple_mem_ref (vtabletmp));
1403 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1405 /* Find the entry with the vcall offset. */
1406 stmt = gimple_build_assign (vtabletmp2,
1407 fold_build_pointer_plus_loc (input_location,
1408 vtabletmp2,
1409 virtual_offset));
1410 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1412 /* Get the offset itself. */
1413 vtabletmp3 = create_tmp_reg (TREE_TYPE (TREE_TYPE (vtabletmp2)),
1414 "vcalloffset");
1415 stmt = gimple_build_assign (vtabletmp3,
1416 build_simple_mem_ref (vtabletmp2));
1417 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1419 /* Adjust the `this' pointer. */
1420 ptr = fold_build_pointer_plus_loc (input_location, ptr, vtabletmp3);
1421 ptr = force_gimple_operand_gsi (bsi, ptr, true, NULL_TREE, false,
1422 GSI_CONTINUE_LINKING);
1425 if (!this_adjusting
1426 && fixed_offset != 0)
1427 /* Adjust the pointer by the constant. */
1429 tree ptrtmp;
1431 if (TREE_CODE (ptr) == VAR_DECL)
1432 ptrtmp = ptr;
1433 else
1435 ptrtmp = create_tmp_reg (TREE_TYPE (ptr), "ptr");
1436 stmt = gimple_build_assign (ptrtmp, ptr);
1437 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1439 ptr = fold_build_pointer_plus_hwi_loc (input_location,
1440 ptrtmp, fixed_offset);
1443 /* Emit the statement and gimplify the adjustment expression. */
1444 ret = create_tmp_reg (TREE_TYPE (ptr), "adjusted_this");
1445 stmt = gimple_build_assign (ret, ptr);
1446 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1448 return ret;
1451 /* Expand thunk NODE to gimple if possible.
1452 When OUTPUT_ASM_THUNK is true, also produce assembler for
1453 thunks that are not lowered. */
1455 bool
1456 expand_thunk (struct cgraph_node *node, bool output_asm_thunks)
1458 bool this_adjusting = node->thunk.this_adjusting;
1459 HOST_WIDE_INT fixed_offset = node->thunk.fixed_offset;
1460 HOST_WIDE_INT virtual_value = node->thunk.virtual_value;
1461 tree virtual_offset = NULL;
1462 tree alias = node->callees->callee->decl;
1463 tree thunk_fndecl = node->decl;
1464 tree a;
1467 if (this_adjusting
1468 && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
1469 virtual_value, alias))
1471 const char *fnname;
1472 tree fn_block;
1473 tree restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1475 if (!output_asm_thunks)
1476 return false;
1478 if (in_lto_p)
1479 cgraph_get_body (node);
1480 a = DECL_ARGUMENTS (thunk_fndecl);
1482 current_function_decl = thunk_fndecl;
1484 /* Ensure thunks are emitted in their correct sections. */
1485 resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
1487 DECL_RESULT (thunk_fndecl)
1488 = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl),
1489 RESULT_DECL, 0, restype);
1490 DECL_CONTEXT (DECL_RESULT (thunk_fndecl)) = thunk_fndecl;
1491 fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
1493 /* The back end expects DECL_INITIAL to contain a BLOCK, so we
1494 create one. */
1495 fn_block = make_node (BLOCK);
1496 BLOCK_VARS (fn_block) = a;
1497 DECL_INITIAL (thunk_fndecl) = fn_block;
1498 init_function_start (thunk_fndecl);
1499 cfun->is_thunk = 1;
1500 insn_locations_init ();
1501 set_curr_insn_location (DECL_SOURCE_LOCATION (thunk_fndecl));
1502 prologue_location = curr_insn_location ();
1503 assemble_start_function (thunk_fndecl, fnname);
1505 targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl,
1506 fixed_offset, virtual_value, alias);
1508 assemble_end_function (thunk_fndecl, fnname);
1509 insn_locations_finalize ();
1510 init_insn_lengths ();
1511 free_after_compilation (cfun);
1512 set_cfun (NULL);
1513 TREE_ASM_WRITTEN (thunk_fndecl) = 1;
1514 node->thunk.thunk_p = false;
1515 node->analyzed = false;
1517 else
1519 tree restype;
1520 basic_block bb, then_bb, else_bb, return_bb;
1521 gimple_stmt_iterator bsi;
1522 int nargs = 0;
1523 tree arg;
1524 int i;
1525 tree resdecl;
1526 tree restmp = NULL;
1527 vec<tree> vargs;
1529 gimple call;
1530 gimple ret;
1532 if (in_lto_p)
1533 cgraph_get_body (node);
1534 a = DECL_ARGUMENTS (thunk_fndecl);
1536 current_function_decl = thunk_fndecl;
1538 /* Ensure thunks are emitted in their correct sections. */
1539 resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
1541 DECL_IGNORED_P (thunk_fndecl) = 1;
1542 bitmap_obstack_initialize (NULL);
1544 if (node->thunk.virtual_offset_p)
1545 virtual_offset = size_int (virtual_value);
1547 /* Build the return declaration for the function. */
1548 restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1549 if (DECL_RESULT (thunk_fndecl) == NULL_TREE)
1551 resdecl = build_decl (input_location, RESULT_DECL, 0, restype);
1552 DECL_ARTIFICIAL (resdecl) = 1;
1553 DECL_IGNORED_P (resdecl) = 1;
1554 DECL_RESULT (thunk_fndecl) = resdecl;
1555 DECL_CONTEXT (DECL_RESULT (thunk_fndecl)) = thunk_fndecl;
1557 else
1558 resdecl = DECL_RESULT (thunk_fndecl);
1560 bb = then_bb = else_bb = return_bb = init_lowered_empty_function (thunk_fndecl, true);
1562 bsi = gsi_start_bb (bb);
1564 /* Build call to the function being thunked. */
1565 if (!VOID_TYPE_P (restype))
1567 if (DECL_BY_REFERENCE (resdecl))
1568 restmp = gimple_fold_indirect_ref (resdecl);
1569 else if (!is_gimple_reg_type (restype))
1571 restmp = resdecl;
1572 add_local_decl (cfun, restmp);
1573 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp;
1575 else
1576 restmp = create_tmp_reg (restype, "retval");
1579 for (arg = a; arg; arg = DECL_CHAIN (arg))
1580 nargs++;
1581 vargs.create (nargs);
1582 if (this_adjusting)
1583 vargs.quick_push (thunk_adjust (&bsi, a, 1, fixed_offset,
1584 virtual_offset));
1585 else if (nargs)
1586 vargs.quick_push (a);
1588 if (nargs)
1589 for (i = 1, arg = DECL_CHAIN (a); i < nargs; i++, arg = DECL_CHAIN (arg))
1590 vargs.quick_push (arg);
1591 call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs);
1592 node->callees->call_stmt = call;
1593 vargs.release ();
1594 gimple_call_set_from_thunk (call, true);
1595 if (restmp)
1597 gimple_call_set_lhs (call, restmp);
1598 gcc_assert (useless_type_conversion_p (TREE_TYPE (restmp),
1599 TREE_TYPE (TREE_TYPE (alias))));
1601 gsi_insert_after (&bsi, call, GSI_NEW_STMT);
1602 if (!(gimple_call_flags (call) & ECF_NORETURN))
1604 if (restmp && !this_adjusting
1605 && (fixed_offset || virtual_offset))
1607 tree true_label = NULL_TREE;
1609 if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE)
1611 gimple stmt;
1612 /* If the return type is a pointer, we need to
1613 protect against NULL. We know there will be an
1614 adjustment, because that's why we're emitting a
1615 thunk. */
1616 then_bb = create_basic_block (NULL, (void *) 0, bb);
1617 return_bb = create_basic_block (NULL, (void *) 0, then_bb);
1618 else_bb = create_basic_block (NULL, (void *) 0, else_bb);
1619 add_bb_to_loop (then_bb, bb->loop_father);
1620 add_bb_to_loop (return_bb, bb->loop_father);
1621 add_bb_to_loop (else_bb, bb->loop_father);
1622 remove_edge (single_succ_edge (bb));
1623 true_label = gimple_block_label (then_bb);
1624 stmt = gimple_build_cond (NE_EXPR, restmp,
1625 build_zero_cst (TREE_TYPE (restmp)),
1626 NULL_TREE, NULL_TREE);
1627 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1628 make_edge (bb, then_bb, EDGE_TRUE_VALUE);
1629 make_edge (bb, else_bb, EDGE_FALSE_VALUE);
1630 make_edge (return_bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
1631 make_edge (then_bb, return_bb, EDGE_FALLTHRU);
1632 make_edge (else_bb, return_bb, EDGE_FALLTHRU);
1633 bsi = gsi_last_bb (then_bb);
1636 restmp = thunk_adjust (&bsi, restmp, /*this_adjusting=*/0,
1637 fixed_offset, virtual_offset);
1638 if (true_label)
1640 gimple stmt;
1641 bsi = gsi_last_bb (else_bb);
1642 stmt = gimple_build_assign (restmp,
1643 build_zero_cst (TREE_TYPE (restmp)));
1644 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1645 bsi = gsi_last_bb (return_bb);
1648 else
1649 gimple_call_set_tail (call, true);
1651 /* Build return value. */
1652 ret = gimple_build_return (restmp);
1653 gsi_insert_after (&bsi, ret, GSI_NEW_STMT);
1655 else
1657 gimple_call_set_tail (call, true);
1658 remove_edge (single_succ_edge (bb));
1661 cfun->gimple_df->in_ssa_p = true;
1662 /* FIXME: C++ FE should stop setting TREE_ASM_WRITTEN on thunks. */
1663 TREE_ASM_WRITTEN (thunk_fndecl) = false;
1664 delete_unreachable_blocks ();
1665 update_ssa (TODO_update_ssa);
1666 #ifdef ENABLE_CHECKING
1667 verify_flow_info ();
1668 #endif
1670 /* Since we want to emit the thunk, we explicitly mark its name as
1671 referenced. */
1672 node->thunk.thunk_p = false;
1673 node->lowered = true;
1674 bitmap_obstack_release (NULL);
1676 current_function_decl = NULL;
1677 set_cfun (NULL);
1678 return true;
1681 /* Assemble thunks and aliases associated to NODE. */
1683 static void
1684 assemble_thunks_and_aliases (struct cgraph_node *node)
1686 struct cgraph_edge *e;
1687 int i;
1688 struct ipa_ref *ref;
1690 for (e = node->callers; e;)
1691 if (e->caller->thunk.thunk_p)
1693 struct cgraph_node *thunk = e->caller;
1695 e = e->next_caller;
1696 assemble_thunks_and_aliases (thunk);
1697 expand_thunk (thunk, true);
1699 else
1700 e = e->next_caller;
1701 for (i = 0; ipa_ref_list_referring_iterate (&node->ref_list,
1702 i, ref); i++)
1703 if (ref->use == IPA_REF_ALIAS)
1705 struct cgraph_node *alias = ipa_ref_referring_node (ref);
1706 bool saved_written = TREE_ASM_WRITTEN (node->decl);
1708 /* Force assemble_alias to really output the alias this time instead
1709 of buffering it in same alias pairs. */
1710 TREE_ASM_WRITTEN (node->decl) = 1;
1711 do_assemble_alias (alias->decl,
1712 DECL_ASSEMBLER_NAME (node->decl));
1713 assemble_thunks_and_aliases (alias);
1714 TREE_ASM_WRITTEN (node->decl) = saved_written;
1718 /* Expand function specified by NODE. */
1720 static void
1721 expand_function (struct cgraph_node *node)
1723 tree decl = node->decl;
1724 location_t saved_loc;
1726 /* We ought to not compile any inline clones. */
1727 gcc_assert (!node->global.inlined_to);
1729 announce_function (decl);
1730 node->process = 0;
1731 gcc_assert (node->lowered);
1732 cgraph_get_body (node);
1734 /* Generate RTL for the body of DECL. */
1736 timevar_push (TV_REST_OF_COMPILATION);
1738 gcc_assert (cgraph_global_info_ready);
1740 /* Initialize the default bitmap obstack. */
1741 bitmap_obstack_initialize (NULL);
1743 /* Initialize the RTL code for the function. */
1744 current_function_decl = decl;
1745 saved_loc = input_location;
1746 input_location = DECL_SOURCE_LOCATION (decl);
1747 init_function_start (decl);
1749 gimple_register_cfg_hooks ();
1751 bitmap_obstack_initialize (&reg_obstack); /* FIXME, only at RTL generation*/
1753 execute_all_ipa_transforms ();
1755 /* Perform all tree transforms and optimizations. */
1757 /* Signal the start of passes. */
1758 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START, NULL);
1760 execute_pass_list (g->get_passes ()->all_passes);
1762 /* Signal the end of passes. */
1763 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END, NULL);
1765 bitmap_obstack_release (&reg_obstack);
1767 /* Release the default bitmap obstack. */
1768 bitmap_obstack_release (NULL);
1770 /* If requested, warn about function definitions where the function will
1771 return a value (usually of some struct or union type) which itself will
1772 take up a lot of stack space. */
1773 if (warn_larger_than && !DECL_EXTERNAL (decl) && TREE_TYPE (decl))
1775 tree ret_type = TREE_TYPE (TREE_TYPE (decl));
1777 if (ret_type && TYPE_SIZE_UNIT (ret_type)
1778 && TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST
1779 && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type),
1780 larger_than_size))
1782 unsigned int size_as_int
1783 = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type));
1785 if (compare_tree_int (TYPE_SIZE_UNIT (ret_type), size_as_int) == 0)
1786 warning (OPT_Wlarger_than_, "size of return value of %q+D is %u bytes",
1787 decl, size_as_int);
1788 else
1789 warning (OPT_Wlarger_than_, "size of return value of %q+D is larger than %wd bytes",
1790 decl, larger_than_size);
1794 gimple_set_body (decl, NULL);
1795 if (DECL_STRUCT_FUNCTION (decl) == 0
1796 && !cgraph_get_node (decl)->origin)
1798 /* Stop pointing to the local nodes about to be freed.
1799 But DECL_INITIAL must remain nonzero so we know this
1800 was an actual function definition.
1801 For a nested function, this is done in c_pop_function_context.
1802 If rest_of_compilation set this to 0, leave it 0. */
1803 if (DECL_INITIAL (decl) != 0)
1804 DECL_INITIAL (decl) = error_mark_node;
1807 input_location = saved_loc;
1809 ggc_collect ();
1810 timevar_pop (TV_REST_OF_COMPILATION);
1812 /* Make sure that BE didn't give up on compiling. */
1813 gcc_assert (TREE_ASM_WRITTEN (decl));
1814 set_cfun (NULL);
1815 current_function_decl = NULL;
1817 /* It would make a lot more sense to output thunks before function body to get more
1818 forward and lest backwarding jumps. This however would need solving problem
1819 with comdats. See PR48668. Also aliases must come after function itself to
1820 make one pass assemblers, like one on AIX, happy. See PR 50689.
1821 FIXME: Perhaps thunks should be move before function IFF they are not in comdat
1822 groups. */
1823 assemble_thunks_and_aliases (node);
1824 cgraph_release_function_body (node);
1825 /* Eliminate all call edges. This is important so the GIMPLE_CALL no longer
1826 points to the dead function body. */
1827 cgraph_node_remove_callees (node);
1828 ipa_remove_all_references (&node->ref_list);
1832 /* Expand all functions that must be output.
1834 Attempt to topologically sort the nodes so function is output when
1835 all called functions are already assembled to allow data to be
1836 propagated across the callgraph. Use a stack to get smaller distance
1837 between a function and its callees (later we may choose to use a more
1838 sophisticated algorithm for function reordering; we will likely want
1839 to use subsections to make the output functions appear in top-down
1840 order). */
1842 static void
1843 expand_all_functions (void)
1845 struct cgraph_node *node;
1846 struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
1847 int order_pos, new_order_pos = 0;
1848 int i;
1850 order_pos = ipa_reverse_postorder (order);
1851 gcc_assert (order_pos == cgraph_n_nodes);
1853 /* Garbage collector may remove inline clones we eliminate during
1854 optimization. So we must be sure to not reference them. */
1855 for (i = 0; i < order_pos; i++)
1856 if (order[i]->process)
1857 order[new_order_pos++] = order[i];
1859 for (i = new_order_pos - 1; i >= 0; i--)
1861 node = order[i];
1862 if (node->process)
1864 node->process = 0;
1865 expand_function (node);
1868 cgraph_process_new_functions ();
1870 free (order);
1874 /* This is used to sort the node types by the cgraph order number. */
1876 enum cgraph_order_sort_kind
1878 ORDER_UNDEFINED = 0,
1879 ORDER_FUNCTION,
1880 ORDER_VAR,
1881 ORDER_ASM
1884 struct cgraph_order_sort
1886 enum cgraph_order_sort_kind kind;
1887 union
1889 struct cgraph_node *f;
1890 struct varpool_node *v;
1891 struct asm_node *a;
1892 } u;
1895 /* Output all functions, variables, and asm statements in the order
1896 according to their order fields, which is the order in which they
1897 appeared in the file. This implements -fno-toplevel-reorder. In
1898 this mode we may output functions and variables which don't really
1899 need to be output. */
1901 static void
1902 output_in_order (void)
1904 int max;
1905 struct cgraph_order_sort *nodes;
1906 int i;
1907 struct cgraph_node *pf;
1908 struct varpool_node *pv;
1909 struct asm_node *pa;
1911 max = symtab_order;
1912 nodes = XCNEWVEC (struct cgraph_order_sort, max);
1914 FOR_EACH_DEFINED_FUNCTION (pf)
1916 if (pf->process && !pf->thunk.thunk_p && !pf->alias)
1918 i = pf->order;
1919 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1920 nodes[i].kind = ORDER_FUNCTION;
1921 nodes[i].u.f = pf;
1925 FOR_EACH_DEFINED_VARIABLE (pv)
1926 if (!DECL_EXTERNAL (pv->decl))
1928 i = pv->order;
1929 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1930 nodes[i].kind = ORDER_VAR;
1931 nodes[i].u.v = pv;
1934 for (pa = asm_nodes; pa; pa = pa->next)
1936 i = pa->order;
1937 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1938 nodes[i].kind = ORDER_ASM;
1939 nodes[i].u.a = pa;
1942 /* In toplevel reorder mode we output all statics; mark them as needed. */
1944 for (i = 0; i < max; ++i)
1945 if (nodes[i].kind == ORDER_VAR)
1946 varpool_finalize_named_section_flags (nodes[i].u.v);
1948 for (i = 0; i < max; ++i)
1950 switch (nodes[i].kind)
1952 case ORDER_FUNCTION:
1953 nodes[i].u.f->process = 0;
1954 expand_function (nodes[i].u.f);
1955 break;
1957 case ORDER_VAR:
1958 varpool_assemble_decl (nodes[i].u.v);
1959 break;
1961 case ORDER_ASM:
1962 assemble_asm (nodes[i].u.a->asm_str);
1963 break;
1965 case ORDER_UNDEFINED:
1966 break;
1968 default:
1969 gcc_unreachable ();
1973 asm_nodes = NULL;
1974 free (nodes);
1977 static void
1978 ipa_passes (void)
1980 gcc::pass_manager *passes = g->get_passes ();
1982 set_cfun (NULL);
1983 current_function_decl = NULL;
1984 gimple_register_cfg_hooks ();
1985 bitmap_obstack_initialize (NULL);
1987 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START, NULL);
1989 if (!in_lto_p)
1991 execute_ipa_pass_list (passes->all_small_ipa_passes);
1992 if (seen_error ())
1993 return;
1996 /* We never run removal of unreachable nodes after early passes. This is
1997 because TODO is run before the subpasses. It is important to remove
1998 the unreachable functions to save works at IPA level and to get LTO
1999 symbol tables right. */
2000 symtab_remove_unreachable_nodes (true, cgraph_dump_file);
2002 /* If pass_all_early_optimizations was not scheduled, the state of
2003 the cgraph will not be properly updated. Update it now. */
2004 if (cgraph_state < CGRAPH_STATE_IPA_SSA)
2005 cgraph_state = CGRAPH_STATE_IPA_SSA;
2007 if (!in_lto_p)
2009 /* Generate coverage variables and constructors. */
2010 coverage_finish ();
2012 /* Process new functions added. */
2013 set_cfun (NULL);
2014 current_function_decl = NULL;
2015 cgraph_process_new_functions ();
2017 execute_ipa_summary_passes
2018 ((struct ipa_opt_pass_d *) passes->all_regular_ipa_passes);
2021 /* Some targets need to handle LTO assembler output specially. */
2022 if (flag_generate_lto)
2023 targetm.asm_out.lto_start ();
2025 if (!in_lto_p)
2026 ipa_write_summaries ();
2028 if (flag_generate_lto)
2029 targetm.asm_out.lto_end ();
2031 if (!flag_ltrans && (in_lto_p || !flag_lto || flag_fat_lto_objects))
2032 execute_ipa_pass_list (passes->all_regular_ipa_passes);
2033 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END, NULL);
2035 bitmap_obstack_release (NULL);
2039 /* Return string alias is alias of. */
2041 static tree
2042 get_alias_symbol (tree decl)
2044 tree alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
2045 return get_identifier (TREE_STRING_POINTER
2046 (TREE_VALUE (TREE_VALUE (alias))));
2050 /* Weakrefs may be associated to external decls and thus not output
2051 at expansion time. Emit all necessary aliases. */
2053 static void
2054 output_weakrefs (void)
2056 symtab_node *node;
2057 FOR_EACH_SYMBOL (node)
2058 if (node->alias
2059 && !TREE_ASM_WRITTEN (node->decl)
2060 && node->weakref)
2062 tree target;
2064 /* Weakrefs are special by not requiring target definition in current
2065 compilation unit. It is thus bit hard to work out what we want to
2066 alias.
2067 When alias target is defined, we need to fetch it from symtab reference,
2068 otherwise it is pointed to by alias_target. */
2069 if (node->alias_target)
2070 target = (DECL_P (node->alias_target)
2071 ? DECL_ASSEMBLER_NAME (node->alias_target)
2072 : node->alias_target);
2073 else if (node->analyzed)
2074 target = DECL_ASSEMBLER_NAME (symtab_alias_target (node)->decl);
2075 else
2077 gcc_unreachable ();
2078 target = get_alias_symbol (node->decl);
2080 do_assemble_alias (node->decl, target);
2084 /* Initialize callgraph dump file. */
2086 void
2087 init_cgraph (void)
2089 if (!cgraph_dump_file)
2090 cgraph_dump_file = dump_begin (TDI_cgraph, NULL);
2094 /* Perform simple optimizations based on callgraph. */
2096 void
2097 compile (void)
2099 if (seen_error ())
2100 return;
2102 #ifdef ENABLE_CHECKING
2103 verify_symtab ();
2104 #endif
2106 timevar_push (TV_CGRAPHOPT);
2107 if (pre_ipa_mem_report)
2109 fprintf (stderr, "Memory consumption before IPA\n");
2110 dump_memory_report (false);
2112 if (!quiet_flag)
2113 fprintf (stderr, "Performing interprocedural optimizations\n");
2114 cgraph_state = CGRAPH_STATE_IPA;
2116 /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE. */
2117 if (flag_lto)
2118 lto_streamer_hooks_init ();
2120 /* Don't run the IPA passes if there was any error or sorry messages. */
2121 if (!seen_error ())
2122 ipa_passes ();
2124 /* Do nothing else if any IPA pass found errors or if we are just streaming LTO. */
2125 if (seen_error ()
2126 || (!in_lto_p && flag_lto && !flag_fat_lto_objects))
2128 timevar_pop (TV_CGRAPHOPT);
2129 return;
2132 /* This pass remove bodies of extern inline functions we never inlined.
2133 Do this later so other IPA passes see what is really going on. */
2134 symtab_remove_unreachable_nodes (false, dump_file);
2135 cgraph_global_info_ready = true;
2136 if (cgraph_dump_file)
2138 fprintf (cgraph_dump_file, "Optimized ");
2139 dump_symtab (cgraph_dump_file);
2141 if (post_ipa_mem_report)
2143 fprintf (stderr, "Memory consumption after IPA\n");
2144 dump_memory_report (false);
2146 timevar_pop (TV_CGRAPHOPT);
2148 /* Output everything. */
2149 (*debug_hooks->assembly_start) ();
2150 if (!quiet_flag)
2151 fprintf (stderr, "Assembling functions:\n");
2152 #ifdef ENABLE_CHECKING
2153 verify_symtab ();
2154 #endif
2156 cgraph_materialize_all_clones ();
2157 bitmap_obstack_initialize (NULL);
2158 execute_ipa_pass_list (g->get_passes ()->all_late_ipa_passes);
2159 symtab_remove_unreachable_nodes (true, dump_file);
2160 #ifdef ENABLE_CHECKING
2161 verify_symtab ();
2162 #endif
2163 bitmap_obstack_release (NULL);
2164 mark_functions_to_output ();
2166 /* When weakref support is missing, we autmatically translate all
2167 references to NODE to references to its ultimate alias target.
2168 The renaming mechanizm uses flag IDENTIFIER_TRANSPARENT_ALIAS and
2169 TREE_CHAIN.
2171 Set up this mapping before we output any assembler but once we are sure
2172 that all symbol renaming is done.
2174 FIXME: All this uglyness can go away if we just do renaming at gimple
2175 level by physically rewritting the IL. At the moment we can only redirect
2176 calls, so we need infrastructure for renaming references as well. */
2177 #ifndef ASM_OUTPUT_WEAKREF
2178 symtab_node *node;
2180 FOR_EACH_SYMBOL (node)
2181 if (node->alias
2182 && lookup_attribute ("weakref", DECL_ATTRIBUTES (node->decl)))
2184 IDENTIFIER_TRANSPARENT_ALIAS
2185 (DECL_ASSEMBLER_NAME (node->decl)) = 1;
2186 TREE_CHAIN (DECL_ASSEMBLER_NAME (node->decl))
2187 = (node->alias_target ? node->alias_target
2188 : DECL_ASSEMBLER_NAME (symtab_alias_target (node)->decl));
2190 #endif
2192 cgraph_state = CGRAPH_STATE_EXPANSION;
2193 if (!flag_toplevel_reorder)
2194 output_in_order ();
2195 else
2197 output_asm_statements ();
2199 expand_all_functions ();
2200 varpool_output_variables ();
2203 cgraph_process_new_functions ();
2204 cgraph_state = CGRAPH_STATE_FINISHED;
2205 output_weakrefs ();
2207 if (cgraph_dump_file)
2209 fprintf (cgraph_dump_file, "\nFinal ");
2210 dump_symtab (cgraph_dump_file);
2212 #ifdef ENABLE_CHECKING
2213 verify_symtab ();
2214 /* Double check that all inline clones are gone and that all
2215 function bodies have been released from memory. */
2216 if (!seen_error ())
2218 struct cgraph_node *node;
2219 bool error_found = false;
2221 FOR_EACH_DEFINED_FUNCTION (node)
2222 if (node->global.inlined_to
2223 || gimple_has_body_p (node->decl))
2225 error_found = true;
2226 dump_cgraph_node (stderr, node);
2228 if (error_found)
2229 internal_error ("nodes with unreleased memory found");
2231 #endif
2235 /* Analyze the whole compilation unit once it is parsed completely. */
2237 void
2238 finalize_compilation_unit (void)
2240 timevar_push (TV_CGRAPH);
2242 /* If we're here there's no current function anymore. Some frontends
2243 are lazy in clearing these. */
2244 current_function_decl = NULL;
2245 set_cfun (NULL);
2247 /* Do not skip analyzing the functions if there were errors, we
2248 miss diagnostics for following functions otherwise. */
2250 /* Emit size functions we didn't inline. */
2251 finalize_size_functions ();
2253 /* Mark alias targets necessary and emit diagnostics. */
2254 handle_alias_pairs ();
2256 if (!quiet_flag)
2258 fprintf (stderr, "\nAnalyzing compilation unit\n");
2259 fflush (stderr);
2262 if (flag_dump_passes)
2263 dump_passes ();
2265 /* Gimplify and lower all functions, compute reachability and
2266 remove unreachable nodes. */
2267 analyze_functions ();
2269 /* Mark alias targets necessary and emit diagnostics. */
2270 handle_alias_pairs ();
2272 /* Gimplify and lower thunks. */
2273 analyze_functions ();
2275 /* Finally drive the pass manager. */
2276 compile ();
2278 timevar_pop (TV_CGRAPH);
2282 #include "gt-cgraphunit.h"