OSDN Git Service

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