2013-09-12 Richard Biener <rguenther@suse.de>
[official-gcc.git] / gcc / cgraphunit.c
blob8331f2e933bb99afb0412445fe0f48d4347bc01c
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 "output.h"
166 #include "rtl.h"
167 #include "tree-ssa.h"
168 #include "tree-inline.h"
169 #include "langhooks.h"
170 #include "pointer-set.h"
171 #include "toplev.h"
172 #include "flags.h"
173 #include "ggc.h"
174 #include "debug.h"
175 #include "target.h"
176 #include "cgraph.h"
177 #include "diagnostic.h"
178 #include "params.h"
179 #include "fibheap.h"
180 #include "intl.h"
181 #include "function.h"
182 #include "ipa-prop.h"
183 #include "gimple.h"
184 #include "tree-iterator.h"
185 #include "tree-pass.h"
186 #include "tree-dump.h"
187 #include "gimple-pretty-print.h"
188 #include "output.h"
189 #include "coverage.h"
190 #include "plugin.h"
191 #include "ipa-inline.h"
192 #include "ipa-utils.h"
193 #include "lto-streamer.h"
194 #include "except.h"
195 #include "cfgloop.h"
196 #include "regset.h" /* FIXME: For reg_obstack. */
197 #include "context.h"
198 #include "pass_manager.h"
200 /* Queue of cgraph nodes scheduled to be added into cgraph. This is a
201 secondary queue used during optimization to accommodate passes that
202 may generate new functions that need to be optimized and expanded. */
203 cgraph_node_set cgraph_new_nodes;
205 static void expand_all_functions (void);
206 static void mark_functions_to_output (void);
207 static void expand_function (struct cgraph_node *);
208 static void analyze_function (struct cgraph_node *);
209 static void handle_alias_pairs (void);
211 FILE *cgraph_dump_file;
213 /* Linked list of cgraph asm nodes. */
214 struct asm_node *asm_nodes;
216 /* Last node in cgraph_asm_nodes. */
217 static GTY(()) struct asm_node *asm_last_node;
219 /* Used for vtable lookup in thunk adjusting. */
220 static GTY (()) tree vtable_entry_type;
222 /* Determine if symbol DECL is needed. That is, visible to something
223 either outside this translation unit, something magic in the system
224 configury */
225 bool
226 decide_is_symbol_needed (symtab_node node)
228 tree decl = node->symbol.decl;
230 /* Double check that no one output the function into assembly file
231 early. */
232 gcc_checking_assert (!DECL_ASSEMBLER_NAME_SET_P (decl)
233 || !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)));
235 if (!node->symbol.definition)
236 return false;
238 if (DECL_EXTERNAL (decl))
239 return false;
241 /* If the user told us it is used, then it must be so. */
242 if (node->symbol.force_output)
243 return true;
245 /* ABI forced symbols are needed when they are external. */
246 if (node->symbol.forced_by_abi && TREE_PUBLIC (decl))
247 return true;
249 /* Keep constructors, destructors and virtual functions. */
250 if (TREE_CODE (decl) == FUNCTION_DECL
251 && (DECL_STATIC_CONSTRUCTOR (decl) || DECL_STATIC_DESTRUCTOR (decl)))
252 return true;
254 /* Externally visible variables must be output. The exception is
255 COMDAT variables that must be output only when they are needed. */
256 if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
257 return true;
259 return false;
262 /* Head of the queue of nodes to be processed while building callgraph */
264 static symtab_node first = (symtab_node)(void *)1;
266 /* Add NODE to queue starting at FIRST.
267 The queue is linked via AUX pointers and terminated by pointer to 1. */
269 static void
270 enqueue_node (symtab_node node)
272 if (node->symbol.aux)
273 return;
274 gcc_checking_assert (first);
275 node->symbol.aux = first;
276 first = node;
279 /* Process CGRAPH_NEW_FUNCTIONS and perform actions necessary to add these
280 functions into callgraph in a way so they look like ordinary reachable
281 functions inserted into callgraph already at construction time. */
283 bool
284 cgraph_process_new_functions (void)
286 bool output = false;
287 tree fndecl;
288 struct cgraph_node *node;
289 cgraph_node_set_iterator csi;
291 if (!cgraph_new_nodes)
292 return false;
293 handle_alias_pairs ();
294 /* Note that this queue may grow as its being processed, as the new
295 functions may generate new ones. */
296 for (csi = csi_start (cgraph_new_nodes); !csi_end_p (csi); csi_next (&csi))
298 node = csi_node (csi);
299 fndecl = node->symbol.decl;
300 switch (cgraph_state)
302 case CGRAPH_STATE_CONSTRUCTION:
303 /* At construction time we just need to finalize function and move
304 it into reachable functions list. */
306 cgraph_finalize_function (fndecl, false);
307 output = true;
308 cgraph_call_function_insertion_hooks (node);
309 enqueue_node ((symtab_node) node);
310 break;
312 case CGRAPH_STATE_IPA:
313 case CGRAPH_STATE_IPA_SSA:
314 /* When IPA optimization already started, do all essential
315 transformations that has been already performed on the whole
316 cgraph but not on this function. */
318 gimple_register_cfg_hooks ();
319 if (!node->symbol.analyzed)
320 analyze_function (node);
321 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
322 if (cgraph_state == CGRAPH_STATE_IPA_SSA
323 && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
324 g->get_passes ()->execute_early_local_passes ();
325 else if (inline_summary_vec != NULL)
326 compute_inline_parameters (node, true);
327 free_dominance_info (CDI_POST_DOMINATORS);
328 free_dominance_info (CDI_DOMINATORS);
329 pop_cfun ();
330 cgraph_call_function_insertion_hooks (node);
331 break;
333 case CGRAPH_STATE_EXPANSION:
334 /* Functions created during expansion shall be compiled
335 directly. */
336 node->process = 0;
337 cgraph_call_function_insertion_hooks (node);
338 expand_function (node);
339 break;
341 default:
342 gcc_unreachable ();
343 break;
346 free_cgraph_node_set (cgraph_new_nodes);
347 cgraph_new_nodes = NULL;
348 return output;
351 /* As an GCC extension we allow redefinition of the function. The
352 semantics when both copies of bodies differ is not well defined.
353 We replace the old body with new body so in unit at a time mode
354 we always use new body, while in normal mode we may end up with
355 old body inlined into some functions and new body expanded and
356 inlined in others.
358 ??? It may make more sense to use one body for inlining and other
359 body for expanding the function but this is difficult to do. */
361 void
362 cgraph_reset_node (struct cgraph_node *node)
364 /* If node->process is set, then we have already begun whole-unit analysis.
365 This is *not* testing for whether we've already emitted the function.
366 That case can be sort-of legitimately seen with real function redefinition
367 errors. I would argue that the front end should never present us with
368 such a case, but don't enforce that for now. */
369 gcc_assert (!node->process);
371 /* Reset our data structures so we can analyze the function again. */
372 memset (&node->local, 0, sizeof (node->local));
373 memset (&node->global, 0, sizeof (node->global));
374 memset (&node->rtl, 0, sizeof (node->rtl));
375 node->symbol.analyzed = false;
376 node->symbol.definition = false;
377 node->symbol.alias = false;
378 node->symbol.weakref = false;
379 node->symbol.cpp_implicit_alias = false;
381 cgraph_node_remove_callees (node);
382 ipa_remove_all_references (&node->symbol.ref_list);
385 /* Return true when there are references to NODE. */
387 static bool
388 referred_to_p (symtab_node node)
390 struct ipa_ref *ref;
392 /* See if there are any references at all. */
393 if (ipa_ref_list_referring_iterate (&node->symbol.ref_list, 0, ref))
394 return true;
395 /* For functions check also calls. */
396 cgraph_node *cn = dyn_cast <cgraph_node> (node);
397 if (cn && cn->callers)
398 return true;
399 return false;
402 /* DECL has been parsed. Take it, queue it, compile it at the whim of the
403 logic in effect. If NO_COLLECT is true, then our caller cannot stand to have
404 the garbage collector run at the moment. We would need to either create
405 a new GC context, or just not compile right now. */
407 void
408 cgraph_finalize_function (tree decl, bool no_collect)
410 struct cgraph_node *node = cgraph_get_create_node (decl);
412 if (node->symbol.definition)
414 /* Nested functions should only be defined once. */
415 gcc_assert (!DECL_CONTEXT (decl)
416 || TREE_CODE (DECL_CONTEXT (decl)) != FUNCTION_DECL);
417 cgraph_reset_node (node);
418 node->local.redefined_extern_inline = true;
421 notice_global_symbol (decl);
422 node->symbol.definition = true;
423 node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL;
425 /* With -fkeep-inline-functions we are keeping all inline functions except
426 for extern inline ones. */
427 if (flag_keep_inline_functions
428 && DECL_DECLARED_INLINE_P (decl)
429 && !DECL_EXTERNAL (decl)
430 && !DECL_DISREGARD_INLINE_LIMITS (decl))
431 node->symbol.force_output = 1;
433 /* When not optimizing, also output the static functions. (see
434 PR24561), but don't do so for always_inline functions, functions
435 declared inline and nested functions. These were optimized out
436 in the original implementation and it is unclear whether we want
437 to change the behavior here. */
438 if ((!optimize
439 && !node->symbol.cpp_implicit_alias
440 && !DECL_DISREGARD_INLINE_LIMITS (decl)
441 && !DECL_DECLARED_INLINE_P (decl)
442 && !(DECL_CONTEXT (decl)
443 && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL))
444 && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
445 node->symbol.force_output = 1;
447 /* If we've not yet emitted decl, tell the debug info about it. */
448 if (!TREE_ASM_WRITTEN (decl))
449 (*debug_hooks->deferred_inline_function) (decl);
451 /* Possibly warn about unused parameters. */
452 if (warn_unused_parameter)
453 do_warn_unused_parameter (decl);
455 if (!no_collect)
456 ggc_collect ();
458 if (cgraph_state == CGRAPH_STATE_CONSTRUCTION
459 && (decide_is_symbol_needed ((symtab_node) node)
460 || referred_to_p ((symtab_node)node)))
461 enqueue_node ((symtab_node)node);
464 /* Add the function FNDECL to the call graph.
465 Unlike cgraph_finalize_function, this function is intended to be used
466 by middle end and allows insertion of new function at arbitrary point
467 of compilation. The function can be either in high, low or SSA form
468 GIMPLE.
470 The function is assumed to be reachable and have address taken (so no
471 API breaking optimizations are performed on it).
473 Main work done by this function is to enqueue the function for later
474 processing to avoid need the passes to be re-entrant. */
476 void
477 cgraph_add_new_function (tree fndecl, bool lowered)
479 gcc::pass_manager *passes = g->get_passes ();
480 struct cgraph_node *node;
481 switch (cgraph_state)
483 case CGRAPH_STATE_PARSING:
484 cgraph_finalize_function (fndecl, false);
485 break;
486 case CGRAPH_STATE_CONSTRUCTION:
487 /* Just enqueue function to be processed at nearest occurrence. */
488 node = cgraph_create_node (fndecl);
489 if (lowered)
490 node->lowered = true;
491 if (!cgraph_new_nodes)
492 cgraph_new_nodes = cgraph_node_set_new ();
493 cgraph_node_set_add (cgraph_new_nodes, node);
494 break;
496 case CGRAPH_STATE_IPA:
497 case CGRAPH_STATE_IPA_SSA:
498 case CGRAPH_STATE_EXPANSION:
499 /* Bring the function into finalized state and enqueue for later
500 analyzing and compilation. */
501 node = cgraph_get_create_node (fndecl);
502 node->local.local = false;
503 node->symbol.definition = true;
504 node->symbol.force_output = true;
505 if (!lowered && cgraph_state == CGRAPH_STATE_EXPANSION)
507 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
508 gimple_register_cfg_hooks ();
509 bitmap_obstack_initialize (NULL);
510 execute_pass_list (passes->all_lowering_passes);
511 passes->execute_early_local_passes ();
512 bitmap_obstack_release (NULL);
513 pop_cfun ();
515 lowered = true;
517 if (lowered)
518 node->lowered = true;
519 if (!cgraph_new_nodes)
520 cgraph_new_nodes = cgraph_node_set_new ();
521 cgraph_node_set_add (cgraph_new_nodes, node);
522 break;
524 case CGRAPH_STATE_FINISHED:
525 /* At the very end of compilation we have to do all the work up
526 to expansion. */
527 node = cgraph_create_node (fndecl);
528 if (lowered)
529 node->lowered = true;
530 node->symbol.definition = true;
531 analyze_function (node);
532 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
533 gimple_register_cfg_hooks ();
534 bitmap_obstack_initialize (NULL);
535 if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
536 g->get_passes ()->execute_early_local_passes ();
537 bitmap_obstack_release (NULL);
538 pop_cfun ();
539 expand_function (node);
540 break;
542 default:
543 gcc_unreachable ();
546 /* Set a personality if required and we already passed EH lowering. */
547 if (lowered
548 && (function_needs_eh_personality (DECL_STRUCT_FUNCTION (fndecl))
549 == eh_personality_lang))
550 DECL_FUNCTION_PERSONALITY (fndecl) = lang_hooks.eh_personality ();
553 /* Add a top-level asm statement to the list. */
555 struct asm_node *
556 add_asm_node (tree asm_str)
558 struct asm_node *node;
560 node = ggc_alloc_cleared_asm_node ();
561 node->asm_str = asm_str;
562 node->order = symtab_order++;
563 node->next = NULL;
564 if (asm_nodes == NULL)
565 asm_nodes = node;
566 else
567 asm_last_node->next = node;
568 asm_last_node = node;
569 return node;
572 /* Output all asm statements we have stored up to be output. */
574 static void
575 output_asm_statements (void)
577 struct asm_node *can;
579 if (seen_error ())
580 return;
582 for (can = asm_nodes; can; can = can->next)
583 assemble_asm (can->asm_str);
584 asm_nodes = NULL;
587 /* Analyze the function scheduled to be output. */
588 static void
589 analyze_function (struct cgraph_node *node)
591 tree decl = node->symbol.decl;
592 location_t saved_loc = input_location;
593 input_location = DECL_SOURCE_LOCATION (decl);
595 if (node->symbol.alias)
596 symtab_resolve_alias
597 ((symtab_node) node, (symtab_node) cgraph_get_node (node->symbol.alias_target));
598 else if (node->thunk.thunk_p)
600 cgraph_create_edge (node, cgraph_get_node (node->thunk.alias),
601 NULL, 0, CGRAPH_FREQ_BASE);
602 node->thunk.alias = NULL;
604 else if (node->dispatcher_function)
606 /* Generate the dispatcher body of multi-versioned functions. */
607 struct cgraph_function_version_info *dispatcher_version_info
608 = get_cgraph_node_version (node);
609 if (dispatcher_version_info != NULL
610 && (dispatcher_version_info->dispatcher_resolver
611 == NULL_TREE))
613 tree resolver = NULL_TREE;
614 gcc_assert (targetm.generate_version_dispatcher_body);
615 resolver = targetm.generate_version_dispatcher_body (node);
616 gcc_assert (resolver != NULL_TREE);
619 else
621 push_cfun (DECL_STRUCT_FUNCTION (decl));
623 assign_assembler_name_if_neeeded (node->symbol.decl);
625 /* Make sure to gimplify bodies only once. During analyzing a
626 function we lower it, which will require gimplified nested
627 functions, so we can end up here with an already gimplified
628 body. */
629 if (!gimple_has_body_p (decl))
630 gimplify_function_tree (decl);
631 dump_function (TDI_generic, decl);
633 /* Lower the function. */
634 if (!node->lowered)
636 if (node->nested)
637 lower_nested_functions (node->symbol.decl);
638 gcc_assert (!node->nested);
640 gimple_register_cfg_hooks ();
641 bitmap_obstack_initialize (NULL);
642 execute_pass_list (g->get_passes ()->all_lowering_passes);
643 free_dominance_info (CDI_POST_DOMINATORS);
644 free_dominance_info (CDI_DOMINATORS);
645 compact_blocks ();
646 bitmap_obstack_release (NULL);
647 node->lowered = true;
650 pop_cfun ();
652 node->symbol.analyzed = true;
654 input_location = saved_loc;
657 /* C++ frontend produce same body aliases all over the place, even before PCH
658 gets streamed out. It relies on us linking the aliases with their function
659 in order to do the fixups, but ipa-ref is not PCH safe. Consequentely we
660 first produce aliases without links, but once C++ FE is sure he won't sream
661 PCH we build the links via this function. */
663 void
664 cgraph_process_same_body_aliases (void)
666 symtab_node node;
667 FOR_EACH_SYMBOL (node)
668 if (node->symbol.cpp_implicit_alias && !node->symbol.analyzed)
669 symtab_resolve_alias
670 (node,
671 TREE_CODE (node->symbol.alias_target) == VAR_DECL
672 ? (symtab_node)varpool_node_for_decl (node->symbol.alias_target)
673 : (symtab_node)cgraph_get_create_node (node->symbol.alias_target));
674 cpp_implicit_aliases_done = true;
677 /* Process attributes common for vars and functions. */
679 static void
680 process_common_attributes (tree decl)
682 tree weakref = lookup_attribute ("weakref", DECL_ATTRIBUTES (decl));
684 if (weakref && !lookup_attribute ("alias", DECL_ATTRIBUTES (decl)))
686 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
687 "%<weakref%> attribute should be accompanied with"
688 " an %<alias%> attribute");
689 DECL_WEAK (decl) = 0;
690 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
691 DECL_ATTRIBUTES (decl));
695 /* Look for externally_visible and used attributes and mark cgraph nodes
696 accordingly.
698 We cannot mark the nodes at the point the attributes are processed (in
699 handle_*_attribute) because the copy of the declarations available at that
700 point may not be canonical. For example, in:
702 void f();
703 void f() __attribute__((used));
705 the declaration we see in handle_used_attribute will be the second
706 declaration -- but the front end will subsequently merge that declaration
707 with the original declaration and discard the second declaration.
709 Furthermore, we can't mark these nodes in cgraph_finalize_function because:
711 void f() {}
712 void f() __attribute__((externally_visible));
714 is valid.
716 So, we walk the nodes at the end of the translation unit, applying the
717 attributes at that point. */
719 static void
720 process_function_and_variable_attributes (struct cgraph_node *first,
721 struct varpool_node *first_var)
723 struct cgraph_node *node;
724 struct varpool_node *vnode;
726 for (node = cgraph_first_function (); node != first;
727 node = cgraph_next_function (node))
729 tree decl = node->symbol.decl;
730 if (DECL_PRESERVE_P (decl))
731 cgraph_mark_force_output_node (node);
732 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
734 if (! TREE_PUBLIC (node->symbol.decl))
735 warning_at (DECL_SOURCE_LOCATION (node->symbol.decl), OPT_Wattributes,
736 "%<externally_visible%>"
737 " attribute have effect only on public objects");
739 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
740 && (node->symbol.definition && !node->symbol.alias))
742 warning_at (DECL_SOURCE_LOCATION (node->symbol.decl), OPT_Wattributes,
743 "%<weakref%> attribute ignored"
744 " because function is defined");
745 DECL_WEAK (decl) = 0;
746 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
747 DECL_ATTRIBUTES (decl));
750 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl))
751 && !DECL_DECLARED_INLINE_P (decl)
752 /* redefining extern inline function makes it DECL_UNINLINABLE. */
753 && !DECL_UNINLINABLE (decl))
754 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
755 "always_inline function might not be inlinable");
757 process_common_attributes (decl);
759 for (vnode = varpool_first_variable (); vnode != first_var;
760 vnode = varpool_next_variable (vnode))
762 tree decl = vnode->symbol.decl;
763 if (DECL_EXTERNAL (decl)
764 && DECL_INITIAL (decl))
765 varpool_finalize_decl (decl);
766 if (DECL_PRESERVE_P (decl))
767 vnode->symbol.force_output = true;
768 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
770 if (! TREE_PUBLIC (vnode->symbol.decl))
771 warning_at (DECL_SOURCE_LOCATION (vnode->symbol.decl), OPT_Wattributes,
772 "%<externally_visible%>"
773 " attribute have effect only on public objects");
775 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
776 && vnode->symbol.definition
777 && DECL_INITIAL (decl))
779 warning_at (DECL_SOURCE_LOCATION (vnode->symbol.decl), OPT_Wattributes,
780 "%<weakref%> attribute ignored"
781 " because variable is initialized");
782 DECL_WEAK (decl) = 0;
783 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
784 DECL_ATTRIBUTES (decl));
786 process_common_attributes (decl);
790 /* Mark DECL as finalized. By finalizing the declaration, frontend instruct the
791 middle end to output the variable to asm file, if needed or externally
792 visible. */
794 void
795 varpool_finalize_decl (tree decl)
797 struct varpool_node *node = varpool_node_for_decl (decl);
799 gcc_assert (TREE_STATIC (decl) || DECL_EXTERNAL (decl));
801 if (node->symbol.definition)
802 return;
803 notice_global_symbol (decl);
804 node->symbol.definition = true;
805 if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
806 /* Traditionally we do not eliminate static variables when not
807 optimizing and when not doing toplevel reoder. */
808 || (!flag_toplevel_reorder && !DECL_COMDAT (node->symbol.decl)
809 && !DECL_ARTIFICIAL (node->symbol.decl)))
810 node->symbol.force_output = true;
812 if (cgraph_state == CGRAPH_STATE_CONSTRUCTION
813 && (decide_is_symbol_needed ((symtab_node) node)
814 || referred_to_p ((symtab_node)node)))
815 enqueue_node ((symtab_node)node);
816 if (cgraph_state >= CGRAPH_STATE_IPA_SSA)
817 varpool_analyze_node (node);
818 /* Some frontends produce various interface variables after compilation
819 finished. */
820 if (cgraph_state == CGRAPH_STATE_FINISHED)
821 varpool_assemble_decl (node);
824 /* EDGE is an polymorphic call. Mark all possible targets as reachable
825 and if there is only one target, perform trivial devirtualization.
826 REACHABLE_CALL_TARGETS collects target lists we already walked to
827 avoid udplicate work. */
829 static void
830 walk_polymorphic_call_targets (pointer_set_t *reachable_call_targets,
831 struct cgraph_edge *edge)
833 unsigned int i;
834 void *cache_token;
835 bool final;
836 vec <cgraph_node *>targets
837 = possible_polymorphic_call_targets
838 (edge, &final, &cache_token);
840 if (!pointer_set_insert (reachable_call_targets,
841 cache_token))
843 if (cgraph_dump_file)
844 dump_possible_polymorphic_call_targets
845 (cgraph_dump_file, edge);
847 for (i = 0; i < targets.length(); i++)
849 /* Do not bother to mark virtual methods in anonymous namespace;
850 either we will find use of virtual table defining it, or it is
851 unused. */
852 if (targets[i]->symbol.definition
853 && TREE_CODE
854 (TREE_TYPE (targets[i]->symbol.decl))
855 == METHOD_TYPE
856 && !type_in_anonymous_namespace_p
857 (method_class_type
858 (TREE_TYPE (targets[i]->symbol.decl))))
859 enqueue_node ((symtab_node) targets[i]);
863 /* Very trivial devirtualization; when the type is
864 final or anonymous (so we know all its derivation)
865 and there is only one possible virtual call target,
866 make the edge direct. */
867 if (final)
869 if (targets.length() <= 1)
871 cgraph_node *target;
872 if (targets.length () == 1)
873 target = targets[0];
874 else
875 target = cgraph_get_create_node
876 (builtin_decl_implicit (BUILT_IN_UNREACHABLE));
878 if (cgraph_dump_file)
880 fprintf (cgraph_dump_file,
881 "Devirtualizing call: ");
882 print_gimple_stmt (cgraph_dump_file,
883 edge->call_stmt, 0,
884 TDF_SLIM);
886 cgraph_make_edge_direct (edge, target);
887 cgraph_redirect_edge_call_stmt_to_callee (edge);
888 if (cgraph_dump_file)
890 fprintf (cgraph_dump_file,
891 "Devirtualized as: ");
892 print_gimple_stmt (cgraph_dump_file,
893 edge->call_stmt, 0,
894 TDF_SLIM);
901 /* Discover all functions and variables that are trivially needed, analyze
902 them as well as all functions and variables referred by them */
904 static void
905 analyze_functions (void)
907 /* Keep track of already processed nodes when called multiple times for
908 intermodule optimization. */
909 static struct cgraph_node *first_analyzed;
910 struct cgraph_node *first_handled = first_analyzed;
911 static struct varpool_node *first_analyzed_var;
912 struct varpool_node *first_handled_var = first_analyzed_var;
913 struct pointer_set_t *reachable_call_targets = pointer_set_create ();
915 symtab_node node, next;
916 int i;
917 struct ipa_ref *ref;
918 bool changed = true;
919 location_t saved_loc = input_location;
921 bitmap_obstack_initialize (NULL);
922 cgraph_state = CGRAPH_STATE_CONSTRUCTION;
923 input_location = UNKNOWN_LOCATION;
925 /* Ugly, but the fixup can not happen at a time same body alias is created;
926 C++ FE is confused about the COMDAT groups being right. */
927 if (cpp_implicit_aliases_done)
928 FOR_EACH_SYMBOL (node)
929 if (node->symbol.cpp_implicit_alias)
930 fixup_same_cpp_alias_visibility (node, symtab_alias_target (node));
931 if (optimize && flag_devirtualize)
932 build_type_inheritance_graph ();
934 /* Analysis adds static variables that in turn adds references to new functions.
935 So we need to iterate the process until it stabilize. */
936 while (changed)
938 changed = false;
939 process_function_and_variable_attributes (first_analyzed,
940 first_analyzed_var);
942 /* First identify the trivially needed symbols. */
943 for (node = symtab_nodes;
944 node != (symtab_node)first_analyzed
945 && node != (symtab_node)first_analyzed_var; node = node->symbol.next)
947 if (decide_is_symbol_needed (node))
949 enqueue_node (node);
950 if (!changed && cgraph_dump_file)
951 fprintf (cgraph_dump_file, "Trivially needed symbols:");
952 changed = true;
953 if (cgraph_dump_file)
954 fprintf (cgraph_dump_file, " %s", symtab_node_asm_name (node));
955 if (!changed && cgraph_dump_file)
956 fprintf (cgraph_dump_file, "\n");
958 if (node == (symtab_node)first_analyzed
959 || node == (symtab_node)first_analyzed_var)
960 break;
962 cgraph_process_new_functions ();
963 first_analyzed_var = varpool_first_variable ();
964 first_analyzed = cgraph_first_function ();
966 if (changed && dump_file)
967 fprintf (cgraph_dump_file, "\n");
969 /* Lower representation, build callgraph edges and references for all trivially
970 needed symbols and all symbols referred by them. */
971 while (first != (symtab_node)(void *)1)
973 changed = true;
974 node = first;
975 first = (symtab_node)first->symbol.aux;
976 cgraph_node *cnode = dyn_cast <cgraph_node> (node);
977 if (cnode && cnode->symbol.definition)
979 struct cgraph_edge *edge;
980 tree decl = cnode->symbol.decl;
982 /* ??? It is possible to create extern inline function
983 and later using weak alias attribute to kill its body.
984 See gcc.c-torture/compile/20011119-1.c */
985 if (!DECL_STRUCT_FUNCTION (decl)
986 && !cnode->symbol.alias
987 && !cnode->thunk.thunk_p
988 && !cnode->dispatcher_function)
990 cgraph_reset_node (cnode);
991 cnode->local.redefined_extern_inline = true;
992 continue;
995 if (!cnode->symbol.analyzed)
996 analyze_function (cnode);
998 for (edge = cnode->callees; edge; edge = edge->next_callee)
999 if (edge->callee->symbol.definition)
1000 enqueue_node ((symtab_node)edge->callee);
1001 if (optimize && flag_devirtualize)
1003 struct cgraph_edge *next;
1005 for (edge = cnode->indirect_calls; edge; edge = next)
1007 next = edge->next_callee;
1008 if (edge->indirect_info->polymorphic)
1009 walk_polymorphic_call_targets (reachable_call_targets,
1010 edge);
1014 /* If decl is a clone of an abstract function,
1015 mark that abstract function so that we don't release its body.
1016 The DECL_INITIAL() of that abstract function declaration
1017 will be later needed to output debug info. */
1018 if (DECL_ABSTRACT_ORIGIN (decl))
1020 struct cgraph_node *origin_node
1021 = cgraph_get_node (DECL_ABSTRACT_ORIGIN (decl));
1022 origin_node->used_as_abstract_origin = true;
1025 else
1027 varpool_node *vnode = dyn_cast <varpool_node> (node);
1028 if (vnode && vnode->symbol.definition && !vnode->symbol.analyzed)
1029 varpool_analyze_node (vnode);
1032 if (node->symbol.same_comdat_group)
1034 symtab_node next;
1035 for (next = node->symbol.same_comdat_group;
1036 next != node;
1037 next = next->symbol.same_comdat_group)
1038 enqueue_node (next);
1040 for (i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list, i, ref); i++)
1041 if (ref->referred->symbol.definition)
1042 enqueue_node (ref->referred);
1043 cgraph_process_new_functions ();
1046 if (optimize && flag_devirtualize)
1047 update_type_inheritance_graph ();
1049 /* Collect entry points to the unit. */
1050 if (cgraph_dump_file)
1052 fprintf (cgraph_dump_file, "\n\nInitial ");
1053 dump_symtab (cgraph_dump_file);
1056 if (cgraph_dump_file)
1057 fprintf (cgraph_dump_file, "\nRemoving unused symbols:");
1059 for (node = symtab_nodes;
1060 node != (symtab_node)first_handled
1061 && node != (symtab_node)first_handled_var; node = next)
1063 next = node->symbol.next;
1064 if (!node->symbol.aux && !referred_to_p (node))
1066 if (cgraph_dump_file)
1067 fprintf (cgraph_dump_file, " %s", symtab_node_name (node));
1068 symtab_remove_node (node);
1069 continue;
1071 if (cgraph_node *cnode = dyn_cast <cgraph_node> (node))
1073 tree decl = node->symbol.decl;
1075 if (cnode->symbol.definition && !gimple_has_body_p (decl)
1076 && !cnode->symbol.alias
1077 && !cnode->thunk.thunk_p)
1078 cgraph_reset_node (cnode);
1080 gcc_assert (!cnode->symbol.definition || cnode->thunk.thunk_p
1081 || cnode->symbol.alias
1082 || gimple_has_body_p (decl));
1083 gcc_assert (cnode->symbol.analyzed == cnode->symbol.definition);
1085 node->symbol.aux = NULL;
1087 for (;node; node = node->symbol.next)
1088 node->symbol.aux = NULL;
1089 first_analyzed = cgraph_first_function ();
1090 first_analyzed_var = varpool_first_variable ();
1091 if (cgraph_dump_file)
1093 fprintf (cgraph_dump_file, "\n\nReclaimed ");
1094 dump_symtab (cgraph_dump_file);
1096 bitmap_obstack_release (NULL);
1097 pointer_set_destroy (reachable_call_targets);
1098 ggc_collect ();
1099 /* Initialize assembler name hash, in particular we want to trigger C++
1100 mangling and same body alias creation before we free DECL_ARGUMENTS
1101 used by it. */
1102 if (!seen_error ())
1103 symtab_initialize_asm_name_hash ();
1105 input_location = saved_loc;
1108 /* Translate the ugly representation of aliases as alias pairs into nice
1109 representation in callgraph. We don't handle all cases yet,
1110 unfortunately. */
1112 static void
1113 handle_alias_pairs (void)
1115 alias_pair *p;
1116 unsigned i;
1118 for (i = 0; alias_pairs && alias_pairs->iterate (i, &p);)
1120 symtab_node target_node = symtab_node_for_asm (p->target);
1122 /* Weakrefs with target not defined in current unit are easy to handle:
1123 they behave just as external variables except we need to note the
1124 alias flag to later output the weakref pseudo op into asm file. */
1125 if (!target_node
1126 && lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL)
1128 symtab_node node = symtab_get_node (p->decl);
1129 if (node)
1131 node->symbol.alias_target = p->target;
1132 node->symbol.weakref = true;
1133 node->symbol.alias = true;
1135 alias_pairs->unordered_remove (i);
1136 continue;
1138 else if (!target_node)
1140 error ("%q+D aliased to undefined symbol %qE", p->decl, p->target);
1141 symtab_node node = symtab_get_node (p->decl);
1142 if (node)
1143 node->symbol.alias = false;
1144 alias_pairs->unordered_remove (i);
1145 continue;
1148 if (DECL_EXTERNAL (target_node->symbol.decl)
1149 /* We use local aliases for C++ thunks to force the tailcall
1150 to bind locally. This is a hack - to keep it working do
1151 the following (which is not strictly correct). */
1152 && (! TREE_CODE (target_node->symbol.decl) == FUNCTION_DECL
1153 || ! DECL_VIRTUAL_P (target_node->symbol.decl))
1154 && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)))
1156 error ("%q+D aliased to external symbol %qE",
1157 p->decl, p->target);
1160 if (TREE_CODE (p->decl) == FUNCTION_DECL
1161 && target_node && is_a <cgraph_node> (target_node))
1163 struct cgraph_node *src_node = cgraph_get_node (p->decl);
1164 if (src_node && src_node->symbol.definition)
1165 cgraph_reset_node (src_node);
1166 cgraph_create_function_alias (p->decl, target_node->symbol.decl);
1167 alias_pairs->unordered_remove (i);
1169 else if (TREE_CODE (p->decl) == VAR_DECL
1170 && target_node && is_a <varpool_node> (target_node))
1172 varpool_create_variable_alias (p->decl, target_node->symbol.decl);
1173 alias_pairs->unordered_remove (i);
1175 else
1177 error ("%q+D alias in between function and variable is not supported",
1178 p->decl);
1179 warning (0, "%q+D aliased declaration",
1180 target_node->symbol.decl);
1181 alias_pairs->unordered_remove (i);
1184 vec_free (alias_pairs);
1188 /* Figure out what functions we want to assemble. */
1190 static void
1191 mark_functions_to_output (void)
1193 struct cgraph_node *node;
1194 #ifdef ENABLE_CHECKING
1195 bool check_same_comdat_groups = false;
1197 FOR_EACH_FUNCTION (node)
1198 gcc_assert (!node->process);
1199 #endif
1201 FOR_EACH_FUNCTION (node)
1203 tree decl = node->symbol.decl;
1205 gcc_assert (!node->process || node->symbol.same_comdat_group);
1206 if (node->process)
1207 continue;
1209 /* We need to output all local functions that are used and not
1210 always inlined, as well as those that are reachable from
1211 outside the current compilation unit. */
1212 if (node->symbol.analyzed
1213 && !node->thunk.thunk_p
1214 && !node->symbol.alias
1215 && !node->global.inlined_to
1216 && !TREE_ASM_WRITTEN (decl)
1217 && !DECL_EXTERNAL (decl))
1219 node->process = 1;
1220 if (node->symbol.same_comdat_group)
1222 struct cgraph_node *next;
1223 for (next = cgraph (node->symbol.same_comdat_group);
1224 next != node;
1225 next = cgraph (next->symbol.same_comdat_group))
1226 if (!next->thunk.thunk_p && !next->symbol.alias)
1227 next->process = 1;
1230 else if (node->symbol.same_comdat_group)
1232 #ifdef ENABLE_CHECKING
1233 check_same_comdat_groups = true;
1234 #endif
1236 else
1238 /* We should've reclaimed all functions that are not needed. */
1239 #ifdef ENABLE_CHECKING
1240 if (!node->global.inlined_to
1241 && gimple_has_body_p (decl)
1242 /* FIXME: in ltrans unit when offline copy is outside partition but inline copies
1243 are inside partition, we can end up not removing the body since we no longer
1244 have analyzed node pointing to it. */
1245 && !node->symbol.in_other_partition
1246 && !node->symbol.alias
1247 && !node->clones
1248 && !DECL_EXTERNAL (decl))
1250 dump_cgraph_node (stderr, node);
1251 internal_error ("failed to reclaim unneeded function");
1253 #endif
1254 gcc_assert (node->global.inlined_to
1255 || !gimple_has_body_p (decl)
1256 || node->symbol.in_other_partition
1257 || node->clones
1258 || DECL_ARTIFICIAL (decl)
1259 || DECL_EXTERNAL (decl));
1264 #ifdef ENABLE_CHECKING
1265 if (check_same_comdat_groups)
1266 FOR_EACH_FUNCTION (node)
1267 if (node->symbol.same_comdat_group && !node->process)
1269 tree decl = node->symbol.decl;
1270 if (!node->global.inlined_to
1271 && gimple_has_body_p (decl)
1272 /* FIXME: in an ltrans unit when the offline copy is outside a
1273 partition but inline copies are inside a partition, we can
1274 end up not removing the body since we no longer have an
1275 analyzed node pointing to it. */
1276 && !node->symbol.in_other_partition
1277 && !node->clones
1278 && !DECL_EXTERNAL (decl))
1280 dump_cgraph_node (stderr, node);
1281 internal_error ("failed to reclaim unneeded function in same "
1282 "comdat group");
1285 #endif
1288 /* DECL is FUNCTION_DECL. Initialize datastructures so DECL is a function
1289 in lowered gimple form. IN_SSA is true if the gimple is in SSA.
1291 Set current_function_decl and cfun to newly constructed empty function body.
1292 return basic block in the function body. */
1294 basic_block
1295 init_lowered_empty_function (tree decl, bool in_ssa)
1297 basic_block bb;
1299 current_function_decl = decl;
1300 allocate_struct_function (decl, false);
1301 gimple_register_cfg_hooks ();
1302 init_empty_tree_cfg ();
1304 if (in_ssa)
1306 init_tree_ssa (cfun);
1307 init_ssa_operands (cfun);
1308 cfun->gimple_df->in_ssa_p = true;
1309 cfun->curr_properties |= PROP_ssa;
1312 DECL_INITIAL (decl) = make_node (BLOCK);
1314 DECL_SAVED_TREE (decl) = error_mark_node;
1315 cfun->curr_properties |= (PROP_gimple_lcf | PROP_gimple_leh | PROP_gimple_any
1316 | PROP_cfg | PROP_loops);
1318 set_loops_for_fn (cfun, ggc_alloc_cleared_loops ());
1319 init_loops_structure (cfun, loops_for_fn (cfun), 1);
1320 loops_for_fn (cfun)->state |= LOOPS_MAY_HAVE_MULTIPLE_LATCHES;
1322 /* Create BB for body of the function and connect it properly. */
1323 bb = create_basic_block (NULL, (void *) 0, ENTRY_BLOCK_PTR);
1324 make_edge (ENTRY_BLOCK_PTR, bb, EDGE_FALLTHRU);
1325 make_edge (bb, EXIT_BLOCK_PTR, 0);
1326 add_bb_to_loop (bb, ENTRY_BLOCK_PTR->loop_father);
1328 return bb;
1331 /* Adjust PTR by the constant FIXED_OFFSET, and by the vtable
1332 offset indicated by VIRTUAL_OFFSET, if that is
1333 non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and
1334 zero for a result adjusting thunk. */
1336 static tree
1337 thunk_adjust (gimple_stmt_iterator * bsi,
1338 tree ptr, bool this_adjusting,
1339 HOST_WIDE_INT fixed_offset, tree virtual_offset)
1341 gimple stmt;
1342 tree ret;
1344 if (this_adjusting
1345 && fixed_offset != 0)
1347 stmt = gimple_build_assign
1348 (ptr, fold_build_pointer_plus_hwi_loc (input_location,
1349 ptr,
1350 fixed_offset));
1351 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1354 /* If there's a virtual offset, look up that value in the vtable and
1355 adjust the pointer again. */
1356 if (virtual_offset)
1358 tree vtabletmp;
1359 tree vtabletmp2;
1360 tree vtabletmp3;
1362 if (!vtable_entry_type)
1364 tree vfunc_type = make_node (FUNCTION_TYPE);
1365 TREE_TYPE (vfunc_type) = integer_type_node;
1366 TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
1367 layout_type (vfunc_type);
1369 vtable_entry_type = build_pointer_type (vfunc_type);
1372 vtabletmp =
1373 create_tmp_reg (build_pointer_type
1374 (build_pointer_type (vtable_entry_type)), "vptr");
1376 /* The vptr is always at offset zero in the object. */
1377 stmt = gimple_build_assign (vtabletmp,
1378 build1 (NOP_EXPR, TREE_TYPE (vtabletmp),
1379 ptr));
1380 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1382 /* Form the vtable address. */
1383 vtabletmp2 = create_tmp_reg (TREE_TYPE (TREE_TYPE (vtabletmp)),
1384 "vtableaddr");
1385 stmt = gimple_build_assign (vtabletmp2,
1386 build_simple_mem_ref (vtabletmp));
1387 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1389 /* Find the entry with the vcall offset. */
1390 stmt = gimple_build_assign (vtabletmp2,
1391 fold_build_pointer_plus_loc (input_location,
1392 vtabletmp2,
1393 virtual_offset));
1394 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1396 /* Get the offset itself. */
1397 vtabletmp3 = create_tmp_reg (TREE_TYPE (TREE_TYPE (vtabletmp2)),
1398 "vcalloffset");
1399 stmt = gimple_build_assign (vtabletmp3,
1400 build_simple_mem_ref (vtabletmp2));
1401 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1403 /* Adjust the `this' pointer. */
1404 ptr = fold_build_pointer_plus_loc (input_location, ptr, vtabletmp3);
1405 ptr = force_gimple_operand_gsi (bsi, ptr, true, NULL_TREE, false,
1406 GSI_CONTINUE_LINKING);
1409 if (!this_adjusting
1410 && fixed_offset != 0)
1411 /* Adjust the pointer by the constant. */
1413 tree ptrtmp;
1415 if (TREE_CODE (ptr) == VAR_DECL)
1416 ptrtmp = ptr;
1417 else
1419 ptrtmp = create_tmp_reg (TREE_TYPE (ptr), "ptr");
1420 stmt = gimple_build_assign (ptrtmp, ptr);
1421 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1423 ptr = fold_build_pointer_plus_hwi_loc (input_location,
1424 ptrtmp, fixed_offset);
1427 /* Emit the statement and gimplify the adjustment expression. */
1428 ret = create_tmp_reg (TREE_TYPE (ptr), "adjusted_this");
1429 stmt = gimple_build_assign (ret, ptr);
1430 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1432 return ret;
1435 /* Produce assembler for thunk NODE. */
1437 void
1438 expand_thunk (struct cgraph_node *node)
1440 bool this_adjusting = node->thunk.this_adjusting;
1441 HOST_WIDE_INT fixed_offset = node->thunk.fixed_offset;
1442 HOST_WIDE_INT virtual_value = node->thunk.virtual_value;
1443 tree virtual_offset = NULL;
1444 tree alias = node->callees->callee->symbol.decl;
1445 tree thunk_fndecl = node->symbol.decl;
1446 tree a;
1448 if (in_lto_p)
1449 cgraph_get_body (node);
1450 a = DECL_ARGUMENTS (thunk_fndecl);
1452 current_function_decl = thunk_fndecl;
1454 /* Ensure thunks are emitted in their correct sections. */
1455 resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
1457 if (this_adjusting
1458 && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
1459 virtual_value, alias))
1461 const char *fnname;
1462 tree fn_block;
1463 tree restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1465 DECL_RESULT (thunk_fndecl)
1466 = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl),
1467 RESULT_DECL, 0, restype);
1468 fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
1470 /* The back end expects DECL_INITIAL to contain a BLOCK, so we
1471 create one. */
1472 fn_block = make_node (BLOCK);
1473 BLOCK_VARS (fn_block) = a;
1474 DECL_INITIAL (thunk_fndecl) = fn_block;
1475 init_function_start (thunk_fndecl);
1476 cfun->is_thunk = 1;
1477 insn_locations_init ();
1478 set_curr_insn_location (DECL_SOURCE_LOCATION (thunk_fndecl));
1479 prologue_location = curr_insn_location ();
1480 assemble_start_function (thunk_fndecl, fnname);
1482 targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl,
1483 fixed_offset, virtual_value, alias);
1485 assemble_end_function (thunk_fndecl, fnname);
1486 insn_locations_finalize ();
1487 init_insn_lengths ();
1488 free_after_compilation (cfun);
1489 set_cfun (NULL);
1490 TREE_ASM_WRITTEN (thunk_fndecl) = 1;
1491 node->thunk.thunk_p = false;
1492 node->symbol.analyzed = false;
1494 else
1496 tree restype;
1497 basic_block bb, then_bb, else_bb, return_bb;
1498 gimple_stmt_iterator bsi;
1499 int nargs = 0;
1500 tree arg;
1501 int i;
1502 tree resdecl;
1503 tree restmp = NULL;
1504 vec<tree> vargs;
1506 gimple call;
1507 gimple ret;
1509 DECL_IGNORED_P (thunk_fndecl) = 1;
1510 bitmap_obstack_initialize (NULL);
1512 if (node->thunk.virtual_offset_p)
1513 virtual_offset = size_int (virtual_value);
1515 /* Build the return declaration for the function. */
1516 restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1517 if (DECL_RESULT (thunk_fndecl) == NULL_TREE)
1519 resdecl = build_decl (input_location, RESULT_DECL, 0, restype);
1520 DECL_ARTIFICIAL (resdecl) = 1;
1521 DECL_IGNORED_P (resdecl) = 1;
1522 DECL_RESULT (thunk_fndecl) = resdecl;
1524 else
1525 resdecl = DECL_RESULT (thunk_fndecl);
1527 bb = then_bb = else_bb = return_bb = init_lowered_empty_function (thunk_fndecl, true);
1529 bsi = gsi_start_bb (bb);
1531 /* Build call to the function being thunked. */
1532 if (!VOID_TYPE_P (restype))
1534 if (DECL_BY_REFERENCE (resdecl))
1535 restmp = gimple_fold_indirect_ref (resdecl);
1536 else if (!is_gimple_reg_type (restype))
1538 restmp = resdecl;
1539 add_local_decl (cfun, restmp);
1540 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp;
1542 else
1543 restmp = create_tmp_reg (restype, "retval");
1546 for (arg = a; arg; arg = DECL_CHAIN (arg))
1547 nargs++;
1548 vargs.create (nargs);
1549 if (this_adjusting)
1550 vargs.quick_push (thunk_adjust (&bsi, a, 1, fixed_offset,
1551 virtual_offset));
1552 else if (nargs)
1553 vargs.quick_push (a);
1555 if (nargs)
1556 for (i = 1, arg = DECL_CHAIN (a); i < nargs; i++, arg = DECL_CHAIN (arg))
1557 vargs.quick_push (arg);
1558 call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs);
1559 vargs.release ();
1560 gimple_call_set_from_thunk (call, true);
1561 if (restmp)
1563 gimple_call_set_lhs (call, restmp);
1564 gcc_assert (useless_type_conversion_p (TREE_TYPE (restmp),
1565 TREE_TYPE (TREE_TYPE (alias))));
1567 gsi_insert_after (&bsi, call, GSI_NEW_STMT);
1568 if (!(gimple_call_flags (call) & ECF_NORETURN))
1570 if (restmp && !this_adjusting
1571 && (fixed_offset || virtual_offset))
1573 tree true_label = NULL_TREE;
1575 if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE)
1577 gimple stmt;
1578 /* If the return type is a pointer, we need to
1579 protect against NULL. We know there will be an
1580 adjustment, because that's why we're emitting a
1581 thunk. */
1582 then_bb = create_basic_block (NULL, (void *) 0, bb);
1583 return_bb = create_basic_block (NULL, (void *) 0, then_bb);
1584 else_bb = create_basic_block (NULL, (void *) 0, else_bb);
1585 add_bb_to_loop (then_bb, bb->loop_father);
1586 add_bb_to_loop (return_bb, bb->loop_father);
1587 add_bb_to_loop (else_bb, bb->loop_father);
1588 remove_edge (single_succ_edge (bb));
1589 true_label = gimple_block_label (then_bb);
1590 stmt = gimple_build_cond (NE_EXPR, restmp,
1591 build_zero_cst (TREE_TYPE (restmp)),
1592 NULL_TREE, NULL_TREE);
1593 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1594 make_edge (bb, then_bb, EDGE_TRUE_VALUE);
1595 make_edge (bb, else_bb, EDGE_FALSE_VALUE);
1596 make_edge (return_bb, EXIT_BLOCK_PTR, 0);
1597 make_edge (then_bb, return_bb, EDGE_FALLTHRU);
1598 make_edge (else_bb, return_bb, EDGE_FALLTHRU);
1599 bsi = gsi_last_bb (then_bb);
1602 restmp = thunk_adjust (&bsi, restmp, /*this_adjusting=*/0,
1603 fixed_offset, virtual_offset);
1604 if (true_label)
1606 gimple stmt;
1607 bsi = gsi_last_bb (else_bb);
1608 stmt = gimple_build_assign (restmp,
1609 build_zero_cst (TREE_TYPE (restmp)));
1610 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1611 bsi = gsi_last_bb (return_bb);
1614 else
1615 gimple_call_set_tail (call, true);
1617 /* Build return value. */
1618 ret = gimple_build_return (restmp);
1619 gsi_insert_after (&bsi, ret, GSI_NEW_STMT);
1621 else
1623 gimple_call_set_tail (call, true);
1624 remove_edge (single_succ_edge (bb));
1627 delete_unreachable_blocks ();
1628 update_ssa (TODO_update_ssa);
1629 #ifdef ENABLE_CHECKING
1630 verify_flow_info ();
1631 #endif
1633 /* Since we want to emit the thunk, we explicitly mark its name as
1634 referenced. */
1635 node->thunk.thunk_p = false;
1636 rebuild_cgraph_edges ();
1637 cgraph_add_new_function (thunk_fndecl, true);
1638 bitmap_obstack_release (NULL);
1640 current_function_decl = NULL;
1641 set_cfun (NULL);
1644 /* Assemble thunks and aliases associated to NODE. */
1646 static void
1647 assemble_thunks_and_aliases (struct cgraph_node *node)
1649 struct cgraph_edge *e;
1650 int i;
1651 struct ipa_ref *ref;
1653 for (e = node->callers; e;)
1654 if (e->caller->thunk.thunk_p)
1656 struct cgraph_node *thunk = e->caller;
1658 e = e->next_caller;
1659 assemble_thunks_and_aliases (thunk);
1660 expand_thunk (thunk);
1662 else
1663 e = e->next_caller;
1664 for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list,
1665 i, ref); i++)
1666 if (ref->use == IPA_REF_ALIAS)
1668 struct cgraph_node *alias = ipa_ref_referring_node (ref);
1669 bool saved_written = TREE_ASM_WRITTEN (node->symbol.decl);
1671 /* Force assemble_alias to really output the alias this time instead
1672 of buffering it in same alias pairs. */
1673 TREE_ASM_WRITTEN (node->symbol.decl) = 1;
1674 do_assemble_alias (alias->symbol.decl,
1675 DECL_ASSEMBLER_NAME (node->symbol.decl));
1676 assemble_thunks_and_aliases (alias);
1677 TREE_ASM_WRITTEN (node->symbol.decl) = saved_written;
1681 /* Expand function specified by NODE. */
1683 static void
1684 expand_function (struct cgraph_node *node)
1686 tree decl = node->symbol.decl;
1687 location_t saved_loc;
1689 /* We ought to not compile any inline clones. */
1690 gcc_assert (!node->global.inlined_to);
1692 announce_function (decl);
1693 node->process = 0;
1694 gcc_assert (node->lowered);
1695 cgraph_get_body (node);
1697 /* Generate RTL for the body of DECL. */
1699 timevar_push (TV_REST_OF_COMPILATION);
1701 gcc_assert (cgraph_global_info_ready);
1703 /* Initialize the default bitmap obstack. */
1704 bitmap_obstack_initialize (NULL);
1706 /* Initialize the RTL code for the function. */
1707 current_function_decl = decl;
1708 saved_loc = input_location;
1709 input_location = DECL_SOURCE_LOCATION (decl);
1710 init_function_start (decl);
1712 gimple_register_cfg_hooks ();
1714 bitmap_obstack_initialize (&reg_obstack); /* FIXME, only at RTL generation*/
1716 execute_all_ipa_transforms ();
1718 /* Perform all tree transforms and optimizations. */
1720 /* Signal the start of passes. */
1721 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START, NULL);
1723 execute_pass_list (g->get_passes ()->all_passes);
1725 /* Signal the end of passes. */
1726 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END, NULL);
1728 bitmap_obstack_release (&reg_obstack);
1730 /* Release the default bitmap obstack. */
1731 bitmap_obstack_release (NULL);
1733 /* If requested, warn about function definitions where the function will
1734 return a value (usually of some struct or union type) which itself will
1735 take up a lot of stack space. */
1736 if (warn_larger_than && !DECL_EXTERNAL (decl) && TREE_TYPE (decl))
1738 tree ret_type = TREE_TYPE (TREE_TYPE (decl));
1740 if (ret_type && TYPE_SIZE_UNIT (ret_type)
1741 && TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST
1742 && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type),
1743 larger_than_size))
1745 unsigned int size_as_int
1746 = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type));
1748 if (compare_tree_int (TYPE_SIZE_UNIT (ret_type), size_as_int) == 0)
1749 warning (OPT_Wlarger_than_, "size of return value of %q+D is %u bytes",
1750 decl, size_as_int);
1751 else
1752 warning (OPT_Wlarger_than_, "size of return value of %q+D is larger than %wd bytes",
1753 decl, larger_than_size);
1757 gimple_set_body (decl, NULL);
1758 if (DECL_STRUCT_FUNCTION (decl) == 0
1759 && !cgraph_get_node (decl)->origin)
1761 /* Stop pointing to the local nodes about to be freed.
1762 But DECL_INITIAL must remain nonzero so we know this
1763 was an actual function definition.
1764 For a nested function, this is done in c_pop_function_context.
1765 If rest_of_compilation set this to 0, leave it 0. */
1766 if (DECL_INITIAL (decl) != 0)
1767 DECL_INITIAL (decl) = error_mark_node;
1770 input_location = saved_loc;
1772 ggc_collect ();
1773 timevar_pop (TV_REST_OF_COMPILATION);
1775 /* Make sure that BE didn't give up on compiling. */
1776 gcc_assert (TREE_ASM_WRITTEN (decl));
1777 set_cfun (NULL);
1778 current_function_decl = NULL;
1780 /* It would make a lot more sense to output thunks before function body to get more
1781 forward and lest backwarding jumps. This however would need solving problem
1782 with comdats. See PR48668. Also aliases must come after function itself to
1783 make one pass assemblers, like one on AIX, happy. See PR 50689.
1784 FIXME: Perhaps thunks should be move before function IFF they are not in comdat
1785 groups. */
1786 assemble_thunks_and_aliases (node);
1787 cgraph_release_function_body (node);
1788 /* Eliminate all call edges. This is important so the GIMPLE_CALL no longer
1789 points to the dead function body. */
1790 cgraph_node_remove_callees (node);
1791 ipa_remove_all_references (&node->symbol.ref_list);
1795 /* Expand all functions that must be output.
1797 Attempt to topologically sort the nodes so function is output when
1798 all called functions are already assembled to allow data to be
1799 propagated across the callgraph. Use a stack to get smaller distance
1800 between a function and its callees (later we may choose to use a more
1801 sophisticated algorithm for function reordering; we will likely want
1802 to use subsections to make the output functions appear in top-down
1803 order). */
1805 static void
1806 expand_all_functions (void)
1808 struct cgraph_node *node;
1809 struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
1810 int order_pos, new_order_pos = 0;
1811 int i;
1813 order_pos = ipa_reverse_postorder (order);
1814 gcc_assert (order_pos == cgraph_n_nodes);
1816 /* Garbage collector may remove inline clones we eliminate during
1817 optimization. So we must be sure to not reference them. */
1818 for (i = 0; i < order_pos; i++)
1819 if (order[i]->process)
1820 order[new_order_pos++] = order[i];
1822 for (i = new_order_pos - 1; i >= 0; i--)
1824 node = order[i];
1825 if (node->process)
1827 node->process = 0;
1828 expand_function (node);
1831 cgraph_process_new_functions ();
1833 free (order);
1837 /* This is used to sort the node types by the cgraph order number. */
1839 enum cgraph_order_sort_kind
1841 ORDER_UNDEFINED = 0,
1842 ORDER_FUNCTION,
1843 ORDER_VAR,
1844 ORDER_ASM
1847 struct cgraph_order_sort
1849 enum cgraph_order_sort_kind kind;
1850 union
1852 struct cgraph_node *f;
1853 struct varpool_node *v;
1854 struct asm_node *a;
1855 } u;
1858 /* Output all functions, variables, and asm statements in the order
1859 according to their order fields, which is the order in which they
1860 appeared in the file. This implements -fno-toplevel-reorder. In
1861 this mode we may output functions and variables which don't really
1862 need to be output. */
1864 static void
1865 output_in_order (void)
1867 int max;
1868 struct cgraph_order_sort *nodes;
1869 int i;
1870 struct cgraph_node *pf;
1871 struct varpool_node *pv;
1872 struct asm_node *pa;
1874 max = symtab_order;
1875 nodes = XCNEWVEC (struct cgraph_order_sort, max);
1877 FOR_EACH_DEFINED_FUNCTION (pf)
1879 if (pf->process && !pf->thunk.thunk_p && !pf->symbol.alias)
1881 i = pf->symbol.order;
1882 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1883 nodes[i].kind = ORDER_FUNCTION;
1884 nodes[i].u.f = pf;
1888 FOR_EACH_DEFINED_VARIABLE (pv)
1889 if (!DECL_EXTERNAL (pv->symbol.decl))
1891 i = pv->symbol.order;
1892 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1893 nodes[i].kind = ORDER_VAR;
1894 nodes[i].u.v = pv;
1897 for (pa = asm_nodes; pa; pa = pa->next)
1899 i = pa->order;
1900 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1901 nodes[i].kind = ORDER_ASM;
1902 nodes[i].u.a = pa;
1905 /* In toplevel reorder mode we output all statics; mark them as needed. */
1907 for (i = 0; i < max; ++i)
1908 if (nodes[i].kind == ORDER_VAR)
1909 varpool_finalize_named_section_flags (nodes[i].u.v);
1911 for (i = 0; i < max; ++i)
1913 switch (nodes[i].kind)
1915 case ORDER_FUNCTION:
1916 nodes[i].u.f->process = 0;
1917 expand_function (nodes[i].u.f);
1918 break;
1920 case ORDER_VAR:
1921 varpool_assemble_decl (nodes[i].u.v);
1922 break;
1924 case ORDER_ASM:
1925 assemble_asm (nodes[i].u.a->asm_str);
1926 break;
1928 case ORDER_UNDEFINED:
1929 break;
1931 default:
1932 gcc_unreachable ();
1936 asm_nodes = NULL;
1937 free (nodes);
1940 static void
1941 ipa_passes (void)
1943 gcc::pass_manager *passes = g->get_passes ();
1945 set_cfun (NULL);
1946 current_function_decl = NULL;
1947 gimple_register_cfg_hooks ();
1948 bitmap_obstack_initialize (NULL);
1950 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START, NULL);
1952 if (!in_lto_p)
1954 execute_ipa_pass_list (passes->all_small_ipa_passes);
1955 if (seen_error ())
1956 return;
1959 /* We never run removal of unreachable nodes after early passes. This is
1960 because TODO is run before the subpasses. It is important to remove
1961 the unreachable functions to save works at IPA level and to get LTO
1962 symbol tables right. */
1963 symtab_remove_unreachable_nodes (true, cgraph_dump_file);
1965 /* If pass_all_early_optimizations was not scheduled, the state of
1966 the cgraph will not be properly updated. Update it now. */
1967 if (cgraph_state < CGRAPH_STATE_IPA_SSA)
1968 cgraph_state = CGRAPH_STATE_IPA_SSA;
1970 if (!in_lto_p)
1972 /* Generate coverage variables and constructors. */
1973 coverage_finish ();
1975 /* Process new functions added. */
1976 set_cfun (NULL);
1977 current_function_decl = NULL;
1978 cgraph_process_new_functions ();
1980 execute_ipa_summary_passes
1981 ((struct ipa_opt_pass_d *) passes->all_regular_ipa_passes);
1984 /* Some targets need to handle LTO assembler output specially. */
1985 if (flag_generate_lto)
1986 targetm.asm_out.lto_start ();
1988 execute_ipa_summary_passes ((struct ipa_opt_pass_d *)
1989 passes->all_lto_gen_passes);
1991 if (!in_lto_p)
1992 ipa_write_summaries ();
1994 if (flag_generate_lto)
1995 targetm.asm_out.lto_end ();
1997 if (!flag_ltrans && (in_lto_p || !flag_lto || flag_fat_lto_objects))
1998 execute_ipa_pass_list (passes->all_regular_ipa_passes);
1999 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END, NULL);
2001 bitmap_obstack_release (NULL);
2005 /* Return string alias is alias of. */
2007 static tree
2008 get_alias_symbol (tree decl)
2010 tree alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
2011 return get_identifier (TREE_STRING_POINTER
2012 (TREE_VALUE (TREE_VALUE (alias))));
2016 /* Weakrefs may be associated to external decls and thus not output
2017 at expansion time. Emit all necessary aliases. */
2019 static void
2020 output_weakrefs (void)
2022 symtab_node node;
2023 FOR_EACH_SYMBOL (node)
2024 if (node->symbol.alias
2025 && !TREE_ASM_WRITTEN (node->symbol.decl)
2026 && node->symbol.weakref)
2028 tree target;
2030 /* Weakrefs are special by not requiring target definition in current
2031 compilation unit. It is thus bit hard to work out what we want to
2032 alias.
2033 When alias target is defined, we need to fetch it from symtab reference,
2034 otherwise it is pointed to by alias_target. */
2035 if (node->symbol.alias_target)
2036 target = (DECL_P (node->symbol.alias_target)
2037 ? DECL_ASSEMBLER_NAME (node->symbol.alias_target)
2038 : node->symbol.alias_target);
2039 else if (node->symbol.analyzed)
2040 target = DECL_ASSEMBLER_NAME (symtab_alias_target (node)->symbol.decl);
2041 else
2043 gcc_unreachable ();
2044 target = get_alias_symbol (node->symbol.decl);
2046 do_assemble_alias (node->symbol.decl, target);
2050 /* Initialize callgraph dump file. */
2052 void
2053 init_cgraph (void)
2055 if (!cgraph_dump_file)
2056 cgraph_dump_file = dump_begin (TDI_cgraph, NULL);
2060 /* Perform simple optimizations based on callgraph. */
2062 void
2063 compile (void)
2065 if (seen_error ())
2066 return;
2068 #ifdef ENABLE_CHECKING
2069 verify_symtab ();
2070 #endif
2072 timevar_push (TV_CGRAPHOPT);
2073 if (pre_ipa_mem_report)
2075 fprintf (stderr, "Memory consumption before IPA\n");
2076 dump_memory_report (false);
2078 if (!quiet_flag)
2079 fprintf (stderr, "Performing interprocedural optimizations\n");
2080 cgraph_state = CGRAPH_STATE_IPA;
2082 /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE. */
2083 if (flag_lto)
2084 lto_streamer_hooks_init ();
2086 /* Don't run the IPA passes if there was any error or sorry messages. */
2087 if (!seen_error ())
2088 ipa_passes ();
2090 /* Do nothing else if any IPA pass found errors or if we are just streaming LTO. */
2091 if (seen_error ()
2092 || (!in_lto_p && flag_lto && !flag_fat_lto_objects))
2094 timevar_pop (TV_CGRAPHOPT);
2095 return;
2098 /* This pass remove bodies of extern inline functions we never inlined.
2099 Do this later so other IPA passes see what is really going on. */
2100 symtab_remove_unreachable_nodes (false, dump_file);
2101 cgraph_global_info_ready = true;
2102 if (cgraph_dump_file)
2104 fprintf (cgraph_dump_file, "Optimized ");
2105 dump_symtab (cgraph_dump_file);
2107 if (post_ipa_mem_report)
2109 fprintf (stderr, "Memory consumption after IPA\n");
2110 dump_memory_report (false);
2112 timevar_pop (TV_CGRAPHOPT);
2114 /* Output everything. */
2115 (*debug_hooks->assembly_start) ();
2116 if (!quiet_flag)
2117 fprintf (stderr, "Assembling functions:\n");
2118 #ifdef ENABLE_CHECKING
2119 verify_symtab ();
2120 #endif
2122 cgraph_materialize_all_clones ();
2123 bitmap_obstack_initialize (NULL);
2124 execute_ipa_pass_list (g->get_passes ()->all_late_ipa_passes);
2125 symtab_remove_unreachable_nodes (true, dump_file);
2126 #ifdef ENABLE_CHECKING
2127 verify_symtab ();
2128 #endif
2129 bitmap_obstack_release (NULL);
2130 mark_functions_to_output ();
2132 /* When weakref support is missing, we autmatically translate all
2133 references to NODE to references to its ultimate alias target.
2134 The renaming mechanizm uses flag IDENTIFIER_TRANSPARENT_ALIAS and
2135 TREE_CHAIN.
2137 Set up this mapping before we output any assembler but once we are sure
2138 that all symbol renaming is done.
2140 FIXME: All this uglyness can go away if we just do renaming at gimple
2141 level by physically rewritting the IL. At the moment we can only redirect
2142 calls, so we need infrastructure for renaming references as well. */
2143 #ifndef ASM_OUTPUT_WEAKREF
2144 symtab_node node;
2146 FOR_EACH_SYMBOL (node)
2147 if (node->symbol.alias
2148 && lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
2150 IDENTIFIER_TRANSPARENT_ALIAS
2151 (DECL_ASSEMBLER_NAME (node->symbol.decl)) = 1;
2152 TREE_CHAIN (DECL_ASSEMBLER_NAME (node->symbol.decl))
2153 = (node->symbol.alias_target ? node->symbol.alias_target
2154 : DECL_ASSEMBLER_NAME (symtab_alias_target (node)->symbol.decl));
2156 #endif
2158 cgraph_state = CGRAPH_STATE_EXPANSION;
2159 if (!flag_toplevel_reorder)
2160 output_in_order ();
2161 else
2163 output_asm_statements ();
2165 expand_all_functions ();
2166 varpool_output_variables ();
2169 cgraph_process_new_functions ();
2170 cgraph_state = CGRAPH_STATE_FINISHED;
2171 output_weakrefs ();
2173 if (cgraph_dump_file)
2175 fprintf (cgraph_dump_file, "\nFinal ");
2176 dump_symtab (cgraph_dump_file);
2178 #ifdef ENABLE_CHECKING
2179 verify_symtab ();
2180 /* Double check that all inline clones are gone and that all
2181 function bodies have been released from memory. */
2182 if (!seen_error ())
2184 struct cgraph_node *node;
2185 bool error_found = false;
2187 FOR_EACH_DEFINED_FUNCTION (node)
2188 if (node->global.inlined_to
2189 || gimple_has_body_p (node->symbol.decl))
2191 error_found = true;
2192 dump_cgraph_node (stderr, node);
2194 if (error_found)
2195 internal_error ("nodes with unreleased memory found");
2197 #endif
2201 /* Analyze the whole compilation unit once it is parsed completely. */
2203 void
2204 finalize_compilation_unit (void)
2206 timevar_push (TV_CGRAPH);
2208 /* If we're here there's no current function anymore. Some frontends
2209 are lazy in clearing these. */
2210 current_function_decl = NULL;
2211 set_cfun (NULL);
2213 /* Do not skip analyzing the functions if there were errors, we
2214 miss diagnostics for following functions otherwise. */
2216 /* Emit size functions we didn't inline. */
2217 finalize_size_functions ();
2219 /* Mark alias targets necessary and emit diagnostics. */
2220 handle_alias_pairs ();
2222 if (!quiet_flag)
2224 fprintf (stderr, "\nAnalyzing compilation unit\n");
2225 fflush (stderr);
2228 if (flag_dump_passes)
2229 dump_passes ();
2231 /* Gimplify and lower all functions, compute reachability and
2232 remove unreachable nodes. */
2233 analyze_functions ();
2235 /* Mark alias targets necessary and emit diagnostics. */
2236 handle_alias_pairs ();
2238 /* Gimplify and lower thunks. */
2239 analyze_functions ();
2241 /* Finally drive the pass manager. */
2242 compile ();
2244 timevar_pop (TV_CGRAPH);
2248 #include "gt-cgraphunit.h"