OSDN Git Service

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