OSDN Git Service

7da68540108db8e867067409b9c11bd82efbd993
[pf3gnuchains/gcc-fork.git] / gcc / cgraphunit.c
1 /* Callgraph based intraprocedural optimizations.
2    Copyright (C) 2003, 2004 Free Software Foundation, Inc.
3    Contributed by Jan Hubicka
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING.  If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA.  */
21
22 /* This module implements main driver of compilation process as well as
23    few basic intraprocedural 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 function.)
36
37     - cgraph_varpool_finalize_variable
38
39       This function has same behavior as the above but is used for static
40       variables.
41
42     - cgraph_finalize_compilation_unit
43
44       This function is called once compilation unit is finalized and it will
45       no longer change.
46
47       In the unit-at-a-time the call-graph construction and local function
48       analysis takes place here.  Bodies of unreachable functions are released
49       to conserve memory usage.
50
51       ???  The compilation unit in this point of view should be compilation
52       unit as defined by the language - for instance C frontend allows multiple
53       compilation units to be parsed at once and it should call function each
54       time parsing is done so we save memory.
55
56     - cgraph_optimize
57
58       In this unit-at-a-time compilation the intra procedural analysis takes
59       place here.  In particular the static functions whose address is never
60       taken are marked as local.  Backend can then use this information to
61       modify calling conventions, do better inlining or similar optimizations.
62
63     - cgraph_assemble_pending_functions
64     - cgraph_varpool_assemble_pending_variables
65
66       In non-unit-at-a-time mode these functions can be used to force compilation
67       of functions or variables that are known to be needed at given stage
68       of compilation
69
70     - cgraph_mark_needed_node
71     - cgraph_varpool_mark_needed_node
72
73       When function or variable is referenced by some hidden way (for instance
74       via assembly code and marked by attribute "used"), the call-graph data structure
75       must be updated accordingly by this function.
76
77     - analyze_expr callback
78
79       This function is responsible for lowering tree nodes not understood by
80       generic code into understandable ones or alternatively marking
81       callgraph and varpool nodes referenced by the as needed.
82
83       ??? On the tree-ssa genericizing should take place here and we will avoid
84       need for these hooks (replacing them by genericizing hook)
85
86     - expand_function callback
87
88       This function is used to expand function and pass it into RTL back-end.
89       Front-end should not make any assumptions about when this function can be
90       called.  In particular cgraph_assemble_pending_functions,
91       cgraph_varpool_assemble_pending_variables, cgraph_finalize_function,
92       cgraph_varpool_finalize_function, cgraph_optimize can cause arbitrarily
93       previously finalized functions to be expanded.
94
95     We implement two compilation modes.
96
97       - unit-at-a-time:  In this mode analyzing of all functions is deferred
98         to cgraph_finalize_compilation_unit and expansion into cgraph_optimize.
99
100         In cgraph_finalize_compilation_unit the reachable functions are
101         analyzed.  During analysis the call-graph edges from reachable
102         functions are constructed and their destinations are marked as
103         reachable.  References to functions and variables are discovered too
104         and variables found to be needed output to the assembly file.  Via
105         mark_referenced call in assemble_variable functions referenced by
106         static variables are noticed too.
107
108         The intra-procedural information is produced and it's existence
109         indicated by global_info_ready.  Once this flag is set it is impossible
110         to change function from !reachable to reachable and thus
111         assemble_variable no longer call mark_referenced.
112
113         Finally the call-graph is topologically sorted and all reachable functions
114         that has not been completely inlined or are not external are output.
115
116         ??? It is possible that reference to function or variable is optimized
117         out.  We can not deal with this nicely because topological order is not
118         suitable for it.  For tree-ssa we may consider another pass doing
119         optimization and re-discovering reachable functions.
120
121         ??? Reorganize code so variables are output very last and only if they
122         really has been referenced by produced code, so we catch more cases
123         where reference has been optimized out.
124
125       - non-unit-at-a-time
126
127         All functions are variables are output as early as possible to conserve
128         memory consumption.  This may or may not result in less memory used but
129         it is still needed for some legacy code that rely on particular ordering
130         of things output from the compiler.
131
132         Varpool data structures are not used and variables are output directly.
133
134         Functions are output early using call of
135         cgraph_assemble_pending_function from cgraph_finalize_function.  The
136         decision on whether function is needed is made more conservative so
137         uninlininable static functions are needed too.  During the call-graph
138         construction the edge destinations are not marked as reachable and it
139         is completely relied upn assemble_variable to mark them.
140         
141      Inlining decision heuristics
142         ??? Move this to separate file after tree-ssa merge.
143
144         We separate inlining decisions from the inliner itself and store it
145         inside callgraph as so called inline plan.  Refer to cgraph.c
146         documentation about particular representation of inline plans in the
147         callgraph
148
149         The implementation of particular heuristics is separated from
150         the rest of code to make it easier to replace it with more complicated
151         implementation in the future.  The rest of inlining code acts as a
152         library aimed to modify the callgraph and verify that the parameters
153         on code size growth fits.
154
155         To mark given call inline, use cgraph_mark_inline function, the
156         verification is performed by cgraph_default_inline_p and
157         cgraph_check_inline_limits.
158
159         The heuristics implements simple knapsack style algorithm ordering
160         all functions by their "profitability" (estimated by code size growth)
161         and inlining them in priority order.
162
163         cgraph_decide_inlining implements heuristics taking whole callgraph
164         into account, while cgraph_decide_inlining_incrementally considers
165         only one function at a time and is used in non-unit-at-a-time mode.  */
166
167
168 /* Additionally this file gathers information about how local statics
169    are used.  This is done in cgraph_characterize_statics.  After the
170    call graph has been built, each function is analyzed to determine
171    which local static variables are either read or written or have
172    their address taken.  Any local static that has its address taken
173    is removed from consideration.  Once the local read and writes
174    are determined, a transitive closure of this information is
175    performed over the call graph to determine the worst case set of
176    side effects of each call.  In a later part of the compiler, these
177    local and global sets are examined to make the call clobbering less
178    traumatic both with respect to aliasing and to code generation.  */
179
180 #include "config.h"
181 #include "system.h"
182 #include "coretypes.h"
183 #include "tm.h"
184 #include "tree.h"
185 #include "rtl.h"
186 #include "tree-flow.h"
187 #include "tree-inline.h"
188 #include "langhooks.h"
189 #include "hashtab.h"
190 #include "toplev.h"
191 #include "flags.h"
192 #include "ggc.h"
193 #include "debug.h"
194 #include "target.h"
195 #include "cgraph.h"
196 #include "diagnostic.h"
197 #include "timevar.h"
198 #include "params.h"
199 #include "fibheap.h"
200 #include "c-common.h"
201 #include "intl.h"
202 #include "function.h"
203 #include "tree-gimple.h"
204
205 #define INSNS_PER_CALL 10
206
207 static void cgraph_expand_all_functions (void);
208 static void cgraph_mark_functions_to_output (void);
209 static void cgraph_expand_function (struct cgraph_node *);
210 static tree record_call_1 (tree *, int *, void *);
211 static void cgraph_mark_local_and_external_functions (void);
212 static bool cgraph_default_inline_p (struct cgraph_node *n);
213 static void cgraph_analyze_function (struct cgraph_node *node);
214 static void cgraph_decide_inlining_incrementally (struct cgraph_node *);
215
216 /* Statistics we collect about inlining algorithm.  */
217 static int ncalls_inlined;
218 static int nfunctions_inlined;
219 static int initial_insns;
220 static int overall_insns;
221
222 /* Records tree nodes seen in cgraph_create_edges.  Simply using
223    walk_tree_without_duplicates doesn't guarantee each node is visited
224    once because it gets a new htab upon each recursive call from
225    record_calls_1.  */
226 static htab_t visited_nodes;
227
228 static FILE *cgraph_dump_file;
229
230 /* These splay trees contain all of the static variables that are
231    being considered by the compilation level alias analysis.  For
232    module_at_a_time compilation, this is the set of static but not
233    public variables.  Any variables that either have their address
234    taken or participate in otherwise unsavory operations are deleted
235    from this list.  */
236 static GTY((param1_is(tree), param2_is(tree)))
237      splay_tree static_vars_to_consider_by_tree;
238
239 /* FIXME -- PROFILE-RESTRUCTURE: change comment from DECL_UID to var-ann. */    
240 /* same as above but indexed by DECL_UID */
241 static GTY((param1_is(int), param2_is(tree)))
242      splay_tree static_vars_to_consider_by_uid;
243
244 /* This bitmap is used to knock out the module static variables whose
245    addresses have been taken and passed around.  This is indexed by
246    uid.  */
247 static bitmap module_statics_escape;
248
249 /* FIXME -- PROFILE-RESTRUCTURE: change comment from DECL_UID to var-ann. */    
250 /* A bit is set for every module static we are considering and is
251    indexed by DECL_UID.  This is ored into the local info when asm
252    code is found that clobbers all memory. */
253 static GTY(()) bitmap all_module_statics;
254
255 /* Holds the value of "memory".  */
256 static tree memory_identifier;
257
258 /* Determine if function DECL is needed.  That is, visible to something
259    either outside this translation unit, something magic in the system
260    configury, or (if not doing unit-at-a-time) to something we havn't
261    seen yet.  */
262
263 static bool
264 decide_is_function_needed (struct cgraph_node *node, tree decl)
265 {
266   tree origin;
267
268   /* If we decided it was needed before, but at the time we didn't have
269      the body of the function available, then it's still needed.  We have
270      to go back and re-check its dependencies now.  */
271   if (node->needed)
272     return true;
273
274   /* Externally visible functions must be output.  The exception is
275      COMDAT functions that must be output only when they are needed.  */
276   if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
277     return true;
278
279   /* Constructors and destructors are reachable from the runtime by
280      some mechanism.  */
281   if (DECL_STATIC_CONSTRUCTOR (decl) || DECL_STATIC_DESTRUCTOR (decl))
282     return true;
283
284   /* If the user told us it is used, then it must be so.  */
285   if (lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
286     return true;
287
288   /* ??? If the assembler name is set by hand, it is possible to assemble
289      the name later after finalizing the function and the fact is noticed
290      in assemble_name then.  This is arguably a bug.  */
291   if (DECL_ASSEMBLER_NAME_SET_P (decl)
292       && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
293     return true;
294
295   if (flag_unit_at_a_time)
296     return false;
297
298   /* If not doing unit at a time, then we'll only defer this function
299      if its marked for inlining.  Otherwise we want to emit it now.  */
300
301   /* "extern inline" functions are never output locally.  */
302   if (DECL_EXTERNAL (decl))
303     return false;
304   /* Nested functions of extern inline function shall not be emit unless
305      we inlined the origin.  */
306   for (origin = decl_function_context (decl); origin;
307        origin = decl_function_context (origin))
308     if (DECL_EXTERNAL (origin))
309       return false;
310   /* We want to emit COMDAT functions only when absolutely necessary.  */
311   if (DECL_COMDAT (decl))
312     return false;
313   if (!DECL_INLINE (decl)
314       || (!node->local.disregard_inline_limits
315           /* When declared inline, defer even the uninlinable functions.
316              This allows them to be eliminated when unused.  */
317           && !DECL_DECLARED_INLINE_P (decl) 
318           && (!node->local.inlinable || !cgraph_default_inline_p (node))))
319     return true;
320
321   return false;
322 }
323
324 /* Debugging function for postorder and inorder code. NOTE is a string
325    that is printed before the nodes are printed.  ORDER is an array of
326    cgraph_nodes that has COUNT useful nodes in it.  */
327
328 static void 
329 print_order (const char * note, struct cgraph_node** order, int count) 
330 {
331   int i;
332   fprintf (cgraph_dump_file, "\n\n ordered call graph: %s\n", note);
333   
334   for (i = count - 1; i >= 0; i--)
335     {
336       struct cgraph_edge *edge;
337
338       fprintf (cgraph_dump_file, "\n  %s<-(", cgraph_node_name (order[i]));
339
340       for (edge = order[i]->callers; edge; edge = edge->next_caller)
341         fprintf (cgraph_dump_file, " %s", cgraph_node_name (edge->caller));
342       fprintf (cgraph_dump_file, ")");
343     }
344   fprintf (cgraph_dump_file, "\n");
345 }
346
347 /* FIXME -- PROFILE-RESTRUCTURE: Remove this function, it becomes a nop. */    
348 /* Convert IN_DECL bitmap which is indexed by DECL_UID to IN_ANN, a
349    bitmap indexed by var_ann (VAR_DECL)->uid.  */
350
351 static void 
352 convert_UIDs_in_bitmap (bitmap in_ann, bitmap in_decl) 
353 {
354   int index;
355   EXECUTE_IF_SET_IN_BITMAP(in_decl, 0, index,
356       {
357         splay_tree_node n = 
358           splay_tree_lookup (static_vars_to_consider_by_uid, index);
359         if (n != NULL) 
360           {
361             tree t = (tree)n->value;
362             var_ann_t va = var_ann (t);
363             if (va) 
364               bitmap_set_bit(in_ann, va->uid);
365           }
366       });
367 }
368
369 /* FIXME -- PROFILE-RESTRUCTURE: Delete all stmts initing *_decl_uid
370    variables.  Add code to create a var_ann for tree node within the
371    cgraph_node and have it point to the newly created
372    static_vars_info.  */
373 /* Create a new static_vars_info structure and place it into
374    cgraph_node, NODE.  INIT_GLOBAL causes the global part of the
375    structure to be initialized.  */
376 static static_vars_info_t
377 new_static_vars_info(struct cgraph_node* node, 
378                      bool init_global)
379 {
380   static_vars_info_t info = ggc_calloc (1, sizeof (struct static_vars_info_d));
381   local_static_vars_info_t l
382     = ggc_calloc (1, sizeof (struct local_static_vars_info_d));
383
384   /* Add the info to the tree's annotation.  */
385   var_ann_t var_ann = get_var_ann(node->decl);
386   node->static_vars_info = info;
387   var_ann->static_vars_info = info;
388
389   info->local = l;
390   l->statics_read_by_decl_uid = BITMAP_GGC_ALLOC ();
391   l->statics_written_by_decl_uid = BITMAP_GGC_ALLOC ();
392
393   if (init_global)
394     {
395       global_static_vars_info_t g
396         = ggc_calloc (1, sizeof (struct global_static_vars_info_d));
397       info->global = g;
398       g->statics_read_by_decl_uid = BITMAP_GGC_ALLOC ();
399       g->statics_written_by_decl_uid = BITMAP_GGC_ALLOC ();
400       g->statics_read_by_ann_uid = BITMAP_GGC_ALLOC ();
401       g->statics_written_by_ann_uid = BITMAP_GGC_ALLOC ();
402       g->statics_not_read_by_decl_uid = BITMAP_GGC_ALLOC ();
403       g->statics_not_written_by_decl_uid = BITMAP_GGC_ALLOC ();
404       g->statics_not_read_by_ann_uid = BITMAP_GGC_ALLOC ();
405       g->statics_not_written_by_ann_uid = BITMAP_GGC_ALLOC ();
406     }
407   return info;
408 }
409
410
411 /* FIXME -- PROFILE-RESTRUCTURE: Remove this function, it becomes a
412    nop. */    
413 /* The bitmaps used to represent the static global variables are
414    indexed by DECL_UID however, this is not used inside of functions
415    to index the ssa variables.  The denser var_ann (VAR_DECL)->uid is
416    used there.  This function is called from
417    tree_dfa:find_referenced_vars after the denser representation is
418    built.  This function invalidates any cached indexes.  */ 
419
420 void
421 cgraph_reset_static_var_maps (void) 
422 {
423   struct cgraph_node *node;
424   
425   for (node = cgraph_nodes; node; node = node->next)
426     {
427       static_vars_info_t info = node->static_vars_info;
428       if (info) 
429         {
430           global_static_vars_info_t g = info->global;
431           if (g->var_anns_valid) 
432             {
433               bitmap_clear (g->statics_read_by_ann_uid);
434               bitmap_clear (g->statics_written_by_ann_uid);
435               bitmap_clear (g->statics_not_read_by_ann_uid);
436               bitmap_clear (g->statics_not_written_by_ann_uid);
437               g->var_anns_valid = false;
438             }
439         }
440       else 
441         /* Handle the case where a cgraph node has been inserted
442            after the analysis.  We know nothing.  */
443         new_static_vars_info(node, true);
444     }
445 }
446
447 /* Get the global static_vars_info structure for the function FN and
448    make sure the ann_uid's bitmaps are properly converted.  */
449  
450 static global_static_vars_info_t
451 get_global_static_vars_info (tree fn) 
452 {
453   global_static_vars_info_t g;
454
455   /* Was not compiled -O2 or higher.  */ 
456   static_vars_info_t info = get_var_ann(fn)->static_vars_info;
457   if (!info)
458     return NULL;
459
460   g = info->global;
461   if (!g->var_anns_valid) 
462     {
463       convert_UIDs_in_bitmap (g->statics_read_by_ann_uid, 
464                               g->statics_read_by_decl_uid);
465       convert_UIDs_in_bitmap (g->statics_written_by_ann_uid, 
466                               g->statics_written_by_decl_uid);
467       convert_UIDs_in_bitmap (g->statics_not_read_by_ann_uid, 
468                               g->statics_not_read_by_decl_uid);
469       convert_UIDs_in_bitmap (g->statics_not_written_by_ann_uid, 
470                               g->statics_not_written_by_decl_uid);
471       g->var_anns_valid = true;
472     }
473   return g;
474 }
475
476 /* Return a bitmap indexed by var_ann (VAR_DECL)->uid for the static
477    variables that are not read during the execution of the function
478    FN.  Returns NULL if no data is available, such as it was not
479    compiled with -O2 or higher.  */
480
481 bitmap 
482 get_global_statics_not_read (tree fn) 
483 {
484   global_static_vars_info_t g = get_global_static_vars_info (fn);
485   if (g) 
486     return g->statics_not_read_by_ann_uid;
487   else
488     return NULL;
489 }
490
491 /* Return a bitmap indexed by var_ann (VAR_DECL)->uid for the static
492    variables that are not written during the execution of the function
493    FN.  Note that variables written may or may not be read during the
494    function call.  Returns NULL if no data is available, such as it
495    was not compiled with -O2 or higher.  */
496
497 bitmap 
498 get_global_statics_not_written (tree fn) 
499 {
500   global_static_vars_info_t g = get_global_static_vars_info (fn);
501   if (g) 
502     return g->statics_not_written_by_ann_uid;
503   else
504     return NULL;
505 }
506
507 /* When not doing unit-at-a-time, output all functions enqueued.
508    Return true when such a functions were found.  */
509
510 bool
511 cgraph_assemble_pending_functions (void)
512 {
513   bool output = false;
514
515   if (flag_unit_at_a_time)
516     return false;
517
518   while (cgraph_nodes_queue)
519     {
520       struct cgraph_node *n = cgraph_nodes_queue;
521
522       cgraph_nodes_queue = cgraph_nodes_queue->next_needed;
523       n->next_needed = NULL;
524       if (!n->global.inlined_to && !DECL_EXTERNAL (n->decl))
525         {
526           cgraph_expand_function (n);
527           output = true;
528         }
529     }
530
531   return output;
532 }
533
534 /* DECL has been parsed.  Take it, queue it, compile it at the whim of the
535    logic in effect.  If NESTED is true, then our caller cannot stand to have
536    the garbage collector run at the moment.  We would need to either create
537    a new GC context, or just not compile right now.  */
538
539 void
540 cgraph_finalize_function (tree decl, bool nested)
541 {
542   struct cgraph_node *node = cgraph_node (decl);
543
544   if (node->local.finalized)
545     {
546       /* As an GCC extension we allow redefinition of the function.  The
547          semantics when both copies of bodies differ is not well defined.
548          We replace the old body with new body so in unit at a time mode
549          we always use new body, while in normal mode we may end up with
550          old body inlined into some functions and new body expanded and
551          inlined in others.
552          
553          ??? It may make more sense to use one body for inlining and other
554          body for expanding the function but this is difficult to do.  */
555
556       /* If node->output is set, then this is a unit-at-a-time compilation
557          and we have already begun whole-unit analysis.  This is *not*
558          testing for whether we've already emitted the function.  That
559          case can be sort-of legitimately seen with real function 
560          redefinition errors.  I would argue that the front end should
561          never present us with such a case, but don't enforce that for now.  */
562       gcc_assert (!node->output);
563
564       /* Reset our data structures so we can analyze the function again.  */
565       memset (&node->local, 0, sizeof (node->local));
566       memset (&node->global, 0, sizeof (node->global));
567       memset (&node->rtl, 0, sizeof (node->rtl));
568       node->analyzed = false;
569       node->local.redefined_extern_inline = true;
570       while (node->callees)
571         cgraph_remove_edge (node->callees);
572
573       /* We may need to re-queue the node for assembling in case
574          we already proceeded it and ignored as not needed.  */
575       if (node->reachable && !flag_unit_at_a_time)
576         {
577           struct cgraph_node *n;
578
579           for (n = cgraph_nodes_queue; n; n = n->next_needed)
580             if (n == node)
581               break;
582           if (!n)
583             node->reachable = 0;
584         }
585     }
586
587   notice_global_symbol (decl);
588   node->decl = decl;
589   node->local.finalized = true;
590   if (node->nested)
591     lower_nested_functions (decl);
592   gcc_assert (!node->nested);
593
594   /* If not unit at a time, then we need to create the call graph
595      now, so that called functions can be queued and emitted now.  */
596   if (!flag_unit_at_a_time)
597     {
598       cgraph_analyze_function (node);
599       cgraph_decide_inlining_incrementally (node);
600     }
601
602   if (decide_is_function_needed (node, decl))
603     cgraph_mark_needed_node (node);
604
605   /* If not unit at a time, go ahead and emit everything we've found
606      to be reachable at this time.  */
607   if (!nested)
608     {
609       if (!cgraph_assemble_pending_functions ())
610         ggc_collect ();
611     }
612
613   /* If we've not yet emitted decl, tell the debug info about it.  */
614   if (!TREE_ASM_WRITTEN (decl))
615     (*debug_hooks->deferred_inline_function) (decl);
616
617   /* Possibly warn about unused parameters.  */
618   if (warn_unused_parameter)
619     do_warn_unused_parameter (decl);
620 }
621
622 /* Walk tree and record all calls.  Called via walk_tree.  */
623 static tree
624 record_call_1 (tree *tp, int *walk_subtrees, void *data)
625 {
626   tree t = *tp;
627
628   switch (TREE_CODE (t))
629     {
630     case VAR_DECL:
631       /* ??? Really, we should mark this decl as *potentially* referenced
632          by this function and re-examine whether the decl is actually used
633          after rtl has been generated.  */
634       if (TREE_STATIC (t))
635         {
636           cgraph_varpool_mark_needed_node (cgraph_varpool_node (t));
637           if (lang_hooks.callgraph.analyze_expr)
638             return lang_hooks.callgraph.analyze_expr (tp, walk_subtrees, 
639                                                       data);
640         }
641       break;
642
643     case ADDR_EXPR:
644       if (flag_unit_at_a_time)
645         {
646           /* Record dereferences to the functions.  This makes the
647              functions reachable unconditionally.  */
648           tree decl = TREE_OPERAND (*tp, 0);
649           if (TREE_CODE (decl) == FUNCTION_DECL)
650             cgraph_mark_needed_node (cgraph_node (decl));
651         }
652       break;
653
654     case CALL_EXPR:
655       {
656         tree decl = get_callee_fndecl (*tp);
657         if (decl && TREE_CODE (decl) == FUNCTION_DECL)
658           {
659             cgraph_create_edge (data, cgraph_node (decl), *tp);
660
661             /* When we see a function call, we don't want to look at the
662                function reference in the ADDR_EXPR that is hanging from
663                the CALL_EXPR we're examining here, because we would
664                conclude incorrectly that the function's address could be
665                taken by something that is not a function call.  So only
666                walk the function parameter list, skip the other subtrees.  */
667
668             walk_tree (&TREE_OPERAND (*tp, 1), record_call_1, data,
669                        visited_nodes);
670             *walk_subtrees = 0;
671           }
672         break;
673       }
674
675     default:
676       /* Save some cycles by not walking types and declaration as we
677          won't find anything useful there anyway.  */
678       if (IS_TYPE_OR_DECL_P (*tp))
679         {
680           *walk_subtrees = 0;
681           break;
682         }
683
684       if ((unsigned int) TREE_CODE (t) >= LAST_AND_UNUSED_TREE_CODE)
685         return lang_hooks.callgraph.analyze_expr (tp, walk_subtrees, data);
686       break;
687     }
688
689   return NULL;
690 }
691
692 /* Create cgraph edges for function calls inside BODY from NODE.  */
693
694 void
695 cgraph_create_edges (struct cgraph_node *node, tree body)
696 {
697   /* The nodes we're interested in are never shared, so walk
698      the tree ignoring duplicates.  */
699   visited_nodes = htab_create (37, htab_hash_pointer,
700                                     htab_eq_pointer, NULL);
701   walk_tree (&body, record_call_1, node, visited_nodes);
702   htab_delete (visited_nodes);
703   visited_nodes = NULL;
704 }
705
706 static bool error_found;
707
708 /* Callbrack of verify_cgraph_node.  Check that all call_exprs have cgraph
709    nodes.  */
710
711 static tree
712 verify_cgraph_node_1 (tree *tp, int *walk_subtrees, void *data)
713 {
714   tree t = *tp;
715   tree decl;
716
717   if (TREE_CODE (t) == CALL_EXPR && (decl = get_callee_fndecl (t)))
718     {
719       struct cgraph_edge *e = cgraph_edge (data, t);
720       if (e)
721         {
722           if (e->aux)
723             {
724               error ("Shared call_expr:");
725               debug_tree (t);
726               error_found = true;
727             }
728           if (e->callee->decl != cgraph_node (decl)->decl)
729             {
730               error ("Edge points to wrong declaration:");
731               debug_tree (e->callee->decl);
732               fprintf (stderr," Instead of:");
733               debug_tree (decl);
734             }
735           e->aux = (void *)1;
736         }
737       else
738         {
739           error ("Missing callgraph edge for call expr:");
740           debug_tree (t);
741           error_found = true;
742         }
743     }
744
745   /* Save some cycles by not walking types and declaration as we
746      won't find anything useful there anyway.  */
747   if (IS_TYPE_OR_DECL_P (*tp))
748     *walk_subtrees = 0;
749
750   return NULL_TREE;
751 }
752
753 /* Verify cgraph nodes of given cgraph node.  */
754 void
755 verify_cgraph_node (struct cgraph_node *node)
756 {
757   struct cgraph_edge *e;
758   struct cgraph_node *main_clone;
759
760   timevar_push (TV_CGRAPH_VERIFY);
761   error_found = false;
762   for (e = node->callees; e; e = e->next_callee)
763     if (e->aux)
764       {
765         error ("Aux field set for edge %s->%s",
766                cgraph_node_name (e->caller), cgraph_node_name (e->callee));
767         error_found = true;
768       }
769   for (e = node->callers; e; e = e->next_caller)
770     {
771       if (!e->inline_failed)
772         {
773           if (node->global.inlined_to
774               != (e->caller->global.inlined_to
775                   ? e->caller->global.inlined_to : e->caller))
776             {
777               error ("Inlined_to pointer is wrong");
778               error_found = true;
779             }
780           if (node->callers->next_caller)
781             {
782               error ("Multiple inline callers");
783               error_found = true;
784             }
785         }
786       else
787         if (node->global.inlined_to)
788           {
789             error ("Inlined_to pointer set for noninline callers");
790             error_found = true;
791           }
792     }
793   if (!node->callers && node->global.inlined_to)
794     {
795       error ("Inlined_to pointer is set but no predecesors found");
796       error_found = true;
797     }
798   if (node->global.inlined_to == node)
799     {
800       error ("Inlined_to pointer reffers to itself");
801       error_found = true;
802     }
803
804   for (main_clone = cgraph_node (node->decl); main_clone;
805        main_clone = main_clone->next_clone)
806     if (main_clone == node)
807       break;
808   if (!node)
809     {
810       error ("Node not found in DECL_ASSEMBLER_NAME hash");
811       error_found = true;
812     }
813   
814   if (node->analyzed
815       && DECL_SAVED_TREE (node->decl) && !TREE_ASM_WRITTEN (node->decl)
816       && (!DECL_EXTERNAL (node->decl) || node->global.inlined_to))
817     {
818       walk_tree_without_duplicates (&DECL_SAVED_TREE (node->decl),
819                                     verify_cgraph_node_1, node);
820       for (e = node->callees; e; e = e->next_callee)
821         {
822           if (!e->aux)
823             {
824               error ("Edge %s->%s has no corresponding call_expr",
825                      cgraph_node_name (e->caller),
826                      cgraph_node_name (e->callee));
827               error_found = true;
828             }
829           e->aux = 0;
830         }
831     }
832   if (error_found)
833     {
834       dump_cgraph_node (stderr, node);
835       internal_error ("verify_cgraph_node failed.");
836     }
837   timevar_pop (TV_CGRAPH_VERIFY);
838 }
839
840 /* Verify whole cgraph structure.  */
841 void
842 verify_cgraph (void)
843 {
844   struct cgraph_node *node;
845
846   if (sorrycount || errorcount)
847     return;
848
849   for (node = cgraph_nodes; node; node = node->next)
850     verify_cgraph_node (node);
851 }
852
853 /* Analyze the function scheduled to be output.  */
854 static void
855 cgraph_analyze_function (struct cgraph_node *node)
856 {
857   tree decl = node->decl;
858   struct cgraph_edge *e;
859
860   current_function_decl = decl;
861
862   /* First kill forward declaration so reverse inlining works properly.  */
863   cgraph_create_edges (node, DECL_SAVED_TREE (decl));
864
865   node->local.inlinable = tree_inlinable_function_p (decl);
866   node->local.self_insns = estimate_num_insns (DECL_SAVED_TREE (decl));
867   if (node->local.inlinable)
868     node->local.disregard_inline_limits
869       = lang_hooks.tree_inlining.disregard_inline_limits (decl);
870   for (e = node->callers; e; e = e->next_caller)
871     {
872       if (node->local.redefined_extern_inline)
873         e->inline_failed = N_("redefined extern inline functions are not "
874                            "considered for inlining");
875       else if (!node->local.inlinable)
876         e->inline_failed = N_("function not inlinable");
877       else
878         e->inline_failed = N_("function not considered for inlining");
879     }
880   if (flag_really_no_inline && !node->local.disregard_inline_limits)
881     node->local.inlinable = 0;
882   /* Inlining characteristics are maintained by the cgraph_mark_inline.  */
883   node->global.insns = node->local.self_insns;
884
885   node->analyzed = true;
886   current_function_decl = NULL;
887 }
888
889 /* Analyze the whole compilation unit once it is parsed completely.  */
890
891 void
892 cgraph_finalize_compilation_unit (void)
893 {
894   struct cgraph_node *node;
895
896   if (!flag_unit_at_a_time)
897     {
898       cgraph_assemble_pending_functions ();
899       return;
900     }
901
902   cgraph_varpool_assemble_pending_decls ();
903   if (!quiet_flag)
904     fprintf (stderr, "\nAnalyzing compilation unit\n");
905
906   timevar_push (TV_CGRAPH);
907   if (cgraph_dump_file)
908     {
909       fprintf (cgraph_dump_file, "Initial entry points:");
910       for (node = cgraph_nodes; node; node = node->next)
911         if (node->needed && DECL_SAVED_TREE (node->decl))
912           fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
913       fprintf (cgraph_dump_file, "\n");
914     }
915
916   /* Propagate reachability flag and lower representation of all reachable
917      functions.  In the future, lowering will introduce new functions and
918      new entry points on the way (by template instantiation and virtual
919      method table generation for instance).  */
920   while (cgraph_nodes_queue)
921     {
922       struct cgraph_edge *edge;
923       tree decl = cgraph_nodes_queue->decl;
924
925       node = cgraph_nodes_queue;
926       cgraph_nodes_queue = cgraph_nodes_queue->next_needed;
927       node->next_needed = NULL;
928
929       /* ??? It is possible to create extern inline function and later using
930          weak alas attribute to kill its body. See
931          gcc.c-torture/compile/20011119-1.c  */
932       if (!DECL_SAVED_TREE (decl))
933         continue;
934
935       gcc_assert (!node->analyzed && node->reachable);
936       gcc_assert (DECL_SAVED_TREE (decl));
937
938       cgraph_analyze_function (node);
939
940       for (edge = node->callees; edge; edge = edge->next_callee)
941         if (!edge->callee->reachable)
942           cgraph_mark_reachable_node (edge->callee);
943
944       cgraph_varpool_assemble_pending_decls ();
945     }
946
947   /* Collect entry points to the unit.  */
948
949   if (cgraph_dump_file)
950     {
951       fprintf (cgraph_dump_file, "Unit entry points:");
952       for (node = cgraph_nodes; node; node = node->next)
953         if (node->needed && DECL_SAVED_TREE (node->decl))
954           fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
955       fprintf (cgraph_dump_file, "\n\nInitial ");
956       dump_cgraph (cgraph_dump_file);
957     }
958
959   if (cgraph_dump_file)
960     fprintf (cgraph_dump_file, "\nReclaiming functions:");
961
962   for (node = cgraph_nodes; node; node = node->next)
963     {
964       tree decl = node->decl;
965
966       if (!node->reachable && DECL_SAVED_TREE (decl))
967         {
968           if (cgraph_dump_file)
969             fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
970           cgraph_remove_node (node);
971         }
972       else
973         node->next_needed = NULL;
974     }
975   if (cgraph_dump_file)
976     {
977       fprintf (cgraph_dump_file, "\n\nReclaimed ");
978       dump_cgraph (cgraph_dump_file);
979     }
980   ggc_collect ();
981   timevar_pop (TV_CGRAPH);
982 }
983 /* Figure out what functions we want to assemble.  */
984
985 static void
986 cgraph_mark_functions_to_output (void)
987 {
988   struct cgraph_node *node;
989
990   for (node = cgraph_nodes; node; node = node->next)
991     {
992       tree decl = node->decl;
993       struct cgraph_edge *e;
994       
995       gcc_assert (!node->output);
996
997       for (e = node->callers; e; e = e->next_caller)
998         if (e->inline_failed)
999           break;
1000
1001       /* We need to output all local functions that are used and not
1002          always inlined, as well as those that are reachable from
1003          outside the current compilation unit.  */
1004       if (DECL_SAVED_TREE (decl)
1005           && !node->global.inlined_to
1006           && (node->needed
1007               || (e && node->reachable))
1008           && !TREE_ASM_WRITTEN (decl)
1009           && !DECL_EXTERNAL (decl))
1010         node->output = 1;
1011       else
1012         {
1013           /* We should've reclaimed all functions that are not needed.  */
1014 #ifdef ENABLE_CHECKING
1015           if (!node->global.inlined_to && DECL_SAVED_TREE (decl)
1016               && !DECL_EXTERNAL (decl))
1017             {
1018               dump_cgraph_node (stderr, node);
1019               internal_error ("failed to reclaim unneeded function");
1020             }
1021 #endif
1022           gcc_assert (node->global.inlined_to || !DECL_SAVED_TREE (decl)
1023                       || DECL_EXTERNAL (decl));
1024
1025         }
1026       
1027     }
1028 }
1029
1030 /* Expand function specified by NODE.  */
1031
1032 static void
1033 cgraph_expand_function (struct cgraph_node *node)
1034 {
1035   tree decl = node->decl;
1036
1037   /* We ought to not compile any inline clones.  */
1038   gcc_assert (!node->global.inlined_to);
1039
1040   if (flag_unit_at_a_time)
1041     announce_function (decl);
1042
1043   /* Generate RTL for the body of DECL.  */
1044   lang_hooks.callgraph.expand_function (decl);
1045
1046   /* Make sure that BE didn't give up on compiling.  */
1047   /* ??? Can happen with nested function of extern inline.  */
1048   gcc_assert (TREE_ASM_WRITTEN (node->decl));
1049
1050   current_function_decl = NULL;
1051   if (!cgraph_preserve_function_body_p (node->decl))
1052     {
1053       DECL_SAVED_TREE (node->decl) = NULL;
1054       DECL_STRUCT_FUNCTION (node->decl) = NULL;
1055       DECL_INITIAL (node->decl) = error_mark_node;
1056       /* Eliminate all call edges.  This is important so the call_expr no longer
1057          points to the dead function body.  */
1058       while (node->callees)
1059         cgraph_remove_edge (node->callees);
1060     }
1061 }
1062
1063 /* Fill array order with all nodes with output flag set in the reverse
1064    topological order.  */
1065
1066 static int
1067 cgraph_postorder (struct cgraph_node **order)
1068 {
1069   struct cgraph_node *node, *node2;
1070   int stack_size = 0;
1071   int order_pos = 0;
1072   struct cgraph_edge *edge, last;
1073
1074   struct cgraph_node **stack =
1075     xcalloc (cgraph_n_nodes, sizeof (struct cgraph_node *));
1076
1077   /* We have to deal with cycles nicely, so use a depth first traversal
1078      output algorithm.  Ignore the fact that some functions won't need
1079      to be output and put them into order as well, so we get dependencies
1080      right through intline functions.  */
1081   for (node = cgraph_nodes; node; node = node->next)
1082     node->aux = NULL;
1083   for (node = cgraph_nodes; node; node = node->next)
1084     if (!node->aux)
1085       {
1086         node2 = node;
1087         if (!node->callers)
1088           node->aux = &last;
1089         else
1090           node->aux = node->callers;
1091         while (node2)
1092           {
1093             while (node2->aux != &last)
1094               {
1095                 edge = node2->aux;
1096                 if (edge->next_caller)
1097                   node2->aux = edge->next_caller;
1098                 else
1099                   node2->aux = &last;
1100                 if (!edge->caller->aux)
1101                   {
1102                     if (!edge->caller->callers)
1103                       edge->caller->aux = &last;
1104                     else
1105                       edge->caller->aux = edge->caller->callers;
1106                     stack[stack_size++] = node2;
1107                     node2 = edge->caller;
1108                     break;
1109                   }
1110               }
1111             if (node2->aux == &last)
1112               {
1113                 order[order_pos++] = node2;
1114                 if (stack_size)
1115                   node2 = stack[--stack_size];
1116                 else
1117                   node2 = NULL;
1118               }
1119           }
1120       }
1121   free (stack);
1122   return order_pos;
1123 }
1124
1125 struct searchc_env {
1126   struct cgraph_node **stack;
1127   int stack_size;
1128   struct cgraph_node **result;
1129   int order_pos;
1130   splay_tree nodes_marked_new;
1131   bool reduce;
1132   int count;
1133 };
1134
1135 struct dfs_info {
1136   int dfn_number;
1137   int low_link;
1138   bool new;
1139   bool on_stack;
1140 };
1141
1142 /* This is an implementation of Tarjan's strongly connected region
1143    finder as reprinted in Aho Hopcraft and Ullman's The Design and
1144    Analysis of Computer Programs (1975) pages 192-193.  This version
1145    has been customized for cgraph_nodes.  The env parameter is because
1146    it is recursive and there are no nested functions here.  This
1147    function should only be called from itself or
1148    cgraph_reduced_inorder.  ENV is a stack env and would be
1149    unnecessary if C had nested functions.  V is the node to start
1150    searching from.  */
1151
1152 static void
1153 searchc (struct searchc_env* env, struct cgraph_node *v) 
1154 {
1155   struct cgraph_edge *edge;
1156   struct dfs_info *v_info = v->aux;
1157   
1158   /* mark node as old */
1159   v_info->new = false;
1160   splay_tree_remove (env->nodes_marked_new, v->uid);
1161   
1162   v_info->dfn_number = env->count;
1163   v_info->low_link = env->count;
1164   env->count++;
1165   env->stack[(env->stack_size)++] = v;
1166   v_info->on_stack = true;
1167   
1168   for (edge = v->callers; edge; edge = edge->next_caller)
1169     {
1170       struct dfs_info * w_info;
1171       struct cgraph_node *w = edge->caller;
1172       /* skip the nodes that we are supposed to ignore */
1173       if (w->aux) 
1174         {
1175           w_info = w->aux;
1176           if (w_info->new) 
1177             {
1178               searchc (env, w);
1179               v_info->low_link =
1180                 (v_info->low_link < w_info->low_link) ?
1181                 v_info->low_link : w_info->low_link;
1182             } 
1183           else 
1184             if ((w_info->dfn_number < v_info->dfn_number) 
1185                 && (w_info->on_stack)) 
1186               v_info->low_link =
1187                 (w_info->dfn_number < v_info->low_link) ?
1188                 w_info->dfn_number : v_info->low_link;
1189         }
1190     }
1191
1192
1193   if (v_info->low_link == v_info->dfn_number) 
1194     {
1195       struct cgraph_node *last = NULL;
1196       struct cgraph_node *x;
1197       struct dfs_info *x_info;
1198       do {
1199         x = env->stack[--(env->stack_size)];
1200         x_info = x->aux;
1201         x_info->on_stack = false;
1202         
1203         if (env->reduce) 
1204           {
1205             x->next_cycle = last;
1206             last = x;
1207           } 
1208         else 
1209           env->result[env->order_pos++] = x;
1210       } 
1211       while (v != x);
1212       if (env->reduce) 
1213         env->result[env->order_pos++] = v;
1214     }
1215 }
1216
1217 /* Topsort the call graph by caller relation.  Put the result in ORDER.
1218
1219    The REDUCE flag is true if you want the cycles reduced to single
1220    nodes.  Only consider nodes that have the output bit set. */
1221
1222 static int
1223 cgraph_reduced_inorder (struct cgraph_node **order, bool reduce)
1224 {
1225   struct cgraph_node *node;
1226   struct searchc_env env;
1227   splay_tree_node result;
1228   env.stack = xcalloc (cgraph_n_nodes, sizeof (struct cgraph_node *));
1229   env.stack_size = 0;
1230   env.result = order;
1231   env.order_pos = 0;
1232   env.nodes_marked_new = splay_tree_new (splay_tree_compare_ints, 0, 0);
1233   env.count = 1;
1234   env.reduce = reduce;
1235   
1236   for (node = cgraph_nodes; node; node = node->next)
1237     if (node->output) 
1238       {
1239         struct dfs_info *info = xcalloc (1, sizeof (struct dfs_info));
1240         info->new = true;
1241         info->on_stack = false;
1242         node->aux = info;
1243         node->next_cycle = NULL;
1244         
1245         splay_tree_insert (env.nodes_marked_new,
1246                            node->uid, (splay_tree_value)node);
1247       } 
1248     else 
1249       node->aux = NULL;
1250   result = splay_tree_min (env.nodes_marked_new);
1251   while (result)
1252     {
1253       node = (struct cgraph_node *)result->value;
1254       searchc (&env, node);
1255       result = splay_tree_min (env.nodes_marked_new);
1256     }
1257   splay_tree_delete (env.nodes_marked_new);
1258   free (env.stack);
1259
1260   for (node = cgraph_nodes; node; node = node->next)
1261     if (node->aux)
1262       {
1263         free (node->aux);
1264         node->aux = NULL;
1265       }
1266   return env.order_pos;
1267 }
1268
1269 /* Perform reachability analysis and reclaim all unreachable nodes.
1270    This function also remove unneeded bodies of extern inline functions
1271    and thus needs to be done only after inlining decisions has been made.  */
1272 static bool
1273 cgraph_remove_unreachable_nodes (void)
1274 {
1275   struct cgraph_node *first = (void *) 1;
1276   struct cgraph_node *node;
1277   bool changed = false;
1278   int insns = 0;
1279
1280 #ifdef ENABLE_CHECKING
1281   verify_cgraph ();
1282 #endif
1283   if (cgraph_dump_file)
1284     fprintf (cgraph_dump_file, "\nReclaiming functions:");
1285 #ifdef ENABLE_CHECKING
1286   for (node = cgraph_nodes; node; node = node->next)
1287     gcc_assert (!node->aux);
1288 #endif
1289   for (node = cgraph_nodes; node; node = node->next)
1290     if (node->needed && !node->global.inlined_to
1291         && (!DECL_EXTERNAL (node->decl) || !node->analyzed))
1292       {
1293         node->aux = first;
1294         first = node;
1295       }
1296     else
1297       gcc_assert (!node->aux);
1298
1299   /* Perform reachability analysis.  As a special case do not consider
1300      extern inline functions not inlined as live because we won't output
1301      them at all.  */
1302   while (first != (void *) 1)
1303     {
1304       struct cgraph_edge *e;
1305       node = first;
1306       first = first->aux;
1307
1308       for (e = node->callees; e; e = e->next_callee)
1309         if (!e->callee->aux
1310             && node->analyzed
1311             && (!e->inline_failed || !e->callee->analyzed
1312                 || !DECL_EXTERNAL (e->callee->decl)))
1313           {
1314             e->callee->aux = first;
1315             first = e->callee;
1316           }
1317     }
1318
1319   /* Remove unreachable nodes.  Extern inline functions need special care;
1320      Unreachable extern inline functions shall be removed.
1321      Reachable extern inline functions we never inlined shall get their bodies
1322      eliminated.
1323      Reachable extern inline functions we sometimes inlined will be turned into
1324      unanalyzed nodes so they look like for true extern functions to the rest
1325      of code.  Body of such functions is released via remove_node once the
1326      inline clones are eliminated.  */
1327   for (node = cgraph_nodes; node; node = node->next)
1328     {
1329       if (!node->aux)
1330         {
1331           int local_insns;
1332           tree decl = node->decl;
1333
1334           node->global.inlined_to = NULL;
1335           if (DECL_STRUCT_FUNCTION (decl))
1336             local_insns = node->local.self_insns;
1337           else
1338             local_insns = 0;
1339           if (cgraph_dump_file)
1340             fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
1341           if (!node->analyzed || !DECL_EXTERNAL (node->decl))
1342             cgraph_remove_node (node);
1343           else
1344             {
1345               struct cgraph_edge *e;
1346
1347               for (e = node->callers; e; e = e->next_caller)
1348                 if (e->caller->aux)
1349                   break;
1350               if (e || node->needed)
1351                 {
1352                   struct cgraph_node *clone;
1353
1354                   for (clone = node->next_clone; clone;
1355                        clone = clone->next_clone)
1356                     if (clone->aux)
1357                       break;
1358                   if (!clone)
1359                     {
1360                       DECL_SAVED_TREE (node->decl) = NULL;
1361                       DECL_STRUCT_FUNCTION (node->decl) = NULL;
1362                       DECL_INITIAL (node->decl) = error_mark_node;
1363                     }
1364                   while (node->callees)
1365                     cgraph_remove_edge (node->callees);
1366                   node->analyzed = false;
1367                 }
1368               else
1369                 cgraph_remove_node (node);
1370             }
1371           if (!DECL_SAVED_TREE (decl))
1372             insns += local_insns;
1373           changed = true;
1374         }
1375     }
1376   for (node = cgraph_nodes; node; node = node->next)
1377     node->aux = NULL;
1378   if (cgraph_dump_file)
1379     fprintf (cgraph_dump_file, "\nReclaimed %i insns", insns);
1380   return changed;
1381 }
1382
1383 /* Estimate size of the function after inlining WHAT into TO.  */
1384
1385 static int
1386 cgraph_estimate_size_after_inlining (int times, struct cgraph_node *to,
1387                                      struct cgraph_node *what)
1388 {
1389   return (what->global.insns - INSNS_PER_CALL) * times + to->global.insns;
1390 }
1391
1392 /* Estimate the growth caused by inlining NODE into all callees.  */
1393
1394 static int
1395 cgraph_estimate_growth (struct cgraph_node *node)
1396 {
1397   int growth = 0;
1398   struct cgraph_edge *e;
1399
1400   for (e = node->callers; e; e = e->next_caller)
1401     if (e->inline_failed)
1402       growth += (cgraph_estimate_size_after_inlining (1, e->caller, node)
1403                  - e->caller->global.insns);
1404
1405   /* ??? Wrong for self recursive functions or cases where we decide to not
1406      inline for different reasons, but it is not big deal as in that case
1407      we will keep the body around, but we will also avoid some inlining.  */
1408   if (!node->needed && !DECL_EXTERNAL (node->decl))
1409     growth -= node->global.insns;
1410
1411   return growth;
1412 }
1413
1414 /* E is expected to be an edge being inlined.  Clone destination node of
1415    the edge and redirect it to the new clone.
1416    DUPLICATE is used for bookkeeping on whether we are actually creating new
1417    clones or re-using node originally representing out-of-line function call.
1418    */
1419 void
1420 cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate)
1421 {
1422   struct cgraph_node *n;
1423
1424   /* We may eliminate the need for out-of-line copy to be output.  In that
1425      case just go ahead and re-use it.  */
1426   if (!e->callee->callers->next_caller
1427       && (!e->callee->needed || DECL_EXTERNAL (e->callee->decl))
1428       && duplicate
1429       && flag_unit_at_a_time)
1430     {
1431       gcc_assert (!e->callee->global.inlined_to);
1432       if (!DECL_EXTERNAL (e->callee->decl))
1433         overall_insns -= e->callee->global.insns, nfunctions_inlined++;
1434       duplicate = 0;
1435     }
1436    else if (duplicate)
1437     {
1438       n = cgraph_clone_node (e->callee);
1439       cgraph_redirect_edge_callee (e, n);
1440     }
1441
1442   if (e->caller->global.inlined_to)
1443     e->callee->global.inlined_to = e->caller->global.inlined_to;
1444   else
1445     e->callee->global.inlined_to = e->caller;
1446
1447   /* Recursively clone all bodies.  */
1448   for (e = e->callee->callees; e; e = e->next_callee)
1449     if (!e->inline_failed)
1450       cgraph_clone_inlined_nodes (e, duplicate);
1451 }
1452
1453 /* Mark edge E as inlined and update callgraph accordingly.  */
1454
1455 void
1456 cgraph_mark_inline_edge (struct cgraph_edge *e)
1457 {
1458   int old_insns = 0, new_insns = 0;
1459   struct cgraph_node *to = NULL, *what;
1460
1461   gcc_assert (e->inline_failed);
1462   e->inline_failed = NULL;
1463
1464   if (!e->callee->global.inlined && flag_unit_at_a_time)
1465     DECL_POSSIBLY_INLINED (e->callee->decl) = true;
1466   e->callee->global.inlined = true;
1467
1468   cgraph_clone_inlined_nodes (e, true);
1469
1470   what = e->callee;
1471
1472   /* Now update size of caller and all functions caller is inlined into.  */
1473   for (;e && !e->inline_failed; e = e->caller->callers)
1474     {
1475       old_insns = e->caller->global.insns;
1476       new_insns = cgraph_estimate_size_after_inlining (1, e->caller,
1477                                                        what);
1478       gcc_assert (new_insns >= 0);
1479       to = e->caller;
1480       to->global.insns = new_insns;
1481     }
1482   gcc_assert (what->global.inlined_to == to);
1483   overall_insns += new_insns - old_insns;
1484   ncalls_inlined++;
1485 }
1486
1487 /* Mark all calls of EDGE->CALLEE inlined into EDGE->CALLER.
1488    Return following unredirected edge in the list of callers
1489    of EDGE->CALLEE  */
1490
1491 static struct cgraph_edge *
1492 cgraph_mark_inline (struct cgraph_edge *edge)
1493 {
1494   struct cgraph_node *to = edge->caller;
1495   struct cgraph_node *what = edge->callee;
1496   struct cgraph_edge *e, *next;
1497   int times = 0;
1498
1499   /* Look for all calls, mark them inline and clone recursively
1500      all inlined functions.  */
1501   for (e = what->callers; e; e = next)
1502     {
1503       next = e->next_caller;
1504       if (e->caller == to && e->inline_failed)
1505         {
1506           cgraph_mark_inline_edge (e);
1507           if (e == edge)
1508             edge = next;
1509           times++;
1510         }
1511     }
1512   gcc_assert (times);
1513   return edge;
1514 }
1515
1516 /* Return false when inlining WHAT into TO is not good idea
1517    as it would cause too large growth of function bodies.  */
1518
1519 static bool
1520 cgraph_check_inline_limits (struct cgraph_node *to, struct cgraph_node *what,
1521                             const char **reason)
1522 {
1523   int times = 0;
1524   struct cgraph_edge *e;
1525   int newsize;
1526   int limit;
1527
1528   if (to->global.inlined_to)
1529     to = to->global.inlined_to;
1530
1531   for (e = to->callees; e; e = e->next_callee)
1532     if (e->callee == what)
1533       times++;
1534
1535   /* When inlining large function body called once into small function,
1536      take the inlined function as base for limiting the growth.  */
1537   if (to->local.self_insns > what->local.self_insns)
1538     limit = to->local.self_insns;
1539   else
1540     limit = what->local.self_insns;
1541
1542   limit += limit * PARAM_VALUE (PARAM_LARGE_FUNCTION_GROWTH) / 100;
1543
1544   newsize = cgraph_estimate_size_after_inlining (times, to, what);
1545   if (newsize > PARAM_VALUE (PARAM_LARGE_FUNCTION_INSNS)
1546       && newsize > limit)
1547     {
1548       if (reason)
1549         *reason = N_("--param large-function-growth limit reached");
1550       return false;
1551     }
1552   return true;
1553 }
1554
1555 /* Return true when function N is small enough to be inlined.  */
1556
1557 static bool
1558 cgraph_default_inline_p (struct cgraph_node *n)
1559 {
1560   if (!DECL_INLINE (n->decl) || !DECL_SAVED_TREE (n->decl))
1561     return false;
1562   if (DECL_DECLARED_INLINE_P (n->decl))
1563     return n->global.insns < MAX_INLINE_INSNS_SINGLE;
1564   else
1565     return n->global.insns < MAX_INLINE_INSNS_AUTO;
1566 }
1567
1568 /* Return true when inlining WHAT would create recursive inlining.
1569    We call recursive inlining all cases where same function appears more than
1570    once in the single recursion nest path in the inline graph.  */
1571
1572 static bool
1573 cgraph_recursive_inlining_p (struct cgraph_node *to,
1574                              struct cgraph_node *what,
1575                              const char **reason)
1576 {
1577   bool recursive;
1578   if (to->global.inlined_to)
1579     recursive = what->decl == to->global.inlined_to->decl;
1580   else
1581     recursive = what->decl == to->decl;
1582   /* Marking recursive function inline has sane semantic and thus we should
1583      not warn on it.  */
1584   if (recursive && reason)
1585     *reason = (what->local.disregard_inline_limits
1586                ? N_("recursive inlining") : "");
1587   return recursive;
1588 }
1589
1590 /* Recompute heap nodes for each of callees.  */
1591 static void
1592 update_callee_keys (fibheap_t heap, struct fibnode **heap_node,
1593                     struct cgraph_node *node)
1594 {
1595   struct cgraph_edge *e;
1596
1597   for (e = node->callees; e; e = e->next_callee)
1598     if (e->inline_failed && heap_node[e->callee->uid])
1599       fibheap_replace_key (heap, heap_node[e->callee->uid],
1600                            cgraph_estimate_growth (e->callee));
1601     else if (!e->inline_failed)
1602       update_callee_keys (heap, heap_node, e->callee);
1603 }
1604
1605 /* Enqueue all recursive calls from NODE into queue linked via aux pointers
1606    in between FIRST and LAST.  WHERE is used for bookkeeping while looking
1607    int calls inlined within NODE.  */
1608 static void
1609 lookup_recursive_calls (struct cgraph_node *node, struct cgraph_node *where,
1610                         struct cgraph_edge **first, struct cgraph_edge **last)
1611 {
1612   struct cgraph_edge *e;
1613   for (e = where->callees; e; e = e->next_callee)
1614     if (e->callee == node)
1615       {
1616         if (!*first)
1617           *first = e;
1618         else
1619           (*last)->aux = e;
1620         *last = e;
1621       }
1622   for (e = where->callees; e; e = e->next_callee)
1623     if (!e->inline_failed)
1624       lookup_recursive_calls (node, e->callee, first, last);
1625 }
1626
1627 /* Decide on recursive inlining: in the case function has recursive calls,
1628    inline until body size reaches given argument.  */
1629 static void
1630 cgraph_decide_recursive_inlining (struct cgraph_node *node)
1631 {
1632   int limit = PARAM_VALUE (PARAM_MAX_INLINE_INSNS_RECURSIVE_AUTO);
1633   int max_depth = PARAM_VALUE (PARAM_MAX_INLINE_RECURSIVE_DEPTH_AUTO);
1634   struct cgraph_edge *first_call = NULL, *last_call = NULL;
1635   struct cgraph_edge *last_in_current_depth;
1636   struct cgraph_edge *e;
1637   struct cgraph_node *master_clone;
1638   int depth = 0;
1639   int n = 0;
1640
1641   if (DECL_DECLARED_INLINE_P (node->decl))
1642     {
1643       limit = PARAM_VALUE (PARAM_MAX_INLINE_INSNS_RECURSIVE);
1644       max_depth = PARAM_VALUE (PARAM_MAX_INLINE_RECURSIVE_DEPTH);
1645     }
1646
1647   /* Make sure that function is small enough to be considered for inlining.  */
1648   if (!max_depth
1649       || cgraph_estimate_size_after_inlining (1, node, node)  >= limit)
1650     return;
1651   lookup_recursive_calls (node, node, &first_call, &last_call);
1652   if (!first_call)
1653     return;
1654
1655   if (cgraph_dump_file)
1656     fprintf (cgraph_dump_file, 
1657              "\nPerforming recursive inlining on %s\n",
1658              cgraph_node_name (node));
1659
1660   /* We need original clone to copy around.  */
1661   master_clone = cgraph_clone_node (node);
1662   master_clone->needed = true;
1663   for (e = master_clone->callees; e; e = e->next_callee)
1664     if (!e->inline_failed)
1665       cgraph_clone_inlined_nodes (e, true);
1666
1667   /* Do the inlining and update list of recursive call during process.  */
1668   last_in_current_depth = last_call;
1669   while (first_call
1670          && cgraph_estimate_size_after_inlining (1, node, master_clone) <= limit)
1671     {
1672       struct cgraph_edge *curr = first_call;
1673
1674       first_call = first_call->aux;
1675       curr->aux = NULL;
1676
1677       cgraph_redirect_edge_callee (curr, master_clone);
1678       cgraph_mark_inline_edge (curr);
1679       lookup_recursive_calls (node, curr->callee, &first_call, &last_call);
1680
1681       if (last_in_current_depth
1682           && ++depth >= max_depth)
1683         break;
1684       n++;
1685     }
1686
1687   /* Cleanup queue pointers.  */
1688   while (first_call)
1689     {
1690       struct cgraph_edge *next = first_call->aux;
1691       first_call->aux = NULL;
1692       first_call = next;
1693     }
1694   if (cgraph_dump_file)
1695     fprintf (cgraph_dump_file, 
1696              "\n   Inlined %i times, body grown from %i to %i insns\n", n,
1697              master_clone->global.insns, node->global.insns);
1698
1699   /* Remove master clone we used for inlining.  We rely that clones inlined
1700      into master clone gets queued just before master clone so we don't
1701      need recursion.  */
1702   for (node = cgraph_nodes; node != master_clone;
1703        node = node->next)
1704     if (node->global.inlined_to == master_clone)
1705       cgraph_remove_node (node);
1706   cgraph_remove_node (master_clone);
1707 }
1708
1709 /* Set inline_failed for all callers of given function to REASON.  */
1710
1711 static void
1712 cgraph_set_inline_failed (struct cgraph_node *node, const char *reason)
1713 {
1714   struct cgraph_edge *e;
1715
1716   if (cgraph_dump_file)
1717     fprintf (cgraph_dump_file, "Inlining failed: %s\n", reason);
1718   for (e = node->callers; e; e = e->next_caller)
1719     if (e->inline_failed)
1720       e->inline_failed = reason;
1721 }
1722
1723 /* We use greedy algorithm for inlining of small functions:
1724    All inline candidates are put into prioritized heap based on estimated
1725    growth of the overall number of instructions and then update the estimates.
1726
1727    INLINED and INLINED_CALEES are just pointers to arrays large enough
1728    to be passed to cgraph_inlined_into and cgraph_inlined_callees.  */
1729
1730 static void
1731 cgraph_decide_inlining_of_small_functions (void)
1732 {
1733   struct cgraph_node *node;
1734   fibheap_t heap = fibheap_new ();
1735   struct fibnode **heap_node =
1736     xcalloc (cgraph_max_uid, sizeof (struct fibnode *));
1737   int max_insns = ((HOST_WIDEST_INT) initial_insns
1738                    * (100 + PARAM_VALUE (PARAM_INLINE_UNIT_GROWTH)) / 100);
1739
1740   /* Put all inline candidates into the heap.  */
1741
1742   for (node = cgraph_nodes; node; node = node->next)
1743     {
1744       if (!node->local.inlinable || !node->callers
1745           || node->local.disregard_inline_limits)
1746         continue;
1747
1748       if (!cgraph_default_inline_p (node))
1749         {
1750           cgraph_set_inline_failed (node,
1751             N_("--param max-inline-insns-single limit reached"));
1752           continue;
1753         }
1754       heap_node[node->uid] =
1755         fibheap_insert (heap, cgraph_estimate_growth (node), node);
1756     }
1757
1758   if (cgraph_dump_file)
1759     fprintf (cgraph_dump_file, "\nDeciding on smaller functions:\n");
1760   while (overall_insns <= max_insns && (node = fibheap_extract_min (heap)))
1761     {
1762       struct cgraph_edge *e, *next;
1763       int old_insns = overall_insns;
1764
1765       heap_node[node->uid] = NULL;
1766       if (cgraph_dump_file)
1767         fprintf (cgraph_dump_file, 
1768                  "\nConsidering %s with %i insns\n"
1769                  " Estimated growth is %+i insns.\n",
1770                  cgraph_node_name (node), node->global.insns,
1771                  cgraph_estimate_growth (node));
1772       if (!cgraph_default_inline_p (node))
1773         {
1774           cgraph_set_inline_failed (node,
1775             N_("--param max-inline-insns-single limit reached after inlining into the callee"));
1776           continue;
1777         }
1778       for (e = node->callers; e; e = next)
1779         {
1780           next = e->next_caller;
1781           if (e->inline_failed)
1782             {
1783               struct cgraph_node *where;
1784
1785               if (cgraph_recursive_inlining_p (e->caller, e->callee,
1786                                                &e->inline_failed)
1787                   || !cgraph_check_inline_limits (e->caller, e->callee,
1788                                                   &e->inline_failed))
1789                 {
1790                   if (cgraph_dump_file)
1791                     fprintf (cgraph_dump_file, " Not inlining into %s:%s.\n",
1792                              cgraph_node_name (e->caller), e->inline_failed);
1793                   continue;
1794                 }
1795               next = cgraph_mark_inline (e);
1796               where = e->caller;
1797               if (where->global.inlined_to)
1798                 where = where->global.inlined_to;
1799
1800               if (heap_node[where->uid])
1801                 fibheap_replace_key (heap, heap_node[where->uid],
1802                                      cgraph_estimate_growth (where));
1803
1804               if (cgraph_dump_file)
1805                 fprintf (cgraph_dump_file, 
1806                          " Inlined into %s which now has %i insns.\n",
1807                          cgraph_node_name (e->caller),
1808                          e->caller->global.insns);
1809             }
1810         }
1811
1812       cgraph_decide_recursive_inlining (node);
1813
1814       /* Similarly all functions called by the function we just inlined
1815          are now called more times; update keys.  */
1816       update_callee_keys (heap, heap_node, node);
1817
1818       if (cgraph_dump_file)
1819         fprintf (cgraph_dump_file, 
1820                  " Inlined for a net change of %+i insns.\n",
1821                  overall_insns - old_insns);
1822     }
1823   while ((node = fibheap_extract_min (heap)) != NULL)
1824     if (!node->local.disregard_inline_limits)
1825       cgraph_set_inline_failed (node, N_("--param inline-unit-growth limit reached"));
1826   fibheap_delete (heap);
1827   free (heap_node);
1828 }
1829
1830 /* Decide on the inlining.  We do so in the topological order to avoid
1831    expenses on updating data structures.  */
1832
1833 static void
1834 cgraph_decide_inlining (void)
1835 {
1836   struct cgraph_node *node;
1837   int nnodes;
1838   struct cgraph_node **order =
1839     xcalloc (cgraph_n_nodes, sizeof (struct cgraph_node *));
1840   int old_insns = 0;
1841   int i;
1842
1843   for (node = cgraph_nodes; node; node = node->next)
1844     initial_insns += node->local.self_insns;
1845   overall_insns = initial_insns;
1846
1847   nnodes = cgraph_postorder (order);
1848
1849   if (cgraph_dump_file)
1850     fprintf (cgraph_dump_file,
1851              "\nDeciding on inlining.  Starting with %i insns.\n",
1852              initial_insns);
1853
1854   for (node = cgraph_nodes; node; node = node->next)
1855     node->aux = 0;
1856
1857   if (cgraph_dump_file)
1858     fprintf (cgraph_dump_file, "\nInlining always_inline functions:\n");
1859
1860   /* In the first pass mark all always_inline edges.  Do this with a priority
1861      so none of our later choices will make this impossible.  */
1862   for (i = nnodes - 1; i >= 0; i--)
1863     {
1864       struct cgraph_edge *e, *next;
1865
1866       node = order[i];
1867
1868       if (!node->local.disregard_inline_limits)
1869         continue;
1870       if (cgraph_dump_file)
1871         fprintf (cgraph_dump_file,
1872                  "\nConsidering %s %i insns (always inline)\n",
1873                  cgraph_node_name (node), node->global.insns);
1874       old_insns = overall_insns;
1875       for (e = node->callers; e; e = next)
1876         {
1877           next = e->next_caller;
1878           if (!e->inline_failed)
1879             continue;
1880           if (cgraph_recursive_inlining_p (e->caller, e->callee,
1881                                            &e->inline_failed))
1882             continue;
1883           cgraph_mark_inline_edge (e);
1884           if (cgraph_dump_file)
1885             fprintf (cgraph_dump_file, 
1886                      " Inlined into %s which now has %i insns.\n",
1887                      cgraph_node_name (e->caller),
1888                      e->caller->global.insns);
1889         }
1890       if (cgraph_dump_file)
1891         fprintf (cgraph_dump_file, 
1892                  " Inlined for a net change of %+i insns.\n",
1893                  overall_insns - old_insns);
1894     }
1895
1896   if (!flag_really_no_inline)
1897     {
1898       cgraph_decide_inlining_of_small_functions ();
1899
1900       if (cgraph_dump_file)
1901         fprintf (cgraph_dump_file, "\nDeciding on functions called once:\n");
1902
1903       /* And finally decide what functions are called once.  */
1904
1905       for (i = nnodes - 1; i >= 0; i--)
1906         {
1907           node = order[i];
1908
1909           if (node->callers && !node->callers->next_caller && !node->needed
1910               && node->local.inlinable && node->callers->inline_failed
1911               && !DECL_EXTERNAL (node->decl) && !DECL_COMDAT (node->decl))
1912             {
1913               bool ok = true;
1914               struct cgraph_node *node1;
1915
1916               /* Verify that we won't duplicate the caller.  */
1917               for (node1 = node->callers->caller;
1918                    node1->callers && !node1->callers->inline_failed
1919                    && ok; node1 = node1->callers->caller)
1920                 if (node1->callers->next_caller || node1->needed)
1921                   ok = false;
1922               if (ok)
1923                 {
1924                   if (cgraph_dump_file)
1925                     fprintf (cgraph_dump_file,
1926                              "\nConsidering %s %i insns.\n"
1927                              " Called once from %s %i insns.\n",
1928                              cgraph_node_name (node), node->global.insns,
1929                              cgraph_node_name (node->callers->caller),
1930                              node->callers->caller->global.insns);
1931
1932                   old_insns = overall_insns;
1933
1934                   if (cgraph_check_inline_limits (node->callers->caller, node,
1935                                                   NULL))
1936                     {
1937                       cgraph_mark_inline (node->callers);
1938                       if (cgraph_dump_file)
1939                         fprintf (cgraph_dump_file,
1940                                  " Inlined into %s which now has %i insns"
1941                                  " for a net change of %+i insns.\n",
1942                                  cgraph_node_name (node->callers->caller),
1943                                  node->callers->caller->global.insns,
1944                                  overall_insns - old_insns);
1945                     }
1946                   else
1947                     {
1948                       if (cgraph_dump_file)
1949                         fprintf (cgraph_dump_file,
1950                                  " Inline limit reached, not inlined.\n");
1951                     }
1952                 }
1953             }
1954         }
1955     }
1956
1957   /* We will never output extern functions we didn't inline. 
1958      ??? Perhaps we can prevent accounting of growth of external
1959      inline functions.  */
1960   cgraph_remove_unreachable_nodes ();
1961
1962   if (cgraph_dump_file)
1963     fprintf (cgraph_dump_file,
1964              "\nInlined %i calls, eliminated %i functions, "
1965              "%i insns turned to %i insns.\n\n",
1966              ncalls_inlined, nfunctions_inlined, initial_insns,
1967              overall_insns);
1968   free (order);
1969 }
1970
1971 /* Decide on the inlining.  We do so in the topological order to avoid
1972    expenses on updating data structures.  */
1973
1974 static void
1975 cgraph_decide_inlining_incrementally (struct cgraph_node *node)
1976 {
1977   struct cgraph_edge *e;
1978
1979   /* First of all look for always inline functions.  */
1980   for (e = node->callees; e; e = e->next_callee)
1981     if (e->callee->local.disregard_inline_limits
1982         && e->inline_failed
1983         && !cgraph_recursive_inlining_p (node, e->callee, &e->inline_failed)
1984         /* ??? It is possible that renaming variable removed the function body
1985            in duplicate_decls. See gcc.c-torture/compile/20011119-2.c  */
1986         && DECL_SAVED_TREE (e->callee->decl))
1987       cgraph_mark_inline (e);
1988
1989   /* Now do the automatic inlining.  */
1990   if (!flag_really_no_inline)
1991     for (e = node->callees; e; e = e->next_callee)
1992       if (e->callee->local.inlinable
1993           && e->inline_failed
1994           && !e->callee->local.disregard_inline_limits
1995           && !cgraph_recursive_inlining_p (node, e->callee, &e->inline_failed)
1996           && cgraph_check_inline_limits (node, e->callee, &e->inline_failed)
1997           && DECL_SAVED_TREE (e->callee->decl))
1998         {
1999           if (cgraph_default_inline_p (e->callee))
2000             cgraph_mark_inline (e);
2001           else
2002             e->inline_failed
2003               = N_("--param max-inline-insns-single limit reached");
2004         }
2005 }
2006
2007
2008 /* Return true when CALLER_DECL should be inlined into CALLEE_DECL.  */
2009
2010 bool
2011 cgraph_inline_p (struct cgraph_edge *e, const char **reason)
2012 {
2013   *reason = e->inline_failed;
2014   return !e->inline_failed;
2015 }
2016
2017 /* FIXME this needs to be enhanced.  If we are compiling a single
2018    module this returns true if the variable is a module level static,
2019    but if we are doing whole program compilation, this could return
2020    true if TREE_PUBLIC is true. */
2021 /* Return true if the variable T is the right kind of static variable to
2022    perform compilation unit scope escape analysis.  */
2023
2024 static inline
2025 bool has_proper_scope_for_analysis (tree t)
2026 {
2027   return (TREE_STATIC(t)) && !(TREE_PUBLIC(t)) && !(TREE_THIS_VOLATILE(t));
2028 }
2029
2030 /* Check to see if T is a read or address of operation on a static var
2031    we are interested in analyzing.  FN is passed in to get access to
2032    its bit vectors.  */
2033
2034 static void
2035 check_rhs_var (struct cgraph_node *fn, tree t)
2036 {
2037   if (TREE_CODE (t) == ADDR_EXPR)
2038     {
2039       tree x = TREE_OPERAND (t, 0);
2040       if ((TREE_CODE (x) == VAR_DECL) && has_proper_scope_for_analysis (x))
2041         {
2042           if (cgraph_dump_file)
2043             fprintf (cgraph_dump_file, "\nadding address:%s",
2044                      lang_hooks.decl_printable_name (x, 2));
2045           
2046           /* FIXME -- PROFILE-RESTRUCTURE: Change the call from
2047              DECL_UID to get the uid from the var_ann field. */    
2048           bitmap_set_bit (module_statics_escape, DECL_UID (x));
2049         }
2050     }
2051   t = get_base_address (t);
2052   if (!t) return;
2053   if ((TREE_CODE (t) == VAR_DECL) && has_proper_scope_for_analysis (t))
2054     {
2055       if (cgraph_dump_file)
2056         fprintf (cgraph_dump_file, "\nadding rhs:%s",
2057                  lang_hooks.decl_printable_name (t, 2));
2058       /* FIXME -- PROFILE-RESTRUCTURE: Change the call from
2059          DECL_UID to get the uid from the var_ann field. */    
2060       bitmap_set_bit (fn->static_vars_info->local->statics_read_by_decl_uid, 
2061                       DECL_UID (t));
2062     }
2063 }
2064
2065 /* Check to see if T is an assignment to a static var we are
2066    interrested in analyzing.  FN is passed in to get access to its bit
2067    vectors.
2068 */
2069
2070 static void
2071 check_lhs_var (struct cgraph_node *fn, tree t)
2072 {
2073   t = get_base_address (t);
2074   if (!t) return;
2075   if ((TREE_CODE (t) == VAR_DECL) && has_proper_scope_for_analysis (t))
2076     {
2077       if (cgraph_dump_file)
2078         fprintf (cgraph_dump_file, "\nadding lhs:%s",
2079                  lang_hooks.decl_printable_name (t, 2));
2080       
2081       /* FIXME -- PROFILE-RESTRUCTURE: Change the call from
2082          DECL_UID to get the uid from the var_ann field. */    
2083       bitmap_set_bit (fn->static_vars_info->local->statics_written_by_decl_uid,
2084                       DECL_UID (t));
2085     }
2086 }
2087
2088 /* This is a scaled down version of get_asm_expr_operands from
2089    tree_ssa_operands.c.  The version there runs much later and assumes
2090    that aliasing information is already available. Here we are just
2091    trying to find if the set of inputs and outputs contain references
2092    or address of operations to local static variables.  FN is the
2093    function being analyzed and STMT is the actual asm statement.  */
2094
2095 static void
2096 get_asm_expr_operands (struct cgraph_node * fn, tree stmt)
2097 {
2098   int noutputs = list_length (ASM_OUTPUTS (stmt));
2099   const char **oconstraints
2100     = (const char **) alloca ((noutputs) * sizeof (const char *));
2101   int i;
2102   tree link;
2103   const char *constraint;
2104   bool allows_mem, allows_reg, is_inout;
2105   
2106   for (i=0, link = ASM_OUTPUTS (stmt); link; ++i, link = TREE_CHAIN (link))
2107     {
2108       oconstraints[i] = constraint
2109         = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
2110       parse_output_constraint (&constraint, i, 0, 0,
2111                                &allows_mem, &allows_reg, &is_inout);
2112       
2113       /* Memory operands are addressable.  Note that STMT needs the
2114          address of this operand.  */
2115       if (!allows_reg && allows_mem)
2116         {
2117           check_lhs_var (fn, TREE_VALUE (link));
2118         }
2119     }
2120
2121   for (link = ASM_INPUTS (stmt); link; link = TREE_CHAIN (link))
2122     {
2123       constraint
2124         = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
2125       parse_input_constraint (&constraint, 0, 0, noutputs, 0,
2126                               oconstraints, &allows_mem, &allows_reg);
2127       
2128       /* Memory operands are addressable.  Note that STMT needs the
2129          address of this operand.  */
2130       if (!allows_reg && allows_mem)
2131         {
2132           check_rhs_var (fn, TREE_VALUE (link));
2133         }
2134     }
2135   
2136   for (link = ASM_CLOBBERS (stmt); link; link = TREE_CHAIN (link))
2137     if (TREE_VALUE (link) == memory_identifier) 
2138       {
2139         /* Abandon all hope, ye who enter here. */
2140         local_static_vars_info_t l = fn->static_vars_info->local;
2141         bitmap_a_or_b (l->statics_read_by_decl_uid,
2142                        l->statics_read_by_decl_uid,
2143                        all_module_statics);
2144         bitmap_a_or_b (l->statics_written_by_decl_uid,
2145                        l->statics_written_by_decl_uid,
2146                        all_module_statics);
2147         
2148       }
2149 }
2150
2151 /* Check the parameters of a function call from CALLER to CALL_EXPR to
2152    see if any of them are static vars.  Also check to see if this is
2153    either an indirect call, a call outside the compilation unit, or
2154    has special attributes that effect the clobbers.  The caller
2155    parameter is the tree node for the caller and the second operand is
2156    the tree node for the entire call expression.  */
2157 static void
2158 process_call_for_static_vars(struct cgraph_node * caller, tree call_expr) 
2159 {
2160   int flags = call_expr_flags(call_expr);
2161   tree operandList = TREE_OPERAND (call_expr, 1);
2162   tree operand;
2163
2164   for (operand = operandList;
2165        operand != NULL_TREE;
2166        operand = TREE_CHAIN (operand))
2167     {
2168       tree argument = TREE_VALUE (operand);
2169       check_rhs_var (caller, argument);
2170     }
2171
2172   /* Const and pure functions have less clobber effects than other
2173      functions so we process these first.  Otherwise if it is a call
2174      outside the compilation unit or an indirect call we punt.  This
2175      leaves local calls which will be processed by following the call
2176      graph.  */  
2177   if (flags & ECF_CONST) 
2178     return;
2179   else if (flags & ECF_PURE) 
2180     caller->local.calls_write_all = true;
2181   else 
2182     {
2183       tree callee_t = get_callee_fndecl (call_expr);
2184       if (callee_t == NULL) 
2185         {
2186           /* Indirect call. */
2187           caller->local.calls_read_all = true;
2188           caller->local.calls_write_all = true;
2189         }
2190       else 
2191         {
2192           struct cgraph_node* callee = cgraph_node(callee_t);
2193
2194           if (callee->local.external) 
2195             {
2196               caller->local.calls_read_all = true;
2197               caller->local.calls_write_all = true;
2198             }
2199         }
2200     }
2201 }
2202
2203 /* FIXME -- PROFILE-RESTRUCTURE: Change to walk by explicitly walking
2204    the basic blocks rather than calling walktree.  */    
2205
2206 /* Walk tree and record all calls.  Called via walk_tree.  FIXME When
2207    this is moved into the tree-profiling-branch, and is dealing with
2208    low GIMPLE, this routine should be changed to use tree iterators
2209    rather than being a walk_tree callback.  The data is the function
2210    that is being scanned.  */
2211 /* TP is the part of the tree currently under the
2212    microscope. WALK_SUBTREES is part of the walk_tree api but is
2213    unused here.  DATA is cgraph_node of the function being walked.  */
2214
2215 static tree
2216 scan_for_static_refs (tree *tp, 
2217                       int *walk_subtrees ATTRIBUTE_UNUSED, 
2218                       void *data)
2219 {
2220   struct cgraph_node *fn = data;
2221   tree t = *tp;
2222   
2223   switch (TREE_CODE (t))  
2224     {
2225     case MODIFY_EXPR:
2226       {
2227         /* First look on the lhs and see what variable is stored to */
2228         tree rhs = TREE_OPERAND (t, 1);
2229         check_lhs_var (fn, TREE_OPERAND (t, 0));
2230         /* Next check the operands on the rhs to see if they are ok. */
2231         switch (TREE_CODE_CLASS (TREE_CODE (rhs))) {
2232         case tcc_binary:
2233           check_rhs_var (fn, TREE_OPERAND (rhs, 0));
2234           check_rhs_var (fn, TREE_OPERAND (rhs, 1));
2235           break;
2236         case tcc_unary:
2237         case tcc_reference:
2238           check_rhs_var (fn, TREE_OPERAND (rhs, 0));
2239           break;
2240         case tcc_declaration:
2241           check_rhs_var (fn, rhs);
2242           break;
2243         case tcc_expression:
2244           switch (TREE_CODE (rhs)) {
2245           case ADDR_EXPR:
2246             check_rhs_var (fn, rhs);
2247             break;
2248           case CALL_EXPR: 
2249             process_call_for_static_vars (fn, rhs);
2250             break;
2251           default:
2252             break;
2253           }
2254           break;
2255         default:
2256           break;
2257         }
2258       }
2259       break;
2260       
2261       
2262     case CALL_EXPR: 
2263       process_call_for_static_vars (fn, t);
2264       break;
2265       
2266     case ASM_EXPR:
2267       get_asm_expr_operands (fn, t);
2268       break;
2269       
2270     default:
2271       break;
2272     }
2273   return NULL;
2274 }
2275
2276
2277 /* This is the main routine for finding the reference patterns for
2278    global variables within a function FN */
2279  static void
2280 cgraph_characterize_statics_local (struct cgraph_node *fn)
2281 {
2282   tree decl = fn->decl;
2283   static_vars_info_t info = new_static_vars_info(fn, false);
2284   local_static_vars_info_t l = info->local;
2285
2286
2287   /* The nodes we're interested in are never shared, so walk
2288      the tree ignoring duplicates.  */
2289   visited_nodes = htab_create (37, htab_hash_pointer,
2290                                htab_eq_pointer, NULL);
2291   
2292   /* FIXME -- PROFILE-RESTRUCTURE: Remove creation of _decl_uid vars.  */
2293   l->statics_read_by_decl_uid = BITMAP_GGC_ALLOC ();
2294   l->statics_written_by_decl_uid = BITMAP_GGC_ALLOC ();
2295   
2296   if (cgraph_dump_file)
2297     fprintf (cgraph_dump_file, "\n local analysis of %s", cgraph_node_name (fn));
2298   
2299   walk_tree (&DECL_SAVED_TREE (decl), scan_for_static_refs, fn, visited_nodes);
2300   htab_delete (visited_nodes);
2301   visited_nodes = NULL;
2302 }
2303
2304 /* Lookup the tree node for the static variable that has UID and
2305    conver the name to a string for debugging. */
2306 static const char *
2307 cgraph_get_static_name_by_uid (int index)
2308 {
2309   splay_tree_node stn = splay_tree_lookup (static_vars_to_consider_by_uid, index);
2310   if (stn)
2311     return lang_hooks.decl_printable_name ((tree)(stn->value), 2);
2312   return NULL;
2313 }
2314
2315 /* Clear out any the static variable with uid INDEX from further
2316    consideration because it escapes (i.e. has had its address
2317    taken).  */
2318 static void
2319 clear_static_vars_maps (int index)
2320 {
2321   splay_tree_node stn = splay_tree_lookup (static_vars_to_consider_by_uid, index);
2322   if (stn) 
2323     {
2324       splay_tree_remove (static_vars_to_consider_by_tree, stn->value);
2325       splay_tree_remove (static_vars_to_consider_by_uid, index);
2326     }
2327 }
2328
2329 /* FIXME -- PROFILE-RESTRUCTURE: Change all *_decl_uid to *_ann_uid.  */
2330
2331 /* Or in all of the bits from every callee into X, the caller's, bit
2332    vector.  There are several cases to check to avoid the sparse
2333    bitmap oring.  */
2334 static void
2335 cgraph_propagate_bits (struct cgraph_node *x)
2336 {
2337   static_vars_info_t x_info = x->static_vars_info;
2338   global_static_vars_info_t x_global = x_info->global;
2339
2340   struct cgraph_edge *e;
2341   for (e = x->callees; e; e = e->next_callee) 
2342     {
2343       struct cgraph_node *y = e->callee;
2344
2345       /* We are only going to look at edges that point to nodes that
2346          have their output bit set.  */
2347       if (y->output)
2348         {
2349           static_vars_info_t y_info; 
2350           global_static_vars_info_t y_global;
2351           y_info = y->static_vars_info;
2352           y_global = y_info->global;
2353
2354           if (x_global->statics_read_by_decl_uid != all_module_statics)
2355             {
2356               if (y_global->statics_read_by_decl_uid == all_module_statics) 
2357                 x_global->statics_read_by_decl_uid = all_module_statics;
2358               /* Skip bitmaps that are pointer equal to node's bitmap
2359                  (no reason to spin within the cycle).  */
2360               else if (x_global->statics_read_by_decl_uid != y_global->statics_read_by_decl_uid)
2361                 bitmap_a_or_b (x_global->statics_read_by_decl_uid,
2362                                x_global->statics_read_by_decl_uid,
2363                                y_global->statics_read_by_decl_uid);
2364             }
2365
2366           if (x_global->statics_written_by_decl_uid != all_module_statics)
2367             {
2368               if (y_global->statics_written_by_decl_uid == all_module_statics) 
2369                 x_global->statics_written_by_decl_uid = all_module_statics;
2370               /* Skip bitmaps that are pointer equal to node's bitmap
2371                  (no reason to spin within the cycle).  */
2372               else if (x_global->statics_written_by_decl_uid != y_global->statics_written_by_decl_uid)
2373                 bitmap_a_or_b (x_global->statics_written_by_decl_uid,
2374                                x_global->statics_written_by_decl_uid,
2375                                y_global->statics_written_by_decl_uid);
2376             }
2377         }
2378     }
2379 }
2380
2381 /* FIXME -- PROFILE-RESTRUCTURE: Change all *_decl_uid to *_ann_uid
2382    except where noted below.  */
2383
2384 /* The main routine for analyzing global static variable usage. See
2385    comments at top for description.  */
2386
2387 static void
2388 cgraph_characterize_statics (void)
2389 {
2390   struct cgraph_node *node;
2391   struct cgraph_node *w;
2392   struct cgraph_node **order =
2393     xcalloc (cgraph_n_nodes, sizeof (struct cgraph_node *));
2394   int order_pos = 0;
2395   int i;
2396   
2397   struct cgraph_varpool_node *vnode;
2398   tree global;
2399
2400   /* get rid of the splay trees from the previous compilation unit. */
2401   
2402   static_vars_to_consider_by_tree =
2403     splay_tree_new_ggc (splay_tree_compare_pointers);
2404   static_vars_to_consider_by_uid =
2405     splay_tree_new_ggc (splay_tree_compare_ints);
2406
2407   if (module_statics_escape) 
2408     {
2409       bitmap_clear (module_statics_escape);
2410       bitmap_clear (all_module_statics);
2411     } 
2412   else
2413     {
2414       module_statics_escape = BITMAP_XMALLOC ();
2415       all_module_statics = BITMAP_GGC_ALLOC ();
2416     }
2417
2418   /* Find all of the global variables that we wish to analyze. */
2419   for (vnode = cgraph_varpool_nodes_queue; vnode; vnode = vnode->next_needed)
2420     {
2421       global = vnode->decl;
2422       if ((TREE_CODE (global) == VAR_DECL) &&
2423           has_proper_scope_for_analysis (global)) 
2424         {
2425           splay_tree_insert (static_vars_to_consider_by_tree,
2426                              (splay_tree_key) global, 
2427                              (splay_tree_value) global);
2428           /* FIXME -- PROFILE-RESTRUCTURE: Change the call from
2429              DECL_UID to get the uid from the var_ann field. */    
2430           splay_tree_insert (static_vars_to_consider_by_uid,
2431                              DECL_UID (global), (splay_tree_value)global);
2432           
2433           if (cgraph_dump_file)
2434             fprintf (cgraph_dump_file, "\nConsidering global:%s",
2435                      lang_hooks.decl_printable_name (global, 2));
2436           /* FIXME -- PROFILE-RESTRUCTURE: Change the call from
2437              DECL_UID to get the uid from the var_ann field. */    
2438           bitmap_set_bit (all_module_statics, DECL_UID (global));
2439         }
2440     }
2441
2442   order_pos = cgraph_reduced_inorder (order, false);
2443   if (cgraph_dump_file)
2444     print_order("new", order, order_pos);
2445
2446   for (i = order_pos - 1; i >= 0; i--)
2447     {
2448       node = order[i];
2449
2450       /* Scan each function to determine the variable usage
2451          patterns.  */ 
2452       cgraph_characterize_statics_local (node);
2453     }
2454
2455   /* Prune out the variables that were found to behave badly
2456      (i.e. have there address taken).  */
2457   {
2458     int index;
2459     EXECUTE_IF_SET_IN_BITMAP (module_statics_escape,
2460                               0, index, clear_static_vars_maps (index));
2461     bitmap_operation (all_module_statics, all_module_statics,
2462                       module_statics_escape, BITMAP_AND_COMPL);
2463
2464     for (i = order_pos - 1; i >= 0; i--)
2465       {
2466         local_static_vars_info_t l;
2467         node = order[i];
2468         l = node->static_vars_info->local;
2469
2470         bitmap_operation (l->statics_read_by_decl_uid, 
2471                           l->statics_read_by_decl_uid,
2472                           module_statics_escape, 
2473                           BITMAP_AND_COMPL);
2474         bitmap_operation (l->statics_written_by_decl_uid, 
2475                           l->statics_written_by_decl_uid,
2476                           module_statics_escape, 
2477                           BITMAP_AND_COMPL);
2478       }
2479   }
2480
2481   if (cgraph_dump_file)
2482     {
2483       for (i = order_pos - 1; i >= 0; i--)
2484         {
2485           int index;
2486           local_static_vars_info_t l;
2487           node = order[i];
2488           l = node->static_vars_info->local;
2489           fprintf (cgraph_dump_file, 
2490                    "\nFunction name:%s/%i:", 
2491                    cgraph_node_name (node), node->uid);
2492           fprintf (cgraph_dump_file, "\n  locals read: ");
2493           EXECUTE_IF_SET_IN_BITMAP (l->statics_read_by_decl_uid,
2494                                     0, index,
2495                                     fprintf (cgraph_dump_file, "%s ",
2496                                              cgraph_get_static_name_by_uid (index)));
2497           fprintf (cgraph_dump_file, "\n  locals written: ");
2498           EXECUTE_IF_SET_IN_BITMAP (l->statics_written_by_decl_uid,
2499                                     0, index,
2500                                     fprintf(cgraph_dump_file, "%s ",
2501                                            cgraph_get_static_name_by_uid (index)));
2502         }
2503     }
2504
2505   /* Propagate the local information thru the call graph to produce
2506      the global information.  All the nodes within a cycle will have
2507      the same info so we collapse cycles first.  Then we can do the
2508      propagation in one pass from the leaves to the roots.  */
2509   order_pos = cgraph_reduced_inorder (order, true);
2510   for (i = order_pos - 1; i >= 0; i--)
2511     {
2512       static_vars_info_t node_info;
2513       global_static_vars_info_t node_g = 
2514         ggc_calloc (1, sizeof (struct global_static_vars_info_d));
2515       local_static_vars_info_t node_l;
2516       
2517
2518       bool read_all;
2519       bool write_all;
2520
2521       node = order[i];
2522       node_info = node->static_vars_info;
2523       node_info->global = node_g;
2524       node_l = node_info->local;
2525
2526       read_all = node->local.calls_read_all;
2527       write_all = node->local.calls_write_all;
2528
2529       /* If any node in a cycle is calls_read_all or calls_write_all
2530          they all are. */
2531       w = node->next_cycle;
2532       while (w)
2533         {
2534           read_all |= w->local.calls_read_all;
2535           write_all |= w->local.calls_write_all;
2536           w = w->next_cycle;
2537         }
2538
2539       /* Initialized the bitmaps for the reduced nodes */
2540       if (read_all) 
2541         node_g->statics_read_by_decl_uid = all_module_statics;
2542       else 
2543         {
2544           node_g->statics_read_by_decl_uid = BITMAP_GGC_ALLOC ();
2545           bitmap_copy (node_g->statics_read_by_decl_uid, 
2546                        node_l->statics_read_by_decl_uid);
2547         }
2548
2549       if (write_all) 
2550         node_g->statics_written_by_decl_uid = all_module_statics;
2551       else
2552         {
2553           node_g->statics_written_by_decl_uid = BITMAP_GGC_ALLOC ();
2554           bitmap_copy (node_g->statics_written_by_decl_uid, 
2555                        node_l->statics_written_by_decl_uid);
2556         }
2557
2558       w = node->next_cycle;
2559       while (w)
2560         {
2561           /* All nodes within a cycle share the same global info bitmaps.  */
2562           static_vars_info_t w_info = w->static_vars_info;
2563           local_static_vars_info_t w_l;
2564
2565           w_info->global = node_g;
2566           w_l = w_info->local;
2567           
2568           /* These global bitmaps are initialized from the local info
2569              of all of the nodes in the region.  However there is no
2570              need to do any work if the bitmaps were set to
2571              all_module_statics.  */
2572           if (!read_all)
2573             bitmap_a_or_b (node_g->statics_read_by_decl_uid,
2574                            node_g->statics_read_by_decl_uid,
2575                            w_l->statics_read_by_decl_uid);
2576           if (!write_all)
2577             bitmap_a_or_b (node_g->statics_written_by_decl_uid,
2578                            node_g->statics_written_by_decl_uid,
2579                            w_l->statics_written_by_decl_uid);
2580           w = w->next_cycle;
2581         }
2582
2583       cgraph_propagate_bits (node);
2584
2585       w = node->next_cycle;
2586       while (w)
2587         {
2588           cgraph_propagate_bits (w);
2589           w = w->next_cycle;
2590         }
2591     }
2592
2593   if (cgraph_dump_file)
2594     {
2595       for (i = order_pos - 1; i >= 0; i--)
2596         {
2597           static_vars_info_t node_info;
2598           global_static_vars_info_t node_g;
2599           int index;
2600           node = order[i];
2601           node_info = node->static_vars_info;
2602           node_g = node_info->global;
2603           fprintf (cgraph_dump_file, 
2604                    "\nFunction name:%s/%i:", 
2605                    cgraph_node_name (node), node->uid);
2606           w = node->next_cycle;
2607           while (w) 
2608             {
2609               fprintf (cgraph_dump_file, "\n  next cycle: %s/%i ",
2610                        cgraph_node_name (w), w->uid);
2611               w = w->next_cycle;
2612             }
2613           fprintf (cgraph_dump_file, "\n  globals read: ");
2614           EXECUTE_IF_SET_IN_BITMAP (node_g->statics_read_by_decl_uid,
2615                                     0, index,
2616                                     fprintf (cgraph_dump_file, "%s ",
2617                                              cgraph_get_static_name_by_uid (index)));
2618           fprintf (cgraph_dump_file, "\n  globals written: ");
2619           EXECUTE_IF_SET_IN_BITMAP (node_g->statics_written_by_decl_uid,
2620                                     0, index,
2621                                     fprintf (cgraph_dump_file, "%s ",
2622                                              cgraph_get_static_name_by_uid (index)));
2623         }
2624     }
2625
2626   /* Cleanup. */
2627   for (i = order_pos - 1; i >= 0; i--)
2628     {
2629       static_vars_info_t node_info;
2630       global_static_vars_info_t node_g;
2631       node = order[i];
2632       node_info = node->static_vars_info;
2633       node_g = node_info->global;
2634       
2635       node_g->var_anns_valid = false;
2636
2637       /* Create the complimentary sets.  These are more useful for
2638          certain apis.  */
2639       node_g->statics_not_read_by_decl_uid = BITMAP_GGC_ALLOC ();
2640       node_g->statics_not_written_by_decl_uid = BITMAP_GGC_ALLOC ();
2641
2642       /* FIXME -- PROFILE-RESTRUCTURE: Delete next 4 assignments.  */
2643       node_g->statics_read_by_ann_uid = BITMAP_GGC_ALLOC ();
2644       node_g->statics_written_by_ann_uid = BITMAP_GGC_ALLOC ();
2645       node_g->statics_not_read_by_ann_uid = BITMAP_GGC_ALLOC ();
2646       node_g->statics_not_written_by_ann_uid = BITMAP_GGC_ALLOC ();
2647
2648       if (node_g->statics_read_by_decl_uid != all_module_statics) 
2649         {
2650           bitmap_operation (node_g->statics_not_read_by_decl_uid, 
2651                             all_module_statics,
2652                             node_g->statics_read_by_decl_uid,
2653                             BITMAP_AND_COMPL);
2654         }
2655
2656       if (node_g->statics_written_by_decl_uid != all_module_statics) 
2657         bitmap_operation (node_g->statics_not_written_by_decl_uid, 
2658                           all_module_statics,
2659                           node_g->statics_written_by_decl_uid,
2660                           BITMAP_AND_COMPL);
2661
2662       w = node->next_cycle;
2663
2664       while (w)
2665         {
2666           struct cgraph_node * last = w;
2667           w = w->next_cycle;
2668           last->next_cycle = NULL;
2669         }
2670     }
2671
2672   free (order);
2673 }
2674
2675 /* Expand all functions that must be output.
2676
2677    Attempt to topologically sort the nodes so function is output when
2678    all called functions are already assembled to allow data to be
2679    propagated across the callgraph.  Use a stack to get smaller distance
2680    between a function and its callees (later we may choose to use a more
2681    sophisticated algorithm for function reordering; we will likely want
2682    to use subsections to make the output functions appear in top-down
2683    order).  */
2684
2685 static void
2686 cgraph_expand_all_functions (void)
2687 {
2688   struct cgraph_node *node;
2689   struct cgraph_node **order =
2690     xcalloc (cgraph_n_nodes, sizeof (struct cgraph_node *));
2691   int order_pos = 0, new_order_pos = 0;
2692   int i;
2693
2694   order_pos = cgraph_postorder (order);
2695   gcc_assert (order_pos == cgraph_n_nodes);
2696
2697   /* Garbage collector may remove inline clones we eliminate during
2698      optimization.  So we must be sure to not reference them.  */
2699   for (i = 0; i < order_pos; i++)
2700     if (order[i]->output)
2701       order[new_order_pos++] = order[i];
2702
2703   for (i = new_order_pos - 1; i >= 0; i--)
2704     {
2705       node = order[i];
2706       if (node->output)
2707         {
2708           gcc_assert (node->reachable);
2709           node->output = 0;
2710           cgraph_expand_function (node);
2711         }
2712     }
2713   free (order);
2714 }
2715
2716 /* Mark all local and external functions.
2717    
2718    A local function is one whose calls can occur only in the current
2719    compilation unit and all its calls are explicit, so we can change
2720    its calling convention.  We simply mark all static functions whose
2721    address is not taken as local.
2722
2723    An external function is one whose body is outside the current
2724    compilation unit.  */
2725
2726 static void
2727 cgraph_mark_local_and_external_functions (void)
2728 {
2729   struct cgraph_node *node;
2730
2731   /* Figure out functions we want to assemble.  */
2732   for (node = cgraph_nodes; node; node = node->next)
2733     {
2734       node->local.local = (!node->needed
2735                            && DECL_SAVED_TREE (node->decl)
2736                            && !TREE_PUBLIC (node->decl));
2737       node->local.external = (!DECL_SAVED_TREE (node->decl)
2738                            && TREE_PUBLIC (node->decl));
2739     }
2740
2741   if (cgraph_dump_file)
2742     {
2743       fprintf (cgraph_dump_file, "\nMarking local functions:");
2744       for (node = cgraph_nodes; node; node = node->next)
2745         if (node->local.local)
2746           fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
2747       fprintf (cgraph_dump_file, "\n\n");
2748
2749       fprintf (cgraph_dump_file, "\nMarking external functions:");
2750       for (node = cgraph_nodes; node; node = node->next)
2751         if (node->local.external)
2752           fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
2753     fprintf (cgraph_dump_file, "\n\n");
2754 }
2755 }
2756
2757 /* Return true when function body of DECL still needs to be kept around
2758    for later re-use.  */
2759 bool
2760 cgraph_preserve_function_body_p (tree decl)
2761 {
2762   struct cgraph_node *node;
2763   /* Keep the body; we're going to dump it.  */
2764   if (dump_enabled_p (TDI_tree_all))
2765     return true;
2766   if (!cgraph_global_info_ready)
2767     return (DECL_INLINE (decl) && !flag_really_no_inline);
2768   /* Look if there is any clone around.  */
2769   for (node = cgraph_node (decl); node; node = node->next_clone)
2770     if (node->global.inlined_to)
2771       return true;
2772   return false;
2773 }
2774
2775 /* Perform simple optimizations based on callgraph.  */
2776
2777 void
2778 cgraph_optimize (void)
2779 {
2780 #ifdef ENABLE_CHECKING
2781   verify_cgraph ();
2782 #endif
2783   if (!flag_unit_at_a_time)
2784     return;
2785   timevar_push (TV_CGRAPHOPT);
2786   if (!quiet_flag)
2787     fprintf (stderr, "Performing intraprocedural optimizations\n");
2788
2789   cgraph_mark_local_and_external_functions ();
2790   if (cgraph_dump_file)
2791     {
2792       fprintf (cgraph_dump_file, "Marked ");
2793       dump_cgraph (cgraph_dump_file);
2794     }
2795
2796   if (flag_inline_trees)
2797     cgraph_decide_inlining ();
2798   cgraph_global_info_ready = true;
2799   if (cgraph_dump_file)
2800     {
2801       fprintf (cgraph_dump_file, "Optimized ");
2802       dump_cgraph (cgraph_dump_file);
2803     }
2804   timevar_pop (TV_CGRAPHOPT);
2805
2806   /* Output everything.  */
2807   if (!quiet_flag)
2808     fprintf (stderr, "Assembling functions:\n");
2809 #ifdef ENABLE_CHECKING
2810   verify_cgraph ();
2811 #endif
2812   
2813   /* This call was moved here from cgraph_expand_all_functions so that
2814      cgraph_characterize_statics could use the output flag of the cgraph
2815      node.  */
2816   
2817   cgraph_mark_functions_to_output ();
2818   
2819   cgraph_characterize_statics ();
2820   
2821   cgraph_expand_all_functions ();
2822   if (cgraph_dump_file)
2823     {
2824       fprintf (cgraph_dump_file, "\nFinal ");
2825       dump_cgraph (cgraph_dump_file);
2826     }
2827 #ifdef ENABLE_CHECKING
2828   verify_cgraph ();
2829   /* Double check that all inline clones are gone and that all
2830      function bodies have been released from memory.  */
2831   if (flag_unit_at_a_time
2832       && !dump_enabled_p (TDI_tree_all)
2833       && !(sorrycount || errorcount))
2834     {
2835       struct cgraph_node *node;
2836       bool error_found = false;
2837
2838       for (node = cgraph_nodes; node; node = node->next)
2839         if (node->analyzed
2840             && (node->global.inlined_to
2841                 || DECL_SAVED_TREE (node->decl)))
2842           {
2843             error_found = true;
2844             dump_cgraph_node (stderr, node);
2845           }
2846       if (error_found)
2847         internal_error ("Nodes with no released memory found.");
2848     }
2849 #endif
2850 }
2851
2852 /* Generate and emit a static constructor or destructor.  WHICH must be
2853    one of 'I' or 'D'.  BODY should be a STATEMENT_LIST containing 
2854    GENERIC statements.  */
2855
2856 void
2857 cgraph_build_static_cdtor (char which, tree body, int priority)
2858 {
2859   static int counter = 0;
2860   char which_buf[16];
2861   tree decl, name, resdecl;
2862
2863   sprintf (which_buf, "%c_%d", which, counter++);
2864   name = get_file_function_name_long (which_buf);
2865
2866   decl = build_decl (FUNCTION_DECL, name,
2867                      build_function_type (void_type_node, void_list_node));
2868   current_function_decl = decl;
2869
2870   resdecl = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
2871   DECL_ARTIFICIAL (resdecl) = 1;
2872   DECL_IGNORED_P (resdecl) = 1;
2873   DECL_RESULT (decl) = resdecl;
2874
2875   allocate_struct_function (decl);
2876
2877   TREE_STATIC (decl) = 1;
2878   TREE_USED (decl) = 1;
2879   DECL_ARTIFICIAL (decl) = 1;
2880   DECL_IGNORED_P (decl) = 1;
2881   DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;
2882   DECL_SAVED_TREE (decl) = body;
2883   TREE_PUBLIC (decl) = ! targetm.have_ctors_dtors;
2884   DECL_UNINLINABLE (decl) = 1;
2885
2886   DECL_INITIAL (decl) = make_node (BLOCK);
2887   TREE_USED (DECL_INITIAL (decl)) = 1;
2888
2889   DECL_SOURCE_LOCATION (decl) = input_location;
2890   cfun->function_end_locus = input_location;
2891
2892   switch (which)
2893     {
2894     case 'I':
2895       DECL_STATIC_CONSTRUCTOR (decl) = 1;
2896       break;
2897     case 'D':
2898       DECL_STATIC_DESTRUCTOR (decl) = 1;
2899       break;
2900     default:
2901       gcc_unreachable ();
2902     }
2903
2904   gimplify_function_tree (decl);
2905
2906   /* ??? We will get called LATE in the compilation process.  */
2907   if (cgraph_global_info_ready)
2908     tree_rest_of_compilation (decl, false);
2909   else
2910     cgraph_finalize_function (decl, 0);
2911   
2912   if (targetm.have_ctors_dtors)
2913     {
2914       void (*fn) (rtx, int);
2915
2916       if (which == 'I')
2917         fn = targetm.asm_out.constructor;
2918       else
2919         fn = targetm.asm_out.destructor;
2920       fn (XEXP (DECL_RTL (decl), 0), priority);
2921     }
2922 }
2923
2924 void
2925 init_cgraph (void)
2926 {
2927   cgraph_dump_file = dump_begin (TDI_cgraph, NULL);
2928   memory_identifier = get_identifier("memory");
2929 }
2930 #include "gt-cgraphunit.h"