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