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    The transitive call site specific clobber effects are computed
26    for the variables whose scope is contained within this compilation
27    unit.
28 
29    First each function and static variable initialization is analyzed
30    to determine which local static variables are either read, written,
31    or have their address taken.  Any local static that has its address
32    taken is removed from consideration.  Once the local read and
33    writes are determined, a transitive closure of this information is
34    performed over the call graph to determine the worst case set of
35    side effects of each call.  In later parts of the compiler, these
36    local and global sets are examined to make the call clobbering less
37    traumatic, promote some statics to registers, and improve aliasing
38    information.  */
39 
40 #include "config.h"
41 #include "system.h"
42 #include "coretypes.h"
43 #include "tm.h"
44 #include "tree.h"
45 #include "tree-flow.h"
46 #include "tree-inline.h"
47 #include "tree-pass.h"
48 #include "langhooks.h"
49 #include "pointer-set.h"
50 #include "splay-tree.h"
51 #include "ggc.h"
52 #include "ipa-utils.h"
53 #include "ipa-reference.h"
54 #include "gimple.h"
55 #include "cgraph.h"
56 #include "output.h"
57 #include "flags.h"
58 #include "timevar.h"
59 #include "diagnostic.h"
60 #include "langhooks.h"
61 #include "data-streamer.h"
62 #include "lto-streamer.h"
63 
64 static void remove_node_data (struct cgraph_node *node,
65 			      void *data ATTRIBUTE_UNUSED);
66 static void duplicate_node_data (struct cgraph_node *src,
67 				 struct cgraph_node *dst,
68 				 void *data ATTRIBUTE_UNUSED);
69 
70 /* The static variables defined within the compilation unit that are
71    loaded or stored directly by function that owns this structure.  */
72 
73 struct ipa_reference_local_vars_info_d
74 {
75   bitmap statics_read;
76   bitmap statics_written;
77 };
78 
79 /* Statics that are read and written by some set of functions. The
80    local ones are based on the loads and stores local to the function.
81    The global ones are based on the local info as well as the
82    transitive closure of the functions that are called. */
83 
84 struct ipa_reference_global_vars_info_d
85 {
86   bitmap statics_read;
87   bitmap statics_written;
88 };
89 
90 /* Information we save about every function after ipa-reference is completed.  */
91 
92 struct ipa_reference_optimization_summary_d
93 {
94   bitmap statics_not_read;
95   bitmap statics_not_written;
96 };
97 
98 typedef struct ipa_reference_local_vars_info_d *ipa_reference_local_vars_info_t;
99 typedef struct ipa_reference_global_vars_info_d *ipa_reference_global_vars_info_t;
100 typedef struct ipa_reference_optimization_summary_d *ipa_reference_optimization_summary_t;
101 
102 struct ipa_reference_vars_info_d
103 {
104   struct ipa_reference_local_vars_info_d local;
105   struct ipa_reference_global_vars_info_d global;
106 };
107 
108 typedef struct ipa_reference_vars_info_d *ipa_reference_vars_info_t;
109 
110 /* This splay tree contains all of the static variables that are
111    being considered by the compilation level alias analysis.  */
112 static splay_tree reference_vars_to_consider;
113 
114 /* A bit is set for every module static we are considering.  This is
115    ored into the local info when asm code is found that clobbers all
116    memory. */
117 static bitmap all_module_statics;
118 
119 /* Obstack holding bitmaps of local analysis (live from analysis to
120    propagation)  */
121 static bitmap_obstack local_info_obstack;
122 /* Obstack holding global analysis live forever.  */
123 static bitmap_obstack optimization_summary_obstack;
124 
125 /* Holders of ipa cgraph hooks: */
126 static struct cgraph_2node_hook_list *node_duplication_hook_holder;
127 static struct cgraph_node_hook_list *node_removal_hook_holder;
128 
129 /* Vector where the reference var infos are actually stored. */
130 DEF_VEC_P (ipa_reference_vars_info_t);
131 DEF_VEC_ALLOC_P (ipa_reference_vars_info_t, heap);
132 static VEC (ipa_reference_vars_info_t, heap) *ipa_reference_vars_vector;
133 DEF_VEC_P (ipa_reference_optimization_summary_t);
134 DEF_VEC_ALLOC_P (ipa_reference_optimization_summary_t, heap);
135 static VEC (ipa_reference_optimization_summary_t, heap) *ipa_reference_opt_sum_vector;
136 
137 /* Return the ipa_reference_vars structure starting from the cgraph NODE.  */
138 static inline ipa_reference_vars_info_t
139 get_reference_vars_info (struct cgraph_node *node)
140 {
141   if (!ipa_reference_vars_vector
142       || VEC_length (ipa_reference_vars_info_t,
143 		     ipa_reference_vars_vector) <= (unsigned int) node->uid)
144     return NULL;
145   return VEC_index (ipa_reference_vars_info_t, ipa_reference_vars_vector,
146 		    node->uid);
147 }
148 
149 /* Return the ipa_reference_vars structure starting from the cgraph NODE.  */
150 static inline ipa_reference_optimization_summary_t
151 get_reference_optimization_summary (struct cgraph_node *node)
152 {
153   if (!ipa_reference_opt_sum_vector
154       || (VEC_length (ipa_reference_optimization_summary_t,
155 		      ipa_reference_opt_sum_vector)
156 	  <= (unsigned int) node->uid))
157     return NULL;
158   return VEC_index (ipa_reference_optimization_summary_t, ipa_reference_opt_sum_vector,
159 		    node->uid);
160 }
161 
162 /* Return the ipa_reference_vars structure starting from the cgraph NODE.  */
163 static inline void
164 set_reference_vars_info (struct cgraph_node *node,
165 			 ipa_reference_vars_info_t info)
166 {
167   if (!ipa_reference_vars_vector
168       || VEC_length (ipa_reference_vars_info_t,
169 		     ipa_reference_vars_vector) <= (unsigned int) node->uid)
170     VEC_safe_grow_cleared (ipa_reference_vars_info_t, heap,
171 			   ipa_reference_vars_vector, node->uid + 1);
172   VEC_replace (ipa_reference_vars_info_t, ipa_reference_vars_vector,
173 	       node->uid, info);
174 }
175 
176 /* Return the ipa_reference_vars structure starting from the cgraph NODE.  */
177 static inline void
178 set_reference_optimization_summary (struct cgraph_node *node,
179 				    ipa_reference_optimization_summary_t info)
180 {
181   if (!ipa_reference_opt_sum_vector
182       || (VEC_length (ipa_reference_optimization_summary_t,
183 		      ipa_reference_opt_sum_vector)
184 	  <= (unsigned int) node->uid))
185     VEC_safe_grow_cleared (ipa_reference_optimization_summary_t,
186 			   heap, ipa_reference_opt_sum_vector, node->uid + 1);
187   VEC_replace (ipa_reference_optimization_summary_t,
188 	       ipa_reference_opt_sum_vector, node->uid, info);
189 }
190 
191 /* Return a bitmap indexed by_DECL_UID uid for the static variables
192    that are not read during the execution of the function FN.  Returns
193    NULL if no data is available.  */
194 
195 bitmap
196 ipa_reference_get_not_read_global (struct cgraph_node *fn)
197 {
198   ipa_reference_optimization_summary_t info;
199 
200   info = get_reference_optimization_summary (cgraph_function_node (fn, NULL));
201   if (info)
202     return info->statics_not_read;
203   else if (flags_from_decl_or_type (fn->decl) & ECF_LEAF)
204     return all_module_statics;
205   else
206     return NULL;
207 }
208 
209 /* Return a bitmap indexed by DECL_UID uid for the static variables
210    that are not written during the execution of the function FN.  Note
211    that variables written may or may not be read during the function
212    call.  Returns NULL if no data is available.  */
213 
214 bitmap
215 ipa_reference_get_not_written_global (struct cgraph_node *fn)
216 {
217   ipa_reference_optimization_summary_t info;
218 
219   info = get_reference_optimization_summary (fn);
220   if (info)
221     return info->statics_not_written;
222   else if (flags_from_decl_or_type (fn->decl) & ECF_LEAF)
223     return all_module_statics;
224   else
225     return NULL;
226 }
227 
228 
229 
230 /* Add VAR to all_module_statics and the two
231    reference_vars_to_consider* sets.  */
232 
233 static inline void
234 add_static_var (tree var)
235 {
236   int uid = DECL_UID (var);
237   gcc_assert (TREE_CODE (var) == VAR_DECL);
238   if (dump_file)
239     splay_tree_insert (reference_vars_to_consider,
240 		       uid, (splay_tree_value)var);
241   bitmap_set_bit (all_module_statics, uid);
242 }
243 
244 /* Return true if the variable T is the right kind of static variable to
245    perform compilation unit scope escape analysis.  */
246 
247 static inline bool
248 is_proper_for_analysis (tree t)
249 {
250   /* We handle only variables whose address is never taken.  */
251   if (TREE_ADDRESSABLE (t))
252     return false;
253 
254   /* If the variable has the "used" attribute, treat it as if it had a
255      been touched by the devil.  */
256   if (DECL_PRESERVE_P (t))
257     return false;
258 
259   /* Do not want to do anything with volatile except mark any
260      function that uses one to be not const or pure.  */
261   if (TREE_THIS_VOLATILE (t))
262     return false;
263 
264   /* We do not need to analyze readonly vars, we already know they do not
265      alias.  */
266   if (TREE_READONLY (t))
267     return false;
268 
269   /* We cannot touch decls where the type needs constructing.  */
270   if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (t)))
271     return false;
272 
273   /* This is a variable we care about.  Check if we have seen it
274      before, and if not add it the set of variables we care about.  */
275   if (all_module_statics
276       && !bitmap_bit_p (all_module_statics, DECL_UID (t)))
277     add_static_var (t);
278 
279   return true;
280 }
281 
282 /* Lookup the tree node for the static variable that has UID and
283    convert the name to a string for debugging.  */
284 
285 static const char *
286 get_static_name (int index)
287 {
288   splay_tree_node stn =
289     splay_tree_lookup (reference_vars_to_consider, index);
290   if (stn)
291     return lang_hooks.decl_printable_name ((tree)(stn->value), 2);
292   return NULL;
293 }
294 
295 /* Or in all of the bits from every callee of X into X_GLOBAL, the caller's cycle,
296    bit vector.  There are several cases to check to avoid the sparse
297    bitmap oring.  */
298 
299 static void
300 propagate_bits (ipa_reference_global_vars_info_t x_global, struct cgraph_node *x)
301 {
302   struct cgraph_edge *e;
303   for (e = x->callees; e; e = e->next_callee)
304     {
305       enum availability avail;
306       struct cgraph_node *y = cgraph_function_node (e->callee, &avail);
307 
308       if (!y)
309 	continue;
310       /* Only look into nodes we can propagate something.  */
311       if (avail > AVAIL_OVERWRITABLE
312 	  || (avail == AVAIL_OVERWRITABLE
313 	      && (flags_from_decl_or_type (y->decl) & ECF_LEAF)))
314 	{
315 	  int flags = flags_from_decl_or_type (y->decl);
316 	  if (get_reference_vars_info (y))
317 	    {
318 	      ipa_reference_vars_info_t y_info
319 		= get_reference_vars_info (y);
320 	      ipa_reference_global_vars_info_t y_global = &y_info->global;
321 
322 	      /* Calls in current cycle do not have global computed yet.  */
323 	      if (!y_global->statics_read)
324 		continue;
325 
326 	      /* If function is declared const, it reads no memory even if it
327 		 seems so to local analysis.  */
328 	      if (flags & ECF_CONST)
329 		continue;
330 
331 	      if (x_global->statics_read
332 		  != all_module_statics)
333 		{
334 		  if (y_global->statics_read
335 		      == all_module_statics)
336 		    {
337 		      BITMAP_FREE (x_global->statics_read);
338 		      x_global->statics_read
339 			= all_module_statics;
340 		    }
341 		  /* Skip bitmaps that are pointer equal to node's bitmap
342 		     (no reason to spin within the cycle).  */
343 		  else if (x_global->statics_read
344 			   != y_global->statics_read)
345 		    bitmap_ior_into (x_global->statics_read,
346 				     y_global->statics_read);
347 		}
348 
349 	      /* If function is declared pure, it has no stores even if it
350 		 seems so to local analysis; If we can not return from here,
351 		 we can safely ignore the call.  */
352 	      if ((flags & ECF_PURE)
353 		  || cgraph_edge_cannot_lead_to_return (e))
354 		continue;
355 
356 	      if (x_global->statics_written
357 		  != all_module_statics)
358 		{
359 		  if (y_global->statics_written
360 		      == all_module_statics)
361 		    {
362 		      BITMAP_FREE (x_global->statics_written);
363 		      x_global->statics_written
364 			= all_module_statics;
365 		    }
366 		  /* Skip bitmaps that are pointer equal to node's bitmap
367 		     (no reason to spin within the cycle).  */
368 		  else if (x_global->statics_written
369 			   != y_global->statics_written)
370 		    bitmap_ior_into (x_global->statics_written,
371 				     y_global->statics_written);
372 		}
373 	    }
374 	  else
375 	    gcc_unreachable ();
376 	}
377     }
378 }
379 
380 /* The init routine for analyzing global static variable usage.  See
381    comments at top for description.  */
382 static void
383 ipa_init (void)
384 {
385   static bool init_p = false;
386 
387   if (init_p)
388     return;
389 
390   init_p = true;
391 
392   if (dump_file)
393     reference_vars_to_consider = splay_tree_new (splay_tree_compare_ints, 0, 0);
394 
395   bitmap_obstack_initialize (&local_info_obstack);
396   bitmap_obstack_initialize (&optimization_summary_obstack);
397   all_module_statics = BITMAP_ALLOC (&optimization_summary_obstack);
398 
399   node_removal_hook_holder =
400       cgraph_add_node_removal_hook (&remove_node_data, NULL);
401   node_duplication_hook_holder =
402       cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
403 }
404 
405 
406 /* Set up the persistent info for FN.  */
407 
408 static ipa_reference_local_vars_info_t
409 init_function_info (struct cgraph_node *fn)
410 {
411   ipa_reference_vars_info_t info
412     = XCNEW (struct ipa_reference_vars_info_d);
413 
414   /* Add the info to the tree's annotation.  */
415   set_reference_vars_info (fn, info);
416 
417   info->local.statics_read = BITMAP_ALLOC (&local_info_obstack);
418   info->local.statics_written = BITMAP_ALLOC (&local_info_obstack);
419 
420   return &info->local;
421 }
422 
423 
424 /* This is the main routine for finding the reference patterns for
425    global variables within a function FN.  */
426 
427 static void
428 analyze_function (struct cgraph_node *fn)
429 {
430   ipa_reference_local_vars_info_t local;
431   struct ipa_ref *ref;
432   int i;
433   tree var;
434 
435   local = init_function_info (fn);
436   for (i = 0; ipa_ref_list_reference_iterate (&fn->ref_list, i, ref); i++)
437     {
438       if (ref->refered_type != IPA_REF_VARPOOL)
439 	continue;
440       var = ipa_ref_varpool_node (ref)->decl;
441       if (ipa_ref_varpool_node (ref)->externally_visible
442 	  || !ipa_ref_varpool_node (ref)->analyzed
443 	  || !is_proper_for_analysis (var))
444 	continue;
445       switch (ref->use)
446 	{
447 	case IPA_REF_LOAD:
448           bitmap_set_bit (local->statics_read, DECL_UID (var));
449 	  break;
450 	case IPA_REF_STORE:
451 	  if (ipa_ref_cannot_lead_to_return (ref))
452 	    break;
453           bitmap_set_bit (local->statics_written, DECL_UID (var));
454 	  break;
455 	case IPA_REF_ADDR:
456 	  gcc_unreachable ();
457 	  break;
458 	}
459     }
460 
461   if (cgraph_node_cannot_return (fn))
462     bitmap_clear (local->statics_written);
463 }
464 
465 static bitmap
466 copy_global_bitmap (bitmap src)
467 {
468   bitmap dst;
469   if (!src)
470     return NULL;
471   if (src == all_module_statics)
472     return all_module_statics;
473   dst = BITMAP_ALLOC (&optimization_summary_obstack);
474   bitmap_copy (dst, src);
475   return dst;
476 }
477 
478 
479 /* Called when new clone is inserted to callgraph late.  */
480 
481 static void
482 duplicate_node_data (struct cgraph_node *src, struct cgraph_node *dst,
483 	 	     void *data ATTRIBUTE_UNUSED)
484 {
485   ipa_reference_optimization_summary_t ginfo;
486   ipa_reference_optimization_summary_t dst_ginfo;
487 
488   ginfo = get_reference_optimization_summary (src);
489   if (!ginfo)
490     return;
491   dst_ginfo = XCNEW (struct ipa_reference_optimization_summary_d);
492   set_reference_optimization_summary (dst, dst_ginfo);
493   dst_ginfo->statics_not_read = copy_global_bitmap (ginfo->statics_not_read);
494   dst_ginfo->statics_not_written = copy_global_bitmap (ginfo->statics_not_written);
495 }
496 
497 /* Called when node is removed.  */
498 
499 static void
500 remove_node_data (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
501 {
502   ipa_reference_optimization_summary_t ginfo;
503   ginfo = get_reference_optimization_summary (node);
504   if (ginfo)
505     {
506       if (ginfo->statics_not_read
507 	  && ginfo->statics_not_read != all_module_statics)
508 	BITMAP_FREE (ginfo->statics_not_read);
509 
510       if (ginfo->statics_not_written
511 	  && ginfo->statics_not_written != all_module_statics)
512 	BITMAP_FREE (ginfo->statics_not_written);
513       free (ginfo);
514       set_reference_optimization_summary (node, NULL);
515     }
516 }
517 
518 /* Analyze each function in the cgraph to see which global or statics
519    are read or written.  */
520 
521 static void
522 generate_summary (void)
523 {
524   struct cgraph_node *node;
525   unsigned int index;
526   bitmap_iterator bi;
527   bitmap bm_temp;
528 
529   ipa_init ();
530   bm_temp = BITMAP_ALLOC (&local_info_obstack);
531 
532   /* Process all of the functions next.  */
533   for (node = cgraph_nodes; node; node = node->next)
534     if (node->analyzed)
535       analyze_function (node);
536 
537   if (dump_file)
538     EXECUTE_IF_SET_IN_BITMAP (all_module_statics, 0, index, bi)
539       {
540 	fprintf (dump_file, "\nPromotable global:%s",
541 		 get_static_name (index));
542       }
543 
544   BITMAP_FREE(bm_temp);
545 
546   if (dump_file)
547     for (node = cgraph_nodes; node; node = node->next)
548       if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
549 	{
550 	  ipa_reference_local_vars_info_t l;
551 	  unsigned int index;
552 	  bitmap_iterator bi;
553 
554 	  l = &get_reference_vars_info (node)->local;
555 	  fprintf (dump_file,
556 		   "\nFunction name:%s/%i:",
557 		   cgraph_node_name (node), node->uid);
558 	  fprintf (dump_file, "\n  locals read: ");
559 	  if (l->statics_read)
560 	    EXECUTE_IF_SET_IN_BITMAP (l->statics_read,
561 				      0, index, bi)
562 	      {
563 	        fprintf (dump_file, "%s ",
564 		         get_static_name (index));
565 	      }
566 	  fprintf (dump_file, "\n  locals written: ");
567 	  if (l->statics_written)
568 	    EXECUTE_IF_SET_IN_BITMAP (l->statics_written,
569 				      0, index, bi)
570 	      {
571 	        fprintf(dump_file, "%s ",
572 		        get_static_name (index));
573 	      }
574 	}
575 }
576 
577 /* Set READ_ALL/WRITE_ALL based on decl flags of NODE.  */
578 
579 static void
580 read_write_all_from_decl (struct cgraph_node *node, bool * read_all,
581 			  bool * write_all)
582 {
583   tree decl = node->decl;
584   int flags = flags_from_decl_or_type (decl);
585   if ((flags & ECF_LEAF)
586       && cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
587     ;
588   else if (flags & ECF_CONST)
589     ;
590   else if ((flags & ECF_PURE)
591 	   || cgraph_node_cannot_return (node))
592     {
593       *read_all = true;
594       if (dump_file && (dump_flags & TDF_DETAILS))
595          fprintf (dump_file, "   %s/%i -> read all\n",
596 		  cgraph_node_name (node), node->uid);
597     }
598   else
599     {
600        /* TODO: To be able to produce sane results, we should also handle
601 	  common builtins, in particular throw.  */
602       *read_all = true;
603       *write_all = true;
604       if (dump_file && (dump_flags & TDF_DETAILS))
605          fprintf (dump_file, "   %s/%i -> read all, write all\n",
606 		  cgraph_node_name (node), node->uid);
607     }
608 }
609 
610 /* Produce the global information by preforming a transitive closure
611    on the local information that was produced by ipa_analyze_function */
612 
613 static unsigned int
614 propagate (void)
615 {
616   struct cgraph_node *node;
617   struct cgraph_node *w;
618   struct cgraph_node **order =
619     XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
620   int order_pos;
621   int i;
622 
623   if (dump_file)
624     dump_cgraph (dump_file);
625 
626   ipa_discover_readonly_nonaddressable_vars ();
627   generate_summary ();
628 
629   /* Propagate the local information thru the call graph to produce
630      the global information.  All the nodes within a cycle will have
631      the same info so we collapse cycles first.  Then we can do the
632      propagation in one pass from the leaves to the roots.  */
633   order_pos = ipa_reduced_postorder (order, true, true, NULL);
634   if (dump_file)
635     ipa_print_order (dump_file, "reduced", order, order_pos);
636 
637   for (i = 0; i < order_pos; i++ )
638     {
639       ipa_reference_vars_info_t node_info;
640       ipa_reference_global_vars_info_t node_g;
641       ipa_reference_local_vars_info_t node_l;
642       struct cgraph_edge *e, *ie;
643 
644       bool read_all;
645       bool write_all;
646       struct ipa_dfs_info * w_info;
647 
648       node = order[i];
649       if (node->alias)
650 	continue;
651       node_info = get_reference_vars_info (node);
652       gcc_assert (node_info);
653 
654 
655       if (dump_file && (dump_flags & TDF_DETAILS))
656 	fprintf (dump_file, "Starting cycle with %s/%i\n",
657 		  cgraph_node_name (node), node->uid);
658 
659       node_l = &node_info->local;
660       node_g = &node_info->global;
661 
662       read_all = false;
663       write_all = false;
664 
665       /* When function is overwritable, we can not assume anything.  */
666       if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
667         read_write_all_from_decl (node, &read_all, &write_all);
668 
669       for (e = node->callees; e; e = e->next_callee)
670 	{
671 	  enum availability avail;
672 	  struct cgraph_node *callee = cgraph_function_node (e->callee, &avail);
673           if (!callee || avail <= AVAIL_OVERWRITABLE)
674             read_write_all_from_decl (callee, &read_all, &write_all);
675 	}
676 
677       for (ie = node->indirect_calls; ie; ie = ie->next_callee)
678 	if (!(ie->indirect_info->ecf_flags & ECF_CONST))
679 	  {
680 	    read_all = true;
681 	    if (dump_file && (dump_flags & TDF_DETAILS))
682 	       fprintf (dump_file, "   indirect call -> read all\n");
683 	    if (!cgraph_edge_cannot_lead_to_return (ie)
684 		&& !(ie->indirect_info->ecf_flags & ECF_PURE))
685 	      {
686 		if (dump_file && (dump_flags & TDF_DETAILS))
687 		   fprintf (dump_file, "   indirect call -> write all\n");
688 	        write_all = true;
689 	      }
690 	  }
691 
692 
693       /* If any node in a cycle is read_all or write_all
694 	 they all are. */
695       w_info = (struct ipa_dfs_info *) node->aux;
696       w = w_info->next_cycle;
697       while (w && (!read_all || !write_all))
698 	{
699 	  if (dump_file && (dump_flags & TDF_DETAILS))
700 	    fprintf (dump_file, "  Visiting %s/%i\n",
701 		      cgraph_node_name (w), w->uid);
702 	  /* When function is overwritable, we can not assume anything.  */
703 	  if (cgraph_function_body_availability (w) <= AVAIL_OVERWRITABLE)
704 	    read_write_all_from_decl (w, &read_all, &write_all);
705 
706 	  for (e = w->callees; e; e = e->next_callee)
707 	    {
708 	      enum availability avail;
709 	      struct cgraph_node *callee = cgraph_function_node (e->callee, &avail);
710 
711 	      if (avail <= AVAIL_OVERWRITABLE)
712 		read_write_all_from_decl (callee, &read_all, &write_all);
713 	    }
714 
715 	  for (ie = w->indirect_calls; ie; ie = ie->next_callee)
716 	    if (!(ie->indirect_info->ecf_flags & ECF_CONST))
717 	      {
718 		read_all = true;
719 		if (dump_file && (dump_flags & TDF_DETAILS))
720 		   fprintf (dump_file, "   indirect call -> read all\n");
721 		if (!cgraph_edge_cannot_lead_to_return (ie)
722 		    && !(ie->indirect_info->ecf_flags & ECF_PURE))
723 		  {
724 		    write_all = true;
725 		    if (dump_file && (dump_flags & TDF_DETAILS))
726 		       fprintf (dump_file, "   indirect call -> write all\n");
727 		  }
728 	      }
729 
730 	  w_info = (struct ipa_dfs_info *) w->aux;
731 	  w = w_info->next_cycle;
732 	}
733 
734 
735       /* Initialized the bitmaps for the reduced nodes */
736       if (read_all)
737 	node_g->statics_read = all_module_statics;
738       else
739 	{
740 	  node_g->statics_read = BITMAP_ALLOC (&local_info_obstack);
741 	  bitmap_copy (node_g->statics_read,
742 		       node_l->statics_read);
743 	}
744       if (write_all)
745 	node_g->statics_written = all_module_statics;
746       else
747 	{
748 	  node_g->statics_written = BITMAP_ALLOC (&local_info_obstack);
749 	  bitmap_copy (node_g->statics_written,
750 		       node_l->statics_written);
751 	}
752 
753       propagate_bits (node_g, node);
754       w_info = (struct ipa_dfs_info *) node->aux;
755       w = w_info->next_cycle;
756       while (w && (!read_all || !write_all))
757 	{
758 	  ipa_reference_vars_info_t w_ri =
759 	    get_reference_vars_info (w);
760 	  ipa_reference_local_vars_info_t w_l = &w_ri->local;
761 	  int flags = flags_from_decl_or_type (w->decl);
762 
763 	  /* These global bitmaps are initialized from the local info
764 	     of all of the nodes in the region.  However there is no
765 	     need to do any work if the bitmaps were set to
766 	     all_module_statics.  */
767 	  if (!read_all && !(flags & ECF_CONST))
768 	    bitmap_ior_into (node_g->statics_read,
769 			     w_l->statics_read);
770 	  if (!write_all
771 	      && !(flags & ECF_PURE)
772 	      && !cgraph_node_cannot_return (w))
773 	    bitmap_ior_into (node_g->statics_written,
774 			     w_l->statics_written);
775 	  propagate_bits (node_g, w);
776 	  w_info = (struct ipa_dfs_info *) w->aux;
777 	  w = w_info->next_cycle;
778 	}
779 
780       /* All nodes within a cycle have the same global info bitmaps.  */
781       node_info->global = *node_g;
782       w_info = (struct ipa_dfs_info *) node->aux;
783       w = w_info->next_cycle;
784       while (w)
785 	{
786 	  ipa_reference_vars_info_t w_ri =
787 	    get_reference_vars_info (w);
788 
789           w_ri->global = *node_g;
790 
791 	  w_info = (struct ipa_dfs_info *) w->aux;
792 	  w = w_info->next_cycle;
793 	}
794     }
795 
796   if (dump_file)
797     {
798       for (i = 0; i < order_pos; i++ )
799 	{
800 	  ipa_reference_vars_info_t node_info;
801 	  ipa_reference_global_vars_info_t node_g;
802 	  ipa_reference_local_vars_info_t node_l;
803 	  unsigned int index;
804 	  bitmap_iterator bi;
805 	  struct ipa_dfs_info * w_info;
806 
807 	  node = order[i];
808 	  if (node->alias)
809 	    continue;
810 	  node_info = get_reference_vars_info (node);
811 	  node_g = &node_info->global;
812 	  node_l = &node_info->local;
813 	  fprintf (dump_file,
814 		   "\nFunction name:%s/%i:",
815 		   cgraph_node_name (node), node->uid);
816 	  fprintf (dump_file, "\n  locals read: ");
817 	  if (node_l->statics_read)
818 	    EXECUTE_IF_SET_IN_BITMAP (node_l->statics_read,
819 				      0, index, bi)
820 	      {
821 		fprintf (dump_file, "%s ",
822 			 get_static_name (index));
823 	      }
824 	  fprintf (dump_file, "\n  locals written: ");
825 	  if (node_l->statics_written)
826 	    EXECUTE_IF_SET_IN_BITMAP (node_l->statics_written,
827 				      0, index, bi)
828 	      {
829 		fprintf(dump_file, "%s ",
830 			get_static_name (index));
831 	      }
832 
833 	  w_info = (struct ipa_dfs_info *) node->aux;
834 	  w = w_info->next_cycle;
835 	  while (w)
836 	    {
837 	      ipa_reference_vars_info_t w_ri =
838 		get_reference_vars_info (w);
839 	      ipa_reference_local_vars_info_t w_l = &w_ri->local;
840 	      fprintf (dump_file, "\n  next cycle: %s/%i ",
841 		       cgraph_node_name (w), w->uid);
842 	      fprintf (dump_file, "\n    locals read: ");
843 	      if (w_l->statics_read)
844 		EXECUTE_IF_SET_IN_BITMAP (w_l->statics_read,
845 					  0, index, bi)
846 		  {
847 		    fprintf (dump_file, "%s ",
848 			     get_static_name (index));
849 		  }
850 
851 	      fprintf (dump_file, "\n    locals written: ");
852 	      if (w_l->statics_written)
853 		EXECUTE_IF_SET_IN_BITMAP (w_l->statics_written,
854 					  0, index, bi)
855 		  {
856 		    fprintf (dump_file, "%s ",
857 			     get_static_name (index));
858 		  }
859 
860 	      w_info = (struct ipa_dfs_info *) w->aux;
861 	      w = w_info->next_cycle;
862 	    }
863 	  fprintf (dump_file, "\n  globals read: ");
864 	  if (node_g->statics_read == all_module_statics)
865 	    fprintf (dump_file, "ALL");
866 	  else
867 	    EXECUTE_IF_SET_IN_BITMAP (node_g->statics_read,
868 				      0, index, bi)
869 	      {
870 	        fprintf (dump_file, "%s ",
871 		         get_static_name (index));
872 	      }
873 	  fprintf (dump_file, "\n  globals written: ");
874 	  if (node_g->statics_written == all_module_statics)
875 	    fprintf (dump_file, "ALL");
876 	  else
877 	    EXECUTE_IF_SET_IN_BITMAP (node_g->statics_written,
878 				      0, index, bi)
879 	      {
880 		fprintf (dump_file, "%s ",
881 			 get_static_name (index));
882 	      }
883 	}
884     }
885 
886   /* Cleanup. */
887   for (node = cgraph_nodes; node; node = node->next)
888     {
889       ipa_reference_vars_info_t node_info;
890       ipa_reference_global_vars_info_t node_g;
891       ipa_reference_optimization_summary_t opt;
892 
893       if (!node->analyzed || node->alias)
894         continue;
895 
896       node_info = get_reference_vars_info (node);
897       if (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE
898 	  || (flags_from_decl_or_type (node->decl) & ECF_LEAF))
899 	{
900 	  node_g = &node_info->global;
901 
902 	  opt = XCNEW (struct ipa_reference_optimization_summary_d);
903 	  set_reference_optimization_summary (node, opt);
904 
905 	  /* Create the complimentary sets.  */
906 
907 	  if (bitmap_empty_p (node_g->statics_read))
908 	    opt->statics_not_read = all_module_statics;
909 	  else
910 	    {
911 	      opt->statics_not_read
912 		 = BITMAP_ALLOC (&optimization_summary_obstack);
913 	      if (node_g->statics_read != all_module_statics)
914 		bitmap_and_compl (opt->statics_not_read,
915 				  all_module_statics,
916 				  node_g->statics_read);
917 	    }
918 
919 	  if (bitmap_empty_p (node_g->statics_written))
920 	    opt->statics_not_written = all_module_statics;
921 	  else
922 	    {
923 	      opt->statics_not_written
924 	        = BITMAP_ALLOC (&optimization_summary_obstack);
925 	      if (node_g->statics_written != all_module_statics)
926 		bitmap_and_compl (opt->statics_not_written,
927 				  all_module_statics,
928 				  node_g->statics_written);
929 	    }
930 	}
931       free (node_info);
932    }
933 
934   ipa_free_postorder_info ();
935   free (order);
936 
937   bitmap_obstack_release (&local_info_obstack);
938   VEC_free (ipa_reference_vars_info_t, heap, ipa_reference_vars_vector);
939   ipa_reference_vars_vector = NULL;
940   if (dump_file)
941     splay_tree_delete (reference_vars_to_consider);
942   reference_vars_to_consider = NULL;
943   return 0;
944 }
945 
946 /* Return true if we need to write summary of NODE. */
947 
948 static bool
949 write_node_summary_p (struct cgraph_node *node,
950 		      cgraph_node_set set,
951 		      varpool_node_set vset,
952 		      bitmap ltrans_statics)
953 {
954   ipa_reference_optimization_summary_t info;
955 
956   /* See if we have (non-empty) info.  */
957   if (!node->analyzed || node->global.inlined_to)
958     return false;
959   info = get_reference_optimization_summary (node);
960   if (!info || (bitmap_empty_p (info->statics_not_read)
961 		&& bitmap_empty_p (info->statics_not_written)))
962     return false;
963 
964   /* See if we want to encode it.
965      Encode also referenced functions since constant folding might turn it into
966      a direct call.
967 
968      In future we might also want to include summaries of functions references
969      by initializers of constant variables references in current unit.  */
970   if (!reachable_from_this_partition_p (node, set)
971       && !referenced_from_this_partition_p (&node->ref_list, set, vset))
972     return false;
973 
974   /* See if the info has non-empty intersections with vars we want to encode.  */
975   if (!bitmap_intersect_p (info->statics_not_read, ltrans_statics)
976       && !bitmap_intersect_p (info->statics_not_written, ltrans_statics))
977     return false;
978   return true;
979 }
980 
981 /* Stream out BITS&LTRANS_STATICS as list of decls to OB.
982    LTRANS_STATICS_BITCOUNT specify number of bits in LTRANS_STATICS
983    or -1.  When it is positive, just output -1 when
984    BITS&LTRANS_STATICS == BITS&LTRANS_STATICS.  */
985 
986 static void
987 stream_out_bitmap (struct lto_simple_output_block *ob,
988 		   bitmap bits, bitmap ltrans_statics,
989 		   int ltrans_statics_bitcount)
990 {
991   int count = 0;
992   unsigned int index;
993   bitmap_iterator bi;
994   if (bits == all_module_statics)
995     {
996       streamer_write_hwi_stream (ob->main_stream, -1);
997       return;
998     }
999   EXECUTE_IF_AND_IN_BITMAP (bits, ltrans_statics, 0, index, bi)
1000     count ++;
1001   if (count == ltrans_statics_bitcount)
1002     {
1003       streamer_write_hwi_stream (ob->main_stream, -1);
1004       return;
1005     }
1006   streamer_write_hwi_stream (ob->main_stream, count);
1007   if (!count)
1008     return;
1009   EXECUTE_IF_AND_IN_BITMAP (bits, ltrans_statics, 0, index, bi)
1010     {
1011       tree decl = (tree)splay_tree_lookup (reference_vars_to_consider, index)->value;
1012       lto_output_var_decl_index(ob->decl_state, ob->main_stream, decl);
1013     }
1014 }
1015 
1016 /* Serialize the ipa info for lto.  */
1017 
1018 static void
1019 ipa_reference_write_optimization_summary (cgraph_node_set set,
1020 					  varpool_node_set vset)
1021 {
1022   struct cgraph_node *node;
1023   struct lto_simple_output_block *ob
1024     = lto_create_simple_output_block (LTO_section_ipa_reference);
1025   unsigned int count = 0;
1026   int ltrans_statics_bitcount = 0;
1027   lto_cgraph_encoder_t encoder = ob->decl_state->cgraph_node_encoder;
1028   lto_varpool_encoder_t varpool_encoder = ob->decl_state->varpool_node_encoder;
1029   bitmap ltrans_statics = BITMAP_ALLOC (NULL);
1030   int i;
1031 
1032   reference_vars_to_consider = splay_tree_new (splay_tree_compare_ints, 0, 0);
1033 
1034   /* See what variables we are interested in.  */
1035   for (i = 0; i < lto_varpool_encoder_size (varpool_encoder); i++)
1036     {
1037       struct varpool_node *vnode = lto_varpool_encoder_deref (varpool_encoder, i);
1038       if (!vnode->externally_visible
1039 	  && vnode->analyzed
1040 	  && bitmap_bit_p (all_module_statics, DECL_UID (vnode->decl))
1041 	  && referenced_from_this_partition_p (&vnode->ref_list, set, vset))
1042 	{
1043 	  tree decl = vnode->decl;
1044 	  bitmap_set_bit (ltrans_statics, DECL_UID (decl));
1045 	  splay_tree_insert (reference_vars_to_consider,
1046 			     DECL_UID (decl), (splay_tree_value)decl);
1047 	  ltrans_statics_bitcount ++;
1048 	}
1049     }
1050 
1051 
1052   if (ltrans_statics_bitcount)
1053     for (i = 0; i < lto_cgraph_encoder_size (encoder); i++)
1054       if (write_node_summary_p (lto_cgraph_encoder_deref (encoder, i),
1055 				set, vset, ltrans_statics))
1056 	  count++;
1057 
1058   streamer_write_uhwi_stream (ob->main_stream, count);
1059   if (count)
1060     stream_out_bitmap (ob, ltrans_statics, ltrans_statics,
1061 		       -1);
1062 
1063   /* Process all of the functions.  */
1064   if (ltrans_statics_bitcount)
1065     for (i = 0; i < lto_cgraph_encoder_size (encoder); i++)
1066       {
1067 	node = lto_cgraph_encoder_deref (encoder, i);
1068 	if (write_node_summary_p (node, set, vset, ltrans_statics))
1069 	  {
1070 	    ipa_reference_optimization_summary_t info;
1071 	    int node_ref;
1072 
1073 	    info = get_reference_optimization_summary (node);
1074 	    node_ref = lto_cgraph_encoder_encode (encoder, node);
1075 	    streamer_write_uhwi_stream (ob->main_stream, node_ref);
1076 
1077 	    stream_out_bitmap (ob, info->statics_not_read, ltrans_statics,
1078 			       ltrans_statics_bitcount);
1079 	    stream_out_bitmap (ob, info->statics_not_written, ltrans_statics,
1080 			       ltrans_statics_bitcount);
1081 	  }
1082       }
1083   BITMAP_FREE (ltrans_statics);
1084   lto_destroy_simple_output_block (ob);
1085   splay_tree_delete (reference_vars_to_consider);
1086 }
1087 
1088 /* Deserialize the ipa info for lto.  */
1089 
1090 static void
1091 ipa_reference_read_optimization_summary (void)
1092 {
1093   struct lto_file_decl_data ** file_data_vec
1094     = lto_get_file_decl_data ();
1095   struct lto_file_decl_data * file_data;
1096   unsigned int j = 0;
1097   bitmap_obstack_initialize (&optimization_summary_obstack);
1098 
1099   node_removal_hook_holder =
1100       cgraph_add_node_removal_hook (&remove_node_data, NULL);
1101   node_duplication_hook_holder =
1102       cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
1103   all_module_statics = BITMAP_ALLOC (&optimization_summary_obstack);
1104 
1105   while ((file_data = file_data_vec[j++]))
1106     {
1107       const char *data;
1108       size_t len;
1109       struct lto_input_block *ib
1110 	= lto_create_simple_input_block (file_data,
1111 					 LTO_section_ipa_reference,
1112 					 &data, &len);
1113       if (ib)
1114 	{
1115 	  unsigned int i;
1116 	  unsigned int f_count = streamer_read_uhwi (ib);
1117 	  int b_count;
1118 	  if (!f_count)
1119 	    continue;
1120 	  b_count = streamer_read_hwi (ib);
1121 	  if (dump_file)
1122 	    fprintf (dump_file, "all module statics:");
1123 	  for (i = 0; i < (unsigned int)b_count; i++)
1124 	    {
1125 	      unsigned int var_index = streamer_read_uhwi (ib);
1126 	      tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1127 							     var_index);
1128 	      bitmap_set_bit (all_module_statics, DECL_UID (v_decl));
1129 	      if (dump_file)
1130 		fprintf (dump_file, " %s",
1131 			 lang_hooks.decl_printable_name (v_decl, 2));
1132 	    }
1133 
1134 	  for (i = 0; i < f_count; i++)
1135 	    {
1136 	      unsigned int j, index;
1137 	      struct cgraph_node *node;
1138 	      ipa_reference_optimization_summary_t info;
1139 	      int v_count;
1140 	      lto_cgraph_encoder_t encoder;
1141 
1142 	      index = streamer_read_uhwi (ib);
1143 	      encoder = file_data->cgraph_node_encoder;
1144 	      node = lto_cgraph_encoder_deref (encoder, index);
1145 	      info = XCNEW (struct ipa_reference_optimization_summary_d);
1146 	      set_reference_optimization_summary (node, info);
1147 	      info->statics_not_read = BITMAP_ALLOC (&optimization_summary_obstack);
1148 	      info->statics_not_written = BITMAP_ALLOC (&optimization_summary_obstack);
1149 	      if (dump_file)
1150 		fprintf (dump_file,
1151 			 "\nFunction name:%s/%i:\n  static not read:",
1152 			 cgraph_node_name (node), node->uid);
1153 
1154 	      /* Set the statics not read.  */
1155 	      v_count = streamer_read_hwi (ib);
1156 	      if (v_count == -1)
1157 		{
1158 		  info->statics_not_read = all_module_statics;
1159 		  if (dump_file)
1160 		    fprintf (dump_file, " all module statics");
1161 		}
1162 	      else
1163 		for (j = 0; j < (unsigned int)v_count; j++)
1164 		  {
1165 		    unsigned int var_index = streamer_read_uhwi (ib);
1166 		    tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1167 								   var_index);
1168 		    bitmap_set_bit (info->statics_not_read, DECL_UID (v_decl));
1169 		    if (dump_file)
1170 		      fprintf (dump_file, " %s",
1171 			       lang_hooks.decl_printable_name (v_decl, 2));
1172 		  }
1173 
1174 	      if (dump_file)
1175 		fprintf (dump_file,
1176 			 "\n  static not written:");
1177 	      /* Set the statics not written.  */
1178 	      v_count = streamer_read_hwi (ib);
1179 	      if (v_count == -1)
1180 		{
1181 		  info->statics_not_written = all_module_statics;
1182 		  if (dump_file)
1183 		    fprintf (dump_file, " all module statics");
1184 		}
1185 	      else
1186 		for (j = 0; j < (unsigned int)v_count; j++)
1187 		  {
1188 		    unsigned int var_index = streamer_read_uhwi (ib);
1189 		    tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1190 								   var_index);
1191 		    bitmap_set_bit (info->statics_not_written, DECL_UID (v_decl));
1192 		    if (dump_file)
1193 		      fprintf (dump_file, " %s",
1194 			       lang_hooks.decl_printable_name (v_decl, 2));
1195 		  }
1196 	      if (dump_file)
1197 		fprintf (dump_file, "\n");
1198 	    }
1199 
1200 	  lto_destroy_simple_input_block (file_data,
1201 					  LTO_section_ipa_reference,
1202 					  ib, data, len);
1203 	}
1204       else
1205 	/* Fatal error here.  We do not want to support compiling ltrans units with
1206 	   different version of compiler or different flags than the WPA unit, so
1207 	   this should never happen.  */
1208 	fatal_error ("ipa reference summary is missing in ltrans unit");
1209     }
1210 }
1211 
1212 static bool
1213 gate_reference (void)
1214 {
1215   return (flag_ipa_reference
1216 	  /* Don't bother doing anything if the program has errors.  */
1217 	  && !seen_error ());
1218 }
1219 
1220 struct ipa_opt_pass_d pass_ipa_reference =
1221 {
1222  {
1223   IPA_PASS,
1224   "static-var",				/* name */
1225   gate_reference,			/* gate */
1226   propagate,			        /* execute */
1227   NULL,					/* sub */
1228   NULL,					/* next */
1229   0,					/* static_pass_number */
1230   TV_IPA_REFERENCE,		        /* tv_id */
1231   0,	                                /* properties_required */
1232   0,					/* properties_provided */
1233   0,					/* properties_destroyed */
1234   0,					/* todo_flags_start */
1235   0                                     /* todo_flags_finish */
1236  },
1237  NULL,				        /* generate_summary */
1238  NULL,					/* write_summary */
1239  NULL,				 	/* read_summary */
1240  ipa_reference_write_optimization_summary,/* write_optimization_summary */
1241  ipa_reference_read_optimization_summary,/* read_optimization_summary */
1242  NULL,					/* stmt_fixup */
1243  0,					/* TODOs */
1244  NULL,			                /* function_transform */
1245  NULL					/* variable_transform */
1246 };
1247