OSDN Git Service

* gcc/ChangeLog: Fix ChangeLog.
[pf3gnuchains/gcc-fork.git] / gcc / ipa-reference.c
1 /* Callgraph based analysis of static variables.
2    Copyright (C) 2004, 2005, 2007, 2008 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    There are two categories of information produced by this pass:
25
26    1) The addressable (TREE_ADDRESSABLE) bit and readonly
27    (TREE_READONLY) bit associated with these variables is properly set
28    based on scanning all of the code withing the compilation unit.
29
30    2) The transitive call site specific clobber effects are computed
31    for the variables whose scope is contained within this compilation
32    unit.
33
34    First each function and static variable initialization is analyzed
35    to determine which local static variables are either read, written,
36    or have their address taken.  Any local static that has its address
37    taken is removed from consideration.  Once the local read and
38    writes are determined, a transitive closure of this information is
39    performed over the call graph to determine the worst case set of
40    side effects of each call.  In later parts of the compiler, these
41    local and global sets are examined to make the call clobbering less
42    traumatic, promote some statics to registers, and improve aliasing
43    information.
44    
45    Currently must be run after inlining decisions have been made since
46    otherwise, the local sets will not contain information that is
47    consistent with post inlined state.  The global sets are not prone
48    to this problem since they are by definition transitive.  */
49
50 #include "config.h"
51 #include "system.h"
52 #include "coretypes.h"
53 #include "tm.h"
54 #include "tree.h"
55 #include "tree-flow.h"
56 #include "tree-inline.h"
57 #include "tree-pass.h"
58 #include "langhooks.h"
59 #include "pointer-set.h"
60 #include "ggc.h"
61 #include "ipa-utils.h"
62 #include "ipa-reference.h"
63 #include "c-common.h"
64 #include "gimple.h"
65 #include "cgraph.h"
66 #include "output.h"
67 #include "flags.h"
68 #include "timevar.h"
69 #include "diagnostic.h"
70 #include "langhooks.h"
71
72 /* The static variables defined within the compilation unit that are
73    loaded or stored directly by function that owns this structure.  */ 
74
75 struct ipa_reference_local_vars_info_d 
76 {
77   bitmap statics_read;
78   bitmap statics_written;
79
80   /* Set when this function calls another function external to the
81      compilation unit or if the function has a asm clobber of memory.
82      In general, such calls are modeled as reading and writing all
83      variables (both bits on) but sometime there are attributes on the
84      called function so we can do better.  */
85   bool calls_read_all;
86   bool calls_write_all;
87 };
88
89 /* Statics that are read and written by some set of functions. The
90    local ones are based on the loads and stores local to the function.
91    The global ones are based on the local info as well as the
92    transitive closure of the functions that are called.  The
93    structures are separated to allow the global structures to be
94    shared between several functions since every function within a
95    strongly connected component will have the same information.  This
96    sharing saves both time and space in the computation of the vectors
97    as well as their translation from decl_uid form to ann_uid
98    form.  */ 
99
100 struct ipa_reference_global_vars_info_d
101 {
102   bitmap statics_read;
103   bitmap statics_written;
104   bitmap statics_not_read;
105   bitmap statics_not_written;
106 };
107
108 typedef struct ipa_reference_local_vars_info_d *ipa_reference_local_vars_info_t;
109 typedef struct ipa_reference_global_vars_info_d *ipa_reference_global_vars_info_t;
110 struct ipa_reference_vars_info_d 
111 {
112   ipa_reference_local_vars_info_t local;
113   ipa_reference_global_vars_info_t global;
114 };
115
116 typedef struct ipa_reference_vars_info_d *ipa_reference_vars_info_t;
117
118 /* This splay tree contains all of the static variables that are
119    being considered by the compilation level alias analysis.  For
120    module_at_a_time compilation, this is the set of static but not
121    public variables.  Any variables that either have their address
122    taken or participate in otherwise unsavory operations are deleted
123    from this list.  */
124 static GTY((param1_is(int), param2_is(tree)))
125      splay_tree reference_vars_to_consider;
126
127 /* This bitmap is used to knock out the module static variables whose
128    addresses have been taken and passed around.  */
129 static bitmap module_statics_escape;
130
131 /* This bitmap is used to knock out the module static variables that
132    are not readonly.  */
133 static bitmap module_statics_written;
134
135 /* A bit is set for every module static we are considering.  This is
136    ored into the local info when asm code is found that clobbers all
137    memory. */
138 static bitmap all_module_statics;
139
140 static struct pointer_set_t *visited_nodes;
141
142 /* Obstack holding bitmaps of local analysis (live from analysis to
143    propagation)  */
144 static bitmap_obstack local_info_obstack;
145 /* Obstack holding global analysis live forever.  */
146 static bitmap_obstack global_info_obstack;
147
148 /* Holders of ipa cgraph hooks: */
149 static struct cgraph_node_hook_list *function_insertion_hook_holder;
150 static struct cgraph_2node_hook_list *node_duplication_hook_holder;
151 static struct cgraph_node_hook_list *node_removal_hook_holder;
152
153 enum initialization_status_t
154 {
155   UNINITIALIZED,
156   RUNNING,
157   FINISHED
158 };
159
160 tree memory_identifier_string;
161
162 /* Vector where the reference var infos are actually stored. */
163 DEF_VEC_P (ipa_reference_vars_info_t);
164 DEF_VEC_ALLOC_P (ipa_reference_vars_info_t, heap);
165 static VEC (ipa_reference_vars_info_t, heap) *ipa_reference_vars_vector;
166
167 /* Return the ipa_reference_vars structure starting from the cgraph NODE.  */
168 static inline ipa_reference_vars_info_t
169 get_reference_vars_info (struct cgraph_node *node)
170 {
171   if (!ipa_reference_vars_vector
172       || VEC_length (ipa_reference_vars_info_t, ipa_reference_vars_vector) <= (unsigned int)node->uid)
173     return NULL;
174   return VEC_index (ipa_reference_vars_info_t, ipa_reference_vars_vector, node->uid);
175 }
176
177 /* Return the ipa_reference_vars structure starting from the cgraph NODE.  */
178 static inline void
179 set_reference_vars_info (struct cgraph_node *node, ipa_reference_vars_info_t info)
180 {
181   if (!ipa_reference_vars_vector
182       || VEC_length (ipa_reference_vars_info_t, ipa_reference_vars_vector) <= (unsigned int)node->uid)
183      VEC_safe_grow_cleared (ipa_reference_vars_info_t, heap, ipa_reference_vars_vector, node->uid + 1);
184   VEC_replace (ipa_reference_vars_info_t, ipa_reference_vars_vector, node->uid, info);
185 }
186
187 /* Get a bitmap that contains all of the locally referenced static
188    variables for function FN.  */
189 static ipa_reference_local_vars_info_t
190 get_local_reference_vars_info (struct cgraph_node *fn) 
191 {
192   ipa_reference_vars_info_t info = get_reference_vars_info (fn);
193
194   if (info)
195     return info->local;
196   else
197     /* This phase was not run.  */ 
198     return NULL;
199 }
200
201 /* Get a bitmap that contains all of the globally referenced static
202    variables for function FN.  */
203  
204 static ipa_reference_global_vars_info_t
205 get_global_reference_vars_info (struct cgraph_node *fn) 
206 {
207   ipa_reference_vars_info_t info = get_reference_vars_info (fn);
208
209   if (info)
210     return info->global;
211   else
212     /* This phase was not run.  */ 
213     return NULL;
214 }
215
216 /* Return a bitmap indexed by VAR_DECL uid for the static variables
217    that are read during the execution of the function FN.  Returns
218    NULL if no data is available.  */
219
220 bitmap 
221 ipa_reference_get_read_global (struct cgraph_node *fn) 
222 {
223   ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
224   if (g) 
225     return g->statics_read;
226   else
227     return NULL;
228 }
229
230 /* Return a bitmap indexed by VAR_DECL uid for the static variables
231    that are written during the execution of the function FN.  Note
232    that variables written may or may not be read during the function
233    call.  Returns NULL if no data is available.  */
234
235 bitmap 
236 ipa_reference_get_written_global (struct cgraph_node *fn) 
237 {
238   ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
239   if (g) 
240     return g->statics_written;
241   else
242     return NULL;
243 }
244
245 /* Return a bitmap indexed by_DECL_UID uid for the static variables
246    that are not read during the execution of the function FN.  Returns
247    NULL if no data is available.  */
248
249 bitmap 
250 ipa_reference_get_not_read_global (struct cgraph_node *fn) 
251 {
252   ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
253   if (g) 
254     return g->statics_not_read;
255   else
256     return NULL;
257 }
258
259 /* Return a bitmap indexed by DECL_UID uid for the static variables
260    that are not written during the execution of the function FN.  Note
261    that variables written may or may not be read during the function
262    call.  Returns NULL if no data is available.  */
263
264 bitmap 
265 ipa_reference_get_not_written_global (struct cgraph_node *fn) 
266 {
267   ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
268   if (g) 
269     return g->statics_not_written;
270   else
271     return NULL;
272 }
273
274 \f
275
276 /* Add VAR to all_module_statics and the two
277    reference_vars_to_consider* sets.  */
278
279 static inline void 
280 add_static_var (tree var) 
281 {
282   int uid = DECL_UID (var);
283   gcc_assert (TREE_CODE (var) == VAR_DECL);
284   if (!bitmap_bit_p (all_module_statics, uid))
285     {
286       splay_tree_insert (reference_vars_to_consider,
287                          uid, (splay_tree_value)var);
288       bitmap_set_bit (all_module_statics, uid);
289     }
290 }
291
292 /* Return true if the variable T is the right kind of static variable to
293    perform compilation unit scope escape analysis.  */
294
295 static inline bool 
296 has_proper_scope_for_analysis (tree t)
297 {
298   /* If the variable has the "used" attribute, treat it as if it had a
299      been touched by the devil.  */
300   if (lookup_attribute ("used", DECL_ATTRIBUTES (t)))
301     return false;
302
303   /* Do not want to do anything with volatile except mark any
304      function that uses one to be not const or pure.  */
305   if (TREE_THIS_VOLATILE (t)) 
306     return false;
307
308   /* Do not care about a local automatic that is not static.  */
309   if (!TREE_STATIC (t) && !DECL_EXTERNAL (t))
310     return false;
311
312   if (DECL_EXTERNAL (t) || TREE_PUBLIC (t))
313     return false;
314
315   /* We cannot touch decls where the type needs constructing.  */
316   if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (t)))
317     return false;
318
319   /* This is a variable we care about.  Check if we have seen it
320      before, and if not add it the set of variables we care about.  */
321   if (!bitmap_bit_p (all_module_statics, DECL_UID (t)))
322     add_static_var (t);
323
324   return true;
325 }
326
327 /* Mark tree T as having address taken.  */
328
329 static void
330 mark_address_taken (tree x)
331 {
332   if (TREE_CODE (x) == VAR_DECL
333       && module_statics_escape && has_proper_scope_for_analysis (x))
334     bitmap_set_bit (module_statics_escape, DECL_UID (x));
335 }
336
337 /* Mark load of T.  */
338
339 static void
340 mark_load (ipa_reference_local_vars_info_t local, 
341            tree t)
342 {
343   if (TREE_CODE (t) == VAR_DECL
344       && has_proper_scope_for_analysis (t))
345     bitmap_set_bit (local->statics_read, DECL_UID (t));
346 }
347
348 /* Mark store of T.  */
349
350 static void
351 mark_store (ipa_reference_local_vars_info_t local, 
352            tree t)
353 {
354   if (TREE_CODE (t) == VAR_DECL
355       && has_proper_scope_for_analysis (t))
356     {
357       if (local)
358         bitmap_set_bit (local->statics_written, DECL_UID (t));
359       /* Mark the write so we can tell which statics are
360          readonly.  */
361       if (module_statics_written)
362         bitmap_set_bit (module_statics_written, DECL_UID (t));
363     }
364 }
365
366 /* Look for memory clobber and set read_all/write_all if present.  */
367
368 static void
369 check_asm_memory_clobber (ipa_reference_local_vars_info_t local, gimple stmt)
370 {
371   size_t i;
372   tree op;
373   
374   for (i = 0; i < gimple_asm_nclobbers (stmt); i++)
375     {
376       op = gimple_asm_clobber_op (stmt, i);
377       if (simple_cst_equal(TREE_VALUE (op), memory_identifier_string) == 1) 
378         {
379           /* Abandon all hope, ye who enter here. */
380           local->calls_read_all = true;
381           local->calls_write_all = true;
382         }      
383     }
384 }
385
386 /* Look for external calls and set read_all/write_all correspondingly.  */
387
388 static void
389 check_call (ipa_reference_local_vars_info_t local, gimple stmt)
390 {
391   int flags = gimple_call_flags (stmt);
392   tree callee_t = gimple_call_fndecl (stmt);
393   enum availability avail = AVAIL_NOT_AVAILABLE;
394
395   if (callee_t)
396     {
397       struct cgraph_node* callee = cgraph_node(callee_t);
398       avail = cgraph_function_body_availability (callee);
399     }
400
401   if (avail <= AVAIL_OVERWRITABLE)
402     if (local) 
403       {
404         if (flags & ECF_CONST) 
405           ;
406         else if (flags & ECF_PURE)
407           local->calls_read_all = true;
408         else 
409           {
410             local->calls_read_all = true;
411             local->calls_write_all = true;
412           }
413       }
414    /* TODO: To be able to produce sane results, we should also handle
415       common builtins, in particular throw.
416       Indirect calls hsould be only counted and as inliner is replacing them
417       by direct calls, we can conclude if any indirect calls are left in body */
418 }
419
420 /* TP is the part of the tree currently under the microscope.
421    WALK_SUBTREES is part of the walk_tree api but is unused here.
422    DATA is cgraph_node of the function being walked.  */
423
424 static tree
425 scan_stmt_for_static_refs (gimple_stmt_iterator *gsip,
426                            struct cgraph_node *fn)
427 {
428   gimple stmt = gsi_stmt (*gsip);
429   ipa_reference_local_vars_info_t local = NULL;
430   unsigned int i;
431   bitmap_iterator bi;
432
433   if (fn)
434     local = get_reference_vars_info (fn)->local;
435
436   /* Look for direct loads and stores.  */
437   if (gimple_has_lhs (stmt))
438     {
439       tree lhs = get_base_address (gimple_get_lhs (stmt));
440       if (lhs && DECL_P (lhs))
441         mark_store (local, lhs);
442     }
443   if (gimple_assign_single_p (stmt))
444     {
445       tree rhs = get_base_address (gimple_assign_rhs1 (stmt));
446       if (rhs && DECL_P (rhs))
447         mark_load (local, rhs);
448     }
449   else if (is_gimple_call (stmt))
450     {
451       for (i = 0; i < gimple_call_num_args (stmt); ++i)
452         {
453           tree rhs = get_base_address (gimple_call_arg (stmt, i));
454           if (rhs && DECL_P (rhs))
455             mark_load (local, rhs);
456         }
457       check_call (local, stmt);
458     }
459   else if (gimple_code (stmt) == GIMPLE_ASM)
460     {
461       for (i = 0; i < gimple_asm_ninputs (stmt); ++i)
462         {
463           tree op = TREE_VALUE (gimple_asm_input_op (stmt, i));
464           op = get_base_address (op);
465           if (op && DECL_P (op))
466             mark_load (local, op);
467         }
468       for (i = 0; i < gimple_asm_noutputs (stmt); ++i)
469         {
470           tree op = TREE_VALUE (gimple_asm_output_op (stmt, i));
471           op = get_base_address (op);
472           if (op && DECL_P (op))
473             mark_store (local, op);
474         }
475       check_asm_memory_clobber (local, stmt);
476     }
477
478   if (gimple_addresses_taken (stmt))
479     EXECUTE_IF_SET_IN_BITMAP (gimple_addresses_taken (stmt), 0, i, bi)
480       mark_address_taken (referenced_var_lookup (i));
481   
482   return NULL;
483 }
484
485 /* Call-back to scan variable initializers for static references.  
486    Called using walk_tree.  */
487
488 static tree
489 scan_initializer_for_static_refs (tree *tp, int *walk_subtrees,
490                                   void *data ATTRIBUTE_UNUSED)
491 {
492   tree t = *tp;
493
494   if (TREE_CODE (t) == ADDR_EXPR)
495     {
496       mark_address_taken (get_base_var (t));
497       *walk_subtrees = 0;
498     }
499   /* Save some cycles by not walking types and declaration as we
500      won't find anything useful there anyway.  */
501   else if (IS_TYPE_OR_DECL_P (*tp))
502     *walk_subtrees = 0;
503  
504   return NULL;
505 }
506
507 /* Lookup the tree node for the static variable that has UID.  */
508 static tree
509 get_static_decl (int index)
510 {
511   splay_tree_node stn = 
512     splay_tree_lookup (reference_vars_to_consider, index);
513   if (stn)
514     return (tree)stn->value;
515   return NULL;
516 }
517
518 /* Lookup the tree node for the static variable that has UID and
519    convert the name to a string for debugging.  */
520
521 static const char *
522 get_static_name (int index)
523 {
524   splay_tree_node stn = 
525     splay_tree_lookup (reference_vars_to_consider, index);
526   if (stn)
527     return lang_hooks.decl_printable_name ((tree)(stn->value), 2);
528   return NULL;
529 }
530
531 /* Or in all of the bits from every callee of X into X_GLOBAL, the caller's cycle,
532    bit vector.  There are several cases to check to avoid the sparse
533    bitmap oring.  */
534
535 static void
536 propagate_bits (ipa_reference_global_vars_info_t x_global, struct cgraph_node *x)
537 {
538   struct cgraph_edge *e;
539   for (e = x->callees; e; e = e->next_callee) 
540     {
541       struct cgraph_node *y = e->callee;
542
543       /* Only look at the master nodes and skip external nodes.  */
544       if (cgraph_function_body_availability (e->callee) > AVAIL_OVERWRITABLE)
545         {
546           if (get_reference_vars_info (y))
547             {
548               ipa_reference_vars_info_t y_info 
549                 = get_reference_vars_info (y);
550               ipa_reference_global_vars_info_t y_global = y_info->global;
551
552               /* Calls in current cycle do not have global computed yet.  */
553               if (!y_info->global)
554                 continue;
555               
556               if (x_global->statics_read
557                   != all_module_statics)
558                 {
559                   if (y_global->statics_read 
560                       == all_module_statics)
561                     {
562                       BITMAP_FREE (x_global->statics_read);
563                       x_global->statics_read 
564                         = all_module_statics;
565                     }
566                   /* Skip bitmaps that are pointer equal to node's bitmap
567                      (no reason to spin within the cycle).  */
568                   else if (x_global->statics_read 
569                            != y_global->statics_read)
570                     bitmap_ior_into (x_global->statics_read,
571                                      y_global->statics_read);
572                 }
573               
574               if (x_global->statics_written 
575                   != all_module_statics)
576                 {
577                   if (y_global->statics_written 
578                       == all_module_statics)
579                     {
580                       BITMAP_FREE (x_global->statics_written);
581                       x_global->statics_written 
582                         = all_module_statics;
583                     }
584                   /* Skip bitmaps that are pointer equal to node's bitmap
585                      (no reason to spin within the cycle).  */
586                   else if (x_global->statics_written 
587                            != y_global->statics_written)
588                     bitmap_ior_into (x_global->statics_written,
589                                      y_global->statics_written);
590                 }
591             }
592           else 
593             gcc_unreachable ();
594         }
595     }
596 }
597
598 /* The init routine for analyzing global static variable usage.  See
599    comments at top for description.  */
600 static void 
601 ipa_init (void) 
602 {
603   memory_identifier_string = build_string(7, "memory");
604
605   reference_vars_to_consider =
606     splay_tree_new_ggc (splay_tree_compare_ints);
607
608   bitmap_obstack_initialize (&local_info_obstack);
609   bitmap_obstack_initialize (&global_info_obstack);
610   module_statics_escape = BITMAP_ALLOC (&local_info_obstack);
611   module_statics_written = BITMAP_ALLOC (&local_info_obstack);
612   all_module_statics = BITMAP_ALLOC (&global_info_obstack);
613
614   /* There are some shared nodes, in particular the initializers on
615      static declarations.  We do not need to scan them more than once
616      since all we would be interested in are the addressof
617      operations.  */
618   visited_nodes = pointer_set_create ();
619 }
620
621 /* Check out the rhs of a static or global initialization VNODE to see
622    if any of them contain addressof operations.  Note that some of
623    these variables may  not even be referenced in the code in this
624    compilation unit but their right hand sides may contain references
625    to variables defined within this unit.  */
626
627 static void 
628 analyze_variable (struct varpool_node *vnode)
629 {
630   struct walk_stmt_info wi;
631   tree global = vnode->decl;
632
633   memset (&wi, 0, sizeof (wi));
634   wi.pset = visited_nodes;
635   walk_tree (&DECL_INITIAL (global), scan_initializer_for_static_refs,
636              &wi, wi.pset);
637 }
638
639 /* Set up the persistent info for FN.  */
640
641 static ipa_reference_local_vars_info_t
642 init_function_info (struct cgraph_node *fn)
643 {
644   ipa_reference_vars_info_t info 
645     = XCNEW (struct ipa_reference_vars_info_d);
646   ipa_reference_local_vars_info_t l
647     = XCNEW (struct ipa_reference_local_vars_info_d);
648
649   /* Add the info to the tree's annotation.  */
650   set_reference_vars_info (fn, info);
651
652   info->local = l;
653   l->statics_read = BITMAP_ALLOC (&local_info_obstack);
654   l->statics_written = BITMAP_ALLOC (&local_info_obstack);
655
656   return l;
657 }
658
659 /* This is the main routine for finding the reference patterns for
660    global variables within a function FN.  */
661   
662 static void
663 analyze_function (struct cgraph_node *fn)
664 {
665   tree decl = fn->decl;
666   struct function *this_cfun = DECL_STRUCT_FUNCTION (decl);
667   basic_block this_block;
668 #ifdef ENABLE_CHECKING
669   tree step;
670 #endif
671
672   if (dump_file)
673     fprintf (dump_file, "\n local analysis of %s\n", cgraph_node_name (fn));
674
675   push_cfun (DECL_STRUCT_FUNCTION (decl));
676   current_function_decl = decl;
677   
678   init_function_info (fn);
679   FOR_EACH_BB_FN (this_block, this_cfun)
680     {
681       gimple_stmt_iterator gsi;
682       gimple phi;
683       tree op;
684       use_operand_p use;
685       ssa_op_iter iter;
686
687       /* Find the addresses taken in phi node arguments.  */
688       for (gsi = gsi_start_phis (this_block);
689            !gsi_end_p (gsi);
690            gsi_next (&gsi))
691         {
692           phi = gsi_stmt (gsi);
693           FOR_EACH_PHI_ARG (use, phi, iter, SSA_OP_USE)
694             {
695               op = USE_FROM_PTR (use);
696               if (TREE_CODE (op) == ADDR_EXPR)
697                 mark_address_taken (get_base_var (op));
698             }
699         }
700
701       for (gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi))
702         scan_stmt_for_static_refs (&gsi, fn);
703     }
704
705 #ifdef ENABLE_CHECKING
706   /* Verify that all local initializers was expanded by gimplifier.  */
707   for (step = DECL_STRUCT_FUNCTION (decl)->local_decls;
708        step;
709        step = TREE_CHAIN (step))
710     {
711       tree var = TREE_VALUE (step);
712       if (TREE_CODE (var) == VAR_DECL 
713           && DECL_INITIAL (var)
714           && !TREE_STATIC (var))
715         gcc_unreachable ();
716     }
717 #endif
718   pop_cfun ();
719   current_function_decl = NULL;
720 }
721
722 /* Remove local data associated with function FN.  */
723 static void
724 clean_function_local_data (struct cgraph_node *fn)
725 {
726   ipa_reference_vars_info_t info = get_reference_vars_info (fn);
727   ipa_reference_local_vars_info_t l = info->local;
728   if (l)
729     {
730       if (l->statics_read
731           && l->statics_read != all_module_statics)
732         BITMAP_FREE (l->statics_read);
733       if (l->statics_written
734           &&l->statics_written != all_module_statics)
735         BITMAP_FREE (l->statics_written);
736       free (l);
737       info->local = NULL;
738     }
739 }
740
741 /* Remove all data associated with function FN.  */
742
743 static void
744 clean_function (struct cgraph_node *fn)
745 {
746   ipa_reference_vars_info_t info = get_reference_vars_info (fn);
747   ipa_reference_global_vars_info_t g = info->global;
748   
749   clean_function_local_data (fn);
750   if (g)
751     {
752       if (g->statics_read
753           && g->statics_read != all_module_statics)
754         BITMAP_FREE (g->statics_read);
755       
756       if (g->statics_written
757           && g->statics_written != all_module_statics)
758         BITMAP_FREE (g->statics_written);
759       
760       if (g->statics_not_read
761           && g->statics_not_read != all_module_statics)
762         BITMAP_FREE (g->statics_not_read);
763       
764       if (g->statics_not_written
765           && g->statics_not_written != all_module_statics)
766         BITMAP_FREE (g->statics_not_written);
767       free (g);
768       info->global = NULL;
769     }
770   
771   free (get_reference_vars_info (fn));
772   set_reference_vars_info (fn, NULL);
773 }
774
775 /* Called when new function is inserted to callgraph late.  */
776 static void
777 add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
778 {
779   /* There are some shared nodes, in particular the initializers on
780      static declarations.  We do not need to scan them more than once
781      since all we would be interested in are the addressof
782      operations.  */
783   analyze_function (node);
784   visited_nodes = NULL;
785 }
786
787 static bitmap
788 copy_local_bitmap (bitmap src)
789 {
790   bitmap dst;
791   if (!src)
792     return NULL;
793   if (src == all_module_statics)
794     return all_module_statics;
795   dst = BITMAP_ALLOC (&local_info_obstack);
796   bitmap_copy (dst, src);
797   return dst;
798 }
799
800 static bitmap
801 copy_global_bitmap (bitmap src)
802 {
803   bitmap dst;
804   if (!src)
805     return NULL;
806   if (src == all_module_statics)
807     return all_module_statics;
808   dst = BITMAP_ALLOC (&global_info_obstack);
809   bitmap_copy (dst, src);
810   return dst;
811 }
812
813 /* Called when new clone is inserted to callgraph late.  */
814
815 static void
816 duplicate_node_data (struct cgraph_node *src, struct cgraph_node *dst,
817                      void *data ATTRIBUTE_UNUSED)
818 {
819   ipa_reference_global_vars_info_t ginfo;
820   ipa_reference_local_vars_info_t linfo;
821   ipa_reference_global_vars_info_t dst_ginfo;
822   ipa_reference_local_vars_info_t dst_linfo;
823
824   ginfo = get_global_reference_vars_info (src);
825   linfo = get_local_reference_vars_info (src);
826   if (!linfo && !ginfo)
827     return;
828   init_function_info (dst);
829   if (linfo)
830     {
831       dst_linfo = get_local_reference_vars_info (dst);
832       dst_linfo->statics_read = copy_local_bitmap (linfo->statics_read);
833       dst_linfo->statics_written = copy_local_bitmap (linfo->statics_written);
834       dst_linfo->calls_read_all = linfo->calls_read_all;
835       dst_linfo->calls_write_all = linfo->calls_write_all;
836     }
837   if (ginfo)
838     {
839       get_reference_vars_info (dst)->global = XCNEW (struct ipa_reference_global_vars_info_d);
840       dst_ginfo = get_global_reference_vars_info (dst);
841       dst_ginfo->statics_read = copy_global_bitmap (ginfo->statics_read);
842       dst_ginfo->statics_written = copy_global_bitmap (ginfo->statics_written);
843       dst_ginfo->statics_not_read = copy_global_bitmap (ginfo->statics_not_read);
844       dst_ginfo->statics_not_written = copy_global_bitmap (ginfo->statics_not_written);
845     }
846 }
847
848 /* Called when node is removed.  */
849
850 static void
851 remove_node_data (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
852 {
853   if (get_reference_vars_info (node))
854     clean_function (node);
855 }
856
857 /* Analyze each function in the cgraph to see which global or statics
858    are read or written.  */
859
860 static void 
861 generate_summary (void)
862 {
863   struct cgraph_node *node;
864   struct varpool_node *vnode;
865   unsigned int index;
866   bitmap_iterator bi;
867   bitmap module_statics_readonly;
868   bitmap bm_temp;
869   
870   function_insertion_hook_holder =
871       cgraph_add_function_insertion_hook (&add_new_function, NULL);
872   node_removal_hook_holder =
873       cgraph_add_node_removal_hook (&remove_node_data, NULL);
874   node_duplication_hook_holder =
875       cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
876   ipa_init ();
877   module_statics_readonly = BITMAP_ALLOC (&local_info_obstack);
878   bm_temp = BITMAP_ALLOC (&local_info_obstack);
879
880   /* Process all of the variables first.  */
881   FOR_EACH_STATIC_INITIALIZER (vnode)
882     analyze_variable (vnode);
883
884   /* Process all of the functions next. 
885
886      We do not want to process any of the clones so we check that this
887      is a master clone.  However, we do need to process any
888      AVAIL_OVERWRITABLE functions (these are never clones) because
889      they may cause a static variable to escape.  The code that can
890      overwrite such a function cannot access the statics because it
891      would not be in the same compilation unit.  When the analysis is
892      finished, the computed information of these AVAIL_OVERWRITABLE is
893      replaced with worst case info.  
894   */
895   for (node = cgraph_nodes; node; node = node->next)
896     if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
897       analyze_function (node);
898
899   pointer_set_destroy (visited_nodes);
900   visited_nodes = NULL;
901
902   /* Prune out the variables that were found to behave badly
903      (i.e. have their address taken).  */
904   EXECUTE_IF_SET_IN_BITMAP (module_statics_escape, 0, index, bi)
905     {
906       splay_tree_remove (reference_vars_to_consider, index);
907     }
908   
909   bitmap_and_compl_into (all_module_statics, 
910                          module_statics_escape);
911   
912   bitmap_and_compl (module_statics_readonly, all_module_statics,
913                     module_statics_written);
914   
915   /* If the address is not taken, we can unset the addressable bit
916      on this variable.  */
917   EXECUTE_IF_SET_IN_BITMAP (all_module_statics, 0, index, bi)
918     {
919       tree var = get_static_decl (index);
920       TREE_ADDRESSABLE (var) = 0;
921       if (dump_file) 
922         fprintf (dump_file, "Not TREE_ADDRESSABLE var %s\n",
923                  get_static_name (index));
924     }
925   
926   /* If the variable is never written, we can set the TREE_READONLY
927      flag.  Additionally if it has a DECL_INITIAL that is made up of
928      constants we can treat the entire global as a constant.  */
929   
930   bitmap_and_compl (module_statics_readonly, all_module_statics,
931                     module_statics_written);
932   EXECUTE_IF_SET_IN_BITMAP (module_statics_readonly, 0, index, bi)
933     {
934       tree var = get_static_decl (index);
935       
936       /* Ignore variables in named sections - changing TREE_READONLY
937          changes the section flags, potentially causing conflicts with
938          other variables in the same named section.  */
939       if (DECL_SECTION_NAME (var) == NULL_TREE)
940         {
941           TREE_READONLY (var) = 1;
942           if (dump_file)
943             fprintf (dump_file, "read-only var %s\n", 
944                      get_static_name (index));
945         }
946     }
947   
948   BITMAP_FREE(module_statics_escape);
949   BITMAP_FREE(module_statics_written);
950   module_statics_escape = NULL;
951   module_statics_written = NULL;
952   
953   if (dump_file)
954     EXECUTE_IF_SET_IN_BITMAP (all_module_statics, 0, index, bi)
955       {
956         fprintf (dump_file, "\nPromotable global:%s",
957                  get_static_name (index));
958       }
959   
960   for (node = cgraph_nodes; node; node = node->next)
961     if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
962       {
963         ipa_reference_local_vars_info_t l;
964         l = get_reference_vars_info (node)->local;
965         
966         /* Any variables that are not in all_module_statics are
967            removed from the local maps.  This will include all of the
968            variables that were found to escape in the function
969            scanning.  */
970         bitmap_and_into (l->statics_read, 
971                          all_module_statics);
972         bitmap_and_into (l->statics_written, 
973                          all_module_statics);
974       }
975   
976   BITMAP_FREE(module_statics_readonly);
977   BITMAP_FREE(bm_temp);
978   
979   if (dump_file)
980     for (node = cgraph_nodes; node; node = node->next)
981       if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
982         {
983           ipa_reference_local_vars_info_t l;
984           unsigned int index;
985           bitmap_iterator bi;
986           
987           l = get_reference_vars_info (node)->local;
988           fprintf (dump_file, 
989                    "\nFunction name:%s/%i:", 
990                    cgraph_node_name (node), node->uid);
991           fprintf (dump_file, "\n  locals read: ");
992           EXECUTE_IF_SET_IN_BITMAP (l->statics_read,
993                                     0, index, bi)
994             {
995               fprintf (dump_file, "%s ",
996                        get_static_name (index));
997             }
998           fprintf (dump_file, "\n  locals written: ");
999           EXECUTE_IF_SET_IN_BITMAP (l->statics_written,
1000                                     0, index, bi)
1001             {
1002               fprintf(dump_file, "%s ",
1003                       get_static_name (index));
1004             }
1005           if (l->calls_read_all)
1006              fprintf (dump_file, "\n  calls read all: ");
1007           if (l->calls_write_all)
1008              fprintf (dump_file, "\n  calls read all: ");
1009         }
1010 }
1011 \f
1012 /* Produce the global information by preforming a transitive closure
1013    on the local information that was produced by ipa_analyze_function
1014    and ipa_analyze_variable.  */
1015
1016 static unsigned int
1017 propagate (void)
1018 {
1019   struct cgraph_node *node;
1020   struct cgraph_node *w;
1021   struct cgraph_node **order =
1022     XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
1023   int order_pos = ipa_utils_reduced_inorder (order, false, true);
1024   int i;
1025
1026   cgraph_remove_function_insertion_hook (function_insertion_hook_holder);
1027   if (dump_file) 
1028     dump_cgraph (dump_file);
1029
1030   /* Propagate the local information thru the call graph to produce
1031      the global information.  All the nodes within a cycle will have
1032      the same info so we collapse cycles first.  Then we can do the
1033      propagation in one pass from the leaves to the roots.  */
1034   order_pos = ipa_utils_reduced_inorder (order, true, true);
1035   if (dump_file)
1036     ipa_utils_print_order(dump_file, "reduced", order, order_pos);
1037
1038   for (i = 0; i < order_pos; i++ )
1039     {
1040       ipa_reference_vars_info_t node_info;
1041       ipa_reference_global_vars_info_t node_g = 
1042         XCNEW (struct ipa_reference_global_vars_info_d);
1043       ipa_reference_local_vars_info_t node_l;
1044       
1045       bool read_all;
1046       bool write_all;
1047       struct ipa_dfs_info * w_info;
1048
1049       node = order[i];
1050       node_info = get_reference_vars_info (node);
1051       if (!node_info) 
1052         {
1053           dump_cgraph_node (stderr, node);
1054           dump_cgraph (stderr);
1055           gcc_unreachable ();
1056         }
1057
1058       gcc_assert (!node_info->global);
1059       node_l = node_info->local;
1060
1061       read_all = node_l->calls_read_all;
1062       write_all = node_l->calls_write_all;
1063
1064       /* If any node in a cycle is calls_read_all or calls_write_all
1065          they all are. */
1066       w_info = (struct ipa_dfs_info *) node->aux;
1067       w = w_info->next_cycle;
1068       while (w)
1069         {
1070           ipa_reference_local_vars_info_t w_l = 
1071             get_reference_vars_info (w)->local;
1072           read_all |= w_l->calls_read_all;
1073           write_all |= w_l->calls_write_all;
1074
1075           w_info = (struct ipa_dfs_info *) w->aux;
1076           w = w_info->next_cycle;
1077         }
1078
1079       /* Initialized the bitmaps for the reduced nodes */
1080       if (read_all) 
1081         node_g->statics_read = all_module_statics;
1082       else 
1083         {
1084           node_g->statics_read = BITMAP_ALLOC (&global_info_obstack);
1085           bitmap_copy (node_g->statics_read, 
1086                        node_l->statics_read);
1087         }
1088
1089       if (write_all) 
1090         node_g->statics_written = all_module_statics;
1091       else
1092         {
1093           node_g->statics_written = BITMAP_ALLOC (&global_info_obstack);
1094           bitmap_copy (node_g->statics_written, 
1095                        node_l->statics_written);
1096         }
1097
1098       propagate_bits (node_g, node);
1099       w_info = (struct ipa_dfs_info *) node->aux;
1100       w = w_info->next_cycle;
1101       while (w)
1102         {
1103           ipa_reference_vars_info_t w_ri = 
1104             get_reference_vars_info (w);
1105           ipa_reference_local_vars_info_t w_l = w_ri->local;
1106           
1107           /* These global bitmaps are initialized from the local info
1108              of all of the nodes in the region.  However there is no
1109              need to do any work if the bitmaps were set to
1110              all_module_statics.  */
1111           if (!read_all)
1112             bitmap_ior_into (node_g->statics_read,
1113                              w_l->statics_read);
1114           if (!write_all)
1115             bitmap_ior_into (node_g->statics_written,
1116                              w_l->statics_written);
1117           propagate_bits (node_g, w);
1118           w_info = (struct ipa_dfs_info *) w->aux;
1119           w = w_info->next_cycle;
1120         }
1121
1122       /* All nodes within a cycle have the same global info bitmaps.  */
1123       node_info->global = node_g;
1124       w_info = (struct ipa_dfs_info *) node->aux;
1125       w = w_info->next_cycle;
1126       while (w)
1127         {
1128           ipa_reference_vars_info_t w_ri = 
1129             get_reference_vars_info (w);
1130
1131           gcc_assert (!w_ri->global);
1132           w_ri->global = XCNEW (struct ipa_reference_global_vars_info_d);
1133           w_ri->global->statics_read = copy_global_bitmap (node_g->statics_read);
1134           w_ri->global->statics_written = copy_global_bitmap (node_g->statics_written);
1135
1136           w_info = (struct ipa_dfs_info *) w->aux;
1137           w = w_info->next_cycle;
1138         }
1139     }
1140
1141   if (dump_file)
1142     {
1143       for (i = 0; i < order_pos; i++ )
1144         {
1145           ipa_reference_vars_info_t node_info;
1146           ipa_reference_global_vars_info_t node_g;
1147           ipa_reference_local_vars_info_t node_l;
1148           unsigned int index;
1149           bitmap_iterator bi;
1150           struct ipa_dfs_info * w_info;
1151
1152           node = order[i];
1153           node_info = get_reference_vars_info (node);
1154           node_g = node_info->global;
1155           node_l = node_info->local;
1156           fprintf (dump_file, 
1157                    "\nFunction name:%s/%i:", 
1158                    cgraph_node_name (node), node->uid);
1159           fprintf (dump_file, "\n  locals read: ");
1160           EXECUTE_IF_SET_IN_BITMAP (node_l->statics_read,
1161                                     0, index, bi)
1162             {
1163               fprintf (dump_file, "%s ",
1164                        get_static_name (index));
1165             }
1166           fprintf (dump_file, "\n  locals written: ");
1167           EXECUTE_IF_SET_IN_BITMAP (node_l->statics_written,
1168                                     0, index, bi)
1169             {
1170               fprintf(dump_file, "%s ",
1171                       get_static_name (index));
1172             }
1173
1174           w_info = (struct ipa_dfs_info *) node->aux;
1175           w = w_info->next_cycle;
1176           while (w) 
1177             {
1178               ipa_reference_vars_info_t w_ri = 
1179                 get_reference_vars_info (w);
1180               ipa_reference_local_vars_info_t w_l = w_ri->local;
1181               fprintf (dump_file, "\n  next cycle: %s/%i ",
1182                        cgraph_node_name (w), w->uid);
1183               fprintf (dump_file, "\n    locals read: ");
1184               EXECUTE_IF_SET_IN_BITMAP (w_l->statics_read,
1185                                         0, index, bi)
1186                 {
1187                   fprintf (dump_file, "%s ",
1188                            get_static_name (index));
1189                 }
1190
1191               fprintf (dump_file, "\n    locals written: ");
1192               EXECUTE_IF_SET_IN_BITMAP (w_l->statics_written,
1193                                         0, index, bi)
1194                 {
1195                   fprintf(dump_file, "%s ",
1196                           get_static_name (index));
1197                 }
1198               
1199
1200               w_info = (struct ipa_dfs_info *) w->aux;
1201               w = w_info->next_cycle;
1202             }
1203           fprintf (dump_file, "\n  globals read: ");
1204           EXECUTE_IF_SET_IN_BITMAP (node_g->statics_read,
1205                                     0, index, bi)
1206             {
1207               fprintf (dump_file, "%s ",
1208                        get_static_name (index));
1209             }
1210           fprintf (dump_file, "\n  globals written: ");
1211           EXECUTE_IF_SET_IN_BITMAP (node_g->statics_written,
1212                                     0, index, bi)
1213             {
1214               fprintf (dump_file, "%s ",
1215                        get_static_name (index));
1216             }
1217         }
1218     }
1219
1220   /* Cleanup. */
1221   for (i = 0; i < order_pos; i++ )
1222     {
1223       ipa_reference_vars_info_t node_info;
1224       ipa_reference_global_vars_info_t node_g;
1225       node = order[i];
1226       node_info = get_reference_vars_info (node);
1227       node_g = node_info->global;
1228       
1229       /* Create the complimentary sets.  These are more useful for
1230          certain apis.  */
1231       node_g->statics_not_read = BITMAP_ALLOC (&global_info_obstack);
1232       node_g->statics_not_written = BITMAP_ALLOC (&global_info_obstack);
1233
1234       if (node_g->statics_read != all_module_statics) 
1235         bitmap_and_compl (node_g->statics_not_read, 
1236                           all_module_statics,
1237                           node_g->statics_read);
1238
1239       if (node_g->statics_written 
1240           != all_module_statics) 
1241         bitmap_and_compl (node_g->statics_not_written, 
1242                           all_module_statics,
1243                           node_g->statics_written);
1244    }
1245
1246   free (order);
1247
1248   for (node = cgraph_nodes; node; node = node->next)
1249     {
1250       ipa_reference_vars_info_t node_info;
1251       node_info = get_reference_vars_info (node);
1252       /* Get rid of the aux information.  */
1253       
1254       if (node->aux)
1255         {
1256           free (node->aux);
1257           node->aux = NULL;
1258         }
1259       
1260       if (cgraph_function_body_availability (node) == AVAIL_OVERWRITABLE)
1261         clean_function (node);
1262       else if (node_info)
1263         clean_function_local_data (node);
1264     }
1265   bitmap_obstack_release (&local_info_obstack);
1266   return 0;
1267 }
1268
1269
1270 static bool
1271 gate_reference (void)
1272 {
1273   return (flag_ipa_reference
1274           /* Don't bother doing anything if the program has errors.  */
1275           && !(errorcount || sorrycount));
1276 }
1277
1278 struct ipa_opt_pass pass_ipa_reference =
1279 {
1280  {
1281   IPA_PASS,
1282   "static-var",                         /* name */
1283   gate_reference,                       /* gate */
1284   propagate,                            /* execute */
1285   NULL,                                 /* sub */
1286   NULL,                                 /* next */
1287   0,                                    /* static_pass_number */
1288   TV_IPA_REFERENCE,                     /* tv_id */
1289   0,                                    /* properties_required */
1290   0,                                    /* properties_provided */
1291   0,                                    /* properties_destroyed */
1292   0,                                    /* todo_flags_start */
1293   0                                     /* todo_flags_finish */
1294  },
1295  generate_summary,                      /* generate_summary */
1296  NULL,                                  /* write_summary */
1297  NULL,                                  /* read_summary */
1298  NULL,                                  /* function_read_summary */
1299  0,                                     /* TODOs */
1300  NULL,                                  /* function_transform */
1301  NULL                                   /* variable_transform */
1302 };
1303
1304 #include "gt-ipa-reference.h"