OpenACC acc_on_device.
[official-gcc.git] / gcc / cgraphunit.c
blob510165fd0e3499f201e61bd126b6691dd644d991
1 /* Driver of optimization process
2 Copyright (C) 2003-2014 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 - finalize_function
30 This function is called once front-end has parsed whole body of function
31 and it is certain that the function body nor the declaration will change.
33 (There is one exception needed for implementing GCC extern inline
34 function.)
36 - varpool_finalize_decl
38 This function has same behavior as the above but is used for static
39 variables.
41 - add_asm_node
43 Insert new toplevel ASM statement
45 - finalize_compilation_unit
47 This function is called once (source level) compilation unit is finalized
48 and it will no longer change.
50 The symbol table is constructed starting from the trivially needed
51 symbols finalized by the frontend. Functions are lowered into
52 GIMPLE representation and callgraph/reference lists are constructed.
53 Those are used to discover other necessary functions and variables.
55 At the end the bodies of unreachable functions are removed.
57 The function can be called multiple times when multiple source level
58 compilation units are combined.
60 - compile
62 This passes control to the back-end. Optimizations are performed and
63 final assembler is generated. This is done in the following way. Note
64 that with link time optimization the process is split into three
65 stages (compile time, linktime analysis and parallel linktime as
66 indicated bellow).
68 Compile time:
70 1) Inter-procedural optimization.
71 (ipa_passes)
73 This part is further split into:
75 a) early optimizations. These are local passes executed in
76 the topological order on the callgraph.
78 The purpose of early optimiations is to optimize away simple
79 things that may otherwise confuse IP analysis. Very simple
80 propagation across the callgraph is done i.e. to discover
81 functions without side effects and simple inlining is performed.
83 b) early small interprocedural passes.
85 Those are interprocedural passes executed only at compilation
86 time. These include, for example, transational memory lowering,
87 unreachable code removal and other simple transformations.
89 c) IP analysis stage. All interprocedural passes do their
90 analysis.
92 Interprocedural passes differ from small interprocedural
93 passes by their ability to operate across whole program
94 at linktime. Their analysis stage is performed early to
95 both reduce linking times and linktime memory usage by
96 not having to represent whole program in memory.
98 d) LTO sreaming. When doing LTO, everything important gets
99 streamed into the object file.
101 Compile time and or linktime analysis stage (WPA):
103 At linktime units gets streamed back and symbol table is
104 merged. Function bodies are not streamed in and not
105 available.
106 e) IP propagation stage. All IP passes execute their
107 IP propagation. This is done based on the earlier analysis
108 without having function bodies at hand.
109 f) Ltrans streaming. When doing WHOPR LTO, the program
110 is partitioned and streamed into multple object files.
112 Compile time and/or parallel linktime stage (ltrans)
114 Each of the object files is streamed back and compiled
115 separately. Now the function bodies becomes available
116 again.
118 2) Virtual clone materialization
119 (cgraph_materialize_clone)
121 IP passes can produce copies of existing functoins (such
122 as versioned clones or inline clones) without actually
123 manipulating their bodies by creating virtual clones in
124 the callgraph. At this time the virtual clones are
125 turned into real functions
126 3) IP transformation
128 All IP passes transform function bodies based on earlier
129 decision of the IP propagation.
131 4) late small IP passes
133 Simple IP passes working within single program partition.
135 5) Expansion
136 (expand_all_functions)
138 At this stage functions that needs to be output into
139 assembler are identified and compiled in topological order
140 6) Output of variables and aliases
141 Now it is known what variable references was not optimized
142 out and thus all variables are output to the file.
144 Note that with -fno-toplevel-reorder passes 5 and 6
145 are combined together in cgraph_output_in_order.
147 Finally there are functions to manipulate the callgraph from
148 backend.
149 - cgraph_add_new_function is used to add backend produced
150 functions introduced after the unit is finalized.
151 The functions are enqueue for later processing and inserted
152 into callgraph with cgraph_process_new_functions.
154 - cgraph_function_versioning
156 produces a copy of function into new one (a version)
157 and apply simple transformations
160 #include "config.h"
161 #include "system.h"
162 #include "coretypes.h"
163 #include "tm.h"
164 #include "tree.h"
165 #include "varasm.h"
166 #include "stor-layout.h"
167 #include "stringpool.h"
168 #include "output.h"
169 #include "rtl.h"
170 #include "basic-block.h"
171 #include "tree-ssa-alias.h"
172 #include "internal-fn.h"
173 #include "gimple-fold.h"
174 #include "gimple-expr.h"
175 #include "is-a.h"
176 #include "gimple.h"
177 #include "gimplify.h"
178 #include "gimple-iterator.h"
179 #include "gimplify-me.h"
180 #include "gimple-ssa.h"
181 #include "tree-cfg.h"
182 #include "tree-into-ssa.h"
183 #include "tree-ssa.h"
184 #include "tree-inline.h"
185 #include "langhooks.h"
186 #include "toplev.h"
187 #include "flags.h"
188 #include "debug.h"
189 #include "target.h"
190 #include "diagnostic.h"
191 #include "params.h"
192 #include "fibheap.h"
193 #include "intl.h"
194 #include "function.h"
195 #include "ipa-prop.h"
196 #include "tree-iterator.h"
197 #include "tree-pass.h"
198 #include "tree-dump.h"
199 #include "gimple-pretty-print.h"
200 #include "output.h"
201 #include "coverage.h"
202 #include "plugin.h"
203 #include "ipa-inline.h"
204 #include "ipa-utils.h"
205 #include "lto-streamer.h"
206 #include "except.h"
207 #include "cfgloop.h"
208 #include "regset.h" /* FIXME: For reg_obstack. */
209 #include "context.h"
210 #include "pass_manager.h"
211 #include "tree-nested.h"
212 #include "gimplify.h"
213 #include "dbgcnt.h"
214 #include "omp-low.h"
215 #include "lto-section-names.h"
217 /* Queue of cgraph nodes scheduled to be added into cgraph. This is a
218 secondary queue used during optimization to accommodate passes that
219 may generate new functions that need to be optimized and expanded. */
220 vec<cgraph_node *> cgraph_new_nodes;
222 static void expand_all_functions (void);
223 static void mark_functions_to_output (void);
224 static void handle_alias_pairs (void);
226 /* Used for vtable lookup in thunk adjusting. */
227 static GTY (()) tree vtable_entry_type;
229 /* Determine if symbol declaration is needed. That is, visible to something
230 either outside this translation unit, something magic in the system
231 configury */
232 bool
233 symtab_node::needed_p (void)
235 /* Double check that no one output the function into assembly file
236 early. */
237 gcc_checking_assert (!DECL_ASSEMBLER_NAME_SET_P (decl)
238 || !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)));
240 if (!definition)
241 return false;
243 if (DECL_EXTERNAL (decl))
244 return false;
246 /* If the user told us it is used, then it must be so. */
247 if (force_output)
248 return true;
250 /* ABI forced symbols are needed when they are external. */
251 if (forced_by_abi && TREE_PUBLIC (decl))
252 return true;
254 /* Keep constructors, destructors and virtual functions. */
255 if (TREE_CODE (decl) == FUNCTION_DECL
256 && (DECL_STATIC_CONSTRUCTOR (decl) || DECL_STATIC_DESTRUCTOR (decl)))
257 return true;
259 /* Externally visible variables must be output. The exception is
260 COMDAT variables that must be output only when they are needed. */
261 if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
262 return true;
264 return false;
267 /* Head and terminator of the queue of nodes to be processed while building
268 callgraph. */
270 static symtab_node symtab_terminator;
271 static symtab_node *queued_nodes = &symtab_terminator;
273 /* Add NODE to queue starting at QUEUED_NODES.
274 The queue is linked via AUX pointers and terminated by pointer to 1. */
276 static void
277 enqueue_node (symtab_node *node)
279 if (node->aux)
280 return;
281 gcc_checking_assert (queued_nodes);
282 node->aux = queued_nodes;
283 queued_nodes = node;
286 /* Process CGRAPH_NEW_FUNCTIONS and perform actions necessary to add these
287 functions into callgraph in a way so they look like ordinary reachable
288 functions inserted into callgraph already at construction time. */
290 void
291 symbol_table::process_new_functions (void)
293 tree fndecl;
295 if (!cgraph_new_nodes.exists ())
296 return;
298 handle_alias_pairs ();
299 /* Note that this queue may grow as its being processed, as the new
300 functions may generate new ones. */
301 for (unsigned i = 0; i < cgraph_new_nodes.length (); i++)
303 cgraph_node *node = cgraph_new_nodes[i];
304 fndecl = node->decl;
305 switch (state)
307 case CONSTRUCTION:
308 /* At construction time we just need to finalize function and move
309 it into reachable functions list. */
311 cgraph_node::finalize_function (fndecl, false);
312 call_cgraph_insertion_hooks (node);
313 enqueue_node (node);
314 break;
316 case IPA:
317 case IPA_SSA:
318 /* When IPA optimization already started, do all essential
319 transformations that has been already performed on the whole
320 cgraph but not on this function. */
322 gimple_register_cfg_hooks ();
323 if (!node->analyzed)
324 node->analyze ();
325 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
326 if (state == IPA_SSA
327 && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
328 g->get_passes ()->execute_early_local_passes ();
329 else if (inline_summary_vec != NULL)
330 compute_inline_parameters (node, true);
331 free_dominance_info (CDI_POST_DOMINATORS);
332 free_dominance_info (CDI_DOMINATORS);
333 pop_cfun ();
334 break;
336 case EXPANSION:
337 /* Functions created during expansion shall be compiled
338 directly. */
339 node->process = 0;
340 call_cgraph_insertion_hooks (node);
341 node->expand ();
342 break;
344 default:
345 gcc_unreachable ();
346 break;
350 cgraph_new_nodes.release ();
353 /* As an GCC extension we allow redefinition of the function. The
354 semantics when both copies of bodies differ is not well defined.
355 We replace the old body with new body so in unit at a time mode
356 we always use new body, while in normal mode we may end up with
357 old body inlined into some functions and new body expanded and
358 inlined in others.
360 ??? It may make more sense to use one body for inlining and other
361 body for expanding the function but this is difficult to do. */
363 void
364 cgraph_node::reset (void)
366 /* If process is set, then we have already begun whole-unit analysis.
367 This is *not* testing for whether we've already emitted the function.
368 That case can be sort-of legitimately seen with real function redefinition
369 errors. I would argue that the front end should never present us with
370 such a case, but don't enforce that for now. */
371 gcc_assert (!process);
373 /* Reset our data structures so we can analyze the function again. */
374 memset (&local, 0, sizeof (local));
375 memset (&global, 0, sizeof (global));
376 memset (&rtl, 0, sizeof (rtl));
377 analyzed = false;
378 definition = false;
379 alias = false;
380 weakref = false;
381 cpp_implicit_alias = false;
383 remove_callees ();
384 remove_all_references ();
387 /* Return true when there are references to the node. */
389 bool
390 symtab_node::referred_to_p (void)
392 ipa_ref *ref = NULL;
394 /* See if there are any references at all. */
395 if (iterate_referring (0, ref))
396 return true;
397 /* For functions check also calls. */
398 cgraph_node *cn = dyn_cast <cgraph_node *> (this);
399 if (cn && cn->callers)
400 return true;
401 return false;
404 /* DECL has been parsed. Take it, queue it, compile it at the whim of the
405 logic in effect. If NO_COLLECT is true, then our caller cannot stand to have
406 the garbage collector run at the moment. We would need to either create
407 a new GC context, or just not compile right now. */
409 void
410 cgraph_node::finalize_function (tree decl, bool no_collect)
412 cgraph_node *node = cgraph_node::get_create (decl);
414 if (node->definition)
416 /* Nested functions should only be defined once. */
417 gcc_assert (!DECL_CONTEXT (decl)
418 || TREE_CODE (DECL_CONTEXT (decl)) != FUNCTION_DECL);
419 node->reset ();
420 node->local.redefined_extern_inline = true;
423 notice_global_symbol (decl);
424 node->definition = true;
425 node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL;
427 /* With -fkeep-inline-functions we are keeping all inline functions except
428 for extern inline ones. */
429 if (flag_keep_inline_functions
430 && DECL_DECLARED_INLINE_P (decl)
431 && !DECL_EXTERNAL (decl)
432 && !DECL_DISREGARD_INLINE_LIMITS (decl))
433 node->force_output = 1;
435 /* When not optimizing, also output the static functions. (see
436 PR24561), but don't do so for always_inline functions, functions
437 declared inline and nested functions. These were optimized out
438 in the original implementation and it is unclear whether we want
439 to change the behavior here. */
440 if ((!optimize
441 && !node->cpp_implicit_alias
442 && !DECL_DISREGARD_INLINE_LIMITS (decl)
443 && !DECL_DECLARED_INLINE_P (decl)
444 && !(DECL_CONTEXT (decl)
445 && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL))
446 && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
447 node->force_output = 1;
449 /* If we've not yet emitted decl, tell the debug info about it. */
450 if (!TREE_ASM_WRITTEN (decl))
451 (*debug_hooks->deferred_inline_function) (decl);
453 /* Possibly warn about unused parameters. */
454 if (warn_unused_parameter)
455 do_warn_unused_parameter (decl);
457 if (!no_collect)
458 ggc_collect ();
460 if (symtab->state == CONSTRUCTION
461 && (node->needed_p () || node->referred_to_p ()))
462 enqueue_node (node);
465 /* Add the function FNDECL to the call graph.
466 Unlike finalize_function, this function is intended to be used
467 by middle end and allows insertion of new function at arbitrary point
468 of compilation. The function can be either in high, low or SSA form
469 GIMPLE.
471 The function is assumed to be reachable and have address taken (so no
472 API breaking optimizations are performed on it).
474 Main work done by this function is to enqueue the function for later
475 processing to avoid need the passes to be re-entrant. */
477 void
478 cgraph_node::add_new_function (tree fndecl, bool lowered)
480 gcc::pass_manager *passes = g->get_passes ();
481 cgraph_node *node;
482 switch (symtab->state)
484 case PARSING:
485 cgraph_node::finalize_function (fndecl, false);
486 break;
487 case CONSTRUCTION:
488 /* Just enqueue function to be processed at nearest occurrence. */
489 node = cgraph_node::get_create (fndecl);
490 if (lowered)
491 node->lowered = true;
492 cgraph_new_nodes.safe_push (node);
493 break;
495 case IPA:
496 case IPA_SSA:
497 case EXPANSION:
498 /* Bring the function into finalized state and enqueue for later
499 analyzing and compilation. */
500 node = cgraph_node::get_create (fndecl);
501 node->local.local = false;
502 node->definition = true;
503 node->force_output = true;
504 if (!lowered && symtab->state == EXPANSION)
506 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
507 gimple_register_cfg_hooks ();
508 bitmap_obstack_initialize (NULL);
509 execute_pass_list (cfun, passes->all_lowering_passes);
510 passes->execute_early_local_passes ();
511 bitmap_obstack_release (NULL);
512 pop_cfun ();
514 lowered = true;
516 if (lowered)
517 node->lowered = true;
518 cgraph_new_nodes.safe_push (node);
519 break;
521 case FINISHED:
522 /* At the very end of compilation we have to do all the work up
523 to expansion. */
524 node = cgraph_node::create (fndecl);
525 if (lowered)
526 node->lowered = true;
527 node->definition = true;
528 node->analyze ();
529 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
530 gimple_register_cfg_hooks ();
531 bitmap_obstack_initialize (NULL);
532 if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
533 g->get_passes ()->execute_early_local_passes ();
534 bitmap_obstack_release (NULL);
535 pop_cfun ();
536 node->expand ();
537 break;
539 default:
540 gcc_unreachable ();
543 /* Set a personality if required and we already passed EH lowering. */
544 if (lowered
545 && (function_needs_eh_personality (DECL_STRUCT_FUNCTION (fndecl))
546 == eh_personality_lang))
547 DECL_FUNCTION_PERSONALITY (fndecl) = lang_hooks.eh_personality ();
550 /* Output all asm statements we have stored up to be output. */
552 void
553 symbol_table::output_asm_statements (void)
555 asm_node *can;
557 if (seen_error ())
558 return;
560 for (can = first_asm_symbol (); can; can = can->next)
561 assemble_asm (can->asm_str);
563 clear_asm_symbols ();
566 /* Analyze the function scheduled to be output. */
567 void
568 cgraph_node::analyze (void)
570 tree decl = this->decl;
571 location_t saved_loc = input_location;
572 input_location = DECL_SOURCE_LOCATION (decl);
574 if (thunk.thunk_p)
576 create_edge (cgraph_node::get (thunk.alias),
577 NULL, 0, CGRAPH_FREQ_BASE);
578 if (!expand_thunk (false, false))
580 thunk.alias = NULL;
581 analyzed = true;
582 return;
584 thunk.alias = NULL;
586 if (alias)
587 resolve_alias (cgraph_node::get (alias_target));
588 else if (dispatcher_function)
590 /* Generate the dispatcher body of multi-versioned functions. */
591 cgraph_function_version_info *dispatcher_version_info
592 = function_version ();
593 if (dispatcher_version_info != NULL
594 && (dispatcher_version_info->dispatcher_resolver
595 == NULL_TREE))
597 tree resolver = NULL_TREE;
598 gcc_assert (targetm.generate_version_dispatcher_body);
599 resolver = targetm.generate_version_dispatcher_body (this);
600 gcc_assert (resolver != NULL_TREE);
603 else
605 push_cfun (DECL_STRUCT_FUNCTION (decl));
607 assign_assembler_name_if_neeeded (decl);
609 /* Make sure to gimplify bodies only once. During analyzing a
610 function we lower it, which will require gimplified nested
611 functions, so we can end up here with an already gimplified
612 body. */
613 if (!gimple_has_body_p (decl))
614 gimplify_function_tree (decl);
615 dump_function (TDI_generic, decl);
617 /* Lower the function. */
618 if (!lowered)
620 if (nested)
621 lower_nested_functions (decl);
622 gcc_assert (!nested);
624 gimple_register_cfg_hooks ();
625 bitmap_obstack_initialize (NULL);
626 execute_pass_list (cfun, g->get_passes ()->all_lowering_passes);
627 free_dominance_info (CDI_POST_DOMINATORS);
628 free_dominance_info (CDI_DOMINATORS);
629 compact_blocks ();
630 bitmap_obstack_release (NULL);
631 lowered = true;
634 pop_cfun ();
636 analyzed = true;
638 input_location = saved_loc;
641 /* C++ frontend produce same body aliases all over the place, even before PCH
642 gets streamed out. It relies on us linking the aliases with their function
643 in order to do the fixups, but ipa-ref is not PCH safe. Consequentely we
644 first produce aliases without links, but once C++ FE is sure he won't sream
645 PCH we build the links via this function. */
647 void
648 symbol_table::process_same_body_aliases (void)
650 symtab_node *node;
651 FOR_EACH_SYMBOL (node)
652 if (node->cpp_implicit_alias && !node->analyzed)
653 node->resolve_alias
654 (TREE_CODE (node->alias_target) == VAR_DECL
655 ? (symtab_node *)varpool_node::get_create (node->alias_target)
656 : (symtab_node *)cgraph_node::get_create (node->alias_target));
657 cpp_implicit_aliases_done = true;
660 /* Process attributes common for vars and functions. */
662 static void
663 process_common_attributes (tree decl)
665 tree weakref = lookup_attribute ("weakref", DECL_ATTRIBUTES (decl));
667 if (weakref && !lookup_attribute ("alias", DECL_ATTRIBUTES (decl)))
669 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
670 "%<weakref%> attribute should be accompanied with"
671 " an %<alias%> attribute");
672 DECL_WEAK (decl) = 0;
673 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
674 DECL_ATTRIBUTES (decl));
678 /* Look for externally_visible and used attributes and mark cgraph nodes
679 accordingly.
681 We cannot mark the nodes at the point the attributes are processed (in
682 handle_*_attribute) because the copy of the declarations available at that
683 point may not be canonical. For example, in:
685 void f();
686 void f() __attribute__((used));
688 the declaration we see in handle_used_attribute will be the second
689 declaration -- but the front end will subsequently merge that declaration
690 with the original declaration and discard the second declaration.
692 Furthermore, we can't mark these nodes in finalize_function because:
694 void f() {}
695 void f() __attribute__((externally_visible));
697 is valid.
699 So, we walk the nodes at the end of the translation unit, applying the
700 attributes at that point. */
702 static void
703 process_function_and_variable_attributes (cgraph_node *first,
704 varpool_node *first_var)
706 cgraph_node *node;
707 varpool_node *vnode;
709 for (node = symtab->first_function (); node != first;
710 node = symtab->next_function (node))
712 tree decl = node->decl;
713 if (DECL_PRESERVE_P (decl))
714 node->mark_force_output ();
715 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
717 if (! TREE_PUBLIC (node->decl))
718 warning_at (DECL_SOURCE_LOCATION (node->decl), OPT_Wattributes,
719 "%<externally_visible%>"
720 " attribute have effect only on public objects");
722 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
723 && (node->definition && !node->alias))
725 warning_at (DECL_SOURCE_LOCATION (node->decl), OPT_Wattributes,
726 "%<weakref%> attribute ignored"
727 " because function is defined");
728 DECL_WEAK (decl) = 0;
729 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
730 DECL_ATTRIBUTES (decl));
733 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl))
734 && !DECL_DECLARED_INLINE_P (decl)
735 /* redefining extern inline function makes it DECL_UNINLINABLE. */
736 && !DECL_UNINLINABLE (decl))
737 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
738 "always_inline function might not be inlinable");
740 process_common_attributes (decl);
742 for (vnode = symtab->first_variable (); vnode != first_var;
743 vnode = symtab->next_variable (vnode))
745 tree decl = vnode->decl;
746 if (DECL_EXTERNAL (decl)
747 && DECL_INITIAL (decl))
748 varpool_node::finalize_decl (decl);
749 if (DECL_PRESERVE_P (decl))
750 vnode->force_output = true;
751 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
753 if (! TREE_PUBLIC (vnode->decl))
754 warning_at (DECL_SOURCE_LOCATION (vnode->decl), OPT_Wattributes,
755 "%<externally_visible%>"
756 " attribute have effect only on public objects");
758 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
759 && vnode->definition
760 && DECL_INITIAL (decl))
762 warning_at (DECL_SOURCE_LOCATION (vnode->decl), OPT_Wattributes,
763 "%<weakref%> attribute ignored"
764 " because variable is initialized");
765 DECL_WEAK (decl) = 0;
766 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
767 DECL_ATTRIBUTES (decl));
769 process_common_attributes (decl);
773 /* Mark DECL as finalized. By finalizing the declaration, frontend instruct the
774 middle end to output the variable to asm file, if needed or externally
775 visible. */
777 void
778 varpool_node::finalize_decl (tree decl)
780 varpool_node *node = varpool_node::get_create (decl);
782 gcc_assert (TREE_STATIC (decl) || DECL_EXTERNAL (decl));
784 if (node->definition)
785 return;
786 notice_global_symbol (decl);
787 node->definition = true;
788 if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
789 /* Traditionally we do not eliminate static variables when not
790 optimizing and when not doing toplevel reoder. */
791 || (!flag_toplevel_reorder && !DECL_COMDAT (node->decl)
792 && !DECL_ARTIFICIAL (node->decl)))
793 node->force_output = true;
795 if (symtab->state == CONSTRUCTION
796 && (node->needed_p () || node->referred_to_p ()))
797 enqueue_node (node);
798 if (symtab->state >= IPA_SSA)
799 node->analyze ();
800 /* Some frontends produce various interface variables after compilation
801 finished. */
802 if (symtab->state == FINISHED
803 || (!flag_toplevel_reorder
804 && symtab->state == EXPANSION))
805 node->assemble_decl ();
808 /* EDGE is an polymorphic call. Mark all possible targets as reachable
809 and if there is only one target, perform trivial devirtualization.
810 REACHABLE_CALL_TARGETS collects target lists we already walked to
811 avoid udplicate work. */
813 static void
814 walk_polymorphic_call_targets (hash_set<void *> *reachable_call_targets,
815 cgraph_edge *edge)
817 unsigned int i;
818 void *cache_token;
819 bool final;
820 vec <cgraph_node *>targets
821 = possible_polymorphic_call_targets
822 (edge, &final, &cache_token);
824 if (!reachable_call_targets->add (cache_token))
826 if (symtab->dump_file)
827 dump_possible_polymorphic_call_targets
828 (symtab->dump_file, edge);
830 for (i = 0; i < targets.length (); i++)
832 /* Do not bother to mark virtual methods in anonymous namespace;
833 either we will find use of virtual table defining it, or it is
834 unused. */
835 if (targets[i]->definition
836 && TREE_CODE
837 (TREE_TYPE (targets[i]->decl))
838 == METHOD_TYPE
839 && !type_in_anonymous_namespace_p
840 (method_class_type
841 (TREE_TYPE (targets[i]->decl))))
842 enqueue_node (targets[i]);
846 /* Very trivial devirtualization; when the type is
847 final or anonymous (so we know all its derivation)
848 and there is only one possible virtual call target,
849 make the edge direct. */
850 if (final)
852 if (targets.length () <= 1 && dbg_cnt (devirt))
854 cgraph_node *target;
855 if (targets.length () == 1)
856 target = targets[0];
857 else
858 target = cgraph_node::create
859 (builtin_decl_implicit (BUILT_IN_UNREACHABLE));
861 if (symtab->dump_file)
863 fprintf (symtab->dump_file,
864 "Devirtualizing call: ");
865 print_gimple_stmt (symtab->dump_file,
866 edge->call_stmt, 0,
867 TDF_SLIM);
869 if (dump_enabled_p ())
871 location_t locus = gimple_location_safe (edge->call_stmt);
872 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, locus,
873 "devirtualizing call in %s to %s\n",
874 edge->caller->name (), target->name ());
877 edge->make_direct (target);
878 edge->redirect_call_stmt_to_callee ();
879 if (symtab->dump_file)
881 fprintf (symtab->dump_file,
882 "Devirtualized as: ");
883 print_gimple_stmt (symtab->dump_file,
884 edge->call_stmt, 0,
885 TDF_SLIM);
892 /* Discover all functions and variables that are trivially needed, analyze
893 them as well as all functions and variables referred by them */
895 static void
896 analyze_functions (void)
898 /* Keep track of already processed nodes when called multiple times for
899 intermodule optimization. */
900 static cgraph_node *first_analyzed;
901 cgraph_node *first_handled = first_analyzed;
902 static varpool_node *first_analyzed_var;
903 varpool_node *first_handled_var = first_analyzed_var;
904 hash_set<void *> reachable_call_targets;
906 symtab_node *node;
907 symtab_node *next;
908 int i;
909 ipa_ref *ref;
910 bool changed = true;
911 location_t saved_loc = input_location;
913 bitmap_obstack_initialize (NULL);
914 symtab->state = CONSTRUCTION;
915 input_location = UNKNOWN_LOCATION;
917 /* Ugly, but the fixup can not happen at a time same body alias is created;
918 C++ FE is confused about the COMDAT groups being right. */
919 if (symtab->cpp_implicit_aliases_done)
920 FOR_EACH_SYMBOL (node)
921 if (node->cpp_implicit_alias)
922 node->fixup_same_cpp_alias_visibility (node->get_alias_target ());
923 if (optimize && flag_devirtualize)
924 build_type_inheritance_graph ();
926 /* Analysis adds static variables that in turn adds references to new functions.
927 So we need to iterate the process until it stabilize. */
928 while (changed)
930 changed = false;
931 process_function_and_variable_attributes (first_analyzed,
932 first_analyzed_var);
934 /* First identify the trivially needed symbols. */
935 for (node = symtab->first_symbol ();
936 node != first_analyzed
937 && node != first_analyzed_var; node = node->next)
939 /* Convert COMDAT group designators to IDENTIFIER_NODEs. */
940 node->get_comdat_group_id ();
941 if (node->needed_p ())
943 enqueue_node (node);
944 if (!changed && symtab->dump_file)
945 fprintf (symtab->dump_file, "Trivially needed symbols:");
946 changed = true;
947 if (symtab->dump_file)
948 fprintf (symtab->dump_file, " %s", node->asm_name ());
949 if (!changed && symtab->dump_file)
950 fprintf (symtab->dump_file, "\n");
952 if (node == first_analyzed
953 || node == first_analyzed_var)
954 break;
956 symtab->process_new_functions ();
957 first_analyzed_var = symtab->first_variable ();
958 first_analyzed = symtab->first_function ();
960 if (changed && symtab->dump_file)
961 fprintf (symtab->dump_file, "\n");
963 /* Lower representation, build callgraph edges and references for all trivially
964 needed symbols and all symbols referred by them. */
965 while (queued_nodes != &symtab_terminator)
967 changed = true;
968 node = queued_nodes;
969 queued_nodes = (symtab_node *)queued_nodes->aux;
970 cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
971 if (cnode && cnode->definition)
973 cgraph_edge *edge;
974 tree decl = cnode->decl;
976 /* ??? It is possible to create extern inline function
977 and later using weak alias attribute to kill its body.
978 See gcc.c-torture/compile/20011119-1.c */
979 if (!DECL_STRUCT_FUNCTION (decl)
980 && !cnode->alias
981 && !cnode->thunk.thunk_p
982 && !cnode->dispatcher_function)
984 cnode->reset ();
985 cnode->local.redefined_extern_inline = true;
986 continue;
989 if (!cnode->analyzed)
990 cnode->analyze ();
992 for (edge = cnode->callees; edge; edge = edge->next_callee)
993 if (edge->callee->definition)
994 enqueue_node (edge->callee);
995 if (optimize && flag_devirtualize)
997 cgraph_edge *next;
999 for (edge = cnode->indirect_calls; edge; edge = next)
1001 next = edge->next_callee;
1002 if (edge->indirect_info->polymorphic)
1003 walk_polymorphic_call_targets (&reachable_call_targets,
1004 edge);
1008 /* If decl is a clone of an abstract function,
1009 mark that abstract function so that we don't release its body.
1010 The DECL_INITIAL() of that abstract function declaration
1011 will be later needed to output debug info. */
1012 if (DECL_ABSTRACT_ORIGIN (decl))
1014 cgraph_node *origin_node
1015 = cgraph_node::get_create (DECL_ABSTRACT_ORIGIN (decl));
1016 origin_node->used_as_abstract_origin = true;
1019 else
1021 varpool_node *vnode = dyn_cast <varpool_node *> (node);
1022 if (vnode && vnode->definition && !vnode->analyzed)
1023 vnode->analyze ();
1026 if (node->same_comdat_group)
1028 symtab_node *next;
1029 for (next = node->same_comdat_group;
1030 next != node;
1031 next = next->same_comdat_group)
1032 enqueue_node (next);
1034 for (i = 0; node->iterate_reference (i, ref); i++)
1035 if (ref->referred->definition)
1036 enqueue_node (ref->referred);
1037 symtab->process_new_functions ();
1040 if (optimize && flag_devirtualize)
1041 update_type_inheritance_graph ();
1043 /* Collect entry points to the unit. */
1044 if (symtab->dump_file)
1046 fprintf (symtab->dump_file, "\n\nInitial ");
1047 symtab_node::dump_table (symtab->dump_file);
1050 if (symtab->dump_file)
1051 fprintf (symtab->dump_file, "\nRemoving unused symbols:");
1053 for (node = symtab->first_symbol ();
1054 node != first_handled
1055 && node != first_handled_var; node = next)
1057 next = node->next;
1058 if (!node->aux && !node->referred_to_p ())
1060 if (symtab->dump_file)
1061 fprintf (symtab->dump_file, " %s", node->name ());
1062 node->remove ();
1063 continue;
1065 if (cgraph_node *cnode = dyn_cast <cgraph_node *> (node))
1067 tree decl = node->decl;
1069 if (cnode->definition && !gimple_has_body_p (decl)
1070 && !cnode->alias
1071 && !cnode->thunk.thunk_p)
1072 cnode->reset ();
1074 gcc_assert (!cnode->definition || cnode->thunk.thunk_p
1075 || cnode->alias
1076 || gimple_has_body_p (decl));
1077 gcc_assert (cnode->analyzed == cnode->definition);
1079 node->aux = NULL;
1081 for (;node; node = node->next)
1082 node->aux = NULL;
1083 first_analyzed = symtab->first_function ();
1084 first_analyzed_var = symtab->first_variable ();
1085 if (symtab->dump_file)
1087 fprintf (symtab->dump_file, "\n\nReclaimed ");
1088 symtab_node::dump_table (symtab->dump_file);
1090 bitmap_obstack_release (NULL);
1091 ggc_collect ();
1092 /* Initialize assembler name hash, in particular we want to trigger C++
1093 mangling and same body alias creation before we free DECL_ARGUMENTS
1094 used by it. */
1095 if (!seen_error ())
1096 symtab->symtab_initialize_asm_name_hash ();
1098 input_location = saved_loc;
1101 /* Translate the ugly representation of aliases as alias pairs into nice
1102 representation in callgraph. We don't handle all cases yet,
1103 unfortunately. */
1105 static void
1106 handle_alias_pairs (void)
1108 alias_pair *p;
1109 unsigned i;
1111 for (i = 0; alias_pairs && alias_pairs->iterate (i, &p);)
1113 symtab_node *target_node = symtab_node::get_for_asmname (p->target);
1115 /* Weakrefs with target not defined in current unit are easy to handle:
1116 they behave just as external variables except we need to note the
1117 alias flag to later output the weakref pseudo op into asm file. */
1118 if (!target_node
1119 && lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL)
1121 symtab_node *node = symtab_node::get (p->decl);
1122 if (node)
1124 node->alias_target = p->target;
1125 node->weakref = true;
1126 node->alias = true;
1128 alias_pairs->unordered_remove (i);
1129 continue;
1131 else if (!target_node)
1133 error ("%q+D aliased to undefined symbol %qE", p->decl, p->target);
1134 symtab_node *node = symtab_node::get (p->decl);
1135 if (node)
1136 node->alias = false;
1137 alias_pairs->unordered_remove (i);
1138 continue;
1141 if (DECL_EXTERNAL (target_node->decl)
1142 /* We use local aliases for C++ thunks to force the tailcall
1143 to bind locally. This is a hack - to keep it working do
1144 the following (which is not strictly correct). */
1145 && (TREE_CODE (target_node->decl) != FUNCTION_DECL
1146 || ! DECL_VIRTUAL_P (target_node->decl))
1147 && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)))
1149 error ("%q+D aliased to external symbol %qE",
1150 p->decl, p->target);
1153 if (TREE_CODE (p->decl) == FUNCTION_DECL
1154 && target_node && is_a <cgraph_node *> (target_node))
1156 cgraph_node *src_node = cgraph_node::get (p->decl);
1157 if (src_node && src_node->definition)
1158 src_node->reset ();
1159 cgraph_node::create_alias (p->decl, target_node->decl);
1160 alias_pairs->unordered_remove (i);
1162 else if (TREE_CODE (p->decl) == VAR_DECL
1163 && target_node && is_a <varpool_node *> (target_node))
1165 varpool_node::create_alias (p->decl, target_node->decl);
1166 alias_pairs->unordered_remove (i);
1168 else
1170 error ("%q+D alias in between function and variable is not supported",
1171 p->decl);
1172 warning (0, "%q+D aliased declaration",
1173 target_node->decl);
1174 alias_pairs->unordered_remove (i);
1177 vec_free (alias_pairs);
1181 /* Figure out what functions we want to assemble. */
1183 static void
1184 mark_functions_to_output (void)
1186 cgraph_node *node;
1187 #ifdef ENABLE_CHECKING
1188 bool check_same_comdat_groups = false;
1190 FOR_EACH_FUNCTION (node)
1191 gcc_assert (!node->process);
1192 #endif
1194 FOR_EACH_FUNCTION (node)
1196 tree decl = node->decl;
1198 gcc_assert (!node->process || node->same_comdat_group);
1199 if (node->process)
1200 continue;
1202 /* We need to output all local functions that are used and not
1203 always inlined, as well as those that are reachable from
1204 outside the current compilation unit. */
1205 if (node->analyzed
1206 && !node->thunk.thunk_p
1207 && !node->alias
1208 && !node->global.inlined_to
1209 && !TREE_ASM_WRITTEN (decl)
1210 && !DECL_EXTERNAL (decl))
1212 node->process = 1;
1213 if (node->same_comdat_group)
1215 cgraph_node *next;
1216 for (next = dyn_cast<cgraph_node *> (node->same_comdat_group);
1217 next != node;
1218 next = dyn_cast<cgraph_node *> (next->same_comdat_group))
1219 if (!next->thunk.thunk_p && !next->alias
1220 && !next->comdat_local_p ())
1221 next->process = 1;
1224 else if (node->same_comdat_group)
1226 #ifdef ENABLE_CHECKING
1227 check_same_comdat_groups = true;
1228 #endif
1230 else
1232 /* We should've reclaimed all functions that are not needed. */
1233 #ifdef ENABLE_CHECKING
1234 if (!node->global.inlined_to
1235 && gimple_has_body_p (decl)
1236 /* FIXME: in ltrans unit when offline copy is outside partition but inline copies
1237 are inside partition, we can end up not removing the body since we no longer
1238 have analyzed node pointing to it. */
1239 && !node->in_other_partition
1240 && !node->alias
1241 && !node->clones
1242 && !DECL_EXTERNAL (decl))
1244 node->debug ();
1245 internal_error ("failed to reclaim unneeded function");
1247 #endif
1248 gcc_assert (node->global.inlined_to
1249 || !gimple_has_body_p (decl)
1250 || node->in_other_partition
1251 || node->clones
1252 || DECL_ARTIFICIAL (decl)
1253 || DECL_EXTERNAL (decl));
1258 #ifdef ENABLE_CHECKING
1259 if (check_same_comdat_groups)
1260 FOR_EACH_FUNCTION (node)
1261 if (node->same_comdat_group && !node->process)
1263 tree decl = node->decl;
1264 if (!node->global.inlined_to
1265 && gimple_has_body_p (decl)
1266 /* FIXME: in an ltrans unit when the offline copy is outside a
1267 partition but inline copies are inside a partition, we can
1268 end up not removing the body since we no longer have an
1269 analyzed node pointing to it. */
1270 && !node->in_other_partition
1271 && !node->clones
1272 && !DECL_EXTERNAL (decl))
1274 node->debug ();
1275 internal_error ("failed to reclaim unneeded function in same "
1276 "comdat group");
1279 #endif
1282 /* DECL is FUNCTION_DECL. Initialize datastructures so DECL is a function
1283 in lowered gimple form. IN_SSA is true if the gimple is in SSA.
1285 Set current_function_decl and cfun to newly constructed empty function body.
1286 return basic block in the function body. */
1288 basic_block
1289 init_lowered_empty_function (tree decl, bool in_ssa)
1291 basic_block bb;
1293 current_function_decl = decl;
1294 allocate_struct_function (decl, false);
1295 gimple_register_cfg_hooks ();
1296 init_empty_tree_cfg ();
1298 if (in_ssa)
1300 init_tree_ssa (cfun);
1301 init_ssa_operands (cfun);
1302 cfun->gimple_df->in_ssa_p = true;
1303 cfun->curr_properties |= PROP_ssa;
1306 DECL_INITIAL (decl) = make_node (BLOCK);
1308 DECL_SAVED_TREE (decl) = error_mark_node;
1309 cfun->curr_properties |= (PROP_gimple_lcf | PROP_gimple_leh | PROP_gimple_any
1310 | PROP_cfg | PROP_loops);
1312 set_loops_for_fn (cfun, ggc_cleared_alloc<loops> ());
1313 init_loops_structure (cfun, loops_for_fn (cfun), 1);
1314 loops_for_fn (cfun)->state |= LOOPS_MAY_HAVE_MULTIPLE_LATCHES;
1316 /* Create BB for body of the function and connect it properly. */
1317 bb = create_basic_block (NULL, (void *) 0, ENTRY_BLOCK_PTR_FOR_FN (cfun));
1318 make_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun), bb, EDGE_FALLTHRU);
1319 make_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
1320 add_bb_to_loop (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun)->loop_father);
1322 return bb;
1325 /* Adjust PTR by the constant FIXED_OFFSET, and by the vtable
1326 offset indicated by VIRTUAL_OFFSET, if that is
1327 non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and
1328 zero for a result adjusting thunk. */
1330 static tree
1331 thunk_adjust (gimple_stmt_iterator * bsi,
1332 tree ptr, bool this_adjusting,
1333 HOST_WIDE_INT fixed_offset, tree virtual_offset)
1335 gimple stmt;
1336 tree ret;
1338 if (this_adjusting
1339 && fixed_offset != 0)
1341 stmt = gimple_build_assign
1342 (ptr, fold_build_pointer_plus_hwi_loc (input_location,
1343 ptr,
1344 fixed_offset));
1345 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1348 /* If there's a virtual offset, look up that value in the vtable and
1349 adjust the pointer again. */
1350 if (virtual_offset)
1352 tree vtabletmp;
1353 tree vtabletmp2;
1354 tree vtabletmp3;
1356 if (!vtable_entry_type)
1358 tree vfunc_type = make_node (FUNCTION_TYPE);
1359 TREE_TYPE (vfunc_type) = integer_type_node;
1360 TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
1361 layout_type (vfunc_type);
1363 vtable_entry_type = build_pointer_type (vfunc_type);
1366 vtabletmp =
1367 create_tmp_reg (build_pointer_type
1368 (build_pointer_type (vtable_entry_type)), "vptr");
1370 /* The vptr is always at offset zero in the object. */
1371 stmt = gimple_build_assign (vtabletmp,
1372 build1 (NOP_EXPR, TREE_TYPE (vtabletmp),
1373 ptr));
1374 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1376 /* Form the vtable address. */
1377 vtabletmp2 = create_tmp_reg (TREE_TYPE (TREE_TYPE (vtabletmp)),
1378 "vtableaddr");
1379 stmt = gimple_build_assign (vtabletmp2,
1380 build_simple_mem_ref (vtabletmp));
1381 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1383 /* Find the entry with the vcall offset. */
1384 stmt = gimple_build_assign (vtabletmp2,
1385 fold_build_pointer_plus_loc (input_location,
1386 vtabletmp2,
1387 virtual_offset));
1388 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1390 /* Get the offset itself. */
1391 vtabletmp3 = create_tmp_reg (TREE_TYPE (TREE_TYPE (vtabletmp2)),
1392 "vcalloffset");
1393 stmt = gimple_build_assign (vtabletmp3,
1394 build_simple_mem_ref (vtabletmp2));
1395 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1397 /* Adjust the `this' pointer. */
1398 ptr = fold_build_pointer_plus_loc (input_location, ptr, vtabletmp3);
1399 ptr = force_gimple_operand_gsi (bsi, ptr, true, NULL_TREE, false,
1400 GSI_CONTINUE_LINKING);
1403 if (!this_adjusting
1404 && fixed_offset != 0)
1405 /* Adjust the pointer by the constant. */
1407 tree ptrtmp;
1409 if (TREE_CODE (ptr) == VAR_DECL)
1410 ptrtmp = ptr;
1411 else
1413 ptrtmp = create_tmp_reg (TREE_TYPE (ptr), "ptr");
1414 stmt = gimple_build_assign (ptrtmp, ptr);
1415 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1417 ptr = fold_build_pointer_plus_hwi_loc (input_location,
1418 ptrtmp, fixed_offset);
1421 /* Emit the statement and gimplify the adjustment expression. */
1422 ret = create_tmp_reg (TREE_TYPE (ptr), "adjusted_this");
1423 stmt = gimple_build_assign (ret, ptr);
1424 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1426 return ret;
1429 /* Expand thunk NODE to gimple if possible.
1430 When FORCE_GIMPLE_THUNK is true, gimple thunk is created and
1431 no assembler is produced.
1432 When OUTPUT_ASM_THUNK is true, also produce assembler for
1433 thunks that are not lowered. */
1435 bool
1436 cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk)
1438 bool this_adjusting = thunk.this_adjusting;
1439 HOST_WIDE_INT fixed_offset = thunk.fixed_offset;
1440 HOST_WIDE_INT virtual_value = thunk.virtual_value;
1441 tree virtual_offset = NULL;
1442 tree alias = callees->callee->decl;
1443 tree thunk_fndecl = decl;
1444 tree a;
1447 if (!force_gimple_thunk && this_adjusting
1448 && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
1449 virtual_value, alias))
1451 const char *fnname;
1452 tree fn_block;
1453 tree restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1455 if (!output_asm_thunks)
1456 return false;
1458 if (in_lto_p)
1459 get_body ();
1460 a = DECL_ARGUMENTS (thunk_fndecl);
1462 current_function_decl = thunk_fndecl;
1464 /* Ensure thunks are emitted in their correct sections. */
1465 resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
1467 DECL_RESULT (thunk_fndecl)
1468 = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl),
1469 RESULT_DECL, 0, restype);
1470 DECL_CONTEXT (DECL_RESULT (thunk_fndecl)) = thunk_fndecl;
1471 fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
1473 /* The back end expects DECL_INITIAL to contain a BLOCK, so we
1474 create one. */
1475 fn_block = make_node (BLOCK);
1476 BLOCK_VARS (fn_block) = a;
1477 DECL_INITIAL (thunk_fndecl) = fn_block;
1478 init_function_start (thunk_fndecl);
1479 cfun->is_thunk = 1;
1480 insn_locations_init ();
1481 set_curr_insn_location (DECL_SOURCE_LOCATION (thunk_fndecl));
1482 prologue_location = curr_insn_location ();
1483 assemble_start_function (thunk_fndecl, fnname);
1485 targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl,
1486 fixed_offset, virtual_value, alias);
1488 assemble_end_function (thunk_fndecl, fnname);
1489 insn_locations_finalize ();
1490 init_insn_lengths ();
1491 free_after_compilation (cfun);
1492 set_cfun (NULL);
1493 TREE_ASM_WRITTEN (thunk_fndecl) = 1;
1494 thunk.thunk_p = false;
1495 analyzed = false;
1497 else
1499 tree restype;
1500 basic_block bb, then_bb, else_bb, return_bb;
1501 gimple_stmt_iterator bsi;
1502 int nargs = 0;
1503 tree arg;
1504 int i;
1505 tree resdecl;
1506 tree restmp = NULL;
1508 gimple call;
1509 gimple ret;
1511 if (in_lto_p)
1512 get_body ();
1513 a = DECL_ARGUMENTS (thunk_fndecl);
1515 current_function_decl = thunk_fndecl;
1517 /* Ensure thunks are emitted in their correct sections. */
1518 resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
1520 DECL_IGNORED_P (thunk_fndecl) = 1;
1521 bitmap_obstack_initialize (NULL);
1523 if (thunk.virtual_offset_p)
1524 virtual_offset = size_int (virtual_value);
1526 /* Build the return declaration for the function. */
1527 restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1528 if (DECL_RESULT (thunk_fndecl) == NULL_TREE)
1530 resdecl = build_decl (input_location, RESULT_DECL, 0, restype);
1531 DECL_ARTIFICIAL (resdecl) = 1;
1532 DECL_IGNORED_P (resdecl) = 1;
1533 DECL_RESULT (thunk_fndecl) = resdecl;
1534 DECL_CONTEXT (DECL_RESULT (thunk_fndecl)) = thunk_fndecl;
1536 else
1537 resdecl = DECL_RESULT (thunk_fndecl);
1539 bb = then_bb = else_bb = return_bb = init_lowered_empty_function (thunk_fndecl, true);
1541 bsi = gsi_start_bb (bb);
1543 /* Build call to the function being thunked. */
1544 if (!VOID_TYPE_P (restype))
1546 if (DECL_BY_REFERENCE (resdecl))
1547 restmp = gimple_fold_indirect_ref (resdecl);
1548 else if (!is_gimple_reg_type (restype))
1550 restmp = resdecl;
1551 add_local_decl (cfun, restmp);
1552 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp;
1554 else
1555 restmp = create_tmp_reg (restype, "retval");
1558 for (arg = a; arg; arg = DECL_CHAIN (arg))
1559 nargs++;
1560 auto_vec<tree> vargs (nargs);
1561 if (this_adjusting)
1562 vargs.quick_push (thunk_adjust (&bsi, a, 1, fixed_offset,
1563 virtual_offset));
1564 else if (nargs)
1565 vargs.quick_push (a);
1567 if (nargs)
1568 for (i = 1, arg = DECL_CHAIN (a); i < nargs; i++, arg = DECL_CHAIN (arg))
1570 tree tmp = arg;
1571 if (!is_gimple_val (arg))
1573 tmp = create_tmp_reg (TYPE_MAIN_VARIANT
1574 (TREE_TYPE (arg)), "arg");
1575 gimple stmt = gimple_build_assign (tmp, arg);
1576 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1578 vargs.quick_push (tmp);
1580 call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs);
1581 callees->call_stmt = call;
1582 gimple_call_set_from_thunk (call, true);
1583 if (restmp)
1585 gimple_call_set_lhs (call, restmp);
1586 gcc_assert (useless_type_conversion_p (TREE_TYPE (restmp),
1587 TREE_TYPE (TREE_TYPE (alias))));
1589 gsi_insert_after (&bsi, call, GSI_NEW_STMT);
1590 if (!(gimple_call_flags (call) & ECF_NORETURN))
1592 if (restmp && !this_adjusting
1593 && (fixed_offset || virtual_offset))
1595 tree true_label = NULL_TREE;
1597 if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE)
1599 gimple stmt;
1600 /* If the return type is a pointer, we need to
1601 protect against NULL. We know there will be an
1602 adjustment, because that's why we're emitting a
1603 thunk. */
1604 then_bb = create_basic_block (NULL, (void *) 0, bb);
1605 return_bb = create_basic_block (NULL, (void *) 0, then_bb);
1606 else_bb = create_basic_block (NULL, (void *) 0, else_bb);
1607 add_bb_to_loop (then_bb, bb->loop_father);
1608 add_bb_to_loop (return_bb, bb->loop_father);
1609 add_bb_to_loop (else_bb, bb->loop_father);
1610 remove_edge (single_succ_edge (bb));
1611 true_label = gimple_block_label (then_bb);
1612 stmt = gimple_build_cond (NE_EXPR, restmp,
1613 build_zero_cst (TREE_TYPE (restmp)),
1614 NULL_TREE, NULL_TREE);
1615 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1616 make_edge (bb, then_bb, EDGE_TRUE_VALUE);
1617 make_edge (bb, else_bb, EDGE_FALSE_VALUE);
1618 make_edge (return_bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
1619 make_edge (then_bb, return_bb, EDGE_FALLTHRU);
1620 make_edge (else_bb, return_bb, EDGE_FALLTHRU);
1621 bsi = gsi_last_bb (then_bb);
1624 restmp = thunk_adjust (&bsi, restmp, /*this_adjusting=*/0,
1625 fixed_offset, virtual_offset);
1626 if (true_label)
1628 gimple stmt;
1629 bsi = gsi_last_bb (else_bb);
1630 stmt = gimple_build_assign (restmp,
1631 build_zero_cst (TREE_TYPE (restmp)));
1632 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1633 bsi = gsi_last_bb (return_bb);
1636 else
1637 gimple_call_set_tail (call, true);
1639 /* Build return value. */
1640 ret = gimple_build_return (restmp);
1641 gsi_insert_after (&bsi, ret, GSI_NEW_STMT);
1643 else
1645 gimple_call_set_tail (call, true);
1646 remove_edge (single_succ_edge (bb));
1649 cfun->gimple_df->in_ssa_p = true;
1650 /* FIXME: C++ FE should stop setting TREE_ASM_WRITTEN on thunks. */
1651 TREE_ASM_WRITTEN (thunk_fndecl) = false;
1652 delete_unreachable_blocks ();
1653 update_ssa (TODO_update_ssa);
1654 #ifdef ENABLE_CHECKING
1655 verify_flow_info ();
1656 #endif
1657 free_dominance_info (CDI_DOMINATORS);
1659 /* Since we want to emit the thunk, we explicitly mark its name as
1660 referenced. */
1661 thunk.thunk_p = false;
1662 lowered = true;
1663 bitmap_obstack_release (NULL);
1665 current_function_decl = NULL;
1666 set_cfun (NULL);
1667 return true;
1670 /* Assemble thunks and aliases associated to node. */
1672 void
1673 cgraph_node::assemble_thunks_and_aliases (void)
1675 cgraph_edge *e;
1676 ipa_ref *ref;
1678 for (e = callers; e;)
1679 if (e->caller->thunk.thunk_p)
1681 cgraph_node *thunk = e->caller;
1683 e = e->next_caller;
1684 thunk->expand_thunk (true, false);
1685 thunk->assemble_thunks_and_aliases ();
1687 else
1688 e = e->next_caller;
1690 FOR_EACH_ALIAS (this, ref)
1692 cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
1693 bool saved_written = TREE_ASM_WRITTEN (decl);
1695 /* Force assemble_alias to really output the alias this time instead
1696 of buffering it in same alias pairs. */
1697 TREE_ASM_WRITTEN (decl) = 1;
1698 do_assemble_alias (alias->decl,
1699 DECL_ASSEMBLER_NAME (decl));
1700 alias->assemble_thunks_and_aliases ();
1701 TREE_ASM_WRITTEN (decl) = saved_written;
1705 /* Expand function specified by node. */
1707 void
1708 cgraph_node::expand (void)
1710 location_t saved_loc;
1712 /* We ought to not compile any inline clones. */
1713 gcc_assert (!global.inlined_to);
1715 announce_function (decl);
1716 process = 0;
1717 gcc_assert (lowered);
1718 get_body ();
1720 /* Generate RTL for the body of DECL. */
1722 timevar_push (TV_REST_OF_COMPILATION);
1724 gcc_assert (symtab->global_info_ready);
1726 /* Initialize the default bitmap obstack. */
1727 bitmap_obstack_initialize (NULL);
1729 /* Initialize the RTL code for the function. */
1730 current_function_decl = decl;
1731 saved_loc = input_location;
1732 input_location = DECL_SOURCE_LOCATION (decl);
1733 init_function_start (decl);
1735 gimple_register_cfg_hooks ();
1737 bitmap_obstack_initialize (&reg_obstack); /* FIXME, only at RTL generation*/
1739 execute_all_ipa_transforms ();
1741 /* Perform all tree transforms and optimizations. */
1743 /* Signal the start of passes. */
1744 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START, NULL);
1746 execute_pass_list (cfun, g->get_passes ()->all_passes);
1748 /* Signal the end of passes. */
1749 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END, NULL);
1751 bitmap_obstack_release (&reg_obstack);
1753 /* Release the default bitmap obstack. */
1754 bitmap_obstack_release (NULL);
1756 /* If requested, warn about function definitions where the function will
1757 return a value (usually of some struct or union type) which itself will
1758 take up a lot of stack space. */
1759 if (warn_larger_than && !DECL_EXTERNAL (decl) && TREE_TYPE (decl))
1761 tree ret_type = TREE_TYPE (TREE_TYPE (decl));
1763 if (ret_type && TYPE_SIZE_UNIT (ret_type)
1764 && TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST
1765 && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type),
1766 larger_than_size))
1768 unsigned int size_as_int
1769 = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type));
1771 if (compare_tree_int (TYPE_SIZE_UNIT (ret_type), size_as_int) == 0)
1772 warning (OPT_Wlarger_than_, "size of return value of %q+D is %u bytes",
1773 decl, size_as_int);
1774 else
1775 warning (OPT_Wlarger_than_, "size of return value of %q+D is larger than %wd bytes",
1776 decl, larger_than_size);
1780 gimple_set_body (decl, NULL);
1781 if (DECL_STRUCT_FUNCTION (decl) == 0
1782 && !cgraph_node::get (decl)->origin)
1784 /* Stop pointing to the local nodes about to be freed.
1785 But DECL_INITIAL must remain nonzero so we know this
1786 was an actual function definition.
1787 For a nested function, this is done in c_pop_function_context.
1788 If rest_of_compilation set this to 0, leave it 0. */
1789 if (DECL_INITIAL (decl) != 0)
1790 DECL_INITIAL (decl) = error_mark_node;
1793 input_location = saved_loc;
1795 ggc_collect ();
1796 timevar_pop (TV_REST_OF_COMPILATION);
1798 /* Make sure that BE didn't give up on compiling. */
1799 gcc_assert (TREE_ASM_WRITTEN (decl));
1800 set_cfun (NULL);
1801 current_function_decl = NULL;
1803 /* It would make a lot more sense to output thunks before function body to get more
1804 forward and lest backwarding jumps. This however would need solving problem
1805 with comdats. See PR48668. Also aliases must come after function itself to
1806 make one pass assemblers, like one on AIX, happy. See PR 50689.
1807 FIXME: Perhaps thunks should be move before function IFF they are not in comdat
1808 groups. */
1809 assemble_thunks_and_aliases ();
1810 release_body ();
1811 /* Eliminate all call edges. This is important so the GIMPLE_CALL no longer
1812 points to the dead function body. */
1813 remove_callees ();
1814 remove_all_references ();
1817 /* Node comparer that is responsible for the order that corresponds
1818 to time when a function was launched for the first time. */
1820 static int
1821 node_cmp (const void *pa, const void *pb)
1823 const cgraph_node *a = *(const cgraph_node * const *) pa;
1824 const cgraph_node *b = *(const cgraph_node * const *) pb;
1826 /* Functions with time profile must be before these without profile. */
1827 if (!a->tp_first_run || !b->tp_first_run)
1828 return a->tp_first_run - b->tp_first_run;
1830 return a->tp_first_run != b->tp_first_run
1831 ? b->tp_first_run - a->tp_first_run
1832 : b->order - a->order;
1835 /* Expand all functions that must be output.
1837 Attempt to topologically sort the nodes so function is output when
1838 all called functions are already assembled to allow data to be
1839 propagated across the callgraph. Use a stack to get smaller distance
1840 between a function and its callees (later we may choose to use a more
1841 sophisticated algorithm for function reordering; we will likely want
1842 to use subsections to make the output functions appear in top-down
1843 order). */
1845 static void
1846 expand_all_functions (void)
1848 cgraph_node *node;
1849 cgraph_node **order = XCNEWVEC (cgraph_node *,
1850 symtab->cgraph_count);
1851 unsigned int expanded_func_count = 0, profiled_func_count = 0;
1852 int order_pos, new_order_pos = 0;
1853 int i;
1855 order_pos = ipa_reverse_postorder (order);
1856 gcc_assert (order_pos == symtab->cgraph_count);
1858 /* Garbage collector may remove inline clones we eliminate during
1859 optimization. So we must be sure to not reference them. */
1860 for (i = 0; i < order_pos; i++)
1861 if (order[i]->process)
1862 order[new_order_pos++] = order[i];
1864 if (flag_profile_reorder_functions)
1865 qsort (order, new_order_pos, sizeof (cgraph_node *), node_cmp);
1867 for (i = new_order_pos - 1; i >= 0; i--)
1869 node = order[i];
1871 if (node->process)
1873 expanded_func_count++;
1874 if(node->tp_first_run)
1875 profiled_func_count++;
1877 if (symtab->dump_file)
1878 fprintf (symtab->dump_file,
1879 "Time profile order in expand_all_functions:%s:%d\n",
1880 node->asm_name (), node->tp_first_run);
1881 node->process = 0;
1882 node->expand ();
1886 if (dump_file)
1887 fprintf (dump_file, "Expanded functions with time profile (%s):%u/%u\n",
1888 main_input_filename, profiled_func_count, expanded_func_count);
1890 if (symtab->dump_file && flag_profile_reorder_functions)
1891 fprintf (symtab->dump_file, "Expanded functions with time profile:%u/%u\n",
1892 profiled_func_count, expanded_func_count);
1894 symtab->process_new_functions ();
1895 free_gimplify_stack ();
1897 free (order);
1900 /* This is used to sort the node types by the cgraph order number. */
1902 enum cgraph_order_sort_kind
1904 ORDER_UNDEFINED = 0,
1905 ORDER_FUNCTION,
1906 ORDER_VAR,
1907 ORDER_ASM
1910 struct cgraph_order_sort
1912 enum cgraph_order_sort_kind kind;
1913 union
1915 cgraph_node *f;
1916 varpool_node *v;
1917 asm_node *a;
1918 } u;
1921 /* Output all functions, variables, and asm statements in the order
1922 according to their order fields, which is the order in which they
1923 appeared in the file. This implements -fno-toplevel-reorder. In
1924 this mode we may output functions and variables which don't really
1925 need to be output. */
1927 static void
1928 output_in_order (void)
1930 int max;
1931 cgraph_order_sort *nodes;
1932 int i;
1933 cgraph_node *pf;
1934 varpool_node *pv;
1935 asm_node *pa;
1936 max = symtab->order;
1937 nodes = XCNEWVEC (cgraph_order_sort, max);
1939 FOR_EACH_DEFINED_FUNCTION (pf)
1941 if (pf->process && !pf->thunk.thunk_p && !pf->alias)
1943 i = pf->order;
1944 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1945 nodes[i].kind = ORDER_FUNCTION;
1946 nodes[i].u.f = pf;
1950 FOR_EACH_DEFINED_VARIABLE (pv)
1951 if (!DECL_EXTERNAL (pv->decl))
1953 i = pv->order;
1954 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1955 nodes[i].kind = ORDER_VAR;
1956 nodes[i].u.v = pv;
1959 for (pa = symtab->first_asm_symbol (); pa; pa = pa->next)
1961 i = pa->order;
1962 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1963 nodes[i].kind = ORDER_ASM;
1964 nodes[i].u.a = pa;
1967 /* In toplevel reorder mode we output all statics; mark them as needed. */
1969 for (i = 0; i < max; ++i)
1970 if (nodes[i].kind == ORDER_VAR)
1971 nodes[i].u.v->finalize_named_section_flags ();
1973 for (i = 0; i < max; ++i)
1975 switch (nodes[i].kind)
1977 case ORDER_FUNCTION:
1978 nodes[i].u.f->process = 0;
1979 nodes[i].u.f->expand ();
1980 break;
1982 case ORDER_VAR:
1983 nodes[i].u.v->assemble_decl ();
1984 break;
1986 case ORDER_ASM:
1987 assemble_asm (nodes[i].u.a->asm_str);
1988 break;
1990 case ORDER_UNDEFINED:
1991 break;
1993 default:
1994 gcc_unreachable ();
1998 symtab->clear_asm_symbols ();
2000 free (nodes);
2003 /* Collect all global variables with "omp declare target" attribute into
2004 OFFLOAD_VARS. It will be streamed out in ipa_write_summaries. */
2006 static void
2007 init_offload_var_table (void)
2009 struct varpool_node *vnode;
2010 FOR_EACH_DEFINED_VARIABLE (vnode)
2012 if (!lookup_attribute ("omp declare target",
2013 DECL_ATTRIBUTES (vnode->decl))
2014 || TREE_CODE (vnode->decl) != VAR_DECL
2015 || DECL_SIZE (vnode->decl) == 0)
2016 continue;
2017 vec_safe_push (offload_vars, vnode->decl);
2021 static void
2022 ipa_passes (void)
2024 gcc::pass_manager *passes = g->get_passes ();
2026 set_cfun (NULL);
2027 current_function_decl = NULL;
2028 gimple_register_cfg_hooks ();
2029 bitmap_obstack_initialize (NULL);
2031 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START, NULL);
2033 if (!in_lto_p)
2035 execute_ipa_pass_list (passes->all_small_ipa_passes);
2036 if (seen_error ())
2037 return;
2040 /* This extra symtab_remove_unreachable_nodes pass tends to catch some
2041 devirtualization and other changes where removal iterate. */
2042 symtab->remove_unreachable_nodes (true, symtab->dump_file);
2044 /* If pass_all_early_optimizations was not scheduled, the state of
2045 the cgraph will not be properly updated. Update it now. */
2046 if (symtab->state < IPA_SSA)
2047 symtab->state = IPA_SSA;
2049 if (!in_lto_p)
2051 /* Generate coverage variables and constructors. */
2052 coverage_finish ();
2054 /* Process new functions added. */
2055 set_cfun (NULL);
2056 current_function_decl = NULL;
2057 symtab->process_new_functions ();
2059 execute_ipa_summary_passes
2060 ((ipa_opt_pass_d *) passes->all_regular_ipa_passes);
2063 /* Some targets need to handle LTO assembler output specially. */
2064 if (flag_generate_lto)
2065 targetm.asm_out.lto_start ();
2067 if (!in_lto_p)
2069 init_offload_var_table ();
2071 if ((flag_openacc || flag_openmp)
2072 && !(vec_safe_is_empty (offload_funcs)
2073 && vec_safe_is_empty (offload_vars)))
2075 section_name_prefix = OMP_SECTION_NAME_PREFIX;
2076 ipa_write_summaries (true);
2078 if (flag_lto)
2080 section_name_prefix = LTO_SECTION_NAME_PREFIX;
2081 ipa_write_summaries (false);
2085 if (flag_generate_lto)
2086 targetm.asm_out.lto_end ();
2088 if (!flag_ltrans && (in_lto_p || !flag_lto || flag_fat_lto_objects))
2089 execute_ipa_pass_list (passes->all_regular_ipa_passes);
2090 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END, NULL);
2092 bitmap_obstack_release (NULL);
2096 /* Return string alias is alias of. */
2098 static tree
2099 get_alias_symbol (tree decl)
2101 tree alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
2102 return get_identifier (TREE_STRING_POINTER
2103 (TREE_VALUE (TREE_VALUE (alias))));
2107 /* Weakrefs may be associated to external decls and thus not output
2108 at expansion time. Emit all necessary aliases. */
2110 void
2111 symbol_table::output_weakrefs (void)
2113 symtab_node *node;
2114 FOR_EACH_SYMBOL (node)
2115 if (node->alias
2116 && !TREE_ASM_WRITTEN (node->decl)
2117 && node->weakref)
2119 tree target;
2121 /* Weakrefs are special by not requiring target definition in current
2122 compilation unit. It is thus bit hard to work out what we want to
2123 alias.
2124 When alias target is defined, we need to fetch it from symtab reference,
2125 otherwise it is pointed to by alias_target. */
2126 if (node->alias_target)
2127 target = (DECL_P (node->alias_target)
2128 ? DECL_ASSEMBLER_NAME (node->alias_target)
2129 : node->alias_target);
2130 else if (node->analyzed)
2131 target = DECL_ASSEMBLER_NAME (node->get_alias_target ()->decl);
2132 else
2134 gcc_unreachable ();
2135 target = get_alias_symbol (node->decl);
2137 do_assemble_alias (node->decl, target);
2141 /* Perform simple optimizations based on callgraph. */
2143 void
2144 symbol_table::compile (void)
2146 if (seen_error ())
2147 return;
2149 #ifdef ENABLE_CHECKING
2150 symtab_node::verify_symtab_nodes ();
2151 #endif
2153 timevar_push (TV_CGRAPHOPT);
2154 if (pre_ipa_mem_report)
2156 fprintf (stderr, "Memory consumption before IPA\n");
2157 dump_memory_report (false);
2159 if (!quiet_flag)
2160 fprintf (stderr, "Performing interprocedural optimizations\n");
2161 state = IPA;
2163 /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE. */
2164 if (flag_lto || flag_openacc || flag_openmp)
2165 lto_streamer_hooks_init ();
2167 /* Don't run the IPA passes if there was any error or sorry messages. */
2168 if (!seen_error ())
2169 ipa_passes ();
2171 /* Do nothing else if any IPA pass found errors or if we are just streaming LTO. */
2172 if (seen_error ()
2173 || (!in_lto_p && flag_lto && !flag_fat_lto_objects))
2175 timevar_pop (TV_CGRAPHOPT);
2176 return;
2179 /* This pass remove bodies of extern inline functions we never inlined.
2180 Do this later so other IPA passes see what is really going on.
2181 FIXME: This should be run just after inlining by pasmanager. */
2182 remove_unreachable_nodes (false, dump_file);
2183 global_info_ready = true;
2184 if (dump_file)
2186 fprintf (dump_file, "Optimized ");
2187 symtab_node:: dump_table (dump_file);
2189 if (post_ipa_mem_report)
2191 fprintf (stderr, "Memory consumption after IPA\n");
2192 dump_memory_report (false);
2194 timevar_pop (TV_CGRAPHOPT);
2196 /* Output everything. */
2197 (*debug_hooks->assembly_start) ();
2198 if (!quiet_flag)
2199 fprintf (stderr, "Assembling functions:\n");
2200 #ifdef ENABLE_CHECKING
2201 symtab_node::verify_symtab_nodes ();
2202 #endif
2204 materialize_all_clones ();
2205 bitmap_obstack_initialize (NULL);
2206 execute_ipa_pass_list (g->get_passes ()->all_late_ipa_passes);
2207 bitmap_obstack_release (NULL);
2208 mark_functions_to_output ();
2210 /* When weakref support is missing, we autmatically translate all
2211 references to NODE to references to its ultimate alias target.
2212 The renaming mechanizm uses flag IDENTIFIER_TRANSPARENT_ALIAS and
2213 TREE_CHAIN.
2215 Set up this mapping before we output any assembler but once we are sure
2216 that all symbol renaming is done.
2218 FIXME: All this uglyness can go away if we just do renaming at gimple
2219 level by physically rewritting the IL. At the moment we can only redirect
2220 calls, so we need infrastructure for renaming references as well. */
2221 #ifndef ASM_OUTPUT_WEAKREF
2222 symtab_node *node;
2224 FOR_EACH_SYMBOL (node)
2225 if (node->alias
2226 && lookup_attribute ("weakref", DECL_ATTRIBUTES (node->decl)))
2228 IDENTIFIER_TRANSPARENT_ALIAS
2229 (DECL_ASSEMBLER_NAME (node->decl)) = 1;
2230 TREE_CHAIN (DECL_ASSEMBLER_NAME (node->decl))
2231 = (node->alias_target ? node->alias_target
2232 : DECL_ASSEMBLER_NAME (node->get_alias_target ()->decl));
2234 #endif
2236 state = EXPANSION;
2238 if (!flag_toplevel_reorder)
2239 output_in_order ();
2240 else
2242 output_asm_statements ();
2244 expand_all_functions ();
2245 output_variables ();
2248 process_new_functions ();
2249 state = FINISHED;
2250 output_weakrefs ();
2252 if (dump_file)
2254 fprintf (dump_file, "\nFinal ");
2255 symtab_node::dump_table (dump_file);
2257 #ifdef ENABLE_CHECKING
2258 symtab_node::verify_symtab_nodes ();
2259 /* Double check that all inline clones are gone and that all
2260 function bodies have been released from memory. */
2261 if (!seen_error ())
2263 cgraph_node *node;
2264 bool error_found = false;
2266 FOR_EACH_DEFINED_FUNCTION (node)
2267 if (node->global.inlined_to
2268 || gimple_has_body_p (node->decl))
2270 error_found = true;
2271 node->debug ();
2273 if (error_found)
2274 internal_error ("nodes with unreleased memory found");
2276 #endif
2280 /* Analyze the whole compilation unit once it is parsed completely. */
2282 void
2283 symbol_table::finalize_compilation_unit (void)
2285 timevar_push (TV_CGRAPH);
2287 /* If we're here there's no current function anymore. Some frontends
2288 are lazy in clearing these. */
2289 current_function_decl = NULL;
2290 set_cfun (NULL);
2292 /* Do not skip analyzing the functions if there were errors, we
2293 miss diagnostics for following functions otherwise. */
2295 /* Emit size functions we didn't inline. */
2296 finalize_size_functions ();
2298 /* Mark alias targets necessary and emit diagnostics. */
2299 handle_alias_pairs ();
2301 if (!quiet_flag)
2303 fprintf (stderr, "\nAnalyzing compilation unit\n");
2304 fflush (stderr);
2307 if (flag_dump_passes)
2308 dump_passes ();
2310 /* Gimplify and lower all functions, compute reachability and
2311 remove unreachable nodes. */
2312 analyze_functions ();
2314 /* Mark alias targets necessary and emit diagnostics. */
2315 handle_alias_pairs ();
2317 /* Gimplify and lower thunks. */
2318 analyze_functions ();
2320 /* Finally drive the pass manager. */
2321 compile ();
2323 timevar_pop (TV_CGRAPH);
2326 /* Creates a wrapper from cgraph_node to TARGET node. Thunk is used for this
2327 kind of wrapper method. */
2329 void
2330 cgraph_node::create_wrapper (cgraph_node *target)
2332 /* Preserve DECL_RESULT so we get right by reference flag. */
2333 tree decl_result = DECL_RESULT (decl);
2335 /* Remove the function's body. */
2336 release_body ();
2337 reset ();
2339 DECL_RESULT (decl) = decl_result;
2340 DECL_INITIAL (decl) = NULL;
2341 allocate_struct_function (decl, false);
2342 set_cfun (NULL);
2344 /* Turn alias into thunk and expand it into GIMPLE representation. */
2345 definition = true;
2346 thunk.thunk_p = true;
2347 thunk.this_adjusting = false;
2349 cgraph_edge *e = create_edge (target, NULL, 0, CGRAPH_FREQ_BASE);
2351 if (!expand_thunk (false, true))
2352 analyzed = true;
2354 e->call_stmt_cannot_inline_p = true;
2356 /* Inline summary set-up. */
2357 analyze ();
2358 inline_analyze_function (this);
2361 #include "gt-cgraphunit.h"