OSDN Git Service

PR tree-optimize/40556
[pf3gnuchains/gcc-fork.git] / gcc / ipa-reference.c
1 /* Callgraph based analysis of static variables.
2    Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
3    Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
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 3, 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 COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.  */
20
21 /* This file gathers information about how variables whose scope is
22    confined to the compilation unit are used.  
23
24    There are two categories of information produced by this pass:
25
26    1) The addressable (TREE_ADDRESSABLE) bit and readonly
27    (TREE_READONLY) bit associated with these variables is properly set
28    based on scanning all of the code withing the compilation unit.
29
30    2) The transitive call site specific clobber effects are computed
31    for the variables whose scope is contained within this compilation
32    unit.
33
34    First each function and static variable initialization is analyzed
35    to determine which local static variables are either read, written,
36    or have their address taken.  Any local static that has its address
37    taken is removed from consideration.  Once the local read and
38    writes are determined, a transitive closure of this information is
39    performed over the call graph to determine the worst case set of
40    side effects of each call.  In later parts of the compiler, these
41    local and global sets are examined to make the call clobbering less
42    traumatic, promote some statics to registers, and improve aliasing
43    information.
44    
45    Currently must be run after inlining decisions have been made since
46    otherwise, the local sets will not contain information that is
47    consistent with post inlined state.  The global sets are not prone
48    to this problem since they are by definition transitive.  */
49
50 #include "config.h"
51 #include "system.h"
52 #include "coretypes.h"
53 #include "tm.h"
54 #include "tree.h"
55 #include "tree-flow.h"
56 #include "tree-inline.h"
57 #include "tree-pass.h"
58 #include "langhooks.h"
59 #include "pointer-set.h"
60 #include "splay-tree.h"
61 #include "ggc.h"
62 #include "ipa-utils.h"
63 #include "ipa-reference.h"
64 #include "gimple.h"
65 #include "cgraph.h"
66 #include "output.h"
67 #include "flags.h"
68 #include "timevar.h"
69 #include "diagnostic.h"
70 #include "langhooks.h"
71 #include "lto-streamer.h"
72
73 static void add_new_function (struct cgraph_node *node,
74                               void *data ATTRIBUTE_UNUSED);
75 static void remove_node_data (struct cgraph_node *node,
76                               void *data ATTRIBUTE_UNUSED);
77 static void duplicate_node_data (struct cgraph_node *src,
78                                  struct cgraph_node *dst,
79                                  void *data ATTRIBUTE_UNUSED);
80
81 /* The static variables defined within the compilation unit that are
82    loaded or stored directly by function that owns this structure.  */ 
83
84 struct ipa_reference_local_vars_info_d 
85 {
86   bitmap statics_read;
87   bitmap statics_written;
88
89   /* Set when this function calls another function external to the
90      compilation unit or if the function has a asm clobber of memory.
91      In general, such calls are modeled as reading and writing all
92      variables (both bits on) but sometime there are attributes on the
93      called function so we can do better.  */
94   bool calls_read_all;
95   bool calls_write_all;
96 };
97
98 /* Statics that are read and written by some set of functions. The
99    local ones are based on the loads and stores local to the function.
100    The global ones are based on the local info as well as the
101    transitive closure of the functions that are called.  The
102    structures are separated to allow the global structures to be
103    shared between several functions since every function within a
104    strongly connected component will have the same information.  This
105    sharing saves both time and space in the computation of the vectors
106    as well as their translation from decl_uid form to ann_uid
107    form.  */ 
108
109 struct ipa_reference_global_vars_info_d
110 {
111   bitmap statics_read;
112   bitmap statics_written;
113   bitmap statics_not_read;
114   bitmap statics_not_written;
115 };
116
117 typedef struct ipa_reference_local_vars_info_d *ipa_reference_local_vars_info_t;
118 typedef struct ipa_reference_global_vars_info_d *ipa_reference_global_vars_info_t;
119 struct ipa_reference_vars_info_d 
120 {
121   ipa_reference_local_vars_info_t local;
122   ipa_reference_global_vars_info_t global;
123 };
124
125 typedef struct ipa_reference_vars_info_d *ipa_reference_vars_info_t;
126
127 /* This splay tree contains all of the static variables that are
128    being considered by the compilation level alias analysis.  For
129    module_at_a_time compilation, this is the set of static but not
130    public variables.  Any variables that either have their address
131    taken or participate in otherwise unsavory operations are deleted
132    from this list.  */
133 static GTY((param1_is(int), param2_is(tree)))
134      splay_tree reference_vars_to_consider;
135
136 /* This bitmap is used to knock out the module static variables whose
137    addresses have been taken and passed around.  */
138 static bitmap module_statics_escape;
139
140 /* This bitmap is used to knock out the module static variables that
141    are not readonly.  */
142 static bitmap module_statics_written;
143
144 /* A bit is set for every module static we are considering.  This is
145    ored into the local info when asm code is found that clobbers all
146    memory. */
147 static bitmap all_module_statics;
148
149 static struct pointer_set_t *visited_nodes;
150
151 /* Obstack holding bitmaps of local analysis (live from analysis to
152    propagation)  */
153 static bitmap_obstack local_info_obstack;
154 /* Obstack holding global analysis live forever.  */
155 static bitmap_obstack global_info_obstack;
156
157 /* Holders of ipa cgraph hooks: */
158 static struct cgraph_node_hook_list *function_insertion_hook_holder;
159 static struct cgraph_2node_hook_list *node_duplication_hook_holder;
160 static struct cgraph_node_hook_list *node_removal_hook_holder;
161
162 enum initialization_status_t
163 {
164   UNINITIALIZED,
165   RUNNING,
166   FINISHED
167 };
168
169 tree memory_identifier_string;
170
171 /* Vector where the reference var infos are actually stored. */
172 DEF_VEC_P (ipa_reference_vars_info_t);
173 DEF_VEC_ALLOC_P (ipa_reference_vars_info_t, heap);
174 static VEC (ipa_reference_vars_info_t, heap) *ipa_reference_vars_vector;
175
176 /* Return the ipa_reference_vars structure starting from the cgraph NODE.  */
177 static inline ipa_reference_vars_info_t
178 get_reference_vars_info (struct cgraph_node *node)
179 {
180   if (!ipa_reference_vars_vector
181       || VEC_length (ipa_reference_vars_info_t, ipa_reference_vars_vector) <= (unsigned int)node->uid)
182     return NULL;
183   return VEC_index (ipa_reference_vars_info_t, ipa_reference_vars_vector, node->uid);
184 }
185
186 /* Return the ipa_reference_vars structure starting from the cgraph NODE.  */
187 static inline void
188 set_reference_vars_info (struct cgraph_node *node, ipa_reference_vars_info_t info)
189 {
190   if (!ipa_reference_vars_vector
191       || VEC_length (ipa_reference_vars_info_t, ipa_reference_vars_vector) <= (unsigned int)node->uid)
192      VEC_safe_grow_cleared (ipa_reference_vars_info_t, heap, ipa_reference_vars_vector, node->uid + 1);
193   VEC_replace (ipa_reference_vars_info_t, ipa_reference_vars_vector, node->uid, info);
194 }
195
196 /* Get a bitmap that contains all of the locally referenced static
197    variables for function FN.  */
198 static ipa_reference_local_vars_info_t
199 get_local_reference_vars_info (struct cgraph_node *fn) 
200 {
201   ipa_reference_vars_info_t info = get_reference_vars_info (fn);
202
203   if (info)
204     return info->local;
205   else
206     /* This phase was not run.  */ 
207     return NULL;
208 }
209
210 /* Get a bitmap that contains all of the globally referenced static
211    variables for function FN.  */
212  
213 static ipa_reference_global_vars_info_t
214 get_global_reference_vars_info (struct cgraph_node *fn) 
215 {
216   ipa_reference_vars_info_t info = get_reference_vars_info (fn);
217
218   if (info)
219     return info->global;
220   else
221     /* This phase was not run.  */ 
222     return NULL;
223 }
224
225 /* Return a bitmap indexed by VAR_DECL uid for the static variables
226    that are read during the execution of the function FN.  Returns
227    NULL if no data is available.  */
228
229 bitmap 
230 ipa_reference_get_read_global (struct cgraph_node *fn) 
231 {
232   ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
233   if (g) 
234     return g->statics_read;
235   else
236     return NULL;
237 }
238
239 /* Return a bitmap indexed by VAR_DECL uid for the static variables
240    that are written during the execution of the function FN.  Note
241    that variables written may or may not be read during the function
242    call.  Returns NULL if no data is available.  */
243
244 bitmap 
245 ipa_reference_get_written_global (struct cgraph_node *fn) 
246 {
247   ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
248   if (g) 
249     return g->statics_written;
250   else
251     return NULL;
252 }
253
254 /* Return a bitmap indexed by_DECL_UID uid for the static variables
255    that are not read during the execution of the function FN.  Returns
256    NULL if no data is available.  */
257
258 bitmap 
259 ipa_reference_get_not_read_global (struct cgraph_node *fn) 
260 {
261   ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
262   if (g) 
263     return g->statics_not_read;
264   else
265     return NULL;
266 }
267
268 /* Return a bitmap indexed by DECL_UID uid for the static variables
269    that are not written during the execution of the function FN.  Note
270    that variables written may or may not be read during the function
271    call.  Returns NULL if no data is available.  */
272
273 bitmap 
274 ipa_reference_get_not_written_global (struct cgraph_node *fn) 
275 {
276   ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
277   if (g) 
278     return g->statics_not_written;
279   else
280     return NULL;
281 }
282
283 \f
284
285 /* Add VAR to all_module_statics and the two
286    reference_vars_to_consider* sets.  */
287
288 static inline void 
289 add_static_var (tree var) 
290 {
291   int uid = DECL_UID (var);
292   gcc_assert (TREE_CODE (var) == VAR_DECL);
293   if (!bitmap_bit_p (all_module_statics, uid))
294     {
295       splay_tree_insert (reference_vars_to_consider,
296                          uid, (splay_tree_value)var);
297       bitmap_set_bit (all_module_statics, uid);
298     }
299 }
300
301 /* Return true if the variable T is the right kind of static variable to
302    perform compilation unit scope escape analysis.  */
303
304 static inline bool 
305 has_proper_scope_for_analysis (tree t)
306 {
307   /* If the variable has the "used" attribute, treat it as if it had a
308      been touched by the devil.  */
309   if (lookup_attribute ("used", DECL_ATTRIBUTES (t)))
310     return false;
311
312   /* Do not want to do anything with volatile except mark any
313      function that uses one to be not const or pure.  */
314   if (TREE_THIS_VOLATILE (t)) 
315     return false;
316
317   /* Do not care about a local automatic that is not static.  */
318   if (!TREE_STATIC (t) && !DECL_EXTERNAL (t))
319     return false;
320
321   /* FIXME: for LTO we should include PUBLIC vars too.  This is bit difficult
322      as summarie would need unsharing.  */
323   if (DECL_EXTERNAL (t) || TREE_PUBLIC (t))
324     return false;
325
326   /* We cannot touch decls where the type needs constructing.  */
327   if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (t)))
328     return false;
329
330   /* This is a variable we care about.  Check if we have seen it
331      before, and if not add it the set of variables we care about.  */
332   if (!bitmap_bit_p (all_module_statics, DECL_UID (t)))
333     add_static_var (t);
334
335   return true;
336 }
337
338 /* Mark tree T as having address taken.  */
339
340 static void
341 mark_address_taken (tree x)
342 {
343   if (TREE_CODE (x) == VAR_DECL
344       && module_statics_escape && has_proper_scope_for_analysis (x))
345     bitmap_set_bit (module_statics_escape, DECL_UID (x));
346 }
347
348 /* Wrapper around mark_address_taken for the stmt walker.  */
349
350 static bool
351 mark_address (gimple stmt ATTRIBUTE_UNUSED, tree addr,
352               void *data ATTRIBUTE_UNUSED)
353 {
354   while (handled_component_p (addr))
355     addr = TREE_OPERAND (addr, 0);
356   mark_address_taken (addr);
357   return false;
358 }
359
360 /* Mark load of T.  */
361
362 static bool
363 mark_load (gimple stmt ATTRIBUTE_UNUSED, tree t, void *data)
364 {
365   ipa_reference_local_vars_info_t local = (ipa_reference_local_vars_info_t)data;
366   if (TREE_CODE (t) == VAR_DECL
367       && has_proper_scope_for_analysis (t))
368     bitmap_set_bit (local->statics_read, DECL_UID (t));
369   return false;
370 }
371
372 /* Mark store of T.  */
373
374 static bool
375 mark_store (gimple stmt ATTRIBUTE_UNUSED, tree t, void *data)
376 {
377   ipa_reference_local_vars_info_t local = (ipa_reference_local_vars_info_t)data;
378   if (TREE_CODE (t) == VAR_DECL
379       && has_proper_scope_for_analysis (t))
380     {
381       if (local)
382         bitmap_set_bit (local->statics_written, DECL_UID (t));
383       /* Mark the write so we can tell which statics are
384          readonly.  */
385       if (module_statics_written)
386         bitmap_set_bit (module_statics_written, DECL_UID (t));
387     }
388   return false;
389 }
390
391 /* Look for memory clobber and set read_all/write_all if present.  */
392
393 static void
394 check_asm_memory_clobber (ipa_reference_local_vars_info_t local, gimple stmt)
395 {
396   size_t i;
397   tree op;
398   
399   for (i = 0; i < gimple_asm_nclobbers (stmt); i++)
400     {
401       op = gimple_asm_clobber_op (stmt, i);
402       if (simple_cst_equal(TREE_VALUE (op), memory_identifier_string) == 1) 
403         {
404           /* Abandon all hope, ye who enter here. */
405           local->calls_read_all = true;
406           local->calls_write_all = true;
407         }      
408     }
409 }
410
411 /* Look for external calls and set read_all/write_all correspondingly.  */
412
413 static void
414 check_call (ipa_reference_local_vars_info_t local, gimple stmt)
415 {
416   int flags = gimple_call_flags (stmt);
417   tree callee_t = gimple_call_fndecl (stmt);
418
419   /* Process indirect calls.  All direct calles are handled at propagation
420      time.  */
421   if (!callee_t)
422     {
423       if (flags & ECF_CONST) 
424         ;
425       else if (flags & ECF_PURE)
426         local->calls_read_all = true;
427       else 
428         {
429           local->calls_read_all = true;
430           local->calls_write_all = true;
431         }
432     }
433 }
434
435 /* TP is the part of the tree currently under the microscope.
436    WALK_SUBTREES is part of the walk_tree api but is unused here.
437    DATA is cgraph_node of the function being walked.  */
438
439 static tree
440 scan_stmt_for_static_refs (gimple_stmt_iterator *gsip,
441                            struct cgraph_node *fn)
442 {
443   gimple stmt = gsi_stmt (*gsip);
444   ipa_reference_local_vars_info_t local = NULL;
445
446   if (is_gimple_debug (stmt))
447     return NULL;
448
449   if (fn)
450     local = get_reference_vars_info (fn)->local;
451
452   /* Look for direct loads and stores.  */
453   walk_stmt_load_store_addr_ops (stmt, local, mark_load, mark_store,
454                                  mark_address);
455
456   if (is_gimple_call (stmt))
457     check_call (local, stmt);
458   else if (gimple_code (stmt) == GIMPLE_ASM)
459     check_asm_memory_clobber (local, stmt);
460   
461   return NULL;
462 }
463
464 /* Call-back to scan variable initializers for static references.  
465    Called using walk_tree.  */
466
467 static tree
468 scan_initializer_for_static_refs (tree *tp, int *walk_subtrees,
469                                   void *data ATTRIBUTE_UNUSED)
470 {
471   tree t = *tp;
472
473   if (TREE_CODE (t) == ADDR_EXPR)
474     {
475       mark_address_taken (get_base_var (t));
476       *walk_subtrees = 0;
477     }
478   /* Save some cycles by not walking types and declaration as we
479      won't find anything useful there anyway.  */
480   else if (IS_TYPE_OR_DECL_P (*tp))
481     *walk_subtrees = 0;
482  
483   return NULL;
484 }
485
486 /* Lookup the tree node for the static variable that has UID.  */
487 static tree
488 get_static_decl (int index)
489 {
490   splay_tree_node stn = 
491     splay_tree_lookup (reference_vars_to_consider, index);
492   if (stn)
493     return (tree)stn->value;
494   return NULL;
495 }
496
497 /* Lookup the tree node for the static variable that has UID and
498    convert the name to a string for debugging.  */
499
500 static const char *
501 get_static_name (int index)
502 {
503   splay_tree_node stn = 
504     splay_tree_lookup (reference_vars_to_consider, index);
505   if (stn)
506     return lang_hooks.decl_printable_name ((tree)(stn->value), 2);
507   return NULL;
508 }
509
510 /* Or in all of the bits from every callee of X into X_GLOBAL, the caller's cycle,
511    bit vector.  There are several cases to check to avoid the sparse
512    bitmap oring.  */
513
514 static void
515 propagate_bits (ipa_reference_global_vars_info_t x_global, struct cgraph_node *x)
516 {
517   struct cgraph_edge *e;
518   for (e = x->callees; e; e = e->next_callee) 
519     {
520       struct cgraph_node *y = e->callee;
521
522       /* Only look into nodes we can propagate something.  */
523       if (cgraph_function_body_availability (e->callee) > AVAIL_OVERWRITABLE)
524         {
525           if (get_reference_vars_info (y))
526             {
527               ipa_reference_vars_info_t y_info 
528                 = get_reference_vars_info (y);
529               ipa_reference_global_vars_info_t y_global = y_info->global;
530
531               /* Calls in current cycle do not have global computed yet.  */
532               if (!y_info->global)
533                 continue;
534               
535               if (x_global->statics_read
536                   != all_module_statics)
537                 {
538                   if (y_global->statics_read 
539                       == all_module_statics)
540                     {
541                       BITMAP_FREE (x_global->statics_read);
542                       x_global->statics_read 
543                         = all_module_statics;
544                     }
545                   /* Skip bitmaps that are pointer equal to node's bitmap
546                      (no reason to spin within the cycle).  */
547                   else if (x_global->statics_read 
548                            != y_global->statics_read)
549                     bitmap_ior_into (x_global->statics_read,
550                                      y_global->statics_read);
551                 }
552               
553               if (x_global->statics_written 
554                   != all_module_statics)
555                 {
556                   if (y_global->statics_written 
557                       == all_module_statics)
558                     {
559                       BITMAP_FREE (x_global->statics_written);
560                       x_global->statics_written 
561                         = all_module_statics;
562                     }
563                   /* Skip bitmaps that are pointer equal to node's bitmap
564                      (no reason to spin within the cycle).  */
565                   else if (x_global->statics_written 
566                            != y_global->statics_written)
567                     bitmap_ior_into (x_global->statics_written,
568                                      y_global->statics_written);
569                 }
570             }
571           else 
572             gcc_unreachable ();
573         }
574     }
575 }
576
577 /* The init routine for analyzing global static variable usage.  See
578    comments at top for description.  */
579 static void 
580 ipa_init (void) 
581 {
582   static bool init_p = false;
583
584   if (init_p)
585     return;
586
587   init_p = true;
588
589   memory_identifier_string = build_string(7, "memory");
590
591   reference_vars_to_consider =
592     splay_tree_new_ggc (splay_tree_compare_ints);
593
594   bitmap_obstack_initialize (&local_info_obstack);
595   bitmap_obstack_initialize (&global_info_obstack);
596   module_statics_escape = BITMAP_ALLOC (&local_info_obstack);
597   module_statics_written = BITMAP_ALLOC (&local_info_obstack);
598   all_module_statics = BITMAP_ALLOC (&global_info_obstack);
599
600   /* There are some shared nodes, in particular the initializers on
601      static declarations.  We do not need to scan them more than once
602      since all we would be interested in are the addressof
603      operations.  */
604   visited_nodes = pointer_set_create ();
605
606   function_insertion_hook_holder =
607       cgraph_add_function_insertion_hook (&add_new_function, NULL);
608   node_removal_hook_holder =
609       cgraph_add_node_removal_hook (&remove_node_data, NULL);
610   node_duplication_hook_holder =
611       cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
612 }
613
614 /* Check out the rhs of a static or global initialization VNODE to see
615    if any of them contain addressof operations.  Note that some of
616    these variables may  not even be referenced in the code in this
617    compilation unit but their right hand sides may contain references
618    to variables defined within this unit.  */
619
620 static void 
621 analyze_variable (struct varpool_node *vnode)
622 {
623   struct walk_stmt_info wi;
624   tree global = vnode->decl;
625
626   memset (&wi, 0, sizeof (wi));
627   wi.pset = visited_nodes;
628   walk_tree (&DECL_INITIAL (global), scan_initializer_for_static_refs,
629              &wi, wi.pset);
630 }
631
632
633 /* Set up the persistent info for FN.  */
634
635 static ipa_reference_local_vars_info_t
636 init_function_info (struct cgraph_node *fn)
637 {
638   ipa_reference_vars_info_t info 
639     = XCNEW (struct ipa_reference_vars_info_d);
640   ipa_reference_local_vars_info_t l
641     = XCNEW (struct ipa_reference_local_vars_info_d);
642
643   /* Add the info to the tree's annotation.  */
644   set_reference_vars_info (fn, info);
645
646   info->local = l;
647   l->statics_read = BITMAP_ALLOC (&local_info_obstack);
648   l->statics_written = BITMAP_ALLOC (&local_info_obstack);
649
650   return l;
651 }
652
653
654 /* This is the main routine for finding the reference patterns for
655    global variables within a function FN.  */
656
657 static void
658 analyze_function (struct cgraph_node *fn)
659 {
660   tree decl = fn->decl;
661   struct function *this_cfun = DECL_STRUCT_FUNCTION (decl);
662   basic_block this_block;
663 #ifdef ENABLE_CHECKING
664   tree step;
665 #endif
666
667   if (dump_file)
668     fprintf (dump_file, "\n local analysis of %s\n", cgraph_node_name (fn));
669
670   push_cfun (DECL_STRUCT_FUNCTION (decl));
671   current_function_decl = decl;
672   
673   init_function_info (fn);
674   FOR_EACH_BB_FN (this_block, this_cfun)
675     {
676       gimple_stmt_iterator gsi;
677       gimple phi;
678       tree op;
679       use_operand_p use;
680       ssa_op_iter iter;
681
682       /* Find the addresses taken in phi node arguments.  */
683       for (gsi = gsi_start_phis (this_block);
684            !gsi_end_p (gsi);
685            gsi_next (&gsi))
686         {
687           phi = gsi_stmt (gsi);
688           FOR_EACH_PHI_ARG (use, phi, iter, SSA_OP_USE)
689             {
690               op = USE_FROM_PTR (use);
691               if (TREE_CODE (op) == ADDR_EXPR)
692                 mark_address_taken (get_base_var (op));
693             }
694         }
695
696       for (gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi))
697         scan_stmt_for_static_refs (&gsi, fn);
698     }
699
700 #ifdef ENABLE_CHECKING
701   /* Verify that all local initializers was expanded by gimplifier.  */
702   for (step = DECL_STRUCT_FUNCTION (decl)->local_decls;
703        step;
704        step = TREE_CHAIN (step))
705     {
706       tree var = TREE_VALUE (step);
707       if (TREE_CODE (var) == VAR_DECL 
708           && DECL_INITIAL (var)
709           && !TREE_STATIC (var))
710         gcc_unreachable ();
711     }
712 #endif
713   pop_cfun ();
714   current_function_decl = NULL;
715 }
716
717 /* Remove local data associated with function FN.  */
718 static void
719 clean_function_local_data (struct cgraph_node *fn)
720 {
721   ipa_reference_vars_info_t info = get_reference_vars_info (fn);
722   ipa_reference_local_vars_info_t l = info->local;
723   if (l)
724     {
725       if (l->statics_read
726           && l->statics_read != all_module_statics)
727         BITMAP_FREE (l->statics_read);
728       if (l->statics_written
729           &&l->statics_written != all_module_statics)
730         BITMAP_FREE (l->statics_written);
731       free (l);
732       info->local = NULL;
733     }
734 }
735
736 /* Remove all data associated with function FN.  */
737
738 static void
739 clean_function (struct cgraph_node *fn)
740 {
741   ipa_reference_vars_info_t info = get_reference_vars_info (fn);
742   ipa_reference_global_vars_info_t g = info->global;
743   
744   clean_function_local_data (fn);
745   if (g)
746     {
747       if (g->statics_read
748           && g->statics_read != all_module_statics)
749         BITMAP_FREE (g->statics_read);
750       
751       if (g->statics_written
752           && g->statics_written != all_module_statics)
753         BITMAP_FREE (g->statics_written);
754       
755       if (g->statics_not_read
756           && g->statics_not_read != all_module_statics)
757         BITMAP_FREE (g->statics_not_read);
758       
759       if (g->statics_not_written
760           && g->statics_not_written != all_module_statics)
761         BITMAP_FREE (g->statics_not_written);
762       free (g);
763       info->global = NULL;
764     }
765   
766   free (get_reference_vars_info (fn));
767   set_reference_vars_info (fn, NULL);
768 }
769
770 /* Called when new function is inserted to callgraph late.  */
771 static void
772 add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
773 {
774   /* There are some shared nodes, in particular the initializers on
775      static declarations.  We do not need to scan them more than once
776      since all we would be interested in are the addressof
777      operations.  */
778   analyze_function (node);
779   visited_nodes = NULL;
780 }
781
782 static bitmap
783 copy_local_bitmap (bitmap src)
784 {
785   bitmap dst;
786   if (!src)
787     return NULL;
788   if (src == all_module_statics)
789     return all_module_statics;
790   dst = BITMAP_ALLOC (&local_info_obstack);
791   bitmap_copy (dst, src);
792   return dst;
793 }
794
795 static bitmap
796 copy_global_bitmap (bitmap src)
797 {
798   bitmap dst;
799   if (!src)
800     return NULL;
801   if (src == all_module_statics)
802     return all_module_statics;
803   dst = BITMAP_ALLOC (&global_info_obstack);
804   bitmap_copy (dst, src);
805   return dst;
806 }
807
808 /* Called when new clone is inserted to callgraph late.  */
809
810 static void
811 duplicate_node_data (struct cgraph_node *src, struct cgraph_node *dst,
812                      void *data ATTRIBUTE_UNUSED)
813 {
814   ipa_reference_global_vars_info_t ginfo;
815   ipa_reference_local_vars_info_t linfo;
816   ipa_reference_global_vars_info_t dst_ginfo;
817   ipa_reference_local_vars_info_t dst_linfo;
818
819   ginfo = get_global_reference_vars_info (src);
820   linfo = get_local_reference_vars_info (src);
821   if (!linfo && !ginfo)
822     return;
823   init_function_info (dst);
824   if (linfo)
825     {
826       dst_linfo = get_local_reference_vars_info (dst);
827       dst_linfo->statics_read = copy_local_bitmap (linfo->statics_read);
828       dst_linfo->statics_written = copy_local_bitmap (linfo->statics_written);
829       dst_linfo->calls_read_all = linfo->calls_read_all;
830       dst_linfo->calls_write_all = linfo->calls_write_all;
831     }
832   if (ginfo)
833     {
834       get_reference_vars_info (dst)->global = XCNEW (struct ipa_reference_global_vars_info_d);
835       dst_ginfo = get_global_reference_vars_info (dst);
836       dst_ginfo->statics_read = copy_global_bitmap (ginfo->statics_read);
837       dst_ginfo->statics_written = copy_global_bitmap (ginfo->statics_written);
838       dst_ginfo->statics_not_read = copy_global_bitmap (ginfo->statics_not_read);
839       dst_ginfo->statics_not_written = copy_global_bitmap (ginfo->statics_not_written);
840     }
841 }
842
843 /* Called when node is removed.  */
844
845 static void
846 remove_node_data (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
847 {
848   if (get_reference_vars_info (node))
849     clean_function (node);
850 }
851
852 /* Analyze each function in the cgraph to see which global or statics
853    are read or written.  */
854
855 static void 
856 generate_summary (void)
857 {
858   struct cgraph_node *node;
859   struct varpool_node *vnode;
860   unsigned int index;
861   bitmap_iterator bi;
862   bitmap module_statics_readonly;
863   bitmap bm_temp;
864   
865   ipa_init ();
866   module_statics_readonly = BITMAP_ALLOC (&local_info_obstack);
867   bm_temp = BITMAP_ALLOC (&local_info_obstack);
868
869   /* Process all of the variables first.  */
870   FOR_EACH_STATIC_INITIALIZER (vnode)
871     analyze_variable (vnode);
872
873   /* Process all of the functions next. 
874
875      We do not want to process any of the clones so we check that this
876      is a master clone.  However, we do need to process any
877      AVAIL_OVERWRITABLE functions (these are never clones) because
878      they may cause a static variable to escape.  The code that can
879      overwrite such a function cannot access the statics because it
880      would not be in the same compilation unit.  When the analysis is
881      finished, the computed information of these AVAIL_OVERWRITABLE is
882      replaced with worst case info.  
883   */
884   for (node = cgraph_nodes; node; node = node->next)
885     if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
886       analyze_function (node);
887
888   pointer_set_destroy (visited_nodes);
889   visited_nodes = NULL;
890
891   /* Prune out the variables that were found to behave badly
892      (i.e. have their address taken).  */
893   EXECUTE_IF_SET_IN_BITMAP (module_statics_escape, 0, index, bi)
894     {
895       splay_tree_remove (reference_vars_to_consider, index);
896     }
897   
898   bitmap_and_compl_into (all_module_statics, 
899                          module_statics_escape);
900   
901   bitmap_and_compl (module_statics_readonly, all_module_statics,
902                     module_statics_written);
903   
904   /* If the address is not taken, we can unset the addressable bit
905      on this variable.  */
906   EXECUTE_IF_SET_IN_BITMAP (all_module_statics, 0, index, bi)
907     {
908       tree var = get_static_decl (index);
909       TREE_ADDRESSABLE (var) = 0;
910       if (dump_file) 
911         fprintf (dump_file, "Not TREE_ADDRESSABLE var %s\n",
912                  get_static_name (index));
913     }
914   
915   /* If the variable is never written, we can set the TREE_READONLY
916      flag.  Additionally if it has a DECL_INITIAL that is made up of
917      constants we can treat the entire global as a constant.  */
918   
919   bitmap_and_compl (module_statics_readonly, all_module_statics,
920                     module_statics_written);
921   EXECUTE_IF_SET_IN_BITMAP (module_statics_readonly, 0, index, bi)
922     {
923       tree var = get_static_decl (index);
924       
925       /* Ignore variables in named sections - changing TREE_READONLY
926          changes the section flags, potentially causing conflicts with
927          other variables in the same named section.  */
928       if (DECL_SECTION_NAME (var) == NULL_TREE)
929         {
930           TREE_READONLY (var) = 1;
931           if (dump_file)
932             fprintf (dump_file, "read-only var %s\n", 
933                      get_static_name (index));
934         }
935     }
936   
937   BITMAP_FREE(module_statics_escape);
938   BITMAP_FREE(module_statics_written);
939   module_statics_escape = NULL;
940   module_statics_written = NULL;
941   
942   if (dump_file)
943     EXECUTE_IF_SET_IN_BITMAP (all_module_statics, 0, index, bi)
944       {
945         fprintf (dump_file, "\nPromotable global:%s",
946                  get_static_name (index));
947       }
948   
949   for (node = cgraph_nodes; node; node = node->next)
950     if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
951       {
952         ipa_reference_local_vars_info_t l;
953         l = get_reference_vars_info (node)->local;
954         
955         /* Any variables that are not in all_module_statics are
956            removed from the local maps.  This will include all of the
957            variables that were found to escape in the function
958            scanning.  */
959         bitmap_and_into (l->statics_read, 
960                          all_module_statics);
961         bitmap_and_into (l->statics_written, 
962                          all_module_statics);
963       }
964   
965   BITMAP_FREE(module_statics_readonly);
966   BITMAP_FREE(bm_temp);
967   
968   if (dump_file)
969     for (node = cgraph_nodes; node; node = node->next)
970       if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
971         {
972           ipa_reference_local_vars_info_t l;
973           unsigned int index;
974           bitmap_iterator bi;
975           
976           l = get_reference_vars_info (node)->local;
977           fprintf (dump_file, 
978                    "\nFunction name:%s/%i:", 
979                    cgraph_node_name (node), node->uid);
980           fprintf (dump_file, "\n  locals read: ");
981           EXECUTE_IF_SET_IN_BITMAP (l->statics_read,
982                                     0, index, bi)
983             {
984               fprintf (dump_file, "%s ",
985                        get_static_name (index));
986             }
987           fprintf (dump_file, "\n  locals written: ");
988           EXECUTE_IF_SET_IN_BITMAP (l->statics_written,
989                                     0, index, bi)
990             {
991               fprintf(dump_file, "%s ",
992                       get_static_name (index));
993             }
994           if (l->calls_read_all)
995              fprintf (dump_file, "\n  calls read all: ");
996           if (l->calls_write_all)
997              fprintf (dump_file, "\n  calls read all: ");
998         }
999 }
1000
1001
1002 /* Return true if we need to write summary of NODE. */
1003
1004 static bool
1005 write_node_summary_p (struct cgraph_node *node)
1006 {
1007   gcc_assert (node->global.inlined_to == NULL);
1008   return (node->analyzed 
1009           && cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE
1010           && get_reference_vars_info (node) != NULL);
1011 }
1012
1013 /* Serialize the ipa info for lto.  */
1014
1015 static void 
1016 ipa_reference_write_summary (cgraph_node_set set)
1017 {
1018   struct cgraph_node *node;
1019   struct lto_simple_output_block *ob
1020     = lto_create_simple_output_block (LTO_section_ipa_reference);
1021   unsigned int count = 0;
1022   cgraph_node_set_iterator csi;
1023
1024   for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
1025     if (write_node_summary_p (csi_node (csi)))
1026         count++;
1027   
1028   lto_output_uleb128_stream (ob->main_stream, count);
1029   
1030   /* Process all of the functions.  */
1031   for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
1032     {
1033       node = csi_node (csi);
1034       if (write_node_summary_p (node))
1035         {
1036           ipa_reference_local_vars_info_t l
1037             = get_reference_vars_info (node)->local;
1038           unsigned int index;
1039           bitmap_iterator bi;
1040           lto_cgraph_encoder_t encoder;
1041           int node_ref;
1042
1043           encoder = ob->decl_state->cgraph_node_encoder;
1044           node_ref = lto_cgraph_encoder_encode (encoder, node);
1045           lto_output_uleb128_stream (ob->main_stream, node_ref);
1046
1047           /* Stream out the statics read.  */
1048           if (l->calls_read_all)
1049             lto_output_sleb128_stream (ob->main_stream, -1);
1050           else
1051             {
1052               lto_output_sleb128_stream (ob->main_stream,
1053                                          bitmap_count_bits (l->statics_read));
1054               EXECUTE_IF_SET_IN_BITMAP (l->statics_read, 0, index, bi)
1055                 lto_output_var_decl_index(ob->decl_state, ob->main_stream,
1056                                           get_static_decl (index));
1057             }
1058
1059           /* Stream out the statics written.  */
1060           if (l->calls_write_all)
1061             lto_output_sleb128_stream (ob->main_stream, -1);
1062           else
1063             {
1064               lto_output_sleb128_stream (ob->main_stream,
1065                                          bitmap_count_bits (l->statics_written));
1066               EXECUTE_IF_SET_IN_BITMAP (l->statics_written, 0, index, bi)
1067                 lto_output_var_decl_index(ob->decl_state, ob->main_stream,
1068                                           get_static_decl (index));
1069             }
1070         }
1071     }
1072   lto_destroy_simple_output_block (ob);
1073 }
1074
1075
1076 /* Deserialize the ipa info for lto.  */
1077
1078 static void 
1079 ipa_reference_read_summary (void)
1080 {
1081   struct lto_file_decl_data ** file_data_vec 
1082     = lto_get_file_decl_data ();
1083   struct lto_file_decl_data * file_data;
1084   unsigned int j = 0;
1085
1086   ipa_init ();
1087
1088   while ((file_data = file_data_vec[j++]))
1089     {
1090       const char *data;
1091       size_t len;
1092       struct lto_input_block *ib
1093         = lto_create_simple_input_block (file_data, 
1094                                          LTO_section_ipa_reference, 
1095                                          &data, &len);
1096       if (ib)
1097         { 
1098           unsigned int i;
1099           unsigned int f_count = lto_input_uleb128 (ib);
1100
1101           for (i = 0; i < f_count; i++)
1102             {
1103               unsigned int j, index;
1104               struct cgraph_node *node;
1105               ipa_reference_local_vars_info_t l;
1106               int v_count;
1107               lto_cgraph_encoder_t encoder;
1108
1109               index = lto_input_uleb128 (ib);
1110               encoder = file_data->cgraph_node_encoder;
1111               node = lto_cgraph_encoder_deref (encoder, index);
1112               l = init_function_info (node);
1113
1114               /* Set the statics read.  */
1115               v_count = lto_input_sleb128 (ib);
1116               if (v_count == -1)
1117                 l->calls_read_all = true;
1118               else
1119                 for (j = 0; j < (unsigned int)v_count; j++)
1120                   {
1121                     unsigned int var_index = lto_input_uleb128 (ib);
1122                     tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1123                                                                    var_index);
1124                     add_static_var (v_decl);
1125                     bitmap_set_bit (l->statics_read, DECL_UID (v_decl));
1126                   } 
1127
1128               /* Set the statics written.  */
1129               v_count = lto_input_sleb128 (ib);
1130               if (v_count == -1)
1131                 l->calls_read_all = true;
1132               else
1133                 for (j = 0; j < (unsigned int)v_count; j++)
1134                   {
1135                     unsigned int var_index = lto_input_uleb128 (ib);
1136                     tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1137                                                                    var_index);
1138                     add_static_var (v_decl);
1139                     bitmap_set_bit (l->statics_written, DECL_UID (v_decl));
1140                   } 
1141             }
1142
1143           lto_destroy_simple_input_block (file_data, 
1144                                           LTO_section_ipa_reference, 
1145                                           ib, data, len);
1146         }
1147     }
1148 }
1149
1150
1151 \f
1152 /* Set READ_ALL/WRITE_ALL based on DECL flags.  */
1153 static void
1154 read_write_all_from_decl (tree decl, bool * read_all, bool * write_all)
1155 {
1156   int flags = flags_from_decl_or_type (decl);
1157   if (flags & ECF_CONST)
1158     ;
1159   else if (flags & ECF_PURE)
1160     *read_all = true;
1161   else
1162     {
1163        /* TODO: To be able to produce sane results, we should also handle
1164           common builtins, in particular throw.
1165           Indirect calls hsould be only counted and as inliner is replacing them
1166           by direct calls, we can conclude if any indirect calls are left in body */
1167       *read_all = true;
1168       *write_all = true;
1169     }
1170 }
1171
1172 /* Produce the global information by preforming a transitive closure
1173    on the local information that was produced by ipa_analyze_function
1174    and ipa_analyze_variable.  */
1175
1176 static unsigned int
1177 propagate (void)
1178 {
1179   struct cgraph_node *node;
1180   struct cgraph_node *w;
1181   struct cgraph_node **order =
1182     XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
1183   int order_pos = ipa_utils_reduced_inorder (order, false, true, NULL);
1184   int i;
1185
1186   cgraph_remove_function_insertion_hook (function_insertion_hook_holder);
1187   if (dump_file) 
1188     dump_cgraph (dump_file);
1189
1190   /* Propagate the local information thru the call graph to produce
1191      the global information.  All the nodes within a cycle will have
1192      the same info so we collapse cycles first.  Then we can do the
1193      propagation in one pass from the leaves to the roots.  */
1194   order_pos = ipa_utils_reduced_inorder (order, true, true, NULL);
1195   if (dump_file)
1196     ipa_utils_print_order(dump_file, "reduced", order, order_pos);
1197
1198   for (i = 0; i < order_pos; i++ )
1199     {
1200       ipa_reference_vars_info_t node_info;
1201       ipa_reference_global_vars_info_t node_g = 
1202         XCNEW (struct ipa_reference_global_vars_info_d);
1203       ipa_reference_local_vars_info_t node_l;
1204       struct cgraph_edge *e;
1205       
1206       bool read_all;
1207       bool write_all;
1208       struct ipa_dfs_info * w_info;
1209
1210       node = order[i];
1211       node_info = get_reference_vars_info (node);
1212       if (!node_info) 
1213         {
1214           dump_cgraph_node (stderr, node);
1215           dump_cgraph (stderr);
1216           gcc_unreachable ();
1217         }
1218
1219       gcc_assert (!node_info->global);
1220       node_l = node_info->local;
1221
1222       read_all = node_l->calls_read_all;
1223       write_all = node_l->calls_write_all;
1224
1225       /* When function is overwrittable, we can not assume anything.  */
1226       if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
1227         read_write_all_from_decl (node->decl, &read_all, &write_all);
1228
1229       for (e = node->callees; e; e = e->next_callee) 
1230         if (cgraph_function_body_availability (e->callee) <= AVAIL_OVERWRITABLE)
1231           read_write_all_from_decl (e->callee->decl, &read_all, &write_all);
1232
1233
1234       /* If any node in a cycle is calls_read_all or calls_write_all
1235          they all are. */
1236       w_info = (struct ipa_dfs_info *) node->aux;
1237       w = w_info->next_cycle;
1238       while (w)
1239         {
1240           ipa_reference_local_vars_info_t w_l = 
1241             get_reference_vars_info (w)->local;
1242
1243           /* When function is overwrittable, we can not assume anything.  */
1244           if (cgraph_function_body_availability (w) <= AVAIL_OVERWRITABLE)
1245             read_write_all_from_decl (w->decl, &read_all, &write_all);
1246
1247           for (e = w->callees; e; e = e->next_callee) 
1248             if (cgraph_function_body_availability (e->callee) <= AVAIL_OVERWRITABLE)
1249               read_write_all_from_decl (e->callee->decl, &read_all, &write_all);
1250
1251           read_all |= w_l->calls_read_all;
1252           write_all |= w_l->calls_write_all;
1253
1254           w_info = (struct ipa_dfs_info *) w->aux;
1255           w = w_info->next_cycle;
1256         }
1257
1258
1259       /* Initialized the bitmaps for the reduced nodes */
1260       if (read_all) 
1261         node_g->statics_read = all_module_statics;
1262       else 
1263         {
1264           node_g->statics_read = BITMAP_ALLOC (&global_info_obstack);
1265           bitmap_copy (node_g->statics_read, 
1266                        node_l->statics_read);
1267         }
1268       if (write_all) 
1269         node_g->statics_written = all_module_statics;
1270       else
1271         {
1272           node_g->statics_written = BITMAP_ALLOC (&global_info_obstack);
1273           bitmap_copy (node_g->statics_written, 
1274                        node_l->statics_written);
1275         }
1276
1277       propagate_bits (node_g, node);
1278       w_info = (struct ipa_dfs_info *) node->aux;
1279       w = w_info->next_cycle;
1280       while (w)
1281         {
1282           ipa_reference_vars_info_t w_ri = 
1283             get_reference_vars_info (w);
1284           ipa_reference_local_vars_info_t w_l = w_ri->local;
1285           
1286           /* These global bitmaps are initialized from the local info
1287              of all of the nodes in the region.  However there is no
1288              need to do any work if the bitmaps were set to
1289              all_module_statics.  */
1290           if (!read_all)
1291             bitmap_ior_into (node_g->statics_read,
1292                              w_l->statics_read);
1293           if (!write_all)
1294             bitmap_ior_into (node_g->statics_written,
1295                              w_l->statics_written);
1296           propagate_bits (node_g, w);
1297           w_info = (struct ipa_dfs_info *) w->aux;
1298           w = w_info->next_cycle;
1299         }
1300
1301       /* All nodes within a cycle have the same global info bitmaps.  */
1302       node_info->global = node_g;
1303       w_info = (struct ipa_dfs_info *) node->aux;
1304       w = w_info->next_cycle;
1305       while (w)
1306         {
1307           ipa_reference_vars_info_t w_ri = 
1308             get_reference_vars_info (w);
1309
1310           gcc_assert (!w_ri->global);
1311           w_ri->global = XCNEW (struct ipa_reference_global_vars_info_d);
1312           w_ri->global->statics_read = copy_global_bitmap (node_g->statics_read);
1313           w_ri->global->statics_written = copy_global_bitmap (node_g->statics_written);
1314
1315           w_info = (struct ipa_dfs_info *) w->aux;
1316           w = w_info->next_cycle;
1317         }
1318     }
1319
1320   if (dump_file)
1321     {
1322       for (i = 0; i < order_pos; i++ )
1323         {
1324           ipa_reference_vars_info_t node_info;
1325           ipa_reference_global_vars_info_t node_g;
1326           ipa_reference_local_vars_info_t node_l;
1327           unsigned int index;
1328           bitmap_iterator bi;
1329           struct ipa_dfs_info * w_info;
1330
1331           node = order[i];
1332           node_info = get_reference_vars_info (node);
1333           node_g = node_info->global;
1334           node_l = node_info->local;
1335           fprintf (dump_file, 
1336                    "\nFunction name:%s/%i:", 
1337                    cgraph_node_name (node), node->uid);
1338           fprintf (dump_file, "\n  locals read: ");
1339           EXECUTE_IF_SET_IN_BITMAP (node_l->statics_read,
1340                                     0, index, bi)
1341             {
1342               fprintf (dump_file, "%s ",
1343                        get_static_name (index));
1344             }
1345           fprintf (dump_file, "\n  locals written: ");
1346           EXECUTE_IF_SET_IN_BITMAP (node_l->statics_written,
1347                                     0, index, bi)
1348             {
1349               fprintf(dump_file, "%s ",
1350                       get_static_name (index));
1351             }
1352
1353           w_info = (struct ipa_dfs_info *) node->aux;
1354           w = w_info->next_cycle;
1355           while (w) 
1356             {
1357               ipa_reference_vars_info_t w_ri = 
1358                 get_reference_vars_info (w);
1359               ipa_reference_local_vars_info_t w_l = w_ri->local;
1360               fprintf (dump_file, "\n  next cycle: %s/%i ",
1361                        cgraph_node_name (w), w->uid);
1362               fprintf (dump_file, "\n    locals read: ");
1363               EXECUTE_IF_SET_IN_BITMAP (w_l->statics_read,
1364                                         0, index, bi)
1365                 {
1366                   fprintf (dump_file, "%s ",
1367                            get_static_name (index));
1368                 }
1369
1370               fprintf (dump_file, "\n    locals written: ");
1371               EXECUTE_IF_SET_IN_BITMAP (w_l->statics_written,
1372                                         0, index, bi)
1373                 {
1374                   fprintf(dump_file, "%s ",
1375                           get_static_name (index));
1376                 }
1377               
1378
1379               w_info = (struct ipa_dfs_info *) w->aux;
1380               w = w_info->next_cycle;
1381             }
1382           fprintf (dump_file, "\n  globals read: ");
1383           EXECUTE_IF_SET_IN_BITMAP (node_g->statics_read,
1384                                     0, index, bi)
1385             {
1386               fprintf (dump_file, "%s ",
1387                        get_static_name (index));
1388             }
1389           fprintf (dump_file, "\n  globals written: ");
1390           EXECUTE_IF_SET_IN_BITMAP (node_g->statics_written,
1391                                     0, index, bi)
1392             {
1393               fprintf (dump_file, "%s ",
1394                        get_static_name (index));
1395             }
1396         }
1397     }
1398
1399   /* Cleanup. */
1400   for (i = 0; i < order_pos; i++ )
1401     {
1402       ipa_reference_vars_info_t node_info;
1403       ipa_reference_global_vars_info_t node_g;
1404       node = order[i];
1405       node_info = get_reference_vars_info (node);
1406       node_g = node_info->global;
1407       
1408       /* Create the complimentary sets.  These are more useful for
1409          certain apis.  */
1410       node_g->statics_not_read = BITMAP_ALLOC (&global_info_obstack);
1411       node_g->statics_not_written = BITMAP_ALLOC (&global_info_obstack);
1412
1413       if (node_g->statics_read != all_module_statics) 
1414         bitmap_and_compl (node_g->statics_not_read, 
1415                           all_module_statics,
1416                           node_g->statics_read);
1417
1418       if (node_g->statics_written 
1419           != all_module_statics) 
1420         bitmap_and_compl (node_g->statics_not_written, 
1421                           all_module_statics,
1422                           node_g->statics_written);
1423    }
1424
1425   free (order);
1426
1427   for (node = cgraph_nodes; node; node = node->next)
1428     {
1429       ipa_reference_vars_info_t node_info;
1430       node_info = get_reference_vars_info (node);
1431       /* Get rid of the aux information.  */
1432       
1433       if (node->aux)
1434         {
1435           free (node->aux);
1436           node->aux = NULL;
1437         }
1438       
1439       if (cgraph_function_body_availability (node) == AVAIL_OVERWRITABLE)
1440         clean_function (node);
1441       else if (node_info)
1442         clean_function_local_data (node);
1443     }
1444   bitmap_obstack_release (&local_info_obstack);
1445   return 0;
1446 }
1447
1448
1449 static bool
1450 gate_reference (void)
1451 {
1452   return (flag_ipa_reference
1453           /* Don't bother doing anything if the program has errors.  */
1454           && !(errorcount || sorrycount));
1455 }
1456
1457 struct ipa_opt_pass_d pass_ipa_reference =
1458 {
1459  {
1460   IPA_PASS,
1461   "static-var",                         /* name */
1462   gate_reference,                       /* gate */
1463   propagate,                            /* execute */
1464   NULL,                                 /* sub */
1465   NULL,                                 /* next */
1466   0,                                    /* static_pass_number */
1467   TV_IPA_REFERENCE,                     /* tv_id */
1468   0,                                    /* properties_required */
1469   0,                                    /* properties_provided */
1470   0,                                    /* properties_destroyed */
1471   0,                                    /* todo_flags_start */
1472   0                                     /* todo_flags_finish */
1473  },
1474  generate_summary,                      /* generate_summary */
1475  ipa_reference_write_summary,           /* write_summary */
1476  ipa_reference_read_summary,            /* read_summary */
1477  NULL,                                  /* function_read_summary */
1478  0,                                     /* TODOs */
1479  NULL,                                  /* function_transform */
1480  NULL                                   /* variable_transform */
1481 };
1482
1483 #include "gt-ipa-reference.h"