lto-symtab.c (lto_cgraph_replace_node): Do not call mark_reahcable_node.
[platform/upstream/gcc.git] / gcc / cgraphunit.c
1 /* Callgraph based interprocedural optimizations.
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 as well as
23    few basic interprocedural optimizers.
24
25    The main scope of this file is to act as an interface in between
26    tree based frontends and the backend (and middle end)
27
28    The front-end is supposed to use following functionality:
29
30     - cgraph_finalize_function
31
32       This function is called once front-end has parsed whole body of function
33       and it is certain that the function body nor the declaration will change.
34
35       (There is one exception needed for implementing GCC extern inline
36         function.)
37
38     - varpool_finalize_variable
39
40       This function has same behavior as the above but is used for static
41       variables.
42
43     - cgraph_finalize_compilation_unit
44
45       This function is called once (source level) compilation unit is finalized
46       and it will no longer change.
47
48       In the call-graph construction and local function analysis takes
49       place here.  Bodies of unreachable functions are released to
50       conserve memory usage.
51
52       The function can be called multiple times when multiple source level
53       compilation units are combined (such as in C frontend)
54
55     - cgraph_optimize
56
57       In this unit-at-a-time compilation the intra procedural analysis takes
58       place here.  In particular the static functions whose address is never
59       taken are marked as local.  Backend can then use this information to
60       modify calling conventions, do better inlining or similar optimizations.
61
62     - cgraph_mark_needed_node
63     - varpool_mark_needed_node
64
65       When function or variable is referenced by some hidden way the call-graph
66       data structure must be updated accordingly by this function.
67       There should be little need to call this function and all the references
68       should be made explicit to cgraph code.  At present these functions are
69       used by C++ frontend to explicitly mark the keyed methods.
70
71     - analyze_expr callback
72
73       This function is responsible for lowering tree nodes not understood by
74       generic code into understandable ones or alternatively marking
75       callgraph and varpool nodes referenced by the as needed.
76
77       ??? On the tree-ssa genericizing should take place here and we will avoid
78       need for these hooks (replacing them by genericizing hook)
79
80         Analyzing of all functions is deferred
81         to cgraph_finalize_compilation_unit and expansion into cgraph_optimize.
82
83         In cgraph_finalize_compilation_unit the reachable functions are
84         analyzed.  During analysis the call-graph edges from reachable
85         functions are constructed and their destinations are marked as
86         reachable.  References to functions and variables are discovered too
87         and variables found to be needed output to the assembly file.  Via
88         mark_referenced call in assemble_variable functions referenced by
89         static variables are noticed too.
90
91         The intra-procedural information is produced and its existence
92         indicated by global_info_ready.  Once this flag is set it is impossible
93         to change function from !reachable to reachable and thus
94         assemble_variable no longer call mark_referenced.
95
96         Finally the call-graph is topologically sorted and all reachable functions
97         that has not been completely inlined or are not external are output.
98
99         ??? It is possible that reference to function or variable is optimized
100         out.  We can not deal with this nicely because topological order is not
101         suitable for it.  For tree-ssa we may consider another pass doing
102         optimization and re-discovering reachable functions.
103
104         ??? Reorganize code so variables are output very last and only if they
105         really has been referenced by produced code, so we catch more cases
106         where reference has been optimized out.  */
107
108
109 #include "config.h"
110 #include "system.h"
111 #include "coretypes.h"
112 #include "tm.h"
113 #include "tree.h"
114 #include "output.h"
115 #include "rtl.h"
116 #include "tree-flow.h"
117 #include "tree-inline.h"
118 #include "langhooks.h"
119 #include "pointer-set.h"
120 #include "toplev.h"
121 #include "flags.h"
122 #include "ggc.h"
123 #include "debug.h"
124 #include "target.h"
125 #include "cgraph.h"
126 #include "diagnostic.h"
127 #include "tree-pretty-print.h"
128 #include "gimple-pretty-print.h"
129 #include "timevar.h"
130 #include "params.h"
131 #include "fibheap.h"
132 #include "intl.h"
133 #include "function.h"
134 #include "ipa-prop.h"
135 #include "gimple.h"
136 #include "tree-iterator.h"
137 #include "tree-pass.h"
138 #include "tree-dump.h"
139 #include "output.h"
140 #include "coverage.h"
141 #include "plugin.h"
142 #include "ipa-inline.h"
143 #include "ipa-utils.h"
144 #include "lto-streamer.h"
145 #include "except.h"
146 #include "regset.h"     /* FIXME: For reg_obstack.  */
147
148 /* Queue of cgraph nodes scheduled to be added into cgraph.  This is a
149    secondary queue used during optimization to accommodate passes that
150    may generate new functions that need to be optimized and expanded.  */
151 cgraph_node_set cgraph_new_nodes;
152
153 static void cgraph_expand_all_functions (void);
154 static void cgraph_mark_functions_to_output (void);
155 static void cgraph_expand_function (struct cgraph_node *);
156 static void cgraph_output_pending_asms (void);
157 static void tree_rest_of_compilation (struct cgraph_node *);
158
159 FILE *cgraph_dump_file;
160
161 /* Used for vtable lookup in thunk adjusting.  */
162 static GTY (()) tree vtable_entry_type;
163
164 /* Determine if function DECL is trivially needed and should stay in the
165    compilation unit.  This is used at the symbol table construction time
166    and differs from later logic removing unnecesary functions that can
167    take into account results of analysis, whole program info etc.  */
168
169 bool
170 cgraph_decide_is_function_needed (struct cgraph_node *node, tree decl)
171 {
172   /* If the user told us it is used, then it must be so.  */
173   if (node->symbol.force_output)
174     return true;
175
176   /* Double check that no one output the function into assembly file
177      early.  */
178   gcc_checking_assert (!DECL_ASSEMBLER_NAME_SET_P (decl)
179                        || (node->thunk.thunk_p || node->same_body_alias)
180                        ||  !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)));
181
182
183   /* Keep constructors, destructors and virtual functions.  */
184   if (DECL_STATIC_CONSTRUCTOR (decl)
185       || DECL_STATIC_DESTRUCTOR (decl)
186       || (DECL_VIRTUAL_P (decl)
187           && optimize && (DECL_COMDAT (decl) || DECL_EXTERNAL (decl))))
188      return true;
189
190   /* Externally visible functions must be output.  The exception is
191      COMDAT functions that must be output only when they are needed.  */
192
193   if (TREE_PUBLIC (decl)
194       && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
195     return true;
196
197   return false;
198 }
199
200 /* Head of the queue of nodes to be processed while building callgraph */
201
202 static symtab_node first = (symtab_node)(void *)1;
203
204 /* Add NODE to queue starting at FIRST. 
205    The queue is linked via AUX pointers and terminated by pointer to 1.  */
206
207 static void
208 enqueue_node (symtab_node node)
209 {
210   if (node->symbol.aux)
211     return;
212   gcc_checking_assert (first);
213   node->symbol.aux = first;
214   first = node;
215 }
216
217 /* Process CGRAPH_NEW_FUNCTIONS and perform actions necessary to add these
218    functions into callgraph in a way so they look like ordinary reachable
219    functions inserted into callgraph already at construction time.  */
220
221 bool
222 cgraph_process_new_functions (void)
223 {
224   bool output = false;
225   tree fndecl;
226   struct cgraph_node *node;
227   cgraph_node_set_iterator csi;
228
229   if (!cgraph_new_nodes)
230     return false;
231   /*  Note that this queue may grow as its being processed, as the new
232       functions may generate new ones.  */
233   for (csi = csi_start (cgraph_new_nodes); !csi_end_p (csi); csi_next (&csi))
234     {
235       node = csi_node (csi);
236       fndecl = node->symbol.decl;
237       switch (cgraph_state)
238         {
239         case CGRAPH_STATE_CONSTRUCTION:
240           /* At construction time we just need to finalize function and move
241              it into reachable functions list.  */
242
243           cgraph_finalize_function (fndecl, false);
244           output = true;
245           cgraph_call_function_insertion_hooks (node);
246           enqueue_node ((symtab_node) node);
247           break;
248
249         case CGRAPH_STATE_IPA:
250         case CGRAPH_STATE_IPA_SSA:
251           /* When IPA optimization already started, do all essential
252              transformations that has been already performed on the whole
253              cgraph but not on this function.  */
254
255           gimple_register_cfg_hooks ();
256           if (!node->analyzed)
257             cgraph_analyze_function (node);
258           push_cfun (DECL_STRUCT_FUNCTION (fndecl));
259           current_function_decl = fndecl;
260           if ((cgraph_state == CGRAPH_STATE_IPA_SSA
261               && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
262               /* When not optimizing, be sure we run early local passes anyway
263                  to expand OMP.  */
264               || !optimize)
265             execute_pass_list (pass_early_local_passes.pass.sub);
266           else
267             compute_inline_parameters (node, true);
268           free_dominance_info (CDI_POST_DOMINATORS);
269           free_dominance_info (CDI_DOMINATORS);
270           pop_cfun ();
271           current_function_decl = NULL;
272           cgraph_call_function_insertion_hooks (node);
273           break;
274
275         case CGRAPH_STATE_EXPANSION:
276           /* Functions created during expansion shall be compiled
277              directly.  */
278           node->process = 0;
279           cgraph_call_function_insertion_hooks (node);
280           cgraph_expand_function (node);
281           break;
282
283         default:
284           gcc_unreachable ();
285           break;
286         }
287     }
288   free_cgraph_node_set (cgraph_new_nodes);
289   cgraph_new_nodes = NULL;
290   return output;
291 }
292
293 /* As an GCC extension we allow redefinition of the function.  The
294    semantics when both copies of bodies differ is not well defined.
295    We replace the old body with new body so in unit at a time mode
296    we always use new body, while in normal mode we may end up with
297    old body inlined into some functions and new body expanded and
298    inlined in others.
299
300    ??? It may make more sense to use one body for inlining and other
301    body for expanding the function but this is difficult to do.  */
302
303 static void
304 cgraph_reset_node (struct cgraph_node *node)
305 {
306   /* If node->process is set, then we have already begun whole-unit analysis.
307      This is *not* testing for whether we've already emitted the function.
308      That case can be sort-of legitimately seen with real function redefinition
309      errors.  I would argue that the front end should never present us with
310      such a case, but don't enforce that for now.  */
311   gcc_assert (!node->process);
312
313   /* Reset our data structures so we can analyze the function again.  */
314   memset (&node->local, 0, sizeof (node->local));
315   memset (&node->global, 0, sizeof (node->global));
316   memset (&node->rtl, 0, sizeof (node->rtl));
317   node->analyzed = false;
318   node->local.finalized = false;
319
320   cgraph_node_remove_callees (node);
321 }
322
323 /* DECL has been parsed.  Take it, queue it, compile it at the whim of the
324    logic in effect.  If NESTED is true, then our caller cannot stand to have
325    the garbage collector run at the moment.  We would need to either create
326    a new GC context, or just not compile right now.  */
327
328 void
329 cgraph_finalize_function (tree decl, bool nested)
330 {
331   struct cgraph_node *node = cgraph_get_create_node (decl);
332
333   if (node->local.finalized)
334     {
335       cgraph_reset_node (node);
336       node->local.redefined_extern_inline = true;
337     }
338
339   notice_global_symbol (decl);
340   node->local.finalized = true;
341   node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL;
342
343   /* With -fkeep-inline-functions we are keeping all inline functions except
344      for extern inline ones.  */
345   if (flag_keep_inline_functions
346       && DECL_DECLARED_INLINE_P (decl)
347       && !DECL_EXTERNAL (decl)
348       && !DECL_DISREGARD_INLINE_LIMITS (decl))
349     node->symbol.force_output = 1;
350
351   /* When not optimizing, also output the static functions. (see
352      PR24561), but don't do so for always_inline functions, functions
353      declared inline and nested functions.  These were optimized out
354      in the original implementation and it is unclear whether we want
355      to change the behavior here.  */
356   if ((!optimize
357        && !node->same_body_alias
358        && !DECL_DISREGARD_INLINE_LIMITS (decl)
359        && !DECL_DECLARED_INLINE_P (decl)
360        && !(DECL_CONTEXT (decl)
361             && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL))
362       && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
363     node->symbol.force_output = 1;
364
365   /* If we've not yet emitted decl, tell the debug info about it.  */
366   if (!TREE_ASM_WRITTEN (decl))
367     (*debug_hooks->deferred_inline_function) (decl);
368
369   /* Possibly warn about unused parameters.  */
370   if (warn_unused_parameter)
371     do_warn_unused_parameter (decl);
372
373   if (!nested)
374     ggc_collect ();
375 }
376
377 /* Add the function FNDECL to the call graph.
378    Unlike cgraph_finalize_function, this function is intended to be used
379    by middle end and allows insertion of new function at arbitrary point
380    of compilation.  The function can be either in high, low or SSA form
381    GIMPLE.
382
383    The function is assumed to be reachable and have address taken (so no
384    API breaking optimizations are performed on it).
385
386    Main work done by this function is to enqueue the function for later
387    processing to avoid need the passes to be re-entrant.  */
388
389 void
390 cgraph_add_new_function (tree fndecl, bool lowered)
391 {
392   struct cgraph_node *node;
393   switch (cgraph_state)
394     {
395       case CGRAPH_STATE_PARSING:
396         cgraph_finalize_function (fndecl, false);
397         break;
398       case CGRAPH_STATE_CONSTRUCTION:
399         /* Just enqueue function to be processed at nearest occurrence.  */
400         node = cgraph_create_node (fndecl);
401         if (lowered)
402           node->lowered = true;
403         if (!cgraph_new_nodes)
404           cgraph_new_nodes = cgraph_node_set_new ();
405         cgraph_node_set_add (cgraph_new_nodes, node);
406         break;
407
408       case CGRAPH_STATE_IPA:
409       case CGRAPH_STATE_IPA_SSA:
410       case CGRAPH_STATE_EXPANSION:
411         /* Bring the function into finalized state and enqueue for later
412            analyzing and compilation.  */
413         node = cgraph_get_create_node (fndecl);
414         node->local.local = false;
415         node->local.finalized = true;
416         node->symbol.force_output = true;
417         if (!lowered && cgraph_state == CGRAPH_STATE_EXPANSION)
418           {
419             push_cfun (DECL_STRUCT_FUNCTION (fndecl));
420             current_function_decl = fndecl;
421             gimple_register_cfg_hooks ();
422             bitmap_obstack_initialize (NULL);
423             execute_pass_list (all_lowering_passes);
424             execute_pass_list (pass_early_local_passes.pass.sub);
425             bitmap_obstack_release (NULL);
426             pop_cfun ();
427             current_function_decl = NULL;
428
429             lowered = true;
430           }
431         if (lowered)
432           node->lowered = true;
433         if (!cgraph_new_nodes)
434           cgraph_new_nodes = cgraph_node_set_new ();
435         cgraph_node_set_add (cgraph_new_nodes, node);
436         break;
437
438       case CGRAPH_STATE_FINISHED:
439         /* At the very end of compilation we have to do all the work up
440            to expansion.  */
441         node = cgraph_create_node (fndecl);
442         if (lowered)
443           node->lowered = true;
444         cgraph_analyze_function (node);
445         push_cfun (DECL_STRUCT_FUNCTION (fndecl));
446         current_function_decl = fndecl;
447         gimple_register_cfg_hooks ();
448         bitmap_obstack_initialize (NULL);
449         if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
450           execute_pass_list (pass_early_local_passes.pass.sub);
451         bitmap_obstack_release (NULL);
452         tree_rest_of_compilation (node);
453         pop_cfun ();
454         current_function_decl = NULL;
455         break;
456
457       default:
458         gcc_unreachable ();
459     }
460
461   /* Set a personality if required and we already passed EH lowering.  */
462   if (lowered
463       && (function_needs_eh_personality (DECL_STRUCT_FUNCTION (fndecl))
464           == eh_personality_lang))
465     DECL_FUNCTION_PERSONALITY (fndecl) = lang_hooks.eh_personality ();
466 }
467
468 /* Return TRUE if NODE2 is equivalent to NODE or its clone.  */
469 static bool
470 clone_of_p (struct cgraph_node *node, struct cgraph_node *node2)
471 {
472   node = cgraph_function_or_thunk_node (node, NULL);
473   node2 = cgraph_function_or_thunk_node (node2, NULL);
474   while (node != node2 && node2)
475     node2 = node2->clone_of;
476   return node2 != NULL;
477 }
478
479 /* Verify edge E count and frequency.  */
480
481 static bool
482 verify_edge_count_and_frequency (struct cgraph_edge *e)
483 {
484   bool error_found = false;
485   if (e->count < 0)
486     {
487       error ("caller edge count is negative");
488       error_found = true;
489     }
490   if (e->frequency < 0)
491     {
492       error ("caller edge frequency is negative");
493       error_found = true;
494     }
495   if (e->frequency > CGRAPH_FREQ_MAX)
496     {
497       error ("caller edge frequency is too large");
498       error_found = true;
499     }
500   if (gimple_has_body_p (e->caller->symbol.decl)
501       && !e->caller->global.inlined_to
502       /* FIXME: Inline-analysis sets frequency to 0 when edge is optimized out.
503          Remove this once edges are actualy removed from the function at that time.  */
504       && (e->frequency
505           || (inline_edge_summary_vec
506               && ((VEC_length(inline_edge_summary_t, inline_edge_summary_vec)
507                   <= (unsigned) e->uid)
508                   || !inline_edge_summary (e)->predicate)))
509       && (e->frequency
510           != compute_call_stmt_bb_frequency (e->caller->symbol.decl,
511                                              gimple_bb (e->call_stmt))))
512     {
513       error ("caller edge frequency %i does not match BB frequency %i",
514              e->frequency,
515              compute_call_stmt_bb_frequency (e->caller->symbol.decl,
516                                              gimple_bb (e->call_stmt)));
517       error_found = true;
518     }
519   return error_found;
520 }
521
522 /* Switch to THIS_CFUN if needed and print STMT to stderr.  */
523 static void
524 cgraph_debug_gimple_stmt (struct function *this_cfun, gimple stmt)
525 {
526   /* debug_gimple_stmt needs correct cfun */
527   if (cfun != this_cfun)
528     set_cfun (this_cfun);
529   debug_gimple_stmt (stmt);
530 }
531
532 /* Verify that call graph edge E corresponds to DECL from the associated
533    statement.  Return true if the verification should fail.  */
534
535 static bool
536 verify_edge_corresponds_to_fndecl (struct cgraph_edge *e, tree decl)
537 {
538   struct cgraph_node *node;
539
540   if (!decl || e->callee->global.inlined_to)
541     return false;
542   node = cgraph_get_node (decl);
543
544   /* We do not know if a node from a different partition is an alias or what it
545      aliases and therefore cannot do the former_clone_of check reliably.  */
546   if (!node || node->symbol.in_other_partition)
547     return false;
548   node = cgraph_function_or_thunk_node (node, NULL);
549
550   if ((e->callee->former_clone_of != node->symbol.decl
551        && (!node->same_body_alias
552            || e->callee->former_clone_of != node->thunk.alias))
553       /* IPA-CP sometimes redirect edge to clone and then back to the former
554          function.  This ping-pong has to go, eventually.  */
555       && (node != cgraph_function_or_thunk_node (e->callee, NULL))
556       && !clone_of_p (node, e->callee)
557       /* If decl is a same body alias of some other decl, allow e->callee to be
558          a clone of a clone of that other decl too.  */
559       && (!node->same_body_alias
560           || !clone_of_p (cgraph_get_node (node->thunk.alias), e->callee)))
561     return true;
562   else
563     return false;
564 }
565
566 /* Verify cgraph nodes of given cgraph node.  */
567 DEBUG_FUNCTION void
568 verify_cgraph_node (struct cgraph_node *node)
569 {
570   struct cgraph_edge *e;
571   struct function *this_cfun = DECL_STRUCT_FUNCTION (node->symbol.decl);
572   basic_block this_block;
573   gimple_stmt_iterator gsi;
574   bool error_found = false;
575
576   if (seen_error ())
577     return;
578
579   timevar_push (TV_CGRAPH_VERIFY);
580   error_found |= verify_symtab_base ((symtab_node) node);
581   for (e = node->callees; e; e = e->next_callee)
582     if (e->aux)
583       {
584         error ("aux field set for edge %s->%s",
585                identifier_to_locale (cgraph_node_name (e->caller)),
586                identifier_to_locale (cgraph_node_name (e->callee)));
587         error_found = true;
588       }
589   if (node->count < 0)
590     {
591       error ("execution count is negative");
592       error_found = true;
593     }
594   if (node->global.inlined_to && node->symbol.externally_visible)
595     {
596       error ("externally visible inline clone");
597       error_found = true;
598     }
599   if (node->global.inlined_to && node->symbol.address_taken)
600     {
601       error ("inline clone with address taken");
602       error_found = true;
603     }
604   if (node->global.inlined_to && node->symbol.force_output)
605     {
606       error ("inline clone is forced to output");
607       error_found = true;
608     }
609   for (e = node->indirect_calls; e; e = e->next_callee)
610     {
611       if (e->aux)
612         {
613           error ("aux field set for indirect edge from %s",
614                  identifier_to_locale (cgraph_node_name (e->caller)));
615           error_found = true;
616         }
617       if (!e->indirect_unknown_callee
618           || !e->indirect_info)
619         {
620           error ("An indirect edge from %s is not marked as indirect or has "
621                  "associated indirect_info, the corresponding statement is: ",
622                  identifier_to_locale (cgraph_node_name (e->caller)));
623           cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
624           error_found = true;
625         }
626     }
627   for (e = node->callers; e; e = e->next_caller)
628     {
629       if (verify_edge_count_and_frequency (e))
630         error_found = true;
631       if (!e->inline_failed)
632         {
633           if (node->global.inlined_to
634               != (e->caller->global.inlined_to
635                   ? e->caller->global.inlined_to : e->caller))
636             {
637               error ("inlined_to pointer is wrong");
638               error_found = true;
639             }
640           if (node->callers->next_caller)
641             {
642               error ("multiple inline callers");
643               error_found = true;
644             }
645         }
646       else
647         if (node->global.inlined_to)
648           {
649             error ("inlined_to pointer set for noninline callers");
650             error_found = true;
651           }
652     }
653   for (e = node->indirect_calls; e; e = e->next_callee)
654     if (verify_edge_count_and_frequency (e))
655       error_found = true;
656   if (!node->callers && node->global.inlined_to)
657     {
658       error ("inlined_to pointer is set but no predecessors found");
659       error_found = true;
660     }
661   if (node->global.inlined_to == node)
662     {
663       error ("inlined_to pointer refers to itself");
664       error_found = true;
665     }
666
667   if (node->clone_of)
668     {
669       struct cgraph_node *n;
670       for (n = node->clone_of->clones; n; n = n->next_sibling_clone)
671         if (n == node)
672           break;
673       if (!n)
674         {
675           error ("node has wrong clone_of");
676           error_found = true;
677         }
678     }
679   if (node->clones)
680     {
681       struct cgraph_node *n;
682       for (n = node->clones; n; n = n->next_sibling_clone)
683         if (n->clone_of != node)
684           break;
685       if (n)
686         {
687           error ("node has wrong clone list");
688           error_found = true;
689         }
690     }
691   if ((node->prev_sibling_clone || node->next_sibling_clone) && !node->clone_of)
692     {
693        error ("node is in clone list but it is not clone");
694        error_found = true;
695     }
696   if (!node->prev_sibling_clone && node->clone_of && node->clone_of->clones != node)
697     {
698       error ("node has wrong prev_clone pointer");
699       error_found = true;
700     }
701   if (node->prev_sibling_clone && node->prev_sibling_clone->next_sibling_clone != node)
702     {
703       error ("double linked list of clones corrupted");
704       error_found = true;
705     }
706
707   if (node->analyzed && node->alias)
708     {
709       bool ref_found = false;
710       int i;
711       struct ipa_ref *ref;
712
713       if (node->callees)
714         {
715           error ("Alias has call edges");
716           error_found = true;
717         }
718       for (i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list,
719                                                   i, ref); i++)
720         if (ref->use != IPA_REF_ALIAS)
721           {
722             error ("Alias has non-alias reference");
723             error_found = true;
724           }
725         else if (ref_found)
726           {
727             error ("Alias has more than one alias reference");
728             error_found = true;
729           }
730         else
731           ref_found = true;
732         if (!ref_found)
733           {
734             error ("Analyzed alias has no reference");
735             error_found = true;
736           }
737     }
738   if (node->analyzed && node->thunk.thunk_p)
739     {
740       if (!node->callees)
741         {
742           error ("No edge out of thunk node");
743           error_found = true;
744         }
745       else if (node->callees->next_callee)
746         {
747           error ("More than one edge out of thunk node");
748           error_found = true;
749         }
750       if (gimple_has_body_p (node->symbol.decl))
751         {
752           error ("Thunk is not supposed to have body");
753           error_found = true;
754         }
755     }
756   else if (node->analyzed && gimple_has_body_p (node->symbol.decl)
757            && !TREE_ASM_WRITTEN (node->symbol.decl)
758            && (!DECL_EXTERNAL (node->symbol.decl) || node->global.inlined_to)
759            && !flag_wpa)
760     {
761       if (this_cfun->cfg)
762         {
763           /* The nodes we're interested in are never shared, so walk
764              the tree ignoring duplicates.  */
765           struct pointer_set_t *visited_nodes = pointer_set_create ();
766           /* Reach the trees by walking over the CFG, and note the
767              enclosing basic-blocks in the call edges.  */
768           FOR_EACH_BB_FN (this_block, this_cfun)
769             for (gsi = gsi_start_bb (this_block);
770                  !gsi_end_p (gsi);
771                  gsi_next (&gsi))
772               {
773                 gimple stmt = gsi_stmt (gsi);
774                 if (is_gimple_call (stmt))
775                   {
776                     struct cgraph_edge *e = cgraph_edge (node, stmt);
777                     tree decl = gimple_call_fndecl (stmt);
778                     if (e)
779                       {
780                         if (e->aux)
781                           {
782                             error ("shared call_stmt:");
783                             cgraph_debug_gimple_stmt (this_cfun, stmt);
784                             error_found = true;
785                           }
786                         if (!e->indirect_unknown_callee)
787                           {
788                             if (verify_edge_corresponds_to_fndecl (e, decl))
789                               {
790                                 error ("edge points to wrong declaration:");
791                                 debug_tree (e->callee->symbol.decl);
792                                 fprintf (stderr," Instead of:");
793                                 debug_tree (decl);
794                                 error_found = true;
795                               }
796                           }
797                         else if (decl)
798                           {
799                             error ("an indirect edge with unknown callee "
800                                    "corresponding to a call_stmt with "
801                                    "a known declaration:");
802                             error_found = true;
803                             cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
804                           }
805                         e->aux = (void *)1;
806                       }
807                     else if (decl)
808                       {
809                         error ("missing callgraph edge for call stmt:");
810                         cgraph_debug_gimple_stmt (this_cfun, stmt);
811                         error_found = true;
812                       }
813                   }
814               }
815           pointer_set_destroy (visited_nodes);
816         }
817       else
818         /* No CFG available?!  */
819         gcc_unreachable ();
820
821       for (e = node->callees; e; e = e->next_callee)
822         {
823           if (!e->aux)
824             {
825               error ("edge %s->%s has no corresponding call_stmt",
826                      identifier_to_locale (cgraph_node_name (e->caller)),
827                      identifier_to_locale (cgraph_node_name (e->callee)));
828               cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
829               error_found = true;
830             }
831           e->aux = 0;
832         }
833       for (e = node->indirect_calls; e; e = e->next_callee)
834         {
835           if (!e->aux)
836             {
837               error ("an indirect edge from %s has no corresponding call_stmt",
838                      identifier_to_locale (cgraph_node_name (e->caller)));
839               cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
840               error_found = true;
841             }
842           e->aux = 0;
843         }
844     }
845   if (error_found)
846     {
847       dump_cgraph_node (stderr, node);
848       internal_error ("verify_cgraph_node failed");
849     }
850   timevar_pop (TV_CGRAPH_VERIFY);
851 }
852
853 /* Verify whole cgraph structure.  */
854 DEBUG_FUNCTION void
855 verify_cgraph (void)
856 {
857   struct cgraph_node *node;
858
859   if (seen_error ())
860     return;
861
862   FOR_EACH_FUNCTION (node)
863     verify_cgraph_node (node);
864 }
865
866 /* Output all asm statements we have stored up to be output.  */
867
868 static void
869 cgraph_output_pending_asms (void)
870 {
871   struct cgraph_asm_node *can;
872
873   if (seen_error ())
874     return;
875
876   for (can = cgraph_asm_nodes; can; can = can->next)
877     assemble_asm (can->asm_str);
878   cgraph_asm_nodes = NULL;
879 }
880
881 /* Analyze the function scheduled to be output.  */
882 void
883 cgraph_analyze_function (struct cgraph_node *node)
884 {
885   tree save = current_function_decl;
886   tree decl = node->symbol.decl;
887
888   if (node->alias && node->thunk.alias)
889     {
890       struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias);
891       struct cgraph_node *n;
892
893       for (n = tgt; n && n->alias;
894            n = n->analyzed ? cgraph_alias_aliased_node (n) : NULL)
895         if (n == node)
896           {
897             error ("function %q+D part of alias cycle", node->symbol.decl);
898             node->alias = false;
899             return;
900           }
901       if (!VEC_length (ipa_ref_t, node->symbol.ref_list.references))
902         ipa_record_reference ((symtab_node)node, (symtab_node)tgt,
903                               IPA_REF_ALIAS, NULL);
904       if (node->same_body_alias)
905         { 
906           DECL_VIRTUAL_P (node->symbol.decl) = DECL_VIRTUAL_P (node->thunk.alias);
907           DECL_DECLARED_INLINE_P (node->symbol.decl)
908              = DECL_DECLARED_INLINE_P (node->thunk.alias);
909           DECL_DISREGARD_INLINE_LIMITS (node->symbol.decl)
910              = DECL_DISREGARD_INLINE_LIMITS (node->thunk.alias);
911         }
912
913       /* Fixup visibility nonsences C++ frontend produce on same body aliases.  */
914       if (TREE_PUBLIC (node->symbol.decl) && node->same_body_alias)
915         {
916           DECL_EXTERNAL (node->symbol.decl) = DECL_EXTERNAL (node->thunk.alias);
917           if (DECL_ONE_ONLY (node->thunk.alias))
918             {
919               DECL_COMDAT (node->symbol.decl) = DECL_COMDAT (node->thunk.alias);
920               DECL_COMDAT_GROUP (node->symbol.decl) = DECL_COMDAT_GROUP (node->thunk.alias);
921               if (DECL_ONE_ONLY (node->thunk.alias) && !node->symbol.same_comdat_group)
922                 {
923                   struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias);
924                   node->symbol.same_comdat_group = (symtab_node)tgt;
925                   if (!tgt->symbol.same_comdat_group)
926                     tgt->symbol.same_comdat_group = (symtab_node)node;
927                   else
928                     {
929                       symtab_node n;
930                       for (n = tgt->symbol.same_comdat_group;
931                            n->symbol.same_comdat_group != (symtab_node)tgt;
932                            n = n->symbol.same_comdat_group)
933                         ;
934                       n->symbol.same_comdat_group = (symtab_node)node;
935                     }
936                 }
937             }
938         }
939       if (node->symbol.address_taken)
940         cgraph_mark_address_taken_node (cgraph_alias_aliased_node (node));
941     }
942   else if (node->thunk.thunk_p)
943     {
944       cgraph_create_edge (node, cgraph_get_node (node->thunk.alias),
945                           NULL, 0, CGRAPH_FREQ_BASE);
946     }
947   else
948     {
949       current_function_decl = decl;
950       push_cfun (DECL_STRUCT_FUNCTION (decl));
951
952       assign_assembler_name_if_neeeded (node->symbol.decl);
953
954       /* Make sure to gimplify bodies only once.  During analyzing a
955          function we lower it, which will require gimplified nested
956          functions, so we can end up here with an already gimplified
957          body.  */
958       if (!gimple_body (decl))
959         gimplify_function_tree (decl);
960       dump_function (TDI_generic, decl);
961
962       /* Lower the function.  */
963       if (!node->lowered)
964         {
965           if (node->nested)
966             lower_nested_functions (node->symbol.decl);
967           gcc_assert (!node->nested);
968
969           gimple_register_cfg_hooks ();
970           bitmap_obstack_initialize (NULL);
971           execute_pass_list (all_lowering_passes);
972           free_dominance_info (CDI_POST_DOMINATORS);
973           free_dominance_info (CDI_DOMINATORS);
974           compact_blocks ();
975           bitmap_obstack_release (NULL);
976           node->lowered = true;
977         }
978
979       pop_cfun ();
980     }
981   node->analyzed = true;
982
983   current_function_decl = save;
984 }
985
986 /* C++ frontend produce same body aliases all over the place, even before PCH
987    gets streamed out. It relies on us linking the aliases with their function
988    in order to do the fixups, but ipa-ref is not PCH safe.  Consequentely we
989    first produce aliases without links, but once C++ FE is sure he won't sream
990    PCH we build the links via this function.  */
991
992 void
993 cgraph_process_same_body_aliases (void)
994 {
995   struct cgraph_node *node;
996   FOR_EACH_FUNCTION (node)
997     if (node->same_body_alias
998         && !VEC_length (ipa_ref_t, node->symbol.ref_list.references))
999       {
1000         struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias);
1001         ipa_record_reference ((symtab_node)node, (symtab_node)tgt,
1002                               IPA_REF_ALIAS, NULL);
1003       }
1004   same_body_aliases_done = true;
1005 }
1006
1007 /* Process attributes common for vars and functions.  */
1008
1009 static void
1010 process_common_attributes (tree decl)
1011 {
1012   tree weakref = lookup_attribute ("weakref", DECL_ATTRIBUTES (decl));
1013
1014   if (weakref && !lookup_attribute ("alias", DECL_ATTRIBUTES (decl)))
1015     {
1016       warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
1017                   "%<weakref%> attribute should be accompanied with"
1018                   " an %<alias%> attribute");
1019       DECL_WEAK (decl) = 0;
1020       DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
1021                                                  DECL_ATTRIBUTES (decl));
1022     }
1023 }
1024
1025 /* Look for externally_visible and used attributes and mark cgraph nodes
1026    accordingly.
1027
1028    We cannot mark the nodes at the point the attributes are processed (in
1029    handle_*_attribute) because the copy of the declarations available at that
1030    point may not be canonical.  For example, in:
1031
1032     void f();
1033     void f() __attribute__((used));
1034
1035    the declaration we see in handle_used_attribute will be the second
1036    declaration -- but the front end will subsequently merge that declaration
1037    with the original declaration and discard the second declaration.
1038
1039    Furthermore, we can't mark these nodes in cgraph_finalize_function because:
1040
1041     void f() {}
1042     void f() __attribute__((externally_visible));
1043
1044    is valid.
1045
1046    So, we walk the nodes at the end of the translation unit, applying the
1047    attributes at that point.  */
1048
1049 static void
1050 process_function_and_variable_attributes (struct cgraph_node *first,
1051                                           struct varpool_node *first_var)
1052 {
1053   struct cgraph_node *node;
1054   struct varpool_node *vnode;
1055
1056   for (node = cgraph_first_function (); node != first;
1057        node = cgraph_next_function (node))
1058     {
1059       tree decl = node->symbol.decl;
1060       if (DECL_PRESERVE_P (decl))
1061         cgraph_mark_force_output_node (node);
1062       else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
1063         {
1064           if (! TREE_PUBLIC (node->symbol.decl))
1065             warning_at (DECL_SOURCE_LOCATION (node->symbol.decl), OPT_Wattributes,
1066                         "%<externally_visible%>"
1067                         " attribute have effect only on public objects");
1068         }
1069       if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
1070           && (node->local.finalized && !node->alias))
1071         {
1072           warning_at (DECL_SOURCE_LOCATION (node->symbol.decl), OPT_Wattributes,
1073                       "%<weakref%> attribute ignored"
1074                       " because function is defined");
1075           DECL_WEAK (decl) = 0;
1076           DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
1077                                                      DECL_ATTRIBUTES (decl));
1078         }
1079
1080       if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl))
1081           && !DECL_DECLARED_INLINE_P (decl)
1082           /* redefining extern inline function makes it DECL_UNINLINABLE.  */
1083           && !DECL_UNINLINABLE (decl))
1084         warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
1085                     "always_inline function might not be inlinable");
1086      
1087       process_common_attributes (decl);
1088     }
1089   for (vnode = varpool_first_variable (); vnode != first_var;
1090        vnode = varpool_next_variable (vnode))
1091     {
1092       tree decl = vnode->symbol.decl;
1093       if (DECL_PRESERVE_P (decl))
1094         vnode->symbol.force_output = true;
1095       else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
1096         {
1097           if (! TREE_PUBLIC (vnode->symbol.decl))
1098             warning_at (DECL_SOURCE_LOCATION (vnode->symbol.decl), OPT_Wattributes,
1099                         "%<externally_visible%>"
1100                         " attribute have effect only on public objects");
1101         }
1102       if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
1103           && vnode->finalized
1104           && DECL_INITIAL (decl))
1105         {
1106           warning_at (DECL_SOURCE_LOCATION (vnode->symbol.decl), OPT_Wattributes,
1107                       "%<weakref%> attribute ignored"
1108                       " because variable is initialized");
1109           DECL_WEAK (decl) = 0;
1110           DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
1111                                                       DECL_ATTRIBUTES (decl));
1112         }
1113       process_common_attributes (decl);
1114     }
1115 }
1116
1117 /* Return true when there are references to NODE.  */
1118
1119 static bool
1120 referred_to_p (symtab_node node)
1121 {
1122   int i;
1123   struct ipa_ref *ref;
1124
1125   for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list, i, ref);
1126        i++)
1127     return true;
1128   if (symtab_function_p (node) && cgraph (node)->callers)
1129     return true;
1130   return false;
1131 }
1132
1133 /* Mark DECL as finalized.  By finalizing the declaration, frontend instruct the
1134    middle end to output the variable to asm file, if needed or externally
1135    visible.  */
1136
1137 void
1138 varpool_finalize_decl (tree decl)
1139 {
1140   struct varpool_node *node = varpool_node (decl);
1141
1142   gcc_assert (TREE_STATIC (decl));
1143
1144   if (node->finalized)
1145     return;
1146   notice_global_symbol (decl);
1147   node->finalized = true;
1148   if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
1149       /* Traditionally we do not eliminate static variables when not
1150          optimizing and when not doing toplevel reoder.  */
1151       || (!flag_toplevel_reorder && !DECL_COMDAT (node->symbol.decl)
1152           && !DECL_ARTIFICIAL (node->symbol.decl)))
1153     node->symbol.force_output = true;
1154
1155   if (cgraph_state == CGRAPH_STATE_CONSTRUCTION
1156       && (decide_is_variable_needed (node, decl)
1157           || referred_to_p ((symtab_node)node)))
1158     enqueue_node ((symtab_node)node);
1159   if (cgraph_state >= CGRAPH_STATE_IPA_SSA)
1160     varpool_analyze_node (node);
1161 }
1162
1163 /* Discover all functions and variables that are trivially needed, analyze
1164    them as well as all functions and variables referred by them  */
1165
1166 static void
1167 cgraph_analyze_functions (void)
1168 {
1169   /* Keep track of already processed nodes when called multiple times for
1170      intermodule optimization.  */
1171   static struct cgraph_node *first_analyzed;
1172   struct cgraph_node *first_handled = first_analyzed;
1173   static struct varpool_node *first_analyzed_var;
1174   struct varpool_node *first_handled_var = first_analyzed_var;
1175
1176   symtab_node node, next;
1177   int i;
1178   struct ipa_ref *ref;
1179   bool changed = true;
1180
1181   bitmap_obstack_initialize (NULL);
1182   cgraph_state = CGRAPH_STATE_CONSTRUCTION;
1183
1184   /* Analysis adds static variables that in turn adds references to new functions.
1185      So we need to iterate the process until it stabilize.  */
1186   while (changed)
1187     {
1188       changed = false;
1189       process_function_and_variable_attributes (first_analyzed,
1190                                                 first_analyzed_var);
1191
1192       /* First identify the trivially needed symbols.  */
1193       for (node = symtab_nodes;
1194            node != (symtab_node)first_analyzed
1195            && node != (symtab_node)first_analyzed_var; node = node->symbol.next)
1196         {
1197           if ((symtab_function_p (node)
1198                && cgraph (node)->local.finalized
1199                && cgraph_decide_is_function_needed (cgraph (node), node->symbol.decl))
1200               || (symtab_variable_p (node)
1201                   && varpool (node)->finalized
1202                   && !DECL_EXTERNAL (node->symbol.decl)
1203                   && decide_is_variable_needed (varpool (node), node->symbol.decl)))
1204             {
1205               enqueue_node (node);
1206               if (!changed && cgraph_dump_file)
1207                 fprintf (cgraph_dump_file, "Trivially needed symbols:");
1208               changed = true;
1209               if (cgraph_dump_file)
1210                 fprintf (cgraph_dump_file, " %s", symtab_node_asm_name (node));
1211             }
1212           if (node == (symtab_node)first_analyzed
1213               || node == (symtab_node)first_analyzed_var)
1214             break;
1215         }
1216       cgraph_process_new_functions ();
1217       first_analyzed_var = varpool_first_variable ();
1218       first_analyzed = cgraph_first_function ();
1219
1220       if (changed && dump_file)
1221         fprintf (cgraph_dump_file, "\n");
1222
1223       /* Lower representation, build callgraph edges and references for all trivially
1224          needed symbols and all symbols referred by them.  */
1225       while (first != (symtab_node)(void *)1)
1226         {
1227           changed = true;
1228           node = first;
1229           first = (symtab_node)first->symbol.aux;
1230           if (symtab_function_p (node) && cgraph (node)->local.finalized)
1231             {
1232               struct cgraph_edge *edge;
1233               struct cgraph_node *cnode;
1234               tree decl;
1235
1236               cnode = cgraph (node);
1237               decl = cnode->symbol.decl;
1238
1239               /* ??? It is possible to create extern inline function and later using
1240                  weak alias attribute to kill its body. See
1241                  gcc.c-torture/compile/20011119-1.c  */
1242               if (!DECL_STRUCT_FUNCTION (decl)
1243                   && (!cnode->alias || !cnode->thunk.alias)
1244                   && !cnode->thunk.thunk_p)
1245                 {
1246                   cgraph_reset_node (cnode);
1247                   cnode->local.redefined_extern_inline = true;
1248                   continue;
1249                 }
1250
1251               if (!cnode->analyzed)
1252                 cgraph_analyze_function (cnode);
1253
1254               for (edge = cnode->callees; edge; edge = edge->next_callee)
1255                 if (edge->callee->local.finalized)
1256                   enqueue_node ((symtab_node)edge->callee);
1257
1258               /* If decl is a clone of an abstract function, mark that abstract
1259                  function so that we don't release its body. The DECL_INITIAL() of that
1260                  abstract function declaration will be later needed to output debug
1261                  info.  */
1262               if (DECL_ABSTRACT_ORIGIN (decl))
1263                 {
1264                   struct cgraph_node *origin_node;
1265                   origin_node = cgraph_get_node (DECL_ABSTRACT_ORIGIN (decl));
1266                   origin_node->abstract_and_needed = true;
1267                 }
1268
1269             }
1270           else if (symtab_variable_p (node)
1271                    && varpool (node)->finalized)
1272             varpool_analyze_node (varpool (node));
1273
1274           if (node->symbol.same_comdat_group)
1275             {
1276               symtab_node next;
1277               for (next = node->symbol.same_comdat_group;
1278                    next != node;
1279                    next = next->symbol.same_comdat_group)
1280                 enqueue_node (next);
1281             }
1282           for (i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list, i, ref); i++)
1283             if ((symtab_function_p (ref->referred) && cgraph (ref->referred)->local.finalized)
1284                 || (symtab_variable_p (ref->referred) && varpool (ref->referred)->finalized))
1285               enqueue_node (ref->referred);
1286           cgraph_process_new_functions ();
1287         }
1288     }
1289
1290   /* Collect entry points to the unit.  */
1291   if (cgraph_dump_file)
1292     {
1293       fprintf (cgraph_dump_file, "\n\nInitial ");
1294       dump_symtab (cgraph_dump_file);
1295     }
1296
1297   if (cgraph_dump_file)
1298     fprintf (cgraph_dump_file, "\nRemoving unused symbols:");
1299
1300   for (node = symtab_nodes;
1301        node != (symtab_node)first_handled
1302        && node != (symtab_node)first_handled_var; node = next)
1303     {
1304       next = node->symbol.next;
1305       if (!node->symbol.aux && !referred_to_p (node))
1306         {
1307           if (cgraph_dump_file)
1308             fprintf (cgraph_dump_file, " %s", symtab_node_name (node));
1309           symtab_remove_node (node);
1310           continue;
1311         }
1312       if (symtab_function_p (node))
1313         {
1314           tree decl = node->symbol.decl;
1315           struct cgraph_node *cnode = cgraph (node);
1316
1317           if (cnode->local.finalized && !gimple_has_body_p (decl)
1318               && (!cnode->alias || !cnode->thunk.alias)
1319               && !cnode->thunk.thunk_p)
1320             cgraph_reset_node (cnode);
1321
1322           gcc_assert (!cnode->local.finalized || cnode->thunk.thunk_p
1323                       || cnode->alias
1324                       || gimple_has_body_p (decl));
1325           gcc_assert (cnode->analyzed == cnode->local.finalized);
1326         }
1327       node->symbol.aux = NULL;
1328     }
1329   first_analyzed = cgraph_first_function ();
1330   first_analyzed_var = varpool_first_variable ();
1331   if (cgraph_dump_file)
1332     {
1333       fprintf (cgraph_dump_file, "\n\nReclaimed ");
1334       dump_symtab (cgraph_dump_file);
1335     }
1336   bitmap_obstack_release (NULL);
1337   ggc_collect ();
1338 }
1339
1340 /* Translate the ugly representation of aliases as alias pairs into nice
1341    representation in callgraph.  We don't handle all cases yet,
1342    unforutnately.  */
1343
1344 static void
1345 handle_alias_pairs (void)
1346 {
1347   alias_pair *p;
1348   unsigned i;
1349   struct cgraph_node *target_node;
1350   struct cgraph_node *src_node;
1351   struct varpool_node *target_vnode;
1352   
1353   for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p);)
1354     {
1355       if (TREE_CODE (p->decl) == FUNCTION_DECL
1356           && (target_node = cgraph_node_for_asm (p->target)) != NULL)
1357         {
1358           src_node = cgraph_get_node (p->decl);
1359           if (src_node && src_node->local.finalized)
1360             cgraph_reset_node (src_node);
1361           /* Normally EXTERNAL flag is used to mark external inlines,
1362              however for aliases it seems to be allowed to use it w/o
1363              any meaning. See gcc.dg/attr-alias-3.c  
1364              However for weakref we insist on EXTERNAL flag being set.
1365              See gcc.dg/attr-alias-5.c  */
1366           if (DECL_EXTERNAL (p->decl))
1367             DECL_EXTERNAL (p->decl)
1368               = lookup_attribute ("weakref",
1369                                   DECL_ATTRIBUTES (p->decl)) != NULL;
1370           cgraph_create_function_alias (p->decl, target_node->symbol.decl);
1371           VEC_unordered_remove (alias_pair, alias_pairs, i);
1372         }
1373       else if (TREE_CODE (p->decl) == VAR_DECL
1374                && (target_vnode = varpool_node_for_asm (p->target)) != NULL)
1375         {
1376           /* Normally EXTERNAL flag is used to mark external inlines,
1377              however for aliases it seems to be allowed to use it w/o
1378              any meaning. See gcc.dg/attr-alias-3.c  
1379              However for weakref we insist on EXTERNAL flag being set.
1380              See gcc.dg/attr-alias-5.c  */
1381           if (DECL_EXTERNAL (p->decl))
1382             DECL_EXTERNAL (p->decl)
1383               = lookup_attribute ("weakref",
1384                                   DECL_ATTRIBUTES (p->decl)) != NULL;
1385           varpool_create_variable_alias (p->decl, target_vnode->symbol.decl);
1386           VEC_unordered_remove (alias_pair, alias_pairs, i);
1387         }
1388       /* Weakrefs with target not defined in current unit are easy to handle; they
1389          behave just as external variables except we need to note the alias flag
1390          to later output the weakref pseudo op into asm file.  */
1391       else if (lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL
1392                && (TREE_CODE (p->decl) == FUNCTION_DECL
1393                    ? (varpool_node_for_asm (p->target) == NULL)
1394                    : (cgraph_node_for_asm (p->target) == NULL)))
1395         {
1396           if (TREE_CODE (p->decl) == FUNCTION_DECL)
1397             cgraph_get_create_node (p->decl)->alias = true;
1398           else
1399             varpool_get_node (p->decl)->alias = true;
1400           DECL_EXTERNAL (p->decl) = 1;
1401           VEC_unordered_remove (alias_pair, alias_pairs, i);
1402         }
1403       else
1404         {
1405           if (dump_file)
1406             fprintf (dump_file, "Unhandled alias %s->%s\n",
1407                      IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (p->decl)),
1408                      IDENTIFIER_POINTER (p->target));
1409
1410           i++;
1411         }
1412     }
1413 }
1414
1415
1416 /* Figure out what functions we want to assemble.  */
1417
1418 static void
1419 cgraph_mark_functions_to_output (void)
1420 {
1421   struct cgraph_node *node;
1422 #ifdef ENABLE_CHECKING
1423   bool check_same_comdat_groups = false;
1424
1425   FOR_EACH_FUNCTION (node)
1426     gcc_assert (!node->process);
1427 #endif
1428
1429   FOR_EACH_FUNCTION (node)
1430     {
1431       tree decl = node->symbol.decl;
1432       struct cgraph_edge *e;
1433
1434       gcc_assert (!node->process || node->symbol.same_comdat_group);
1435       if (node->process)
1436         continue;
1437
1438       for (e = node->callers; e; e = e->next_caller)
1439         if (e->inline_failed)
1440           break;
1441
1442       /* We need to output all local functions that are used and not
1443          always inlined, as well as those that are reachable from
1444          outside the current compilation unit.  */
1445       if (node->analyzed
1446           && !node->thunk.thunk_p
1447           && !node->alias
1448           && !node->global.inlined_to
1449           && !TREE_ASM_WRITTEN (decl)
1450           && !DECL_EXTERNAL (decl))
1451         {
1452           node->process = 1;
1453           if (node->symbol.same_comdat_group)
1454             {
1455               struct cgraph_node *next;
1456               for (next = cgraph (node->symbol.same_comdat_group);
1457                    next != node;
1458                    next = cgraph (next->symbol.same_comdat_group))
1459                 if (!next->thunk.thunk_p && !next->alias)
1460                   next->process = 1;
1461             }
1462         }
1463       else if (node->symbol.same_comdat_group)
1464         {
1465 #ifdef ENABLE_CHECKING
1466           check_same_comdat_groups = true;
1467 #endif
1468         }
1469       else
1470         {
1471           /* We should've reclaimed all functions that are not needed.  */
1472 #ifdef ENABLE_CHECKING
1473           if (!node->global.inlined_to
1474               && gimple_has_body_p (decl)
1475               /* FIXME: in ltrans unit when offline copy is outside partition but inline copies
1476                  are inside partition, we can end up not removing the body since we no longer
1477                  have analyzed node pointing to it.  */
1478               && !node->symbol.in_other_partition
1479               && !node->alias
1480               && !DECL_EXTERNAL (decl))
1481             {
1482               dump_cgraph_node (stderr, node);
1483               internal_error ("failed to reclaim unneeded function");
1484             }
1485 #endif
1486           gcc_assert (node->global.inlined_to
1487                       || !gimple_has_body_p (decl)
1488                       || node->symbol.in_other_partition
1489                       || DECL_EXTERNAL (decl));
1490
1491         }
1492
1493     }
1494 #ifdef ENABLE_CHECKING
1495   if (check_same_comdat_groups)
1496     FOR_EACH_FUNCTION (node)
1497       if (node->symbol.same_comdat_group && !node->process)
1498         {
1499           tree decl = node->symbol.decl;
1500           if (!node->global.inlined_to
1501               && gimple_has_body_p (decl)
1502               /* FIXME: in an ltrans unit when the offline copy is outside a
1503                  partition but inline copies are inside a partition, we can
1504                  end up not removing the body since we no longer have an
1505                  analyzed node pointing to it.  */
1506               && !node->symbol.in_other_partition
1507               && !DECL_EXTERNAL (decl))
1508             {
1509               dump_cgraph_node (stderr, node);
1510               internal_error ("failed to reclaim unneeded function in same "
1511                               "comdat group");
1512             }
1513         }
1514 #endif
1515 }
1516
1517 /* DECL is FUNCTION_DECL.  Initialize datastructures so DECL is a function
1518    in lowered gimple form.
1519    
1520    Set current_function_decl and cfun to newly constructed empty function body.
1521    return basic block in the function body.  */
1522
1523 static basic_block
1524 init_lowered_empty_function (tree decl)
1525 {
1526   basic_block bb;
1527
1528   current_function_decl = decl;
1529   allocate_struct_function (decl, false);
1530   gimple_register_cfg_hooks ();
1531   init_empty_tree_cfg ();
1532   init_tree_ssa (cfun);
1533   init_ssa_operands ();
1534   cfun->gimple_df->in_ssa_p = true;
1535   DECL_INITIAL (decl) = make_node (BLOCK);
1536
1537   DECL_SAVED_TREE (decl) = error_mark_node;
1538   cfun->curr_properties |=
1539     (PROP_gimple_lcf | PROP_gimple_leh | PROP_cfg | PROP_referenced_vars |
1540      PROP_ssa | PROP_gimple_any);
1541
1542   /* Create BB for body of the function and connect it properly.  */
1543   bb = create_basic_block (NULL, (void *) 0, ENTRY_BLOCK_PTR);
1544   make_edge (ENTRY_BLOCK_PTR, bb, 0);
1545   make_edge (bb, EXIT_BLOCK_PTR, 0);
1546
1547   return bb;
1548 }
1549
1550 /* Adjust PTR by the constant FIXED_OFFSET, and by the vtable
1551    offset indicated by VIRTUAL_OFFSET, if that is
1552    non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and
1553    zero for a result adjusting thunk.  */
1554
1555 static tree
1556 thunk_adjust (gimple_stmt_iterator * bsi,
1557               tree ptr, bool this_adjusting,
1558               HOST_WIDE_INT fixed_offset, tree virtual_offset)
1559 {
1560   gimple stmt;
1561   tree ret;
1562
1563   if (this_adjusting
1564       && fixed_offset != 0)
1565     {
1566       stmt = gimple_build_assign
1567                 (ptr, fold_build_pointer_plus_hwi_loc (input_location,
1568                                                        ptr,
1569                                                        fixed_offset));
1570       gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1571     }
1572
1573   /* If there's a virtual offset, look up that value in the vtable and
1574      adjust the pointer again.  */
1575   if (virtual_offset)
1576     {
1577       tree vtabletmp;
1578       tree vtabletmp2;
1579       tree vtabletmp3;
1580
1581       if (!vtable_entry_type)
1582         {
1583           tree vfunc_type = make_node (FUNCTION_TYPE);
1584           TREE_TYPE (vfunc_type) = integer_type_node;
1585           TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
1586           layout_type (vfunc_type);
1587
1588           vtable_entry_type = build_pointer_type (vfunc_type);
1589         }
1590
1591       vtabletmp =
1592         create_tmp_var (build_pointer_type
1593                         (build_pointer_type (vtable_entry_type)), "vptr");
1594
1595       /* The vptr is always at offset zero in the object.  */
1596       stmt = gimple_build_assign (vtabletmp,
1597                                   build1 (NOP_EXPR, TREE_TYPE (vtabletmp),
1598                                           ptr));
1599       gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1600       mark_symbols_for_renaming (stmt);
1601       find_referenced_vars_in (stmt);
1602
1603       /* Form the vtable address.  */
1604       vtabletmp2 = create_tmp_var (TREE_TYPE (TREE_TYPE (vtabletmp)),
1605                                    "vtableaddr");
1606       stmt = gimple_build_assign (vtabletmp2,
1607                                   build_simple_mem_ref (vtabletmp));
1608       gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1609       mark_symbols_for_renaming (stmt);
1610       find_referenced_vars_in (stmt);
1611
1612       /* Find the entry with the vcall offset.  */
1613       stmt = gimple_build_assign (vtabletmp2,
1614                                   fold_build_pointer_plus_loc (input_location,
1615                                                                vtabletmp2,
1616                                                                virtual_offset));
1617       gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1618
1619       /* Get the offset itself.  */
1620       vtabletmp3 = create_tmp_var (TREE_TYPE (TREE_TYPE (vtabletmp2)),
1621                                    "vcalloffset");
1622       stmt = gimple_build_assign (vtabletmp3,
1623                                   build_simple_mem_ref (vtabletmp2));
1624       gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1625       mark_symbols_for_renaming (stmt);
1626       find_referenced_vars_in (stmt);
1627
1628       /* Adjust the `this' pointer.  */
1629       ptr = fold_build_pointer_plus_loc (input_location, ptr, vtabletmp3);
1630       ptr = force_gimple_operand_gsi (bsi, ptr, true, NULL_TREE, false,
1631                                       GSI_CONTINUE_LINKING);
1632     }
1633
1634   if (!this_adjusting
1635       && fixed_offset != 0)
1636     /* Adjust the pointer by the constant.  */
1637     {
1638       tree ptrtmp;
1639
1640       if (TREE_CODE (ptr) == VAR_DECL)
1641         ptrtmp = ptr;
1642       else
1643         {
1644           ptrtmp = create_tmp_var (TREE_TYPE (ptr), "ptr");
1645           stmt = gimple_build_assign (ptrtmp, ptr);
1646           gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1647           mark_symbols_for_renaming (stmt);
1648           find_referenced_vars_in (stmt);
1649         }
1650       ptr = fold_build_pointer_plus_hwi_loc (input_location,
1651                                              ptrtmp, fixed_offset);
1652     }
1653
1654   /* Emit the statement and gimplify the adjustment expression.  */
1655   ret = create_tmp_var (TREE_TYPE (ptr), "adjusted_this");
1656   stmt = gimple_build_assign (ret, ptr);
1657   mark_symbols_for_renaming (stmt);
1658   find_referenced_vars_in (stmt);
1659   gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1660
1661   return ret;
1662 }
1663
1664 /* Produce assembler for thunk NODE.  */
1665
1666 static void
1667 assemble_thunk (struct cgraph_node *node)
1668 {
1669   bool this_adjusting = node->thunk.this_adjusting;
1670   HOST_WIDE_INT fixed_offset = node->thunk.fixed_offset;
1671   HOST_WIDE_INT virtual_value = node->thunk.virtual_value;
1672   tree virtual_offset = NULL;
1673   tree alias = node->thunk.alias;
1674   tree thunk_fndecl = node->symbol.decl;
1675   tree a = DECL_ARGUMENTS (thunk_fndecl);
1676
1677   current_function_decl = thunk_fndecl;
1678
1679   /* Ensure thunks are emitted in their correct sections.  */
1680   resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
1681
1682   if (this_adjusting
1683       && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
1684                                               virtual_value, alias))
1685     {
1686       const char *fnname;
1687       tree fn_block;
1688       tree restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1689       
1690       DECL_RESULT (thunk_fndecl)
1691         = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl),
1692                       RESULT_DECL, 0, restype);
1693       fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
1694
1695       /* The back end expects DECL_INITIAL to contain a BLOCK, so we
1696          create one.  */
1697       fn_block = make_node (BLOCK);
1698       BLOCK_VARS (fn_block) = a;
1699       DECL_INITIAL (thunk_fndecl) = fn_block;
1700       init_function_start (thunk_fndecl);
1701       cfun->is_thunk = 1;
1702       assemble_start_function (thunk_fndecl, fnname);
1703
1704       targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl,
1705                                        fixed_offset, virtual_value, alias);
1706
1707       assemble_end_function (thunk_fndecl, fnname);
1708       init_insn_lengths ();
1709       free_after_compilation (cfun);
1710       set_cfun (NULL);
1711       TREE_ASM_WRITTEN (thunk_fndecl) = 1;
1712       node->thunk.thunk_p = false;
1713       node->analyzed = false;
1714     }
1715   else
1716     {
1717       tree restype;
1718       basic_block bb, then_bb, else_bb, return_bb;
1719       gimple_stmt_iterator bsi;
1720       int nargs = 0;
1721       tree arg;
1722       int i;
1723       tree resdecl;
1724       tree restmp = NULL;
1725       VEC(tree, heap) *vargs;
1726
1727       gimple call;
1728       gimple ret;
1729
1730       DECL_IGNORED_P (thunk_fndecl) = 1;
1731       bitmap_obstack_initialize (NULL);
1732
1733       if (node->thunk.virtual_offset_p)
1734         virtual_offset = size_int (virtual_value);
1735
1736       /* Build the return declaration for the function.  */
1737       restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1738       if (DECL_RESULT (thunk_fndecl) == NULL_TREE)
1739         {
1740           resdecl = build_decl (input_location, RESULT_DECL, 0, restype);
1741           DECL_ARTIFICIAL (resdecl) = 1;
1742           DECL_IGNORED_P (resdecl) = 1;
1743           DECL_RESULT (thunk_fndecl) = resdecl;
1744         }
1745       else
1746         resdecl = DECL_RESULT (thunk_fndecl);
1747
1748       bb = then_bb = else_bb = return_bb = init_lowered_empty_function (thunk_fndecl);
1749
1750       bsi = gsi_start_bb (bb);
1751
1752       /* Build call to the function being thunked.  */
1753       if (!VOID_TYPE_P (restype))
1754         {
1755           if (!is_gimple_reg_type (restype))
1756             {
1757               restmp = resdecl;
1758               add_local_decl (cfun, restmp);
1759               BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp;
1760             }
1761           else
1762             restmp = create_tmp_var_raw (restype, "retval");
1763         }
1764
1765       for (arg = a; arg; arg = DECL_CHAIN (arg))
1766         nargs++;
1767       vargs = VEC_alloc (tree, heap, nargs);
1768       if (this_adjusting)
1769         VEC_quick_push (tree, vargs,
1770                         thunk_adjust (&bsi,
1771                                       a, 1, fixed_offset,
1772                                       virtual_offset));
1773       else
1774         VEC_quick_push (tree, vargs, a);
1775       for (i = 1, arg = DECL_CHAIN (a); i < nargs; i++, arg = DECL_CHAIN (arg))
1776         VEC_quick_push (tree, vargs, arg);
1777       call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs);
1778       VEC_free (tree, heap, vargs);
1779       gimple_call_set_from_thunk (call, true);
1780       if (restmp)
1781         gimple_call_set_lhs (call, restmp);
1782       gsi_insert_after (&bsi, call, GSI_NEW_STMT);
1783       mark_symbols_for_renaming (call);
1784       find_referenced_vars_in (call);
1785       update_stmt (call);
1786
1787       if (restmp && !this_adjusting)
1788         {
1789           tree true_label = NULL_TREE;
1790
1791           if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE)
1792             {
1793               gimple stmt;
1794               /* If the return type is a pointer, we need to
1795                  protect against NULL.  We know there will be an
1796                  adjustment, because that's why we're emitting a
1797                  thunk.  */
1798               then_bb = create_basic_block (NULL, (void *) 0, bb);
1799               return_bb = create_basic_block (NULL, (void *) 0, then_bb);
1800               else_bb = create_basic_block (NULL, (void *) 0, else_bb);
1801               remove_edge (single_succ_edge (bb));
1802               true_label = gimple_block_label (then_bb);
1803               stmt = gimple_build_cond (NE_EXPR, restmp,
1804                                         build_zero_cst (TREE_TYPE (restmp)),
1805                                         NULL_TREE, NULL_TREE);
1806               gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1807               make_edge (bb, then_bb, EDGE_TRUE_VALUE);
1808               make_edge (bb, else_bb, EDGE_FALSE_VALUE);
1809               make_edge (return_bb, EXIT_BLOCK_PTR, 0);
1810               make_edge (then_bb, return_bb, EDGE_FALLTHRU);
1811               make_edge (else_bb, return_bb, EDGE_FALLTHRU);
1812               bsi = gsi_last_bb (then_bb);
1813             }
1814
1815           restmp = thunk_adjust (&bsi, restmp, /*this_adjusting=*/0,
1816                                  fixed_offset, virtual_offset);
1817           if (true_label)
1818             {
1819               gimple stmt;
1820               bsi = gsi_last_bb (else_bb);
1821               stmt = gimple_build_assign (restmp,
1822                                           build_zero_cst (TREE_TYPE (restmp)));
1823               gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1824               bsi = gsi_last_bb (return_bb);
1825             }
1826         }
1827       else
1828         gimple_call_set_tail (call, true);
1829
1830       /* Build return value.  */
1831       ret = gimple_build_return (restmp);
1832       gsi_insert_after (&bsi, ret, GSI_NEW_STMT);
1833
1834       delete_unreachable_blocks ();
1835       update_ssa (TODO_update_ssa);
1836
1837       /* Since we want to emit the thunk, we explicitly mark its name as
1838          referenced.  */
1839       node->thunk.thunk_p = false;
1840       cgraph_node_remove_callees (node);
1841       cgraph_add_new_function (thunk_fndecl, true);
1842       bitmap_obstack_release (NULL);
1843     }
1844   current_function_decl = NULL;
1845 }
1846
1847
1848
1849 /* Assemble thunks and aliases asociated to NODE.  */
1850
1851 static void
1852 assemble_thunks_and_aliases (struct cgraph_node *node)
1853 {
1854   struct cgraph_edge *e;
1855   int i;
1856   struct ipa_ref *ref;
1857
1858   for (e = node->callers; e;)
1859     if (e->caller->thunk.thunk_p)
1860       {
1861         struct cgraph_node *thunk = e->caller;
1862
1863         e = e->next_caller;
1864         assemble_thunks_and_aliases (thunk);
1865         assemble_thunk (thunk);
1866       }
1867     else
1868       e = e->next_caller;
1869   for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list,
1870                                              i, ref); i++)
1871     if (ref->use == IPA_REF_ALIAS)
1872       {
1873         struct cgraph_node *alias = ipa_ref_referring_node (ref);
1874         bool saved_written = TREE_ASM_WRITTEN (alias->thunk.alias);
1875
1876         /* Force assemble_alias to really output the alias this time instead
1877            of buffering it in same alias pairs.  */
1878         TREE_ASM_WRITTEN (alias->thunk.alias) = 1;
1879         assemble_alias (alias->symbol.decl,
1880                         DECL_ASSEMBLER_NAME (alias->thunk.alias));
1881         assemble_thunks_and_aliases (alias);
1882         TREE_ASM_WRITTEN (alias->thunk.alias) = saved_written;
1883       }
1884 }
1885
1886 /* Perform IPA transforms and all further optimizations and compilation
1887    for FNDECL.  */
1888
1889 static void
1890 tree_rest_of_compilation (struct cgraph_node *node)
1891 {
1892   tree fndecl = node->symbol.decl;
1893   location_t saved_loc;
1894
1895   timevar_push (TV_REST_OF_COMPILATION);
1896
1897   gcc_assert (cgraph_global_info_ready);
1898
1899   /* Initialize the default bitmap obstack.  */
1900   bitmap_obstack_initialize (NULL);
1901
1902   /* Initialize the RTL code for the function.  */
1903   current_function_decl = fndecl;
1904   saved_loc = input_location;
1905   input_location = DECL_SOURCE_LOCATION (fndecl);
1906   init_function_start (fndecl);
1907
1908   gimple_register_cfg_hooks ();
1909
1910   bitmap_obstack_initialize (&reg_obstack); /* FIXME, only at RTL generation*/
1911
1912   execute_all_ipa_transforms ();
1913
1914   /* Perform all tree transforms and optimizations.  */
1915
1916   /* Signal the start of passes.  */
1917   invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START, NULL);
1918
1919   execute_pass_list (all_passes);
1920
1921   /* Signal the end of passes.  */
1922   invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END, NULL);
1923
1924   bitmap_obstack_release (&reg_obstack);
1925
1926   /* Release the default bitmap obstack.  */
1927   bitmap_obstack_release (NULL);
1928
1929   set_cfun (NULL);
1930
1931   /* If requested, warn about function definitions where the function will
1932      return a value (usually of some struct or union type) which itself will
1933      take up a lot of stack space.  */
1934   if (warn_larger_than && !DECL_EXTERNAL (fndecl) && TREE_TYPE (fndecl))
1935     {
1936       tree ret_type = TREE_TYPE (TREE_TYPE (fndecl));
1937
1938       if (ret_type && TYPE_SIZE_UNIT (ret_type)
1939           && TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST
1940           && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type),
1941                                    larger_than_size))
1942         {
1943           unsigned int size_as_int
1944             = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type));
1945
1946           if (compare_tree_int (TYPE_SIZE_UNIT (ret_type), size_as_int) == 0)
1947             warning (OPT_Wlarger_than_, "size of return value of %q+D is %u bytes",
1948                      fndecl, size_as_int);
1949           else
1950             warning (OPT_Wlarger_than_, "size of return value of %q+D is larger than %wd bytes",
1951                      fndecl, larger_than_size);
1952         }
1953     }
1954
1955   gimple_set_body (fndecl, NULL);
1956   if (DECL_STRUCT_FUNCTION (fndecl) == 0
1957       && !cgraph_get_node (fndecl)->origin)
1958     {
1959       /* Stop pointing to the local nodes about to be freed.
1960          But DECL_INITIAL must remain nonzero so we know this
1961          was an actual function definition.
1962          For a nested function, this is done in c_pop_function_context.
1963          If rest_of_compilation set this to 0, leave it 0.  */
1964       if (DECL_INITIAL (fndecl) != 0)
1965         DECL_INITIAL (fndecl) = error_mark_node;
1966     }
1967
1968   input_location = saved_loc;
1969
1970   ggc_collect ();
1971   timevar_pop (TV_REST_OF_COMPILATION);
1972 }
1973
1974 /* Expand function specified by NODE.  */
1975
1976 static void
1977 cgraph_expand_function (struct cgraph_node *node)
1978 {
1979   tree decl = node->symbol.decl;
1980
1981   /* We ought to not compile any inline clones.  */
1982   gcc_assert (!node->global.inlined_to);
1983
1984   announce_function (decl);
1985   node->process = 0;
1986   gcc_assert (node->lowered);
1987
1988   /* Generate RTL for the body of DECL.  */
1989   tree_rest_of_compilation (node);
1990
1991   /* Make sure that BE didn't give up on compiling.  */
1992   gcc_assert (TREE_ASM_WRITTEN (decl));
1993   current_function_decl = NULL;
1994   gcc_assert (!cgraph_preserve_function_body_p (node));
1995
1996   /* It would make a lot more sense to output thunks before function body to get more
1997      forward and lest backwarding jumps.  This is however would need solving problem
1998      with comdats. See PR48668.  Also aliases must come after function itself to
1999      make one pass assemblers, like one on AIX happy.  See PR 50689.
2000      FIXME: Perhaps thunks should be move before function IFF they are not in comdat
2001      groups.  */
2002   assemble_thunks_and_aliases (node);
2003   cgraph_release_function_body (node);
2004   /* Eliminate all call edges.  This is important so the GIMPLE_CALL no longer
2005      points to the dead function body.  */
2006   cgraph_node_remove_callees (node);
2007 }
2008
2009 /* Return true when CALLER_DECL should be inlined into CALLEE_DECL.  */
2010
2011 bool
2012 cgraph_inline_p (struct cgraph_edge *e, cgraph_inline_failed_t *reason)
2013 {
2014   *reason = e->inline_failed;
2015   return !e->inline_failed;
2016 }
2017
2018
2019
2020 /* Expand all functions that must be output.
2021
2022    Attempt to topologically sort the nodes so function is output when
2023    all called functions are already assembled to allow data to be
2024    propagated across the callgraph.  Use a stack to get smaller distance
2025    between a function and its callees (later we may choose to use a more
2026    sophisticated algorithm for function reordering; we will likely want
2027    to use subsections to make the output functions appear in top-down
2028    order).  */
2029
2030 static void
2031 cgraph_expand_all_functions (void)
2032 {
2033   struct cgraph_node *node;
2034   struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
2035   int order_pos, new_order_pos = 0;
2036   int i;
2037
2038   order_pos = ipa_reverse_postorder (order);
2039   gcc_assert (order_pos == cgraph_n_nodes);
2040
2041   /* Garbage collector may remove inline clones we eliminate during
2042      optimization.  So we must be sure to not reference them.  */
2043   for (i = 0; i < order_pos; i++)
2044     if (order[i]->process)
2045       order[new_order_pos++] = order[i];
2046
2047   for (i = new_order_pos - 1; i >= 0; i--)
2048     {
2049       node = order[i];
2050       if (node->process)
2051         {
2052           node->process = 0;
2053           cgraph_expand_function (node);
2054         }
2055     }
2056   cgraph_process_new_functions ();
2057
2058   free (order);
2059
2060 }
2061
2062 /* This is used to sort the node types by the cgraph order number.  */
2063
2064 enum cgraph_order_sort_kind
2065 {
2066   ORDER_UNDEFINED = 0,
2067   ORDER_FUNCTION,
2068   ORDER_VAR,
2069   ORDER_ASM
2070 };
2071
2072 struct cgraph_order_sort
2073 {
2074   enum cgraph_order_sort_kind kind;
2075   union
2076   {
2077     struct cgraph_node *f;
2078     struct varpool_node *v;
2079     struct cgraph_asm_node *a;
2080   } u;
2081 };
2082
2083 /* Output all functions, variables, and asm statements in the order
2084    according to their order fields, which is the order in which they
2085    appeared in the file.  This implements -fno-toplevel-reorder.  In
2086    this mode we may output functions and variables which don't really
2087    need to be output.  */
2088
2089 static void
2090 cgraph_output_in_order (void)
2091 {
2092   int max;
2093   struct cgraph_order_sort *nodes;
2094   int i;
2095   struct cgraph_node *pf;
2096   struct varpool_node *pv;
2097   struct cgraph_asm_node *pa;
2098
2099   max = symtab_order;
2100   nodes = XCNEWVEC (struct cgraph_order_sort, max);
2101
2102   FOR_EACH_DEFINED_FUNCTION (pf)
2103     {
2104       if (pf->process && !pf->thunk.thunk_p && !pf->alias)
2105         {
2106           i = pf->symbol.order;
2107           gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
2108           nodes[i].kind = ORDER_FUNCTION;
2109           nodes[i].u.f = pf;
2110         }
2111     }
2112
2113   FOR_EACH_DEFINED_VARIABLE (pv)
2114     {
2115       i = pv->symbol.order;
2116       gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
2117       nodes[i].kind = ORDER_VAR;
2118       nodes[i].u.v = pv;
2119     }
2120
2121   for (pa = cgraph_asm_nodes; pa; pa = pa->next)
2122     {
2123       i = pa->order;
2124       gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
2125       nodes[i].kind = ORDER_ASM;
2126       nodes[i].u.a = pa;
2127     }
2128
2129   /* In toplevel reorder mode we output all statics; mark them as needed.  */
2130
2131   for (i = 0; i < max; ++i)
2132     if (nodes[i].kind == ORDER_VAR)
2133       varpool_finalize_named_section_flags (nodes[i].u.v);
2134
2135   for (i = 0; i < max; ++i)
2136     {
2137       switch (nodes[i].kind)
2138         {
2139         case ORDER_FUNCTION:
2140           nodes[i].u.f->process = 0;
2141           cgraph_expand_function (nodes[i].u.f);
2142           break;
2143
2144         case ORDER_VAR:
2145           varpool_assemble_decl (nodes[i].u.v);
2146           break;
2147
2148         case ORDER_ASM:
2149           assemble_asm (nodes[i].u.a->asm_str);
2150           break;
2151
2152         case ORDER_UNDEFINED:
2153           break;
2154
2155         default:
2156           gcc_unreachable ();
2157         }
2158     }
2159
2160   cgraph_asm_nodes = NULL;
2161   free (nodes);
2162 }
2163
2164 /* Return true when function body of DECL still needs to be kept around
2165    for later re-use.  */
2166 bool
2167 cgraph_preserve_function_body_p (struct cgraph_node *node)
2168 {
2169   gcc_assert (cgraph_global_info_ready);
2170   gcc_assert (!node->alias && !node->thunk.thunk_p);
2171
2172   /* Look if there is any clone around.  */
2173   if (node->clones)
2174     return true;
2175   return false;
2176 }
2177
2178 static void
2179 ipa_passes (void)
2180 {
2181   set_cfun (NULL);
2182   current_function_decl = NULL;
2183   gimple_register_cfg_hooks ();
2184   bitmap_obstack_initialize (NULL);
2185
2186   invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START, NULL);
2187
2188   if (!in_lto_p)
2189     {
2190       execute_ipa_pass_list (all_small_ipa_passes);
2191       if (seen_error ())
2192         return;
2193     }
2194
2195   /* We never run removal of unreachable nodes after early passes.  This is
2196      because TODO is run before the subpasses.  It is important to remove
2197      the unreachable functions to save works at IPA level and to get LTO
2198      symbol tables right.  */
2199   cgraph_remove_unreachable_nodes (true, cgraph_dump_file);
2200
2201   /* If pass_all_early_optimizations was not scheduled, the state of
2202      the cgraph will not be properly updated.  Update it now.  */
2203   if (cgraph_state < CGRAPH_STATE_IPA_SSA)
2204     cgraph_state = CGRAPH_STATE_IPA_SSA;
2205
2206   if (!in_lto_p)
2207     {
2208       /* Generate coverage variables and constructors.  */
2209       coverage_finish ();
2210
2211       /* Process new functions added.  */
2212       set_cfun (NULL);
2213       current_function_decl = NULL;
2214       cgraph_process_new_functions ();
2215
2216       execute_ipa_summary_passes
2217         ((struct ipa_opt_pass_d *) all_regular_ipa_passes);
2218     }
2219
2220   /* Some targets need to handle LTO assembler output specially.  */
2221   if (flag_generate_lto)
2222     targetm.asm_out.lto_start ();
2223
2224   execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_lto_gen_passes);
2225
2226   if (!in_lto_p)
2227     ipa_write_summaries ();
2228
2229   if (flag_generate_lto)
2230     targetm.asm_out.lto_end ();
2231
2232   if (!flag_ltrans && (in_lto_p || !flag_lto || flag_fat_lto_objects))
2233     execute_ipa_pass_list (all_regular_ipa_passes);
2234   invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END, NULL);
2235
2236   bitmap_obstack_release (NULL);
2237 }
2238
2239
2240 /* Return string alias is alias of.  */
2241
2242 static tree
2243 get_alias_symbol (tree decl)
2244 {
2245   tree alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
2246   return get_identifier (TREE_STRING_POINTER
2247                           (TREE_VALUE (TREE_VALUE (alias))));
2248 }
2249
2250
2251 /* Weakrefs may be associated to external decls and thus not output
2252    at expansion time.  Emit all neccesary aliases.  */
2253
2254 static void
2255 output_weakrefs (void)
2256 {
2257   struct cgraph_node *node;
2258   struct varpool_node *vnode;
2259   FOR_EACH_FUNCTION (node)
2260     if (node->alias && DECL_EXTERNAL (node->symbol.decl)
2261         && !TREE_ASM_WRITTEN (node->symbol.decl)
2262         && lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
2263       assemble_alias (node->symbol.decl,
2264                       node->thunk.alias ? DECL_ASSEMBLER_NAME (node->thunk.alias)
2265                       : get_alias_symbol (node->symbol.decl));
2266   FOR_EACH_VARIABLE (vnode)
2267     if (vnode->alias && DECL_EXTERNAL (vnode->symbol.decl)
2268         && !TREE_ASM_WRITTEN (vnode->symbol.decl)
2269         && lookup_attribute ("weakref", DECL_ATTRIBUTES (vnode->symbol.decl)))
2270       assemble_alias (vnode->symbol.decl,
2271                       vnode->alias_of ? DECL_ASSEMBLER_NAME (vnode->alias_of)
2272                       : get_alias_symbol (vnode->symbol.decl));
2273 }
2274
2275
2276
2277 void
2278 init_cgraph (void)
2279 {
2280   if (!cgraph_dump_file)
2281     cgraph_dump_file = dump_begin (TDI_cgraph, NULL);
2282 }
2283
2284 /* The edges representing the callers of the NEW_VERSION node were
2285    fixed by cgraph_function_versioning (), now the call_expr in their
2286    respective tree code should be updated to call the NEW_VERSION.  */
2287
2288 static void
2289 update_call_expr (struct cgraph_node *new_version)
2290 {
2291   struct cgraph_edge *e;
2292
2293   gcc_assert (new_version);
2294
2295   /* Update the call expr on the edges to call the new version.  */
2296   for (e = new_version->callers; e; e = e->next_caller)
2297     {
2298       struct function *inner_function = DECL_STRUCT_FUNCTION (e->caller->symbol.decl);
2299       gimple_call_set_fndecl (e->call_stmt, new_version->symbol.decl);
2300       maybe_clean_eh_stmt_fn (inner_function, e->call_stmt);
2301     }
2302 }
2303
2304
2305 /* Create a new cgraph node which is the new version of
2306    OLD_VERSION node.  REDIRECT_CALLERS holds the callers
2307    edges which should be redirected to point to
2308    NEW_VERSION.  ALL the callees edges of OLD_VERSION
2309    are cloned to the new version node.  Return the new
2310    version node. 
2311
2312    If non-NULL BLOCK_TO_COPY determine what basic blocks 
2313    was copied to prevent duplications of calls that are dead
2314    in the clone.  */
2315
2316 struct cgraph_node *
2317 cgraph_copy_node_for_versioning (struct cgraph_node *old_version,
2318                                  tree new_decl,
2319                                  VEC(cgraph_edge_p,heap) *redirect_callers,
2320                                  bitmap bbs_to_copy)
2321  {
2322    struct cgraph_node *new_version;
2323    struct cgraph_edge *e;
2324    unsigned i;
2325
2326    gcc_assert (old_version);
2327
2328    new_version = cgraph_create_node (new_decl);
2329
2330    new_version->analyzed = old_version->analyzed;
2331    new_version->local = old_version->local;
2332    new_version->symbol.externally_visible = false;
2333    new_version->local.local = old_version->analyzed;
2334    new_version->global = old_version->global;
2335    new_version->rtl = old_version->rtl;
2336    new_version->count = old_version->count;
2337
2338    for (e = old_version->callees; e; e=e->next_callee)
2339      if (!bbs_to_copy
2340          || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
2341        cgraph_clone_edge (e, new_version, e->call_stmt,
2342                           e->lto_stmt_uid, REG_BR_PROB_BASE,
2343                           CGRAPH_FREQ_BASE,
2344                           true);
2345    for (e = old_version->indirect_calls; e; e=e->next_callee)
2346      if (!bbs_to_copy
2347          || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
2348        cgraph_clone_edge (e, new_version, e->call_stmt,
2349                           e->lto_stmt_uid, REG_BR_PROB_BASE,
2350                           CGRAPH_FREQ_BASE,
2351                           true);
2352    FOR_EACH_VEC_ELT (cgraph_edge_p, redirect_callers, i, e)
2353      {
2354        /* Redirect calls to the old version node to point to its new
2355           version.  */
2356        cgraph_redirect_edge_callee (e, new_version);
2357      }
2358
2359    cgraph_call_node_duplication_hooks (old_version, new_version);
2360
2361    return new_version;
2362  }
2363
2364  /* Perform function versioning.
2365     Function versioning includes copying of the tree and
2366     a callgraph update (creating a new cgraph node and updating
2367     its callees and callers).
2368
2369     REDIRECT_CALLERS varray includes the edges to be redirected
2370     to the new version.
2371
2372     TREE_MAP is a mapping of tree nodes we want to replace with
2373     new ones (according to results of prior analysis).
2374     OLD_VERSION_NODE is the node that is versioned.
2375
2376     If non-NULL ARGS_TO_SKIP determine function parameters to remove
2377     from new version.
2378     If SKIP_RETURN is true, the new version will return void.
2379     If non-NULL BLOCK_TO_COPY determine what basic blocks to copy.
2380     If non_NULL NEW_ENTRY determine new entry BB of the clone.
2381
2382     Return the new version's cgraph node.  */
2383
2384 struct cgraph_node *
2385 cgraph_function_versioning (struct cgraph_node *old_version_node,
2386                             VEC(cgraph_edge_p,heap) *redirect_callers,
2387                             VEC (ipa_replace_map_p,gc)* tree_map,
2388                             bitmap args_to_skip,
2389                             bool skip_return,
2390                             bitmap bbs_to_copy,
2391                             basic_block new_entry_block,
2392                             const char *clone_name)
2393 {
2394   tree old_decl = old_version_node->symbol.decl;
2395   struct cgraph_node *new_version_node = NULL;
2396   tree new_decl;
2397
2398   if (!tree_versionable_function_p (old_decl))
2399     return NULL;
2400
2401   gcc_assert (old_version_node->local.can_change_signature || !args_to_skip);
2402
2403   /* Make a new FUNCTION_DECL tree node for the new version. */
2404   if (!args_to_skip && !skip_return)
2405     new_decl = copy_node (old_decl);
2406   else
2407     new_decl
2408       = build_function_decl_skip_args (old_decl, args_to_skip, skip_return);
2409
2410   /* Generate a new name for the new version. */
2411   DECL_NAME (new_decl) = clone_function_name (old_decl, clone_name);
2412   SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
2413   SET_DECL_RTL (new_decl, NULL);
2414
2415   /* When the old decl was a con-/destructor make sure the clone isn't.  */
2416   DECL_STATIC_CONSTRUCTOR(new_decl) = 0;
2417   DECL_STATIC_DESTRUCTOR(new_decl) = 0;
2418
2419   /* Create the new version's call-graph node.
2420      and update the edges of the new node. */
2421   new_version_node =
2422     cgraph_copy_node_for_versioning (old_version_node, new_decl,
2423                                      redirect_callers, bbs_to_copy);
2424
2425   /* Copy the OLD_VERSION_NODE function tree to the new version.  */
2426   tree_function_versioning (old_decl, new_decl, tree_map, false, args_to_skip,
2427                             skip_return, bbs_to_copy, new_entry_block);
2428
2429   /* Update the new version's properties.
2430      Make The new version visible only within this translation unit.  Make sure
2431      that is not weak also.
2432      ??? We cannot use COMDAT linkage because there is no
2433      ABI support for this.  */
2434   cgraph_make_decl_local (new_version_node->symbol.decl);
2435   DECL_VIRTUAL_P (new_version_node->symbol.decl) = 0;
2436   new_version_node->symbol.externally_visible = 0;
2437   new_version_node->local.local = 1;
2438   new_version_node->lowered = true;
2439
2440   /* Update the call_expr on the edges to call the new version node. */
2441   update_call_expr (new_version_node);
2442
2443   cgraph_call_function_insertion_hooks (new_version_node);
2444   return new_version_node;
2445 }
2446
2447 /* Given virtual clone, turn it into actual clone.  */
2448 static void
2449 cgraph_materialize_clone (struct cgraph_node *node)
2450 {
2451   bitmap_obstack_initialize (NULL);
2452   node->former_clone_of = node->clone_of->symbol.decl;
2453   if (node->clone_of->former_clone_of)
2454     node->former_clone_of = node->clone_of->former_clone_of;
2455   /* Copy the OLD_VERSION_NODE function tree to the new version.  */
2456   tree_function_versioning (node->clone_of->symbol.decl, node->symbol.decl,
2457                             node->clone.tree_map, true,
2458                             node->clone.args_to_skip, false,
2459                             NULL, NULL);
2460   if (cgraph_dump_file)
2461     {
2462       dump_function_to_file (node->clone_of->symbol.decl, cgraph_dump_file, dump_flags);
2463       dump_function_to_file (node->symbol.decl, cgraph_dump_file, dump_flags);
2464     }
2465
2466   /* Function is no longer clone.  */
2467   if (node->next_sibling_clone)
2468     node->next_sibling_clone->prev_sibling_clone = node->prev_sibling_clone;
2469   if (node->prev_sibling_clone)
2470     node->prev_sibling_clone->next_sibling_clone = node->next_sibling_clone;
2471   else
2472     node->clone_of->clones = node->next_sibling_clone;
2473   node->next_sibling_clone = NULL;
2474   node->prev_sibling_clone = NULL;
2475   if (!node->clone_of->analyzed && !node->clone_of->clones)
2476     {
2477       cgraph_release_function_body (node->clone_of);
2478       cgraph_node_remove_callees (node->clone_of);
2479       ipa_remove_all_references (&node->clone_of->symbol.ref_list);
2480     }
2481   node->clone_of = NULL;
2482   bitmap_obstack_release (NULL);
2483 }
2484
2485 /* If necessary, change the function declaration in the call statement
2486    associated with E so that it corresponds to the edge callee.  */
2487
2488 gimple
2489 cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *e)
2490 {
2491   tree decl = gimple_call_fndecl (e->call_stmt);
2492   gimple new_stmt;
2493   gimple_stmt_iterator gsi;
2494 #ifdef ENABLE_CHECKING
2495   struct cgraph_node *node;
2496 #endif
2497
2498   if (e->indirect_unknown_callee
2499       || decl == e->callee->symbol.decl)
2500     return e->call_stmt;
2501
2502 #ifdef ENABLE_CHECKING
2503   if (decl)
2504     {
2505       node = cgraph_get_node (decl);
2506       gcc_assert (!node || !node->clone.combined_args_to_skip);
2507     }
2508 #endif
2509
2510   if (cgraph_dump_file)
2511     {
2512       fprintf (cgraph_dump_file, "updating call of %s/%i -> %s/%i: ",
2513                cgraph_node_name (e->caller), e->caller->uid,
2514                cgraph_node_name (e->callee), e->callee->uid);
2515       print_gimple_stmt (cgraph_dump_file, e->call_stmt, 0, dump_flags);
2516       if (e->callee->clone.combined_args_to_skip)
2517         {
2518           fprintf (cgraph_dump_file, " combined args to skip: ");
2519           dump_bitmap (cgraph_dump_file,
2520                        e->callee->clone.combined_args_to_skip);
2521         }
2522     }
2523
2524   if (e->callee->clone.combined_args_to_skip)
2525     {
2526       int lp_nr;
2527
2528       new_stmt
2529         = gimple_call_copy_skip_args (e->call_stmt,
2530                                       e->callee->clone.combined_args_to_skip);
2531       gimple_call_set_fndecl (new_stmt, e->callee->symbol.decl);
2532
2533       if (gimple_vdef (new_stmt)
2534           && TREE_CODE (gimple_vdef (new_stmt)) == SSA_NAME)
2535         SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt;
2536
2537       gsi = gsi_for_stmt (e->call_stmt);
2538       gsi_replace (&gsi, new_stmt, false);
2539       /* We need to defer cleaning EH info on the new statement to
2540          fixup-cfg.  We may not have dominator information at this point
2541          and thus would end up with unreachable blocks and have no way
2542          to communicate that we need to run CFG cleanup then.  */
2543       lp_nr = lookup_stmt_eh_lp (e->call_stmt);
2544       if (lp_nr != 0)
2545         {
2546           remove_stmt_from_eh_lp (e->call_stmt);
2547           add_stmt_to_eh_lp (new_stmt, lp_nr);
2548         }
2549     }
2550   else
2551     {
2552       new_stmt = e->call_stmt;
2553       gimple_call_set_fndecl (new_stmt, e->callee->symbol.decl);
2554       update_stmt (new_stmt);
2555     }
2556
2557   cgraph_set_call_stmt_including_clones (e->caller, e->call_stmt, new_stmt);
2558
2559   if (cgraph_dump_file)
2560     {
2561       fprintf (cgraph_dump_file, "  updated to:");
2562       print_gimple_stmt (cgraph_dump_file, e->call_stmt, 0, dump_flags);
2563     }
2564   return new_stmt;
2565 }
2566
2567 /* Once all functions from compilation unit are in memory, produce all clones
2568    and update all calls.  We might also do this on demand if we don't want to
2569    bring all functions to memory prior compilation, but current WHOPR
2570    implementation does that and it is is bit easier to keep everything right in
2571    this order.  */
2572 static void
2573 cgraph_materialize_all_clones (void)
2574 {
2575   struct cgraph_node *node;
2576   bool stabilized = false;
2577
2578   if (cgraph_dump_file)
2579     fprintf (cgraph_dump_file, "Materializing clones\n");
2580 #ifdef ENABLE_CHECKING
2581   verify_cgraph ();
2582 #endif
2583
2584   /* We can also do topological order, but number of iterations should be
2585      bounded by number of IPA passes since single IPA pass is probably not
2586      going to create clones of clones it created itself.  */
2587   while (!stabilized)
2588     {
2589       stabilized = true;
2590       FOR_EACH_FUNCTION (node)
2591         {
2592           if (node->clone_of && node->symbol.decl != node->clone_of->symbol.decl
2593               && !gimple_has_body_p (node->symbol.decl))
2594             {
2595               if (gimple_has_body_p (node->clone_of->symbol.decl))
2596                 {
2597                   if (cgraph_dump_file)
2598                     {
2599                       fprintf (cgraph_dump_file, "cloning %s to %s\n",
2600                                cgraph_node_name (node->clone_of),
2601                                cgraph_node_name (node));
2602                       if (node->clone.tree_map)
2603                         {
2604                           unsigned int i;
2605                           fprintf (cgraph_dump_file, "   replace map: ");
2606                           for (i = 0; i < VEC_length (ipa_replace_map_p,
2607                                                       node->clone.tree_map);
2608                                                       i++)
2609                             {
2610                               struct ipa_replace_map *replace_info;
2611                               replace_info = VEC_index (ipa_replace_map_p,
2612                                                         node->clone.tree_map,
2613                                                         i);
2614                               print_generic_expr (cgraph_dump_file, replace_info->old_tree, 0);
2615                               fprintf (cgraph_dump_file, " -> ");
2616                               print_generic_expr (cgraph_dump_file, replace_info->new_tree, 0);
2617                               fprintf (cgraph_dump_file, "%s%s;",
2618                                        replace_info->replace_p ? "(replace)":"",
2619                                        replace_info->ref_p ? "(ref)":"");
2620                             }
2621                           fprintf (cgraph_dump_file, "\n");
2622                         }
2623                       if (node->clone.args_to_skip)
2624                         {
2625                           fprintf (cgraph_dump_file, "   args_to_skip: ");
2626                           dump_bitmap (cgraph_dump_file, node->clone.args_to_skip);
2627                         }
2628                       if (node->clone.args_to_skip)
2629                         {
2630                           fprintf (cgraph_dump_file, "   combined_args_to_skip:");
2631                           dump_bitmap (cgraph_dump_file, node->clone.combined_args_to_skip);
2632                         }
2633                     }
2634                   cgraph_materialize_clone (node);
2635                   stabilized = false;
2636                 }
2637             }
2638         }
2639     }
2640   FOR_EACH_FUNCTION (node)
2641     if (!node->analyzed && node->callees)
2642       cgraph_node_remove_callees (node);
2643   if (cgraph_dump_file)
2644     fprintf (cgraph_dump_file, "Materialization Call site updates done.\n");
2645 #ifdef ENABLE_CHECKING
2646   verify_cgraph ();
2647 #endif
2648   cgraph_remove_unreachable_nodes (false, cgraph_dump_file);
2649 }
2650
2651
2652 /* Perform simple optimizations based on callgraph.  */
2653
2654 void
2655 cgraph_optimize (void)
2656 {
2657   if (seen_error ())
2658     return;
2659
2660 #ifdef ENABLE_CHECKING
2661   verify_symtab ();
2662 #endif
2663
2664   timevar_push (TV_CGRAPHOPT);
2665   if (pre_ipa_mem_report)
2666     {
2667       fprintf (stderr, "Memory consumption before IPA\n");
2668       dump_memory_report (false);
2669     }
2670   if (!quiet_flag)
2671     fprintf (stderr, "Performing interprocedural optimizations\n");
2672   cgraph_state = CGRAPH_STATE_IPA;
2673
2674   /* Don't run the IPA passes if there was any error or sorry messages.  */
2675   if (!seen_error ())
2676     ipa_passes ();
2677
2678   /* Do nothing else if any IPA pass found errors or if we are just streaming LTO.  */
2679   if (seen_error ()
2680       || (!in_lto_p && flag_lto && !flag_fat_lto_objects))
2681     {
2682       timevar_pop (TV_CGRAPHOPT);
2683       return;
2684     }
2685
2686   /* This pass remove bodies of extern inline functions we never inlined.
2687      Do this later so other IPA passes see what is really going on.  */
2688   cgraph_remove_unreachable_nodes (false, dump_file);
2689   cgraph_global_info_ready = true;
2690   if (cgraph_dump_file)
2691     {
2692       fprintf (cgraph_dump_file, "Optimized ");
2693       dump_symtab (cgraph_dump_file);
2694     }
2695   if (post_ipa_mem_report)
2696     {
2697       fprintf (stderr, "Memory consumption after IPA\n");
2698       dump_memory_report (false);
2699     }
2700   timevar_pop (TV_CGRAPHOPT);
2701
2702   /* Output everything.  */
2703   (*debug_hooks->assembly_start) ();
2704   if (!quiet_flag)
2705     fprintf (stderr, "Assembling functions:\n");
2706 #ifdef ENABLE_CHECKING
2707   verify_symtab ();
2708 #endif
2709
2710   cgraph_materialize_all_clones ();
2711   bitmap_obstack_initialize (NULL);
2712   execute_ipa_pass_list (all_late_ipa_passes);
2713   cgraph_remove_unreachable_nodes (true, dump_file);
2714 #ifdef ENABLE_CHECKING
2715   verify_symtab ();
2716 #endif
2717   bitmap_obstack_release (NULL);
2718   cgraph_mark_functions_to_output ();
2719   output_weakrefs ();
2720
2721   cgraph_state = CGRAPH_STATE_EXPANSION;
2722   if (!flag_toplevel_reorder)
2723     cgraph_output_in_order ();
2724   else
2725     {
2726       cgraph_output_pending_asms ();
2727
2728       cgraph_expand_all_functions ();
2729       varpool_remove_unreferenced_decls ();
2730
2731       varpool_assemble_pending_decls ();
2732     }
2733
2734   cgraph_process_new_functions ();
2735   cgraph_state = CGRAPH_STATE_FINISHED;
2736
2737   if (cgraph_dump_file)
2738     {
2739       fprintf (cgraph_dump_file, "\nFinal ");
2740       dump_symtab (cgraph_dump_file);
2741     }
2742 #ifdef ENABLE_CHECKING
2743   verify_symtab ();
2744   /* Double check that all inline clones are gone and that all
2745      function bodies have been released from memory.  */
2746   if (!seen_error ())
2747     {
2748       struct cgraph_node *node;
2749       bool error_found = false;
2750
2751       FOR_EACH_DEFINED_FUNCTION (node)
2752         if (node->global.inlined_to
2753             || gimple_has_body_p (node->symbol.decl))
2754           {
2755             error_found = true;
2756             dump_cgraph_node (stderr, node);
2757           }
2758       if (error_found)
2759         internal_error ("nodes with unreleased memory found");
2760     }
2761 #endif
2762 }
2763
2764
2765 /* Analyze the whole compilation unit once it is parsed completely.  */
2766
2767 void
2768 cgraph_finalize_compilation_unit (void)
2769 {
2770   timevar_push (TV_CGRAPH);
2771
2772   /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE.  */
2773   if (flag_lto)
2774     lto_streamer_hooks_init ();
2775
2776   /* If we're here there's no current function anymore.  Some frontends
2777      are lazy in clearing these.  */
2778   current_function_decl = NULL;
2779   set_cfun (NULL);
2780
2781   /* Do not skip analyzing the functions if there were errors, we
2782      miss diagnostics for following functions otherwise.  */
2783
2784   /* Emit size functions we didn't inline.  */
2785   finalize_size_functions ();
2786
2787   /* Mark alias targets necessary and emit diagnostics.  */
2788   finish_aliases_1 ();
2789   handle_alias_pairs ();
2790
2791   if (!quiet_flag)
2792     {
2793       fprintf (stderr, "\nAnalyzing compilation unit\n");
2794       fflush (stderr);
2795     }
2796
2797   if (flag_dump_passes)
2798     dump_passes ();
2799
2800   /* Gimplify and lower all functions, compute reachability and
2801      remove unreachable nodes.  */
2802   cgraph_analyze_functions ();
2803
2804   /* Mark alias targets necessary and emit diagnostics.  */
2805   finish_aliases_1 ();
2806   handle_alias_pairs ();
2807
2808   /* Gimplify and lower thunks.  */
2809   cgraph_analyze_functions ();
2810
2811   /* Finally drive the pass manager.  */
2812   cgraph_optimize ();
2813
2814   timevar_pop (TV_CGRAPH);
2815 }
2816
2817
2818 #include "gt-cgraphunit.h"