2012-10-06 Janus Weil <janus@gcc.gnu.org>
[official-gcc.git] / gcc / cgraphunit.c
blob64460ac63b7e7a754268de467b62c6b6c0137cfb
1 /* Driver of optimization process
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
3 2011, 2012 Free Software Foundation, Inc.
4 Contributed by Jan Hubicka
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
22 /* This module implements main driver of compilation process.
24 The main scope of this file is to act as an interface in between
25 tree based frontends and the backend.
27 The front-end is supposed to use following functionality:
29 - cgraph_finalize_function
31 This function is called once front-end has parsed whole body of function
32 and it is certain that the function body nor the declaration will change.
34 (There is one exception needed for implementing GCC extern inline
35 function.)
37 - varpool_finalize_decl
39 This function has same behavior as the above but is used for static
40 variables.
42 - add_asm_node
44 Insert new toplevel ASM statement
46 - finalize_compilation_unit
48 This function is called once (source level) compilation unit is finalized
49 and it will no longer change.
51 The symbol table is constructed starting from the trivially needed
52 symbols finalized by the frontend. Functions are lowered into
53 GIMPLE representation and callgraph/reference lists are constructed.
54 Those are used to discover other necessary functions and variables.
56 At the end the bodies of unreachable functions are removed.
58 The function can be called multiple times when multiple source level
59 compilation units are combined.
61 - compile
63 This passes control to the back-end. Optimizations are performed and
64 final assembler is generated. This is done in the following way. Note
65 that with link time optimization the process is split into three
66 stages (compile time, linktime analysis and parallel linktime as
67 indicated bellow).
69 Compile time:
71 1) Inter-procedural optimization.
72 (ipa_passes)
74 This part is further split into:
76 a) early optimizations. These are local passes executed in
77 the topological order on the callgraph.
79 The purpose of early optimiations is to optimize away simple
80 things that may otherwise confuse IP analysis. Very simple
81 propagation across the callgraph is done i.e. to discover
82 functions without side effects and simple inlining is performed.
84 b) early small interprocedural passes.
86 Those are interprocedural passes executed only at compilation
87 time. These include, for exmaple, transational memory lowering,
88 unreachable code removal and other simple transformations.
90 c) IP analysis stage. All interprocedural passes do their
91 analysis.
93 Interprocedural passes differ from small interprocedural
94 passes by their ability to operate across whole program
95 at linktime. Their analysis stage is performed early to
96 both reduce linking times and linktime memory usage by
97 not having to represent whole program in memory.
99 d) LTO sreaming. When doing LTO, everything important gets
100 streamed into the object file.
102 Compile time and or linktime analysis stage (WPA):
104 At linktime units gets streamed back and symbol table is
105 merged. Function bodies are not streamed in and not
106 available.
107 e) IP propagation stage. All IP passes execute their
108 IP propagation. This is done based on the earlier analysis
109 without having function bodies at hand.
110 f) Ltrans streaming. When doing WHOPR LTO, the program
111 is partitioned and streamed into multple object files.
113 Compile time and/or parallel linktime stage (ltrans)
115 Each of the object files is streamed back and compiled
116 separately. Now the function bodies becomes available
117 again.
119 2) Virtual clone materialization
120 (cgraph_materialize_clone)
122 IP passes can produce copies of existing functoins (such
123 as versioned clones or inline clones) without actually
124 manipulating their bodies by creating virtual clones in
125 the callgraph. At this time the virtual clones are
126 turned into real functions
127 3) IP transformation
129 All IP passes transform function bodies based on earlier
130 decision of the IP propagation.
132 4) late small IP passes
134 Simple IP passes working within single program partition.
136 5) Expansion
137 (expand_all_functions)
139 At this stage functions that needs to be output into
140 assembler are identified and compiled in topological order
141 6) Output of variables and aliases
142 Now it is known what variable references was not optimized
143 out and thus all variables are output to the file.
145 Note that with -fno-toplevel-reorder passes 5 and 6
146 are combined together in cgraph_output_in_order.
148 Finally there are functions to manipulate the callgraph from
149 backend.
150 - cgraph_add_new_function is used to add backend produced
151 functions introduced after the unit is finalized.
152 The functions are enqueue for later processing and inserted
153 into callgraph with cgraph_process_new_functions.
155 - cgraph_function_versioning
157 produces a copy of function into new one (a version)
158 and apply simple transformations
161 #include "config.h"
162 #include "system.h"
163 #include "coretypes.h"
164 #include "tm.h"
165 #include "tree.h"
166 #include "output.h"
167 #include "rtl.h"
168 #include "tree-flow.h"
169 #include "tree-inline.h"
170 #include "langhooks.h"
171 #include "pointer-set.h"
172 #include "toplev.h"
173 #include "flags.h"
174 #include "ggc.h"
175 #include "debug.h"
176 #include "target.h"
177 #include "cgraph.h"
178 #include "diagnostic.h"
179 #include "params.h"
180 #include "fibheap.h"
181 #include "intl.h"
182 #include "function.h"
183 #include "ipa-prop.h"
184 #include "gimple.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 "except.h"
196 #include "regset.h" /* FIXME: For reg_obstack. */
198 /* Queue of cgraph nodes scheduled to be added into cgraph. This is a
199 secondary queue used during optimization to accommodate passes that
200 may generate new functions that need to be optimized and expanded. */
201 cgraph_node_set cgraph_new_nodes;
203 static void expand_all_functions (void);
204 static void mark_functions_to_output (void);
205 static void expand_function (struct cgraph_node *);
206 static void cgraph_analyze_function (struct cgraph_node *);
207 static void handle_alias_pairs (void);
209 FILE *cgraph_dump_file;
211 /* Linked list of cgraph asm nodes. */
212 struct asm_node *asm_nodes;
214 /* Last node in cgraph_asm_nodes. */
215 static GTY(()) struct asm_node *asm_last_node;
217 /* Used for vtable lookup in thunk adjusting. */
218 static GTY (()) tree vtable_entry_type;
220 /* Determine if function DECL is trivially needed and should stay in the
221 compilation unit. This is used at the symbol table construction time
222 and differs from later logic removing unnecessary functions that can
223 take into account results of analysis, whole program info etc. */
225 static bool
226 cgraph_decide_is_function_needed (struct cgraph_node *node, tree decl)
228 /* If the user told us it is used, then it must be so. */
229 if (node->symbol.force_output)
230 return true;
232 /* Double check that no one output the function into assembly file
233 early. */
234 gcc_checking_assert (!DECL_ASSEMBLER_NAME_SET_P (decl)
235 || (node->thunk.thunk_p || node->same_body_alias)
236 || !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)));
239 /* Keep constructors, destructors and virtual functions. */
240 if (DECL_STATIC_CONSTRUCTOR (decl)
241 || DECL_STATIC_DESTRUCTOR (decl)
242 || (DECL_VIRTUAL_P (decl)
243 && optimize && (DECL_COMDAT (decl) || DECL_EXTERNAL (decl))))
244 return true;
246 /* Externally visible functions must be output. The exception is
247 COMDAT functions that must be output only when they are needed. */
249 if (TREE_PUBLIC (decl)
250 && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
251 return true;
253 return false;
256 /* Head of the queue of nodes to be processed while building callgraph */
258 static symtab_node first = (symtab_node)(void *)1;
260 /* Add NODE to queue starting at FIRST.
261 The queue is linked via AUX pointers and terminated by pointer to 1. */
263 static void
264 enqueue_node (symtab_node node)
266 if (node->symbol.aux)
267 return;
268 gcc_checking_assert (first);
269 node->symbol.aux = first;
270 first = node;
273 /* Process CGRAPH_NEW_FUNCTIONS and perform actions necessary to add these
274 functions into callgraph in a way so they look like ordinary reachable
275 functions inserted into callgraph already at construction time. */
277 bool
278 cgraph_process_new_functions (void)
280 bool output = false;
281 tree fndecl;
282 struct cgraph_node *node;
283 cgraph_node_set_iterator csi;
285 if (!cgraph_new_nodes)
286 return false;
287 handle_alias_pairs ();
288 /* Note that this queue may grow as its being processed, as the new
289 functions may generate new ones. */
290 for (csi = csi_start (cgraph_new_nodes); !csi_end_p (csi); csi_next (&csi))
292 node = csi_node (csi);
293 fndecl = node->symbol.decl;
294 switch (cgraph_state)
296 case CGRAPH_STATE_CONSTRUCTION:
297 /* At construction time we just need to finalize function and move
298 it into reachable functions list. */
300 cgraph_finalize_function (fndecl, false);
301 output = true;
302 cgraph_call_function_insertion_hooks (node);
303 enqueue_node ((symtab_node) node);
304 break;
306 case CGRAPH_STATE_IPA:
307 case CGRAPH_STATE_IPA_SSA:
308 /* When IPA optimization already started, do all essential
309 transformations that has been already performed on the whole
310 cgraph but not on this function. */
312 gimple_register_cfg_hooks ();
313 if (!node->analyzed)
314 cgraph_analyze_function (node);
315 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
316 if ((cgraph_state == CGRAPH_STATE_IPA_SSA
317 && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
318 /* When not optimizing, be sure we run early local passes anyway
319 to expand OMP. */
320 || !optimize)
321 execute_pass_list (pass_early_local_passes.pass.sub);
322 else
323 compute_inline_parameters (node, true);
324 free_dominance_info (CDI_POST_DOMINATORS);
325 free_dominance_info (CDI_DOMINATORS);
326 pop_cfun ();
327 cgraph_call_function_insertion_hooks (node);
328 break;
330 case CGRAPH_STATE_EXPANSION:
331 /* Functions created during expansion shall be compiled
332 directly. */
333 node->process = 0;
334 cgraph_call_function_insertion_hooks (node);
335 expand_function (node);
336 break;
338 default:
339 gcc_unreachable ();
340 break;
343 free_cgraph_node_set (cgraph_new_nodes);
344 cgraph_new_nodes = NULL;
345 return output;
348 /* As an GCC extension we allow redefinition of the function. The
349 semantics when both copies of bodies differ is not well defined.
350 We replace the old body with new body so in unit at a time mode
351 we always use new body, while in normal mode we may end up with
352 old body inlined into some functions and new body expanded and
353 inlined in others.
355 ??? It may make more sense to use one body for inlining and other
356 body for expanding the function but this is difficult to do. */
358 static void
359 cgraph_reset_node (struct cgraph_node *node)
361 /* If node->process is set, then we have already begun whole-unit analysis.
362 This is *not* testing for whether we've already emitted the function.
363 That case can be sort-of legitimately seen with real function redefinition
364 errors. I would argue that the front end should never present us with
365 such a case, but don't enforce that for now. */
366 gcc_assert (!node->process);
368 /* Reset our data structures so we can analyze the function again. */
369 memset (&node->local, 0, sizeof (node->local));
370 memset (&node->global, 0, sizeof (node->global));
371 memset (&node->rtl, 0, sizeof (node->rtl));
372 node->analyzed = false;
373 node->local.finalized = false;
375 cgraph_node_remove_callees (node);
378 /* Return true when there are references to NODE. */
380 static bool
381 referred_to_p (symtab_node node)
383 struct ipa_ref *ref;
385 /* See if there are any references at all. */
386 if (ipa_ref_list_referring_iterate (&node->symbol.ref_list, 0, ref))
387 return true;
388 /* For functions check also calls. */
389 if (symtab_function_p (node) && cgraph (node)->callers)
390 return true;
391 return false;
394 /* DECL has been parsed. Take it, queue it, compile it at the whim of the
395 logic in effect. If NESTED is true, then our caller cannot stand to have
396 the garbage collector run at the moment. We would need to either create
397 a new GC context, or just not compile right now. */
399 void
400 cgraph_finalize_function (tree decl, bool nested)
402 struct cgraph_node *node = cgraph_get_create_node (decl);
404 if (node->local.finalized)
406 cgraph_reset_node (node);
407 node->local.redefined_extern_inline = true;
410 notice_global_symbol (decl);
411 node->local.finalized = true;
412 node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL;
414 /* With -fkeep-inline-functions we are keeping all inline functions except
415 for extern inline ones. */
416 if (flag_keep_inline_functions
417 && DECL_DECLARED_INLINE_P (decl)
418 && !DECL_EXTERNAL (decl)
419 && !DECL_DISREGARD_INLINE_LIMITS (decl))
420 node->symbol.force_output = 1;
422 /* When not optimizing, also output the static functions. (see
423 PR24561), but don't do so for always_inline functions, functions
424 declared inline and nested functions. These were optimized out
425 in the original implementation and it is unclear whether we want
426 to change the behavior here. */
427 if ((!optimize
428 && !node->same_body_alias
429 && !DECL_DISREGARD_INLINE_LIMITS (decl)
430 && !DECL_DECLARED_INLINE_P (decl)
431 && !(DECL_CONTEXT (decl)
432 && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL))
433 && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
434 node->symbol.force_output = 1;
436 /* If we've not yet emitted decl, tell the debug info about it. */
437 if (!TREE_ASM_WRITTEN (decl))
438 (*debug_hooks->deferred_inline_function) (decl);
440 /* Possibly warn about unused parameters. */
441 if (warn_unused_parameter)
442 do_warn_unused_parameter (decl);
444 if (!nested)
445 ggc_collect ();
447 if (cgraph_state == CGRAPH_STATE_CONSTRUCTION
448 && (cgraph_decide_is_function_needed (node, decl)
449 || referred_to_p ((symtab_node)node)))
450 enqueue_node ((symtab_node)node);
453 /* Add the function FNDECL to the call graph.
454 Unlike cgraph_finalize_function, this function is intended to be used
455 by middle end and allows insertion of new function at arbitrary point
456 of compilation. The function can be either in high, low or SSA form
457 GIMPLE.
459 The function is assumed to be reachable and have address taken (so no
460 API breaking optimizations are performed on it).
462 Main work done by this function is to enqueue the function for later
463 processing to avoid need the passes to be re-entrant. */
465 void
466 cgraph_add_new_function (tree fndecl, bool lowered)
468 struct cgraph_node *node;
469 switch (cgraph_state)
471 case CGRAPH_STATE_PARSING:
472 cgraph_finalize_function (fndecl, false);
473 break;
474 case CGRAPH_STATE_CONSTRUCTION:
475 /* Just enqueue function to be processed at nearest occurrence. */
476 node = cgraph_create_node (fndecl);
477 if (lowered)
478 node->lowered = true;
479 if (!cgraph_new_nodes)
480 cgraph_new_nodes = cgraph_node_set_new ();
481 cgraph_node_set_add (cgraph_new_nodes, node);
482 break;
484 case CGRAPH_STATE_IPA:
485 case CGRAPH_STATE_IPA_SSA:
486 case CGRAPH_STATE_EXPANSION:
487 /* Bring the function into finalized state and enqueue for later
488 analyzing and compilation. */
489 node = cgraph_get_create_node (fndecl);
490 node->local.local = false;
491 node->local.finalized = true;
492 node->symbol.force_output = true;
493 if (!lowered && cgraph_state == CGRAPH_STATE_EXPANSION)
495 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
496 gimple_register_cfg_hooks ();
497 bitmap_obstack_initialize (NULL);
498 execute_pass_list (all_lowering_passes);
499 execute_pass_list (pass_early_local_passes.pass.sub);
500 bitmap_obstack_release (NULL);
501 pop_cfun ();
503 lowered = true;
505 if (lowered)
506 node->lowered = true;
507 if (!cgraph_new_nodes)
508 cgraph_new_nodes = cgraph_node_set_new ();
509 cgraph_node_set_add (cgraph_new_nodes, node);
510 break;
512 case CGRAPH_STATE_FINISHED:
513 /* At the very end of compilation we have to do all the work up
514 to expansion. */
515 node = cgraph_create_node (fndecl);
516 if (lowered)
517 node->lowered = true;
518 cgraph_analyze_function (node);
519 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
520 gimple_register_cfg_hooks ();
521 bitmap_obstack_initialize (NULL);
522 if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
523 execute_pass_list (pass_early_local_passes.pass.sub);
524 bitmap_obstack_release (NULL);
525 pop_cfun ();
526 expand_function (node);
527 break;
529 default:
530 gcc_unreachable ();
533 /* Set a personality if required and we already passed EH lowering. */
534 if (lowered
535 && (function_needs_eh_personality (DECL_STRUCT_FUNCTION (fndecl))
536 == eh_personality_lang))
537 DECL_FUNCTION_PERSONALITY (fndecl) = lang_hooks.eh_personality ();
540 /* Add a top-level asm statement to the list. */
542 struct asm_node *
543 add_asm_node (tree asm_str)
545 struct asm_node *node;
547 node = ggc_alloc_cleared_asm_node ();
548 node->asm_str = asm_str;
549 node->order = symtab_order++;
550 node->next = NULL;
551 if (asm_nodes == NULL)
552 asm_nodes = node;
553 else
554 asm_last_node->next = node;
555 asm_last_node = node;
556 return node;
559 /* Output all asm statements we have stored up to be output. */
561 static void
562 output_asm_statements (void)
564 struct asm_node *can;
566 if (seen_error ())
567 return;
569 for (can = asm_nodes; can; can = can->next)
570 assemble_asm (can->asm_str);
571 asm_nodes = NULL;
574 /* C++ FE sometimes change linkage flags after producing same body aliases. */
575 void
576 fixup_same_cpp_alias_visibility (symtab_node node, symtab_node target, tree alias)
578 DECL_VIRTUAL_P (node->symbol.decl) = DECL_VIRTUAL_P (alias);
579 if (TREE_PUBLIC (node->symbol.decl))
581 DECL_EXTERNAL (node->symbol.decl) = DECL_EXTERNAL (alias);
582 DECL_COMDAT (node->symbol.decl) = DECL_COMDAT (alias);
583 DECL_COMDAT_GROUP (node->symbol.decl) = DECL_COMDAT_GROUP (alias);
584 if (DECL_ONE_ONLY (alias)
585 && !node->symbol.same_comdat_group)
586 symtab_add_to_same_comdat_group ((symtab_node)node, (symtab_node)target);
590 /* Analyze the function scheduled to be output. */
591 static void
592 cgraph_analyze_function (struct cgraph_node *node)
594 tree decl = node->symbol.decl;
595 location_t saved_loc = input_location;
596 input_location = DECL_SOURCE_LOCATION (decl);
598 if (node->alias && node->thunk.alias)
600 struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias);
601 struct cgraph_node *n;
603 for (n = tgt; n && n->alias;
604 n = n->analyzed ? cgraph_alias_aliased_node (n) : NULL)
605 if (n == node)
607 error ("function %q+D part of alias cycle", node->symbol.decl);
608 node->alias = false;
609 input_location = saved_loc;
610 return;
612 if (!VEC_length (ipa_ref_t, node->symbol.ref_list.references))
613 ipa_record_reference ((symtab_node)node, (symtab_node)tgt,
614 IPA_REF_ALIAS, NULL);
615 if (node->same_body_alias)
617 DECL_DECLARED_INLINE_P (node->symbol.decl)
618 = DECL_DECLARED_INLINE_P (node->thunk.alias);
619 DECL_DISREGARD_INLINE_LIMITS (node->symbol.decl)
620 = DECL_DISREGARD_INLINE_LIMITS (node->thunk.alias);
621 fixup_same_cpp_alias_visibility ((symtab_node) node, (symtab_node) tgt, node->thunk.alias);
624 if (node->symbol.address_taken)
625 cgraph_mark_address_taken_node (cgraph_alias_aliased_node (node));
627 else if (node->thunk.thunk_p)
629 cgraph_create_edge (node, cgraph_get_node (node->thunk.alias),
630 NULL, 0, CGRAPH_FREQ_BASE);
632 else
634 push_cfun (DECL_STRUCT_FUNCTION (decl));
636 assign_assembler_name_if_neeeded (node->symbol.decl);
638 /* Make sure to gimplify bodies only once. During analyzing a
639 function we lower it, which will require gimplified nested
640 functions, so we can end up here with an already gimplified
641 body. */
642 if (!gimple_has_body_p (decl))
643 gimplify_function_tree (decl);
644 dump_function (TDI_generic, decl);
646 /* Lower the function. */
647 if (!node->lowered)
649 if (node->nested)
650 lower_nested_functions (node->symbol.decl);
651 gcc_assert (!node->nested);
653 gimple_register_cfg_hooks ();
654 bitmap_obstack_initialize (NULL);
655 execute_pass_list (all_lowering_passes);
656 free_dominance_info (CDI_POST_DOMINATORS);
657 free_dominance_info (CDI_DOMINATORS);
658 compact_blocks ();
659 bitmap_obstack_release (NULL);
660 node->lowered = true;
663 pop_cfun ();
665 node->analyzed = true;
667 input_location = saved_loc;
670 /* C++ frontend produce same body aliases all over the place, even before PCH
671 gets streamed out. It relies on us linking the aliases with their function
672 in order to do the fixups, but ipa-ref is not PCH safe. Consequentely we
673 first produce aliases without links, but once C++ FE is sure he won't sream
674 PCH we build the links via this function. */
676 void
677 cgraph_process_same_body_aliases (void)
679 struct cgraph_node *node;
680 FOR_EACH_FUNCTION (node)
681 if (node->same_body_alias
682 && !VEC_length (ipa_ref_t, node->symbol.ref_list.references))
684 struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias);
685 ipa_record_reference ((symtab_node)node, (symtab_node)tgt,
686 IPA_REF_ALIAS, NULL);
688 same_body_aliases_done = true;
691 /* Process attributes common for vars and functions. */
693 static void
694 process_common_attributes (tree decl)
696 tree weakref = lookup_attribute ("weakref", DECL_ATTRIBUTES (decl));
698 if (weakref && !lookup_attribute ("alias", DECL_ATTRIBUTES (decl)))
700 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
701 "%<weakref%> attribute should be accompanied with"
702 " an %<alias%> attribute");
703 DECL_WEAK (decl) = 0;
704 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
705 DECL_ATTRIBUTES (decl));
709 /* Look for externally_visible and used attributes and mark cgraph nodes
710 accordingly.
712 We cannot mark the nodes at the point the attributes are processed (in
713 handle_*_attribute) because the copy of the declarations available at that
714 point may not be canonical. For example, in:
716 void f();
717 void f() __attribute__((used));
719 the declaration we see in handle_used_attribute will be the second
720 declaration -- but the front end will subsequently merge that declaration
721 with the original declaration and discard the second declaration.
723 Furthermore, we can't mark these nodes in cgraph_finalize_function because:
725 void f() {}
726 void f() __attribute__((externally_visible));
728 is valid.
730 So, we walk the nodes at the end of the translation unit, applying the
731 attributes at that point. */
733 static void
734 process_function_and_variable_attributes (struct cgraph_node *first,
735 struct varpool_node *first_var)
737 struct cgraph_node *node;
738 struct varpool_node *vnode;
740 for (node = cgraph_first_function (); node != first;
741 node = cgraph_next_function (node))
743 tree decl = node->symbol.decl;
744 if (DECL_PRESERVE_P (decl))
745 cgraph_mark_force_output_node (node);
746 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
748 if (! TREE_PUBLIC (node->symbol.decl))
749 warning_at (DECL_SOURCE_LOCATION (node->symbol.decl), OPT_Wattributes,
750 "%<externally_visible%>"
751 " attribute have effect only on public objects");
753 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
754 && (node->local.finalized && !node->alias))
756 warning_at (DECL_SOURCE_LOCATION (node->symbol.decl), OPT_Wattributes,
757 "%<weakref%> attribute ignored"
758 " because function is defined");
759 DECL_WEAK (decl) = 0;
760 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
761 DECL_ATTRIBUTES (decl));
764 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl))
765 && !DECL_DECLARED_INLINE_P (decl)
766 /* redefining extern inline function makes it DECL_UNINLINABLE. */
767 && !DECL_UNINLINABLE (decl))
768 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
769 "always_inline function might not be inlinable");
771 process_common_attributes (decl);
773 for (vnode = varpool_first_variable (); vnode != first_var;
774 vnode = varpool_next_variable (vnode))
776 tree decl = vnode->symbol.decl;
777 if (DECL_EXTERNAL (decl)
778 && DECL_INITIAL (decl)
779 && const_value_known_p (decl))
780 varpool_finalize_decl (decl);
781 if (DECL_PRESERVE_P (decl))
782 vnode->symbol.force_output = true;
783 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
785 if (! TREE_PUBLIC (vnode->symbol.decl))
786 warning_at (DECL_SOURCE_LOCATION (vnode->symbol.decl), OPT_Wattributes,
787 "%<externally_visible%>"
788 " attribute have effect only on public objects");
790 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
791 && vnode->finalized
792 && DECL_INITIAL (decl))
794 warning_at (DECL_SOURCE_LOCATION (vnode->symbol.decl), OPT_Wattributes,
795 "%<weakref%> attribute ignored"
796 " because variable is initialized");
797 DECL_WEAK (decl) = 0;
798 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
799 DECL_ATTRIBUTES (decl));
801 process_common_attributes (decl);
805 /* Mark DECL as finalized. By finalizing the declaration, frontend instruct the
806 middle end to output the variable to asm file, if needed or externally
807 visible. */
809 void
810 varpool_finalize_decl (tree decl)
812 struct varpool_node *node = varpool_node (decl);
814 gcc_assert (TREE_STATIC (decl) || DECL_EXTERNAL (decl));
816 if (node->finalized)
817 return;
818 notice_global_symbol (decl);
819 node->finalized = true;
820 if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
821 /* Traditionally we do not eliminate static variables when not
822 optimizing and when not doing toplevel reoder. */
823 || (!flag_toplevel_reorder && !DECL_COMDAT (node->symbol.decl)
824 && !DECL_ARTIFICIAL (node->symbol.decl)))
825 node->symbol.force_output = true;
827 if (cgraph_state == CGRAPH_STATE_CONSTRUCTION
828 && (decide_is_variable_needed (node, decl)
829 || referred_to_p ((symtab_node)node)))
830 enqueue_node ((symtab_node)node);
831 if (cgraph_state >= CGRAPH_STATE_IPA_SSA)
832 varpool_analyze_node (node);
833 /* Some frontends produce various interface variables after compilation
834 finished. */
835 if (cgraph_state == CGRAPH_STATE_FINISHED)
836 varpool_assemble_decl (node);
839 /* Discover all functions and variables that are trivially needed, analyze
840 them as well as all functions and variables referred by them */
842 static void
843 cgraph_analyze_functions (void)
845 /* Keep track of already processed nodes when called multiple times for
846 intermodule optimization. */
847 static struct cgraph_node *first_analyzed;
848 struct cgraph_node *first_handled = first_analyzed;
849 static struct varpool_node *first_analyzed_var;
850 struct varpool_node *first_handled_var = first_analyzed_var;
852 symtab_node node, next;
853 int i;
854 struct ipa_ref *ref;
855 bool changed = true;
857 bitmap_obstack_initialize (NULL);
858 cgraph_state = CGRAPH_STATE_CONSTRUCTION;
860 /* Analysis adds static variables that in turn adds references to new functions.
861 So we need to iterate the process until it stabilize. */
862 while (changed)
864 changed = false;
865 process_function_and_variable_attributes (first_analyzed,
866 first_analyzed_var);
868 /* First identify the trivially needed symbols. */
869 for (node = symtab_nodes;
870 node != (symtab_node)first_analyzed
871 && node != (symtab_node)first_analyzed_var; node = node->symbol.next)
873 if ((symtab_function_p (node)
874 && cgraph (node)->local.finalized
875 && cgraph_decide_is_function_needed (cgraph (node), node->symbol.decl))
876 || (symtab_variable_p (node)
877 && varpool (node)->finalized
878 && !DECL_EXTERNAL (node->symbol.decl)
879 && decide_is_variable_needed (varpool (node), node->symbol.decl)))
881 enqueue_node (node);
882 if (!changed && cgraph_dump_file)
883 fprintf (cgraph_dump_file, "Trivially needed symbols:");
884 changed = true;
885 if (cgraph_dump_file)
886 fprintf (cgraph_dump_file, " %s", symtab_node_asm_name (node));
888 if (node == (symtab_node)first_analyzed
889 || node == (symtab_node)first_analyzed_var)
890 break;
892 cgraph_process_new_functions ();
893 first_analyzed_var = varpool_first_variable ();
894 first_analyzed = cgraph_first_function ();
896 if (changed && dump_file)
897 fprintf (cgraph_dump_file, "\n");
899 /* Lower representation, build callgraph edges and references for all trivially
900 needed symbols and all symbols referred by them. */
901 while (first != (symtab_node)(void *)1)
903 changed = true;
904 node = first;
905 first = (symtab_node)first->symbol.aux;
906 if (symtab_function_p (node) && cgraph (node)->local.finalized)
908 struct cgraph_edge *edge;
909 struct cgraph_node *cnode;
910 tree decl;
912 cnode = cgraph (node);
913 decl = cnode->symbol.decl;
915 /* ??? It is possible to create extern inline function and later using
916 weak alias attribute to kill its body. See
917 gcc.c-torture/compile/20011119-1.c */
918 if (!DECL_STRUCT_FUNCTION (decl)
919 && (!cnode->alias || !cnode->thunk.alias)
920 && !cnode->thunk.thunk_p)
922 cgraph_reset_node (cnode);
923 cnode->local.redefined_extern_inline = true;
924 continue;
927 if (!cnode->analyzed)
928 cgraph_analyze_function (cnode);
930 for (edge = cnode->callees; edge; edge = edge->next_callee)
931 if (edge->callee->local.finalized)
932 enqueue_node ((symtab_node)edge->callee);
934 /* If decl is a clone of an abstract function, mark that abstract
935 function so that we don't release its body. The DECL_INITIAL() of that
936 abstract function declaration will be later needed to output debug
937 info. */
938 if (DECL_ABSTRACT_ORIGIN (decl))
940 struct cgraph_node *origin_node;
941 origin_node = cgraph_get_node (DECL_ABSTRACT_ORIGIN (decl));
942 origin_node->abstract_and_needed = true;
946 else if (symtab_variable_p (node)
947 && varpool (node)->finalized)
948 varpool_analyze_node (varpool (node));
950 if (node->symbol.same_comdat_group)
952 symtab_node next;
953 for (next = node->symbol.same_comdat_group;
954 next != node;
955 next = next->symbol.same_comdat_group)
956 enqueue_node (next);
958 for (i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list, i, ref); i++)
959 if ((symtab_function_p (ref->referred) && cgraph (ref->referred)->local.finalized)
960 || (symtab_variable_p (ref->referred) && varpool (ref->referred)->finalized))
961 enqueue_node (ref->referred);
962 cgraph_process_new_functions ();
966 /* Collect entry points to the unit. */
967 if (cgraph_dump_file)
969 fprintf (cgraph_dump_file, "\n\nInitial ");
970 dump_symtab (cgraph_dump_file);
973 if (cgraph_dump_file)
974 fprintf (cgraph_dump_file, "\nRemoving unused symbols:");
976 for (node = symtab_nodes;
977 node != (symtab_node)first_handled
978 && node != (symtab_node)first_handled_var; node = next)
980 next = node->symbol.next;
981 if (!node->symbol.aux && !referred_to_p (node))
983 if (cgraph_dump_file)
984 fprintf (cgraph_dump_file, " %s", symtab_node_name (node));
985 symtab_remove_node (node);
986 continue;
988 if (symtab_function_p (node))
990 tree decl = node->symbol.decl;
991 struct cgraph_node *cnode = cgraph (node);
993 if (cnode->local.finalized && !gimple_has_body_p (decl)
994 && (!cnode->alias || !cnode->thunk.alias)
995 && !cnode->thunk.thunk_p)
996 cgraph_reset_node (cnode);
998 gcc_assert (!cnode->local.finalized || cnode->thunk.thunk_p
999 || cnode->alias
1000 || gimple_has_body_p (decl));
1001 gcc_assert (cnode->analyzed == cnode->local.finalized);
1003 node->symbol.aux = NULL;
1005 first_analyzed = cgraph_first_function ();
1006 first_analyzed_var = varpool_first_variable ();
1007 if (cgraph_dump_file)
1009 fprintf (cgraph_dump_file, "\n\nReclaimed ");
1010 dump_symtab (cgraph_dump_file);
1012 bitmap_obstack_release (NULL);
1013 ggc_collect ();
1016 /* Translate the ugly representation of aliases as alias pairs into nice
1017 representation in callgraph. We don't handle all cases yet,
1018 unforutnately. */
1020 static void
1021 handle_alias_pairs (void)
1023 alias_pair *p;
1024 unsigned i;
1026 for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p);)
1028 symtab_node target_node = symtab_node_for_asm (p->target);
1030 /* Weakrefs with target not defined in current unit are easy to handle; they
1031 behave just as external variables except we need to note the alias flag
1032 to later output the weakref pseudo op into asm file. */
1033 if (!target_node && lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL)
1035 if (TREE_CODE (p->decl) == FUNCTION_DECL)
1036 cgraph_get_create_node (p->decl)->alias = true;
1037 else
1038 varpool_get_node (p->decl)->alias = true;
1039 DECL_EXTERNAL (p->decl) = 1;
1040 VEC_unordered_remove (alias_pair, alias_pairs, i);
1041 continue;
1043 else if (!target_node)
1045 error ("%q+D aliased to undefined symbol %qE", p->decl, p->target);
1046 VEC_unordered_remove (alias_pair, alias_pairs, i);
1047 continue;
1050 /* Normally EXTERNAL flag is used to mark external inlines,
1051 however for aliases it seems to be allowed to use it w/o
1052 any meaning. See gcc.dg/attr-alias-3.c
1053 However for weakref we insist on EXTERNAL flag being set.
1054 See gcc.dg/attr-alias-5.c */
1055 if (DECL_EXTERNAL (p->decl))
1056 DECL_EXTERNAL (p->decl)
1057 = lookup_attribute ("weakref",
1058 DECL_ATTRIBUTES (p->decl)) != NULL;
1060 if (DECL_EXTERNAL (target_node->symbol.decl)
1061 /* We use local aliases for C++ thunks to force the tailcall
1062 to bind locally. This is a hack - to keep it working do
1063 the following (which is not strictly correct). */
1064 && (! TREE_CODE (target_node->symbol.decl) == FUNCTION_DECL
1065 || ! DECL_VIRTUAL_P (target_node->symbol.decl))
1066 && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)))
1068 error ("%q+D aliased to external symbol %qE",
1069 p->decl, p->target);
1072 if (TREE_CODE (p->decl) == FUNCTION_DECL
1073 && target_node && symtab_function_p (target_node))
1075 struct cgraph_node *src_node = cgraph_get_node (p->decl);
1076 if (src_node && src_node->local.finalized)
1077 cgraph_reset_node (src_node);
1078 cgraph_create_function_alias (p->decl, target_node->symbol.decl);
1079 VEC_unordered_remove (alias_pair, alias_pairs, i);
1081 else if (TREE_CODE (p->decl) == VAR_DECL
1082 && target_node && symtab_variable_p (target_node))
1084 varpool_create_variable_alias (p->decl, target_node->symbol.decl);
1085 VEC_unordered_remove (alias_pair, alias_pairs, i);
1087 else
1089 error ("%q+D alias in between function and variable is not supported",
1090 p->decl);
1091 warning (0, "%q+D aliased declaration",
1092 target_node->symbol.decl);
1093 VEC_unordered_remove (alias_pair, alias_pairs, i);
1096 VEC_free (alias_pair, gc, alias_pairs);
1100 /* Figure out what functions we want to assemble. */
1102 static void
1103 mark_functions_to_output (void)
1105 struct cgraph_node *node;
1106 #ifdef ENABLE_CHECKING
1107 bool check_same_comdat_groups = false;
1109 FOR_EACH_FUNCTION (node)
1110 gcc_assert (!node->process);
1111 #endif
1113 FOR_EACH_FUNCTION (node)
1115 tree decl = node->symbol.decl;
1117 gcc_assert (!node->process || node->symbol.same_comdat_group);
1118 if (node->process)
1119 continue;
1121 /* We need to output all local functions that are used and not
1122 always inlined, as well as those that are reachable from
1123 outside the current compilation unit. */
1124 if (node->analyzed
1125 && !node->thunk.thunk_p
1126 && !node->alias
1127 && !node->global.inlined_to
1128 && !TREE_ASM_WRITTEN (decl)
1129 && !DECL_EXTERNAL (decl))
1131 node->process = 1;
1132 if (node->symbol.same_comdat_group)
1134 struct cgraph_node *next;
1135 for (next = cgraph (node->symbol.same_comdat_group);
1136 next != node;
1137 next = cgraph (next->symbol.same_comdat_group))
1138 if (!next->thunk.thunk_p && !next->alias)
1139 next->process = 1;
1142 else if (node->symbol.same_comdat_group)
1144 #ifdef ENABLE_CHECKING
1145 check_same_comdat_groups = true;
1146 #endif
1148 else
1150 /* We should've reclaimed all functions that are not needed. */
1151 #ifdef ENABLE_CHECKING
1152 if (!node->global.inlined_to
1153 && gimple_has_body_p (decl)
1154 /* FIXME: in ltrans unit when offline copy is outside partition but inline copies
1155 are inside partition, we can end up not removing the body since we no longer
1156 have analyzed node pointing to it. */
1157 && !node->symbol.in_other_partition
1158 && !node->alias
1159 && !node->clones
1160 && !DECL_EXTERNAL (decl))
1162 dump_cgraph_node (stderr, node);
1163 internal_error ("failed to reclaim unneeded function");
1165 #endif
1166 gcc_assert (node->global.inlined_to
1167 || !gimple_has_body_p (decl)
1168 || node->symbol.in_other_partition
1169 || node->clones
1170 || DECL_ARTIFICIAL (decl)
1171 || DECL_EXTERNAL (decl));
1176 #ifdef ENABLE_CHECKING
1177 if (check_same_comdat_groups)
1178 FOR_EACH_FUNCTION (node)
1179 if (node->symbol.same_comdat_group && !node->process)
1181 tree decl = node->symbol.decl;
1182 if (!node->global.inlined_to
1183 && gimple_has_body_p (decl)
1184 /* FIXME: in an ltrans unit when the offline copy is outside a
1185 partition but inline copies are inside a partition, we can
1186 end up not removing the body since we no longer have an
1187 analyzed node pointing to it. */
1188 && !node->symbol.in_other_partition
1189 && !node->clones
1190 && !DECL_EXTERNAL (decl))
1192 dump_cgraph_node (stderr, node);
1193 internal_error ("failed to reclaim unneeded function in same "
1194 "comdat group");
1197 #endif
1200 /* DECL is FUNCTION_DECL. Initialize datastructures so DECL is a function
1201 in lowered gimple form.
1203 Set current_function_decl and cfun to newly constructed empty function body.
1204 return basic block in the function body. */
1206 static basic_block
1207 init_lowered_empty_function (tree decl)
1209 basic_block bb;
1211 current_function_decl = decl;
1212 allocate_struct_function (decl, false);
1213 gimple_register_cfg_hooks ();
1214 init_empty_tree_cfg ();
1215 init_tree_ssa (cfun);
1216 init_ssa_operands (cfun);
1217 cfun->gimple_df->in_ssa_p = true;
1218 DECL_INITIAL (decl) = make_node (BLOCK);
1220 DECL_SAVED_TREE (decl) = error_mark_node;
1221 cfun->curr_properties |=
1222 (PROP_gimple_lcf | PROP_gimple_leh | PROP_cfg | PROP_ssa | PROP_gimple_any);
1224 /* Create BB for body of the function and connect it properly. */
1225 bb = create_basic_block (NULL, (void *) 0, ENTRY_BLOCK_PTR);
1226 make_edge (ENTRY_BLOCK_PTR, bb, 0);
1227 make_edge (bb, EXIT_BLOCK_PTR, 0);
1229 return bb;
1232 /* Adjust PTR by the constant FIXED_OFFSET, and by the vtable
1233 offset indicated by VIRTUAL_OFFSET, if that is
1234 non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and
1235 zero for a result adjusting thunk. */
1237 static tree
1238 thunk_adjust (gimple_stmt_iterator * bsi,
1239 tree ptr, bool this_adjusting,
1240 HOST_WIDE_INT fixed_offset, tree virtual_offset)
1242 gimple stmt;
1243 tree ret;
1245 if (this_adjusting
1246 && fixed_offset != 0)
1248 stmt = gimple_build_assign
1249 (ptr, fold_build_pointer_plus_hwi_loc (input_location,
1250 ptr,
1251 fixed_offset));
1252 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1255 /* If there's a virtual offset, look up that value in the vtable and
1256 adjust the pointer again. */
1257 if (virtual_offset)
1259 tree vtabletmp;
1260 tree vtabletmp2;
1261 tree vtabletmp3;
1263 if (!vtable_entry_type)
1265 tree vfunc_type = make_node (FUNCTION_TYPE);
1266 TREE_TYPE (vfunc_type) = integer_type_node;
1267 TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
1268 layout_type (vfunc_type);
1270 vtable_entry_type = build_pointer_type (vfunc_type);
1273 vtabletmp =
1274 create_tmp_reg (build_pointer_type
1275 (build_pointer_type (vtable_entry_type)), "vptr");
1277 /* The vptr is always at offset zero in the object. */
1278 stmt = gimple_build_assign (vtabletmp,
1279 build1 (NOP_EXPR, TREE_TYPE (vtabletmp),
1280 ptr));
1281 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1283 /* Form the vtable address. */
1284 vtabletmp2 = create_tmp_reg (TREE_TYPE (TREE_TYPE (vtabletmp)),
1285 "vtableaddr");
1286 stmt = gimple_build_assign (vtabletmp2,
1287 build_simple_mem_ref (vtabletmp));
1288 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1290 /* Find the entry with the vcall offset. */
1291 stmt = gimple_build_assign (vtabletmp2,
1292 fold_build_pointer_plus_loc (input_location,
1293 vtabletmp2,
1294 virtual_offset));
1295 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1297 /* Get the offset itself. */
1298 vtabletmp3 = create_tmp_reg (TREE_TYPE (TREE_TYPE (vtabletmp2)),
1299 "vcalloffset");
1300 stmt = gimple_build_assign (vtabletmp3,
1301 build_simple_mem_ref (vtabletmp2));
1302 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1304 /* Adjust the `this' pointer. */
1305 ptr = fold_build_pointer_plus_loc (input_location, ptr, vtabletmp3);
1306 ptr = force_gimple_operand_gsi (bsi, ptr, true, NULL_TREE, false,
1307 GSI_CONTINUE_LINKING);
1310 if (!this_adjusting
1311 && fixed_offset != 0)
1312 /* Adjust the pointer by the constant. */
1314 tree ptrtmp;
1316 if (TREE_CODE (ptr) == VAR_DECL)
1317 ptrtmp = ptr;
1318 else
1320 ptrtmp = create_tmp_reg (TREE_TYPE (ptr), "ptr");
1321 stmt = gimple_build_assign (ptrtmp, ptr);
1322 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1324 ptr = fold_build_pointer_plus_hwi_loc (input_location,
1325 ptrtmp, fixed_offset);
1328 /* Emit the statement and gimplify the adjustment expression. */
1329 ret = create_tmp_reg (TREE_TYPE (ptr), "adjusted_this");
1330 stmt = gimple_build_assign (ret, ptr);
1331 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1333 return ret;
1336 /* Produce assembler for thunk NODE. */
1338 static void
1339 assemble_thunk (struct cgraph_node *node)
1341 bool this_adjusting = node->thunk.this_adjusting;
1342 HOST_WIDE_INT fixed_offset = node->thunk.fixed_offset;
1343 HOST_WIDE_INT virtual_value = node->thunk.virtual_value;
1344 tree virtual_offset = NULL;
1345 tree alias = node->thunk.alias;
1346 tree thunk_fndecl = node->symbol.decl;
1347 tree a = DECL_ARGUMENTS (thunk_fndecl);
1349 current_function_decl = thunk_fndecl;
1351 /* Ensure thunks are emitted in their correct sections. */
1352 resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
1354 if (this_adjusting
1355 && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
1356 virtual_value, alias))
1358 const char *fnname;
1359 tree fn_block;
1360 tree restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1362 DECL_RESULT (thunk_fndecl)
1363 = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl),
1364 RESULT_DECL, 0, restype);
1365 fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
1367 /* The back end expects DECL_INITIAL to contain a BLOCK, so we
1368 create one. */
1369 fn_block = make_node (BLOCK);
1370 BLOCK_VARS (fn_block) = a;
1371 DECL_INITIAL (thunk_fndecl) = fn_block;
1372 init_function_start (thunk_fndecl);
1373 cfun->is_thunk = 1;
1374 assemble_start_function (thunk_fndecl, fnname);
1375 (*debug_hooks->source_line) (DECL_SOURCE_LINE (thunk_fndecl),
1376 DECL_SOURCE_FILE (thunk_fndecl),
1377 /* discriminator */ 0,
1378 /* is_stmt */ 1);
1380 targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl,
1381 fixed_offset, virtual_value, alias);
1383 assemble_end_function (thunk_fndecl, fnname);
1384 init_insn_lengths ();
1385 free_after_compilation (cfun);
1386 set_cfun (NULL);
1387 TREE_ASM_WRITTEN (thunk_fndecl) = 1;
1388 node->thunk.thunk_p = false;
1389 node->analyzed = false;
1391 else
1393 tree restype;
1394 basic_block bb, then_bb, else_bb, return_bb;
1395 gimple_stmt_iterator bsi;
1396 int nargs = 0;
1397 tree arg;
1398 int i;
1399 tree resdecl;
1400 tree restmp = NULL;
1401 VEC(tree, heap) *vargs;
1403 gimple call;
1404 gimple ret;
1406 DECL_IGNORED_P (thunk_fndecl) = 1;
1407 bitmap_obstack_initialize (NULL);
1409 if (node->thunk.virtual_offset_p)
1410 virtual_offset = size_int (virtual_value);
1412 /* Build the return declaration for the function. */
1413 restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1414 if (DECL_RESULT (thunk_fndecl) == NULL_TREE)
1416 resdecl = build_decl (input_location, RESULT_DECL, 0, restype);
1417 DECL_ARTIFICIAL (resdecl) = 1;
1418 DECL_IGNORED_P (resdecl) = 1;
1419 DECL_RESULT (thunk_fndecl) = resdecl;
1421 else
1422 resdecl = DECL_RESULT (thunk_fndecl);
1424 bb = then_bb = else_bb = return_bb = init_lowered_empty_function (thunk_fndecl);
1426 bsi = gsi_start_bb (bb);
1428 /* Build call to the function being thunked. */
1429 if (!VOID_TYPE_P (restype))
1431 if (!is_gimple_reg_type (restype))
1433 restmp = resdecl;
1434 add_local_decl (cfun, restmp);
1435 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp;
1437 else
1438 restmp = create_tmp_reg (restype, "retval");
1441 for (arg = a; arg; arg = DECL_CHAIN (arg))
1442 nargs++;
1443 vargs = VEC_alloc (tree, heap, nargs);
1444 if (this_adjusting)
1445 VEC_quick_push (tree, vargs,
1446 thunk_adjust (&bsi,
1447 a, 1, fixed_offset,
1448 virtual_offset));
1449 else
1450 VEC_quick_push (tree, vargs, a);
1451 for (i = 1, arg = DECL_CHAIN (a); i < nargs; i++, arg = DECL_CHAIN (arg))
1452 VEC_quick_push (tree, vargs, arg);
1453 call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs);
1454 VEC_free (tree, heap, vargs);
1455 gimple_call_set_from_thunk (call, true);
1456 if (restmp)
1457 gimple_call_set_lhs (call, restmp);
1458 gsi_insert_after (&bsi, call, GSI_NEW_STMT);
1460 if (restmp && !this_adjusting)
1462 tree true_label = NULL_TREE;
1464 if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE)
1466 gimple stmt;
1467 /* If the return type is a pointer, we need to
1468 protect against NULL. We know there will be an
1469 adjustment, because that's why we're emitting a
1470 thunk. */
1471 then_bb = create_basic_block (NULL, (void *) 0, bb);
1472 return_bb = create_basic_block (NULL, (void *) 0, then_bb);
1473 else_bb = create_basic_block (NULL, (void *) 0, else_bb);
1474 remove_edge (single_succ_edge (bb));
1475 true_label = gimple_block_label (then_bb);
1476 stmt = gimple_build_cond (NE_EXPR, restmp,
1477 build_zero_cst (TREE_TYPE (restmp)),
1478 NULL_TREE, NULL_TREE);
1479 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1480 make_edge (bb, then_bb, EDGE_TRUE_VALUE);
1481 make_edge (bb, else_bb, EDGE_FALSE_VALUE);
1482 make_edge (return_bb, EXIT_BLOCK_PTR, 0);
1483 make_edge (then_bb, return_bb, EDGE_FALLTHRU);
1484 make_edge (else_bb, return_bb, EDGE_FALLTHRU);
1485 bsi = gsi_last_bb (then_bb);
1488 restmp = thunk_adjust (&bsi, restmp, /*this_adjusting=*/0,
1489 fixed_offset, virtual_offset);
1490 if (true_label)
1492 gimple stmt;
1493 bsi = gsi_last_bb (else_bb);
1494 stmt = gimple_build_assign (restmp,
1495 build_zero_cst (TREE_TYPE (restmp)));
1496 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1497 bsi = gsi_last_bb (return_bb);
1500 else
1501 gimple_call_set_tail (call, true);
1503 /* Build return value. */
1504 ret = gimple_build_return (restmp);
1505 gsi_insert_after (&bsi, ret, GSI_NEW_STMT);
1507 delete_unreachable_blocks ();
1508 update_ssa (TODO_update_ssa);
1510 /* Since we want to emit the thunk, we explicitly mark its name as
1511 referenced. */
1512 node->thunk.thunk_p = false;
1513 cgraph_node_remove_callees (node);
1514 cgraph_add_new_function (thunk_fndecl, true);
1515 bitmap_obstack_release (NULL);
1517 current_function_decl = NULL;
1518 set_cfun (NULL);
1523 /* Assemble thunks and aliases associated to NODE. */
1525 static void
1526 assemble_thunks_and_aliases (struct cgraph_node *node)
1528 struct cgraph_edge *e;
1529 int i;
1530 struct ipa_ref *ref;
1532 for (e = node->callers; e;)
1533 if (e->caller->thunk.thunk_p)
1535 struct cgraph_node *thunk = e->caller;
1537 e = e->next_caller;
1538 assemble_thunks_and_aliases (thunk);
1539 assemble_thunk (thunk);
1541 else
1542 e = e->next_caller;
1543 for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list,
1544 i, ref); i++)
1545 if (ref->use == IPA_REF_ALIAS)
1547 struct cgraph_node *alias = ipa_ref_referring_node (ref);
1548 bool saved_written = TREE_ASM_WRITTEN (alias->thunk.alias);
1550 /* Force assemble_alias to really output the alias this time instead
1551 of buffering it in same alias pairs. */
1552 TREE_ASM_WRITTEN (alias->thunk.alias) = 1;
1553 do_assemble_alias (alias->symbol.decl,
1554 DECL_ASSEMBLER_NAME (alias->thunk.alias));
1555 assemble_thunks_and_aliases (alias);
1556 TREE_ASM_WRITTEN (alias->thunk.alias) = saved_written;
1560 /* Expand function specified by NODE. */
1562 static void
1563 expand_function (struct cgraph_node *node)
1565 tree decl = node->symbol.decl;
1566 location_t saved_loc;
1568 /* We ought to not compile any inline clones. */
1569 gcc_assert (!node->global.inlined_to);
1571 announce_function (decl);
1572 node->process = 0;
1573 gcc_assert (node->lowered);
1575 /* Generate RTL for the body of DECL. */
1577 timevar_push (TV_REST_OF_COMPILATION);
1579 gcc_assert (cgraph_global_info_ready);
1581 /* Initialize the default bitmap obstack. */
1582 bitmap_obstack_initialize (NULL);
1584 /* Initialize the RTL code for the function. */
1585 current_function_decl = decl;
1586 saved_loc = input_location;
1587 input_location = DECL_SOURCE_LOCATION (decl);
1588 init_function_start (decl);
1590 gimple_register_cfg_hooks ();
1592 bitmap_obstack_initialize (&reg_obstack); /* FIXME, only at RTL generation*/
1594 execute_all_ipa_transforms ();
1596 /* Perform all tree transforms and optimizations. */
1598 /* Signal the start of passes. */
1599 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START, NULL);
1601 execute_pass_list (all_passes);
1603 /* Signal the end of passes. */
1604 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END, NULL);
1606 bitmap_obstack_release (&reg_obstack);
1608 /* Release the default bitmap obstack. */
1609 bitmap_obstack_release (NULL);
1611 /* If requested, warn about function definitions where the function will
1612 return a value (usually of some struct or union type) which itself will
1613 take up a lot of stack space. */
1614 if (warn_larger_than && !DECL_EXTERNAL (decl) && TREE_TYPE (decl))
1616 tree ret_type = TREE_TYPE (TREE_TYPE (decl));
1618 if (ret_type && TYPE_SIZE_UNIT (ret_type)
1619 && TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST
1620 && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type),
1621 larger_than_size))
1623 unsigned int size_as_int
1624 = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type));
1626 if (compare_tree_int (TYPE_SIZE_UNIT (ret_type), size_as_int) == 0)
1627 warning (OPT_Wlarger_than_, "size of return value of %q+D is %u bytes",
1628 decl, size_as_int);
1629 else
1630 warning (OPT_Wlarger_than_, "size of return value of %q+D is larger than %wd bytes",
1631 decl, larger_than_size);
1635 gimple_set_body (decl, NULL);
1636 if (DECL_STRUCT_FUNCTION (decl) == 0
1637 && !cgraph_get_node (decl)->origin)
1639 /* Stop pointing to the local nodes about to be freed.
1640 But DECL_INITIAL must remain nonzero so we know this
1641 was an actual function definition.
1642 For a nested function, this is done in c_pop_function_context.
1643 If rest_of_compilation set this to 0, leave it 0. */
1644 if (DECL_INITIAL (decl) != 0)
1645 DECL_INITIAL (decl) = error_mark_node;
1648 input_location = saved_loc;
1650 ggc_collect ();
1651 timevar_pop (TV_REST_OF_COMPILATION);
1653 /* Make sure that BE didn't give up on compiling. */
1654 gcc_assert (TREE_ASM_WRITTEN (decl));
1655 set_cfun (NULL);
1656 current_function_decl = NULL;
1658 /* It would make a lot more sense to output thunks before function body to get more
1659 forward and lest backwarding jumps. This however would need solving problem
1660 with comdats. See PR48668. Also aliases must come after function itself to
1661 make one pass assemblers, like one on AIX, happy. See PR 50689.
1662 FIXME: Perhaps thunks should be move before function IFF they are not in comdat
1663 groups. */
1664 assemble_thunks_and_aliases (node);
1665 cgraph_release_function_body (node);
1666 /* Eliminate all call edges. This is important so the GIMPLE_CALL no longer
1667 points to the dead function body. */
1668 cgraph_node_remove_callees (node);
1672 /* Expand all functions that must be output.
1674 Attempt to topologically sort the nodes so function is output when
1675 all called functions are already assembled to allow data to be
1676 propagated across the callgraph. Use a stack to get smaller distance
1677 between a function and its callees (later we may choose to use a more
1678 sophisticated algorithm for function reordering; we will likely want
1679 to use subsections to make the output functions appear in top-down
1680 order). */
1682 static void
1683 expand_all_functions (void)
1685 struct cgraph_node *node;
1686 struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
1687 int order_pos, new_order_pos = 0;
1688 int i;
1690 order_pos = ipa_reverse_postorder (order);
1691 gcc_assert (order_pos == cgraph_n_nodes);
1693 /* Garbage collector may remove inline clones we eliminate during
1694 optimization. So we must be sure to not reference them. */
1695 for (i = 0; i < order_pos; i++)
1696 if (order[i]->process)
1697 order[new_order_pos++] = order[i];
1699 for (i = new_order_pos - 1; i >= 0; i--)
1701 node = order[i];
1702 if (node->process)
1704 node->process = 0;
1705 expand_function (node);
1708 cgraph_process_new_functions ();
1710 free (order);
1714 /* This is used to sort the node types by the cgraph order number. */
1716 enum cgraph_order_sort_kind
1718 ORDER_UNDEFINED = 0,
1719 ORDER_FUNCTION,
1720 ORDER_VAR,
1721 ORDER_ASM
1724 struct cgraph_order_sort
1726 enum cgraph_order_sort_kind kind;
1727 union
1729 struct cgraph_node *f;
1730 struct varpool_node *v;
1731 struct asm_node *a;
1732 } u;
1735 /* Output all functions, variables, and asm statements in the order
1736 according to their order fields, which is the order in which they
1737 appeared in the file. This implements -fno-toplevel-reorder. In
1738 this mode we may output functions and variables which don't really
1739 need to be output. */
1741 static void
1742 output_in_order (void)
1744 int max;
1745 struct cgraph_order_sort *nodes;
1746 int i;
1747 struct cgraph_node *pf;
1748 struct varpool_node *pv;
1749 struct asm_node *pa;
1751 max = symtab_order;
1752 nodes = XCNEWVEC (struct cgraph_order_sort, max);
1754 FOR_EACH_DEFINED_FUNCTION (pf)
1756 if (pf->process && !pf->thunk.thunk_p && !pf->alias)
1758 i = pf->symbol.order;
1759 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1760 nodes[i].kind = ORDER_FUNCTION;
1761 nodes[i].u.f = pf;
1765 FOR_EACH_DEFINED_VARIABLE (pv)
1766 if (!DECL_EXTERNAL (pv->symbol.decl))
1768 i = pv->symbol.order;
1769 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1770 nodes[i].kind = ORDER_VAR;
1771 nodes[i].u.v = pv;
1774 for (pa = asm_nodes; pa; pa = pa->next)
1776 i = pa->order;
1777 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1778 nodes[i].kind = ORDER_ASM;
1779 nodes[i].u.a = pa;
1782 /* In toplevel reorder mode we output all statics; mark them as needed. */
1784 for (i = 0; i < max; ++i)
1785 if (nodes[i].kind == ORDER_VAR)
1786 varpool_finalize_named_section_flags (nodes[i].u.v);
1788 for (i = 0; i < max; ++i)
1790 switch (nodes[i].kind)
1792 case ORDER_FUNCTION:
1793 nodes[i].u.f->process = 0;
1794 expand_function (nodes[i].u.f);
1795 break;
1797 case ORDER_VAR:
1798 varpool_assemble_decl (nodes[i].u.v);
1799 break;
1801 case ORDER_ASM:
1802 assemble_asm (nodes[i].u.a->asm_str);
1803 break;
1805 case ORDER_UNDEFINED:
1806 break;
1808 default:
1809 gcc_unreachable ();
1813 asm_nodes = NULL;
1814 free (nodes);
1817 static void
1818 ipa_passes (void)
1820 set_cfun (NULL);
1821 current_function_decl = NULL;
1822 gimple_register_cfg_hooks ();
1823 bitmap_obstack_initialize (NULL);
1825 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START, NULL);
1827 if (!in_lto_p)
1829 execute_ipa_pass_list (all_small_ipa_passes);
1830 if (seen_error ())
1831 return;
1834 /* We never run removal of unreachable nodes after early passes. This is
1835 because TODO is run before the subpasses. It is important to remove
1836 the unreachable functions to save works at IPA level and to get LTO
1837 symbol tables right. */
1838 symtab_remove_unreachable_nodes (true, cgraph_dump_file);
1840 /* If pass_all_early_optimizations was not scheduled, the state of
1841 the cgraph will not be properly updated. Update it now. */
1842 if (cgraph_state < CGRAPH_STATE_IPA_SSA)
1843 cgraph_state = CGRAPH_STATE_IPA_SSA;
1845 if (!in_lto_p)
1847 /* Generate coverage variables and constructors. */
1848 coverage_finish ();
1850 /* Process new functions added. */
1851 set_cfun (NULL);
1852 current_function_decl = NULL;
1853 cgraph_process_new_functions ();
1855 execute_ipa_summary_passes
1856 ((struct ipa_opt_pass_d *) all_regular_ipa_passes);
1859 /* Some targets need to handle LTO assembler output specially. */
1860 if (flag_generate_lto)
1861 targetm.asm_out.lto_start ();
1863 execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_lto_gen_passes);
1865 if (!in_lto_p)
1866 ipa_write_summaries ();
1868 if (flag_generate_lto)
1869 targetm.asm_out.lto_end ();
1871 if (!flag_ltrans && (in_lto_p || !flag_lto || flag_fat_lto_objects))
1872 execute_ipa_pass_list (all_regular_ipa_passes);
1873 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END, NULL);
1875 bitmap_obstack_release (NULL);
1879 /* Return string alias is alias of. */
1881 static tree
1882 get_alias_symbol (tree decl)
1884 tree alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
1885 return get_identifier (TREE_STRING_POINTER
1886 (TREE_VALUE (TREE_VALUE (alias))));
1890 /* Weakrefs may be associated to external decls and thus not output
1891 at expansion time. Emit all necessary aliases. */
1893 static void
1894 output_weakrefs (void)
1896 struct cgraph_node *node;
1897 struct varpool_node *vnode;
1898 FOR_EACH_FUNCTION (node)
1899 if (node->alias && DECL_EXTERNAL (node->symbol.decl)
1900 && !TREE_ASM_WRITTEN (node->symbol.decl)
1901 && lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
1902 do_assemble_alias (node->symbol.decl,
1903 node->thunk.alias ? DECL_ASSEMBLER_NAME (node->thunk.alias)
1904 : get_alias_symbol (node->symbol.decl));
1905 FOR_EACH_VARIABLE (vnode)
1906 if (vnode->alias && DECL_EXTERNAL (vnode->symbol.decl)
1907 && !TREE_ASM_WRITTEN (vnode->symbol.decl)
1908 && lookup_attribute ("weakref", DECL_ATTRIBUTES (vnode->symbol.decl)))
1909 do_assemble_alias (vnode->symbol.decl,
1910 vnode->alias_of ? DECL_ASSEMBLER_NAME (vnode->alias_of)
1911 : get_alias_symbol (vnode->symbol.decl));
1914 /* Initialize callgraph dump file. */
1916 void
1917 init_cgraph (void)
1919 if (!cgraph_dump_file)
1920 cgraph_dump_file = dump_begin (TDI_cgraph, NULL);
1924 /* Perform simple optimizations based on callgraph. */
1926 void
1927 compile (void)
1929 if (seen_error ())
1930 return;
1932 #ifdef ENABLE_CHECKING
1933 verify_symtab ();
1934 #endif
1936 timevar_push (TV_CGRAPHOPT);
1937 if (pre_ipa_mem_report)
1939 fprintf (stderr, "Memory consumption before IPA\n");
1940 dump_memory_report (false);
1942 if (!quiet_flag)
1943 fprintf (stderr, "Performing interprocedural optimizations\n");
1944 cgraph_state = CGRAPH_STATE_IPA;
1946 /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE. */
1947 if (flag_lto)
1948 lto_streamer_hooks_init ();
1950 /* Don't run the IPA passes if there was any error or sorry messages. */
1951 if (!seen_error ())
1952 ipa_passes ();
1954 /* Do nothing else if any IPA pass found errors or if we are just streaming LTO. */
1955 if (seen_error ()
1956 || (!in_lto_p && flag_lto && !flag_fat_lto_objects))
1958 timevar_pop (TV_CGRAPHOPT);
1959 return;
1962 /* This pass remove bodies of extern inline functions we never inlined.
1963 Do this later so other IPA passes see what is really going on. */
1964 symtab_remove_unreachable_nodes (false, dump_file);
1965 cgraph_global_info_ready = true;
1966 if (cgraph_dump_file)
1968 fprintf (cgraph_dump_file, "Optimized ");
1969 dump_symtab (cgraph_dump_file);
1971 if (post_ipa_mem_report)
1973 fprintf (stderr, "Memory consumption after IPA\n");
1974 dump_memory_report (false);
1976 timevar_pop (TV_CGRAPHOPT);
1978 /* Output everything. */
1979 (*debug_hooks->assembly_start) ();
1980 if (!quiet_flag)
1981 fprintf (stderr, "Assembling functions:\n");
1982 #ifdef ENABLE_CHECKING
1983 verify_symtab ();
1984 #endif
1986 cgraph_materialize_all_clones ();
1987 bitmap_obstack_initialize (NULL);
1988 execute_ipa_pass_list (all_late_ipa_passes);
1989 symtab_remove_unreachable_nodes (true, dump_file);
1990 #ifdef ENABLE_CHECKING
1991 verify_symtab ();
1992 #endif
1993 bitmap_obstack_release (NULL);
1994 mark_functions_to_output ();
1996 cgraph_state = CGRAPH_STATE_EXPANSION;
1997 if (!flag_toplevel_reorder)
1998 output_in_order ();
1999 else
2001 output_asm_statements ();
2003 expand_all_functions ();
2004 varpool_output_variables ();
2007 cgraph_process_new_functions ();
2008 cgraph_state = CGRAPH_STATE_FINISHED;
2009 output_weakrefs ();
2011 if (cgraph_dump_file)
2013 fprintf (cgraph_dump_file, "\nFinal ");
2014 dump_symtab (cgraph_dump_file);
2016 #ifdef ENABLE_CHECKING
2017 verify_symtab ();
2018 /* Double check that all inline clones are gone and that all
2019 function bodies have been released from memory. */
2020 if (!seen_error ())
2022 struct cgraph_node *node;
2023 bool error_found = false;
2025 FOR_EACH_DEFINED_FUNCTION (node)
2026 if (node->global.inlined_to
2027 || gimple_has_body_p (node->symbol.decl))
2029 error_found = true;
2030 dump_cgraph_node (stderr, node);
2032 if (error_found)
2033 internal_error ("nodes with unreleased memory found");
2035 #endif
2039 /* Analyze the whole compilation unit once it is parsed completely. */
2041 void
2042 finalize_compilation_unit (void)
2044 timevar_push (TV_CGRAPH);
2046 /* If we're here there's no current function anymore. Some frontends
2047 are lazy in clearing these. */
2048 current_function_decl = NULL;
2049 set_cfun (NULL);
2051 /* Do not skip analyzing the functions if there were errors, we
2052 miss diagnostics for following functions otherwise. */
2054 /* Emit size functions we didn't inline. */
2055 finalize_size_functions ();
2057 /* Mark alias targets necessary and emit diagnostics. */
2058 handle_alias_pairs ();
2060 if (!quiet_flag)
2062 fprintf (stderr, "\nAnalyzing compilation unit\n");
2063 fflush (stderr);
2066 if (flag_dump_passes)
2067 dump_passes ();
2069 /* Gimplify and lower all functions, compute reachability and
2070 remove unreachable nodes. */
2071 cgraph_analyze_functions ();
2073 /* Mark alias targets necessary and emit diagnostics. */
2074 handle_alias_pairs ();
2076 /* Gimplify and lower thunks. */
2077 cgraph_analyze_functions ();
2079 /* Finally drive the pass manager. */
2080 compile ();
2082 timevar_pop (TV_CGRAPH);
2086 #include "gt-cgraphunit.h"