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
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 3, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along 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
81static void remove_node_data (struct cgraph_node *node,
82			      void *data ATTRIBUTE_UNUSED);
83static 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
90struct 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
101struct 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
109struct ipa_reference_optimization_summary_d
110{
111  bitmap statics_not_read;
112  bitmap statics_not_written;
113};
114
115typedef struct ipa_reference_local_vars_info_d *ipa_reference_local_vars_info_t;
116typedef struct ipa_reference_global_vars_info_d *ipa_reference_global_vars_info_t;
117typedef struct ipa_reference_optimization_summary_d *ipa_reference_optimization_summary_t;
118
119struct 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
125typedef 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.  */
129static 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.  */
134static bitmap all_module_statics;
135/* Set of all statics that should be ignored becuase they are touched by
136   -fno-ipa-reference code.  */
137static bitmap ignore_module_statics;
138
139/* Obstack holding bitmaps of local analysis (live from analysis to
140   propagation)  */
141static bitmap_obstack local_info_obstack;
142/* Obstack holding global analysis live forever.  */
143static bitmap_obstack optimization_summary_obstack;
144
145/* Holders of ipa cgraph hooks: */
146static struct cgraph_2node_hook_list *node_duplication_hook_holder;
147static 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.  */
151static vec<ipa_reference_vars_info_t> ipa_reference_vars_vector;
152
153static vec<ipa_reference_optimization_summary_t> ipa_reference_opt_sum_vector;
154
155/* Return the ipa_reference_vars structure starting from the cgraph NODE.  */
156static inline ipa_reference_vars_info_t
157get_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.  */
166static inline ipa_reference_optimization_summary_t
167get_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.  */
176static inline void
177set_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.  */
187static inline void
188set_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
201bitmap
202ipa_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
222bitmap
223ipa_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
242static inline bool
243is_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
279static const char *
280get_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.  */
288static void
289dump_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
308static bool
309union_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
339static bitmap
340copy_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
357static void
358propagate_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
413static bool ipa_init_p = false;
414
415/* The init routine for analyzing global static variable usage.  See
416   comments at top for description.  */
417static void
418ipa_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
442static ipa_reference_local_vars_info_t
443init_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
461static void
462analyze_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
512static void
513duplicate_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
532static void
533remove_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
554static void
555generate_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
623static void
624read_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
656static void
657get_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
701static bool
702ignore_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
712static unsigned int
713propagate (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
917static bool
918write_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
954static void
955stream_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
986static void
987ipa_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
1059static void
1060ipa_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
1180namespace {
1181
1182const 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
1195class pass_ipa_reference : public ipa_opt_pass_d
1196{
1197public:
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
1227ipa_opt_pass_d *
1228make_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
1236void
1237ipa_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