* cgraphunit.c (handle_alias_pairs): Cleanup; handle all types of aliases.
[platform/upstream/gcc.git] / gcc / cgraphunit.c
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
5
6 This file is part of GCC.
7
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.
12
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.
17
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/>.  */
21
22 /* This module implements main driver of compilation process.
23
24    The main scope of this file is to act as an interface in between
25    tree based frontends and the backend.
26
27    The front-end is supposed to use following functionality:
28
29     - cgraph_finalize_function
30
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.
33
34       (There is one exception needed for implementing GCC extern inline
35         function.)
36
37     - varpool_finalize_variable
38
39       This function has same behavior as the above but is used for static
40       variables.
41
42     - add_asm_node
43
44       Insert new toplevel ASM statement
45
46     - finalize_compilation_unit
47
48       This function is called once (source level) compilation unit is finalized
49       and it will no longer change.
50
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 neccesary functions and variables.
55
56       At the end the bodies of unreachable functions are removed.
57
58       The function can be called multiple times when multiple source level
59       compilation units are combined.
60
61     - compile
62
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).
68
69       Compile time:
70
71         1) Inter-procedural optimization.
72            (ipa_passes)
73
74            This part is further split into:
75
76            a) early optimizations. These are local passes executed in
77               the topological order on the callgraph.
78
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.
83
84            b) early small interprocedural passes.
85
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.
89
90            c) IP analysis stage.  All interprocedural passes do their
91               analysis.
92
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.
98
99            d) LTO sreaming.  When doing LTO, everything important gets
100               streamed into the object file.
101
102        Compile time and or linktime analysis stage (WPA):
103
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.
112
113        Compile time and/or parallel linktime stage (ltrans)
114
115               Each of the object files is streamed back and compiled
116               separately.  Now the function bodies becomes available
117               again.
118
119          2) Virtual clone materialization
120             (cgraph_materialize_clone)
121
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
128
129             All IP passes transform function bodies based on earlier
130             decision of the IP propagation.
131
132          4) late small IP passes
133
134             Simple IP passes working within single program partition.
135
136          5) Expansion
137             (expand_all_functions)
138
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.
144
145             Note that with -fno-toplevel-reorder passes 5 and 6
146             are combined together in cgraph_output_in_order.  
147
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.
154
155     - cgraph_function_versioning
156
157       produces a copy of function into new one (a version)
158       and apply simple transformations
159 */
160
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 "timevar.h"
180 #include "params.h"
181 #include "fibheap.h"
182 #include "intl.h"
183 #include "function.h"
184 #include "ipa-prop.h"
185 #include "gimple.h"
186 #include "tree-iterator.h"
187 #include "tree-pass.h"
188 #include "tree-dump.h"
189 #include "gimple-pretty-print.h"
190 #include "output.h"
191 #include "coverage.h"
192 #include "plugin.h"
193 #include "ipa-inline.h"
194 #include "ipa-utils.h"
195 #include "lto-streamer.h"
196 #include "except.h"
197 #include "regset.h"     /* FIXME: For reg_obstack.  */
198
199 /* Queue of cgraph nodes scheduled to be added into cgraph.  This is a
200    secondary queue used during optimization to accommodate passes that
201    may generate new functions that need to be optimized and expanded.  */
202 cgraph_node_set cgraph_new_nodes;
203
204 static void expand_all_functions (void);
205 static void mark_functions_to_output (void);
206 static void expand_function (struct cgraph_node *);
207 static void cgraph_analyze_function (struct cgraph_node *);
208
209 FILE *cgraph_dump_file;
210
211 /* Linked list of cgraph asm nodes.  */
212 struct asm_node *asm_nodes;
213
214 /* Last node in cgraph_asm_nodes.  */
215 static GTY(()) struct asm_node *asm_last_node;
216
217 /* Used for vtable lookup in thunk adjusting.  */
218 static GTY (()) tree vtable_entry_type;
219
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 unnecesary functions that can
223    take into account results of analysis, whole program info etc.  */
224
225 static bool
226 cgraph_decide_is_function_needed (struct cgraph_node *node, tree decl)
227 {
228   /* If the user told us it is used, then it must be so.  */
229   if (node->symbol.force_output)
230     return true;
231
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)));
237
238
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;
245
246   /* Externally visible functions must be output.  The exception is
247      COMDAT functions that must be output only when they are needed.  */
248
249   if (TREE_PUBLIC (decl)
250       && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
251     return true;
252
253   return false;
254 }
255
256 /* Head of the queue of nodes to be processed while building callgraph */
257
258 static symtab_node first = (symtab_node)(void *)1;
259
260 /* Add NODE to queue starting at FIRST. 
261    The queue is linked via AUX pointers and terminated by pointer to 1.  */
262
263 static void
264 enqueue_node (symtab_node node)
265 {
266   if (node->symbol.aux)
267     return;
268   gcc_checking_assert (first);
269   node->symbol.aux = first;
270   first = node;
271 }
272
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.  */
276
277 bool
278 cgraph_process_new_functions (void)
279 {
280   bool output = false;
281   tree fndecl;
282   struct cgraph_node *node;
283   cgraph_node_set_iterator csi;
284
285   if (!cgraph_new_nodes)
286     return false;
287   /*  Note that this queue may grow as its being processed, as the new
288       functions may generate new ones.  */
289   for (csi = csi_start (cgraph_new_nodes); !csi_end_p (csi); csi_next (&csi))
290     {
291       node = csi_node (csi);
292       fndecl = node->symbol.decl;
293       switch (cgraph_state)
294         {
295         case CGRAPH_STATE_CONSTRUCTION:
296           /* At construction time we just need to finalize function and move
297              it into reachable functions list.  */
298
299           cgraph_finalize_function (fndecl, false);
300           output = true;
301           cgraph_call_function_insertion_hooks (node);
302           enqueue_node ((symtab_node) node);
303           break;
304
305         case CGRAPH_STATE_IPA:
306         case CGRAPH_STATE_IPA_SSA:
307           /* When IPA optimization already started, do all essential
308              transformations that has been already performed on the whole
309              cgraph but not on this function.  */
310
311           gimple_register_cfg_hooks ();
312           if (!node->analyzed)
313             cgraph_analyze_function (node);
314           push_cfun (DECL_STRUCT_FUNCTION (fndecl));
315           current_function_decl = 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           current_function_decl = NULL;
328           cgraph_call_function_insertion_hooks (node);
329           break;
330
331         case CGRAPH_STATE_EXPANSION:
332           /* Functions created during expansion shall be compiled
333              directly.  */
334           node->process = 0;
335           cgraph_call_function_insertion_hooks (node);
336           expand_function (node);
337           break;
338
339         default:
340           gcc_unreachable ();
341           break;
342         }
343     }
344   free_cgraph_node_set (cgraph_new_nodes);
345   cgraph_new_nodes = NULL;
346   return output;
347 }
348
349 /* As an GCC extension we allow redefinition of the function.  The
350    semantics when both copies of bodies differ is not well defined.
351    We replace the old body with new body so in unit at a time mode
352    we always use new body, while in normal mode we may end up with
353    old body inlined into some functions and new body expanded and
354    inlined in others.
355
356    ??? It may make more sense to use one body for inlining and other
357    body for expanding the function but this is difficult to do.  */
358
359 static void
360 cgraph_reset_node (struct cgraph_node *node)
361 {
362   /* If node->process is set, then we have already begun whole-unit analysis.
363      This is *not* testing for whether we've already emitted the function.
364      That case can be sort-of legitimately seen with real function redefinition
365      errors.  I would argue that the front end should never present us with
366      such a case, but don't enforce that for now.  */
367   gcc_assert (!node->process);
368
369   /* Reset our data structures so we can analyze the function again.  */
370   memset (&node->local, 0, sizeof (node->local));
371   memset (&node->global, 0, sizeof (node->global));
372   memset (&node->rtl, 0, sizeof (node->rtl));
373   node->analyzed = false;
374   node->local.finalized = false;
375
376   cgraph_node_remove_callees (node);
377 }
378
379 /* Return true when there are references to NODE.  */
380
381 static bool
382 referred_to_p (symtab_node node)
383 {
384   struct ipa_ref *ref;
385
386   /* See if there are any refrences at all.  */
387   if (ipa_ref_list_referring_iterate (&node->symbol.ref_list, 0, ref))
388     return true;
389   /* For functions check also calls.  */
390   if (symtab_function_p (node) && cgraph (node)->callers)
391     return true;
392   return false;
393 }
394
395 /* DECL has been parsed.  Take it, queue it, compile it at the whim of the
396    logic in effect.  If NESTED is true, then our caller cannot stand to have
397    the garbage collector run at the moment.  We would need to either create
398    a new GC context, or just not compile right now.  */
399
400 void
401 cgraph_finalize_function (tree decl, bool nested)
402 {
403   struct cgraph_node *node = cgraph_get_create_node (decl);
404
405   if (node->local.finalized)
406     {
407       cgraph_reset_node (node);
408       node->local.redefined_extern_inline = true;
409     }
410
411   notice_global_symbol (decl);
412   node->local.finalized = true;
413   node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL;
414
415   /* With -fkeep-inline-functions we are keeping all inline functions except
416      for extern inline ones.  */
417   if (flag_keep_inline_functions
418       && DECL_DECLARED_INLINE_P (decl)
419       && !DECL_EXTERNAL (decl)
420       && !DECL_DISREGARD_INLINE_LIMITS (decl))
421     node->symbol.force_output = 1;
422
423   /* When not optimizing, also output the static functions. (see
424      PR24561), but don't do so for always_inline functions, functions
425      declared inline and nested functions.  These were optimized out
426      in the original implementation and it is unclear whether we want
427      to change the behavior here.  */
428   if ((!optimize
429        && !node->same_body_alias
430        && !DECL_DISREGARD_INLINE_LIMITS (decl)
431        && !DECL_DECLARED_INLINE_P (decl)
432        && !(DECL_CONTEXT (decl)
433             && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL))
434       && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
435     node->symbol.force_output = 1;
436
437   /* If we've not yet emitted decl, tell the debug info about it.  */
438   if (!TREE_ASM_WRITTEN (decl))
439     (*debug_hooks->deferred_inline_function) (decl);
440
441   /* Possibly warn about unused parameters.  */
442   if (warn_unused_parameter)
443     do_warn_unused_parameter (decl);
444
445   if (!nested)
446     ggc_collect ();
447
448   if (cgraph_state == CGRAPH_STATE_CONSTRUCTION
449       && (cgraph_decide_is_function_needed (node, decl)
450           || referred_to_p ((symtab_node)node)))
451     enqueue_node ((symtab_node)node);
452 }
453
454 /* Add the function FNDECL to the call graph.
455    Unlike cgraph_finalize_function, this function is intended to be used
456    by middle end and allows insertion of new function at arbitrary point
457    of compilation.  The function can be either in high, low or SSA form
458    GIMPLE.
459
460    The function is assumed to be reachable and have address taken (so no
461    API breaking optimizations are performed on it).
462
463    Main work done by this function is to enqueue the function for later
464    processing to avoid need the passes to be re-entrant.  */
465
466 void
467 cgraph_add_new_function (tree fndecl, bool lowered)
468 {
469   struct cgraph_node *node;
470   switch (cgraph_state)
471     {
472       case CGRAPH_STATE_PARSING:
473         cgraph_finalize_function (fndecl, false);
474         break;
475       case CGRAPH_STATE_CONSTRUCTION:
476         /* Just enqueue function to be processed at nearest occurrence.  */
477         node = cgraph_create_node (fndecl);
478         if (lowered)
479           node->lowered = true;
480         if (!cgraph_new_nodes)
481           cgraph_new_nodes = cgraph_node_set_new ();
482         cgraph_node_set_add (cgraph_new_nodes, node);
483         break;
484
485       case CGRAPH_STATE_IPA:
486       case CGRAPH_STATE_IPA_SSA:
487       case CGRAPH_STATE_EXPANSION:
488         /* Bring the function into finalized state and enqueue for later
489            analyzing and compilation.  */
490         node = cgraph_get_create_node (fndecl);
491         node->local.local = false;
492         node->local.finalized = true;
493         node->symbol.force_output = true;
494         if (!lowered && cgraph_state == CGRAPH_STATE_EXPANSION)
495           {
496             push_cfun (DECL_STRUCT_FUNCTION (fndecl));
497             current_function_decl = fndecl;
498             gimple_register_cfg_hooks ();
499             bitmap_obstack_initialize (NULL);
500             execute_pass_list (all_lowering_passes);
501             execute_pass_list (pass_early_local_passes.pass.sub);
502             bitmap_obstack_release (NULL);
503             pop_cfun ();
504             current_function_decl = NULL;
505
506             lowered = true;
507           }
508         if (lowered)
509           node->lowered = true;
510         if (!cgraph_new_nodes)
511           cgraph_new_nodes = cgraph_node_set_new ();
512         cgraph_node_set_add (cgraph_new_nodes, node);
513         break;
514
515       case CGRAPH_STATE_FINISHED:
516         /* At the very end of compilation we have to do all the work up
517            to expansion.  */
518         node = cgraph_create_node (fndecl);
519         if (lowered)
520           node->lowered = true;
521         cgraph_analyze_function (node);
522         push_cfun (DECL_STRUCT_FUNCTION (fndecl));
523         current_function_decl = fndecl;
524         gimple_register_cfg_hooks ();
525         bitmap_obstack_initialize (NULL);
526         if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
527           execute_pass_list (pass_early_local_passes.pass.sub);
528         bitmap_obstack_release (NULL);
529         pop_cfun ();
530         expand_function (node);
531         current_function_decl = NULL;
532         break;
533
534       default:
535         gcc_unreachable ();
536     }
537
538   /* Set a personality if required and we already passed EH lowering.  */
539   if (lowered
540       && (function_needs_eh_personality (DECL_STRUCT_FUNCTION (fndecl))
541           == eh_personality_lang))
542     DECL_FUNCTION_PERSONALITY (fndecl) = lang_hooks.eh_personality ();
543 }
544
545 /* Add a top-level asm statement to the list.  */
546
547 struct asm_node *
548 add_asm_node (tree asm_str)
549 {
550   struct asm_node *node;
551
552   node = ggc_alloc_cleared_asm_node ();
553   node->asm_str = asm_str;
554   node->order = symtab_order++;
555   node->next = NULL;
556   if (asm_nodes == NULL)
557     asm_nodes = node;
558   else
559     asm_last_node->next = node;
560   asm_last_node = node;
561   return node;
562 }
563
564 /* Output all asm statements we have stored up to be output.  */
565
566 static void
567 output_asm_statements (void)
568 {
569   struct asm_node *can;
570
571   if (seen_error ())
572     return;
573
574   for (can = asm_nodes; can; can = can->next)
575     assemble_asm (can->asm_str);
576   asm_nodes = NULL;
577 }
578
579 /* C++ FE sometimes change linkage flags after producing same body aliases.  */
580 void
581 fixup_same_cpp_alias_visibility (symtab_node node, symtab_node target, tree alias)
582 {
583   DECL_VIRTUAL_P (node->symbol.decl) = DECL_VIRTUAL_P (alias);
584   if (TREE_PUBLIC (node->symbol.decl))
585     {
586       DECL_EXTERNAL (node->symbol.decl) = DECL_EXTERNAL (alias);
587       DECL_COMDAT (node->symbol.decl) = DECL_COMDAT (alias);
588       DECL_COMDAT_GROUP (node->symbol.decl) = DECL_COMDAT_GROUP (alias);
589       if (DECL_ONE_ONLY (alias)
590           && !node->symbol.same_comdat_group)
591         symtab_add_to_same_comdat_group ((symtab_node)node, (symtab_node)target);
592     }
593 }
594
595 /* Analyze the function scheduled to be output.  */
596 static void
597 cgraph_analyze_function (struct cgraph_node *node)
598 {
599   tree save = current_function_decl;
600   tree decl = node->symbol.decl;
601   location_t saved_loc = input_location;
602   input_location = DECL_SOURCE_LOCATION (decl);
603
604   if (node->alias && node->thunk.alias)
605     {
606       struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias);
607       struct cgraph_node *n;
608
609       for (n = tgt; n && n->alias;
610            n = n->analyzed ? cgraph_alias_aliased_node (n) : NULL)
611         if (n == node)
612           {
613             error ("function %q+D part of alias cycle", node->symbol.decl);
614             node->alias = false;
615             input_location = saved_loc;
616             return;
617           }
618       if (!VEC_length (ipa_ref_t, node->symbol.ref_list.references))
619         ipa_record_reference ((symtab_node)node, (symtab_node)tgt,
620                               IPA_REF_ALIAS, NULL);
621       if (node->same_body_alias)
622         { 
623           DECL_DECLARED_INLINE_P (node->symbol.decl)
624              = DECL_DECLARED_INLINE_P (node->thunk.alias);
625           DECL_DISREGARD_INLINE_LIMITS (node->symbol.decl)
626              = DECL_DISREGARD_INLINE_LIMITS (node->thunk.alias);
627           fixup_same_cpp_alias_visibility ((symtab_node) node, (symtab_node) tgt, node->thunk.alias);
628         }
629
630       if (node->symbol.address_taken)
631         cgraph_mark_address_taken_node (cgraph_alias_aliased_node (node));
632     }
633   else if (node->thunk.thunk_p)
634     {
635       cgraph_create_edge (node, cgraph_get_node (node->thunk.alias),
636                           NULL, 0, CGRAPH_FREQ_BASE);
637     }
638   else
639     {
640       current_function_decl = decl;
641       push_cfun (DECL_STRUCT_FUNCTION (decl));
642
643       assign_assembler_name_if_neeeded (node->symbol.decl);
644
645       /* Make sure to gimplify bodies only once.  During analyzing a
646          function we lower it, which will require gimplified nested
647          functions, so we can end up here with an already gimplified
648          body.  */
649       if (!gimple_has_body_p (decl))
650         gimplify_function_tree (decl);
651       dump_function (TDI_generic, decl);
652
653       /* Lower the function.  */
654       if (!node->lowered)
655         {
656           if (node->nested)
657             lower_nested_functions (node->symbol.decl);
658           gcc_assert (!node->nested);
659
660           gimple_register_cfg_hooks ();
661           bitmap_obstack_initialize (NULL);
662           execute_pass_list (all_lowering_passes);
663           free_dominance_info (CDI_POST_DOMINATORS);
664           free_dominance_info (CDI_DOMINATORS);
665           compact_blocks ();
666           bitmap_obstack_release (NULL);
667           node->lowered = true;
668         }
669
670       pop_cfun ();
671     }
672   node->analyzed = true;
673
674   current_function_decl = save;
675   input_location = saved_loc;
676 }
677
678 /* C++ frontend produce same body aliases all over the place, even before PCH
679    gets streamed out. It relies on us linking the aliases with their function
680    in order to do the fixups, but ipa-ref is not PCH safe.  Consequentely we
681    first produce aliases without links, but once C++ FE is sure he won't sream
682    PCH we build the links via this function.  */
683
684 void
685 cgraph_process_same_body_aliases (void)
686 {
687   struct cgraph_node *node;
688   FOR_EACH_FUNCTION (node)
689     if (node->same_body_alias
690         && !VEC_length (ipa_ref_t, node->symbol.ref_list.references))
691       {
692         struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias);
693         ipa_record_reference ((symtab_node)node, (symtab_node)tgt,
694                               IPA_REF_ALIAS, NULL);
695       }
696   same_body_aliases_done = true;
697 }
698
699 /* Process attributes common for vars and functions.  */
700
701 static void
702 process_common_attributes (tree decl)
703 {
704   tree weakref = lookup_attribute ("weakref", DECL_ATTRIBUTES (decl));
705
706   if (weakref && !lookup_attribute ("alias", DECL_ATTRIBUTES (decl)))
707     {
708       warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
709                   "%<weakref%> attribute should be accompanied with"
710                   " an %<alias%> attribute");
711       DECL_WEAK (decl) = 0;
712       DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
713                                                  DECL_ATTRIBUTES (decl));
714     }
715 }
716
717 /* Look for externally_visible and used attributes and mark cgraph nodes
718    accordingly.
719
720    We cannot mark the nodes at the point the attributes are processed (in
721    handle_*_attribute) because the copy of the declarations available at that
722    point may not be canonical.  For example, in:
723
724     void f();
725     void f() __attribute__((used));
726
727    the declaration we see in handle_used_attribute will be the second
728    declaration -- but the front end will subsequently merge that declaration
729    with the original declaration and discard the second declaration.
730
731    Furthermore, we can't mark these nodes in cgraph_finalize_function because:
732
733     void f() {}
734     void f() __attribute__((externally_visible));
735
736    is valid.
737
738    So, we walk the nodes at the end of the translation unit, applying the
739    attributes at that point.  */
740
741 static void
742 process_function_and_variable_attributes (struct cgraph_node *first,
743                                           struct varpool_node *first_var)
744 {
745   struct cgraph_node *node;
746   struct varpool_node *vnode;
747
748   for (node = cgraph_first_function (); node != first;
749        node = cgraph_next_function (node))
750     {
751       tree decl = node->symbol.decl;
752       if (DECL_PRESERVE_P (decl))
753         cgraph_mark_force_output_node (node);
754       else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
755         {
756           if (! TREE_PUBLIC (node->symbol.decl))
757             warning_at (DECL_SOURCE_LOCATION (node->symbol.decl), OPT_Wattributes,
758                         "%<externally_visible%>"
759                         " attribute have effect only on public objects");
760         }
761       if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
762           && (node->local.finalized && !node->alias))
763         {
764           warning_at (DECL_SOURCE_LOCATION (node->symbol.decl), OPT_Wattributes,
765                       "%<weakref%> attribute ignored"
766                       " because function is defined");
767           DECL_WEAK (decl) = 0;
768           DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
769                                                      DECL_ATTRIBUTES (decl));
770         }
771
772       if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl))
773           && !DECL_DECLARED_INLINE_P (decl)
774           /* redefining extern inline function makes it DECL_UNINLINABLE.  */
775           && !DECL_UNINLINABLE (decl))
776         warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
777                     "always_inline function might not be inlinable");
778      
779       process_common_attributes (decl);
780     }
781   for (vnode = varpool_first_variable (); vnode != first_var;
782        vnode = varpool_next_variable (vnode))
783     {
784       tree decl = vnode->symbol.decl;
785       if (DECL_EXTERNAL (decl)
786           && DECL_INITIAL (decl)
787           && const_value_known_p (decl))
788         varpool_finalize_decl (decl);
789       if (DECL_PRESERVE_P (decl))
790         vnode->symbol.force_output = true;
791       else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
792         {
793           if (! TREE_PUBLIC (vnode->symbol.decl))
794             warning_at (DECL_SOURCE_LOCATION (vnode->symbol.decl), OPT_Wattributes,
795                         "%<externally_visible%>"
796                         " attribute have effect only on public objects");
797         }
798       if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
799           && vnode->finalized
800           && DECL_INITIAL (decl))
801         {
802           warning_at (DECL_SOURCE_LOCATION (vnode->symbol.decl), OPT_Wattributes,
803                       "%<weakref%> attribute ignored"
804                       " because variable is initialized");
805           DECL_WEAK (decl) = 0;
806           DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
807                                                       DECL_ATTRIBUTES (decl));
808         }
809       process_common_attributes (decl);
810     }
811 }
812
813 /* Mark DECL as finalized.  By finalizing the declaration, frontend instruct the
814    middle end to output the variable to asm file, if needed or externally
815    visible.  */
816
817 void
818 varpool_finalize_decl (tree decl)
819 {
820   struct varpool_node *node = varpool_node (decl);
821
822   gcc_assert (TREE_STATIC (decl) || DECL_EXTERNAL (decl));
823
824   if (node->finalized)
825     return;
826   notice_global_symbol (decl);
827   node->finalized = true;
828   if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
829       /* Traditionally we do not eliminate static variables when not
830          optimizing and when not doing toplevel reoder.  */
831       || (!flag_toplevel_reorder && !DECL_COMDAT (node->symbol.decl)
832           && !DECL_ARTIFICIAL (node->symbol.decl)))
833     node->symbol.force_output = true;
834
835   if (cgraph_state == CGRAPH_STATE_CONSTRUCTION
836       && (decide_is_variable_needed (node, decl)
837           || referred_to_p ((symtab_node)node)))
838     enqueue_node ((symtab_node)node);
839   if (cgraph_state >= CGRAPH_STATE_IPA_SSA)
840     varpool_analyze_node (node);
841   /* Some frontends produce various interface variables after compilation
842      finished.  */
843   if (cgraph_state == CGRAPH_STATE_FINISHED)
844     varpool_assemble_decl (node);
845 }
846
847 /* Discover all functions and variables that are trivially needed, analyze
848    them as well as all functions and variables referred by them  */
849
850 static void
851 cgraph_analyze_functions (void)
852 {
853   /* Keep track of already processed nodes when called multiple times for
854      intermodule optimization.  */
855   static struct cgraph_node *first_analyzed;
856   struct cgraph_node *first_handled = first_analyzed;
857   static struct varpool_node *first_analyzed_var;
858   struct varpool_node *first_handled_var = first_analyzed_var;
859
860   symtab_node node, next;
861   int i;
862   struct ipa_ref *ref;
863   bool changed = true;
864
865   bitmap_obstack_initialize (NULL);
866   cgraph_state = CGRAPH_STATE_CONSTRUCTION;
867
868   /* Analysis adds static variables that in turn adds references to new functions.
869      So we need to iterate the process until it stabilize.  */
870   while (changed)
871     {
872       changed = false;
873       process_function_and_variable_attributes (first_analyzed,
874                                                 first_analyzed_var);
875
876       /* First identify the trivially needed symbols.  */
877       for (node = symtab_nodes;
878            node != (symtab_node)first_analyzed
879            && node != (symtab_node)first_analyzed_var; node = node->symbol.next)
880         {
881           if ((symtab_function_p (node)
882                && cgraph (node)->local.finalized
883                && cgraph_decide_is_function_needed (cgraph (node), node->symbol.decl))
884               || (symtab_variable_p (node)
885                   && varpool (node)->finalized
886                   && !DECL_EXTERNAL (node->symbol.decl)
887                   && decide_is_variable_needed (varpool (node), node->symbol.decl)))
888             {
889               enqueue_node (node);
890               if (!changed && cgraph_dump_file)
891                 fprintf (cgraph_dump_file, "Trivially needed symbols:");
892               changed = true;
893               if (cgraph_dump_file)
894                 fprintf (cgraph_dump_file, " %s", symtab_node_asm_name (node));
895             }
896           if (node == (symtab_node)first_analyzed
897               || node == (symtab_node)first_analyzed_var)
898             break;
899         }
900       cgraph_process_new_functions ();
901       first_analyzed_var = varpool_first_variable ();
902       first_analyzed = cgraph_first_function ();
903
904       if (changed && dump_file)
905         fprintf (cgraph_dump_file, "\n");
906
907       /* Lower representation, build callgraph edges and references for all trivially
908          needed symbols and all symbols referred by them.  */
909       while (first != (symtab_node)(void *)1)
910         {
911           changed = true;
912           node = first;
913           first = (symtab_node)first->symbol.aux;
914           if (symtab_function_p (node) && cgraph (node)->local.finalized)
915             {
916               struct cgraph_edge *edge;
917               struct cgraph_node *cnode;
918               tree decl;
919
920               cnode = cgraph (node);
921               decl = cnode->symbol.decl;
922
923               /* ??? It is possible to create extern inline function and later using
924                  weak alias attribute to kill its body. See
925                  gcc.c-torture/compile/20011119-1.c  */
926               if (!DECL_STRUCT_FUNCTION (decl)
927                   && (!cnode->alias || !cnode->thunk.alias)
928                   && !cnode->thunk.thunk_p)
929                 {
930                   cgraph_reset_node (cnode);
931                   cnode->local.redefined_extern_inline = true;
932                   continue;
933                 }
934
935               if (!cnode->analyzed)
936                 cgraph_analyze_function (cnode);
937
938               for (edge = cnode->callees; edge; edge = edge->next_callee)
939                 if (edge->callee->local.finalized)
940                   enqueue_node ((symtab_node)edge->callee);
941
942               /* If decl is a clone of an abstract function, mark that abstract
943                  function so that we don't release its body. The DECL_INITIAL() of that
944                  abstract function declaration will be later needed to output debug
945                  info.  */
946               if (DECL_ABSTRACT_ORIGIN (decl))
947                 {
948                   struct cgraph_node *origin_node;
949                   origin_node = cgraph_get_node (DECL_ABSTRACT_ORIGIN (decl));
950                   origin_node->abstract_and_needed = true;
951                 }
952
953             }
954           else if (symtab_variable_p (node)
955                    && varpool (node)->finalized)
956             varpool_analyze_node (varpool (node));
957
958           if (node->symbol.same_comdat_group)
959             {
960               symtab_node next;
961               for (next = node->symbol.same_comdat_group;
962                    next != node;
963                    next = next->symbol.same_comdat_group)
964                 enqueue_node (next);
965             }
966           for (i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list, i, ref); i++)
967             if ((symtab_function_p (ref->referred) && cgraph (ref->referred)->local.finalized)
968                 || (symtab_variable_p (ref->referred) && varpool (ref->referred)->finalized))
969               enqueue_node (ref->referred);
970           cgraph_process_new_functions ();
971         }
972     }
973
974   /* Collect entry points to the unit.  */
975   if (cgraph_dump_file)
976     {
977       fprintf (cgraph_dump_file, "\n\nInitial ");
978       dump_symtab (cgraph_dump_file);
979     }
980
981   if (cgraph_dump_file)
982     fprintf (cgraph_dump_file, "\nRemoving unused symbols:");
983
984   for (node = symtab_nodes;
985        node != (symtab_node)first_handled
986        && node != (symtab_node)first_handled_var; node = next)
987     {
988       next = node->symbol.next;
989       if (!node->symbol.aux && !referred_to_p (node))
990         {
991           if (cgraph_dump_file)
992             fprintf (cgraph_dump_file, " %s", symtab_node_name (node));
993           symtab_remove_node (node);
994           continue;
995         }
996       if (symtab_function_p (node))
997         {
998           tree decl = node->symbol.decl;
999           struct cgraph_node *cnode = cgraph (node);
1000
1001           if (cnode->local.finalized && !gimple_has_body_p (decl)
1002               && (!cnode->alias || !cnode->thunk.alias)
1003               && !cnode->thunk.thunk_p)
1004             cgraph_reset_node (cnode);
1005
1006           gcc_assert (!cnode->local.finalized || cnode->thunk.thunk_p
1007                       || cnode->alias
1008                       || gimple_has_body_p (decl));
1009           gcc_assert (cnode->analyzed == cnode->local.finalized);
1010         }
1011       node->symbol.aux = NULL;
1012     }
1013   first_analyzed = cgraph_first_function ();
1014   first_analyzed_var = varpool_first_variable ();
1015   if (cgraph_dump_file)
1016     {
1017       fprintf (cgraph_dump_file, "\n\nReclaimed ");
1018       dump_symtab (cgraph_dump_file);
1019     }
1020   bitmap_obstack_release (NULL);
1021   ggc_collect ();
1022 }
1023
1024 /* Translate the ugly representation of aliases as alias pairs into nice
1025    representation in callgraph.  We don't handle all cases yet,
1026    unforutnately.  */
1027
1028 static void
1029 handle_alias_pairs (void)
1030 {
1031   alias_pair *p;
1032   unsigned i;
1033   
1034   for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p);)
1035     {
1036       symtab_node target_node = symtab_node_for_asm (p->target);
1037
1038       /* Weakrefs with target not defined in current unit are easy to handle; they
1039          behave just as external variables except we need to note the alias flag
1040          to later output the weakref pseudo op into asm file.  */
1041       if (!target_node && lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL)
1042         {
1043           if (TREE_CODE (p->decl) == FUNCTION_DECL)
1044             cgraph_get_create_node (p->decl)->alias = true;
1045           else
1046             varpool_get_node (p->decl)->alias = true;
1047           DECL_EXTERNAL (p->decl) = 1;
1048           VEC_unordered_remove (alias_pair, alias_pairs, i);
1049           continue;
1050         }
1051       else if (!target_node)
1052         {
1053           error ("%q+D aliased to undefined symbol %qE", p->decl, p->target);
1054           VEC_unordered_remove (alias_pair, alias_pairs, i);
1055           continue;
1056         }
1057
1058       /* Normally EXTERNAL flag is used to mark external inlines,
1059          however for aliases it seems to be allowed to use it w/o
1060          any meaning. See gcc.dg/attr-alias-3.c  
1061          However for weakref we insist on EXTERNAL flag being set.
1062          See gcc.dg/attr-alias-5.c  */
1063       if (DECL_EXTERNAL (p->decl))
1064         DECL_EXTERNAL (p->decl)
1065           = lookup_attribute ("weakref",
1066                               DECL_ATTRIBUTES (p->decl)) != NULL;
1067
1068       if (TREE_CODE (p->decl) == FUNCTION_DECL
1069           && target_node && symtab_function_p (target_node))
1070         {
1071           struct cgraph_node *src_node = cgraph_get_node (p->decl);
1072           if (src_node && src_node->local.finalized)
1073             cgraph_reset_node (src_node);
1074           cgraph_create_function_alias (p->decl, target_node->symbol.decl);
1075           VEC_unordered_remove (alias_pair, alias_pairs, i);
1076         }
1077       else if (TREE_CODE (p->decl) == VAR_DECL
1078                && target_node && symtab_variable_p (target_node))
1079         {
1080           varpool_create_variable_alias (p->decl, target_node->symbol.decl);
1081           VEC_unordered_remove (alias_pair, alias_pairs, i);
1082         }
1083       else
1084         {
1085           error ("%q+D alias in between function and variable is not supported",
1086                  p->decl);
1087           warning (0, "%q+D aliased declaration",
1088                    target_node->symbol.decl);
1089           VEC_unordered_remove (alias_pair, alias_pairs, i);
1090         }
1091     }
1092 }
1093
1094
1095 /* Figure out what functions we want to assemble.  */
1096
1097 static void
1098 mark_functions_to_output (void)
1099 {
1100   struct cgraph_node *node;
1101 #ifdef ENABLE_CHECKING
1102   bool check_same_comdat_groups = false;
1103
1104   FOR_EACH_FUNCTION (node)
1105     gcc_assert (!node->process);
1106 #endif
1107
1108   FOR_EACH_FUNCTION (node)
1109     {
1110       tree decl = node->symbol.decl;
1111
1112       gcc_assert (!node->process || node->symbol.same_comdat_group);
1113       if (node->process)
1114         continue;
1115
1116       /* We need to output all local functions that are used and not
1117          always inlined, as well as those that are reachable from
1118          outside the current compilation unit.  */
1119       if (node->analyzed
1120           && !node->thunk.thunk_p
1121           && !node->alias
1122           && !node->global.inlined_to
1123           && !TREE_ASM_WRITTEN (decl)
1124           && !DECL_EXTERNAL (decl))
1125         {
1126           node->process = 1;
1127           if (node->symbol.same_comdat_group)
1128             {
1129               struct cgraph_node *next;
1130               for (next = cgraph (node->symbol.same_comdat_group);
1131                    next != node;
1132                    next = cgraph (next->symbol.same_comdat_group))
1133                 if (!next->thunk.thunk_p && !next->alias)
1134                   next->process = 1;
1135             }
1136         }
1137       else if (node->symbol.same_comdat_group)
1138         {
1139 #ifdef ENABLE_CHECKING
1140           check_same_comdat_groups = true;
1141 #endif
1142         }
1143       else
1144         {
1145           /* We should've reclaimed all functions that are not needed.  */
1146 #ifdef ENABLE_CHECKING
1147           if (!node->global.inlined_to
1148               && gimple_has_body_p (decl)
1149               /* FIXME: in ltrans unit when offline copy is outside partition but inline copies
1150                  are inside partition, we can end up not removing the body since we no longer
1151                  have analyzed node pointing to it.  */
1152               && !node->symbol.in_other_partition
1153               && !node->alias
1154               && !node->clones
1155               && !DECL_EXTERNAL (decl))
1156             {
1157               dump_cgraph_node (stderr, node);
1158               internal_error ("failed to reclaim unneeded function");
1159             }
1160 #endif
1161           gcc_assert (node->global.inlined_to
1162                       || !gimple_has_body_p (decl)
1163                       || node->symbol.in_other_partition
1164                       || node->clones
1165                       || DECL_ARTIFICIAL (decl)
1166                       || DECL_EXTERNAL (decl));
1167
1168         }
1169
1170     }
1171 #ifdef ENABLE_CHECKING
1172   if (check_same_comdat_groups)
1173     FOR_EACH_FUNCTION (node)
1174       if (node->symbol.same_comdat_group && !node->process)
1175         {
1176           tree decl = node->symbol.decl;
1177           if (!node->global.inlined_to
1178               && gimple_has_body_p (decl)
1179               /* FIXME: in an ltrans unit when the offline copy is outside a
1180                  partition but inline copies are inside a partition, we can
1181                  end up not removing the body since we no longer have an
1182                  analyzed node pointing to it.  */
1183               && !node->symbol.in_other_partition
1184               && !DECL_EXTERNAL (decl))
1185             {
1186               dump_cgraph_node (stderr, node);
1187               internal_error ("failed to reclaim unneeded function in same "
1188                               "comdat group");
1189             }
1190         }
1191 #endif
1192 }
1193
1194 /* DECL is FUNCTION_DECL.  Initialize datastructures so DECL is a function
1195    in lowered gimple form.
1196    
1197    Set current_function_decl and cfun to newly constructed empty function body.
1198    return basic block in the function body.  */
1199
1200 static basic_block
1201 init_lowered_empty_function (tree decl)
1202 {
1203   basic_block bb;
1204
1205   current_function_decl = decl;
1206   allocate_struct_function (decl, false);
1207   gimple_register_cfg_hooks ();
1208   init_empty_tree_cfg ();
1209   init_tree_ssa (cfun);
1210   init_ssa_operands ();
1211   cfun->gimple_df->in_ssa_p = true;
1212   DECL_INITIAL (decl) = make_node (BLOCK);
1213
1214   DECL_SAVED_TREE (decl) = error_mark_node;
1215   cfun->curr_properties |=
1216     (PROP_gimple_lcf | PROP_gimple_leh | PROP_cfg | PROP_referenced_vars |
1217      PROP_ssa | PROP_gimple_any);
1218
1219   /* Create BB for body of the function and connect it properly.  */
1220   bb = create_basic_block (NULL, (void *) 0, ENTRY_BLOCK_PTR);
1221   make_edge (ENTRY_BLOCK_PTR, bb, 0);
1222   make_edge (bb, EXIT_BLOCK_PTR, 0);
1223
1224   return bb;
1225 }
1226
1227 /* Adjust PTR by the constant FIXED_OFFSET, and by the vtable
1228    offset indicated by VIRTUAL_OFFSET, if that is
1229    non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and
1230    zero for a result adjusting thunk.  */
1231
1232 static tree
1233 thunk_adjust (gimple_stmt_iterator * bsi,
1234               tree ptr, bool this_adjusting,
1235               HOST_WIDE_INT fixed_offset, tree virtual_offset)
1236 {
1237   gimple stmt;
1238   tree ret;
1239
1240   if (this_adjusting
1241       && fixed_offset != 0)
1242     {
1243       stmt = gimple_build_assign
1244                 (ptr, fold_build_pointer_plus_hwi_loc (input_location,
1245                                                        ptr,
1246                                                        fixed_offset));
1247       gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1248     }
1249
1250   /* If there's a virtual offset, look up that value in the vtable and
1251      adjust the pointer again.  */
1252   if (virtual_offset)
1253     {
1254       tree vtabletmp;
1255       tree vtabletmp2;
1256       tree vtabletmp3;
1257
1258       if (!vtable_entry_type)
1259         {
1260           tree vfunc_type = make_node (FUNCTION_TYPE);
1261           TREE_TYPE (vfunc_type) = integer_type_node;
1262           TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
1263           layout_type (vfunc_type);
1264
1265           vtable_entry_type = build_pointer_type (vfunc_type);
1266         }
1267
1268       vtabletmp =
1269         make_rename_temp (build_pointer_type
1270                           (build_pointer_type (vtable_entry_type)), "vptr");
1271
1272       /* The vptr is always at offset zero in the object.  */
1273       stmt = gimple_build_assign (vtabletmp,
1274                                   build1 (NOP_EXPR, TREE_TYPE (vtabletmp),
1275                                           ptr));
1276       gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1277
1278       /* Form the vtable address.  */
1279       vtabletmp2 = make_rename_temp (TREE_TYPE (TREE_TYPE (vtabletmp)),
1280                                      "vtableaddr");
1281       stmt = gimple_build_assign (vtabletmp2,
1282                                   build_simple_mem_ref (vtabletmp));
1283       gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1284
1285       /* Find the entry with the vcall offset.  */
1286       stmt = gimple_build_assign (vtabletmp2,
1287                                   fold_build_pointer_plus_loc (input_location,
1288                                                                vtabletmp2,
1289                                                                virtual_offset));
1290       gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1291
1292       /* Get the offset itself.  */
1293       vtabletmp3 = make_rename_temp (TREE_TYPE (TREE_TYPE (vtabletmp2)),
1294                                      "vcalloffset");
1295       stmt = gimple_build_assign (vtabletmp3,
1296                                   build_simple_mem_ref (vtabletmp2));
1297       gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1298
1299       /* Adjust the `this' pointer.  */
1300       ptr = fold_build_pointer_plus_loc (input_location, ptr, vtabletmp3);
1301       ptr = force_gimple_operand_gsi (bsi, ptr, true, NULL_TREE, false,
1302                                       GSI_CONTINUE_LINKING);
1303     }
1304
1305   if (!this_adjusting
1306       && fixed_offset != 0)
1307     /* Adjust the pointer by the constant.  */
1308     {
1309       tree ptrtmp;
1310
1311       if (TREE_CODE (ptr) == VAR_DECL)
1312         ptrtmp = ptr;
1313       else
1314         {
1315           ptrtmp = make_rename_temp (TREE_TYPE (ptr), "ptr");
1316           stmt = gimple_build_assign (ptrtmp, ptr);
1317           gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1318         }
1319       ptr = fold_build_pointer_plus_hwi_loc (input_location,
1320                                              ptrtmp, fixed_offset);
1321     }
1322
1323   /* Emit the statement and gimplify the adjustment expression.  */
1324   ret = make_rename_temp (TREE_TYPE (ptr), "adjusted_this");
1325   stmt = gimple_build_assign (ret, ptr);
1326   gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1327
1328   return ret;
1329 }
1330
1331 /* Produce assembler for thunk NODE.  */
1332
1333 static void
1334 assemble_thunk (struct cgraph_node *node)
1335 {
1336   bool this_adjusting = node->thunk.this_adjusting;
1337   HOST_WIDE_INT fixed_offset = node->thunk.fixed_offset;
1338   HOST_WIDE_INT virtual_value = node->thunk.virtual_value;
1339   tree virtual_offset = NULL;
1340   tree alias = node->thunk.alias;
1341   tree thunk_fndecl = node->symbol.decl;
1342   tree a = DECL_ARGUMENTS (thunk_fndecl);
1343
1344   current_function_decl = thunk_fndecl;
1345
1346   /* Ensure thunks are emitted in their correct sections.  */
1347   resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
1348
1349   if (this_adjusting
1350       && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
1351                                               virtual_value, alias))
1352     {
1353       const char *fnname;
1354       tree fn_block;
1355       tree restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1356       
1357       DECL_RESULT (thunk_fndecl)
1358         = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl),
1359                       RESULT_DECL, 0, restype);
1360       fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
1361
1362       /* The back end expects DECL_INITIAL to contain a BLOCK, so we
1363          create one.  */
1364       fn_block = make_node (BLOCK);
1365       BLOCK_VARS (fn_block) = a;
1366       DECL_INITIAL (thunk_fndecl) = fn_block;
1367       init_function_start (thunk_fndecl);
1368       cfun->is_thunk = 1;
1369       assemble_start_function (thunk_fndecl, fnname);
1370
1371       targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl,
1372                                        fixed_offset, virtual_value, alias);
1373
1374       assemble_end_function (thunk_fndecl, fnname);
1375       init_insn_lengths ();
1376       free_after_compilation (cfun);
1377       set_cfun (NULL);
1378       TREE_ASM_WRITTEN (thunk_fndecl) = 1;
1379       node->thunk.thunk_p = false;
1380       node->analyzed = false;
1381     }
1382   else
1383     {
1384       tree restype;
1385       basic_block bb, then_bb, else_bb, return_bb;
1386       gimple_stmt_iterator bsi;
1387       int nargs = 0;
1388       tree arg;
1389       int i;
1390       tree resdecl;
1391       tree restmp = NULL;
1392       VEC(tree, heap) *vargs;
1393
1394       gimple call;
1395       gimple ret;
1396
1397       DECL_IGNORED_P (thunk_fndecl) = 1;
1398       bitmap_obstack_initialize (NULL);
1399
1400       if (node->thunk.virtual_offset_p)
1401         virtual_offset = size_int (virtual_value);
1402
1403       /* Build the return declaration for the function.  */
1404       restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1405       if (DECL_RESULT (thunk_fndecl) == NULL_TREE)
1406         {
1407           resdecl = build_decl (input_location, RESULT_DECL, 0, restype);
1408           DECL_ARTIFICIAL (resdecl) = 1;
1409           DECL_IGNORED_P (resdecl) = 1;
1410           DECL_RESULT (thunk_fndecl) = resdecl;
1411         }
1412       else
1413         resdecl = DECL_RESULT (thunk_fndecl);
1414
1415       bb = then_bb = else_bb = return_bb = init_lowered_empty_function (thunk_fndecl);
1416
1417       bsi = gsi_start_bb (bb);
1418
1419       /* Build call to the function being thunked.  */
1420       if (!VOID_TYPE_P (restype))
1421         {
1422           if (!is_gimple_reg_type (restype))
1423             {
1424               restmp = resdecl;
1425               add_local_decl (cfun, restmp);
1426               BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp;
1427             }
1428           else
1429             restmp = make_rename_temp (restype, "retval");
1430         }
1431
1432       for (arg = a; arg; arg = DECL_CHAIN (arg))
1433         nargs++;
1434       vargs = VEC_alloc (tree, heap, nargs);
1435       if (this_adjusting)
1436         VEC_quick_push (tree, vargs,
1437                         thunk_adjust (&bsi,
1438                                       a, 1, fixed_offset,
1439                                       virtual_offset));
1440       else
1441         VEC_quick_push (tree, vargs, a);
1442       add_referenced_var (a);
1443       if (is_gimple_reg (a))
1444         mark_sym_for_renaming (a);
1445       for (i = 1, arg = DECL_CHAIN (a); i < nargs; i++, arg = DECL_CHAIN (arg))
1446         {
1447           add_referenced_var (arg);
1448           if (is_gimple_reg (arg))
1449             mark_sym_for_renaming (arg);
1450           VEC_quick_push (tree, vargs, arg);
1451         }
1452       call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs);
1453       VEC_free (tree, heap, vargs);
1454       gimple_call_set_from_thunk (call, true);
1455       if (restmp)
1456         gimple_call_set_lhs (call, restmp);
1457       gsi_insert_after (&bsi, call, GSI_NEW_STMT);
1458
1459       if (restmp && !this_adjusting)
1460         {
1461           tree true_label = NULL_TREE;
1462
1463           if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE)
1464             {
1465               gimple stmt;
1466               /* If the return type is a pointer, we need to
1467                  protect against NULL.  We know there will be an
1468                  adjustment, because that's why we're emitting a
1469                  thunk.  */
1470               then_bb = create_basic_block (NULL, (void *) 0, bb);
1471               return_bb = create_basic_block (NULL, (void *) 0, then_bb);
1472               else_bb = create_basic_block (NULL, (void *) 0, else_bb);
1473               remove_edge (single_succ_edge (bb));
1474               true_label = gimple_block_label (then_bb);
1475               stmt = gimple_build_cond (NE_EXPR, restmp,
1476                                         build_zero_cst (TREE_TYPE (restmp)),
1477                                         NULL_TREE, NULL_TREE);
1478               gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1479               make_edge (bb, then_bb, EDGE_TRUE_VALUE);
1480               make_edge (bb, else_bb, EDGE_FALSE_VALUE);
1481               make_edge (return_bb, EXIT_BLOCK_PTR, 0);
1482               make_edge (then_bb, return_bb, EDGE_FALLTHRU);
1483               make_edge (else_bb, return_bb, EDGE_FALLTHRU);
1484               bsi = gsi_last_bb (then_bb);
1485             }
1486
1487           restmp = thunk_adjust (&bsi, restmp, /*this_adjusting=*/0,
1488                                  fixed_offset, virtual_offset);
1489           if (true_label)
1490             {
1491               gimple stmt;
1492               bsi = gsi_last_bb (else_bb);
1493               stmt = gimple_build_assign (restmp,
1494                                           build_zero_cst (TREE_TYPE (restmp)));
1495               gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1496               bsi = gsi_last_bb (return_bb);
1497             }
1498         }
1499       else
1500         gimple_call_set_tail (call, true);
1501
1502       /* Build return value.  */
1503       ret = gimple_build_return (restmp);
1504       gsi_insert_after (&bsi, ret, GSI_NEW_STMT);
1505
1506       delete_unreachable_blocks ();
1507       update_ssa (TODO_update_ssa);
1508
1509       /* Since we want to emit the thunk, we explicitly mark its name as
1510          referenced.  */
1511       node->thunk.thunk_p = false;
1512       cgraph_node_remove_callees (node);
1513       cgraph_add_new_function (thunk_fndecl, true);
1514       bitmap_obstack_release (NULL);
1515     }
1516   current_function_decl = NULL;
1517 }
1518
1519
1520
1521 /* Assemble thunks and aliases asociated to NODE.  */
1522
1523 static void
1524 assemble_thunks_and_aliases (struct cgraph_node *node)
1525 {
1526   struct cgraph_edge *e;
1527   int i;
1528   struct ipa_ref *ref;
1529
1530   for (e = node->callers; e;)
1531     if (e->caller->thunk.thunk_p)
1532       {
1533         struct cgraph_node *thunk = e->caller;
1534
1535         e = e->next_caller;
1536         assemble_thunks_and_aliases (thunk);
1537         assemble_thunk (thunk);
1538       }
1539     else
1540       e = e->next_caller;
1541   for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list,
1542                                              i, ref); i++)
1543     if (ref->use == IPA_REF_ALIAS)
1544       {
1545         struct cgraph_node *alias = ipa_ref_referring_node (ref);
1546         bool saved_written = TREE_ASM_WRITTEN (alias->thunk.alias);
1547
1548         /* Force assemble_alias to really output the alias this time instead
1549            of buffering it in same alias pairs.  */
1550         TREE_ASM_WRITTEN (alias->thunk.alias) = 1;
1551         assemble_alias (alias->symbol.decl,
1552                         DECL_ASSEMBLER_NAME (alias->thunk.alias));
1553         assemble_thunks_and_aliases (alias);
1554         TREE_ASM_WRITTEN (alias->thunk.alias) = saved_written;
1555       }
1556 }
1557
1558 /* Expand function specified by NODE.  */
1559
1560 static void
1561 expand_function (struct cgraph_node *node)
1562 {
1563   tree decl = node->symbol.decl;
1564   location_t saved_loc;
1565
1566   /* We ought to not compile any inline clones.  */
1567   gcc_assert (!node->global.inlined_to);
1568
1569   announce_function (decl);
1570   node->process = 0;
1571   gcc_assert (node->lowered);
1572
1573   /* Generate RTL for the body of DECL.  */
1574
1575   timevar_push (TV_REST_OF_COMPILATION);
1576
1577   gcc_assert (cgraph_global_info_ready);
1578
1579   /* Initialize the default bitmap obstack.  */
1580   bitmap_obstack_initialize (NULL);
1581
1582   /* Initialize the RTL code for the function.  */
1583   current_function_decl = decl;
1584   saved_loc = input_location;
1585   input_location = DECL_SOURCE_LOCATION (decl);
1586   init_function_start (decl);
1587
1588   gimple_register_cfg_hooks ();
1589
1590   bitmap_obstack_initialize (&reg_obstack); /* FIXME, only at RTL generation*/
1591
1592   execute_all_ipa_transforms ();
1593
1594   /* Perform all tree transforms and optimizations.  */
1595
1596   /* Signal the start of passes.  */
1597   invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START, NULL);
1598
1599   execute_pass_list (all_passes);
1600
1601   /* Signal the end of passes.  */
1602   invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END, NULL);
1603
1604   bitmap_obstack_release (&reg_obstack);
1605
1606   /* Release the default bitmap obstack.  */
1607   bitmap_obstack_release (NULL);
1608
1609   set_cfun (NULL);
1610
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))
1615     {
1616       tree ret_type = TREE_TYPE (TREE_TYPE (decl));
1617
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))
1622         {
1623           unsigned int size_as_int
1624             = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type));
1625
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);
1632         }
1633     }
1634
1635   gimple_set_body (decl, NULL);
1636   if (DECL_STRUCT_FUNCTION (decl) == 0
1637       && !cgraph_get_node (decl)->origin)
1638     {
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;
1646     }
1647
1648   input_location = saved_loc;
1649
1650   ggc_collect ();
1651   timevar_pop (TV_REST_OF_COMPILATION);
1652
1653   /* Make sure that BE didn't give up on compiling.  */
1654   gcc_assert (TREE_ASM_WRITTEN (decl));
1655   current_function_decl = NULL;
1656
1657   /* It would make a lot more sense to output thunks before function body to get more
1658      forward and lest backwarding jumps.  This however would need solving problem
1659      with comdats. See PR48668.  Also aliases must come after function itself to
1660      make one pass assemblers, like one on AIX, happy.  See PR 50689.
1661      FIXME: Perhaps thunks should be move before function IFF they are not in comdat
1662      groups.  */
1663   assemble_thunks_and_aliases (node);
1664   cgraph_release_function_body (node);
1665   /* Eliminate all call edges.  This is important so the GIMPLE_CALL no longer
1666      points to the dead function body.  */
1667   cgraph_node_remove_callees (node);
1668 }
1669
1670
1671 /* Expand all functions that must be output.
1672
1673    Attempt to topologically sort the nodes so function is output when
1674    all called functions are already assembled to allow data to be
1675    propagated across the callgraph.  Use a stack to get smaller distance
1676    between a function and its callees (later we may choose to use a more
1677    sophisticated algorithm for function reordering; we will likely want
1678    to use subsections to make the output functions appear in top-down
1679    order).  */
1680
1681 static void
1682 expand_all_functions (void)
1683 {
1684   struct cgraph_node *node;
1685   struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
1686   int order_pos, new_order_pos = 0;
1687   int i;
1688
1689   order_pos = ipa_reverse_postorder (order);
1690   gcc_assert (order_pos == cgraph_n_nodes);
1691
1692   /* Garbage collector may remove inline clones we eliminate during
1693      optimization.  So we must be sure to not reference them.  */
1694   for (i = 0; i < order_pos; i++)
1695     if (order[i]->process)
1696       order[new_order_pos++] = order[i];
1697
1698   for (i = new_order_pos - 1; i >= 0; i--)
1699     {
1700       node = order[i];
1701       if (node->process)
1702         {
1703           node->process = 0;
1704           expand_function (node);
1705         }
1706     }
1707   cgraph_process_new_functions ();
1708
1709   free (order);
1710
1711 }
1712
1713 /* This is used to sort the node types by the cgraph order number.  */
1714
1715 enum cgraph_order_sort_kind
1716 {
1717   ORDER_UNDEFINED = 0,
1718   ORDER_FUNCTION,
1719   ORDER_VAR,
1720   ORDER_ASM
1721 };
1722
1723 struct cgraph_order_sort
1724 {
1725   enum cgraph_order_sort_kind kind;
1726   union
1727   {
1728     struct cgraph_node *f;
1729     struct varpool_node *v;
1730     struct asm_node *a;
1731   } u;
1732 };
1733
1734 /* Output all functions, variables, and asm statements in the order
1735    according to their order fields, which is the order in which they
1736    appeared in the file.  This implements -fno-toplevel-reorder.  In
1737    this mode we may output functions and variables which don't really
1738    need to be output.  */
1739
1740 static void
1741 output_in_order (void)
1742 {
1743   int max;
1744   struct cgraph_order_sort *nodes;
1745   int i;
1746   struct cgraph_node *pf;
1747   struct varpool_node *pv;
1748   struct asm_node *pa;
1749
1750   max = symtab_order;
1751   nodes = XCNEWVEC (struct cgraph_order_sort, max);
1752
1753   FOR_EACH_DEFINED_FUNCTION (pf)
1754     {
1755       if (pf->process && !pf->thunk.thunk_p && !pf->alias)
1756         {
1757           i = pf->symbol.order;
1758           gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1759           nodes[i].kind = ORDER_FUNCTION;
1760           nodes[i].u.f = pf;
1761         }
1762     }
1763
1764   FOR_EACH_DEFINED_VARIABLE (pv)
1765     if (!DECL_EXTERNAL (pv->symbol.decl))
1766       {
1767         i = pv->symbol.order;
1768         gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1769         nodes[i].kind = ORDER_VAR;
1770         nodes[i].u.v = pv;
1771       }
1772
1773   for (pa = asm_nodes; pa; pa = pa->next)
1774     {
1775       i = pa->order;
1776       gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1777       nodes[i].kind = ORDER_ASM;
1778       nodes[i].u.a = pa;
1779     }
1780
1781   /* In toplevel reorder mode we output all statics; mark them as needed.  */
1782
1783   for (i = 0; i < max; ++i)
1784     if (nodes[i].kind == ORDER_VAR)
1785       varpool_finalize_named_section_flags (nodes[i].u.v);
1786
1787   for (i = 0; i < max; ++i)
1788     {
1789       switch (nodes[i].kind)
1790         {
1791         case ORDER_FUNCTION:
1792           nodes[i].u.f->process = 0;
1793           expand_function (nodes[i].u.f);
1794           break;
1795
1796         case ORDER_VAR:
1797           varpool_assemble_decl (nodes[i].u.v);
1798           break;
1799
1800         case ORDER_ASM:
1801           assemble_asm (nodes[i].u.a->asm_str);
1802           break;
1803
1804         case ORDER_UNDEFINED:
1805           break;
1806
1807         default:
1808           gcc_unreachable ();
1809         }
1810     }
1811
1812   asm_nodes = NULL;
1813   free (nodes);
1814 }
1815
1816 static void
1817 ipa_passes (void)
1818 {
1819   set_cfun (NULL);
1820   current_function_decl = NULL;
1821   gimple_register_cfg_hooks ();
1822   bitmap_obstack_initialize (NULL);
1823
1824   invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START, NULL);
1825
1826   if (!in_lto_p)
1827     {
1828       execute_ipa_pass_list (all_small_ipa_passes);
1829       if (seen_error ())
1830         return;
1831     }
1832
1833   /* We never run removal of unreachable nodes after early passes.  This is
1834      because TODO is run before the subpasses.  It is important to remove
1835      the unreachable functions to save works at IPA level and to get LTO
1836      symbol tables right.  */
1837   symtab_remove_unreachable_nodes (true, cgraph_dump_file);
1838
1839   /* If pass_all_early_optimizations was not scheduled, the state of
1840      the cgraph will not be properly updated.  Update it now.  */
1841   if (cgraph_state < CGRAPH_STATE_IPA_SSA)
1842     cgraph_state = CGRAPH_STATE_IPA_SSA;
1843
1844   if (!in_lto_p)
1845     {
1846       /* Generate coverage variables and constructors.  */
1847       coverage_finish ();
1848
1849       /* Process new functions added.  */
1850       set_cfun (NULL);
1851       current_function_decl = NULL;
1852       cgraph_process_new_functions ();
1853
1854       execute_ipa_summary_passes
1855         ((struct ipa_opt_pass_d *) all_regular_ipa_passes);
1856     }
1857
1858   /* Some targets need to handle LTO assembler output specially.  */
1859   if (flag_generate_lto)
1860     targetm.asm_out.lto_start ();
1861
1862   execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_lto_gen_passes);
1863
1864   if (!in_lto_p)
1865     ipa_write_summaries ();
1866
1867   if (flag_generate_lto)
1868     targetm.asm_out.lto_end ();
1869
1870   if (!flag_ltrans && (in_lto_p || !flag_lto || flag_fat_lto_objects))
1871     execute_ipa_pass_list (all_regular_ipa_passes);
1872   invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END, NULL);
1873
1874   bitmap_obstack_release (NULL);
1875 }
1876
1877
1878 /* Return string alias is alias of.  */
1879
1880 static tree
1881 get_alias_symbol (tree decl)
1882 {
1883   tree alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
1884   return get_identifier (TREE_STRING_POINTER
1885                           (TREE_VALUE (TREE_VALUE (alias))));
1886 }
1887
1888
1889 /* Weakrefs may be associated to external decls and thus not output
1890    at expansion time.  Emit all neccesary aliases.  */
1891
1892 static void
1893 output_weakrefs (void)
1894 {
1895   struct cgraph_node *node;
1896   struct varpool_node *vnode;
1897   FOR_EACH_FUNCTION (node)
1898     if (node->alias && DECL_EXTERNAL (node->symbol.decl)
1899         && !TREE_ASM_WRITTEN (node->symbol.decl)
1900         && lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
1901       assemble_alias (node->symbol.decl,
1902                       node->thunk.alias ? DECL_ASSEMBLER_NAME (node->thunk.alias)
1903                       : get_alias_symbol (node->symbol.decl));
1904   FOR_EACH_VARIABLE (vnode)
1905     if (vnode->alias && DECL_EXTERNAL (vnode->symbol.decl)
1906         && !TREE_ASM_WRITTEN (vnode->symbol.decl)
1907         && lookup_attribute ("weakref", DECL_ATTRIBUTES (vnode->symbol.decl)))
1908       assemble_alias (vnode->symbol.decl,
1909                       vnode->alias_of ? DECL_ASSEMBLER_NAME (vnode->alias_of)
1910                       : get_alias_symbol (vnode->symbol.decl));
1911 }
1912
1913 /* Initialize callgraph dump file.  */
1914
1915 void
1916 init_cgraph (void)
1917 {
1918   if (!cgraph_dump_file)
1919     cgraph_dump_file = dump_begin (TDI_cgraph, NULL);
1920 }
1921
1922
1923 /* Perform simple optimizations based on callgraph.  */
1924
1925 void
1926 compile (void)
1927 {
1928   if (seen_error ())
1929     return;
1930
1931 #ifdef ENABLE_CHECKING
1932   verify_symtab ();
1933 #endif
1934
1935   timevar_push (TV_CGRAPHOPT);
1936   if (pre_ipa_mem_report)
1937     {
1938       fprintf (stderr, "Memory consumption before IPA\n");
1939       dump_memory_report (false);
1940     }
1941   if (!quiet_flag)
1942     fprintf (stderr, "Performing interprocedural optimizations\n");
1943   cgraph_state = CGRAPH_STATE_IPA;
1944
1945   /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE.  */
1946   if (flag_lto)
1947     lto_streamer_hooks_init ();
1948
1949   /* Don't run the IPA passes if there was any error or sorry messages.  */
1950   if (!seen_error ())
1951     ipa_passes ();
1952
1953   /* Do nothing else if any IPA pass found errors or if we are just streaming LTO.  */
1954   if (seen_error ()
1955       || (!in_lto_p && flag_lto && !flag_fat_lto_objects))
1956     {
1957       timevar_pop (TV_CGRAPHOPT);
1958       return;
1959     }
1960
1961   /* This pass remove bodies of extern inline functions we never inlined.
1962      Do this later so other IPA passes see what is really going on.  */
1963   symtab_remove_unreachable_nodes (false, dump_file);
1964   cgraph_global_info_ready = true;
1965   if (cgraph_dump_file)
1966     {
1967       fprintf (cgraph_dump_file, "Optimized ");
1968       dump_symtab (cgraph_dump_file);
1969     }
1970   if (post_ipa_mem_report)
1971     {
1972       fprintf (stderr, "Memory consumption after IPA\n");
1973       dump_memory_report (false);
1974     }
1975   timevar_pop (TV_CGRAPHOPT);
1976
1977   /* Output everything.  */
1978   (*debug_hooks->assembly_start) ();
1979   if (!quiet_flag)
1980     fprintf (stderr, "Assembling functions:\n");
1981 #ifdef ENABLE_CHECKING
1982   verify_symtab ();
1983 #endif
1984
1985   cgraph_materialize_all_clones ();
1986   bitmap_obstack_initialize (NULL);
1987   execute_ipa_pass_list (all_late_ipa_passes);
1988   symtab_remove_unreachable_nodes (true, dump_file);
1989 #ifdef ENABLE_CHECKING
1990   verify_symtab ();
1991 #endif
1992   bitmap_obstack_release (NULL);
1993   mark_functions_to_output ();
1994   output_weakrefs ();
1995
1996   cgraph_state = CGRAPH_STATE_EXPANSION;
1997   if (!flag_toplevel_reorder)
1998     output_in_order ();
1999   else
2000     {
2001       output_asm_statements ();
2002
2003       expand_all_functions ();
2004       varpool_output_variables ();
2005     }
2006
2007   cgraph_process_new_functions ();
2008   cgraph_state = CGRAPH_STATE_FINISHED;
2009
2010   if (cgraph_dump_file)
2011     {
2012       fprintf (cgraph_dump_file, "\nFinal ");
2013       dump_symtab (cgraph_dump_file);
2014     }
2015 #ifdef ENABLE_CHECKING
2016   verify_symtab ();
2017   /* Double check that all inline clones are gone and that all
2018      function bodies have been released from memory.  */
2019   if (!seen_error ())
2020     {
2021       struct cgraph_node *node;
2022       bool error_found = false;
2023
2024       FOR_EACH_DEFINED_FUNCTION (node)
2025         if (node->global.inlined_to
2026             || gimple_has_body_p (node->symbol.decl))
2027           {
2028             error_found = true;
2029             dump_cgraph_node (stderr, node);
2030           }
2031       if (error_found)
2032         internal_error ("nodes with unreleased memory found");
2033     }
2034 #endif
2035 }
2036
2037
2038 /* Analyze the whole compilation unit once it is parsed completely.  */
2039
2040 void
2041 finalize_compilation_unit (void)
2042 {
2043   timevar_push (TV_CGRAPH);
2044
2045   /* If we're here there's no current function anymore.  Some frontends
2046      are lazy in clearing these.  */
2047   current_function_decl = NULL;
2048   set_cfun (NULL);
2049
2050   /* Do not skip analyzing the functions if there were errors, we
2051      miss diagnostics for following functions otherwise.  */
2052
2053   /* Emit size functions we didn't inline.  */
2054   finalize_size_functions ();
2055
2056   /* Mark alias targets necessary and emit diagnostics.  */
2057   finish_aliases_1 ();
2058   handle_alias_pairs ();
2059
2060   if (!quiet_flag)
2061     {
2062       fprintf (stderr, "\nAnalyzing compilation unit\n");
2063       fflush (stderr);
2064     }
2065
2066   if (flag_dump_passes)
2067     dump_passes ();
2068
2069   /* Gimplify and lower all functions, compute reachability and
2070      remove unreachable nodes.  */
2071   cgraph_analyze_functions ();
2072
2073   /* Mark alias targets necessary and emit diagnostics.  */
2074   finish_aliases_1 ();
2075   handle_alias_pairs ();
2076
2077   /* Gimplify and lower thunks.  */
2078   cgraph_analyze_functions ();
2079
2080   /* Finally drive the pass manager.  */
2081   compile ();
2082
2083   timevar_pop (TV_CGRAPH);
2084 }
2085
2086
2087 #include "gt-cgraphunit.h"