xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/ipa-reference.c (revision b7b7574d3bf8eeb51a1fa3977b59142ec6434a55)
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 
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   while (handled_component_p (addr))
356     addr = TREE_OPERAND (addr, 0);
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   if (TREE_CODE (t) == VAR_DECL
368       && has_proper_scope_for_analysis (t))
369     bitmap_set_bit (local->statics_read, DECL_UID (t));
370   return false;
371 }
372 
373 /* Mark store of T.  */
374 
375 static bool
376 mark_store (gimple stmt ATTRIBUTE_UNUSED, tree t, void *data)
377 {
378   ipa_reference_local_vars_info_t local = (ipa_reference_local_vars_info_t)data;
379   if (TREE_CODE (t) == VAR_DECL
380       && has_proper_scope_for_analysis (t))
381     {
382       if (local)
383 	bitmap_set_bit (local->statics_written, DECL_UID (t));
384       /* Mark the write so we can tell which statics are
385 	 readonly.  */
386       if (module_statics_written)
387 	bitmap_set_bit (module_statics_written, DECL_UID (t));
388     }
389   return false;
390 }
391 
392 /* Look for memory clobber and set read_all/write_all if present.  */
393 
394 static void
395 check_asm_memory_clobber (ipa_reference_local_vars_info_t local, gimple stmt)
396 {
397   size_t i;
398   tree op;
399 
400   for (i = 0; i < gimple_asm_nclobbers (stmt); i++)
401     {
402       op = gimple_asm_clobber_op (stmt, i);
403       if (simple_cst_equal(TREE_VALUE (op), memory_identifier_string) == 1)
404 	{
405 	  /* Abandon all hope, ye who enter here. */
406 	  local->calls_read_all = true;
407 	  local->calls_write_all = true;
408 	}
409     }
410 }
411 
412 /* Look for external calls and set read_all/write_all correspondingly.  */
413 
414 static void
415 check_call (ipa_reference_local_vars_info_t local, gimple stmt)
416 {
417   int flags = gimple_call_flags (stmt);
418   tree callee_t = gimple_call_fndecl (stmt);
419 
420   /* Process indirect calls.  All direct calles are handled at propagation
421      time.  */
422   if (!callee_t)
423     {
424       if (flags & ECF_CONST)
425 	;
426       else if (flags & ECF_PURE)
427 	local->calls_read_all = true;
428       else
429 	{
430 	  local->calls_read_all = true;
431 	  /* When function does not reutrn, it is safe to ignore anythign it writes
432 	     to, because the effect will never happen.  */
433 	  if ((flags & (ECF_NOTHROW | ECF_NORETURN))
434 	      != (ECF_NOTHROW | ECF_NORETURN))
435 	    local->calls_write_all = true;
436 	}
437     }
438 }
439 
440 /* TP is the part of the tree currently under the microscope.
441    WALK_SUBTREES is part of the walk_tree api but is unused here.
442    DATA is cgraph_node of the function being walked.  */
443 
444 static tree
445 scan_stmt_for_static_refs (gimple_stmt_iterator *gsip,
446 			   struct cgraph_node *fn)
447 {
448   gimple stmt = gsi_stmt (*gsip);
449   ipa_reference_local_vars_info_t local = NULL;
450 
451   if (is_gimple_debug (stmt))
452     return NULL;
453 
454   if (fn)
455     local = get_reference_vars_info (fn)->local;
456 
457   /* Look for direct loads and stores.  */
458   walk_stmt_load_store_addr_ops (stmt, local, mark_load, mark_store,
459 				 mark_address);
460 
461   if (is_gimple_call (stmt))
462     check_call (local, stmt);
463   else if (gimple_code (stmt) == GIMPLE_ASM)
464     check_asm_memory_clobber (local, stmt);
465 
466   return NULL;
467 }
468 
469 /* Call-back to scan variable initializers for static references.
470    Called using walk_tree.  */
471 
472 static tree
473 scan_initializer_for_static_refs (tree *tp, int *walk_subtrees,
474 				  void *data ATTRIBUTE_UNUSED)
475 {
476   tree t = *tp;
477 
478   if (TREE_CODE (t) == ADDR_EXPR)
479     {
480       mark_address_taken (get_base_var (t));
481       *walk_subtrees = 0;
482     }
483   /* Save some cycles by not walking types and declaration as we
484      won't find anything useful there anyway.  */
485   else if (IS_TYPE_OR_DECL_P (*tp))
486     *walk_subtrees = 0;
487 
488   return NULL;
489 }
490 
491 /* Lookup the tree node for the static variable that has UID.  */
492 static tree
493 get_static_decl (int index)
494 {
495   splay_tree_node stn =
496     splay_tree_lookup (reference_vars_to_consider, index);
497   if (stn)
498     return (tree)stn->value;
499   return NULL;
500 }
501 
502 /* Lookup the tree node for the static variable that has UID and
503    convert the name to a string for debugging.  */
504 
505 static const char *
506 get_static_name (int index)
507 {
508   splay_tree_node stn =
509     splay_tree_lookup (reference_vars_to_consider, index);
510   if (stn)
511     return lang_hooks.decl_printable_name ((tree)(stn->value), 2);
512   return NULL;
513 }
514 
515 /* Or in all of the bits from every callee of X into X_GLOBAL, the caller's cycle,
516    bit vector.  There are several cases to check to avoid the sparse
517    bitmap oring.  */
518 
519 static void
520 propagate_bits (ipa_reference_global_vars_info_t x_global, struct cgraph_node *x)
521 {
522   struct cgraph_edge *e;
523   for (e = x->callees; e; e = e->next_callee)
524     {
525       struct cgraph_node *y = e->callee;
526 
527       /* Only look into nodes we can propagate something.  */
528       if (cgraph_function_body_availability (e->callee) > AVAIL_OVERWRITABLE)
529 	{
530 	  if (get_reference_vars_info (y))
531 	    {
532 	      ipa_reference_vars_info_t y_info
533 		= get_reference_vars_info (y);
534 	      ipa_reference_global_vars_info_t y_global = y_info->global;
535 
536 	      /* Calls in current cycle do not have global computed yet.  */
537 	      if (!y_info->global)
538 		continue;
539 
540 	      if (x_global->statics_read
541 		  != all_module_statics)
542 		{
543 		  if (y_global->statics_read
544 		      == all_module_statics)
545 		    {
546 		      BITMAP_FREE (x_global->statics_read);
547 		      x_global->statics_read
548 			= all_module_statics;
549 		    }
550 		  /* Skip bitmaps that are pointer equal to node's bitmap
551 		     (no reason to spin within the cycle).  */
552 		  else if (x_global->statics_read
553 			   != y_global->statics_read)
554 		    bitmap_ior_into (x_global->statics_read,
555 				     y_global->statics_read);
556 		}
557 
558 	      if (x_global->statics_written
559 		  != all_module_statics)
560 		{
561 		  if (y_global->statics_written
562 		      == all_module_statics)
563 		    {
564 		      BITMAP_FREE (x_global->statics_written);
565 		      x_global->statics_written
566 			= all_module_statics;
567 		    }
568 		  /* Skip bitmaps that are pointer equal to node's bitmap
569 		     (no reason to spin within the cycle).  */
570 		  else if (x_global->statics_written
571 			   != y_global->statics_written)
572 		    bitmap_ior_into (x_global->statics_written,
573 				     y_global->statics_written);
574 		}
575 	    }
576 	  else
577 	    gcc_unreachable ();
578 	}
579     }
580 }
581 
582 /* The init routine for analyzing global static variable usage.  See
583    comments at top for description.  */
584 static void
585 ipa_init (void)
586 {
587   static bool init_p = false;
588 
589   if (init_p)
590     return;
591 
592   init_p = true;
593 
594   memory_identifier_string = build_string(7, "memory");
595 
596   reference_vars_to_consider =
597     splay_tree_new_ggc (splay_tree_compare_ints);
598 
599   bitmap_obstack_initialize (&local_info_obstack);
600   bitmap_obstack_initialize (&global_info_obstack);
601   module_statics_escape = BITMAP_ALLOC (&local_info_obstack);
602   module_statics_written = BITMAP_ALLOC (&local_info_obstack);
603   all_module_statics = BITMAP_ALLOC (&global_info_obstack);
604 
605   /* There are some shared nodes, in particular the initializers on
606      static declarations.  We do not need to scan them more than once
607      since all we would be interested in are the addressof
608      operations.  */
609   visited_nodes = pointer_set_create ();
610 
611   function_insertion_hook_holder =
612       cgraph_add_function_insertion_hook (&add_new_function, NULL);
613   node_removal_hook_holder =
614       cgraph_add_node_removal_hook (&remove_node_data, NULL);
615   node_duplication_hook_holder =
616       cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
617 }
618 
619 /* Check out the rhs of a static or global initialization VNODE to see
620    if any of them contain addressof operations.  Note that some of
621    these variables may  not even be referenced in the code in this
622    compilation unit but their right hand sides may contain references
623    to variables defined within this unit.  */
624 
625 static void
626 analyze_variable (struct varpool_node *vnode)
627 {
628   struct walk_stmt_info wi;
629   tree global = vnode->decl;
630 
631   memset (&wi, 0, sizeof (wi));
632   wi.pset = visited_nodes;
633   walk_tree (&DECL_INITIAL (global), scan_initializer_for_static_refs,
634              &wi, wi.pset);
635 }
636 
637 
638 /* Set up the persistent info for FN.  */
639 
640 static ipa_reference_local_vars_info_t
641 init_function_info (struct cgraph_node *fn)
642 {
643   ipa_reference_vars_info_t info
644     = XCNEW (struct ipa_reference_vars_info_d);
645   ipa_reference_local_vars_info_t l
646     = XCNEW (struct ipa_reference_local_vars_info_d);
647 
648   /* Add the info to the tree's annotation.  */
649   set_reference_vars_info (fn, info);
650 
651   info->local = l;
652   l->statics_read = BITMAP_ALLOC (&local_info_obstack);
653   l->statics_written = BITMAP_ALLOC (&local_info_obstack);
654 
655   return l;
656 }
657 
658 
659 /* This is the main routine for finding the reference patterns for
660    global variables within a function FN.  */
661 
662 static void
663 analyze_function (struct cgraph_node *fn)
664 {
665   tree decl = fn->decl;
666   struct function *this_cfun = DECL_STRUCT_FUNCTION (decl);
667   basic_block this_block;
668 #ifdef ENABLE_CHECKING
669   tree step;
670 #endif
671   ipa_reference_local_vars_info_t local;
672 
673   if (dump_file)
674     fprintf (dump_file, "\n local analysis of %s\n", cgraph_node_name (fn));
675 
676   push_cfun (DECL_STRUCT_FUNCTION (decl));
677   current_function_decl = decl;
678 
679   init_function_info (fn);
680   FOR_EACH_BB_FN (this_block, this_cfun)
681     {
682       gimple_stmt_iterator gsi;
683       gimple phi;
684       tree op;
685       use_operand_p use;
686       ssa_op_iter iter;
687 
688       /* Find the addresses taken in phi node arguments.  */
689       for (gsi = gsi_start_phis (this_block);
690 	   !gsi_end_p (gsi);
691 	   gsi_next (&gsi))
692 	{
693 	  phi = gsi_stmt (gsi);
694 	  FOR_EACH_PHI_ARG (use, phi, iter, SSA_OP_USE)
695 	    {
696 	      op = USE_FROM_PTR (use);
697 	      if (TREE_CODE (op) == ADDR_EXPR)
698 		mark_address_taken (get_base_var (op));
699 	    }
700 	}
701 
702       for (gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi))
703 	scan_stmt_for_static_refs (&gsi, fn);
704     }
705 
706   local = get_reference_vars_info (fn)->local;
707   if ((flags_from_decl_or_type (decl) & (ECF_NOTHROW | ECF_NORETURN))
708       == (ECF_NOTHROW | ECF_NORETURN))
709     {
710       local->calls_write_all = false;
711       bitmap_clear (local->statics_written);
712     }
713 
714   /* Free bitmaps of direct references if we can not use them anyway.  */
715   if (local->calls_write_all)
716     BITMAP_FREE (local->statics_written);
717   if (local->calls_read_all)
718     BITMAP_FREE (local->statics_read);
719 
720 
721 #ifdef ENABLE_CHECKING
722   /* Verify that all local initializers was expanded by gimplifier.  */
723   for (step = DECL_STRUCT_FUNCTION (decl)->local_decls;
724        step;
725        step = TREE_CHAIN (step))
726     {
727       tree var = TREE_VALUE (step);
728       if (TREE_CODE (var) == VAR_DECL
729 	  && DECL_INITIAL (var)
730 	  && !TREE_STATIC (var))
731 	gcc_unreachable ();
732     }
733 #endif
734   pop_cfun ();
735   current_function_decl = NULL;
736 }
737 
738 /* Remove local data associated with function FN.  */
739 static void
740 clean_function_local_data (struct cgraph_node *fn)
741 {
742   ipa_reference_vars_info_t info = get_reference_vars_info (fn);
743   ipa_reference_local_vars_info_t l = info->local;
744   if (l)
745     {
746       if (l->statics_read
747 	  && l->statics_read != all_module_statics)
748 	BITMAP_FREE (l->statics_read);
749       if (l->statics_written
750 	  &&l->statics_written != all_module_statics)
751 	BITMAP_FREE (l->statics_written);
752       free (l);
753       info->local = NULL;
754     }
755 }
756 
757 /* Remove all data associated with function FN.  */
758 
759 static void
760 clean_function (struct cgraph_node *fn)
761 {
762   ipa_reference_vars_info_t info = get_reference_vars_info (fn);
763   ipa_reference_global_vars_info_t g = info->global;
764 
765   clean_function_local_data (fn);
766   if (g)
767     {
768       if (g->statics_read
769 	  && g->statics_read != all_module_statics)
770 	BITMAP_FREE (g->statics_read);
771 
772       if (g->statics_written
773 	  && g->statics_written != all_module_statics)
774 	BITMAP_FREE (g->statics_written);
775 
776       if (g->statics_not_read
777 	  && g->statics_not_read != all_module_statics)
778 	BITMAP_FREE (g->statics_not_read);
779 
780       if (g->statics_not_written
781 	  && g->statics_not_written != all_module_statics)
782 	BITMAP_FREE (g->statics_not_written);
783       free (g);
784       info->global = NULL;
785     }
786 
787   free (get_reference_vars_info (fn));
788   set_reference_vars_info (fn, NULL);
789 }
790 
791 /* Called when new function is inserted to callgraph late.  */
792 static void
793 add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
794 {
795   /* There are some shared nodes, in particular the initializers on
796      static declarations.  We do not need to scan them more than once
797      since all we would be interested in are the addressof
798      operations.  */
799   analyze_function (node);
800   visited_nodes = NULL;
801 }
802 
803 static bitmap
804 copy_local_bitmap (bitmap src)
805 {
806   bitmap dst;
807   if (!src)
808     return NULL;
809   if (src == all_module_statics)
810     return all_module_statics;
811   dst = BITMAP_ALLOC (&local_info_obstack);
812   bitmap_copy (dst, src);
813   return dst;
814 }
815 
816 static bitmap
817 copy_global_bitmap (bitmap src)
818 {
819   bitmap dst;
820   if (!src)
821     return NULL;
822   if (src == all_module_statics)
823     return all_module_statics;
824   dst = BITMAP_ALLOC (&global_info_obstack);
825   bitmap_copy (dst, src);
826   return dst;
827 }
828 
829 /* Called when new clone is inserted to callgraph late.  */
830 
831 static void
832 duplicate_node_data (struct cgraph_node *src, struct cgraph_node *dst,
833 	 	     void *data ATTRIBUTE_UNUSED)
834 {
835   ipa_reference_global_vars_info_t ginfo;
836   ipa_reference_local_vars_info_t linfo;
837   ipa_reference_global_vars_info_t dst_ginfo;
838   ipa_reference_local_vars_info_t dst_linfo;
839 
840   ginfo = get_global_reference_vars_info (src);
841   linfo = get_local_reference_vars_info (src);
842   if (!linfo && !ginfo)
843     return;
844   init_function_info (dst);
845   if (linfo)
846     {
847       dst_linfo = get_local_reference_vars_info (dst);
848       dst_linfo->statics_read = copy_local_bitmap (linfo->statics_read);
849       dst_linfo->statics_written = copy_local_bitmap (linfo->statics_written);
850       dst_linfo->calls_read_all = linfo->calls_read_all;
851       dst_linfo->calls_write_all = linfo->calls_write_all;
852     }
853   if (ginfo)
854     {
855       get_reference_vars_info (dst)->global = XCNEW (struct ipa_reference_global_vars_info_d);
856       dst_ginfo = get_global_reference_vars_info (dst);
857       dst_ginfo->statics_read = copy_global_bitmap (ginfo->statics_read);
858       dst_ginfo->statics_written = copy_global_bitmap (ginfo->statics_written);
859       dst_ginfo->statics_not_read = copy_global_bitmap (ginfo->statics_not_read);
860       dst_ginfo->statics_not_written = copy_global_bitmap (ginfo->statics_not_written);
861     }
862 }
863 
864 /* Called when node is removed.  */
865 
866 static void
867 remove_node_data (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
868 {
869   if (get_reference_vars_info (node))
870     clean_function (node);
871 }
872 
873 /* Analyze each function in the cgraph to see which global or statics
874    are read or written.  */
875 
876 static void
877 generate_summary (void)
878 {
879   struct cgraph_node *node;
880   struct varpool_node *vnode;
881   unsigned int index;
882   bitmap_iterator bi;
883   bitmap module_statics_readonly;
884   bitmap bm_temp;
885 
886   ipa_init ();
887   module_statics_readonly = BITMAP_ALLOC (&local_info_obstack);
888   bm_temp = BITMAP_ALLOC (&local_info_obstack);
889 
890   /* Process all of the variables first.  */
891   FOR_EACH_STATIC_INITIALIZER (vnode)
892     analyze_variable (vnode);
893 
894   /* Process all of the functions next.
895 
896      We do not want to process any of the clones so we check that this
897      is a master clone.  However, we do need to process any
898      AVAIL_OVERWRITABLE functions (these are never clones) because
899      they may cause a static variable to escape.  The code that can
900      overwrite such a function cannot access the statics because it
901      would not be in the same compilation unit.  When the analysis is
902      finished, the computed information of these AVAIL_OVERWRITABLE is
903      replaced with worst case info.
904   */
905   for (node = cgraph_nodes; node; node = node->next)
906     if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
907       analyze_function (node);
908 
909   pointer_set_destroy (visited_nodes);
910   visited_nodes = NULL;
911 
912   /* Prune out the variables that were found to behave badly
913      (i.e. have their address taken).  */
914   EXECUTE_IF_SET_IN_BITMAP (module_statics_escape, 0, index, bi)
915     {
916       splay_tree_remove (reference_vars_to_consider, index);
917     }
918 
919   bitmap_and_compl_into (all_module_statics,
920 			 module_statics_escape);
921 
922   bitmap_and_compl (module_statics_readonly, all_module_statics,
923 		    module_statics_written);
924 
925   /* If the address is not taken, we can unset the addressable bit
926      on this variable.  */
927   EXECUTE_IF_SET_IN_BITMAP (all_module_statics, 0, index, bi)
928     {
929       tree var = get_static_decl (index);
930       TREE_ADDRESSABLE (var) = 0;
931       if (dump_file)
932 	fprintf (dump_file, "Not TREE_ADDRESSABLE var %s\n",
933 		 get_static_name (index));
934     }
935 
936   /* If the variable is never written, we can set the TREE_READONLY
937      flag.  Additionally if it has a DECL_INITIAL that is made up of
938      constants we can treat the entire global as a constant.  */
939 
940   bitmap_and_compl (module_statics_readonly, all_module_statics,
941 		    module_statics_written);
942   EXECUTE_IF_SET_IN_BITMAP (module_statics_readonly, 0, index, bi)
943     {
944       tree var = get_static_decl (index);
945 
946       /* Ignore variables in named sections - changing TREE_READONLY
947 	 changes the section flags, potentially causing conflicts with
948 	 other variables in the same named section.  */
949       if (DECL_SECTION_NAME (var) == NULL_TREE)
950 	{
951 	  TREE_READONLY (var) = 1;
952 	  if (dump_file)
953 	    fprintf (dump_file, "read-only var %s\n",
954 		     get_static_name (index));
955 	}
956     }
957 
958   BITMAP_FREE(module_statics_escape);
959   BITMAP_FREE(module_statics_written);
960   module_statics_escape = NULL;
961   module_statics_written = NULL;
962 
963   if (dump_file)
964     EXECUTE_IF_SET_IN_BITMAP (all_module_statics, 0, index, bi)
965       {
966 	fprintf (dump_file, "\nPromotable global:%s",
967 		 get_static_name (index));
968       }
969 
970   for (node = cgraph_nodes; node; node = node->next)
971     if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
972       {
973 	ipa_reference_local_vars_info_t l;
974 	l = get_reference_vars_info (node)->local;
975 
976 	/* Any variables that are not in all_module_statics are
977 	   removed from the local maps.  This will include all of the
978 	   variables that were found to escape in the function
979 	   scanning.  */
980 	if (l->statics_read)
981 	  bitmap_and_into (l->statics_read,
982 			   all_module_statics);
983 	if (l->statics_written)
984 	  bitmap_and_into (l->statics_written,
985 			   all_module_statics);
986       }
987 
988   BITMAP_FREE(module_statics_readonly);
989   BITMAP_FREE(bm_temp);
990 
991   if (dump_file)
992     for (node = cgraph_nodes; node; node = node->next)
993       if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
994 	{
995 	  ipa_reference_local_vars_info_t l;
996 	  unsigned int index;
997 	  bitmap_iterator bi;
998 
999 	  l = get_reference_vars_info (node)->local;
1000 	  fprintf (dump_file,
1001 		   "\nFunction name:%s/%i:",
1002 		   cgraph_node_name (node), node->uid);
1003 	  fprintf (dump_file, "\n  locals read: ");
1004 	  if (l->statics_read)
1005 	    EXECUTE_IF_SET_IN_BITMAP (l->statics_read,
1006 				      0, index, bi)
1007 	      {
1008 	        fprintf (dump_file, "%s ",
1009 		         get_static_name (index));
1010 	      }
1011 	  fprintf (dump_file, "\n  locals written: ");
1012 	  if (l->statics_written)
1013 	    EXECUTE_IF_SET_IN_BITMAP (l->statics_written,
1014 				      0, index, bi)
1015 	      {
1016 	        fprintf(dump_file, "%s ",
1017 		        get_static_name (index));
1018 	      }
1019 	  if (l->calls_read_all)
1020 	     fprintf (dump_file, "\n  calls read all: ");
1021 	  if (l->calls_write_all)
1022 	     fprintf (dump_file, "\n  calls read all: ");
1023 	}
1024 }
1025 
1026 
1027 /* Return true if we need to write summary of NODE. */
1028 
1029 static bool
1030 write_node_summary_p (struct cgraph_node *node)
1031 {
1032   gcc_assert (node->global.inlined_to == NULL);
1033   return (node->analyzed
1034 	  && cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE
1035 	  && get_reference_vars_info (node) != NULL);
1036 }
1037 
1038 /* Serialize the ipa info for lto.  */
1039 
1040 static void
1041 ipa_reference_write_summary (cgraph_node_set set)
1042 {
1043   struct cgraph_node *node;
1044   struct lto_simple_output_block *ob
1045     = lto_create_simple_output_block (LTO_section_ipa_reference);
1046   unsigned int count = 0;
1047   cgraph_node_set_iterator csi;
1048 
1049   for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
1050     if (write_node_summary_p (csi_node (csi)))
1051 	count++;
1052 
1053   lto_output_uleb128_stream (ob->main_stream, count);
1054 
1055   /* Process all of the functions.  */
1056   for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
1057     {
1058       node = csi_node (csi);
1059       if (write_node_summary_p (node))
1060 	{
1061 	  ipa_reference_local_vars_info_t l
1062 	    = get_reference_vars_info (node)->local;
1063 	  unsigned int index;
1064 	  bitmap_iterator bi;
1065 	  lto_cgraph_encoder_t encoder;
1066 	  int node_ref;
1067 
1068 	  encoder = ob->decl_state->cgraph_node_encoder;
1069 	  node_ref = lto_cgraph_encoder_encode (encoder, node);
1070 	  lto_output_uleb128_stream (ob->main_stream, node_ref);
1071 
1072 	  /* Stream out the statics read.  */
1073 	  if (l->calls_read_all)
1074 	    lto_output_sleb128_stream (ob->main_stream, -1);
1075 	  else
1076 	    {
1077 	      lto_output_sleb128_stream (ob->main_stream,
1078 					 bitmap_count_bits (l->statics_read));
1079 	      EXECUTE_IF_SET_IN_BITMAP (l->statics_read, 0, index, bi)
1080 		lto_output_var_decl_index(ob->decl_state, ob->main_stream,
1081 					  get_static_decl (index));
1082 	    }
1083 
1084 	  /* Stream out the statics written.  */
1085 	  if (l->calls_write_all)
1086 	    lto_output_sleb128_stream (ob->main_stream, -1);
1087 	  else
1088 	    {
1089 	      lto_output_sleb128_stream (ob->main_stream,
1090 					 bitmap_count_bits (l->statics_written));
1091 	      EXECUTE_IF_SET_IN_BITMAP (l->statics_written, 0, index, bi)
1092 		lto_output_var_decl_index(ob->decl_state, ob->main_stream,
1093 					  get_static_decl (index));
1094 	    }
1095 	}
1096     }
1097   lto_destroy_simple_output_block (ob);
1098 }
1099 
1100 
1101 /* Deserialize the ipa info for lto.  */
1102 
1103 static void
1104 ipa_reference_read_summary (void)
1105 {
1106   struct lto_file_decl_data ** file_data_vec
1107     = lto_get_file_decl_data ();
1108   struct lto_file_decl_data * file_data;
1109   unsigned int j = 0;
1110 
1111   ipa_init ();
1112 
1113   while ((file_data = file_data_vec[j++]))
1114     {
1115       const char *data;
1116       size_t len;
1117       struct lto_input_block *ib
1118 	= lto_create_simple_input_block (file_data,
1119 					 LTO_section_ipa_reference,
1120 					 &data, &len);
1121       if (ib)
1122 	{
1123 	  unsigned int i;
1124 	  unsigned int f_count = lto_input_uleb128 (ib);
1125 
1126 	  for (i = 0; i < f_count; i++)
1127 	    {
1128 	      unsigned int j, index;
1129 	      struct cgraph_node *node;
1130 	      ipa_reference_local_vars_info_t l;
1131 	      int v_count;
1132 	      lto_cgraph_encoder_t encoder;
1133 
1134 	      index = lto_input_uleb128 (ib);
1135 	      encoder = file_data->cgraph_node_encoder;
1136 	      node = lto_cgraph_encoder_deref (encoder, index);
1137 	      l = init_function_info (node);
1138 
1139 	      /* Set the statics read.  */
1140 	      v_count = lto_input_sleb128 (ib);
1141 	      if (v_count == -1)
1142 	        l->calls_read_all = true;
1143 	      else
1144 		for (j = 0; j < (unsigned int)v_count; j++)
1145 		  {
1146 		    unsigned int var_index = lto_input_uleb128 (ib);
1147 		    tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1148 								   var_index);
1149 		    add_static_var (v_decl);
1150 		    bitmap_set_bit (l->statics_read, DECL_UID (v_decl));
1151 		  }
1152 
1153 	      /* Set the statics written.  */
1154 	      v_count = lto_input_sleb128 (ib);
1155 	      if (v_count == -1)
1156 	        l->calls_write_all = true;
1157 	      else
1158 		for (j = 0; j < (unsigned int)v_count; j++)
1159 		  {
1160 		    unsigned int var_index = lto_input_uleb128 (ib);
1161 		    tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1162 								   var_index);
1163 		    add_static_var (v_decl);
1164 		    bitmap_set_bit (l->statics_written, DECL_UID (v_decl));
1165 		  }
1166 	    }
1167 
1168 	  lto_destroy_simple_input_block (file_data,
1169 					  LTO_section_ipa_reference,
1170 					  ib, data, len);
1171 	}
1172     }
1173 }
1174 
1175 
1176 
1177 /* Set READ_ALL/WRITE_ALL based on DECL flags.  */
1178 static void
1179 read_write_all_from_decl (tree decl, bool * read_all, bool * write_all)
1180 {
1181   int flags = flags_from_decl_or_type (decl);
1182   if (flags & ECF_CONST)
1183     ;
1184   else if (flags & ECF_PURE)
1185     *read_all = true;
1186   else
1187     {
1188        /* TODO: To be able to produce sane results, we should also handle
1189 	  common builtins, in particular throw.
1190 	  Indirect calls hsould be only counted and as inliner is replacing them
1191 	  by direct calls, we can conclude if any indirect calls are left in body */
1192       *read_all = true;
1193       /* When function does not reutrn, it is safe to ignore anythign it writes
1194 	 to, because the effect will never happen.  */
1195       if ((flags & (ECF_NOTHROW | ECF_NORETURN))
1196 	  != (ECF_NOTHROW | ECF_NORETURN))
1197         *write_all = true;
1198     }
1199 }
1200 
1201 /* Produce the global information by preforming a transitive closure
1202    on the local information that was produced by ipa_analyze_function
1203    and ipa_analyze_variable.  */
1204 
1205 static unsigned int
1206 propagate (void)
1207 {
1208   struct cgraph_node *node;
1209   struct cgraph_node *w;
1210   struct cgraph_node **order =
1211     XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
1212   int order_pos = ipa_utils_reduced_inorder (order, false, true, NULL);
1213   int i;
1214 
1215   cgraph_remove_function_insertion_hook (function_insertion_hook_holder);
1216   if (dump_file)
1217     dump_cgraph (dump_file);
1218 
1219   /* Propagate the local information thru the call graph to produce
1220      the global information.  All the nodes within a cycle will have
1221      the same info so we collapse cycles first.  Then we can do the
1222      propagation in one pass from the leaves to the roots.  */
1223   order_pos = ipa_utils_reduced_inorder (order, true, true, NULL);
1224   if (dump_file)
1225     ipa_utils_print_order(dump_file, "reduced", order, order_pos);
1226 
1227   for (i = 0; i < order_pos; i++ )
1228     {
1229       ipa_reference_vars_info_t node_info;
1230       ipa_reference_global_vars_info_t node_g =
1231 	XCNEW (struct ipa_reference_global_vars_info_d);
1232       ipa_reference_local_vars_info_t node_l;
1233       struct cgraph_edge *e;
1234 
1235       bool read_all;
1236       bool write_all;
1237       struct ipa_dfs_info * w_info;
1238 
1239       node = order[i];
1240       node_info = get_reference_vars_info (node);
1241       if (!node_info)
1242 	{
1243 	  dump_cgraph_node (stderr, node);
1244 	  dump_cgraph (stderr);
1245 	  gcc_unreachable ();
1246 	}
1247 
1248       gcc_assert (!node_info->global);
1249       node_l = node_info->local;
1250 
1251       read_all = node_l->calls_read_all;
1252       write_all = node_l->calls_write_all;
1253 
1254       /* When function is overwrittable, we can not assume anything.  */
1255       if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
1256         read_write_all_from_decl (node->decl, &read_all, &write_all);
1257 
1258       for (e = node->callees; e; e = e->next_callee)
1259         if (cgraph_function_body_availability (e->callee) <= AVAIL_OVERWRITABLE)
1260           read_write_all_from_decl (e->callee->decl, &read_all, &write_all);
1261 
1262 
1263       /* If any node in a cycle is calls_read_all or calls_write_all
1264 	 they all are. */
1265       w_info = (struct ipa_dfs_info *) node->aux;
1266       w = w_info->next_cycle;
1267       while (w)
1268 	{
1269 	  ipa_reference_local_vars_info_t w_l =
1270 	    get_reference_vars_info (w)->local;
1271 
1272 	  /* When function is overwrittable, we can not assume anything.  */
1273 	  if (cgraph_function_body_availability (w) <= AVAIL_OVERWRITABLE)
1274 	    read_write_all_from_decl (w->decl, &read_all, &write_all);
1275 
1276 	  for (e = w->callees; e; e = e->next_callee)
1277 	    if (cgraph_function_body_availability (e->callee) <= AVAIL_OVERWRITABLE)
1278 	      read_write_all_from_decl (e->callee->decl, &read_all, &write_all);
1279 
1280 	  read_all |= w_l->calls_read_all;
1281 	  write_all |= w_l->calls_write_all;
1282 
1283 	  w_info = (struct ipa_dfs_info *) w->aux;
1284 	  w = w_info->next_cycle;
1285 	}
1286 
1287 
1288       /* Initialized the bitmaps for the reduced nodes */
1289       if (read_all)
1290 	node_g->statics_read = all_module_statics;
1291       else
1292 	{
1293 	  node_g->statics_read = BITMAP_ALLOC (&global_info_obstack);
1294 	  bitmap_copy (node_g->statics_read,
1295 		       node_l->statics_read);
1296 	}
1297       if (write_all)
1298 	node_g->statics_written = all_module_statics;
1299       else
1300 	{
1301 	  node_g->statics_written = BITMAP_ALLOC (&global_info_obstack);
1302 	  bitmap_copy (node_g->statics_written,
1303 		       node_l->statics_written);
1304 	}
1305 
1306       propagate_bits (node_g, node);
1307       w_info = (struct ipa_dfs_info *) node->aux;
1308       w = w_info->next_cycle;
1309       while (w)
1310 	{
1311 	  ipa_reference_vars_info_t w_ri =
1312 	    get_reference_vars_info (w);
1313 	  ipa_reference_local_vars_info_t w_l = w_ri->local;
1314 
1315 	  /* These global bitmaps are initialized from the local info
1316 	     of all of the nodes in the region.  However there is no
1317 	     need to do any work if the bitmaps were set to
1318 	     all_module_statics.  */
1319 	  if (!read_all)
1320 	    bitmap_ior_into (node_g->statics_read,
1321 			     w_l->statics_read);
1322 	  if (!write_all)
1323 	    bitmap_ior_into (node_g->statics_written,
1324 			     w_l->statics_written);
1325 	  propagate_bits (node_g, w);
1326 	  w_info = (struct ipa_dfs_info *) w->aux;
1327 	  w = w_info->next_cycle;
1328 	}
1329 
1330       /* All nodes within a cycle have the same global info bitmaps.  */
1331       node_info->global = node_g;
1332       w_info = (struct ipa_dfs_info *) node->aux;
1333       w = w_info->next_cycle;
1334       while (w)
1335 	{
1336 	  ipa_reference_vars_info_t w_ri =
1337 	    get_reference_vars_info (w);
1338 
1339 	  gcc_assert (!w_ri->global);
1340           w_ri->global = XCNEW (struct ipa_reference_global_vars_info_d);
1341 	  w_ri->global->statics_read = copy_global_bitmap (node_g->statics_read);
1342 	  w_ri->global->statics_written = copy_global_bitmap (node_g->statics_written);
1343 
1344 	  w_info = (struct ipa_dfs_info *) w->aux;
1345 	  w = w_info->next_cycle;
1346 	}
1347     }
1348 
1349   if (dump_file)
1350     {
1351       for (i = 0; i < order_pos; i++ )
1352 	{
1353 	  ipa_reference_vars_info_t node_info;
1354 	  ipa_reference_global_vars_info_t node_g;
1355 	  ipa_reference_local_vars_info_t node_l;
1356 	  unsigned int index;
1357 	  bitmap_iterator bi;
1358 	  struct ipa_dfs_info * w_info;
1359 
1360 	  node = order[i];
1361 	  node_info = get_reference_vars_info (node);
1362 	  node_g = node_info->global;
1363 	  node_l = node_info->local;
1364 	  fprintf (dump_file,
1365 		   "\nFunction name:%s/%i:",
1366 		   cgraph_node_name (node), node->uid);
1367 	  fprintf (dump_file, "\n  locals read: ");
1368 	  if (node_l->statics_read)
1369 	    EXECUTE_IF_SET_IN_BITMAP (node_l->statics_read,
1370 				      0, index, bi)
1371 	      {
1372 		fprintf (dump_file, "%s ",
1373 			 get_static_name (index));
1374 	      }
1375 	  fprintf (dump_file, "\n  locals written: ");
1376 	  if (node_l->statics_written)
1377 	    EXECUTE_IF_SET_IN_BITMAP (node_l->statics_written,
1378 				      0, index, bi)
1379 	      {
1380 		fprintf(dump_file, "%s ",
1381 			get_static_name (index));
1382 	      }
1383 
1384 	  w_info = (struct ipa_dfs_info *) node->aux;
1385 	  w = w_info->next_cycle;
1386 	  while (w)
1387 	    {
1388 	      ipa_reference_vars_info_t w_ri =
1389 		get_reference_vars_info (w);
1390 	      ipa_reference_local_vars_info_t w_l = w_ri->local;
1391 	      fprintf (dump_file, "\n  next cycle: %s/%i ",
1392 		       cgraph_node_name (w), w->uid);
1393 	      fprintf (dump_file, "\n    locals read: ");
1394 	      if (w_l->statics_read)
1395 		EXECUTE_IF_SET_IN_BITMAP (w_l->statics_read,
1396 					  0, index, bi)
1397 		  {
1398 		    fprintf (dump_file, "%s ",
1399 			     get_static_name (index));
1400 		  }
1401 
1402 	      fprintf (dump_file, "\n    locals written: ");
1403 	      if (w_l->statics_written)
1404 		EXECUTE_IF_SET_IN_BITMAP (w_l->statics_written,
1405 					  0, index, bi)
1406 		  {
1407 		    fprintf (dump_file, "%s ",
1408 			     get_static_name (index));
1409 		  }
1410 
1411 	      w_info = (struct ipa_dfs_info *) w->aux;
1412 	      w = w_info->next_cycle;
1413 	    }
1414 	  fprintf (dump_file, "\n  globals read: ");
1415 	  if (node_g->statics_read == all_module_statics)
1416 	    fprintf (dump_file, "ALL");
1417 	  else
1418 	    EXECUTE_IF_SET_IN_BITMAP (node_g->statics_read,
1419 				      0, index, bi)
1420 	      {
1421 	        fprintf (dump_file, "%s ",
1422 		         get_static_name (index));
1423 	      }
1424 	  fprintf (dump_file, "\n  globals written: ");
1425 	  if (node_g->statics_written == all_module_statics)
1426 	    fprintf (dump_file, "ALL");
1427 	  else
1428 	    EXECUTE_IF_SET_IN_BITMAP (node_g->statics_written,
1429 				      0, index, bi)
1430 	      {
1431 		fprintf (dump_file, "%s ",
1432 			 get_static_name (index));
1433 	      }
1434 	}
1435     }
1436 
1437   /* Cleanup. */
1438   for (i = 0; i < order_pos; i++ )
1439     {
1440       ipa_reference_vars_info_t node_info;
1441       ipa_reference_global_vars_info_t node_g;
1442       node = order[i];
1443       node_info = get_reference_vars_info (node);
1444       node_g = node_info->global;
1445 
1446       /* Create the complimentary sets.  These are more useful for
1447 	 certain apis.  */
1448       node_g->statics_not_read = BITMAP_ALLOC (&global_info_obstack);
1449       node_g->statics_not_written = BITMAP_ALLOC (&global_info_obstack);
1450 
1451       if (node_g->statics_read != all_module_statics)
1452 	bitmap_and_compl (node_g->statics_not_read,
1453 			  all_module_statics,
1454 			  node_g->statics_read);
1455 
1456       if (node_g->statics_written
1457 	  != all_module_statics)
1458 	bitmap_and_compl (node_g->statics_not_written,
1459 			  all_module_statics,
1460 			  node_g->statics_written);
1461    }
1462 
1463   free (order);
1464 
1465   for (node = cgraph_nodes; node; node = node->next)
1466     {
1467       ipa_reference_vars_info_t node_info;
1468       node_info = get_reference_vars_info (node);
1469       /* Get rid of the aux information.  */
1470 
1471       if (node->aux)
1472 	{
1473 	  free (node->aux);
1474 	  node->aux = NULL;
1475 	}
1476 
1477       if (cgraph_function_body_availability (node) == AVAIL_OVERWRITABLE)
1478 	clean_function (node);
1479       else if (node_info)
1480 	clean_function_local_data (node);
1481     }
1482   bitmap_obstack_release (&local_info_obstack);
1483   return 0;
1484 }
1485 
1486 
1487 static bool
1488 gate_reference (void)
1489 {
1490   return (flag_ipa_reference
1491 	  /* Don't bother doing anything if the program has errors.  */
1492 	  && !(errorcount || sorrycount));
1493 }
1494 
1495 struct ipa_opt_pass_d pass_ipa_reference =
1496 {
1497  {
1498   IPA_PASS,
1499   "static-var",				/* name */
1500   gate_reference,			/* gate */
1501   propagate,			        /* execute */
1502   NULL,					/* sub */
1503   NULL,					/* next */
1504   0,					/* static_pass_number */
1505   TV_IPA_REFERENCE,		        /* tv_id */
1506   0,	                                /* properties_required */
1507   0,					/* properties_provided */
1508   0,					/* properties_destroyed */
1509   0,					/* todo_flags_start */
1510   0                                     /* todo_flags_finish */
1511  },
1512  generate_summary,		        /* generate_summary */
1513  ipa_reference_write_summary,		/* write_summary */
1514  ipa_reference_read_summary,		/* read_summary */
1515  NULL,					/* function_read_summary */
1516  NULL,					/* stmt_fixup */
1517  0,					/* TODOs */
1518  NULL,			                /* function_transform */
1519  NULL					/* variable_transform */
1520 };
1521 
1522 #include "gt-ipa-reference.h"
1523