Port the following FDO/LIPO related changes from google/gcc-4_8 branch to google...
[official-gcc.git] / main / gcc / cgraphunit.c
blob387b4a6ee05d3499cac88bd398478cf754757a20
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 exmaple, 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-flow.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 "gcov-io.h"
185 #include "tree-iterator.h"
186 #include "tree-pass.h"
187 #include "tree-dump.h"
188 #include "gimple-pretty-print.h"
189 #include "output.h"
190 #include "coverage.h"
191 #include "plugin.h"
192 #include "ipa-inline.h"
193 #include "ipa-utils.h"
194 #include "lto-streamer.h"
195 #include "l-ipo.h"
196 #include "except.h"
197 #include "regset.h" /* FIXME: For reg_obstack. */
199 /* Queue of cgraph nodes scheduled to be added into cgraph. This is a
200 secondary queue used during optimization to accommodate passes that
201 may generate new functions that need to be optimized and expanded. */
202 cgraph_node_set cgraph_new_nodes;
204 static void expand_all_functions (void);
205 static void mark_functions_to_output (void);
206 static void expand_function (struct cgraph_node *);
207 static void cgraph_analyze_function (struct cgraph_node *);
208 static void handle_alias_pairs (void);
210 FILE *cgraph_dump_file;
212 /* Linked list of cgraph asm nodes. */
213 struct asm_node *asm_nodes;
215 /* Last node in cgraph_asm_nodes. */
216 static GTY(()) struct asm_node *asm_last_node;
218 /* Used for vtable lookup in thunk adjusting. */
219 static GTY (()) tree vtable_entry_type;
221 /* Determine if function DECL is trivially needed and should stay in the
222 compilation unit. This is used at the symbol table construction time
223 and differs from later logic removing unnecessary functions that can
224 take into account results of analysis, whole program info etc. */
226 bool
227 cgraph_decide_is_function_needed (struct cgraph_node *node, tree decl)
229 /* If the user told us it is used, then it must be so. */
230 if (node->symbol.force_output)
231 return true;
233 /* Double check that no one output the function into assembly file
234 early. */
235 gcc_checking_assert (!DECL_ASSEMBLER_NAME_SET_P (decl)
236 || (node->thunk.thunk_p || node->same_body_alias)
237 || !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)));
240 /* Keep constructors, destructors and virtual functions. */
241 if (DECL_STATIC_CONSTRUCTOR (decl)
242 || DECL_STATIC_DESTRUCTOR (decl)
243 || (DECL_VIRTUAL_P (decl)
244 && optimize && (DECL_COMDAT (decl) || DECL_EXTERNAL (decl))))
245 return true;
247 /* Externally visible functions must be output. The exception is
248 COMDAT functions that must be output only when they are needed. */
250 if (TREE_PUBLIC (decl)
251 && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
252 return true;
254 return false;
257 /* Head of the queue of nodes to be processed while building callgraph */
259 static symtab_node first = (symtab_node)(void *)1;
261 /* Add NODE to queue starting at FIRST.
262 The queue is linked via AUX pointers and terminated by pointer to 1. */
264 static void
265 enqueue_node (symtab_node node)
267 if (node->symbol.aux)
268 return;
269 gcc_checking_assert (first);
270 node->symbol.aux = first;
271 first = node;
274 void
275 cgraph_enqueue_node (struct cgraph_node *node)
277 enqueue_node ((symtab_node) node);
280 /* Process CGRAPH_NEW_FUNCTIONS and perform actions necessary to add these
281 functions into callgraph in a way so they look like ordinary reachable
282 functions inserted into callgraph already at construction time. */
284 bool
285 cgraph_process_new_functions (void)
287 bool output = false;
288 tree fndecl;
289 struct cgraph_node *node;
290 cgraph_node_set_iterator csi;
292 if (!cgraph_new_nodes)
293 return false;
294 handle_alias_pairs ();
295 /* Note that this queue may grow as its being processed, as the new
296 functions may generate new ones. */
297 for (csi = csi_start (cgraph_new_nodes); !csi_end_p (csi); csi_next (&csi))
299 node = csi_node (csi);
300 fndecl = node->symbol.decl;
301 switch (cgraph_state)
303 case CGRAPH_STATE_CONSTRUCTION:
304 /* At construction time we just need to finalize function and move
305 it into reachable functions list. */
307 cgraph_finalize_function (fndecl, false);
308 output = true;
309 cgraph_call_function_insertion_hooks (node);
310 enqueue_node ((symtab_node) node);
311 break;
313 case CGRAPH_STATE_IPA:
314 case CGRAPH_STATE_IPA_SSA:
315 /* When IPA optimization already started, do all essential
316 transformations that has been already performed on the whole
317 cgraph but not on this function. */
319 gimple_register_cfg_hooks ();
320 if (!node->analyzed)
321 cgraph_analyze_function (node);
322 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
323 if ((cgraph_state == CGRAPH_STATE_IPA_SSA
324 && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
325 /* When not optimizing, be sure we run early local passes anyway
326 to expand OMP. */
327 || !optimize)
328 execute_pass_list (pass_early_local_passes.pass.sub);
329 else
330 compute_inline_parameters (node, true);
331 free_dominance_info (CDI_POST_DOMINATORS);
332 free_dominance_info (CDI_DOMINATORS);
333 pop_cfun ();
334 cgraph_call_function_insertion_hooks (node);
335 break;
337 case CGRAPH_STATE_EXPANSION:
338 /* Functions created during expansion shall be compiled
339 directly. */
340 node->process = 0;
341 cgraph_call_function_insertion_hooks (node);
342 expand_function (node);
343 break;
345 default:
346 gcc_unreachable ();
347 break;
350 free_cgraph_node_set (cgraph_new_nodes);
351 cgraph_new_nodes = NULL;
352 return output;
355 /* As an GCC extension we allow redefinition of the function. The
356 semantics when both copies of bodies differ is not well defined.
357 We replace the old body with new body so in unit at a time mode
358 we always use new body, while in normal mode we may end up with
359 old body inlined into some functions and new body expanded and
360 inlined in others.
362 ??? It may make more sense to use one body for inlining and other
363 body for expanding the function but this is difficult to do. */
365 static void
366 cgraph_reset_node (struct cgraph_node *node)
368 /* If node->process is set, then we have already begun whole-unit analysis.
369 This is *not* testing for whether we've already emitted the function.
370 That case can be sort-of legitimately seen with real function redefinition
371 errors. I would argue that the front end should never present us with
372 such a case, but don't enforce that for now. */
373 gcc_assert (!node->process);
375 /* Reset our data structures so we can analyze the function again. */
376 memset (&node->local, 0, sizeof (node->local));
377 memset (&node->global, 0, sizeof (node->global));
378 memset (&node->rtl, 0, sizeof (node->rtl));
379 node->analyzed = false;
380 node->local.finalized = false;
382 cgraph_node_remove_callees (node);
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 NESTED 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 nested)
410 struct cgraph_node *node = cgraph_get_create_node (decl);
412 if (node->local.finalized)
414 cgraph_reset_node (node);
415 node->local.redefined_extern_inline = true;
418 notice_global_symbol (decl);
419 node->local.finalized = true;
420 node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL;
422 /* With -fkeep-inline-functions we are keeping all inline functions except
423 for extern inline ones. */
424 if (flag_keep_inline_functions
425 && DECL_DECLARED_INLINE_P (decl)
426 && !DECL_EXTERNAL (decl)
427 && !DECL_DISREGARD_INLINE_LIMITS (decl))
428 node->symbol.force_output = 1;
430 /* When not optimizing, also output the static functions. (see
431 PR24561), but don't do so for always_inline functions, functions
432 declared inline and nested functions. These were optimized out
433 in the original implementation and it is unclear whether we want
434 to change the behavior here. */
435 if ((!optimize
436 && !node->same_body_alias
437 && !DECL_DISREGARD_INLINE_LIMITS (decl)
438 && !DECL_DECLARED_INLINE_P (decl)
439 && !(DECL_CONTEXT (decl)
440 && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL))
441 && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
442 node->symbol.force_output = 1;
444 /* If we've not yet emitted decl, tell the debug info about it. */
445 if (!TREE_ASM_WRITTEN (decl))
446 (*debug_hooks->deferred_inline_function) (decl);
448 /* Possibly warn about unused parameters. */
449 if (warn_unused_parameter)
450 do_warn_unused_parameter (decl);
452 if (!nested)
453 ggc_collect ();
455 if (cgraph_state == CGRAPH_STATE_CONSTRUCTION
456 && (cgraph_decide_is_function_needed (node, decl)
457 || referred_to_p ((symtab_node)node)))
458 enqueue_node ((symtab_node)node);
461 /* Add the function FNDECL to the call graph.
462 Unlike cgraph_finalize_function, this function is intended to be used
463 by middle end and allows insertion of new function at arbitrary point
464 of compilation. The function can be either in high, low or SSA form
465 GIMPLE.
467 The function is assumed to be reachable and have address taken (so no
468 API breaking optimizations are performed on it).
470 Main work done by this function is to enqueue the function for later
471 processing to avoid need the passes to be re-entrant. */
473 void
474 cgraph_add_new_function (tree fndecl, bool lowered)
476 struct cgraph_node *node;
478 switch (cgraph_state)
480 case CGRAPH_STATE_PARSING:
481 cgraph_finalize_function (fndecl, false);
482 break;
483 case CGRAPH_STATE_CONSTRUCTION:
484 /* Just enqueue function to be processed at nearest occurrence. */
485 node = cgraph_create_node (fndecl);
486 if (lowered)
487 node->lowered = true;
488 if (!cgraph_new_nodes)
489 cgraph_new_nodes = cgraph_node_set_new ();
490 cgraph_node_set_add (cgraph_new_nodes, node);
491 break;
493 case CGRAPH_STATE_IPA:
494 case CGRAPH_STATE_IPA_SSA:
495 case CGRAPH_STATE_EXPANSION:
496 /* Bring the function into finalized state and enqueue for later
497 analyzing and compilation. */
498 node = cgraph_get_create_node (fndecl);
499 node->local.local = false;
500 node->local.finalized = true;
501 node->symbol.force_output = true;
502 if (!lowered && cgraph_state == CGRAPH_STATE_EXPANSION)
504 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
505 gimple_register_cfg_hooks ();
506 bitmap_obstack_initialize (NULL);
507 execute_pass_list (all_lowering_passes);
508 execute_pass_list (pass_early_local_passes.pass.sub);
509 bitmap_obstack_release (NULL);
510 pop_cfun ();
512 lowered = true;
514 if (lowered)
515 node->lowered = true;
516 if (!cgraph_new_nodes)
517 cgraph_new_nodes = cgraph_node_set_new ();
518 cgraph_node_set_add (cgraph_new_nodes, node);
519 break;
521 case CGRAPH_STATE_FINISHED:
522 /* At the very end of compilation we have to do all the work up
523 to expansion. */
524 node = cgraph_create_node (fndecl);
525 if (lowered)
526 node->lowered = true;
527 cgraph_analyze_function (node);
528 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
529 gimple_register_cfg_hooks ();
530 bitmap_obstack_initialize (NULL);
531 if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
532 execute_pass_list (pass_early_local_passes.pass.sub);
533 bitmap_obstack_release (NULL);
534 pop_cfun ();
535 expand_function (node);
536 break;
537 default:
538 gcc_unreachable ();
541 /* Set a personality if required and we already passed EH lowering. */
542 if (lowered
543 && (function_needs_eh_personality (DECL_STRUCT_FUNCTION (fndecl))
544 == eh_personality_lang))
545 DECL_FUNCTION_PERSONALITY (fndecl) = lang_hooks.eh_personality ();
548 /* Add a top-level asm statement to the list. */
550 struct asm_node *
551 add_asm_node (tree asm_str)
553 struct asm_node *node;
555 node = ggc_alloc_cleared_asm_node ();
556 node->asm_str = asm_str;
557 node->order = symtab_order++;
558 node->next = NULL;
559 if (asm_nodes == NULL)
560 asm_nodes = node;
561 else
562 asm_last_node->next = node;
563 asm_last_node = node;
564 return node;
567 /* Output all asm statements we have stored up to be output. */
569 static void
570 output_asm_statements (void)
572 struct asm_node *can;
574 if (seen_error ())
575 return;
577 for (can = asm_nodes; can; can = can->next)
578 assemble_asm (can->asm_str);
579 asm_nodes = NULL;
582 /* C++ FE sometimes change linkage flags after producing same body aliases. */
583 void
584 fixup_same_cpp_alias_visibility (symtab_node node, symtab_node target, tree alias)
586 DECL_VIRTUAL_P (node->symbol.decl) = DECL_VIRTUAL_P (alias);
587 if (TREE_PUBLIC (node->symbol.decl))
589 DECL_EXTERNAL (node->symbol.decl) = DECL_EXTERNAL (alias);
590 DECL_COMDAT (node->symbol.decl) = DECL_COMDAT (alias);
591 DECL_COMDAT_GROUP (node->symbol.decl) = DECL_COMDAT_GROUP (alias);
592 if (DECL_ONE_ONLY (alias)
593 && !node->symbol.same_comdat_group)
594 symtab_add_to_same_comdat_group ((symtab_node)node, (symtab_node)target);
598 /* Analyze the function scheduled to be output. */
599 static void
600 cgraph_analyze_function (struct cgraph_node *node)
602 tree decl = node->symbol.decl;
603 location_t saved_loc = input_location;
604 input_location = DECL_SOURCE_LOCATION (decl);
606 if (node->alias && node->thunk.alias)
608 struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias);
609 struct cgraph_node *n;
611 for (n = tgt; n && n->alias;
612 n = n->analyzed ? cgraph_alias_aliased_node (n) : NULL)
613 if (n == node)
615 error ("function %q+D part of alias cycle", node->symbol.decl);
616 node->alias = false;
617 input_location = saved_loc;
618 return;
620 if (!vec_safe_length (node->symbol.ref_list.references))
621 ipa_record_reference ((symtab_node)node, (symtab_node)tgt,
622 IPA_REF_ALIAS, NULL);
623 if (node->same_body_alias)
625 DECL_DECLARED_INLINE_P (node->symbol.decl)
626 = DECL_DECLARED_INLINE_P (node->thunk.alias);
627 DECL_DISREGARD_INLINE_LIMITS (node->symbol.decl)
628 = DECL_DISREGARD_INLINE_LIMITS (node->thunk.alias);
629 fixup_same_cpp_alias_visibility ((symtab_node) node, (symtab_node) tgt, node->thunk.alias);
632 if (node->symbol.address_taken)
633 cgraph_mark_address_taken_node (cgraph_alias_aliased_node (node));
635 else if (node->thunk.thunk_p)
637 cgraph_create_edge (node, cgraph_get_node (node->thunk.alias),
638 NULL, 0, CGRAPH_FREQ_BASE);
640 else if (node->dispatcher_function)
642 /* Generate the dispatcher body of multi-versioned functions. */
643 struct cgraph_function_version_info *dispatcher_version_info
644 = get_cgraph_node_version (node);
645 if (dispatcher_version_info != NULL
646 && (dispatcher_version_info->dispatcher_resolver
647 == NULL_TREE))
649 tree resolver = NULL_TREE;
650 gcc_assert (targetm.generate_version_dispatcher_body);
651 resolver = targetm.generate_version_dispatcher_body (node);
652 gcc_assert (resolver != NULL_TREE);
655 else
657 push_cfun (DECL_STRUCT_FUNCTION (decl));
659 assign_assembler_name_if_neeeded (node->symbol.decl);
661 /* Make sure to gimplify bodies only once. During analyzing a
662 function we lower it, which will require gimplified nested
663 functions, so we can end up here with an already gimplified
664 body. */
665 if (!gimple_has_body_p (decl))
666 gimplify_function_tree (decl);
667 dump_function (TDI_generic, decl);
669 /* Lower the function. */
670 if (!node->lowered)
672 if (node->nested)
673 lower_nested_functions (node->symbol.decl);
674 gcc_assert (!node->nested);
676 gimple_register_cfg_hooks ();
677 bitmap_obstack_initialize (NULL);
678 execute_pass_list (all_lowering_passes);
679 free_dominance_info (CDI_POST_DOMINATORS);
680 free_dominance_info (CDI_DOMINATORS);
681 compact_blocks ();
682 bitmap_obstack_release (NULL);
683 node->lowered = true;
686 pop_cfun ();
688 node->analyzed = true;
690 input_location = saved_loc;
693 /* C++ frontend produce same body aliases all over the place, even before PCH
694 gets streamed out. It relies on us linking the aliases with their function
695 in order to do the fixups, but ipa-ref is not PCH safe. Consequentely we
696 first produce aliases without links, but once C++ FE is sure he won't sream
697 PCH we build the links via this function. */
699 void
700 cgraph_process_same_body_aliases (void)
702 struct cgraph_node *node;
703 FOR_EACH_FUNCTION (node)
704 if (node->same_body_alias
705 && !vec_safe_length (node->symbol.ref_list.references))
707 struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias);
708 ipa_record_reference ((symtab_node)node, (symtab_node)tgt,
709 IPA_REF_ALIAS, NULL);
711 same_body_aliases_done = true;
714 /* Process attributes common for vars and functions. */
716 static void
717 process_common_attributes (tree decl)
719 tree weakref = lookup_attribute ("weakref", DECL_ATTRIBUTES (decl));
721 if (weakref && !lookup_attribute ("alias", DECL_ATTRIBUTES (decl)))
723 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
724 "%<weakref%> attribute should be accompanied with"
725 " an %<alias%> attribute");
726 DECL_WEAK (decl) = 0;
727 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
728 DECL_ATTRIBUTES (decl));
732 /* Look for externally_visible and used attributes and mark cgraph nodes
733 accordingly.
735 We cannot mark the nodes at the point the attributes are processed (in
736 handle_*_attribute) because the copy of the declarations available at that
737 point may not be canonical. For example, in:
739 void f();
740 void f() __attribute__((used));
742 the declaration we see in handle_used_attribute will be the second
743 declaration -- but the front end will subsequently merge that declaration
744 with the original declaration and discard the second declaration.
746 Furthermore, we can't mark these nodes in cgraph_finalize_function because:
748 void f() {}
749 void f() __attribute__((externally_visible));
751 is valid.
753 So, we walk the nodes at the end of the translation unit, applying the
754 attributes at that point. */
756 static void
757 process_function_and_variable_attributes (struct cgraph_node *first,
758 struct varpool_node *first_var)
760 struct cgraph_node *node;
761 struct varpool_node *vnode;
763 for (node = cgraph_first_function (); node != first;
764 node = cgraph_next_function (node))
766 tree decl = node->symbol.decl;
767 if (DECL_PRESERVE_P (decl))
768 cgraph_mark_force_output_node (node);
769 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
771 if (! TREE_PUBLIC (node->symbol.decl))
772 warning_at (DECL_SOURCE_LOCATION (node->symbol.decl), OPT_Wattributes,
773 "%<externally_visible%>"
774 " attribute have effect only on public objects");
776 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
777 && (node->local.finalized && !node->alias))
779 warning_at (DECL_SOURCE_LOCATION (node->symbol.decl), OPT_Wattributes,
780 "%<weakref%> attribute ignored"
781 " because function is defined");
782 DECL_WEAK (decl) = 0;
783 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
784 DECL_ATTRIBUTES (decl));
787 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl))
788 && !DECL_DECLARED_INLINE_P (decl)
789 /* redefining extern inline function makes it DECL_UNINLINABLE. */
790 && !DECL_UNINLINABLE (decl))
791 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
792 "always_inline function might not be inlinable");
794 process_common_attributes (decl);
796 for (vnode = varpool_first_variable (); vnode != first_var;
797 vnode = varpool_next_variable (vnode))
799 tree decl = vnode->symbol.decl;
800 if (DECL_EXTERNAL (decl)
801 && DECL_INITIAL (decl)
802 && const_value_known_p (decl))
803 varpool_finalize_decl (decl);
804 if (DECL_PRESERVE_P (decl))
805 vnode->symbol.force_output = true;
806 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
808 if (! TREE_PUBLIC (vnode->symbol.decl))
809 warning_at (DECL_SOURCE_LOCATION (vnode->symbol.decl), OPT_Wattributes,
810 "%<externally_visible%>"
811 " attribute have effect only on public objects");
813 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
814 && vnode->finalized
815 && DECL_INITIAL (decl))
817 warning_at (DECL_SOURCE_LOCATION (vnode->symbol.decl), OPT_Wattributes,
818 "%<weakref%> attribute ignored"
819 " because variable is initialized");
820 DECL_WEAK (decl) = 0;
821 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
822 DECL_ATTRIBUTES (decl));
824 process_common_attributes (decl);
828 /* Mark DECL as finalized. By finalizing the declaration, frontend instruct the
829 middle end to output the variable to asm file, if needed or externally
830 visible. */
832 void
833 varpool_finalize_decl (tree decl)
835 struct varpool_node *node = varpool_node_for_decl (decl);
837 gcc_assert (TREE_STATIC (decl) || DECL_EXTERNAL (decl));
839 if (node->finalized)
840 return;
841 notice_global_symbol (decl);
842 node->finalized = true;
843 if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
844 /* Traditionally we do not eliminate static variables when not
845 optimizing and when not doing toplevel reoder. */
846 || (!flag_toplevel_reorder && !DECL_COMDAT (node->symbol.decl)
847 && !DECL_ARTIFICIAL (node->symbol.decl)))
848 node->symbol.force_output = true;
850 if (cgraph_state == CGRAPH_STATE_CONSTRUCTION
851 && (decide_is_variable_needed (node, decl)
852 || referred_to_p ((symtab_node)node)))
853 enqueue_node ((symtab_node)node);
854 if (cgraph_state >= CGRAPH_STATE_IPA_SSA)
855 varpool_analyze_node (node);
856 /* Some frontends produce various interface variables after compilation
857 finished. */
858 if (cgraph_state == CGRAPH_STATE_FINISHED
859 || (cgraph_state == CGRAPH_STATE_EXPANSION
860 && flag_dyn_ipa && !flag_toplevel_reorder))
861 varpool_assemble_decl (node);
865 /* Determine if a symbol NODE is finalized and needed. */
867 inline static bool
868 symbol_finalized_and_needed (symtab_node node)
870 if (cgraph_node *cnode = dyn_cast <cgraph_node> (node))
871 return cnode->local.finalized
872 && cgraph_decide_is_function_needed (cnode, cnode->symbol.decl);
873 if (varpool_node *vnode = dyn_cast <varpool_node> (node))
874 return vnode->finalized
875 && !DECL_EXTERNAL (vnode->symbol.decl)
876 && decide_is_variable_needed (vnode, vnode->symbol.decl);
877 return false;
880 /* Determine if a symbol NODE is finalized. */
882 inline static bool
883 symbol_finalized (symtab_node node)
885 if (cgraph_node *cnode= dyn_cast <cgraph_node> (node))
886 return cnode->local.finalized;
887 if (varpool_node *vnode = dyn_cast <varpool_node> (node))
888 return vnode->finalized;
889 return false;
893 /* Discover all functions and variables that are trivially needed, analyze
894 them as well as all functions and variables referred by them */
896 static void
897 cgraph_analyze_functions (void)
899 /* Keep track of already processed nodes when called multiple times for
900 intermodule optimization. */
901 static struct cgraph_node *first_analyzed;
902 struct cgraph_node *first_handled = first_analyzed;
903 static struct varpool_node *first_analyzed_var;
904 struct varpool_node *first_handled_var = first_analyzed_var;
906 symtab_node node, next;
907 int i;
908 struct ipa_ref *ref;
909 bool changed = true;
911 bitmap_obstack_initialize (NULL);
912 cgraph_state = CGRAPH_STATE_CONSTRUCTION;
914 /* Analysis adds static variables that in turn adds references to new functions.
915 So we need to iterate the process until it stabilize. */
916 while (changed)
918 changed = false;
919 process_function_and_variable_attributes (first_analyzed,
920 first_analyzed_var);
922 /* First identify the trivially needed symbols. */
923 for (node = symtab_nodes;
924 node != (symtab_node)first_analyzed
925 && node != (symtab_node)first_analyzed_var; node = node->symbol.next)
927 if (symbol_finalized_and_needed (node))
929 enqueue_node (node);
930 if (!changed && cgraph_dump_file)
931 fprintf (cgraph_dump_file, "Trivially needed symbols:");
932 changed = true;
933 if (cgraph_dump_file)
934 fprintf (cgraph_dump_file, " %s/%d", symtab_node_asm_name (node), node->symbol.order);
936 if (node == (symtab_node)first_analyzed
937 || node == (symtab_node)first_analyzed_var)
938 break;
940 cgraph_process_new_functions ();
941 first_analyzed_var = varpool_first_variable ();
942 first_analyzed = cgraph_first_function ();
944 if (changed && dump_file)
945 fprintf (cgraph_dump_file, "\n");
947 /* Lower representation, build callgraph edges and references for all trivially
948 needed symbols and all symbols referred by them. */
949 while (first != (symtab_node)(void *)1)
951 changed = true;
952 node = first;
953 first = (symtab_node)first->symbol.aux;
954 cgraph_node *cnode = dyn_cast <cgraph_node> (node);
955 if (cnode && cnode->local.finalized)
957 struct cgraph_edge *edge;
958 tree decl = cnode->symbol.decl;
960 /* ??? It is possible to create extern inline function
961 and later using weak alias attribute to kill its body.
962 See gcc.c-torture/compile/20011119-1.c */
963 if (!DECL_STRUCT_FUNCTION (decl)
964 && (!cnode->alias || !cnode->thunk.alias)
965 && !cnode->thunk.thunk_p
966 && !cnode->dispatcher_function)
968 cgraph_reset_node (cnode);
969 cnode->local.redefined_extern_inline = true;
970 continue;
973 if (!cnode->analyzed)
974 cgraph_analyze_function (cnode);
976 for (edge = cnode->callees; edge; edge = edge->next_callee)
977 if (edge->callee->local.finalized)
978 enqueue_node ((symtab_node)edge->callee);
980 /* If decl is a clone of an abstract function,
981 mark that abstract function so that we don't release its body.
982 The DECL_INITIAL() of that abstract function declaration
983 will be later needed to output debug info. */
984 if (DECL_ABSTRACT_ORIGIN (decl))
986 struct cgraph_node *origin_node
987 = cgraph_get_node (DECL_ABSTRACT_ORIGIN (decl));
988 origin_node->abstract_and_needed = true;
991 else
993 varpool_node *vnode = dyn_cast <varpool_node> (node);
994 if (vnode && vnode->finalized)
995 varpool_analyze_node (vnode);
998 if (node->symbol.same_comdat_group)
1000 symtab_node next;
1001 for (next = node->symbol.same_comdat_group;
1002 next != node;
1003 next = next->symbol.same_comdat_group)
1004 enqueue_node (next);
1006 for (i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list, i, ref); i++)
1007 if (symbol_finalized (ref->referred))
1008 enqueue_node (ref->referred);
1009 cgraph_process_new_functions ();
1013 /* Collect entry points to the unit. */
1014 if (cgraph_dump_file)
1016 fprintf (cgraph_dump_file, "\n\nInitial ");
1017 dump_symtab (cgraph_dump_file);
1020 if (cgraph_dump_file)
1021 fprintf (cgraph_dump_file, "\nRemoving unused symbols:");
1023 for (node = symtab_nodes;
1024 node != (symtab_node)first_handled
1025 && node != (symtab_node)first_handled_var; node = next)
1027 next = node->symbol.next;
1028 if (!node->symbol.aux && !referred_to_p (node))
1030 if (cgraph_dump_file)
1031 fprintf (cgraph_dump_file, " %s/%d", symtab_node_name (node), node->symbol.order);
1032 symtab_remove_node (node);
1033 continue;
1035 if (cgraph_node *cnode = dyn_cast <cgraph_node> (node))
1037 tree decl = node->symbol.decl;
1039 if (cnode->local.finalized && !gimple_has_body_p (decl)
1040 && (!cnode->alias || !cnode->thunk.alias)
1041 && !cnode->thunk.thunk_p)
1042 cgraph_reset_node (cnode);
1044 gcc_assert (!cnode->local.finalized || cnode->thunk.thunk_p
1045 || cnode->alias
1046 || gimple_has_body_p (decl));
1047 gcc_assert (cnode->analyzed == cnode->local.finalized);
1049 node->symbol.aux = NULL;
1051 first_analyzed = cgraph_first_function ();
1052 first_analyzed_var = varpool_first_variable ();
1053 if (cgraph_dump_file)
1055 fprintf (cgraph_dump_file, "\n\nReclaimed ");
1056 dump_symtab (cgraph_dump_file);
1058 bitmap_obstack_release (NULL);
1059 ggc_collect ();
1062 /* Translate the ugly representation of aliases as alias pairs into nice
1063 representation in callgraph. We don't handle all cases yet,
1064 unforutnately. */
1066 static void
1067 handle_alias_pairs (void)
1069 alias_pair *p;
1070 unsigned i;
1072 for (i = 0; alias_pairs && alias_pairs->iterate (i, &p);)
1074 symtab_node target_node = symtab_node_for_asm (p->target);
1076 /* Weakrefs with target not defined in current unit are easy to handle; they
1077 behave just as external variables except we need to note the alias flag
1078 to later output the weakref pseudo op into asm file. */
1079 if (!target_node && lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL)
1081 if (TREE_CODE (p->decl) == FUNCTION_DECL)
1082 cgraph_get_create_node (p->decl)->alias = true;
1083 else
1084 varpool_get_node (p->decl)->alias = true;
1085 DECL_EXTERNAL (p->decl) = 1;
1086 alias_pairs->unordered_remove (i);
1087 continue;
1089 else if (!target_node)
1091 error ("%q+D aliased to undefined symbol %qE", p->decl, p->target);
1092 alias_pairs->unordered_remove (i);
1093 continue;
1096 /* Normally EXTERNAL flag is used to mark external inlines,
1097 however for aliases it seems to be allowed to use it w/o
1098 any meaning. See gcc.dg/attr-alias-3.c
1099 However for weakref we insist on EXTERNAL flag being set.
1100 See gcc.dg/attr-alias-5.c */
1101 if (DECL_EXTERNAL (p->decl))
1102 DECL_EXTERNAL (p->decl)
1103 = lookup_attribute ("weakref",
1104 DECL_ATTRIBUTES (p->decl)) != NULL;
1106 if (DECL_EXTERNAL (target_node->symbol.decl)
1107 /* We use local aliases for C++ thunks to force the tailcall
1108 to bind locally. This is a hack - to keep it working do
1109 the following (which is not strictly correct). */
1110 && (! TREE_CODE (target_node->symbol.decl) == FUNCTION_DECL
1111 || ! DECL_VIRTUAL_P (target_node->symbol.decl))
1112 && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)))
1114 error ("%q+D aliased to external symbol %qE",
1115 p->decl, p->target);
1118 if (TREE_CODE (p->decl) == FUNCTION_DECL
1119 && target_node && is_a <cgraph_node> (target_node))
1121 struct cgraph_node *src_node = cgraph_get_node (p->decl);
1122 if (src_node && src_node->local.finalized)
1123 cgraph_reset_node (src_node);
1124 cgraph_create_function_alias (p->decl, target_node->symbol.decl);
1125 alias_pairs->unordered_remove (i);
1127 else if (TREE_CODE (p->decl) == VAR_DECL
1128 && target_node && is_a <varpool_node> (target_node))
1130 varpool_create_variable_alias (p->decl, target_node->symbol.decl);
1131 alias_pairs->unordered_remove (i);
1133 else
1135 error ("%q+D alias in between function and variable is not supported",
1136 p->decl);
1137 warning (0, "%q+D aliased declaration",
1138 target_node->symbol.decl);
1139 alias_pairs->unordered_remove (i);
1142 vec_free (alias_pairs);
1145 /* Hash function for symbol (function) resolution. */
1147 static hashval_t
1148 hash_node_by_assembler_name (const void *p)
1150 const struct cgraph_node *n = (const struct cgraph_node *) p;
1151 return (hashval_t) decl_assembler_name_hash (
1152 DECL_ASSEMBLER_NAME (n->symbol.decl));
1155 /* Equality function for cgraph_node table. */
1157 static int
1158 eq_node_assembler_name (const void *p1, const void *p2)
1160 const struct cgraph_node *n1 = (const struct cgraph_node *) p1;
1161 const_tree name = (const_tree)p2;
1162 return (decl_assembler_name_equal (n1->symbol.decl, name));
1165 /* In l-ipo mode compilation (light weight IPO), multiple bodies may
1166 be available for the same inline declared function. cgraph linking
1167 does not really merge them in order to keep the context (module info)
1168 of each body. After inlining, the linkage of the function may require
1169 them to be output (even if it is defined in an auxiliary module). This
1170 in term may result in duplicate emission. */
1172 static GTY((param_is (struct cgraph_node))) htab_t output_node_hash = NULL;
1174 /* Add NODE that is expanded into the hashtable. */
1176 static struct cgraph_node *
1177 cgraph_add_output_node (struct cgraph_node *node)
1179 void **aslot;
1180 tree name;
1182 if (!L_IPO_COMP_MODE)
1183 return node;
1185 /* Never common non public names except for compiler
1186 generated static functions. (they are not promoted
1187 to globals either. */
1188 if (!TREE_PUBLIC (node->symbol.decl)
1189 && !(DECL_ARTIFICIAL (node->symbol.decl)
1190 && DECL_ASSEMBLER_NAME_SET_P (node->symbol.decl)))
1191 return node;
1193 if (!output_node_hash)
1194 output_node_hash =
1195 htab_create_ggc (10, hash_node_by_assembler_name,
1196 eq_node_assembler_name, NULL);
1198 name = DECL_ASSEMBLER_NAME (node->symbol.decl);
1200 aslot = htab_find_slot_with_hash (output_node_hash, name,
1201 decl_assembler_name_hash (name),
1202 INSERT);
1203 if (*aslot == NULL)
1205 *aslot = node;
1206 return node;
1208 else
1209 return (struct cgraph_node *)(*aslot);
1212 #if ENABLE_CHECKING
1213 /* Return the cgraph_node if the function symbol for NODE is
1214 expanded in the output. Returns NULL otherwise. */
1216 static struct cgraph_node *
1217 cgraph_find_output_node (struct cgraph_node *node)
1219 void **aslot;
1220 tree name;
1222 if (!L_IPO_COMP_MODE)
1223 return node;
1225 /* We do not track non-public functions. */
1226 if (!TREE_PUBLIC (node->symbol.decl))
1227 return NULL;
1229 /* Never addedd. */
1230 if (!output_node_hash)
1231 return NULL;
1233 name = DECL_ASSEMBLER_NAME (node->symbol.decl);
1235 aslot = htab_find_slot_with_hash (output_node_hash, name,
1236 decl_assembler_name_hash (name),
1237 NO_INSERT);
1238 if (!aslot)
1239 return NULL;
1241 return (struct cgraph_node *)(*aslot);
1243 #endif
1246 #if ENABLE_CHECKING
1247 /* A function used in validation. Return true if NODE was
1248 not expanded and its body was not reclaimed. */
1250 static bool
1251 cgraph_node_expansion_skipped (struct cgraph_node *node)
1253 struct cgraph_node *output_node;
1255 if (!L_IPO_COMP_MODE)
1256 return false;
1258 output_node = cgraph_find_output_node (node);
1260 if (output_node == node)
1261 return false;
1263 if (output_node)
1264 return true;
1266 /* No output, no duplicate being output, and the node is not
1267 inlined (and reclaimed) either -- check if the caller node
1268 is output/expanded or not. */
1269 if (node->global.inlined_to)
1270 return cgraph_node_expansion_skipped (node->global.inlined_to);
1272 /* External functions not marked for output. */
1273 return true;
1275 #endif
1277 /* Figure out what functions we want to assemble. */
1279 static void
1280 mark_functions_to_output (void)
1282 struct cgraph_node *node;
1283 #ifdef ENABLE_CHECKING
1284 bool check_same_comdat_groups = false;
1286 FOR_EACH_FUNCTION (node)
1287 gcc_assert (!node->process);
1288 #endif
1290 FOR_EACH_FUNCTION (node)
1292 tree decl = node->symbol.decl;
1294 gcc_assert (!node->process || node->symbol.same_comdat_group);
1295 if (node->process)
1296 continue;
1298 /* We need to output all local functions that are used and not
1299 always inlined, as well as those that are reachable from
1300 outside the current compilation unit. */
1301 if (node->analyzed
1302 && !node->thunk.thunk_p
1303 && !node->alias
1304 && !node->global.inlined_to
1305 && !TREE_ASM_WRITTEN (decl)
1306 && !(DECL_EXTERNAL (decl) || cgraph_is_aux_decl_external (node)))
1308 if (cgraph_add_output_node (node) == node)
1310 node->process = 1;
1311 if (node->symbol.same_comdat_group)
1313 struct cgraph_node *next;
1314 for (next = cgraph (node->symbol.same_comdat_group);
1315 next != node;
1316 next = cgraph (next->symbol.same_comdat_group))
1317 if (!next->thunk.thunk_p && !next->alias
1318 && cgraph_add_output_node (next) == next)
1319 next->process = 1;
1323 else if (node->symbol.same_comdat_group)
1325 #ifdef ENABLE_CHECKING
1326 check_same_comdat_groups = true;
1327 #endif
1329 else
1331 /* We should've reclaimed all functions that are not needed. */
1332 #ifdef ENABLE_CHECKING
1333 if (!node->global.inlined_to
1334 && gimple_has_body_p (decl)
1335 /* FIXME: in ltrans unit when offline copy is outside partition but inline copies
1336 are inside partition, we can end up not removing the body since we no longer
1337 have analyzed node pointing to it. */
1338 && !node->symbol.in_other_partition
1339 && !node->alias
1340 && !cgraph_is_auxiliary (node->symbol.decl)
1341 && !node->clones
1342 && !DECL_EXTERNAL (decl))
1344 dump_cgraph_node (stderr, node);
1345 internal_error ("failed to reclaim unneeded function");
1347 #endif
1348 gcc_assert (node->global.inlined_to
1349 || !gimple_has_body_p (decl)
1350 || node->symbol.in_other_partition
1351 || node->clones
1352 || DECL_ARTIFICIAL (decl)
1353 || DECL_EXTERNAL (decl)
1354 || cgraph_is_auxiliary (node->symbol.decl));
1359 #ifdef ENABLE_CHECKING
1360 if (check_same_comdat_groups && !L_IPO_COMP_MODE)
1361 FOR_EACH_FUNCTION (node)
1362 if (node->symbol.same_comdat_group && !node->process)
1364 tree decl = node->symbol.decl;
1365 if (!node->global.inlined_to
1366 && gimple_has_body_p (decl)
1367 /* FIXME: in an ltrans unit when the offline copy is outside a
1368 partition but inline copies are inside a partition, we can
1369 end up not removing the body since we no longer have an
1370 analyzed node pointing to it. */
1371 && !node->symbol.in_other_partition
1372 && !node->clones
1373 && !(DECL_EXTERNAL (decl) || cgraph_is_aux_decl_external (node))
1374 && !L_IPO_COMP_MODE)
1376 dump_cgraph_node (stderr, node);
1377 internal_error ("failed to reclaim unneeded function in same "
1378 "comdat group");
1381 #endif
1384 /* DECL is FUNCTION_DECL. Initialize datastructures so DECL is a function
1385 in lowered gimple form. IN_SSA is true if the gimple is in SSA.
1387 Set current_function_decl and cfun to newly constructed empty function body.
1388 return basic block in the function body. */
1390 basic_block
1391 init_lowered_empty_function (tree decl, bool in_ssa)
1393 basic_block bb;
1395 current_function_decl = decl;
1396 allocate_struct_function (decl, false);
1397 gimple_register_cfg_hooks ();
1398 init_empty_tree_cfg ();
1400 if (in_ssa)
1402 init_tree_ssa (cfun);
1403 init_ssa_operands (cfun);
1404 cfun->gimple_df->in_ssa_p = true;
1407 DECL_INITIAL (decl) = make_node (BLOCK);
1409 DECL_SAVED_TREE (decl) = error_mark_node;
1410 cfun->curr_properties |=
1411 (PROP_gimple_lcf | PROP_gimple_leh | PROP_cfg | PROP_ssa | PROP_gimple_any);
1413 /* Create BB for body of the function and connect it properly. */
1414 bb = create_basic_block (NULL, (void *) 0, ENTRY_BLOCK_PTR);
1415 make_edge (ENTRY_BLOCK_PTR, bb, 0);
1416 make_edge (bb, EXIT_BLOCK_PTR, 0);
1418 return bb;
1421 /* Adjust PTR by the constant FIXED_OFFSET, and by the vtable
1422 offset indicated by VIRTUAL_OFFSET, if that is
1423 non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and
1424 zero for a result adjusting thunk. */
1426 static tree
1427 thunk_adjust (gimple_stmt_iterator * bsi,
1428 tree ptr, bool this_adjusting,
1429 HOST_WIDE_INT fixed_offset, tree virtual_offset)
1431 gimple stmt;
1432 tree ret;
1434 if (this_adjusting
1435 && fixed_offset != 0)
1437 stmt = gimple_build_assign
1438 (ptr, fold_build_pointer_plus_hwi_loc (input_location,
1439 ptr,
1440 fixed_offset));
1441 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1444 /* If there's a virtual offset, look up that value in the vtable and
1445 adjust the pointer again. */
1446 if (virtual_offset)
1448 tree vtabletmp;
1449 tree vtabletmp2;
1450 tree vtabletmp3;
1452 if (!vtable_entry_type)
1454 tree vfunc_type = make_node (FUNCTION_TYPE);
1455 TREE_TYPE (vfunc_type) = integer_type_node;
1456 TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
1457 layout_type (vfunc_type);
1459 vtable_entry_type = build_pointer_type (vfunc_type);
1462 vtabletmp =
1463 create_tmp_reg (build_pointer_type
1464 (build_pointer_type (vtable_entry_type)), "vptr");
1466 /* The vptr is always at offset zero in the object. */
1467 stmt = gimple_build_assign (vtabletmp,
1468 build1 (NOP_EXPR, TREE_TYPE (vtabletmp),
1469 ptr));
1470 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1472 /* Form the vtable address. */
1473 vtabletmp2 = create_tmp_reg (TREE_TYPE (TREE_TYPE (vtabletmp)),
1474 "vtableaddr");
1475 stmt = gimple_build_assign (vtabletmp2,
1476 build_simple_mem_ref (vtabletmp));
1477 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1479 /* Find the entry with the vcall offset. */
1480 stmt = gimple_build_assign (vtabletmp2,
1481 fold_build_pointer_plus_loc (input_location,
1482 vtabletmp2,
1483 virtual_offset));
1484 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1486 /* Get the offset itself. */
1487 vtabletmp3 = create_tmp_reg (TREE_TYPE (TREE_TYPE (vtabletmp2)),
1488 "vcalloffset");
1489 stmt = gimple_build_assign (vtabletmp3,
1490 build_simple_mem_ref (vtabletmp2));
1491 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1493 /* Adjust the `this' pointer. */
1494 ptr = fold_build_pointer_plus_loc (input_location, ptr, vtabletmp3);
1495 ptr = force_gimple_operand_gsi (bsi, ptr, true, NULL_TREE, false,
1496 GSI_CONTINUE_LINKING);
1499 if (!this_adjusting
1500 && fixed_offset != 0)
1501 /* Adjust the pointer by the constant. */
1503 tree ptrtmp;
1505 if (TREE_CODE (ptr) == VAR_DECL)
1506 ptrtmp = ptr;
1507 else
1509 ptrtmp = create_tmp_reg (TREE_TYPE (ptr), "ptr");
1510 stmt = gimple_build_assign (ptrtmp, ptr);
1511 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1513 ptr = fold_build_pointer_plus_hwi_loc (input_location,
1514 ptrtmp, fixed_offset);
1517 /* Emit the statement and gimplify the adjustment expression. */
1518 ret = create_tmp_reg (TREE_TYPE (ptr), "adjusted_this");
1519 stmt = gimple_build_assign (ret, ptr);
1520 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1522 return ret;
1525 /* Produce assembler for thunk NODE. */
1527 static void
1528 assemble_thunk (struct cgraph_node *node)
1530 bool this_adjusting = node->thunk.this_adjusting;
1531 HOST_WIDE_INT fixed_offset = node->thunk.fixed_offset;
1532 HOST_WIDE_INT virtual_value = node->thunk.virtual_value;
1533 tree virtual_offset = NULL;
1534 tree alias = node->thunk.alias;
1535 tree thunk_fndecl = node->symbol.decl;
1536 tree a = DECL_ARGUMENTS (thunk_fndecl);
1538 current_function_decl = thunk_fndecl;
1540 /* Ensure thunks are emitted in their correct sections. */
1541 resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
1543 if (this_adjusting
1544 && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
1545 virtual_value, alias))
1547 const char *fnname;
1548 tree fn_block;
1549 tree restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1551 DECL_RESULT (thunk_fndecl)
1552 = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl),
1553 RESULT_DECL, 0, restype);
1554 fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
1556 /* The back end expects DECL_INITIAL to contain a BLOCK, so we
1557 create one. */
1558 fn_block = make_node (BLOCK);
1559 BLOCK_VARS (fn_block) = a;
1560 DECL_INITIAL (thunk_fndecl) = fn_block;
1561 init_function_start (thunk_fndecl);
1562 cfun->is_thunk = 1;
1563 insn_locations_init ();
1564 set_curr_insn_location (DECL_SOURCE_LOCATION (thunk_fndecl));
1565 prologue_location = curr_insn_location ();
1566 assemble_start_function (thunk_fndecl, fnname);
1568 targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl,
1569 fixed_offset, virtual_value, alias);
1571 assemble_end_function (thunk_fndecl, fnname);
1572 insn_locations_finalize ();
1573 init_insn_lengths ();
1574 free_after_compilation (cfun);
1575 set_cfun (NULL);
1576 TREE_ASM_WRITTEN (thunk_fndecl) = 1;
1577 node->thunk.thunk_p = false;
1578 node->analyzed = false;
1580 else
1582 tree restype;
1583 basic_block bb, then_bb, else_bb, return_bb;
1584 gimple_stmt_iterator bsi;
1585 int nargs = 0;
1586 tree arg;
1587 int i;
1588 tree resdecl;
1589 tree restmp = NULL;
1590 vec<tree> vargs;
1592 gimple call;
1593 gimple ret;
1595 DECL_IGNORED_P (thunk_fndecl) = 1;
1596 bitmap_obstack_initialize (NULL);
1598 if (node->thunk.virtual_offset_p)
1599 virtual_offset = size_int (virtual_value);
1601 /* Build the return declaration for the function. */
1602 restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1603 if (DECL_RESULT (thunk_fndecl) == NULL_TREE)
1605 resdecl = build_decl (input_location, RESULT_DECL, 0, restype);
1606 DECL_ARTIFICIAL (resdecl) = 1;
1607 DECL_IGNORED_P (resdecl) = 1;
1608 DECL_RESULT (thunk_fndecl) = resdecl;
1610 else
1611 resdecl = DECL_RESULT (thunk_fndecl);
1613 bb = then_bb = else_bb = return_bb = init_lowered_empty_function (thunk_fndecl, true);
1615 bsi = gsi_start_bb (bb);
1617 /* Build call to the function being thunked. */
1618 if (!VOID_TYPE_P (restype))
1620 if (!is_gimple_reg_type (restype))
1622 restmp = resdecl;
1623 add_local_decl (cfun, restmp);
1624 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp;
1626 else
1627 restmp = create_tmp_reg (restype, "retval");
1630 for (arg = a; arg; arg = DECL_CHAIN (arg))
1631 nargs++;
1632 vargs.create (nargs);
1633 if (this_adjusting)
1634 vargs.quick_push (thunk_adjust (&bsi, a, 1, fixed_offset,
1635 virtual_offset));
1636 else
1637 vargs.quick_push (a);
1638 for (i = 1, arg = DECL_CHAIN (a); i < nargs; i++, arg = DECL_CHAIN (arg))
1639 vargs.quick_push (arg);
1640 call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs);
1641 vargs.release ();
1642 gimple_call_set_from_thunk (call, true);
1643 if (restmp)
1644 gimple_call_set_lhs (call, restmp);
1645 gsi_insert_after (&bsi, call, GSI_NEW_STMT);
1647 if (restmp && !this_adjusting)
1649 tree true_label = NULL_TREE;
1651 if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE)
1653 gimple stmt;
1654 /* If the return type is a pointer, we need to
1655 protect against NULL. We know there will be an
1656 adjustment, because that's why we're emitting a
1657 thunk. */
1658 then_bb = create_basic_block (NULL, (void *) 0, bb);
1659 return_bb = create_basic_block (NULL, (void *) 0, then_bb);
1660 else_bb = create_basic_block (NULL, (void *) 0, else_bb);
1661 remove_edge (single_succ_edge (bb));
1662 true_label = gimple_block_label (then_bb);
1663 stmt = gimple_build_cond (NE_EXPR, restmp,
1664 build_zero_cst (TREE_TYPE (restmp)),
1665 NULL_TREE, NULL_TREE);
1666 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1667 make_edge (bb, then_bb, EDGE_TRUE_VALUE);
1668 make_edge (bb, else_bb, EDGE_FALSE_VALUE);
1669 make_edge (return_bb, EXIT_BLOCK_PTR, 0);
1670 make_edge (then_bb, return_bb, EDGE_FALLTHRU);
1671 make_edge (else_bb, return_bb, EDGE_FALLTHRU);
1672 bsi = gsi_last_bb (then_bb);
1675 restmp = thunk_adjust (&bsi, restmp, /*this_adjusting=*/0,
1676 fixed_offset, virtual_offset);
1677 if (true_label)
1679 gimple stmt;
1680 bsi = gsi_last_bb (else_bb);
1681 stmt = gimple_build_assign (restmp,
1682 build_zero_cst (TREE_TYPE (restmp)));
1683 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1684 bsi = gsi_last_bb (return_bb);
1687 else
1688 gimple_call_set_tail (call, true);
1690 /* Build return value. */
1691 ret = gimple_build_return (restmp);
1692 gsi_insert_after (&bsi, ret, GSI_NEW_STMT);
1694 delete_unreachable_blocks ();
1695 update_ssa (TODO_update_ssa);
1697 /* Since we want to emit the thunk, we explicitly mark its name as
1698 referenced. */
1699 node->thunk.thunk_p = false;
1700 cgraph_node_remove_callees (node);
1701 cgraph_add_new_function (thunk_fndecl, true);
1702 bitmap_obstack_release (NULL);
1704 current_function_decl = NULL;
1705 set_cfun (NULL);
1710 /* Assemble thunks and aliases associated to NODE. */
1712 static void
1713 assemble_thunks_and_aliases (struct cgraph_node *node)
1715 struct cgraph_edge *e;
1716 int i;
1717 struct ipa_ref *ref;
1719 for (e = node->callers; e;)
1720 if (e->caller->thunk.thunk_p)
1722 struct cgraph_node *thunk = e->caller;
1724 e = e->next_caller;
1725 assemble_thunks_and_aliases (thunk);
1726 assemble_thunk (thunk);
1728 else
1729 e = e->next_caller;
1730 for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list,
1731 i, ref); i++)
1732 if (ref->use == IPA_REF_ALIAS)
1734 struct cgraph_node *alias = ipa_ref_referring_node (ref);
1735 bool saved_written = TREE_ASM_WRITTEN (alias->thunk.alias);
1737 /* Force assemble_alias to really output the alias this time instead
1738 of buffering it in same alias pairs. */
1739 TREE_ASM_WRITTEN (alias->thunk.alias) = 1;
1740 do_assemble_alias (alias->symbol.decl,
1741 DECL_ASSEMBLER_NAME (alias->thunk.alias));
1742 assemble_thunks_and_aliases (alias);
1743 TREE_ASM_WRITTEN (alias->thunk.alias) = saved_written;
1747 /* Expand function specified by NODE. */
1749 static void
1750 expand_function (struct cgraph_node *node)
1752 tree decl = node->symbol.decl;
1753 location_t saved_loc;
1755 /* We ought to not compile any inline clones. */
1756 gcc_assert (!node->global.inlined_to);
1758 announce_function (decl);
1759 node->process = 0;
1760 gcc_assert (node->lowered);
1762 /* Generate RTL for the body of DECL. */
1764 timevar_push (TV_REST_OF_COMPILATION);
1766 gcc_assert (cgraph_global_info_ready);
1768 /* Initialize the default bitmap obstack. */
1769 bitmap_obstack_initialize (NULL);
1771 /* Initialize the RTL code for the function. */
1772 current_function_decl = decl;
1773 saved_loc = input_location;
1774 input_location = DECL_SOURCE_LOCATION (decl);
1775 init_function_start (decl);
1777 gimple_register_cfg_hooks ();
1779 bitmap_obstack_initialize (&reg_obstack); /* FIXME, only at RTL generation*/
1781 execute_all_ipa_transforms ();
1783 /* Perform all tree transforms and optimizations. */
1785 /* Signal the start of passes. */
1786 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START, NULL);
1788 execute_pass_list (all_passes);
1790 /* Signal the end of passes. */
1791 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END, NULL);
1793 bitmap_obstack_release (&reg_obstack);
1795 /* Release the default bitmap obstack. */
1796 bitmap_obstack_release (NULL);
1798 /* If requested, warn about function definitions where the function will
1799 return a value (usually of some struct or union type) which itself will
1800 take up a lot of stack space. */
1801 if (warn_larger_than && !DECL_EXTERNAL (decl) && TREE_TYPE (decl))
1803 tree ret_type = TREE_TYPE (TREE_TYPE (decl));
1805 if (ret_type && TYPE_SIZE_UNIT (ret_type)
1806 && TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST
1807 && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type),
1808 larger_than_size))
1810 unsigned int size_as_int
1811 = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type));
1813 if (compare_tree_int (TYPE_SIZE_UNIT (ret_type), size_as_int) == 0)
1814 warning (OPT_Wlarger_than_, "size of return value of %q+D is %u bytes",
1815 decl, size_as_int);
1816 else
1817 warning (OPT_Wlarger_than_, "size of return value of %q+D is larger than %wd bytes",
1818 decl, larger_than_size);
1822 gimple_set_body (decl, NULL);
1823 if (DECL_STRUCT_FUNCTION (decl) == 0
1824 && !cgraph_get_node (decl)->origin)
1826 /* Stop pointing to the local nodes about to be freed.
1827 But DECL_INITIAL must remain nonzero so we know this
1828 was an actual function definition.
1829 For a nested function, this is done in c_pop_function_context.
1830 If rest_of_compilation set this to 0, leave it 0. */
1831 if (DECL_INITIAL (decl) != 0)
1832 DECL_INITIAL (decl) = error_mark_node;
1835 input_location = saved_loc;
1837 ggc_collect ();
1838 timevar_pop (TV_REST_OF_COMPILATION);
1840 /* Make sure that BE didn't give up on compiling. */
1841 gcc_assert (TREE_ASM_WRITTEN (decl));
1842 set_cfun (NULL);
1843 current_function_decl = NULL;
1845 /* It would make a lot more sense to output thunks before function body to get more
1846 forward and lest backwarding jumps. This however would need solving problem
1847 with comdats. See PR48668. Also aliases must come after function itself to
1848 make one pass assemblers, like one on AIX, happy. See PR 50689.
1849 FIXME: Perhaps thunks should be move before function IFF they are not in comdat
1850 groups. */
1851 assemble_thunks_and_aliases (node);
1852 cgraph_release_function_body (node);
1853 /* Eliminate all call edges. This is important so the GIMPLE_CALL no longer
1854 points to the dead function body. */
1855 cgraph_node_remove_callees (node);
1859 /* Expand all functions that must be output.
1861 Attempt to topologically sort the nodes so function is output when
1862 all called functions are already assembled to allow data to be
1863 propagated across the callgraph. Use a stack to get smaller distance
1864 between a function and its callees (later we may choose to use a more
1865 sophisticated algorithm for function reordering; we will likely want
1866 to use subsections to make the output functions appear in top-down
1867 order). */
1869 static void
1870 expand_all_functions (void)
1872 struct cgraph_node *node;
1873 struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
1874 int order_pos, new_order_pos = 0;
1875 int i;
1877 order_pos = ipa_reverse_postorder (order);
1878 gcc_assert (order_pos == cgraph_n_nodes);
1880 /* Garbage collector may remove inline clones we eliminate during
1881 optimization. So we must be sure to not reference them. */
1882 for (i = 0; i < order_pos; i++)
1883 if (order[i]->process)
1884 order[new_order_pos++] = order[i];
1886 for (i = new_order_pos - 1; i >= 0; i--)
1888 node = order[i];
1889 if (node->process)
1891 node->process = 0;
1892 expand_function (node);
1895 cgraph_process_new_functions ();
1897 free (order);
1901 /* This is used to sort the node types by the cgraph order number. */
1903 enum cgraph_order_sort_kind
1905 ORDER_UNDEFINED = 0,
1906 ORDER_FUNCTION,
1907 ORDER_VAR,
1908 ORDER_ASM
1911 struct cgraph_order_sort
1913 enum cgraph_order_sort_kind kind;
1914 union
1916 struct cgraph_node *f;
1917 struct varpool_node *v;
1918 struct asm_node *a;
1919 } u;
1922 /* Output all functions, variables, and asm statements in the order
1923 according to their order fields, which is the order in which they
1924 appeared in the file. This implements -fno-toplevel-reorder. In
1925 this mode we may output functions and variables which don't really
1926 need to be output. */
1928 static void
1929 output_in_order (void)
1931 int max;
1932 struct cgraph_order_sort *nodes;
1933 int i;
1934 struct cgraph_node *pf;
1935 struct varpool_node *pv;
1936 struct asm_node *pa;
1938 max = symtab_order;
1939 nodes = XCNEWVEC (struct cgraph_order_sort, max);
1941 varpool_remove_duplicate_weak_decls ();
1943 FOR_EACH_DEFINED_FUNCTION (pf)
1945 if (pf->process && !pf->thunk.thunk_p && !pf->alias)
1947 i = pf->symbol.order;
1948 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1949 nodes[i].kind = ORDER_FUNCTION;
1950 nodes[i].u.f = pf;
1954 FOR_EACH_DEFINED_VARIABLE (pv)
1955 if (!DECL_EXTERNAL (pv->symbol.decl))
1957 i = pv->symbol.order;
1958 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1959 nodes[i].kind = ORDER_VAR;
1960 nodes[i].u.v = pv;
1963 for (pa = asm_nodes; pa; pa = pa->next)
1965 i = pa->order;
1966 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1967 nodes[i].kind = ORDER_ASM;
1968 nodes[i].u.a = pa;
1971 /* In toplevel reorder mode we output all statics; mark them as needed. */
1973 for (i = 0; i < max; ++i)
1974 if (nodes[i].kind == ORDER_VAR)
1975 varpool_finalize_named_section_flags (nodes[i].u.v);
1977 for (i = 0; i < max; ++i)
1979 switch (nodes[i].kind)
1981 case ORDER_FUNCTION:
1982 nodes[i].u.f->process = 0;
1983 expand_function (nodes[i].u.f);
1984 break;
1986 case ORDER_VAR:
1987 varpool_assemble_decl (nodes[i].u.v);
1988 break;
1990 case ORDER_ASM:
1991 assemble_asm (nodes[i].u.a->asm_str);
1992 break;
1994 case ORDER_UNDEFINED:
1995 break;
1997 default:
1998 gcc_unreachable ();
2002 asm_nodes = NULL;
2003 free (nodes);
2006 static void
2007 ipa_passes (void)
2009 set_cfun (NULL);
2010 current_function_decl = NULL;
2011 gimple_register_cfg_hooks ();
2012 bitmap_obstack_initialize (NULL);
2014 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START, NULL);
2016 if (!in_lto_p)
2018 execute_ipa_pass_list (all_small_ipa_passes);
2019 if (seen_error ())
2020 return;
2023 /* We never run removal of unreachable nodes after early passes. This is
2024 because TODO is run before the subpasses. It is important to remove
2025 the unreachable functions to save works at IPA level and to get LTO
2026 symbol tables right. */
2027 symtab_remove_unreachable_nodes (true, cgraph_dump_file);
2029 /* If pass_all_early_optimizations was not scheduled, the state of
2030 the cgraph will not be properly updated. Update it now. */
2031 if (cgraph_state < CGRAPH_STATE_IPA_SSA)
2032 cgraph_state = CGRAPH_STATE_IPA_SSA;
2034 if (!in_lto_p)
2036 /* Generate coverage variables and constructors.
2037 In LIPO mode, delay this until direct call profiling
2038 is done. */
2039 if (!flag_dyn_ipa)
2040 coverage_finish ();
2042 /* Process new functions added. */
2043 set_cfun (NULL);
2044 current_function_decl = NULL;
2045 cgraph_process_new_functions ();
2047 execute_ipa_summary_passes
2048 ((struct ipa_opt_pass_d *) all_regular_ipa_passes);
2051 /* Some targets need to handle LTO assembler output specially. */
2052 if (flag_generate_lto)
2053 targetm.asm_out.lto_start ();
2055 execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_lto_gen_passes);
2057 if (!in_lto_p)
2058 ipa_write_summaries ();
2060 if (flag_generate_lto)
2061 targetm.asm_out.lto_end ();
2063 if (!flag_ltrans && (in_lto_p || !flag_lto || flag_fat_lto_objects))
2064 execute_ipa_pass_list (all_regular_ipa_passes);
2065 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END, NULL);
2067 bitmap_obstack_release (NULL);
2071 /* Return string alias is alias of. */
2073 static tree
2074 get_alias_symbol (tree decl)
2076 tree alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
2077 return get_identifier (TREE_STRING_POINTER
2078 (TREE_VALUE (TREE_VALUE (alias))));
2082 /* Weakrefs may be associated to external decls and thus not output
2083 at expansion time. Emit all necessary aliases. */
2085 static void
2086 output_weakrefs (void)
2088 struct cgraph_node *node;
2089 struct varpool_node *vnode;
2090 FOR_EACH_FUNCTION (node)
2091 if (node->alias && DECL_EXTERNAL (node->symbol.decl)
2092 && !TREE_ASM_WRITTEN (node->symbol.decl)
2093 && lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
2094 do_assemble_alias (node->symbol.decl,
2095 node->thunk.alias ? DECL_ASSEMBLER_NAME (node->thunk.alias)
2096 : get_alias_symbol (node->symbol.decl));
2097 FOR_EACH_VARIABLE (vnode)
2098 if (vnode->alias && DECL_EXTERNAL (vnode->symbol.decl)
2099 && !TREE_ASM_WRITTEN (vnode->symbol.decl)
2100 && lookup_attribute ("weakref", DECL_ATTRIBUTES (vnode->symbol.decl)))
2101 do_assemble_alias (vnode->symbol.decl,
2102 vnode->alias_of ? DECL_ASSEMBLER_NAME (vnode->alias_of)
2103 : get_alias_symbol (vnode->symbol.decl));
2106 /* Initialize callgraph dump file. */
2108 void
2109 init_cgraph (void)
2111 if (!cgraph_dump_file)
2112 cgraph_dump_file = dump_begin (TDI_cgraph, NULL);
2116 /* Perform simple optimizations based on callgraph. */
2118 void
2119 compile (void)
2121 if (seen_error ())
2122 return;
2124 #ifdef ENABLE_CHECKING
2125 verify_symtab ();
2126 #endif
2128 timevar_push (TV_CGRAPHOPT);
2129 if (pre_ipa_mem_report)
2131 fprintf (stderr, "Memory consumption before IPA\n");
2132 dump_memory_report (false);
2134 if (!quiet_flag)
2135 fprintf (stderr, "Performing interprocedural optimizations\n");
2136 cgraph_state = CGRAPH_STATE_IPA;
2138 if (L_IPO_COMP_MODE)
2140 cgraph_init_gid_map ();
2141 cgraph_add_fake_indirect_call_edges ();
2144 /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE. */
2145 if (flag_lto)
2146 lto_streamer_hooks_init ();
2148 /* Don't run the IPA passes if there was any error or sorry messages. */
2149 if (!seen_error ())
2150 ipa_passes ();
2152 /* Do nothing else if any IPA pass found errors or if we are just streaming LTO. */
2153 if (seen_error ()
2154 || (!in_lto_p && flag_lto && !flag_fat_lto_objects))
2156 timevar_pop (TV_CGRAPHOPT);
2157 return;
2160 /* This pass remove bodies of extern inline functions we never inlined.
2161 Do this later so other IPA passes see what is really going on. */
2162 symtab_remove_unreachable_nodes (false, dump_file);
2163 cgraph_global_info_ready = true;
2164 if (cgraph_dump_file)
2166 fprintf (cgraph_dump_file, "Optimized ");
2167 dump_symtab (cgraph_dump_file);
2169 if (post_ipa_mem_report)
2171 fprintf (stderr, "Memory consumption after IPA\n");
2172 dump_memory_report (false);
2174 timevar_pop (TV_CGRAPHOPT);
2176 /* Output everything. */
2177 (*debug_hooks->assembly_start) ();
2178 if (!quiet_flag)
2179 fprintf (stderr, "Assembling functions:\n");
2180 #ifdef ENABLE_CHECKING
2181 verify_symtab ();
2182 #endif
2184 cgraph_materialize_all_clones ();
2185 bitmap_obstack_initialize (NULL);
2186 execute_ipa_pass_list (all_late_ipa_passes);
2187 symtab_remove_unreachable_nodes (true, dump_file);
2188 #ifdef ENABLE_CHECKING
2189 verify_symtab ();
2190 #endif
2191 bitmap_obstack_release (NULL);
2192 mark_functions_to_output ();
2194 cgraph_state = CGRAPH_STATE_EXPANSION;
2195 if (!flag_toplevel_reorder)
2196 output_in_order ();
2197 else
2199 output_asm_statements ();
2201 expand_all_functions ();
2202 varpool_remove_duplicate_weak_decls ();
2203 varpool_output_variables ();
2206 cgraph_process_new_functions ();
2207 cgraph_state = CGRAPH_STATE_FINISHED;
2208 output_weakrefs ();
2210 if (cgraph_dump_file)
2212 fprintf (cgraph_dump_file, "\nFinal ");
2213 dump_symtab (cgraph_dump_file);
2215 #ifdef ENABLE_CHECKING
2216 verify_symtab ();
2217 /* Double check that all inline clones are gone and that all
2218 function bodies have been released from memory.
2219 As an exception, allow inline clones in the callgraph if
2220 they are auxiliary functions. This is because we don't
2221 expand any of the auxiliary functions, which may result
2222 in inline clones of some auxiliary functions to be left
2223 in the callgraph. */
2224 if (!seen_error ())
2226 struct cgraph_node *node;
2227 bool error_found = false;
2229 FOR_EACH_DEFINED_FUNCTION (node)
2230 if (((node->global.inlined_to && !cgraph_is_auxiliary (node->symbol.decl))
2231 || gimple_has_body_p (node->symbol.decl))
2232 && !cgraph_node_expansion_skipped (node))
2234 error_found = true;
2235 dump_cgraph_node (stderr, node);
2237 if (error_found)
2238 internal_error ("nodes with unreleased memory found");
2240 #endif
2244 /* Analyze the whole compilation unit once it is parsed completely. */
2246 void
2247 finalize_compilation_unit (void)
2249 timevar_push (TV_CGRAPH);
2251 /* If we're here there's no current function anymore. Some frontends
2252 are lazy in clearing these. */
2253 current_function_decl = NULL;
2254 set_cfun (NULL);
2256 /* Do not skip analyzing the functions if there were errors, we
2257 miss diagnostics for following functions otherwise. */
2259 /* Emit size functions we didn't inline. */
2260 finalize_size_functions ();
2262 /* Mark alias targets necessary and emit diagnostics. */
2263 handle_alias_pairs ();
2265 if (!quiet_flag)
2267 fprintf (stderr, "\nAnalyzing compilation unit\n");
2268 fflush (stderr);
2271 if (flag_dump_passes)
2272 dump_passes ();
2274 /* Gimplify and lower all functions, compute reachability and
2275 remove unreachable nodes. */
2276 cgraph_analyze_functions ();
2278 /* Mark alias targets necessary and emit diagnostics. */
2279 handle_alias_pairs ();
2281 /* Gimplify and lower thunks. */
2282 cgraph_analyze_functions ();
2284 /* Finally drive the pass manager. */
2285 compile ();
2287 timevar_pop (TV_CGRAPH);
2291 #include "gt-cgraphunit.h"