OSDN Git Service

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