tree-ssa-threadupdate.c: Include tree-cfg.h and tree-pass.h
[official-gcc.git] / gcc / cgraphunit.c
blobb10d75531b034288b6a99609006659419ec5fd54
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"
208 #include "gimplify.h"
210 /* Queue of cgraph nodes scheduled to be added into cgraph. This is a
211 secondary queue used during optimization to accommodate passes that
212 may generate new functions that need to be optimized and expanded. */
213 cgraph_node_set cgraph_new_nodes;
215 static void expand_all_functions (void);
216 static void mark_functions_to_output (void);
217 static void expand_function (struct cgraph_node *);
218 static void analyze_function (struct cgraph_node *);
219 static void handle_alias_pairs (void);
221 FILE *cgraph_dump_file;
223 /* Linked list of cgraph asm nodes. */
224 struct asm_node *asm_nodes;
226 /* Last node in cgraph_asm_nodes. */
227 static GTY(()) struct asm_node *asm_last_node;
229 /* Used for vtable lookup in thunk adjusting. */
230 static GTY (()) tree vtable_entry_type;
232 /* Determine if symbol DECL is needed. That is, visible to something
233 either outside this translation unit, something magic in the system
234 configury */
235 bool
236 decide_is_symbol_needed (symtab_node *node)
238 tree decl = node->decl;
240 /* Double check that no one output the function into assembly file
241 early. */
242 gcc_checking_assert (!DECL_ASSEMBLER_NAME_SET_P (decl)
243 || !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)));
245 if (!node->definition)
246 return false;
248 if (DECL_EXTERNAL (decl))
249 return false;
251 /* If the user told us it is used, then it must be so. */
252 if (node->force_output)
253 return true;
255 /* ABI forced symbols are needed when they are external. */
256 if (node->forced_by_abi && TREE_PUBLIC (decl))
257 return true;
259 /* Keep constructors, destructors and virtual functions. */
260 if (TREE_CODE (decl) == FUNCTION_DECL
261 && (DECL_STATIC_CONSTRUCTOR (decl) || DECL_STATIC_DESTRUCTOR (decl)))
262 return true;
264 /* Externally visible variables must be output. The exception is
265 COMDAT variables that must be output only when they are needed. */
266 if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
267 return true;
269 return false;
272 /* Head and terminator of the queue of nodes to be processed while building
273 callgraph. */
275 static symtab_node symtab_terminator;
276 static symtab_node *queued_nodes = &symtab_terminator;
278 /* Add NODE to queue starting at QUEUED_NODES.
279 The queue is linked via AUX pointers and terminated by pointer to 1. */
281 static void
282 enqueue_node (symtab_node *node)
284 if (node->aux)
285 return;
286 gcc_checking_assert (queued_nodes);
287 node->aux = queued_nodes;
288 queued_nodes = node;
291 /* Process CGRAPH_NEW_FUNCTIONS and perform actions necessary to add these
292 functions into callgraph in a way so they look like ordinary reachable
293 functions inserted into callgraph already at construction time. */
295 void
296 cgraph_process_new_functions (void)
298 tree fndecl;
299 struct cgraph_node *node;
300 cgraph_node_set_iterator csi;
302 if (!cgraph_new_nodes)
303 return;
304 handle_alias_pairs ();
305 /* Note that this queue may grow as its being processed, as the new
306 functions may generate new ones. */
307 for (csi = csi_start (cgraph_new_nodes); !csi_end_p (csi); csi_next (&csi))
309 node = csi_node (csi);
310 fndecl = node->decl;
311 switch (cgraph_state)
313 case CGRAPH_STATE_CONSTRUCTION:
314 /* At construction time we just need to finalize function and move
315 it into reachable functions list. */
317 cgraph_finalize_function (fndecl, false);
318 cgraph_call_function_insertion_hooks (node);
319 enqueue_node (node);
320 break;
322 case CGRAPH_STATE_IPA:
323 case CGRAPH_STATE_IPA_SSA:
324 /* When IPA optimization already started, do all essential
325 transformations that has been already performed on the whole
326 cgraph but not on this function. */
328 gimple_register_cfg_hooks ();
329 if (!node->analyzed)
330 analyze_function (node);
331 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
332 if (cgraph_state == CGRAPH_STATE_IPA_SSA
333 && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
334 g->get_passes ()->execute_early_local_passes ();
335 else if (inline_summary_vec != NULL)
336 compute_inline_parameters (node, true);
337 free_dominance_info (CDI_POST_DOMINATORS);
338 free_dominance_info (CDI_DOMINATORS);
339 pop_cfun ();
340 cgraph_call_function_insertion_hooks (node);
341 break;
343 case CGRAPH_STATE_EXPANSION:
344 /* Functions created during expansion shall be compiled
345 directly. */
346 node->process = 0;
347 cgraph_call_function_insertion_hooks (node);
348 expand_function (node);
349 break;
351 default:
352 gcc_unreachable ();
353 break;
356 free_cgraph_node_set (cgraph_new_nodes);
357 cgraph_new_nodes = NULL;
360 /* As an GCC extension we allow redefinition of the function. The
361 semantics when both copies of bodies differ is not well defined.
362 We replace the old body with new body so in unit at a time mode
363 we always use new body, while in normal mode we may end up with
364 old body inlined into some functions and new body expanded and
365 inlined in others.
367 ??? It may make more sense to use one body for inlining and other
368 body for expanding the function but this is difficult to do. */
370 void
371 cgraph_reset_node (struct cgraph_node *node)
373 /* If node->process is set, then we have already begun whole-unit analysis.
374 This is *not* testing for whether we've already emitted the function.
375 That case can be sort-of legitimately seen with real function redefinition
376 errors. I would argue that the front end should never present us with
377 such a case, but don't enforce that for now. */
378 gcc_assert (!node->process);
380 /* Reset our data structures so we can analyze the function again. */
381 memset (&node->local, 0, sizeof (node->local));
382 memset (&node->global, 0, sizeof (node->global));
383 memset (&node->rtl, 0, sizeof (node->rtl));
384 node->analyzed = false;
385 node->definition = false;
386 node->alias = false;
387 node->weakref = false;
388 node->cpp_implicit_alias = false;
390 cgraph_node_remove_callees (node);
391 ipa_remove_all_references (&node->ref_list);
394 /* Return true when there are references to NODE. */
396 static bool
397 referred_to_p (symtab_node *node)
399 struct ipa_ref *ref;
401 /* See if there are any references at all. */
402 if (ipa_ref_list_referring_iterate (&node->ref_list, 0, ref))
403 return true;
404 /* For functions check also calls. */
405 cgraph_node *cn = dyn_cast <cgraph_node> (node);
406 if (cn && cn->callers)
407 return true;
408 return false;
411 /* DECL has been parsed. Take it, queue it, compile it at the whim of the
412 logic in effect. If NO_COLLECT is true, then our caller cannot stand to have
413 the garbage collector run at the moment. We would need to either create
414 a new GC context, or just not compile right now. */
416 void
417 cgraph_finalize_function (tree decl, bool no_collect)
419 struct cgraph_node *node = cgraph_get_create_node (decl);
421 if (node->definition)
423 /* Nested functions should only be defined once. */
424 gcc_assert (!DECL_CONTEXT (decl)
425 || TREE_CODE (DECL_CONTEXT (decl)) != FUNCTION_DECL);
426 cgraph_reset_node (node);
427 node->local.redefined_extern_inline = true;
430 notice_global_symbol (decl);
431 node->definition = true;
432 node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL;
434 /* With -fkeep-inline-functions we are keeping all inline functions except
435 for extern inline ones. */
436 if (flag_keep_inline_functions
437 && DECL_DECLARED_INLINE_P (decl)
438 && !DECL_EXTERNAL (decl)
439 && !DECL_DISREGARD_INLINE_LIMITS (decl))
440 node->force_output = 1;
442 /* When not optimizing, also output the static functions. (see
443 PR24561), but don't do so for always_inline functions, functions
444 declared inline and nested functions. These were optimized out
445 in the original implementation and it is unclear whether we want
446 to change the behavior here. */
447 if ((!optimize
448 && !node->cpp_implicit_alias
449 && !DECL_DISREGARD_INLINE_LIMITS (decl)
450 && !DECL_DECLARED_INLINE_P (decl)
451 && !(DECL_CONTEXT (decl)
452 && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL))
453 && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
454 node->force_output = 1;
456 /* If we've not yet emitted decl, tell the debug info about it. */
457 if (!TREE_ASM_WRITTEN (decl))
458 (*debug_hooks->deferred_inline_function) (decl);
460 /* Possibly warn about unused parameters. */
461 if (warn_unused_parameter)
462 do_warn_unused_parameter (decl);
464 if (!no_collect)
465 ggc_collect ();
467 if (cgraph_state == CGRAPH_STATE_CONSTRUCTION
468 && (decide_is_symbol_needed (node)
469 || referred_to_p (node)))
470 enqueue_node (node);
473 /* Add the function FNDECL to the call graph.
474 Unlike cgraph_finalize_function, this function is intended to be used
475 by middle end and allows insertion of new function at arbitrary point
476 of compilation. The function can be either in high, low or SSA form
477 GIMPLE.
479 The function is assumed to be reachable and have address taken (so no
480 API breaking optimizations are performed on it).
482 Main work done by this function is to enqueue the function for later
483 processing to avoid need the passes to be re-entrant. */
485 void
486 cgraph_add_new_function (tree fndecl, bool lowered)
488 gcc::pass_manager *passes = g->get_passes ();
489 struct cgraph_node *node;
490 switch (cgraph_state)
492 case CGRAPH_STATE_PARSING:
493 cgraph_finalize_function (fndecl, false);
494 break;
495 case CGRAPH_STATE_CONSTRUCTION:
496 /* Just enqueue function to be processed at nearest occurrence. */
497 node = cgraph_create_node (fndecl);
498 if (lowered)
499 node->lowered = true;
500 if (!cgraph_new_nodes)
501 cgraph_new_nodes = cgraph_node_set_new ();
502 cgraph_node_set_add (cgraph_new_nodes, node);
503 break;
505 case CGRAPH_STATE_IPA:
506 case CGRAPH_STATE_IPA_SSA:
507 case CGRAPH_STATE_EXPANSION:
508 /* Bring the function into finalized state and enqueue for later
509 analyzing and compilation. */
510 node = cgraph_get_create_node (fndecl);
511 node->local.local = false;
512 node->definition = true;
513 node->force_output = true;
514 if (!lowered && cgraph_state == CGRAPH_STATE_EXPANSION)
516 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
517 gimple_register_cfg_hooks ();
518 bitmap_obstack_initialize (NULL);
519 execute_pass_list (passes->all_lowering_passes);
520 passes->execute_early_local_passes ();
521 bitmap_obstack_release (NULL);
522 pop_cfun ();
524 lowered = true;
526 if (lowered)
527 node->lowered = true;
528 if (!cgraph_new_nodes)
529 cgraph_new_nodes = cgraph_node_set_new ();
530 cgraph_node_set_add (cgraph_new_nodes, node);
531 break;
533 case CGRAPH_STATE_FINISHED:
534 /* At the very end of compilation we have to do all the work up
535 to expansion. */
536 node = cgraph_create_node (fndecl);
537 if (lowered)
538 node->lowered = true;
539 node->definition = true;
540 analyze_function (node);
541 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
542 gimple_register_cfg_hooks ();
543 bitmap_obstack_initialize (NULL);
544 if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
545 g->get_passes ()->execute_early_local_passes ();
546 bitmap_obstack_release (NULL);
547 pop_cfun ();
548 expand_function (node);
549 break;
551 default:
552 gcc_unreachable ();
555 /* Set a personality if required and we already passed EH lowering. */
556 if (lowered
557 && (function_needs_eh_personality (DECL_STRUCT_FUNCTION (fndecl))
558 == eh_personality_lang))
559 DECL_FUNCTION_PERSONALITY (fndecl) = lang_hooks.eh_personality ();
562 /* Add a top-level asm statement to the list. */
564 struct asm_node *
565 add_asm_node (tree asm_str)
567 struct asm_node *node;
569 node = ggc_alloc_cleared_asm_node ();
570 node->asm_str = asm_str;
571 node->order = symtab_order++;
572 node->next = NULL;
573 if (asm_nodes == NULL)
574 asm_nodes = node;
575 else
576 asm_last_node->next = node;
577 asm_last_node = node;
578 return node;
581 /* Output all asm statements we have stored up to be output. */
583 static void
584 output_asm_statements (void)
586 struct asm_node *can;
588 if (seen_error ())
589 return;
591 for (can = asm_nodes; can; can = can->next)
592 assemble_asm (can->asm_str);
593 asm_nodes = NULL;
596 /* Analyze the function scheduled to be output. */
597 static void
598 analyze_function (struct cgraph_node *node)
600 tree decl = node->decl;
601 location_t saved_loc = input_location;
602 input_location = DECL_SOURCE_LOCATION (decl);
604 if (node->thunk.thunk_p)
606 cgraph_create_edge (node, cgraph_get_node (node->thunk.alias),
607 NULL, 0, CGRAPH_FREQ_BASE);
608 if (!expand_thunk (node, false))
610 node->thunk.alias = NULL;
611 node->analyzed = true;
612 return;
614 node->thunk.alias = NULL;
616 if (node->alias)
617 symtab_resolve_alias
618 (node, cgraph_get_node (node->alias_target));
619 else if (node->dispatcher_function)
621 /* Generate the dispatcher body of multi-versioned functions. */
622 struct cgraph_function_version_info *dispatcher_version_info
623 = get_cgraph_node_version (node);
624 if (dispatcher_version_info != NULL
625 && (dispatcher_version_info->dispatcher_resolver
626 == NULL_TREE))
628 tree resolver = NULL_TREE;
629 gcc_assert (targetm.generate_version_dispatcher_body);
630 resolver = targetm.generate_version_dispatcher_body (node);
631 gcc_assert (resolver != NULL_TREE);
634 else
636 push_cfun (DECL_STRUCT_FUNCTION (decl));
638 assign_assembler_name_if_neeeded (node->decl);
640 /* Make sure to gimplify bodies only once. During analyzing a
641 function we lower it, which will require gimplified nested
642 functions, so we can end up here with an already gimplified
643 body. */
644 if (!gimple_has_body_p (decl))
645 gimplify_function_tree (decl);
646 dump_function (TDI_generic, decl);
648 /* Lower the function. */
649 if (!node->lowered)
651 if (node->nested)
652 lower_nested_functions (node->decl);
653 gcc_assert (!node->nested);
655 gimple_register_cfg_hooks ();
656 bitmap_obstack_initialize (NULL);
657 execute_pass_list (g->get_passes ()->all_lowering_passes);
658 free_dominance_info (CDI_POST_DOMINATORS);
659 free_dominance_info (CDI_DOMINATORS);
660 compact_blocks ();
661 bitmap_obstack_release (NULL);
662 node->lowered = true;
665 pop_cfun ();
667 node->analyzed = true;
669 input_location = saved_loc;
672 /* C++ frontend produce same body aliases all over the place, even before PCH
673 gets streamed out. It relies on us linking the aliases with their function
674 in order to do the fixups, but ipa-ref is not PCH safe. Consequentely we
675 first produce aliases without links, but once C++ FE is sure he won't sream
676 PCH we build the links via this function. */
678 void
679 cgraph_process_same_body_aliases (void)
681 symtab_node *node;
682 FOR_EACH_SYMBOL (node)
683 if (node->cpp_implicit_alias && !node->analyzed)
684 symtab_resolve_alias
685 (node,
686 TREE_CODE (node->alias_target) == VAR_DECL
687 ? (symtab_node *)varpool_node_for_decl (node->alias_target)
688 : (symtab_node *)cgraph_get_create_node (node->alias_target));
689 cpp_implicit_aliases_done = true;
692 /* Process attributes common for vars and functions. */
694 static void
695 process_common_attributes (tree decl)
697 tree weakref = lookup_attribute ("weakref", DECL_ATTRIBUTES (decl));
699 if (weakref && !lookup_attribute ("alias", DECL_ATTRIBUTES (decl)))
701 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
702 "%<weakref%> attribute should be accompanied with"
703 " an %<alias%> attribute");
704 DECL_WEAK (decl) = 0;
705 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
706 DECL_ATTRIBUTES (decl));
710 /* Look for externally_visible and used attributes and mark cgraph nodes
711 accordingly.
713 We cannot mark the nodes at the point the attributes are processed (in
714 handle_*_attribute) because the copy of the declarations available at that
715 point may not be canonical. For example, in:
717 void f();
718 void f() __attribute__((used));
720 the declaration we see in handle_used_attribute will be the second
721 declaration -- but the front end will subsequently merge that declaration
722 with the original declaration and discard the second declaration.
724 Furthermore, we can't mark these nodes in cgraph_finalize_function because:
726 void f() {}
727 void f() __attribute__((externally_visible));
729 is valid.
731 So, we walk the nodes at the end of the translation unit, applying the
732 attributes at that point. */
734 static void
735 process_function_and_variable_attributes (struct cgraph_node *first,
736 struct varpool_node *first_var)
738 struct cgraph_node *node;
739 struct varpool_node *vnode;
741 for (node = cgraph_first_function (); node != first;
742 node = cgraph_next_function (node))
744 tree decl = node->decl;
745 if (DECL_PRESERVE_P (decl))
746 cgraph_mark_force_output_node (node);
747 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
749 if (! TREE_PUBLIC (node->decl))
750 warning_at (DECL_SOURCE_LOCATION (node->decl), OPT_Wattributes,
751 "%<externally_visible%>"
752 " attribute have effect only on public objects");
754 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
755 && (node->definition && !node->alias))
757 warning_at (DECL_SOURCE_LOCATION (node->decl), OPT_Wattributes,
758 "%<weakref%> attribute ignored"
759 " because function is defined");
760 DECL_WEAK (decl) = 0;
761 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
762 DECL_ATTRIBUTES (decl));
765 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl))
766 && !DECL_DECLARED_INLINE_P (decl)
767 /* redefining extern inline function makes it DECL_UNINLINABLE. */
768 && !DECL_UNINLINABLE (decl))
769 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
770 "always_inline function might not be inlinable");
772 process_common_attributes (decl);
774 for (vnode = varpool_first_variable (); vnode != first_var;
775 vnode = varpool_next_variable (vnode))
777 tree decl = vnode->decl;
778 if (DECL_EXTERNAL (decl)
779 && DECL_INITIAL (decl))
780 varpool_finalize_decl (decl);
781 if (DECL_PRESERVE_P (decl))
782 vnode->force_output = true;
783 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
785 if (! TREE_PUBLIC (vnode->decl))
786 warning_at (DECL_SOURCE_LOCATION (vnode->decl), OPT_Wattributes,
787 "%<externally_visible%>"
788 " attribute have effect only on public objects");
790 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
791 && vnode->definition
792 && DECL_INITIAL (decl))
794 warning_at (DECL_SOURCE_LOCATION (vnode->decl), OPT_Wattributes,
795 "%<weakref%> attribute ignored"
796 " because variable is initialized");
797 DECL_WEAK (decl) = 0;
798 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
799 DECL_ATTRIBUTES (decl));
801 process_common_attributes (decl);
805 /* Mark DECL as finalized. By finalizing the declaration, frontend instruct the
806 middle end to output the variable to asm file, if needed or externally
807 visible. */
809 void
810 varpool_finalize_decl (tree decl)
812 struct varpool_node *node = varpool_node_for_decl (decl);
814 gcc_assert (TREE_STATIC (decl) || DECL_EXTERNAL (decl));
816 if (node->definition)
817 return;
818 notice_global_symbol (decl);
819 node->definition = true;
820 if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
821 /* Traditionally we do not eliminate static variables when not
822 optimizing and when not doing toplevel reoder. */
823 || (!flag_toplevel_reorder && !DECL_COMDAT (node->decl)
824 && !DECL_ARTIFICIAL (node->decl)))
825 node->force_output = true;
827 if (cgraph_state == CGRAPH_STATE_CONSTRUCTION
828 && (decide_is_symbol_needed (node)
829 || referred_to_p (node)))
830 enqueue_node (node);
831 if (cgraph_state >= CGRAPH_STATE_IPA_SSA)
832 varpool_analyze_node (node);
833 /* Some frontends produce various interface variables after compilation
834 finished. */
835 if (cgraph_state == CGRAPH_STATE_FINISHED
836 || (!flag_toplevel_reorder && cgraph_state == CGRAPH_STATE_EXPANSION))
837 varpool_assemble_decl (node);
840 /* EDGE is an polymorphic call. Mark all possible targets as reachable
841 and if there is only one target, perform trivial devirtualization.
842 REACHABLE_CALL_TARGETS collects target lists we already walked to
843 avoid udplicate work. */
845 static void
846 walk_polymorphic_call_targets (pointer_set_t *reachable_call_targets,
847 struct cgraph_edge *edge)
849 unsigned int i;
850 void *cache_token;
851 bool final;
852 vec <cgraph_node *>targets
853 = possible_polymorphic_call_targets
854 (edge, &final, &cache_token);
856 if (!pointer_set_insert (reachable_call_targets,
857 cache_token))
859 if (cgraph_dump_file)
860 dump_possible_polymorphic_call_targets
861 (cgraph_dump_file, edge);
863 for (i = 0; i < targets.length (); i++)
865 /* Do not bother to mark virtual methods in anonymous namespace;
866 either we will find use of virtual table defining it, or it is
867 unused. */
868 if (targets[i]->definition
869 && TREE_CODE
870 (TREE_TYPE (targets[i]->decl))
871 == METHOD_TYPE
872 && !type_in_anonymous_namespace_p
873 (method_class_type
874 (TREE_TYPE (targets[i]->decl))))
875 enqueue_node (targets[i]);
879 /* Very trivial devirtualization; when the type is
880 final or anonymous (so we know all its derivation)
881 and there is only one possible virtual call target,
882 make the edge direct. */
883 if (final)
885 if (targets.length () <= 1)
887 cgraph_node *target;
888 if (targets.length () == 1)
889 target = targets[0];
890 else
891 target = cgraph_get_create_node
892 (builtin_decl_implicit (BUILT_IN_UNREACHABLE));
894 if (cgraph_dump_file)
896 fprintf (cgraph_dump_file,
897 "Devirtualizing call: ");
898 print_gimple_stmt (cgraph_dump_file,
899 edge->call_stmt, 0,
900 TDF_SLIM);
902 cgraph_make_edge_direct (edge, target);
903 cgraph_redirect_edge_call_stmt_to_callee (edge);
904 if (cgraph_dump_file)
906 fprintf (cgraph_dump_file,
907 "Devirtualized as: ");
908 print_gimple_stmt (cgraph_dump_file,
909 edge->call_stmt, 0,
910 TDF_SLIM);
917 /* Discover all functions and variables that are trivially needed, analyze
918 them as well as all functions and variables referred by them */
920 static void
921 analyze_functions (void)
923 /* Keep track of already processed nodes when called multiple times for
924 intermodule optimization. */
925 static struct cgraph_node *first_analyzed;
926 struct cgraph_node *first_handled = first_analyzed;
927 static struct varpool_node *first_analyzed_var;
928 struct varpool_node *first_handled_var = first_analyzed_var;
929 struct pointer_set_t *reachable_call_targets = pointer_set_create ();
931 symtab_node *node;
932 symtab_node *next;
933 int i;
934 struct ipa_ref *ref;
935 bool changed = true;
936 location_t saved_loc = input_location;
938 bitmap_obstack_initialize (NULL);
939 cgraph_state = CGRAPH_STATE_CONSTRUCTION;
940 input_location = UNKNOWN_LOCATION;
942 /* Ugly, but the fixup can not happen at a time same body alias is created;
943 C++ FE is confused about the COMDAT groups being right. */
944 if (cpp_implicit_aliases_done)
945 FOR_EACH_SYMBOL (node)
946 if (node->cpp_implicit_alias)
947 fixup_same_cpp_alias_visibility (node, symtab_alias_target (node));
948 if (optimize && flag_devirtualize)
949 build_type_inheritance_graph ();
951 /* Analysis adds static variables that in turn adds references to new functions.
952 So we need to iterate the process until it stabilize. */
953 while (changed)
955 changed = false;
956 process_function_and_variable_attributes (first_analyzed,
957 first_analyzed_var);
959 /* First identify the trivially needed symbols. */
960 for (node = symtab_nodes;
961 node != first_analyzed
962 && node != first_analyzed_var; node = node->next)
964 if (decide_is_symbol_needed (node))
966 enqueue_node (node);
967 if (!changed && cgraph_dump_file)
968 fprintf (cgraph_dump_file, "Trivially needed symbols:");
969 changed = true;
970 if (cgraph_dump_file)
971 fprintf (cgraph_dump_file, " %s", node->asm_name ());
972 if (!changed && cgraph_dump_file)
973 fprintf (cgraph_dump_file, "\n");
975 if (node == first_analyzed
976 || node == first_analyzed_var)
977 break;
979 cgraph_process_new_functions ();
980 first_analyzed_var = varpool_first_variable ();
981 first_analyzed = cgraph_first_function ();
983 if (changed && dump_file)
984 fprintf (cgraph_dump_file, "\n");
986 /* Lower representation, build callgraph edges and references for all trivially
987 needed symbols and all symbols referred by them. */
988 while (queued_nodes != &symtab_terminator)
990 changed = true;
991 node = queued_nodes;
992 queued_nodes = (symtab_node *)queued_nodes->aux;
993 cgraph_node *cnode = dyn_cast <cgraph_node> (node);
994 if (cnode && cnode->definition)
996 struct cgraph_edge *edge;
997 tree decl = cnode->decl;
999 /* ??? It is possible to create extern inline function
1000 and later using weak alias attribute to kill its body.
1001 See gcc.c-torture/compile/20011119-1.c */
1002 if (!DECL_STRUCT_FUNCTION (decl)
1003 && !cnode->alias
1004 && !cnode->thunk.thunk_p
1005 && !cnode->dispatcher_function)
1007 cgraph_reset_node (cnode);
1008 cnode->local.redefined_extern_inline = true;
1009 continue;
1012 if (!cnode->analyzed)
1013 analyze_function (cnode);
1015 for (edge = cnode->callees; edge; edge = edge->next_callee)
1016 if (edge->callee->definition)
1017 enqueue_node (edge->callee);
1018 if (optimize && flag_devirtualize)
1020 struct cgraph_edge *next;
1022 for (edge = cnode->indirect_calls; edge; edge = next)
1024 next = edge->next_callee;
1025 if (edge->indirect_info->polymorphic)
1026 walk_polymorphic_call_targets (reachable_call_targets,
1027 edge);
1031 /* If decl is a clone of an abstract function,
1032 mark that abstract function so that we don't release its body.
1033 The DECL_INITIAL() of that abstract function declaration
1034 will be later needed to output debug info. */
1035 if (DECL_ABSTRACT_ORIGIN (decl))
1037 struct cgraph_node *origin_node
1038 = cgraph_get_node (DECL_ABSTRACT_ORIGIN (decl));
1039 origin_node->used_as_abstract_origin = true;
1042 else
1044 varpool_node *vnode = dyn_cast <varpool_node> (node);
1045 if (vnode && vnode->definition && !vnode->analyzed)
1046 varpool_analyze_node (vnode);
1049 if (node->same_comdat_group)
1051 symtab_node *next;
1052 for (next = node->same_comdat_group;
1053 next != node;
1054 next = next->same_comdat_group)
1055 enqueue_node (next);
1057 for (i = 0; ipa_ref_list_reference_iterate (&node->ref_list, i, ref); i++)
1058 if (ref->referred->definition)
1059 enqueue_node (ref->referred);
1060 cgraph_process_new_functions ();
1063 if (optimize && flag_devirtualize)
1064 update_type_inheritance_graph ();
1066 /* Collect entry points to the unit. */
1067 if (cgraph_dump_file)
1069 fprintf (cgraph_dump_file, "\n\nInitial ");
1070 dump_symtab (cgraph_dump_file);
1073 if (cgraph_dump_file)
1074 fprintf (cgraph_dump_file, "\nRemoving unused symbols:");
1076 for (node = symtab_nodes;
1077 node != first_handled
1078 && node != first_handled_var; node = next)
1080 next = node->next;
1081 if (!node->aux && !referred_to_p (node))
1083 if (cgraph_dump_file)
1084 fprintf (cgraph_dump_file, " %s", node->name ());
1085 symtab_remove_node (node);
1086 continue;
1088 if (cgraph_node *cnode = dyn_cast <cgraph_node> (node))
1090 tree decl = node->decl;
1092 if (cnode->definition && !gimple_has_body_p (decl)
1093 && !cnode->alias
1094 && !cnode->thunk.thunk_p)
1095 cgraph_reset_node (cnode);
1097 gcc_assert (!cnode->definition || cnode->thunk.thunk_p
1098 || cnode->alias
1099 || gimple_has_body_p (decl));
1100 gcc_assert (cnode->analyzed == cnode->definition);
1102 node->aux = NULL;
1104 for (;node; node = node->next)
1105 node->aux = NULL;
1106 first_analyzed = cgraph_first_function ();
1107 first_analyzed_var = varpool_first_variable ();
1108 if (cgraph_dump_file)
1110 fprintf (cgraph_dump_file, "\n\nReclaimed ");
1111 dump_symtab (cgraph_dump_file);
1113 bitmap_obstack_release (NULL);
1114 pointer_set_destroy (reachable_call_targets);
1115 ggc_collect ();
1116 /* Initialize assembler name hash, in particular we want to trigger C++
1117 mangling and same body alias creation before we free DECL_ARGUMENTS
1118 used by it. */
1119 if (!seen_error ())
1120 symtab_initialize_asm_name_hash ();
1122 input_location = saved_loc;
1125 /* Translate the ugly representation of aliases as alias pairs into nice
1126 representation in callgraph. We don't handle all cases yet,
1127 unfortunately. */
1129 static void
1130 handle_alias_pairs (void)
1132 alias_pair *p;
1133 unsigned i;
1135 for (i = 0; alias_pairs && alias_pairs->iterate (i, &p);)
1137 symtab_node *target_node = symtab_node_for_asm (p->target);
1139 /* Weakrefs with target not defined in current unit are easy to handle:
1140 they behave just as external variables except we need to note the
1141 alias flag to later output the weakref pseudo op into asm file. */
1142 if (!target_node
1143 && lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL)
1145 symtab_node *node = symtab_get_node (p->decl);
1146 if (node)
1148 node->alias_target = p->target;
1149 node->weakref = true;
1150 node->alias = true;
1152 alias_pairs->unordered_remove (i);
1153 continue;
1155 else if (!target_node)
1157 error ("%q+D aliased to undefined symbol %qE", p->decl, p->target);
1158 symtab_node *node = symtab_get_node (p->decl);
1159 if (node)
1160 node->alias = false;
1161 alias_pairs->unordered_remove (i);
1162 continue;
1165 if (DECL_EXTERNAL (target_node->decl)
1166 /* We use local aliases for C++ thunks to force the tailcall
1167 to bind locally. This is a hack - to keep it working do
1168 the following (which is not strictly correct). */
1169 && (! TREE_CODE (target_node->decl) == FUNCTION_DECL
1170 || ! DECL_VIRTUAL_P (target_node->decl))
1171 && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)))
1173 error ("%q+D aliased to external symbol %qE",
1174 p->decl, p->target);
1177 if (TREE_CODE (p->decl) == FUNCTION_DECL
1178 && target_node && is_a <cgraph_node> (target_node))
1180 struct cgraph_node *src_node = cgraph_get_node (p->decl);
1181 if (src_node && src_node->definition)
1182 cgraph_reset_node (src_node);
1183 cgraph_create_function_alias (p->decl, target_node->decl);
1184 alias_pairs->unordered_remove (i);
1186 else if (TREE_CODE (p->decl) == VAR_DECL
1187 && target_node && is_a <varpool_node> (target_node))
1189 varpool_create_variable_alias (p->decl, target_node->decl);
1190 alias_pairs->unordered_remove (i);
1192 else
1194 error ("%q+D alias in between function and variable is not supported",
1195 p->decl);
1196 warning (0, "%q+D aliased declaration",
1197 target_node->decl);
1198 alias_pairs->unordered_remove (i);
1201 vec_free (alias_pairs);
1205 /* Figure out what functions we want to assemble. */
1207 static void
1208 mark_functions_to_output (void)
1210 struct cgraph_node *node;
1211 #ifdef ENABLE_CHECKING
1212 bool check_same_comdat_groups = false;
1214 FOR_EACH_FUNCTION (node)
1215 gcc_assert (!node->process);
1216 #endif
1218 FOR_EACH_FUNCTION (node)
1220 tree decl = node->decl;
1222 gcc_assert (!node->process || node->same_comdat_group);
1223 if (node->process)
1224 continue;
1226 /* We need to output all local functions that are used and not
1227 always inlined, as well as those that are reachable from
1228 outside the current compilation unit. */
1229 if (node->analyzed
1230 && !node->thunk.thunk_p
1231 && !node->alias
1232 && !node->global.inlined_to
1233 && !TREE_ASM_WRITTEN (decl)
1234 && !DECL_EXTERNAL (decl))
1236 node->process = 1;
1237 if (node->same_comdat_group)
1239 struct cgraph_node *next;
1240 for (next = cgraph (node->same_comdat_group);
1241 next != node;
1242 next = cgraph (next->same_comdat_group))
1243 if (!next->thunk.thunk_p && !next->alias)
1244 next->process = 1;
1247 else if (node->same_comdat_group)
1249 #ifdef ENABLE_CHECKING
1250 check_same_comdat_groups = true;
1251 #endif
1253 else
1255 /* We should've reclaimed all functions that are not needed. */
1256 #ifdef ENABLE_CHECKING
1257 if (!node->global.inlined_to
1258 && gimple_has_body_p (decl)
1259 /* FIXME: in ltrans unit when offline copy is outside partition but inline copies
1260 are inside partition, we can end up not removing the body since we no longer
1261 have analyzed node pointing to it. */
1262 && !node->in_other_partition
1263 && !node->alias
1264 && !node->clones
1265 && !DECL_EXTERNAL (decl))
1267 dump_cgraph_node (stderr, node);
1268 internal_error ("failed to reclaim unneeded function");
1270 #endif
1271 gcc_assert (node->global.inlined_to
1272 || !gimple_has_body_p (decl)
1273 || node->in_other_partition
1274 || node->clones
1275 || DECL_ARTIFICIAL (decl)
1276 || DECL_EXTERNAL (decl));
1281 #ifdef ENABLE_CHECKING
1282 if (check_same_comdat_groups)
1283 FOR_EACH_FUNCTION (node)
1284 if (node->same_comdat_group && !node->process)
1286 tree decl = node->decl;
1287 if (!node->global.inlined_to
1288 && gimple_has_body_p (decl)
1289 /* FIXME: in an ltrans unit when the offline copy is outside a
1290 partition but inline copies are inside a partition, we can
1291 end up not removing the body since we no longer have an
1292 analyzed node pointing to it. */
1293 && !node->in_other_partition
1294 && !node->clones
1295 && !DECL_EXTERNAL (decl))
1297 dump_cgraph_node (stderr, node);
1298 internal_error ("failed to reclaim unneeded function in same "
1299 "comdat group");
1302 #endif
1305 /* DECL is FUNCTION_DECL. Initialize datastructures so DECL is a function
1306 in lowered gimple form. IN_SSA is true if the gimple is in SSA.
1308 Set current_function_decl and cfun to newly constructed empty function body.
1309 return basic block in the function body. */
1311 basic_block
1312 init_lowered_empty_function (tree decl, bool in_ssa)
1314 basic_block bb;
1316 current_function_decl = decl;
1317 allocate_struct_function (decl, false);
1318 gimple_register_cfg_hooks ();
1319 init_empty_tree_cfg ();
1321 if (in_ssa)
1323 init_tree_ssa (cfun);
1324 init_ssa_operands (cfun);
1325 cfun->gimple_df->in_ssa_p = true;
1326 cfun->curr_properties |= PROP_ssa;
1329 DECL_INITIAL (decl) = make_node (BLOCK);
1331 DECL_SAVED_TREE (decl) = error_mark_node;
1332 cfun->curr_properties |= (PROP_gimple_lcf | PROP_gimple_leh | PROP_gimple_any
1333 | PROP_cfg | PROP_loops);
1335 set_loops_for_fn (cfun, ggc_alloc_cleared_loops ());
1336 init_loops_structure (cfun, loops_for_fn (cfun), 1);
1337 loops_for_fn (cfun)->state |= LOOPS_MAY_HAVE_MULTIPLE_LATCHES;
1339 /* Create BB for body of the function and connect it properly. */
1340 bb = create_basic_block (NULL, (void *) 0, ENTRY_BLOCK_PTR_FOR_FN (cfun));
1341 make_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun), bb, EDGE_FALLTHRU);
1342 make_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
1343 add_bb_to_loop (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun)->loop_father);
1345 return bb;
1348 /* Adjust PTR by the constant FIXED_OFFSET, and by the vtable
1349 offset indicated by VIRTUAL_OFFSET, if that is
1350 non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and
1351 zero for a result adjusting thunk. */
1353 static tree
1354 thunk_adjust (gimple_stmt_iterator * bsi,
1355 tree ptr, bool this_adjusting,
1356 HOST_WIDE_INT fixed_offset, tree virtual_offset)
1358 gimple stmt;
1359 tree ret;
1361 if (this_adjusting
1362 && fixed_offset != 0)
1364 stmt = gimple_build_assign
1365 (ptr, fold_build_pointer_plus_hwi_loc (input_location,
1366 ptr,
1367 fixed_offset));
1368 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1371 /* If there's a virtual offset, look up that value in the vtable and
1372 adjust the pointer again. */
1373 if (virtual_offset)
1375 tree vtabletmp;
1376 tree vtabletmp2;
1377 tree vtabletmp3;
1379 if (!vtable_entry_type)
1381 tree vfunc_type = make_node (FUNCTION_TYPE);
1382 TREE_TYPE (vfunc_type) = integer_type_node;
1383 TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
1384 layout_type (vfunc_type);
1386 vtable_entry_type = build_pointer_type (vfunc_type);
1389 vtabletmp =
1390 create_tmp_reg (build_pointer_type
1391 (build_pointer_type (vtable_entry_type)), "vptr");
1393 /* The vptr is always at offset zero in the object. */
1394 stmt = gimple_build_assign (vtabletmp,
1395 build1 (NOP_EXPR, TREE_TYPE (vtabletmp),
1396 ptr));
1397 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1399 /* Form the vtable address. */
1400 vtabletmp2 = create_tmp_reg (TREE_TYPE (TREE_TYPE (vtabletmp)),
1401 "vtableaddr");
1402 stmt = gimple_build_assign (vtabletmp2,
1403 build_simple_mem_ref (vtabletmp));
1404 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1406 /* Find the entry with the vcall offset. */
1407 stmt = gimple_build_assign (vtabletmp2,
1408 fold_build_pointer_plus_loc (input_location,
1409 vtabletmp2,
1410 virtual_offset));
1411 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1413 /* Get the offset itself. */
1414 vtabletmp3 = create_tmp_reg (TREE_TYPE (TREE_TYPE (vtabletmp2)),
1415 "vcalloffset");
1416 stmt = gimple_build_assign (vtabletmp3,
1417 build_simple_mem_ref (vtabletmp2));
1418 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1420 /* Adjust the `this' pointer. */
1421 ptr = fold_build_pointer_plus_loc (input_location, ptr, vtabletmp3);
1422 ptr = force_gimple_operand_gsi (bsi, ptr, true, NULL_TREE, false,
1423 GSI_CONTINUE_LINKING);
1426 if (!this_adjusting
1427 && fixed_offset != 0)
1428 /* Adjust the pointer by the constant. */
1430 tree ptrtmp;
1432 if (TREE_CODE (ptr) == VAR_DECL)
1433 ptrtmp = ptr;
1434 else
1436 ptrtmp = create_tmp_reg (TREE_TYPE (ptr), "ptr");
1437 stmt = gimple_build_assign (ptrtmp, ptr);
1438 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1440 ptr = fold_build_pointer_plus_hwi_loc (input_location,
1441 ptrtmp, fixed_offset);
1444 /* Emit the statement and gimplify the adjustment expression. */
1445 ret = create_tmp_reg (TREE_TYPE (ptr), "adjusted_this");
1446 stmt = gimple_build_assign (ret, ptr);
1447 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1449 return ret;
1452 /* Expand thunk NODE to gimple if possible.
1453 When OUTPUT_ASM_THUNK is true, also produce assembler for
1454 thunks that are not lowered. */
1456 bool
1457 expand_thunk (struct cgraph_node *node, bool output_asm_thunks)
1459 bool this_adjusting = node->thunk.this_adjusting;
1460 HOST_WIDE_INT fixed_offset = node->thunk.fixed_offset;
1461 HOST_WIDE_INT virtual_value = node->thunk.virtual_value;
1462 tree virtual_offset = NULL;
1463 tree alias = node->callees->callee->decl;
1464 tree thunk_fndecl = node->decl;
1465 tree a;
1468 if (this_adjusting
1469 && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
1470 virtual_value, alias))
1472 const char *fnname;
1473 tree fn_block;
1474 tree restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1476 if (!output_asm_thunks)
1477 return false;
1479 if (in_lto_p)
1480 cgraph_get_body (node);
1481 a = DECL_ARGUMENTS (thunk_fndecl);
1483 current_function_decl = thunk_fndecl;
1485 /* Ensure thunks are emitted in their correct sections. */
1486 resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
1488 DECL_RESULT (thunk_fndecl)
1489 = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl),
1490 RESULT_DECL, 0, restype);
1491 DECL_CONTEXT (DECL_RESULT (thunk_fndecl)) = thunk_fndecl;
1492 fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
1494 /* The back end expects DECL_INITIAL to contain a BLOCK, so we
1495 create one. */
1496 fn_block = make_node (BLOCK);
1497 BLOCK_VARS (fn_block) = a;
1498 DECL_INITIAL (thunk_fndecl) = fn_block;
1499 init_function_start (thunk_fndecl);
1500 cfun->is_thunk = 1;
1501 insn_locations_init ();
1502 set_curr_insn_location (DECL_SOURCE_LOCATION (thunk_fndecl));
1503 prologue_location = curr_insn_location ();
1504 assemble_start_function (thunk_fndecl, fnname);
1506 targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl,
1507 fixed_offset, virtual_value, alias);
1509 assemble_end_function (thunk_fndecl, fnname);
1510 insn_locations_finalize ();
1511 init_insn_lengths ();
1512 free_after_compilation (cfun);
1513 set_cfun (NULL);
1514 TREE_ASM_WRITTEN (thunk_fndecl) = 1;
1515 node->thunk.thunk_p = false;
1516 node->analyzed = false;
1518 else
1520 tree restype;
1521 basic_block bb, then_bb, else_bb, return_bb;
1522 gimple_stmt_iterator bsi;
1523 int nargs = 0;
1524 tree arg;
1525 int i;
1526 tree resdecl;
1527 tree restmp = NULL;
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 auto_vec<tree> vargs (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 gimple_call_set_from_thunk (call, true);
1594 if (restmp)
1596 gimple_call_set_lhs (call, restmp);
1597 gcc_assert (useless_type_conversion_p (TREE_TYPE (restmp),
1598 TREE_TYPE (TREE_TYPE (alias))));
1600 gsi_insert_after (&bsi, call, GSI_NEW_STMT);
1601 if (!(gimple_call_flags (call) & ECF_NORETURN))
1603 if (restmp && !this_adjusting
1604 && (fixed_offset || virtual_offset))
1606 tree true_label = NULL_TREE;
1608 if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE)
1610 gimple stmt;
1611 /* If the return type is a pointer, we need to
1612 protect against NULL. We know there will be an
1613 adjustment, because that's why we're emitting a
1614 thunk. */
1615 then_bb = create_basic_block (NULL, (void *) 0, bb);
1616 return_bb = create_basic_block (NULL, (void *) 0, then_bb);
1617 else_bb = create_basic_block (NULL, (void *) 0, else_bb);
1618 add_bb_to_loop (then_bb, bb->loop_father);
1619 add_bb_to_loop (return_bb, bb->loop_father);
1620 add_bb_to_loop (else_bb, bb->loop_father);
1621 remove_edge (single_succ_edge (bb));
1622 true_label = gimple_block_label (then_bb);
1623 stmt = gimple_build_cond (NE_EXPR, restmp,
1624 build_zero_cst (TREE_TYPE (restmp)),
1625 NULL_TREE, NULL_TREE);
1626 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1627 make_edge (bb, then_bb, EDGE_TRUE_VALUE);
1628 make_edge (bb, else_bb, EDGE_FALSE_VALUE);
1629 make_edge (return_bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
1630 make_edge (then_bb, return_bb, EDGE_FALLTHRU);
1631 make_edge (else_bb, return_bb, EDGE_FALLTHRU);
1632 bsi = gsi_last_bb (then_bb);
1635 restmp = thunk_adjust (&bsi, restmp, /*this_adjusting=*/0,
1636 fixed_offset, virtual_offset);
1637 if (true_label)
1639 gimple stmt;
1640 bsi = gsi_last_bb (else_bb);
1641 stmt = gimple_build_assign (restmp,
1642 build_zero_cst (TREE_TYPE (restmp)));
1643 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1644 bsi = gsi_last_bb (return_bb);
1647 else
1648 gimple_call_set_tail (call, true);
1650 /* Build return value. */
1651 ret = gimple_build_return (restmp);
1652 gsi_insert_after (&bsi, ret, GSI_NEW_STMT);
1654 else
1656 gimple_call_set_tail (call, true);
1657 remove_edge (single_succ_edge (bb));
1660 cfun->gimple_df->in_ssa_p = true;
1661 /* FIXME: C++ FE should stop setting TREE_ASM_WRITTEN on thunks. */
1662 TREE_ASM_WRITTEN (thunk_fndecl) = false;
1663 delete_unreachable_blocks ();
1664 update_ssa (TODO_update_ssa);
1665 #ifdef ENABLE_CHECKING
1666 verify_flow_info ();
1667 #endif
1669 /* Since we want to emit the thunk, we explicitly mark its name as
1670 referenced. */
1671 node->thunk.thunk_p = false;
1672 node->lowered = true;
1673 bitmap_obstack_release (NULL);
1675 current_function_decl = NULL;
1676 set_cfun (NULL);
1677 return true;
1680 /* Assemble thunks and aliases associated to NODE. */
1682 static void
1683 assemble_thunks_and_aliases (struct cgraph_node *node)
1685 struct cgraph_edge *e;
1686 int i;
1687 struct ipa_ref *ref;
1689 for (e = node->callers; e;)
1690 if (e->caller->thunk.thunk_p)
1692 struct cgraph_node *thunk = e->caller;
1694 e = e->next_caller;
1695 assemble_thunks_and_aliases (thunk);
1696 expand_thunk (thunk, true);
1698 else
1699 e = e->next_caller;
1700 for (i = 0; ipa_ref_list_referring_iterate (&node->ref_list,
1701 i, ref); i++)
1702 if (ref->use == IPA_REF_ALIAS)
1704 struct cgraph_node *alias = ipa_ref_referring_node (ref);
1705 bool saved_written = TREE_ASM_WRITTEN (node->decl);
1707 /* Force assemble_alias to really output the alias this time instead
1708 of buffering it in same alias pairs. */
1709 TREE_ASM_WRITTEN (node->decl) = 1;
1710 do_assemble_alias (alias->decl,
1711 DECL_ASSEMBLER_NAME (node->decl));
1712 assemble_thunks_and_aliases (alias);
1713 TREE_ASM_WRITTEN (node->decl) = saved_written;
1717 /* Expand function specified by NODE. */
1719 static void
1720 expand_function (struct cgraph_node *node)
1722 tree decl = node->decl;
1723 location_t saved_loc;
1725 /* We ought to not compile any inline clones. */
1726 gcc_assert (!node->global.inlined_to);
1728 announce_function (decl);
1729 node->process = 0;
1730 gcc_assert (node->lowered);
1731 cgraph_get_body (node);
1733 /* Generate RTL for the body of DECL. */
1735 timevar_push (TV_REST_OF_COMPILATION);
1737 gcc_assert (cgraph_global_info_ready);
1739 /* Initialize the default bitmap obstack. */
1740 bitmap_obstack_initialize (NULL);
1742 /* Initialize the RTL code for the function. */
1743 current_function_decl = decl;
1744 saved_loc = input_location;
1745 input_location = DECL_SOURCE_LOCATION (decl);
1746 init_function_start (decl);
1748 gimple_register_cfg_hooks ();
1750 bitmap_obstack_initialize (&reg_obstack); /* FIXME, only at RTL generation*/
1752 execute_all_ipa_transforms ();
1754 /* Perform all tree transforms and optimizations. */
1756 /* Signal the start of passes. */
1757 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START, NULL);
1759 execute_pass_list (g->get_passes ()->all_passes);
1761 /* Signal the end of passes. */
1762 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END, NULL);
1764 bitmap_obstack_release (&reg_obstack);
1766 /* Release the default bitmap obstack. */
1767 bitmap_obstack_release (NULL);
1769 /* If requested, warn about function definitions where the function will
1770 return a value (usually of some struct or union type) which itself will
1771 take up a lot of stack space. */
1772 if (warn_larger_than && !DECL_EXTERNAL (decl) && TREE_TYPE (decl))
1774 tree ret_type = TREE_TYPE (TREE_TYPE (decl));
1776 if (ret_type && TYPE_SIZE_UNIT (ret_type)
1777 && TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST
1778 && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type),
1779 larger_than_size))
1781 unsigned int size_as_int
1782 = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type));
1784 if (compare_tree_int (TYPE_SIZE_UNIT (ret_type), size_as_int) == 0)
1785 warning (OPT_Wlarger_than_, "size of return value of %q+D is %u bytes",
1786 decl, size_as_int);
1787 else
1788 warning (OPT_Wlarger_than_, "size of return value of %q+D is larger than %wd bytes",
1789 decl, larger_than_size);
1793 gimple_set_body (decl, NULL);
1794 if (DECL_STRUCT_FUNCTION (decl) == 0
1795 && !cgraph_get_node (decl)->origin)
1797 /* Stop pointing to the local nodes about to be freed.
1798 But DECL_INITIAL must remain nonzero so we know this
1799 was an actual function definition.
1800 For a nested function, this is done in c_pop_function_context.
1801 If rest_of_compilation set this to 0, leave it 0. */
1802 if (DECL_INITIAL (decl) != 0)
1803 DECL_INITIAL (decl) = error_mark_node;
1806 input_location = saved_loc;
1808 ggc_collect ();
1809 timevar_pop (TV_REST_OF_COMPILATION);
1811 /* Make sure that BE didn't give up on compiling. */
1812 gcc_assert (TREE_ASM_WRITTEN (decl));
1813 set_cfun (NULL);
1814 current_function_decl = NULL;
1816 /* It would make a lot more sense to output thunks before function body to get more
1817 forward and lest backwarding jumps. This however would need solving problem
1818 with comdats. See PR48668. Also aliases must come after function itself to
1819 make one pass assemblers, like one on AIX, happy. See PR 50689.
1820 FIXME: Perhaps thunks should be move before function IFF they are not in comdat
1821 groups. */
1822 assemble_thunks_and_aliases (node);
1823 cgraph_release_function_body (node);
1824 /* Eliminate all call edges. This is important so the GIMPLE_CALL no longer
1825 points to the dead function body. */
1826 cgraph_node_remove_callees (node);
1827 ipa_remove_all_references (&node->ref_list);
1831 /* Expand all functions that must be output.
1833 Attempt to topologically sort the nodes so function is output when
1834 all called functions are already assembled to allow data to be
1835 propagated across the callgraph. Use a stack to get smaller distance
1836 between a function and its callees (later we may choose to use a more
1837 sophisticated algorithm for function reordering; we will likely want
1838 to use subsections to make the output functions appear in top-down
1839 order). */
1841 static void
1842 expand_all_functions (void)
1844 struct cgraph_node *node;
1845 struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
1846 int order_pos, new_order_pos = 0;
1847 int i;
1849 order_pos = ipa_reverse_postorder (order);
1850 gcc_assert (order_pos == cgraph_n_nodes);
1852 /* Garbage collector may remove inline clones we eliminate during
1853 optimization. So we must be sure to not reference them. */
1854 for (i = 0; i < order_pos; i++)
1855 if (order[i]->process)
1856 order[new_order_pos++] = order[i];
1858 for (i = new_order_pos - 1; i >= 0; i--)
1860 node = order[i];
1861 if (node->process)
1863 node->process = 0;
1864 expand_function (node);
1867 cgraph_process_new_functions ();
1868 free_gimplify_stack ();
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"