2013-11-21 Edward Smith-Rowland <3dw4rd@verizon.net>
[official-gcc.git] / gcc / cgraphunit.c
blobf56f7c7abbb6e93428de113c41f0e6f0f1dc5b68
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;
1528 vec<tree> vargs;
1530 gimple call;
1531 gimple ret;
1533 if (in_lto_p)
1534 cgraph_get_body (node);
1535 a = DECL_ARGUMENTS (thunk_fndecl);
1537 current_function_decl = thunk_fndecl;
1539 /* Ensure thunks are emitted in their correct sections. */
1540 resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
1542 DECL_IGNORED_P (thunk_fndecl) = 1;
1543 bitmap_obstack_initialize (NULL);
1545 if (node->thunk.virtual_offset_p)
1546 virtual_offset = size_int (virtual_value);
1548 /* Build the return declaration for the function. */
1549 restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1550 if (DECL_RESULT (thunk_fndecl) == NULL_TREE)
1552 resdecl = build_decl (input_location, RESULT_DECL, 0, restype);
1553 DECL_ARTIFICIAL (resdecl) = 1;
1554 DECL_IGNORED_P (resdecl) = 1;
1555 DECL_RESULT (thunk_fndecl) = resdecl;
1556 DECL_CONTEXT (DECL_RESULT (thunk_fndecl)) = thunk_fndecl;
1558 else
1559 resdecl = DECL_RESULT (thunk_fndecl);
1561 bb = then_bb = else_bb = return_bb = init_lowered_empty_function (thunk_fndecl, true);
1563 bsi = gsi_start_bb (bb);
1565 /* Build call to the function being thunked. */
1566 if (!VOID_TYPE_P (restype))
1568 if (DECL_BY_REFERENCE (resdecl))
1569 restmp = gimple_fold_indirect_ref (resdecl);
1570 else if (!is_gimple_reg_type (restype))
1572 restmp = resdecl;
1573 add_local_decl (cfun, restmp);
1574 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp;
1576 else
1577 restmp = create_tmp_reg (restype, "retval");
1580 for (arg = a; arg; arg = DECL_CHAIN (arg))
1581 nargs++;
1582 vargs.create (nargs);
1583 if (this_adjusting)
1584 vargs.quick_push (thunk_adjust (&bsi, a, 1, fixed_offset,
1585 virtual_offset));
1586 else if (nargs)
1587 vargs.quick_push (a);
1589 if (nargs)
1590 for (i = 1, arg = DECL_CHAIN (a); i < nargs; i++, arg = DECL_CHAIN (arg))
1591 vargs.quick_push (arg);
1592 call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs);
1593 node->callees->call_stmt = call;
1594 vargs.release ();
1595 gimple_call_set_from_thunk (call, true);
1596 if (restmp)
1598 gimple_call_set_lhs (call, restmp);
1599 gcc_assert (useless_type_conversion_p (TREE_TYPE (restmp),
1600 TREE_TYPE (TREE_TYPE (alias))));
1602 gsi_insert_after (&bsi, call, GSI_NEW_STMT);
1603 if (!(gimple_call_flags (call) & ECF_NORETURN))
1605 if (restmp && !this_adjusting
1606 && (fixed_offset || virtual_offset))
1608 tree true_label = NULL_TREE;
1610 if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE)
1612 gimple stmt;
1613 /* If the return type is a pointer, we need to
1614 protect against NULL. We know there will be an
1615 adjustment, because that's why we're emitting a
1616 thunk. */
1617 then_bb = create_basic_block (NULL, (void *) 0, bb);
1618 return_bb = create_basic_block (NULL, (void *) 0, then_bb);
1619 else_bb = create_basic_block (NULL, (void *) 0, else_bb);
1620 add_bb_to_loop (then_bb, bb->loop_father);
1621 add_bb_to_loop (return_bb, bb->loop_father);
1622 add_bb_to_loop (else_bb, bb->loop_father);
1623 remove_edge (single_succ_edge (bb));
1624 true_label = gimple_block_label (then_bb);
1625 stmt = gimple_build_cond (NE_EXPR, restmp,
1626 build_zero_cst (TREE_TYPE (restmp)),
1627 NULL_TREE, NULL_TREE);
1628 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1629 make_edge (bb, then_bb, EDGE_TRUE_VALUE);
1630 make_edge (bb, else_bb, EDGE_FALSE_VALUE);
1631 make_edge (return_bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
1632 make_edge (then_bb, return_bb, EDGE_FALLTHRU);
1633 make_edge (else_bb, return_bb, EDGE_FALLTHRU);
1634 bsi = gsi_last_bb (then_bb);
1637 restmp = thunk_adjust (&bsi, restmp, /*this_adjusting=*/0,
1638 fixed_offset, virtual_offset);
1639 if (true_label)
1641 gimple stmt;
1642 bsi = gsi_last_bb (else_bb);
1643 stmt = gimple_build_assign (restmp,
1644 build_zero_cst (TREE_TYPE (restmp)));
1645 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1646 bsi = gsi_last_bb (return_bb);
1649 else
1650 gimple_call_set_tail (call, true);
1652 /* Build return value. */
1653 ret = gimple_build_return (restmp);
1654 gsi_insert_after (&bsi, ret, GSI_NEW_STMT);
1656 else
1658 gimple_call_set_tail (call, true);
1659 remove_edge (single_succ_edge (bb));
1662 cfun->gimple_df->in_ssa_p = true;
1663 /* FIXME: C++ FE should stop setting TREE_ASM_WRITTEN on thunks. */
1664 TREE_ASM_WRITTEN (thunk_fndecl) = false;
1665 delete_unreachable_blocks ();
1666 update_ssa (TODO_update_ssa);
1667 #ifdef ENABLE_CHECKING
1668 verify_flow_info ();
1669 #endif
1671 /* Since we want to emit the thunk, we explicitly mark its name as
1672 referenced. */
1673 node->thunk.thunk_p = false;
1674 node->lowered = true;
1675 bitmap_obstack_release (NULL);
1677 current_function_decl = NULL;
1678 set_cfun (NULL);
1679 return true;
1682 /* Assemble thunks and aliases associated to NODE. */
1684 static void
1685 assemble_thunks_and_aliases (struct cgraph_node *node)
1687 struct cgraph_edge *e;
1688 int i;
1689 struct ipa_ref *ref;
1691 for (e = node->callers; e;)
1692 if (e->caller->thunk.thunk_p)
1694 struct cgraph_node *thunk = e->caller;
1696 e = e->next_caller;
1697 assemble_thunks_and_aliases (thunk);
1698 expand_thunk (thunk, true);
1700 else
1701 e = e->next_caller;
1702 for (i = 0; ipa_ref_list_referring_iterate (&node->ref_list,
1703 i, ref); i++)
1704 if (ref->use == IPA_REF_ALIAS)
1706 struct cgraph_node *alias = ipa_ref_referring_node (ref);
1707 bool saved_written = TREE_ASM_WRITTEN (node->decl);
1709 /* Force assemble_alias to really output the alias this time instead
1710 of buffering it in same alias pairs. */
1711 TREE_ASM_WRITTEN (node->decl) = 1;
1712 do_assemble_alias (alias->decl,
1713 DECL_ASSEMBLER_NAME (node->decl));
1714 assemble_thunks_and_aliases (alias);
1715 TREE_ASM_WRITTEN (node->decl) = saved_written;
1719 /* Expand function specified by NODE. */
1721 static void
1722 expand_function (struct cgraph_node *node)
1724 tree decl = node->decl;
1725 location_t saved_loc;
1727 /* We ought to not compile any inline clones. */
1728 gcc_assert (!node->global.inlined_to);
1730 announce_function (decl);
1731 node->process = 0;
1732 gcc_assert (node->lowered);
1733 cgraph_get_body (node);
1735 /* Generate RTL for the body of DECL. */
1737 timevar_push (TV_REST_OF_COMPILATION);
1739 gcc_assert (cgraph_global_info_ready);
1741 /* Initialize the default bitmap obstack. */
1742 bitmap_obstack_initialize (NULL);
1744 /* Initialize the RTL code for the function. */
1745 current_function_decl = decl;
1746 saved_loc = input_location;
1747 input_location = DECL_SOURCE_LOCATION (decl);
1748 init_function_start (decl);
1750 gimple_register_cfg_hooks ();
1752 bitmap_obstack_initialize (&reg_obstack); /* FIXME, only at RTL generation*/
1754 execute_all_ipa_transforms ();
1756 /* Perform all tree transforms and optimizations. */
1758 /* Signal the start of passes. */
1759 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START, NULL);
1761 execute_pass_list (g->get_passes ()->all_passes);
1763 /* Signal the end of passes. */
1764 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END, NULL);
1766 bitmap_obstack_release (&reg_obstack);
1768 /* Release the default bitmap obstack. */
1769 bitmap_obstack_release (NULL);
1771 /* If requested, warn about function definitions where the function will
1772 return a value (usually of some struct or union type) which itself will
1773 take up a lot of stack space. */
1774 if (warn_larger_than && !DECL_EXTERNAL (decl) && TREE_TYPE (decl))
1776 tree ret_type = TREE_TYPE (TREE_TYPE (decl));
1778 if (ret_type && TYPE_SIZE_UNIT (ret_type)
1779 && TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST
1780 && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type),
1781 larger_than_size))
1783 unsigned int size_as_int
1784 = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type));
1786 if (compare_tree_int (TYPE_SIZE_UNIT (ret_type), size_as_int) == 0)
1787 warning (OPT_Wlarger_than_, "size of return value of %q+D is %u bytes",
1788 decl, size_as_int);
1789 else
1790 warning (OPT_Wlarger_than_, "size of return value of %q+D is larger than %wd bytes",
1791 decl, larger_than_size);
1795 gimple_set_body (decl, NULL);
1796 if (DECL_STRUCT_FUNCTION (decl) == 0
1797 && !cgraph_get_node (decl)->origin)
1799 /* Stop pointing to the local nodes about to be freed.
1800 But DECL_INITIAL must remain nonzero so we know this
1801 was an actual function definition.
1802 For a nested function, this is done in c_pop_function_context.
1803 If rest_of_compilation set this to 0, leave it 0. */
1804 if (DECL_INITIAL (decl) != 0)
1805 DECL_INITIAL (decl) = error_mark_node;
1808 input_location = saved_loc;
1810 ggc_collect ();
1811 timevar_pop (TV_REST_OF_COMPILATION);
1813 /* Make sure that BE didn't give up on compiling. */
1814 gcc_assert (TREE_ASM_WRITTEN (decl));
1815 set_cfun (NULL);
1816 current_function_decl = NULL;
1818 /* It would make a lot more sense to output thunks before function body to get more
1819 forward and lest backwarding jumps. This however would need solving problem
1820 with comdats. See PR48668. Also aliases must come after function itself to
1821 make one pass assemblers, like one on AIX, happy. See PR 50689.
1822 FIXME: Perhaps thunks should be move before function IFF they are not in comdat
1823 groups. */
1824 assemble_thunks_and_aliases (node);
1825 cgraph_release_function_body (node);
1826 /* Eliminate all call edges. This is important so the GIMPLE_CALL no longer
1827 points to the dead function body. */
1828 cgraph_node_remove_callees (node);
1829 ipa_remove_all_references (&node->ref_list);
1833 /* Expand all functions that must be output.
1835 Attempt to topologically sort the nodes so function is output when
1836 all called functions are already assembled to allow data to be
1837 propagated across the callgraph. Use a stack to get smaller distance
1838 between a function and its callees (later we may choose to use a more
1839 sophisticated algorithm for function reordering; we will likely want
1840 to use subsections to make the output functions appear in top-down
1841 order). */
1843 static void
1844 expand_all_functions (void)
1846 struct cgraph_node *node;
1847 struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
1848 int order_pos, new_order_pos = 0;
1849 int i;
1851 order_pos = ipa_reverse_postorder (order);
1852 gcc_assert (order_pos == cgraph_n_nodes);
1854 /* Garbage collector may remove inline clones we eliminate during
1855 optimization. So we must be sure to not reference them. */
1856 for (i = 0; i < order_pos; i++)
1857 if (order[i]->process)
1858 order[new_order_pos++] = order[i];
1860 for (i = new_order_pos - 1; i >= 0; i--)
1862 node = order[i];
1863 if (node->process)
1865 node->process = 0;
1866 expand_function (node);
1869 cgraph_process_new_functions ();
1870 free_gimplify_stack ();
1872 free (order);
1876 /* This is used to sort the node types by the cgraph order number. */
1878 enum cgraph_order_sort_kind
1880 ORDER_UNDEFINED = 0,
1881 ORDER_FUNCTION,
1882 ORDER_VAR,
1883 ORDER_ASM
1886 struct cgraph_order_sort
1888 enum cgraph_order_sort_kind kind;
1889 union
1891 struct cgraph_node *f;
1892 struct varpool_node *v;
1893 struct asm_node *a;
1894 } u;
1897 /* Output all functions, variables, and asm statements in the order
1898 according to their order fields, which is the order in which they
1899 appeared in the file. This implements -fno-toplevel-reorder. In
1900 this mode we may output functions and variables which don't really
1901 need to be output. */
1903 static void
1904 output_in_order (void)
1906 int max;
1907 struct cgraph_order_sort *nodes;
1908 int i;
1909 struct cgraph_node *pf;
1910 struct varpool_node *pv;
1911 struct asm_node *pa;
1913 max = symtab_order;
1914 nodes = XCNEWVEC (struct cgraph_order_sort, max);
1916 FOR_EACH_DEFINED_FUNCTION (pf)
1918 if (pf->process && !pf->thunk.thunk_p && !pf->alias)
1920 i = pf->order;
1921 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1922 nodes[i].kind = ORDER_FUNCTION;
1923 nodes[i].u.f = pf;
1927 FOR_EACH_DEFINED_VARIABLE (pv)
1928 if (!DECL_EXTERNAL (pv->decl))
1930 i = pv->order;
1931 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1932 nodes[i].kind = ORDER_VAR;
1933 nodes[i].u.v = pv;
1936 for (pa = asm_nodes; pa; pa = pa->next)
1938 i = pa->order;
1939 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1940 nodes[i].kind = ORDER_ASM;
1941 nodes[i].u.a = pa;
1944 /* In toplevel reorder mode we output all statics; mark them as needed. */
1946 for (i = 0; i < max; ++i)
1947 if (nodes[i].kind == ORDER_VAR)
1948 varpool_finalize_named_section_flags (nodes[i].u.v);
1950 for (i = 0; i < max; ++i)
1952 switch (nodes[i].kind)
1954 case ORDER_FUNCTION:
1955 nodes[i].u.f->process = 0;
1956 expand_function (nodes[i].u.f);
1957 break;
1959 case ORDER_VAR:
1960 varpool_assemble_decl (nodes[i].u.v);
1961 break;
1963 case ORDER_ASM:
1964 assemble_asm (nodes[i].u.a->asm_str);
1965 break;
1967 case ORDER_UNDEFINED:
1968 break;
1970 default:
1971 gcc_unreachable ();
1975 asm_nodes = NULL;
1976 free (nodes);
1979 static void
1980 ipa_passes (void)
1982 gcc::pass_manager *passes = g->get_passes ();
1984 set_cfun (NULL);
1985 current_function_decl = NULL;
1986 gimple_register_cfg_hooks ();
1987 bitmap_obstack_initialize (NULL);
1989 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START, NULL);
1991 if (!in_lto_p)
1993 execute_ipa_pass_list (passes->all_small_ipa_passes);
1994 if (seen_error ())
1995 return;
1998 /* We never run removal of unreachable nodes after early passes. This is
1999 because TODO is run before the subpasses. It is important to remove
2000 the unreachable functions to save works at IPA level and to get LTO
2001 symbol tables right. */
2002 symtab_remove_unreachable_nodes (true, cgraph_dump_file);
2004 /* If pass_all_early_optimizations was not scheduled, the state of
2005 the cgraph will not be properly updated. Update it now. */
2006 if (cgraph_state < CGRAPH_STATE_IPA_SSA)
2007 cgraph_state = CGRAPH_STATE_IPA_SSA;
2009 if (!in_lto_p)
2011 /* Generate coverage variables and constructors. */
2012 coverage_finish ();
2014 /* Process new functions added. */
2015 set_cfun (NULL);
2016 current_function_decl = NULL;
2017 cgraph_process_new_functions ();
2019 execute_ipa_summary_passes
2020 ((struct ipa_opt_pass_d *) passes->all_regular_ipa_passes);
2023 /* Some targets need to handle LTO assembler output specially. */
2024 if (flag_generate_lto)
2025 targetm.asm_out.lto_start ();
2027 if (!in_lto_p)
2028 ipa_write_summaries ();
2030 if (flag_generate_lto)
2031 targetm.asm_out.lto_end ();
2033 if (!flag_ltrans && (in_lto_p || !flag_lto || flag_fat_lto_objects))
2034 execute_ipa_pass_list (passes->all_regular_ipa_passes);
2035 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END, NULL);
2037 bitmap_obstack_release (NULL);
2041 /* Return string alias is alias of. */
2043 static tree
2044 get_alias_symbol (tree decl)
2046 tree alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
2047 return get_identifier (TREE_STRING_POINTER
2048 (TREE_VALUE (TREE_VALUE (alias))));
2052 /* Weakrefs may be associated to external decls and thus not output
2053 at expansion time. Emit all necessary aliases. */
2055 static void
2056 output_weakrefs (void)
2058 symtab_node *node;
2059 FOR_EACH_SYMBOL (node)
2060 if (node->alias
2061 && !TREE_ASM_WRITTEN (node->decl)
2062 && node->weakref)
2064 tree target;
2066 /* Weakrefs are special by not requiring target definition in current
2067 compilation unit. It is thus bit hard to work out what we want to
2068 alias.
2069 When alias target is defined, we need to fetch it from symtab reference,
2070 otherwise it is pointed to by alias_target. */
2071 if (node->alias_target)
2072 target = (DECL_P (node->alias_target)
2073 ? DECL_ASSEMBLER_NAME (node->alias_target)
2074 : node->alias_target);
2075 else if (node->analyzed)
2076 target = DECL_ASSEMBLER_NAME (symtab_alias_target (node)->decl);
2077 else
2079 gcc_unreachable ();
2080 target = get_alias_symbol (node->decl);
2082 do_assemble_alias (node->decl, target);
2086 /* Initialize callgraph dump file. */
2088 void
2089 init_cgraph (void)
2091 if (!cgraph_dump_file)
2092 cgraph_dump_file = dump_begin (TDI_cgraph, NULL);
2096 /* Perform simple optimizations based on callgraph. */
2098 void
2099 compile (void)
2101 if (seen_error ())
2102 return;
2104 #ifdef ENABLE_CHECKING
2105 verify_symtab ();
2106 #endif
2108 timevar_push (TV_CGRAPHOPT);
2109 if (pre_ipa_mem_report)
2111 fprintf (stderr, "Memory consumption before IPA\n");
2112 dump_memory_report (false);
2114 if (!quiet_flag)
2115 fprintf (stderr, "Performing interprocedural optimizations\n");
2116 cgraph_state = CGRAPH_STATE_IPA;
2118 /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE. */
2119 if (flag_lto)
2120 lto_streamer_hooks_init ();
2122 /* Don't run the IPA passes if there was any error or sorry messages. */
2123 if (!seen_error ())
2124 ipa_passes ();
2126 /* Do nothing else if any IPA pass found errors or if we are just streaming LTO. */
2127 if (seen_error ()
2128 || (!in_lto_p && flag_lto && !flag_fat_lto_objects))
2130 timevar_pop (TV_CGRAPHOPT);
2131 return;
2134 /* This pass remove bodies of extern inline functions we never inlined.
2135 Do this later so other IPA passes see what is really going on. */
2136 symtab_remove_unreachable_nodes (false, dump_file);
2137 cgraph_global_info_ready = true;
2138 if (cgraph_dump_file)
2140 fprintf (cgraph_dump_file, "Optimized ");
2141 dump_symtab (cgraph_dump_file);
2143 if (post_ipa_mem_report)
2145 fprintf (stderr, "Memory consumption after IPA\n");
2146 dump_memory_report (false);
2148 timevar_pop (TV_CGRAPHOPT);
2150 /* Output everything. */
2151 (*debug_hooks->assembly_start) ();
2152 if (!quiet_flag)
2153 fprintf (stderr, "Assembling functions:\n");
2154 #ifdef ENABLE_CHECKING
2155 verify_symtab ();
2156 #endif
2158 cgraph_materialize_all_clones ();
2159 bitmap_obstack_initialize (NULL);
2160 execute_ipa_pass_list (g->get_passes ()->all_late_ipa_passes);
2161 symtab_remove_unreachable_nodes (true, dump_file);
2162 #ifdef ENABLE_CHECKING
2163 verify_symtab ();
2164 #endif
2165 bitmap_obstack_release (NULL);
2166 mark_functions_to_output ();
2168 /* When weakref support is missing, we autmatically translate all
2169 references to NODE to references to its ultimate alias target.
2170 The renaming mechanizm uses flag IDENTIFIER_TRANSPARENT_ALIAS and
2171 TREE_CHAIN.
2173 Set up this mapping before we output any assembler but once we are sure
2174 that all symbol renaming is done.
2176 FIXME: All this uglyness can go away if we just do renaming at gimple
2177 level by physically rewritting the IL. At the moment we can only redirect
2178 calls, so we need infrastructure for renaming references as well. */
2179 #ifndef ASM_OUTPUT_WEAKREF
2180 symtab_node *node;
2182 FOR_EACH_SYMBOL (node)
2183 if (node->alias
2184 && lookup_attribute ("weakref", DECL_ATTRIBUTES (node->decl)))
2186 IDENTIFIER_TRANSPARENT_ALIAS
2187 (DECL_ASSEMBLER_NAME (node->decl)) = 1;
2188 TREE_CHAIN (DECL_ASSEMBLER_NAME (node->decl))
2189 = (node->alias_target ? node->alias_target
2190 : DECL_ASSEMBLER_NAME (symtab_alias_target (node)->decl));
2192 #endif
2194 cgraph_state = CGRAPH_STATE_EXPANSION;
2195 if (!flag_toplevel_reorder)
2196 output_in_order ();
2197 else
2199 output_asm_statements ();
2201 expand_all_functions ();
2202 varpool_output_variables ();
2205 cgraph_process_new_functions ();
2206 cgraph_state = CGRAPH_STATE_FINISHED;
2207 output_weakrefs ();
2209 if (cgraph_dump_file)
2211 fprintf (cgraph_dump_file, "\nFinal ");
2212 dump_symtab (cgraph_dump_file);
2214 #ifdef ENABLE_CHECKING
2215 verify_symtab ();
2216 /* Double check that all inline clones are gone and that all
2217 function bodies have been released from memory. */
2218 if (!seen_error ())
2220 struct cgraph_node *node;
2221 bool error_found = false;
2223 FOR_EACH_DEFINED_FUNCTION (node)
2224 if (node->global.inlined_to
2225 || gimple_has_body_p (node->decl))
2227 error_found = true;
2228 dump_cgraph_node (stderr, node);
2230 if (error_found)
2231 internal_error ("nodes with unreleased memory found");
2233 #endif
2237 /* Analyze the whole compilation unit once it is parsed completely. */
2239 void
2240 finalize_compilation_unit (void)
2242 timevar_push (TV_CGRAPH);
2244 /* If we're here there's no current function anymore. Some frontends
2245 are lazy in clearing these. */
2246 current_function_decl = NULL;
2247 set_cfun (NULL);
2249 /* Do not skip analyzing the functions if there were errors, we
2250 miss diagnostics for following functions otherwise. */
2252 /* Emit size functions we didn't inline. */
2253 finalize_size_functions ();
2255 /* Mark alias targets necessary and emit diagnostics. */
2256 handle_alias_pairs ();
2258 if (!quiet_flag)
2260 fprintf (stderr, "\nAnalyzing compilation unit\n");
2261 fflush (stderr);
2264 if (flag_dump_passes)
2265 dump_passes ();
2267 /* Gimplify and lower all functions, compute reachability and
2268 remove unreachable nodes. */
2269 analyze_functions ();
2271 /* Mark alias targets necessary and emit diagnostics. */
2272 handle_alias_pairs ();
2274 /* Gimplify and lower thunks. */
2275 analyze_functions ();
2277 /* Finally drive the pass manager. */
2278 compile ();
2280 timevar_pop (TV_CGRAPH);
2284 #include "gt-cgraphunit.h"