OSDN Git Service

* g++.dg/cdce3.C: Skip on alpha*-dec-osf5*.
[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                              varpool_node_set vset ATTRIBUTE_UNUSED)
1045 {
1046   struct cgraph_node *node;
1047   struct lto_simple_output_block *ob
1048     = lto_create_simple_output_block (LTO_section_ipa_reference);
1049   unsigned int count = 0;
1050   cgraph_node_set_iterator csi;
1051
1052   for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
1053     if (write_node_summary_p (csi_node (csi)))
1054         count++;
1055
1056   lto_output_uleb128_stream (ob->main_stream, count);
1057
1058   /* Process all of the functions.  */
1059   for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
1060     {
1061       node = csi_node (csi);
1062       if (write_node_summary_p (node))
1063         {
1064           ipa_reference_local_vars_info_t l
1065             = get_reference_vars_info (node)->local;
1066           unsigned int index;
1067           bitmap_iterator bi;
1068           lto_cgraph_encoder_t encoder;
1069           int node_ref;
1070
1071           encoder = ob->decl_state->cgraph_node_encoder;
1072           node_ref = lto_cgraph_encoder_encode (encoder, node);
1073           lto_output_uleb128_stream (ob->main_stream, node_ref);
1074
1075           /* Stream out the statics read.  */
1076           if (l->calls_read_all)
1077             lto_output_sleb128_stream (ob->main_stream, -1);
1078           else
1079             {
1080               lto_output_sleb128_stream (ob->main_stream,
1081                                          bitmap_count_bits (l->statics_read));
1082               EXECUTE_IF_SET_IN_BITMAP (l->statics_read, 0, index, bi)
1083                 lto_output_var_decl_index(ob->decl_state, ob->main_stream,
1084                                           get_static_decl (index));
1085             }
1086
1087           /* Stream out the statics written.  */
1088           if (l->calls_write_all)
1089             lto_output_sleb128_stream (ob->main_stream, -1);
1090           else
1091             {
1092               lto_output_sleb128_stream (ob->main_stream,
1093                                          bitmap_count_bits (l->statics_written));
1094               EXECUTE_IF_SET_IN_BITMAP (l->statics_written, 0, index, bi)
1095                 lto_output_var_decl_index(ob->decl_state, ob->main_stream,
1096                                           get_static_decl (index));
1097             }
1098         }
1099     }
1100   lto_destroy_simple_output_block (ob);
1101 }
1102
1103
1104 /* Deserialize the ipa info for lto.  */
1105
1106 static void
1107 ipa_reference_read_summary (void)
1108 {
1109   struct lto_file_decl_data ** file_data_vec
1110     = lto_get_file_decl_data ();
1111   struct lto_file_decl_data * file_data;
1112   unsigned int j = 0;
1113
1114   ipa_init ();
1115
1116   while ((file_data = file_data_vec[j++]))
1117     {
1118       const char *data;
1119       size_t len;
1120       struct lto_input_block *ib
1121         = lto_create_simple_input_block (file_data,
1122                                          LTO_section_ipa_reference,
1123                                          &data, &len);
1124       if (ib)
1125         {
1126           unsigned int i;
1127           unsigned int f_count = lto_input_uleb128 (ib);
1128
1129           for (i = 0; i < f_count; i++)
1130             {
1131               unsigned int j, index;
1132               struct cgraph_node *node;
1133               ipa_reference_local_vars_info_t l;
1134               int v_count;
1135               lto_cgraph_encoder_t encoder;
1136
1137               index = lto_input_uleb128 (ib);
1138               encoder = file_data->cgraph_node_encoder;
1139               node = lto_cgraph_encoder_deref (encoder, index);
1140               l = init_function_info (node);
1141
1142               /* Set the statics read.  */
1143               v_count = lto_input_sleb128 (ib);
1144               if (v_count == -1)
1145                 l->calls_read_all = true;
1146               else
1147                 for (j = 0; j < (unsigned int)v_count; j++)
1148                   {
1149                     unsigned int var_index = lto_input_uleb128 (ib);
1150                     tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1151                                                                    var_index);
1152                     add_static_var (v_decl);
1153                     bitmap_set_bit (l->statics_read, DECL_UID (v_decl));
1154                   }
1155
1156               /* Set the statics written.  */
1157               v_count = lto_input_sleb128 (ib);
1158               if (v_count == -1)
1159                 l->calls_write_all = true;
1160               else
1161                 for (j = 0; j < (unsigned int)v_count; j++)
1162                   {
1163                     unsigned int var_index = lto_input_uleb128 (ib);
1164                     tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1165                                                                    var_index);
1166                     add_static_var (v_decl);
1167                     bitmap_set_bit (l->statics_written, DECL_UID (v_decl));
1168                   }
1169             }
1170
1171           lto_destroy_simple_input_block (file_data,
1172                                           LTO_section_ipa_reference,
1173                                           ib, data, len);
1174         }
1175     }
1176 }
1177
1178
1179 \f
1180 /* Set READ_ALL/WRITE_ALL based on DECL flags.  */
1181 static void
1182 read_write_all_from_decl (tree decl, bool * read_all, bool * write_all)
1183 {
1184   int flags = flags_from_decl_or_type (decl);
1185   if (flags & ECF_CONST)
1186     ;
1187   else if (flags & ECF_PURE)
1188     *read_all = true;
1189   else
1190     {
1191        /* TODO: To be able to produce sane results, we should also handle
1192           common builtins, in particular throw.
1193           Indirect calls hsould be only counted and as inliner is replacing them
1194           by direct calls, we can conclude if any indirect calls are left in body */
1195       *read_all = true;
1196       /* When function does not reutrn, it is safe to ignore anythign it writes
1197          to, because the effect will never happen.  */
1198       if ((flags & (ECF_NOTHROW | ECF_NORETURN))
1199           != (ECF_NOTHROW | ECF_NORETURN))
1200         *write_all = true;
1201     }
1202 }
1203
1204 /* Produce the global information by preforming a transitive closure
1205    on the local information that was produced by ipa_analyze_function
1206    and ipa_analyze_variable.  */
1207
1208 static unsigned int
1209 propagate (void)
1210 {
1211   struct cgraph_node *node;
1212   struct cgraph_node *w;
1213   struct cgraph_node **order =
1214     XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
1215   int order_pos = ipa_utils_reduced_inorder (order, false, true, NULL);
1216   int i;
1217
1218   cgraph_remove_function_insertion_hook (function_insertion_hook_holder);
1219   if (dump_file)
1220     dump_cgraph (dump_file);
1221
1222   /* Propagate the local information thru the call graph to produce
1223      the global information.  All the nodes within a cycle will have
1224      the same info so we collapse cycles first.  Then we can do the
1225      propagation in one pass from the leaves to the roots.  */
1226   order_pos = ipa_utils_reduced_inorder (order, true, true, NULL);
1227   if (dump_file)
1228     ipa_utils_print_order(dump_file, "reduced", order, order_pos);
1229
1230   for (i = 0; i < order_pos; i++ )
1231     {
1232       ipa_reference_vars_info_t node_info;
1233       ipa_reference_global_vars_info_t node_g =
1234         XCNEW (struct ipa_reference_global_vars_info_d);
1235       ipa_reference_local_vars_info_t node_l;
1236       struct cgraph_edge *e;
1237
1238       bool read_all;
1239       bool write_all;
1240       struct ipa_dfs_info * w_info;
1241
1242       node = order[i];
1243       node_info = get_reference_vars_info (node);
1244       if (!node_info)
1245         {
1246           dump_cgraph_node (stderr, node);
1247           dump_cgraph (stderr);
1248           gcc_unreachable ();
1249         }
1250
1251       gcc_assert (!node_info->global);
1252       node_l = node_info->local;
1253
1254       read_all = node_l->calls_read_all;
1255       write_all = node_l->calls_write_all;
1256
1257       /* When function is overwrittable, we can not assume anything.  */
1258       if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
1259         read_write_all_from_decl (node->decl, &read_all, &write_all);
1260
1261       for (e = node->callees; e; e = e->next_callee)
1262         if (cgraph_function_body_availability (e->callee) <= AVAIL_OVERWRITABLE)
1263           read_write_all_from_decl (e->callee->decl, &read_all, &write_all);
1264
1265
1266       /* If any node in a cycle is calls_read_all or calls_write_all
1267          they all are. */
1268       w_info = (struct ipa_dfs_info *) node->aux;
1269       w = w_info->next_cycle;
1270       while (w)
1271         {
1272           ipa_reference_local_vars_info_t w_l =
1273             get_reference_vars_info (w)->local;
1274
1275           /* When function is overwrittable, we can not assume anything.  */
1276           if (cgraph_function_body_availability (w) <= AVAIL_OVERWRITABLE)
1277             read_write_all_from_decl (w->decl, &read_all, &write_all);
1278
1279           for (e = w->callees; e; e = e->next_callee)
1280             if (cgraph_function_body_availability (e->callee) <= AVAIL_OVERWRITABLE)
1281               read_write_all_from_decl (e->callee->decl, &read_all, &write_all);
1282
1283           read_all |= w_l->calls_read_all;
1284           write_all |= w_l->calls_write_all;
1285
1286           w_info = (struct ipa_dfs_info *) w->aux;
1287           w = w_info->next_cycle;
1288         }
1289
1290
1291       /* Initialized the bitmaps for the reduced nodes */
1292       if (read_all)
1293         node_g->statics_read = all_module_statics;
1294       else
1295         {
1296           node_g->statics_read = BITMAP_ALLOC (&global_info_obstack);
1297           bitmap_copy (node_g->statics_read,
1298                        node_l->statics_read);
1299         }
1300       if (write_all)
1301         node_g->statics_written = all_module_statics;
1302       else
1303         {
1304           node_g->statics_written = BITMAP_ALLOC (&global_info_obstack);
1305           bitmap_copy (node_g->statics_written,
1306                        node_l->statics_written);
1307         }
1308
1309       propagate_bits (node_g, node);
1310       w_info = (struct ipa_dfs_info *) node->aux;
1311       w = w_info->next_cycle;
1312       while (w)
1313         {
1314           ipa_reference_vars_info_t w_ri =
1315             get_reference_vars_info (w);
1316           ipa_reference_local_vars_info_t w_l = w_ri->local;
1317
1318           /* These global bitmaps are initialized from the local info
1319              of all of the nodes in the region.  However there is no
1320              need to do any work if the bitmaps were set to
1321              all_module_statics.  */
1322           if (!read_all)
1323             bitmap_ior_into (node_g->statics_read,
1324                              w_l->statics_read);
1325           if (!write_all)
1326             bitmap_ior_into (node_g->statics_written,
1327                              w_l->statics_written);
1328           propagate_bits (node_g, w);
1329           w_info = (struct ipa_dfs_info *) w->aux;
1330           w = w_info->next_cycle;
1331         }
1332
1333       /* All nodes within a cycle have the same global info bitmaps.  */
1334       node_info->global = node_g;
1335       w_info = (struct ipa_dfs_info *) node->aux;
1336       w = w_info->next_cycle;
1337       while (w)
1338         {
1339           ipa_reference_vars_info_t w_ri =
1340             get_reference_vars_info (w);
1341
1342           gcc_assert (!w_ri->global);
1343           w_ri->global = XCNEW (struct ipa_reference_global_vars_info_d);
1344           w_ri->global->statics_read = copy_global_bitmap (node_g->statics_read);
1345           w_ri->global->statics_written = copy_global_bitmap (node_g->statics_written);
1346
1347           w_info = (struct ipa_dfs_info *) w->aux;
1348           w = w_info->next_cycle;
1349         }
1350     }
1351
1352   if (dump_file)
1353     {
1354       for (i = 0; i < order_pos; i++ )
1355         {
1356           ipa_reference_vars_info_t node_info;
1357           ipa_reference_global_vars_info_t node_g;
1358           ipa_reference_local_vars_info_t node_l;
1359           unsigned int index;
1360           bitmap_iterator bi;
1361           struct ipa_dfs_info * w_info;
1362
1363           node = order[i];
1364           node_info = get_reference_vars_info (node);
1365           node_g = node_info->global;
1366           node_l = node_info->local;
1367           fprintf (dump_file,
1368                    "\nFunction name:%s/%i:",
1369                    cgraph_node_name (node), node->uid);
1370           fprintf (dump_file, "\n  locals read: ");
1371           if (node_l->statics_read)
1372             EXECUTE_IF_SET_IN_BITMAP (node_l->statics_read,
1373                                       0, index, bi)
1374               {
1375                 fprintf (dump_file, "%s ",
1376                          get_static_name (index));
1377               }
1378           fprintf (dump_file, "\n  locals written: ");
1379           if (node_l->statics_written)
1380             EXECUTE_IF_SET_IN_BITMAP (node_l->statics_written,
1381                                       0, index, bi)
1382               {
1383                 fprintf(dump_file, "%s ",
1384                         get_static_name (index));
1385               }
1386
1387           w_info = (struct ipa_dfs_info *) node->aux;
1388           w = w_info->next_cycle;
1389           while (w)
1390             {
1391               ipa_reference_vars_info_t w_ri =
1392                 get_reference_vars_info (w);
1393               ipa_reference_local_vars_info_t w_l = w_ri->local;
1394               fprintf (dump_file, "\n  next cycle: %s/%i ",
1395                        cgraph_node_name (w), w->uid);
1396               fprintf (dump_file, "\n    locals read: ");
1397               if (w_l->statics_read)
1398                 EXECUTE_IF_SET_IN_BITMAP (w_l->statics_read,
1399                                           0, index, bi)
1400                   {
1401                     fprintf (dump_file, "%s ",
1402                              get_static_name (index));
1403                   }
1404
1405               fprintf (dump_file, "\n    locals written: ");
1406               if (w_l->statics_written)
1407                 EXECUTE_IF_SET_IN_BITMAP (w_l->statics_written,
1408                                           0, index, bi)
1409                   {
1410                     fprintf (dump_file, "%s ",
1411                              get_static_name (index));
1412                   }
1413
1414               w_info = (struct ipa_dfs_info *) w->aux;
1415               w = w_info->next_cycle;
1416             }
1417           fprintf (dump_file, "\n  globals read: ");
1418           if (node_g->statics_read == all_module_statics)
1419             fprintf (dump_file, "ALL");
1420           else
1421             EXECUTE_IF_SET_IN_BITMAP (node_g->statics_read,
1422                                       0, index, bi)
1423               {
1424                 fprintf (dump_file, "%s ",
1425                          get_static_name (index));
1426               }
1427           fprintf (dump_file, "\n  globals written: ");
1428           if (node_g->statics_written == all_module_statics)
1429             fprintf (dump_file, "ALL");
1430           else
1431             EXECUTE_IF_SET_IN_BITMAP (node_g->statics_written,
1432                                       0, index, bi)
1433               {
1434                 fprintf (dump_file, "%s ",
1435                          get_static_name (index));
1436               }
1437         }
1438     }
1439
1440   /* Cleanup. */
1441   for (i = 0; i < order_pos; i++ )
1442     {
1443       ipa_reference_vars_info_t node_info;
1444       ipa_reference_global_vars_info_t node_g;
1445       node = order[i];
1446       node_info = get_reference_vars_info (node);
1447       node_g = node_info->global;
1448
1449       /* Create the complimentary sets.  These are more useful for
1450          certain apis.  */
1451       node_g->statics_not_read = BITMAP_ALLOC (&global_info_obstack);
1452       node_g->statics_not_written = BITMAP_ALLOC (&global_info_obstack);
1453
1454       if (node_g->statics_read != all_module_statics)
1455         bitmap_and_compl (node_g->statics_not_read,
1456                           all_module_statics,
1457                           node_g->statics_read);
1458
1459       if (node_g->statics_written
1460           != all_module_statics)
1461         bitmap_and_compl (node_g->statics_not_written,
1462                           all_module_statics,
1463                           node_g->statics_written);
1464    }
1465
1466   free (order);
1467
1468   for (node = cgraph_nodes; node; node = node->next)
1469     {
1470       ipa_reference_vars_info_t node_info;
1471       node_info = get_reference_vars_info (node);
1472       /* Get rid of the aux information.  */
1473
1474       if (node->aux)
1475         {
1476           free (node->aux);
1477           node->aux = NULL;
1478         }
1479
1480       if (cgraph_function_body_availability (node) == AVAIL_OVERWRITABLE)
1481         clean_function (node);
1482       else if (node_info)
1483         clean_function_local_data (node);
1484     }
1485   bitmap_obstack_release (&local_info_obstack);
1486   return 0;
1487 }
1488
1489
1490 static bool
1491 gate_reference (void)
1492 {
1493   return (flag_ipa_reference
1494           /* Don't bother doing anything if the program has errors.  */
1495           && !(errorcount || sorrycount));
1496 }
1497
1498 struct ipa_opt_pass_d pass_ipa_reference =
1499 {
1500  {
1501   IPA_PASS,
1502   "static-var",                         /* name */
1503   gate_reference,                       /* gate */
1504   propagate,                            /* execute */
1505   NULL,                                 /* sub */
1506   NULL,                                 /* next */
1507   0,                                    /* static_pass_number */
1508   TV_IPA_REFERENCE,                     /* tv_id */
1509   0,                                    /* properties_required */
1510   0,                                    /* properties_provided */
1511   0,                                    /* properties_destroyed */
1512   0,                                    /* todo_flags_start */
1513   0                                     /* todo_flags_finish */
1514  },
1515  generate_summary,                      /* generate_summary */
1516  ipa_reference_write_summary,           /* write_summary */
1517  ipa_reference_read_summary,            /* read_summary */
1518  NULL,                                  /* write_optimization_summary */
1519  NULL,                                  /* read_optimization_summary */
1520  NULL,                                  /* stmt_fixup */
1521  0,                                     /* TODOs */
1522  NULL,                                  /* function_transform */
1523  NULL                                   /* variable_transform */
1524 };
1525
1526 #include "gt-ipa-reference.h"