vectorizer cost model enhancement
[official-gcc.git] / gcc / cgraphunit.c
blob1644ca9eea9579b8eec35ae080cf99d434c4c962
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->thunk.thunk_p)
597 cgraph_create_edge (node, cgraph_get_node (node->thunk.alias),
598 NULL, 0, CGRAPH_FREQ_BASE);
599 if (!expand_thunk (node, false))
601 node->thunk.alias = NULL;
602 node->symbol.analyzed = true;
603 return;
605 node->thunk.alias = NULL;
607 if (node->symbol.alias)
608 symtab_resolve_alias
609 ((symtab_node) node, (symtab_node) cgraph_get_node (node->symbol.alias_target));
610 else if (node->dispatcher_function)
612 /* Generate the dispatcher body of multi-versioned functions. */
613 struct cgraph_function_version_info *dispatcher_version_info
614 = get_cgraph_node_version (node);
615 if (dispatcher_version_info != NULL
616 && (dispatcher_version_info->dispatcher_resolver
617 == NULL_TREE))
619 tree resolver = NULL_TREE;
620 gcc_assert (targetm.generate_version_dispatcher_body);
621 resolver = targetm.generate_version_dispatcher_body (node);
622 gcc_assert (resolver != NULL_TREE);
625 else
627 push_cfun (DECL_STRUCT_FUNCTION (decl));
629 assign_assembler_name_if_neeeded (node->symbol.decl);
631 /* Make sure to gimplify bodies only once. During analyzing a
632 function we lower it, which will require gimplified nested
633 functions, so we can end up here with an already gimplified
634 body. */
635 if (!gimple_has_body_p (decl))
636 gimplify_function_tree (decl);
637 dump_function (TDI_generic, decl);
639 /* Lower the function. */
640 if (!node->lowered)
642 if (node->nested)
643 lower_nested_functions (node->symbol.decl);
644 gcc_assert (!node->nested);
646 gimple_register_cfg_hooks ();
647 bitmap_obstack_initialize (NULL);
648 execute_pass_list (g->get_passes ()->all_lowering_passes);
649 free_dominance_info (CDI_POST_DOMINATORS);
650 free_dominance_info (CDI_DOMINATORS);
651 compact_blocks ();
652 bitmap_obstack_release (NULL);
653 node->lowered = true;
656 pop_cfun ();
658 node->symbol.analyzed = true;
660 input_location = saved_loc;
663 /* C++ frontend produce same body aliases all over the place, even before PCH
664 gets streamed out. It relies on us linking the aliases with their function
665 in order to do the fixups, but ipa-ref is not PCH safe. Consequentely we
666 first produce aliases without links, but once C++ FE is sure he won't sream
667 PCH we build the links via this function. */
669 void
670 cgraph_process_same_body_aliases (void)
672 symtab_node node;
673 FOR_EACH_SYMBOL (node)
674 if (node->symbol.cpp_implicit_alias && !node->symbol.analyzed)
675 symtab_resolve_alias
676 (node,
677 TREE_CODE (node->symbol.alias_target) == VAR_DECL
678 ? (symtab_node)varpool_node_for_decl (node->symbol.alias_target)
679 : (symtab_node)cgraph_get_create_node (node->symbol.alias_target));
680 cpp_implicit_aliases_done = true;
683 /* Process attributes common for vars and functions. */
685 static void
686 process_common_attributes (tree decl)
688 tree weakref = lookup_attribute ("weakref", DECL_ATTRIBUTES (decl));
690 if (weakref && !lookup_attribute ("alias", DECL_ATTRIBUTES (decl)))
692 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
693 "%<weakref%> attribute should be accompanied with"
694 " an %<alias%> attribute");
695 DECL_WEAK (decl) = 0;
696 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
697 DECL_ATTRIBUTES (decl));
701 /* Look for externally_visible and used attributes and mark cgraph nodes
702 accordingly.
704 We cannot mark the nodes at the point the attributes are processed (in
705 handle_*_attribute) because the copy of the declarations available at that
706 point may not be canonical. For example, in:
708 void f();
709 void f() __attribute__((used));
711 the declaration we see in handle_used_attribute will be the second
712 declaration -- but the front end will subsequently merge that declaration
713 with the original declaration and discard the second declaration.
715 Furthermore, we can't mark these nodes in cgraph_finalize_function because:
717 void f() {}
718 void f() __attribute__((externally_visible));
720 is valid.
722 So, we walk the nodes at the end of the translation unit, applying the
723 attributes at that point. */
725 static void
726 process_function_and_variable_attributes (struct cgraph_node *first,
727 struct varpool_node *first_var)
729 struct cgraph_node *node;
730 struct varpool_node *vnode;
732 for (node = cgraph_first_function (); node != first;
733 node = cgraph_next_function (node))
735 tree decl = node->symbol.decl;
736 if (DECL_PRESERVE_P (decl))
737 cgraph_mark_force_output_node (node);
738 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
740 if (! TREE_PUBLIC (node->symbol.decl))
741 warning_at (DECL_SOURCE_LOCATION (node->symbol.decl), OPT_Wattributes,
742 "%<externally_visible%>"
743 " attribute have effect only on public objects");
745 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
746 && (node->symbol.definition && !node->symbol.alias))
748 warning_at (DECL_SOURCE_LOCATION (node->symbol.decl), OPT_Wattributes,
749 "%<weakref%> attribute ignored"
750 " because function is defined");
751 DECL_WEAK (decl) = 0;
752 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
753 DECL_ATTRIBUTES (decl));
756 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl))
757 && !DECL_DECLARED_INLINE_P (decl)
758 /* redefining extern inline function makes it DECL_UNINLINABLE. */
759 && !DECL_UNINLINABLE (decl))
760 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
761 "always_inline function might not be inlinable");
763 process_common_attributes (decl);
765 for (vnode = varpool_first_variable (); vnode != first_var;
766 vnode = varpool_next_variable (vnode))
768 tree decl = vnode->symbol.decl;
769 if (DECL_EXTERNAL (decl)
770 && DECL_INITIAL (decl))
771 varpool_finalize_decl (decl);
772 if (DECL_PRESERVE_P (decl))
773 vnode->symbol.force_output = true;
774 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
776 if (! TREE_PUBLIC (vnode->symbol.decl))
777 warning_at (DECL_SOURCE_LOCATION (vnode->symbol.decl), OPT_Wattributes,
778 "%<externally_visible%>"
779 " attribute have effect only on public objects");
781 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
782 && vnode->symbol.definition
783 && DECL_INITIAL (decl))
785 warning_at (DECL_SOURCE_LOCATION (vnode->symbol.decl), OPT_Wattributes,
786 "%<weakref%> attribute ignored"
787 " because variable is initialized");
788 DECL_WEAK (decl) = 0;
789 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
790 DECL_ATTRIBUTES (decl));
792 process_common_attributes (decl);
796 /* Mark DECL as finalized. By finalizing the declaration, frontend instruct the
797 middle end to output the variable to asm file, if needed or externally
798 visible. */
800 void
801 varpool_finalize_decl (tree decl)
803 struct varpool_node *node = varpool_node_for_decl (decl);
805 gcc_assert (TREE_STATIC (decl) || DECL_EXTERNAL (decl));
807 if (node->symbol.definition)
808 return;
809 notice_global_symbol (decl);
810 node->symbol.definition = true;
811 if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
812 /* Traditionally we do not eliminate static variables when not
813 optimizing and when not doing toplevel reoder. */
814 || (!flag_toplevel_reorder && !DECL_COMDAT (node->symbol.decl)
815 && !DECL_ARTIFICIAL (node->symbol.decl)))
816 node->symbol.force_output = true;
818 if (cgraph_state == CGRAPH_STATE_CONSTRUCTION
819 && (decide_is_symbol_needed ((symtab_node) node)
820 || referred_to_p ((symtab_node)node)))
821 enqueue_node ((symtab_node)node);
822 if (cgraph_state >= CGRAPH_STATE_IPA_SSA)
823 varpool_analyze_node (node);
824 /* Some frontends produce various interface variables after compilation
825 finished. */
826 if (cgraph_state == CGRAPH_STATE_FINISHED)
827 varpool_assemble_decl (node);
830 /* EDGE is an polymorphic call. Mark all possible targets as reachable
831 and if there is only one target, perform trivial devirtualization.
832 REACHABLE_CALL_TARGETS collects target lists we already walked to
833 avoid udplicate work. */
835 static void
836 walk_polymorphic_call_targets (pointer_set_t *reachable_call_targets,
837 struct cgraph_edge *edge)
839 unsigned int i;
840 void *cache_token;
841 bool final;
842 vec <cgraph_node *>targets
843 = possible_polymorphic_call_targets
844 (edge, &final, &cache_token);
846 if (!pointer_set_insert (reachable_call_targets,
847 cache_token))
849 if (cgraph_dump_file)
850 dump_possible_polymorphic_call_targets
851 (cgraph_dump_file, edge);
853 for (i = 0; i < targets.length(); i++)
855 /* Do not bother to mark virtual methods in anonymous namespace;
856 either we will find use of virtual table defining it, or it is
857 unused. */
858 if (targets[i]->symbol.definition
859 && TREE_CODE
860 (TREE_TYPE (targets[i]->symbol.decl))
861 == METHOD_TYPE
862 && !type_in_anonymous_namespace_p
863 (method_class_type
864 (TREE_TYPE (targets[i]->symbol.decl))))
865 enqueue_node ((symtab_node) targets[i]);
869 /* Very trivial devirtualization; when the type is
870 final or anonymous (so we know all its derivation)
871 and there is only one possible virtual call target,
872 make the edge direct. */
873 if (final)
875 if (targets.length() <= 1)
877 cgraph_node *target;
878 if (targets.length () == 1)
879 target = targets[0];
880 else
881 target = cgraph_get_create_node
882 (builtin_decl_implicit (BUILT_IN_UNREACHABLE));
884 if (cgraph_dump_file)
886 fprintf (cgraph_dump_file,
887 "Devirtualizing call: ");
888 print_gimple_stmt (cgraph_dump_file,
889 edge->call_stmt, 0,
890 TDF_SLIM);
892 cgraph_make_edge_direct (edge, target);
893 cgraph_redirect_edge_call_stmt_to_callee (edge);
894 if (cgraph_dump_file)
896 fprintf (cgraph_dump_file,
897 "Devirtualized as: ");
898 print_gimple_stmt (cgraph_dump_file,
899 edge->call_stmt, 0,
900 TDF_SLIM);
907 /* Discover all functions and variables that are trivially needed, analyze
908 them as well as all functions and variables referred by them */
910 static void
911 analyze_functions (void)
913 /* Keep track of already processed nodes when called multiple times for
914 intermodule optimization. */
915 static struct cgraph_node *first_analyzed;
916 struct cgraph_node *first_handled = first_analyzed;
917 static struct varpool_node *first_analyzed_var;
918 struct varpool_node *first_handled_var = first_analyzed_var;
919 struct pointer_set_t *reachable_call_targets = pointer_set_create ();
921 symtab_node node, next;
922 int i;
923 struct ipa_ref *ref;
924 bool changed = true;
925 location_t saved_loc = input_location;
927 bitmap_obstack_initialize (NULL);
928 cgraph_state = CGRAPH_STATE_CONSTRUCTION;
929 input_location = UNKNOWN_LOCATION;
931 /* Ugly, but the fixup can not happen at a time same body alias is created;
932 C++ FE is confused about the COMDAT groups being right. */
933 if (cpp_implicit_aliases_done)
934 FOR_EACH_SYMBOL (node)
935 if (node->symbol.cpp_implicit_alias)
936 fixup_same_cpp_alias_visibility (node, symtab_alias_target (node));
937 if (optimize && flag_devirtualize)
938 build_type_inheritance_graph ();
940 /* Analysis adds static variables that in turn adds references to new functions.
941 So we need to iterate the process until it stabilize. */
942 while (changed)
944 changed = false;
945 process_function_and_variable_attributes (first_analyzed,
946 first_analyzed_var);
948 /* First identify the trivially needed symbols. */
949 for (node = symtab_nodes;
950 node != (symtab_node)first_analyzed
951 && node != (symtab_node)first_analyzed_var; node = node->symbol.next)
953 if (decide_is_symbol_needed (node))
955 enqueue_node (node);
956 if (!changed && cgraph_dump_file)
957 fprintf (cgraph_dump_file, "Trivially needed symbols:");
958 changed = true;
959 if (cgraph_dump_file)
960 fprintf (cgraph_dump_file, " %s", symtab_node_asm_name (node));
961 if (!changed && cgraph_dump_file)
962 fprintf (cgraph_dump_file, "\n");
964 if (node == (symtab_node)first_analyzed
965 || node == (symtab_node)first_analyzed_var)
966 break;
968 cgraph_process_new_functions ();
969 first_analyzed_var = varpool_first_variable ();
970 first_analyzed = cgraph_first_function ();
972 if (changed && dump_file)
973 fprintf (cgraph_dump_file, "\n");
975 /* Lower representation, build callgraph edges and references for all trivially
976 needed symbols and all symbols referred by them. */
977 while (first != (symtab_node)(void *)1)
979 changed = true;
980 node = first;
981 first = (symtab_node)first->symbol.aux;
982 cgraph_node *cnode = dyn_cast <cgraph_node> (node);
983 if (cnode && cnode->symbol.definition)
985 struct cgraph_edge *edge;
986 tree decl = cnode->symbol.decl;
988 /* ??? It is possible to create extern inline function
989 and later using weak alias attribute to kill its body.
990 See gcc.c-torture/compile/20011119-1.c */
991 if (!DECL_STRUCT_FUNCTION (decl)
992 && !cnode->symbol.alias
993 && !cnode->thunk.thunk_p
994 && !cnode->dispatcher_function)
996 cgraph_reset_node (cnode);
997 cnode->local.redefined_extern_inline = true;
998 continue;
1001 if (!cnode->symbol.analyzed)
1002 analyze_function (cnode);
1004 for (edge = cnode->callees; edge; edge = edge->next_callee)
1005 if (edge->callee->symbol.definition)
1006 enqueue_node ((symtab_node)edge->callee);
1007 if (optimize && flag_devirtualize)
1009 struct cgraph_edge *next;
1011 for (edge = cnode->indirect_calls; edge; edge = next)
1013 next = edge->next_callee;
1014 if (edge->indirect_info->polymorphic)
1015 walk_polymorphic_call_targets (reachable_call_targets,
1016 edge);
1020 /* If decl is a clone of an abstract function,
1021 mark that abstract function so that we don't release its body.
1022 The DECL_INITIAL() of that abstract function declaration
1023 will be later needed to output debug info. */
1024 if (DECL_ABSTRACT_ORIGIN (decl))
1026 struct cgraph_node *origin_node
1027 = cgraph_get_node (DECL_ABSTRACT_ORIGIN (decl));
1028 origin_node->used_as_abstract_origin = true;
1031 else
1033 varpool_node *vnode = dyn_cast <varpool_node> (node);
1034 if (vnode && vnode->symbol.definition && !vnode->symbol.analyzed)
1035 varpool_analyze_node (vnode);
1038 if (node->symbol.same_comdat_group)
1040 symtab_node next;
1041 for (next = node->symbol.same_comdat_group;
1042 next != node;
1043 next = next->symbol.same_comdat_group)
1044 enqueue_node (next);
1046 for (i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list, i, ref); i++)
1047 if (ref->referred->symbol.definition)
1048 enqueue_node (ref->referred);
1049 cgraph_process_new_functions ();
1052 if (optimize && flag_devirtualize)
1053 update_type_inheritance_graph ();
1055 /* Collect entry points to the unit. */
1056 if (cgraph_dump_file)
1058 fprintf (cgraph_dump_file, "\n\nInitial ");
1059 dump_symtab (cgraph_dump_file);
1062 if (cgraph_dump_file)
1063 fprintf (cgraph_dump_file, "\nRemoving unused symbols:");
1065 for (node = symtab_nodes;
1066 node != (symtab_node)first_handled
1067 && node != (symtab_node)first_handled_var; node = next)
1069 next = node->symbol.next;
1070 if (!node->symbol.aux && !referred_to_p (node))
1072 if (cgraph_dump_file)
1073 fprintf (cgraph_dump_file, " %s", symtab_node_name (node));
1074 symtab_remove_node (node);
1075 continue;
1077 if (cgraph_node *cnode = dyn_cast <cgraph_node> (node))
1079 tree decl = node->symbol.decl;
1081 if (cnode->symbol.definition && !gimple_has_body_p (decl)
1082 && !cnode->symbol.alias
1083 && !cnode->thunk.thunk_p)
1084 cgraph_reset_node (cnode);
1086 gcc_assert (!cnode->symbol.definition || cnode->thunk.thunk_p
1087 || cnode->symbol.alias
1088 || gimple_has_body_p (decl));
1089 gcc_assert (cnode->symbol.analyzed == cnode->symbol.definition);
1091 node->symbol.aux = NULL;
1093 for (;node; node = node->symbol.next)
1094 node->symbol.aux = NULL;
1095 first_analyzed = cgraph_first_function ();
1096 first_analyzed_var = varpool_first_variable ();
1097 if (cgraph_dump_file)
1099 fprintf (cgraph_dump_file, "\n\nReclaimed ");
1100 dump_symtab (cgraph_dump_file);
1102 bitmap_obstack_release (NULL);
1103 pointer_set_destroy (reachable_call_targets);
1104 ggc_collect ();
1105 /* Initialize assembler name hash, in particular we want to trigger C++
1106 mangling and same body alias creation before we free DECL_ARGUMENTS
1107 used by it. */
1108 if (!seen_error ())
1109 symtab_initialize_asm_name_hash ();
1111 input_location = saved_loc;
1114 /* Translate the ugly representation of aliases as alias pairs into nice
1115 representation in callgraph. We don't handle all cases yet,
1116 unfortunately. */
1118 static void
1119 handle_alias_pairs (void)
1121 alias_pair *p;
1122 unsigned i;
1124 for (i = 0; alias_pairs && alias_pairs->iterate (i, &p);)
1126 symtab_node target_node = symtab_node_for_asm (p->target);
1128 /* Weakrefs with target not defined in current unit are easy to handle:
1129 they behave just as external variables except we need to note the
1130 alias flag to later output the weakref pseudo op into asm file. */
1131 if (!target_node
1132 && lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL)
1134 symtab_node node = symtab_get_node (p->decl);
1135 if (node)
1137 node->symbol.alias_target = p->target;
1138 node->symbol.weakref = true;
1139 node->symbol.alias = true;
1141 alias_pairs->unordered_remove (i);
1142 continue;
1144 else if (!target_node)
1146 error ("%q+D aliased to undefined symbol %qE", p->decl, p->target);
1147 symtab_node node = symtab_get_node (p->decl);
1148 if (node)
1149 node->symbol.alias = false;
1150 alias_pairs->unordered_remove (i);
1151 continue;
1154 if (DECL_EXTERNAL (target_node->symbol.decl)
1155 /* We use local aliases for C++ thunks to force the tailcall
1156 to bind locally. This is a hack - to keep it working do
1157 the following (which is not strictly correct). */
1158 && (! TREE_CODE (target_node->symbol.decl) == FUNCTION_DECL
1159 || ! DECL_VIRTUAL_P (target_node->symbol.decl))
1160 && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)))
1162 error ("%q+D aliased to external symbol %qE",
1163 p->decl, p->target);
1166 if (TREE_CODE (p->decl) == FUNCTION_DECL
1167 && target_node && is_a <cgraph_node> (target_node))
1169 struct cgraph_node *src_node = cgraph_get_node (p->decl);
1170 if (src_node && src_node->symbol.definition)
1171 cgraph_reset_node (src_node);
1172 cgraph_create_function_alias (p->decl, target_node->symbol.decl);
1173 alias_pairs->unordered_remove (i);
1175 else if (TREE_CODE (p->decl) == VAR_DECL
1176 && target_node && is_a <varpool_node> (target_node))
1178 varpool_create_variable_alias (p->decl, target_node->symbol.decl);
1179 alias_pairs->unordered_remove (i);
1181 else
1183 error ("%q+D alias in between function and variable is not supported",
1184 p->decl);
1185 warning (0, "%q+D aliased declaration",
1186 target_node->symbol.decl);
1187 alias_pairs->unordered_remove (i);
1190 vec_free (alias_pairs);
1194 /* Figure out what functions we want to assemble. */
1196 static void
1197 mark_functions_to_output (void)
1199 struct cgraph_node *node;
1200 #ifdef ENABLE_CHECKING
1201 bool check_same_comdat_groups = false;
1203 FOR_EACH_FUNCTION (node)
1204 gcc_assert (!node->process);
1205 #endif
1207 FOR_EACH_FUNCTION (node)
1209 tree decl = node->symbol.decl;
1211 gcc_assert (!node->process || node->symbol.same_comdat_group);
1212 if (node->process)
1213 continue;
1215 /* We need to output all local functions that are used and not
1216 always inlined, as well as those that are reachable from
1217 outside the current compilation unit. */
1218 if (node->symbol.analyzed
1219 && !node->thunk.thunk_p
1220 && !node->symbol.alias
1221 && !node->global.inlined_to
1222 && !TREE_ASM_WRITTEN (decl)
1223 && !DECL_EXTERNAL (decl))
1225 node->process = 1;
1226 if (node->symbol.same_comdat_group)
1228 struct cgraph_node *next;
1229 for (next = cgraph (node->symbol.same_comdat_group);
1230 next != node;
1231 next = cgraph (next->symbol.same_comdat_group))
1232 if (!next->thunk.thunk_p && !next->symbol.alias)
1233 next->process = 1;
1236 else if (node->symbol.same_comdat_group)
1238 #ifdef ENABLE_CHECKING
1239 check_same_comdat_groups = true;
1240 #endif
1242 else
1244 /* We should've reclaimed all functions that are not needed. */
1245 #ifdef ENABLE_CHECKING
1246 if (!node->global.inlined_to
1247 && gimple_has_body_p (decl)
1248 /* FIXME: in ltrans unit when offline copy is outside partition but inline copies
1249 are inside partition, we can end up not removing the body since we no longer
1250 have analyzed node pointing to it. */
1251 && !node->symbol.in_other_partition
1252 && !node->symbol.alias
1253 && !node->clones
1254 && !DECL_EXTERNAL (decl))
1256 dump_cgraph_node (stderr, node);
1257 internal_error ("failed to reclaim unneeded function");
1259 #endif
1260 gcc_assert (node->global.inlined_to
1261 || !gimple_has_body_p (decl)
1262 || node->symbol.in_other_partition
1263 || node->clones
1264 || DECL_ARTIFICIAL (decl)
1265 || DECL_EXTERNAL (decl));
1270 #ifdef ENABLE_CHECKING
1271 if (check_same_comdat_groups)
1272 FOR_EACH_FUNCTION (node)
1273 if (node->symbol.same_comdat_group && !node->process)
1275 tree decl = node->symbol.decl;
1276 if (!node->global.inlined_to
1277 && gimple_has_body_p (decl)
1278 /* FIXME: in an ltrans unit when the offline copy is outside a
1279 partition but inline copies are inside a partition, we can
1280 end up not removing the body since we no longer have an
1281 analyzed node pointing to it. */
1282 && !node->symbol.in_other_partition
1283 && !node->clones
1284 && !DECL_EXTERNAL (decl))
1286 dump_cgraph_node (stderr, node);
1287 internal_error ("failed to reclaim unneeded function in same "
1288 "comdat group");
1291 #endif
1294 /* DECL is FUNCTION_DECL. Initialize datastructures so DECL is a function
1295 in lowered gimple form. IN_SSA is true if the gimple is in SSA.
1297 Set current_function_decl and cfun to newly constructed empty function body.
1298 return basic block in the function body. */
1300 basic_block
1301 init_lowered_empty_function (tree decl, bool in_ssa)
1303 basic_block bb;
1305 current_function_decl = decl;
1306 allocate_struct_function (decl, false);
1307 gimple_register_cfg_hooks ();
1308 init_empty_tree_cfg ();
1310 if (in_ssa)
1312 init_tree_ssa (cfun);
1313 init_ssa_operands (cfun);
1314 cfun->gimple_df->in_ssa_p = true;
1315 cfun->curr_properties |= PROP_ssa;
1318 DECL_INITIAL (decl) = make_node (BLOCK);
1320 DECL_SAVED_TREE (decl) = error_mark_node;
1321 cfun->curr_properties |= (PROP_gimple_lcf | PROP_gimple_leh | PROP_gimple_any
1322 | PROP_cfg | PROP_loops);
1324 set_loops_for_fn (cfun, ggc_alloc_cleared_loops ());
1325 init_loops_structure (cfun, loops_for_fn (cfun), 1);
1326 loops_for_fn (cfun)->state |= LOOPS_MAY_HAVE_MULTIPLE_LATCHES;
1328 /* Create BB for body of the function and connect it properly. */
1329 bb = create_basic_block (NULL, (void *) 0, ENTRY_BLOCK_PTR);
1330 make_edge (ENTRY_BLOCK_PTR, bb, EDGE_FALLTHRU);
1331 make_edge (bb, EXIT_BLOCK_PTR, 0);
1332 add_bb_to_loop (bb, ENTRY_BLOCK_PTR->loop_father);
1334 return bb;
1337 /* Adjust PTR by the constant FIXED_OFFSET, and by the vtable
1338 offset indicated by VIRTUAL_OFFSET, if that is
1339 non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and
1340 zero for a result adjusting thunk. */
1342 static tree
1343 thunk_adjust (gimple_stmt_iterator * bsi,
1344 tree ptr, bool this_adjusting,
1345 HOST_WIDE_INT fixed_offset, tree virtual_offset)
1347 gimple stmt;
1348 tree ret;
1350 if (this_adjusting
1351 && fixed_offset != 0)
1353 stmt = gimple_build_assign
1354 (ptr, fold_build_pointer_plus_hwi_loc (input_location,
1355 ptr,
1356 fixed_offset));
1357 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1360 /* If there's a virtual offset, look up that value in the vtable and
1361 adjust the pointer again. */
1362 if (virtual_offset)
1364 tree vtabletmp;
1365 tree vtabletmp2;
1366 tree vtabletmp3;
1368 if (!vtable_entry_type)
1370 tree vfunc_type = make_node (FUNCTION_TYPE);
1371 TREE_TYPE (vfunc_type) = integer_type_node;
1372 TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
1373 layout_type (vfunc_type);
1375 vtable_entry_type = build_pointer_type (vfunc_type);
1378 vtabletmp =
1379 create_tmp_reg (build_pointer_type
1380 (build_pointer_type (vtable_entry_type)), "vptr");
1382 /* The vptr is always at offset zero in the object. */
1383 stmt = gimple_build_assign (vtabletmp,
1384 build1 (NOP_EXPR, TREE_TYPE (vtabletmp),
1385 ptr));
1386 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1388 /* Form the vtable address. */
1389 vtabletmp2 = create_tmp_reg (TREE_TYPE (TREE_TYPE (vtabletmp)),
1390 "vtableaddr");
1391 stmt = gimple_build_assign (vtabletmp2,
1392 build_simple_mem_ref (vtabletmp));
1393 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1395 /* Find the entry with the vcall offset. */
1396 stmt = gimple_build_assign (vtabletmp2,
1397 fold_build_pointer_plus_loc (input_location,
1398 vtabletmp2,
1399 virtual_offset));
1400 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1402 /* Get the offset itself. */
1403 vtabletmp3 = create_tmp_reg (TREE_TYPE (TREE_TYPE (vtabletmp2)),
1404 "vcalloffset");
1405 stmt = gimple_build_assign (vtabletmp3,
1406 build_simple_mem_ref (vtabletmp2));
1407 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1409 /* Adjust the `this' pointer. */
1410 ptr = fold_build_pointer_plus_loc (input_location, ptr, vtabletmp3);
1411 ptr = force_gimple_operand_gsi (bsi, ptr, true, NULL_TREE, false,
1412 GSI_CONTINUE_LINKING);
1415 if (!this_adjusting
1416 && fixed_offset != 0)
1417 /* Adjust the pointer by the constant. */
1419 tree ptrtmp;
1421 if (TREE_CODE (ptr) == VAR_DECL)
1422 ptrtmp = ptr;
1423 else
1425 ptrtmp = create_tmp_reg (TREE_TYPE (ptr), "ptr");
1426 stmt = gimple_build_assign (ptrtmp, ptr);
1427 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1429 ptr = fold_build_pointer_plus_hwi_loc (input_location,
1430 ptrtmp, fixed_offset);
1433 /* Emit the statement and gimplify the adjustment expression. */
1434 ret = create_tmp_reg (TREE_TYPE (ptr), "adjusted_this");
1435 stmt = gimple_build_assign (ret, ptr);
1436 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1438 return ret;
1441 /* Expand thunk NODE to gimple if possible.
1442 When OUTPUT_ASM_THUNK is true, also produce assembler for
1443 thunks that are not lowered. */
1445 bool
1446 expand_thunk (struct cgraph_node *node, bool output_asm_thunks)
1448 bool this_adjusting = node->thunk.this_adjusting;
1449 HOST_WIDE_INT fixed_offset = node->thunk.fixed_offset;
1450 HOST_WIDE_INT virtual_value = node->thunk.virtual_value;
1451 tree virtual_offset = NULL;
1452 tree alias = node->callees->callee->symbol.decl;
1453 tree thunk_fndecl = node->symbol.decl;
1454 tree a;
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 if (!output_asm_thunks)
1466 return false;
1468 if (in_lto_p)
1469 cgraph_get_body (node);
1470 a = DECL_ARGUMENTS (thunk_fndecl);
1472 current_function_decl = thunk_fndecl;
1474 /* Ensure thunks are emitted in their correct sections. */
1475 resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
1477 DECL_RESULT (thunk_fndecl)
1478 = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl),
1479 RESULT_DECL, 0, restype);
1480 DECL_CONTEXT (DECL_RESULT (thunk_fndecl)) = thunk_fndecl;
1481 fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
1483 /* The back end expects DECL_INITIAL to contain a BLOCK, so we
1484 create one. */
1485 fn_block = make_node (BLOCK);
1486 BLOCK_VARS (fn_block) = a;
1487 DECL_INITIAL (thunk_fndecl) = fn_block;
1488 init_function_start (thunk_fndecl);
1489 cfun->is_thunk = 1;
1490 insn_locations_init ();
1491 set_curr_insn_location (DECL_SOURCE_LOCATION (thunk_fndecl));
1492 prologue_location = curr_insn_location ();
1493 assemble_start_function (thunk_fndecl, fnname);
1495 targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl,
1496 fixed_offset, virtual_value, alias);
1498 assemble_end_function (thunk_fndecl, fnname);
1499 insn_locations_finalize ();
1500 init_insn_lengths ();
1501 free_after_compilation (cfun);
1502 set_cfun (NULL);
1503 TREE_ASM_WRITTEN (thunk_fndecl) = 1;
1504 node->thunk.thunk_p = false;
1505 node->symbol.analyzed = false;
1507 else
1509 tree restype;
1510 basic_block bb, then_bb, else_bb, return_bb;
1511 gimple_stmt_iterator bsi;
1512 int nargs = 0;
1513 tree arg;
1514 int i;
1515 tree resdecl;
1516 tree restmp = NULL;
1517 vec<tree> vargs;
1519 gimple call;
1520 gimple ret;
1522 if (in_lto_p)
1523 cgraph_get_body (node);
1524 a = DECL_ARGUMENTS (thunk_fndecl);
1526 current_function_decl = thunk_fndecl;
1528 /* Ensure thunks are emitted in their correct sections. */
1529 resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
1531 DECL_IGNORED_P (thunk_fndecl) = 1;
1532 bitmap_obstack_initialize (NULL);
1534 if (node->thunk.virtual_offset_p)
1535 virtual_offset = size_int (virtual_value);
1537 /* Build the return declaration for the function. */
1538 restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1539 if (DECL_RESULT (thunk_fndecl) == NULL_TREE)
1541 resdecl = build_decl (input_location, RESULT_DECL, 0, restype);
1542 DECL_ARTIFICIAL (resdecl) = 1;
1543 DECL_IGNORED_P (resdecl) = 1;
1544 DECL_RESULT (thunk_fndecl) = resdecl;
1545 DECL_CONTEXT (DECL_RESULT (thunk_fndecl)) = thunk_fndecl;
1547 else
1548 resdecl = DECL_RESULT (thunk_fndecl);
1550 bb = then_bb = else_bb = return_bb = init_lowered_empty_function (thunk_fndecl, true);
1552 bsi = gsi_start_bb (bb);
1554 /* Build call to the function being thunked. */
1555 if (!VOID_TYPE_P (restype))
1557 if (DECL_BY_REFERENCE (resdecl))
1558 restmp = gimple_fold_indirect_ref (resdecl);
1559 else if (!is_gimple_reg_type (restype))
1561 restmp = resdecl;
1562 add_local_decl (cfun, restmp);
1563 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp;
1565 else
1566 restmp = create_tmp_reg (restype, "retval");
1569 for (arg = a; arg; arg = DECL_CHAIN (arg))
1570 nargs++;
1571 vargs.create (nargs);
1572 if (this_adjusting)
1573 vargs.quick_push (thunk_adjust (&bsi, a, 1, fixed_offset,
1574 virtual_offset));
1575 else if (nargs)
1576 vargs.quick_push (a);
1578 if (nargs)
1579 for (i = 1, arg = DECL_CHAIN (a); i < nargs; i++, arg = DECL_CHAIN (arg))
1580 vargs.quick_push (arg);
1581 call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs);
1582 node->callees->call_stmt = call;
1583 vargs.release ();
1584 gimple_call_set_from_thunk (call, true);
1585 if (restmp)
1587 gimple_call_set_lhs (call, restmp);
1588 gcc_assert (useless_type_conversion_p (TREE_TYPE (restmp),
1589 TREE_TYPE (TREE_TYPE (alias))));
1591 gsi_insert_after (&bsi, call, GSI_NEW_STMT);
1592 if (!(gimple_call_flags (call) & ECF_NORETURN))
1594 if (restmp && !this_adjusting
1595 && (fixed_offset || virtual_offset))
1597 tree true_label = NULL_TREE;
1599 if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE)
1601 gimple stmt;
1602 /* If the return type is a pointer, we need to
1603 protect against NULL. We know there will be an
1604 adjustment, because that's why we're emitting a
1605 thunk. */
1606 then_bb = create_basic_block (NULL, (void *) 0, bb);
1607 return_bb = create_basic_block (NULL, (void *) 0, then_bb);
1608 else_bb = create_basic_block (NULL, (void *) 0, else_bb);
1609 add_bb_to_loop (then_bb, bb->loop_father);
1610 add_bb_to_loop (return_bb, bb->loop_father);
1611 add_bb_to_loop (else_bb, bb->loop_father);
1612 remove_edge (single_succ_edge (bb));
1613 true_label = gimple_block_label (then_bb);
1614 stmt = gimple_build_cond (NE_EXPR, restmp,
1615 build_zero_cst (TREE_TYPE (restmp)),
1616 NULL_TREE, NULL_TREE);
1617 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1618 make_edge (bb, then_bb, EDGE_TRUE_VALUE);
1619 make_edge (bb, else_bb, EDGE_FALSE_VALUE);
1620 make_edge (return_bb, EXIT_BLOCK_PTR, 0);
1621 make_edge (then_bb, return_bb, EDGE_FALLTHRU);
1622 make_edge (else_bb, return_bb, EDGE_FALLTHRU);
1623 bsi = gsi_last_bb (then_bb);
1626 restmp = thunk_adjust (&bsi, restmp, /*this_adjusting=*/0,
1627 fixed_offset, virtual_offset);
1628 if (true_label)
1630 gimple stmt;
1631 bsi = gsi_last_bb (else_bb);
1632 stmt = gimple_build_assign (restmp,
1633 build_zero_cst (TREE_TYPE (restmp)));
1634 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1635 bsi = gsi_last_bb (return_bb);
1638 else
1639 gimple_call_set_tail (call, true);
1641 /* Build return value. */
1642 ret = gimple_build_return (restmp);
1643 gsi_insert_after (&bsi, ret, GSI_NEW_STMT);
1645 else
1647 gimple_call_set_tail (call, true);
1648 remove_edge (single_succ_edge (bb));
1651 cfun->gimple_df->in_ssa_p = true;
1652 /* FIXME: C++ FE should stop setting TREE_ASM_WRITTEN on thunks. */
1653 TREE_ASM_WRITTEN (thunk_fndecl) = false;
1654 delete_unreachable_blocks ();
1655 update_ssa (TODO_update_ssa);
1656 #ifdef ENABLE_CHECKING
1657 verify_flow_info ();
1658 #endif
1660 /* Since we want to emit the thunk, we explicitly mark its name as
1661 referenced. */
1662 node->thunk.thunk_p = false;
1663 node->lowered = true;
1664 bitmap_obstack_release (NULL);
1666 current_function_decl = NULL;
1667 set_cfun (NULL);
1668 return true;
1671 /* Assemble thunks and aliases associated to NODE. */
1673 static void
1674 assemble_thunks_and_aliases (struct cgraph_node *node)
1676 struct cgraph_edge *e;
1677 int i;
1678 struct ipa_ref *ref;
1680 for (e = node->callers; e;)
1681 if (e->caller->thunk.thunk_p)
1683 struct cgraph_node *thunk = e->caller;
1685 e = e->next_caller;
1686 assemble_thunks_and_aliases (thunk);
1687 expand_thunk (thunk, true);
1689 else
1690 e = e->next_caller;
1691 for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list,
1692 i, ref); i++)
1693 if (ref->use == IPA_REF_ALIAS)
1695 struct cgraph_node *alias = ipa_ref_referring_node (ref);
1696 bool saved_written = TREE_ASM_WRITTEN (node->symbol.decl);
1698 /* Force assemble_alias to really output the alias this time instead
1699 of buffering it in same alias pairs. */
1700 TREE_ASM_WRITTEN (node->symbol.decl) = 1;
1701 do_assemble_alias (alias->symbol.decl,
1702 DECL_ASSEMBLER_NAME (node->symbol.decl));
1703 assemble_thunks_and_aliases (alias);
1704 TREE_ASM_WRITTEN (node->symbol.decl) = saved_written;
1708 /* Expand function specified by NODE. */
1710 static void
1711 expand_function (struct cgraph_node *node)
1713 tree decl = node->symbol.decl;
1714 location_t saved_loc;
1716 /* We ought to not compile any inline clones. */
1717 gcc_assert (!node->global.inlined_to);
1719 announce_function (decl);
1720 node->process = 0;
1721 gcc_assert (node->lowered);
1722 cgraph_get_body (node);
1724 /* Generate RTL for the body of DECL. */
1726 timevar_push (TV_REST_OF_COMPILATION);
1728 gcc_assert (cgraph_global_info_ready);
1730 /* Initialize the default bitmap obstack. */
1731 bitmap_obstack_initialize (NULL);
1733 /* Initialize the RTL code for the function. */
1734 current_function_decl = decl;
1735 saved_loc = input_location;
1736 input_location = DECL_SOURCE_LOCATION (decl);
1737 init_function_start (decl);
1739 gimple_register_cfg_hooks ();
1741 bitmap_obstack_initialize (&reg_obstack); /* FIXME, only at RTL generation*/
1743 execute_all_ipa_transforms ();
1745 /* Perform all tree transforms and optimizations. */
1747 /* Signal the start of passes. */
1748 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START, NULL);
1750 execute_pass_list (g->get_passes ()->all_passes);
1752 /* Signal the end of passes. */
1753 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END, NULL);
1755 bitmap_obstack_release (&reg_obstack);
1757 /* Release the default bitmap obstack. */
1758 bitmap_obstack_release (NULL);
1760 /* If requested, warn about function definitions where the function will
1761 return a value (usually of some struct or union type) which itself will
1762 take up a lot of stack space. */
1763 if (warn_larger_than && !DECL_EXTERNAL (decl) && TREE_TYPE (decl))
1765 tree ret_type = TREE_TYPE (TREE_TYPE (decl));
1767 if (ret_type && TYPE_SIZE_UNIT (ret_type)
1768 && TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST
1769 && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type),
1770 larger_than_size))
1772 unsigned int size_as_int
1773 = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type));
1775 if (compare_tree_int (TYPE_SIZE_UNIT (ret_type), size_as_int) == 0)
1776 warning (OPT_Wlarger_than_, "size of return value of %q+D is %u bytes",
1777 decl, size_as_int);
1778 else
1779 warning (OPT_Wlarger_than_, "size of return value of %q+D is larger than %wd bytes",
1780 decl, larger_than_size);
1784 gimple_set_body (decl, NULL);
1785 if (DECL_STRUCT_FUNCTION (decl) == 0
1786 && !cgraph_get_node (decl)->origin)
1788 /* Stop pointing to the local nodes about to be freed.
1789 But DECL_INITIAL must remain nonzero so we know this
1790 was an actual function definition.
1791 For a nested function, this is done in c_pop_function_context.
1792 If rest_of_compilation set this to 0, leave it 0. */
1793 if (DECL_INITIAL (decl) != 0)
1794 DECL_INITIAL (decl) = error_mark_node;
1797 input_location = saved_loc;
1799 ggc_collect ();
1800 timevar_pop (TV_REST_OF_COMPILATION);
1802 /* Make sure that BE didn't give up on compiling. */
1803 gcc_assert (TREE_ASM_WRITTEN (decl));
1804 set_cfun (NULL);
1805 current_function_decl = NULL;
1807 /* It would make a lot more sense to output thunks before function body to get more
1808 forward and lest backwarding jumps. This however would need solving problem
1809 with comdats. See PR48668. Also aliases must come after function itself to
1810 make one pass assemblers, like one on AIX, happy. See PR 50689.
1811 FIXME: Perhaps thunks should be move before function IFF they are not in comdat
1812 groups. */
1813 assemble_thunks_and_aliases (node);
1814 cgraph_release_function_body (node);
1815 /* Eliminate all call edges. This is important so the GIMPLE_CALL no longer
1816 points to the dead function body. */
1817 cgraph_node_remove_callees (node);
1818 ipa_remove_all_references (&node->symbol.ref_list);
1822 /* Expand all functions that must be output.
1824 Attempt to topologically sort the nodes so function is output when
1825 all called functions are already assembled to allow data to be
1826 propagated across the callgraph. Use a stack to get smaller distance
1827 between a function and its callees (later we may choose to use a more
1828 sophisticated algorithm for function reordering; we will likely want
1829 to use subsections to make the output functions appear in top-down
1830 order). */
1832 static void
1833 expand_all_functions (void)
1835 struct cgraph_node *node;
1836 struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
1837 int order_pos, new_order_pos = 0;
1838 int i;
1840 order_pos = ipa_reverse_postorder (order);
1841 gcc_assert (order_pos == cgraph_n_nodes);
1843 /* Garbage collector may remove inline clones we eliminate during
1844 optimization. So we must be sure to not reference them. */
1845 for (i = 0; i < order_pos; i++)
1846 if (order[i]->process)
1847 order[new_order_pos++] = order[i];
1849 for (i = new_order_pos - 1; i >= 0; i--)
1851 node = order[i];
1852 if (node->process)
1854 node->process = 0;
1855 expand_function (node);
1858 cgraph_process_new_functions ();
1860 free (order);
1864 /* This is used to sort the node types by the cgraph order number. */
1866 enum cgraph_order_sort_kind
1868 ORDER_UNDEFINED = 0,
1869 ORDER_FUNCTION,
1870 ORDER_VAR,
1871 ORDER_ASM
1874 struct cgraph_order_sort
1876 enum cgraph_order_sort_kind kind;
1877 union
1879 struct cgraph_node *f;
1880 struct varpool_node *v;
1881 struct asm_node *a;
1882 } u;
1885 /* Output all functions, variables, and asm statements in the order
1886 according to their order fields, which is the order in which they
1887 appeared in the file. This implements -fno-toplevel-reorder. In
1888 this mode we may output functions and variables which don't really
1889 need to be output. */
1891 static void
1892 output_in_order (void)
1894 int max;
1895 struct cgraph_order_sort *nodes;
1896 int i;
1897 struct cgraph_node *pf;
1898 struct varpool_node *pv;
1899 struct asm_node *pa;
1901 max = symtab_order;
1902 nodes = XCNEWVEC (struct cgraph_order_sort, max);
1904 FOR_EACH_DEFINED_FUNCTION (pf)
1906 if (pf->process && !pf->thunk.thunk_p && !pf->symbol.alias)
1908 i = pf->symbol.order;
1909 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1910 nodes[i].kind = ORDER_FUNCTION;
1911 nodes[i].u.f = pf;
1915 FOR_EACH_DEFINED_VARIABLE (pv)
1916 if (!DECL_EXTERNAL (pv->symbol.decl))
1918 i = pv->symbol.order;
1919 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1920 nodes[i].kind = ORDER_VAR;
1921 nodes[i].u.v = pv;
1924 for (pa = asm_nodes; pa; pa = pa->next)
1926 i = pa->order;
1927 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1928 nodes[i].kind = ORDER_ASM;
1929 nodes[i].u.a = pa;
1932 /* In toplevel reorder mode we output all statics; mark them as needed. */
1934 for (i = 0; i < max; ++i)
1935 if (nodes[i].kind == ORDER_VAR)
1936 varpool_finalize_named_section_flags (nodes[i].u.v);
1938 for (i = 0; i < max; ++i)
1940 switch (nodes[i].kind)
1942 case ORDER_FUNCTION:
1943 nodes[i].u.f->process = 0;
1944 expand_function (nodes[i].u.f);
1945 break;
1947 case ORDER_VAR:
1948 varpool_assemble_decl (nodes[i].u.v);
1949 break;
1951 case ORDER_ASM:
1952 assemble_asm (nodes[i].u.a->asm_str);
1953 break;
1955 case ORDER_UNDEFINED:
1956 break;
1958 default:
1959 gcc_unreachable ();
1963 asm_nodes = NULL;
1964 free (nodes);
1967 static void
1968 ipa_passes (void)
1970 gcc::pass_manager *passes = g->get_passes ();
1972 set_cfun (NULL);
1973 current_function_decl = NULL;
1974 gimple_register_cfg_hooks ();
1975 bitmap_obstack_initialize (NULL);
1977 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START, NULL);
1979 if (!in_lto_p)
1981 execute_ipa_pass_list (passes->all_small_ipa_passes);
1982 if (seen_error ())
1983 return;
1986 /* We never run removal of unreachable nodes after early passes. This is
1987 because TODO is run before the subpasses. It is important to remove
1988 the unreachable functions to save works at IPA level and to get LTO
1989 symbol tables right. */
1990 symtab_remove_unreachable_nodes (true, cgraph_dump_file);
1992 /* If pass_all_early_optimizations was not scheduled, the state of
1993 the cgraph will not be properly updated. Update it now. */
1994 if (cgraph_state < CGRAPH_STATE_IPA_SSA)
1995 cgraph_state = CGRAPH_STATE_IPA_SSA;
1997 if (!in_lto_p)
1999 /* Generate coverage variables and constructors. */
2000 coverage_finish ();
2002 /* Process new functions added. */
2003 set_cfun (NULL);
2004 current_function_decl = NULL;
2005 cgraph_process_new_functions ();
2007 execute_ipa_summary_passes
2008 ((struct ipa_opt_pass_d *) passes->all_regular_ipa_passes);
2011 /* Some targets need to handle LTO assembler output specially. */
2012 if (flag_generate_lto)
2013 targetm.asm_out.lto_start ();
2015 execute_ipa_summary_passes ((struct ipa_opt_pass_d *)
2016 passes->all_lto_gen_passes);
2018 if (!in_lto_p)
2019 ipa_write_summaries ();
2021 if (flag_generate_lto)
2022 targetm.asm_out.lto_end ();
2024 if (!flag_ltrans && (in_lto_p || !flag_lto || flag_fat_lto_objects))
2025 execute_ipa_pass_list (passes->all_regular_ipa_passes);
2026 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END, NULL);
2028 bitmap_obstack_release (NULL);
2032 /* Return string alias is alias of. */
2034 static tree
2035 get_alias_symbol (tree decl)
2037 tree alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
2038 return get_identifier (TREE_STRING_POINTER
2039 (TREE_VALUE (TREE_VALUE (alias))));
2043 /* Weakrefs may be associated to external decls and thus not output
2044 at expansion time. Emit all necessary aliases. */
2046 static void
2047 output_weakrefs (void)
2049 symtab_node node;
2050 FOR_EACH_SYMBOL (node)
2051 if (node->symbol.alias
2052 && !TREE_ASM_WRITTEN (node->symbol.decl)
2053 && node->symbol.weakref)
2055 tree target;
2057 /* Weakrefs are special by not requiring target definition in current
2058 compilation unit. It is thus bit hard to work out what we want to
2059 alias.
2060 When alias target is defined, we need to fetch it from symtab reference,
2061 otherwise it is pointed to by alias_target. */
2062 if (node->symbol.alias_target)
2063 target = (DECL_P (node->symbol.alias_target)
2064 ? DECL_ASSEMBLER_NAME (node->symbol.alias_target)
2065 : node->symbol.alias_target);
2066 else if (node->symbol.analyzed)
2067 target = DECL_ASSEMBLER_NAME (symtab_alias_target (node)->symbol.decl);
2068 else
2070 gcc_unreachable ();
2071 target = get_alias_symbol (node->symbol.decl);
2073 do_assemble_alias (node->symbol.decl, target);
2077 /* Initialize callgraph dump file. */
2079 void
2080 init_cgraph (void)
2082 if (!cgraph_dump_file)
2083 cgraph_dump_file = dump_begin (TDI_cgraph, NULL);
2087 /* Perform simple optimizations based on callgraph. */
2089 void
2090 compile (void)
2092 if (seen_error ())
2093 return;
2095 #ifdef ENABLE_CHECKING
2096 verify_symtab ();
2097 #endif
2099 timevar_push (TV_CGRAPHOPT);
2100 if (pre_ipa_mem_report)
2102 fprintf (stderr, "Memory consumption before IPA\n");
2103 dump_memory_report (false);
2105 if (!quiet_flag)
2106 fprintf (stderr, "Performing interprocedural optimizations\n");
2107 cgraph_state = CGRAPH_STATE_IPA;
2109 /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE. */
2110 if (flag_lto)
2111 lto_streamer_hooks_init ();
2113 /* Don't run the IPA passes if there was any error or sorry messages. */
2114 if (!seen_error ())
2115 ipa_passes ();
2117 /* Do nothing else if any IPA pass found errors or if we are just streaming LTO. */
2118 if (seen_error ()
2119 || (!in_lto_p && flag_lto && !flag_fat_lto_objects))
2121 timevar_pop (TV_CGRAPHOPT);
2122 return;
2125 /* This pass remove bodies of extern inline functions we never inlined.
2126 Do this later so other IPA passes see what is really going on. */
2127 symtab_remove_unreachable_nodes (false, dump_file);
2128 cgraph_global_info_ready = true;
2129 if (cgraph_dump_file)
2131 fprintf (cgraph_dump_file, "Optimized ");
2132 dump_symtab (cgraph_dump_file);
2134 if (post_ipa_mem_report)
2136 fprintf (stderr, "Memory consumption after IPA\n");
2137 dump_memory_report (false);
2139 timevar_pop (TV_CGRAPHOPT);
2141 /* Output everything. */
2142 (*debug_hooks->assembly_start) ();
2143 if (!quiet_flag)
2144 fprintf (stderr, "Assembling functions:\n");
2145 #ifdef ENABLE_CHECKING
2146 verify_symtab ();
2147 #endif
2149 cgraph_materialize_all_clones ();
2150 bitmap_obstack_initialize (NULL);
2151 execute_ipa_pass_list (g->get_passes ()->all_late_ipa_passes);
2152 symtab_remove_unreachable_nodes (true, dump_file);
2153 #ifdef ENABLE_CHECKING
2154 verify_symtab ();
2155 #endif
2156 bitmap_obstack_release (NULL);
2157 mark_functions_to_output ();
2159 /* When weakref support is missing, we autmatically translate all
2160 references to NODE to references to its ultimate alias target.
2161 The renaming mechanizm uses flag IDENTIFIER_TRANSPARENT_ALIAS and
2162 TREE_CHAIN.
2164 Set up this mapping before we output any assembler but once we are sure
2165 that all symbol renaming is done.
2167 FIXME: All this uglyness can go away if we just do renaming at gimple
2168 level by physically rewritting the IL. At the moment we can only redirect
2169 calls, so we need infrastructure for renaming references as well. */
2170 #ifndef ASM_OUTPUT_WEAKREF
2171 symtab_node node;
2173 FOR_EACH_SYMBOL (node)
2174 if (node->symbol.alias
2175 && lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
2177 IDENTIFIER_TRANSPARENT_ALIAS
2178 (DECL_ASSEMBLER_NAME (node->symbol.decl)) = 1;
2179 TREE_CHAIN (DECL_ASSEMBLER_NAME (node->symbol.decl))
2180 = (node->symbol.alias_target ? node->symbol.alias_target
2181 : DECL_ASSEMBLER_NAME (symtab_alias_target (node)->symbol.decl));
2183 #endif
2185 cgraph_state = CGRAPH_STATE_EXPANSION;
2186 if (!flag_toplevel_reorder)
2187 output_in_order ();
2188 else
2190 output_asm_statements ();
2192 expand_all_functions ();
2193 varpool_output_variables ();
2196 cgraph_process_new_functions ();
2197 cgraph_state = CGRAPH_STATE_FINISHED;
2198 output_weakrefs ();
2200 if (cgraph_dump_file)
2202 fprintf (cgraph_dump_file, "\nFinal ");
2203 dump_symtab (cgraph_dump_file);
2205 #ifdef ENABLE_CHECKING
2206 verify_symtab ();
2207 /* Double check that all inline clones are gone and that all
2208 function bodies have been released from memory. */
2209 if (!seen_error ())
2211 struct cgraph_node *node;
2212 bool error_found = false;
2214 FOR_EACH_DEFINED_FUNCTION (node)
2215 if (node->global.inlined_to
2216 || gimple_has_body_p (node->symbol.decl))
2218 error_found = true;
2219 dump_cgraph_node (stderr, node);
2221 if (error_found)
2222 internal_error ("nodes with unreleased memory found");
2224 #endif
2228 /* Analyze the whole compilation unit once it is parsed completely. */
2230 void
2231 finalize_compilation_unit (void)
2233 timevar_push (TV_CGRAPH);
2235 /* If we're here there's no current function anymore. Some frontends
2236 are lazy in clearing these. */
2237 current_function_decl = NULL;
2238 set_cfun (NULL);
2240 /* Do not skip analyzing the functions if there were errors, we
2241 miss diagnostics for following functions otherwise. */
2243 /* Emit size functions we didn't inline. */
2244 finalize_size_functions ();
2246 /* Mark alias targets necessary and emit diagnostics. */
2247 handle_alias_pairs ();
2249 if (!quiet_flag)
2251 fprintf (stderr, "\nAnalyzing compilation unit\n");
2252 fflush (stderr);
2255 if (flag_dump_passes)
2256 dump_passes ();
2258 /* Gimplify and lower all functions, compute reachability and
2259 remove unreachable nodes. */
2260 analyze_functions ();
2262 /* Mark alias targets necessary and emit diagnostics. */
2263 handle_alias_pairs ();
2265 /* Gimplify and lower thunks. */
2266 analyze_functions ();
2268 /* Finally drive the pass manager. */
2269 compile ();
2271 timevar_pop (TV_CGRAPH);
2275 #include "gt-cgraphunit.h"