invoke.texi (-fvar-tracking-assignments): New.
[gcc.git] / gcc / ipa-reference.c
1 /* Callgraph based analysis of static variables.
2 Copyright (C) 2004, 2005, 2007, 2008, 2009 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 "splay-tree.h"
61 #include "ggc.h"
62 #include "ipa-utils.h"
63 #include "ipa-reference.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 /* Wrapper around mark_address_taken for the stmt walker. */
338
339 static bool
340 mark_address (gimple stmt ATTRIBUTE_UNUSED, tree addr,
341 void *data ATTRIBUTE_UNUSED)
342 {
343 while (handled_component_p (addr))
344 addr = TREE_OPERAND (addr, 0);
345 mark_address_taken (addr);
346 return false;
347 }
348
349 /* Mark load of T. */
350
351 static bool
352 mark_load (gimple stmt ATTRIBUTE_UNUSED, tree t, void *data)
353 {
354 ipa_reference_local_vars_info_t local = (ipa_reference_local_vars_info_t)data;
355 if (TREE_CODE (t) == VAR_DECL
356 && has_proper_scope_for_analysis (t))
357 bitmap_set_bit (local->statics_read, DECL_UID (t));
358 return false;
359 }
360
361 /* Mark store of T. */
362
363 static bool
364 mark_store (gimple stmt ATTRIBUTE_UNUSED, tree t, void *data)
365 {
366 ipa_reference_local_vars_info_t local = (ipa_reference_local_vars_info_t)data;
367 if (TREE_CODE (t) == VAR_DECL
368 && has_proper_scope_for_analysis (t))
369 {
370 if (local)
371 bitmap_set_bit (local->statics_written, DECL_UID (t));
372 /* Mark the write so we can tell which statics are
373 readonly. */
374 if (module_statics_written)
375 bitmap_set_bit (module_statics_written, DECL_UID (t));
376 }
377 return false;
378 }
379
380 /* Look for memory clobber and set read_all/write_all if present. */
381
382 static void
383 check_asm_memory_clobber (ipa_reference_local_vars_info_t local, gimple stmt)
384 {
385 size_t i;
386 tree op;
387
388 for (i = 0; i < gimple_asm_nclobbers (stmt); i++)
389 {
390 op = gimple_asm_clobber_op (stmt, i);
391 if (simple_cst_equal(TREE_VALUE (op), memory_identifier_string) == 1)
392 {
393 /* Abandon all hope, ye who enter here. */
394 local->calls_read_all = true;
395 local->calls_write_all = true;
396 }
397 }
398 }
399
400 /* Look for external calls and set read_all/write_all correspondingly. */
401
402 static void
403 check_call (ipa_reference_local_vars_info_t local, gimple stmt)
404 {
405 int flags = gimple_call_flags (stmt);
406 tree callee_t = gimple_call_fndecl (stmt);
407 enum availability avail = AVAIL_NOT_AVAILABLE;
408
409 if (callee_t)
410 {
411 struct cgraph_node* callee = cgraph_node(callee_t);
412 avail = cgraph_function_body_availability (callee);
413 }
414
415 if (avail <= AVAIL_OVERWRITABLE)
416 if (local)
417 {
418 if (flags & ECF_CONST)
419 ;
420 else if (flags & ECF_PURE)
421 local->calls_read_all = true;
422 else
423 {
424 local->calls_read_all = true;
425 local->calls_write_all = true;
426 }
427 }
428 /* TODO: To be able to produce sane results, we should also handle
429 common builtins, in particular throw.
430 Indirect calls hsould be only counted and as inliner is replacing them
431 by direct calls, we can conclude if any indirect calls are left in body */
432 }
433
434 /* TP is the part of the tree currently under the microscope.
435 WALK_SUBTREES is part of the walk_tree api but is unused here.
436 DATA is cgraph_node of the function being walked. */
437
438 static tree
439 scan_stmt_for_static_refs (gimple_stmt_iterator *gsip,
440 struct cgraph_node *fn)
441 {
442 gimple stmt = gsi_stmt (*gsip);
443 ipa_reference_local_vars_info_t local = NULL;
444
445 if (is_gimple_debug (stmt))
446 return NULL;
447
448 if (fn)
449 local = get_reference_vars_info (fn)->local;
450
451 /* Look for direct loads and stores. */
452 walk_stmt_load_store_addr_ops (stmt, local, mark_load, mark_store,
453 mark_address);
454
455 if (is_gimple_call (stmt))
456 check_call (local, stmt);
457 else if (gimple_code (stmt) == GIMPLE_ASM)
458 check_asm_memory_clobber (local, stmt);
459
460 return NULL;
461 }
462
463 /* Call-back to scan variable initializers for static references.
464 Called using walk_tree. */
465
466 static tree
467 scan_initializer_for_static_refs (tree *tp, int *walk_subtrees,
468 void *data ATTRIBUTE_UNUSED)
469 {
470 tree t = *tp;
471
472 if (TREE_CODE (t) == ADDR_EXPR)
473 {
474 mark_address_taken (get_base_var (t));
475 *walk_subtrees = 0;
476 }
477 /* Save some cycles by not walking types and declaration as we
478 won't find anything useful there anyway. */
479 else if (IS_TYPE_OR_DECL_P (*tp))
480 *walk_subtrees = 0;
481
482 return NULL;
483 }
484
485 /* Lookup the tree node for the static variable that has UID. */
486 static tree
487 get_static_decl (int index)
488 {
489 splay_tree_node stn =
490 splay_tree_lookup (reference_vars_to_consider, index);
491 if (stn)
492 return (tree)stn->value;
493 return NULL;
494 }
495
496 /* Lookup the tree node for the static variable that has UID and
497 convert the name to a string for debugging. */
498
499 static const char *
500 get_static_name (int index)
501 {
502 splay_tree_node stn =
503 splay_tree_lookup (reference_vars_to_consider, index);
504 if (stn)
505 return lang_hooks.decl_printable_name ((tree)(stn->value), 2);
506 return NULL;
507 }
508
509 /* Or in all of the bits from every callee of X into X_GLOBAL, the caller's cycle,
510 bit vector. There are several cases to check to avoid the sparse
511 bitmap oring. */
512
513 static void
514 propagate_bits (ipa_reference_global_vars_info_t x_global, struct cgraph_node *x)
515 {
516 struct cgraph_edge *e;
517 for (e = x->callees; e; e = e->next_callee)
518 {
519 struct cgraph_node *y = e->callee;
520
521 /* Only look at the master nodes and skip external nodes. */
522 if (cgraph_function_body_availability (e->callee) > AVAIL_OVERWRITABLE)
523 {
524 if (get_reference_vars_info (y))
525 {
526 ipa_reference_vars_info_t y_info
527 = get_reference_vars_info (y);
528 ipa_reference_global_vars_info_t y_global = y_info->global;
529
530 /* Calls in current cycle do not have global computed yet. */
531 if (!y_info->global)
532 continue;
533
534 if (x_global->statics_read
535 != all_module_statics)
536 {
537 if (y_global->statics_read
538 == all_module_statics)
539 {
540 BITMAP_FREE (x_global->statics_read);
541 x_global->statics_read
542 = all_module_statics;
543 }
544 /* Skip bitmaps that are pointer equal to node's bitmap
545 (no reason to spin within the cycle). */
546 else if (x_global->statics_read
547 != y_global->statics_read)
548 bitmap_ior_into (x_global->statics_read,
549 y_global->statics_read);
550 }
551
552 if (x_global->statics_written
553 != all_module_statics)
554 {
555 if (y_global->statics_written
556 == all_module_statics)
557 {
558 BITMAP_FREE (x_global->statics_written);
559 x_global->statics_written
560 = all_module_statics;
561 }
562 /* Skip bitmaps that are pointer equal to node's bitmap
563 (no reason to spin within the cycle). */
564 else if (x_global->statics_written
565 != y_global->statics_written)
566 bitmap_ior_into (x_global->statics_written,
567 y_global->statics_written);
568 }
569 }
570 else
571 gcc_unreachable ();
572 }
573 }
574 }
575
576 /* The init routine for analyzing global static variable usage. See
577 comments at top for description. */
578 static void
579 ipa_init (void)
580 {
581 memory_identifier_string = build_string(7, "memory");
582
583 reference_vars_to_consider =
584 splay_tree_new_ggc (splay_tree_compare_ints);
585
586 bitmap_obstack_initialize (&local_info_obstack);
587 bitmap_obstack_initialize (&global_info_obstack);
588 module_statics_escape = BITMAP_ALLOC (&local_info_obstack);
589 module_statics_written = BITMAP_ALLOC (&local_info_obstack);
590 all_module_statics = BITMAP_ALLOC (&global_info_obstack);
591
592 /* There are some shared nodes, in particular the initializers on
593 static declarations. We do not need to scan them more than once
594 since all we would be interested in are the addressof
595 operations. */
596 visited_nodes = pointer_set_create ();
597 }
598
599 /* Check out the rhs of a static or global initialization VNODE to see
600 if any of them contain addressof operations. Note that some of
601 these variables may not even be referenced in the code in this
602 compilation unit but their right hand sides may contain references
603 to variables defined within this unit. */
604
605 static void
606 analyze_variable (struct varpool_node *vnode)
607 {
608 struct walk_stmt_info wi;
609 tree global = vnode->decl;
610
611 memset (&wi, 0, sizeof (wi));
612 wi.pset = visited_nodes;
613 walk_tree (&DECL_INITIAL (global), scan_initializer_for_static_refs,
614 &wi, wi.pset);
615 }
616
617 /* Set up the persistent info for FN. */
618
619 static ipa_reference_local_vars_info_t
620 init_function_info (struct cgraph_node *fn)
621 {
622 ipa_reference_vars_info_t info
623 = XCNEW (struct ipa_reference_vars_info_d);
624 ipa_reference_local_vars_info_t l
625 = XCNEW (struct ipa_reference_local_vars_info_d);
626
627 /* Add the info to the tree's annotation. */
628 set_reference_vars_info (fn, info);
629
630 info->local = l;
631 l->statics_read = BITMAP_ALLOC (&local_info_obstack);
632 l->statics_written = BITMAP_ALLOC (&local_info_obstack);
633
634 return l;
635 }
636
637 /* This is the main routine for finding the reference patterns for
638 global variables within a function FN. */
639
640 static void
641 analyze_function (struct cgraph_node *fn)
642 {
643 tree decl = fn->decl;
644 struct function *this_cfun = DECL_STRUCT_FUNCTION (decl);
645 basic_block this_block;
646 #ifdef ENABLE_CHECKING
647 tree step;
648 #endif
649
650 if (dump_file)
651 fprintf (dump_file, "\n local analysis of %s\n", cgraph_node_name (fn));
652
653 push_cfun (DECL_STRUCT_FUNCTION (decl));
654 current_function_decl = decl;
655
656 init_function_info (fn);
657 FOR_EACH_BB_FN (this_block, this_cfun)
658 {
659 gimple_stmt_iterator gsi;
660 gimple phi;
661 tree op;
662 use_operand_p use;
663 ssa_op_iter iter;
664
665 /* Find the addresses taken in phi node arguments. */
666 for (gsi = gsi_start_phis (this_block);
667 !gsi_end_p (gsi);
668 gsi_next (&gsi))
669 {
670 phi = gsi_stmt (gsi);
671 FOR_EACH_PHI_ARG (use, phi, iter, SSA_OP_USE)
672 {
673 op = USE_FROM_PTR (use);
674 if (TREE_CODE (op) == ADDR_EXPR)
675 mark_address_taken (get_base_var (op));
676 }
677 }
678
679 for (gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi))
680 scan_stmt_for_static_refs (&gsi, fn);
681 }
682
683 #ifdef ENABLE_CHECKING
684 /* Verify that all local initializers was expanded by gimplifier. */
685 for (step = DECL_STRUCT_FUNCTION (decl)->local_decls;
686 step;
687 step = TREE_CHAIN (step))
688 {
689 tree var = TREE_VALUE (step);
690 if (TREE_CODE (var) == VAR_DECL
691 && DECL_INITIAL (var)
692 && !TREE_STATIC (var))
693 gcc_unreachable ();
694 }
695 #endif
696 pop_cfun ();
697 current_function_decl = NULL;
698 }
699
700 /* Remove local data associated with function FN. */
701 static void
702 clean_function_local_data (struct cgraph_node *fn)
703 {
704 ipa_reference_vars_info_t info = get_reference_vars_info (fn);
705 ipa_reference_local_vars_info_t l = info->local;
706 if (l)
707 {
708 if (l->statics_read
709 && l->statics_read != all_module_statics)
710 BITMAP_FREE (l->statics_read);
711 if (l->statics_written
712 &&l->statics_written != all_module_statics)
713 BITMAP_FREE (l->statics_written);
714 free (l);
715 info->local = NULL;
716 }
717 }
718
719 /* Remove all data associated with function FN. */
720
721 static void
722 clean_function (struct cgraph_node *fn)
723 {
724 ipa_reference_vars_info_t info = get_reference_vars_info (fn);
725 ipa_reference_global_vars_info_t g = info->global;
726
727 clean_function_local_data (fn);
728 if (g)
729 {
730 if (g->statics_read
731 && g->statics_read != all_module_statics)
732 BITMAP_FREE (g->statics_read);
733
734 if (g->statics_written
735 && g->statics_written != all_module_statics)
736 BITMAP_FREE (g->statics_written);
737
738 if (g->statics_not_read
739 && g->statics_not_read != all_module_statics)
740 BITMAP_FREE (g->statics_not_read);
741
742 if (g->statics_not_written
743 && g->statics_not_written != all_module_statics)
744 BITMAP_FREE (g->statics_not_written);
745 free (g);
746 info->global = NULL;
747 }
748
749 free (get_reference_vars_info (fn));
750 set_reference_vars_info (fn, NULL);
751 }
752
753 /* Called when new function is inserted to callgraph late. */
754 static void
755 add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
756 {
757 /* There are some shared nodes, in particular the initializers on
758 static declarations. We do not need to scan them more than once
759 since all we would be interested in are the addressof
760 operations. */
761 analyze_function (node);
762 visited_nodes = NULL;
763 }
764
765 static bitmap
766 copy_local_bitmap (bitmap src)
767 {
768 bitmap dst;
769 if (!src)
770 return NULL;
771 if (src == all_module_statics)
772 return all_module_statics;
773 dst = BITMAP_ALLOC (&local_info_obstack);
774 bitmap_copy (dst, src);
775 return dst;
776 }
777
778 static bitmap
779 copy_global_bitmap (bitmap src)
780 {
781 bitmap dst;
782 if (!src)
783 return NULL;
784 if (src == all_module_statics)
785 return all_module_statics;
786 dst = BITMAP_ALLOC (&global_info_obstack);
787 bitmap_copy (dst, src);
788 return dst;
789 }
790
791 /* Called when new clone is inserted to callgraph late. */
792
793 static void
794 duplicate_node_data (struct cgraph_node *src, struct cgraph_node *dst,
795 void *data ATTRIBUTE_UNUSED)
796 {
797 ipa_reference_global_vars_info_t ginfo;
798 ipa_reference_local_vars_info_t linfo;
799 ipa_reference_global_vars_info_t dst_ginfo;
800 ipa_reference_local_vars_info_t dst_linfo;
801
802 ginfo = get_global_reference_vars_info (src);
803 linfo = get_local_reference_vars_info (src);
804 if (!linfo && !ginfo)
805 return;
806 init_function_info (dst);
807 if (linfo)
808 {
809 dst_linfo = get_local_reference_vars_info (dst);
810 dst_linfo->statics_read = copy_local_bitmap (linfo->statics_read);
811 dst_linfo->statics_written = copy_local_bitmap (linfo->statics_written);
812 dst_linfo->calls_read_all = linfo->calls_read_all;
813 dst_linfo->calls_write_all = linfo->calls_write_all;
814 }
815 if (ginfo)
816 {
817 get_reference_vars_info (dst)->global = XCNEW (struct ipa_reference_global_vars_info_d);
818 dst_ginfo = get_global_reference_vars_info (dst);
819 dst_ginfo->statics_read = copy_global_bitmap (ginfo->statics_read);
820 dst_ginfo->statics_written = copy_global_bitmap (ginfo->statics_written);
821 dst_ginfo->statics_not_read = copy_global_bitmap (ginfo->statics_not_read);
822 dst_ginfo->statics_not_written = copy_global_bitmap (ginfo->statics_not_written);
823 }
824 }
825
826 /* Called when node is removed. */
827
828 static void
829 remove_node_data (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
830 {
831 if (get_reference_vars_info (node))
832 clean_function (node);
833 }
834
835 /* Analyze each function in the cgraph to see which global or statics
836 are read or written. */
837
838 static void
839 generate_summary (void)
840 {
841 struct cgraph_node *node;
842 struct varpool_node *vnode;
843 unsigned int index;
844 bitmap_iterator bi;
845 bitmap module_statics_readonly;
846 bitmap bm_temp;
847
848 function_insertion_hook_holder =
849 cgraph_add_function_insertion_hook (&add_new_function, NULL);
850 node_removal_hook_holder =
851 cgraph_add_node_removal_hook (&remove_node_data, NULL);
852 node_duplication_hook_holder =
853 cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
854 ipa_init ();
855 module_statics_readonly = BITMAP_ALLOC (&local_info_obstack);
856 bm_temp = BITMAP_ALLOC (&local_info_obstack);
857
858 /* Process all of the variables first. */
859 FOR_EACH_STATIC_INITIALIZER (vnode)
860 analyze_variable (vnode);
861
862 /* Process all of the functions next.
863
864 We do not want to process any of the clones so we check that this
865 is a master clone. However, we do need to process any
866 AVAIL_OVERWRITABLE functions (these are never clones) because
867 they may cause a static variable to escape. The code that can
868 overwrite such a function cannot access the statics because it
869 would not be in the same compilation unit. When the analysis is
870 finished, the computed information of these AVAIL_OVERWRITABLE is
871 replaced with worst case info.
872 */
873 for (node = cgraph_nodes; node; node = node->next)
874 if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
875 analyze_function (node);
876
877 pointer_set_destroy (visited_nodes);
878 visited_nodes = NULL;
879
880 /* Prune out the variables that were found to behave badly
881 (i.e. have their address taken). */
882 EXECUTE_IF_SET_IN_BITMAP (module_statics_escape, 0, index, bi)
883 {
884 splay_tree_remove (reference_vars_to_consider, index);
885 }
886
887 bitmap_and_compl_into (all_module_statics,
888 module_statics_escape);
889
890 bitmap_and_compl (module_statics_readonly, all_module_statics,
891 module_statics_written);
892
893 /* If the address is not taken, we can unset the addressable bit
894 on this variable. */
895 EXECUTE_IF_SET_IN_BITMAP (all_module_statics, 0, index, bi)
896 {
897 tree var = get_static_decl (index);
898 TREE_ADDRESSABLE (var) = 0;
899 if (dump_file)
900 fprintf (dump_file, "Not TREE_ADDRESSABLE var %s\n",
901 get_static_name (index));
902 }
903
904 /* If the variable is never written, we can set the TREE_READONLY
905 flag. Additionally if it has a DECL_INITIAL that is made up of
906 constants we can treat the entire global as a constant. */
907
908 bitmap_and_compl (module_statics_readonly, all_module_statics,
909 module_statics_written);
910 EXECUTE_IF_SET_IN_BITMAP (module_statics_readonly, 0, index, bi)
911 {
912 tree var = get_static_decl (index);
913
914 /* Ignore variables in named sections - changing TREE_READONLY
915 changes the section flags, potentially causing conflicts with
916 other variables in the same named section. */
917 if (DECL_SECTION_NAME (var) == NULL_TREE)
918 {
919 TREE_READONLY (var) = 1;
920 if (dump_file)
921 fprintf (dump_file, "read-only var %s\n",
922 get_static_name (index));
923 }
924 }
925
926 BITMAP_FREE(module_statics_escape);
927 BITMAP_FREE(module_statics_written);
928 module_statics_escape = NULL;
929 module_statics_written = NULL;
930
931 if (dump_file)
932 EXECUTE_IF_SET_IN_BITMAP (all_module_statics, 0, index, bi)
933 {
934 fprintf (dump_file, "\nPromotable global:%s",
935 get_static_name (index));
936 }
937
938 for (node = cgraph_nodes; node; node = node->next)
939 if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
940 {
941 ipa_reference_local_vars_info_t l;
942 l = get_reference_vars_info (node)->local;
943
944 /* Any variables that are not in all_module_statics are
945 removed from the local maps. This will include all of the
946 variables that were found to escape in the function
947 scanning. */
948 bitmap_and_into (l->statics_read,
949 all_module_statics);
950 bitmap_and_into (l->statics_written,
951 all_module_statics);
952 }
953
954 BITMAP_FREE(module_statics_readonly);
955 BITMAP_FREE(bm_temp);
956
957 if (dump_file)
958 for (node = cgraph_nodes; node; node = node->next)
959 if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
960 {
961 ipa_reference_local_vars_info_t l;
962 unsigned int index;
963 bitmap_iterator bi;
964
965 l = get_reference_vars_info (node)->local;
966 fprintf (dump_file,
967 "\nFunction name:%s/%i:",
968 cgraph_node_name (node), node->uid);
969 fprintf (dump_file, "\n locals read: ");
970 EXECUTE_IF_SET_IN_BITMAP (l->statics_read,
971 0, index, bi)
972 {
973 fprintf (dump_file, "%s ",
974 get_static_name (index));
975 }
976 fprintf (dump_file, "\n locals written: ");
977 EXECUTE_IF_SET_IN_BITMAP (l->statics_written,
978 0, index, bi)
979 {
980 fprintf(dump_file, "%s ",
981 get_static_name (index));
982 }
983 if (l->calls_read_all)
984 fprintf (dump_file, "\n calls read all: ");
985 if (l->calls_write_all)
986 fprintf (dump_file, "\n calls read all: ");
987 }
988 }
989 \f
990 /* Produce the global information by preforming a transitive closure
991 on the local information that was produced by ipa_analyze_function
992 and ipa_analyze_variable. */
993
994 static unsigned int
995 propagate (void)
996 {
997 struct cgraph_node *node;
998 struct cgraph_node *w;
999 struct cgraph_node **order =
1000 XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
1001 int order_pos = ipa_utils_reduced_inorder (order, false, true, NULL);
1002 int i;
1003
1004 cgraph_remove_function_insertion_hook (function_insertion_hook_holder);
1005 if (dump_file)
1006 dump_cgraph (dump_file);
1007
1008 /* Propagate the local information thru the call graph to produce
1009 the global information. All the nodes within a cycle will have
1010 the same info so we collapse cycles first. Then we can do the
1011 propagation in one pass from the leaves to the roots. */
1012 order_pos = ipa_utils_reduced_inorder (order, true, true, NULL);
1013 if (dump_file)
1014 ipa_utils_print_order(dump_file, "reduced", order, order_pos);
1015
1016 for (i = 0; i < order_pos; i++ )
1017 {
1018 ipa_reference_vars_info_t node_info;
1019 ipa_reference_global_vars_info_t node_g =
1020 XCNEW (struct ipa_reference_global_vars_info_d);
1021 ipa_reference_local_vars_info_t node_l;
1022
1023 bool read_all;
1024 bool write_all;
1025 struct ipa_dfs_info * w_info;
1026
1027 node = order[i];
1028 node_info = get_reference_vars_info (node);
1029 if (!node_info)
1030 {
1031 dump_cgraph_node (stderr, node);
1032 dump_cgraph (stderr);
1033 gcc_unreachable ();
1034 }
1035
1036 gcc_assert (!node_info->global);
1037 node_l = node_info->local;
1038
1039 read_all = node_l->calls_read_all;
1040 write_all = node_l->calls_write_all;
1041
1042 /* If any node in a cycle is calls_read_all or calls_write_all
1043 they all are. */
1044 w_info = (struct ipa_dfs_info *) node->aux;
1045 w = w_info->next_cycle;
1046 while (w)
1047 {
1048 ipa_reference_local_vars_info_t w_l =
1049 get_reference_vars_info (w)->local;
1050 read_all |= w_l->calls_read_all;
1051 write_all |= w_l->calls_write_all;
1052
1053 w_info = (struct ipa_dfs_info *) w->aux;
1054 w = w_info->next_cycle;
1055 }
1056
1057 /* Initialized the bitmaps for the reduced nodes */
1058 if (read_all)
1059 node_g->statics_read = all_module_statics;
1060 else
1061 {
1062 node_g->statics_read = BITMAP_ALLOC (&global_info_obstack);
1063 bitmap_copy (node_g->statics_read,
1064 node_l->statics_read);
1065 }
1066
1067 if (write_all)
1068 node_g->statics_written = all_module_statics;
1069 else
1070 {
1071 node_g->statics_written = BITMAP_ALLOC (&global_info_obstack);
1072 bitmap_copy (node_g->statics_written,
1073 node_l->statics_written);
1074 }
1075
1076 propagate_bits (node_g, node);
1077 w_info = (struct ipa_dfs_info *) node->aux;
1078 w = w_info->next_cycle;
1079 while (w)
1080 {
1081 ipa_reference_vars_info_t w_ri =
1082 get_reference_vars_info (w);
1083 ipa_reference_local_vars_info_t w_l = w_ri->local;
1084
1085 /* These global bitmaps are initialized from the local info
1086 of all of the nodes in the region. However there is no
1087 need to do any work if the bitmaps were set to
1088 all_module_statics. */
1089 if (!read_all)
1090 bitmap_ior_into (node_g->statics_read,
1091 w_l->statics_read);
1092 if (!write_all)
1093 bitmap_ior_into (node_g->statics_written,
1094 w_l->statics_written);
1095 propagate_bits (node_g, w);
1096 w_info = (struct ipa_dfs_info *) w->aux;
1097 w = w_info->next_cycle;
1098 }
1099
1100 /* All nodes within a cycle have the same global info bitmaps. */
1101 node_info->global = node_g;
1102 w_info = (struct ipa_dfs_info *) node->aux;
1103 w = w_info->next_cycle;
1104 while (w)
1105 {
1106 ipa_reference_vars_info_t w_ri =
1107 get_reference_vars_info (w);
1108
1109 gcc_assert (!w_ri->global);
1110 w_ri->global = XCNEW (struct ipa_reference_global_vars_info_d);
1111 w_ri->global->statics_read = copy_global_bitmap (node_g->statics_read);
1112 w_ri->global->statics_written = copy_global_bitmap (node_g->statics_written);
1113
1114 w_info = (struct ipa_dfs_info *) w->aux;
1115 w = w_info->next_cycle;
1116 }
1117 }
1118
1119 if (dump_file)
1120 {
1121 for (i = 0; i < order_pos; i++ )
1122 {
1123 ipa_reference_vars_info_t node_info;
1124 ipa_reference_global_vars_info_t node_g;
1125 ipa_reference_local_vars_info_t node_l;
1126 unsigned int index;
1127 bitmap_iterator bi;
1128 struct ipa_dfs_info * w_info;
1129
1130 node = order[i];
1131 node_info = get_reference_vars_info (node);
1132 node_g = node_info->global;
1133 node_l = node_info->local;
1134 fprintf (dump_file,
1135 "\nFunction name:%s/%i:",
1136 cgraph_node_name (node), node->uid);
1137 fprintf (dump_file, "\n locals read: ");
1138 EXECUTE_IF_SET_IN_BITMAP (node_l->statics_read,
1139 0, index, bi)
1140 {
1141 fprintf (dump_file, "%s ",
1142 get_static_name (index));
1143 }
1144 fprintf (dump_file, "\n locals written: ");
1145 EXECUTE_IF_SET_IN_BITMAP (node_l->statics_written,
1146 0, index, bi)
1147 {
1148 fprintf(dump_file, "%s ",
1149 get_static_name (index));
1150 }
1151
1152 w_info = (struct ipa_dfs_info *) node->aux;
1153 w = w_info->next_cycle;
1154 while (w)
1155 {
1156 ipa_reference_vars_info_t w_ri =
1157 get_reference_vars_info (w);
1158 ipa_reference_local_vars_info_t w_l = w_ri->local;
1159 fprintf (dump_file, "\n next cycle: %s/%i ",
1160 cgraph_node_name (w), w->uid);
1161 fprintf (dump_file, "\n locals read: ");
1162 EXECUTE_IF_SET_IN_BITMAP (w_l->statics_read,
1163 0, index, bi)
1164 {
1165 fprintf (dump_file, "%s ",
1166 get_static_name (index));
1167 }
1168
1169 fprintf (dump_file, "\n locals written: ");
1170 EXECUTE_IF_SET_IN_BITMAP (w_l->statics_written,
1171 0, index, bi)
1172 {
1173 fprintf(dump_file, "%s ",
1174 get_static_name (index));
1175 }
1176
1177
1178 w_info = (struct ipa_dfs_info *) w->aux;
1179 w = w_info->next_cycle;
1180 }
1181 fprintf (dump_file, "\n globals read: ");
1182 EXECUTE_IF_SET_IN_BITMAP (node_g->statics_read,
1183 0, index, bi)
1184 {
1185 fprintf (dump_file, "%s ",
1186 get_static_name (index));
1187 }
1188 fprintf (dump_file, "\n globals written: ");
1189 EXECUTE_IF_SET_IN_BITMAP (node_g->statics_written,
1190 0, index, bi)
1191 {
1192 fprintf (dump_file, "%s ",
1193 get_static_name (index));
1194 }
1195 }
1196 }
1197
1198 /* Cleanup. */
1199 for (i = 0; i < order_pos; i++ )
1200 {
1201 ipa_reference_vars_info_t node_info;
1202 ipa_reference_global_vars_info_t node_g;
1203 node = order[i];
1204 node_info = get_reference_vars_info (node);
1205 node_g = node_info->global;
1206
1207 /* Create the complimentary sets. These are more useful for
1208 certain apis. */
1209 node_g->statics_not_read = BITMAP_ALLOC (&global_info_obstack);
1210 node_g->statics_not_written = BITMAP_ALLOC (&global_info_obstack);
1211
1212 if (node_g->statics_read != all_module_statics)
1213 bitmap_and_compl (node_g->statics_not_read,
1214 all_module_statics,
1215 node_g->statics_read);
1216
1217 if (node_g->statics_written
1218 != all_module_statics)
1219 bitmap_and_compl (node_g->statics_not_written,
1220 all_module_statics,
1221 node_g->statics_written);
1222 }
1223
1224 free (order);
1225
1226 for (node = cgraph_nodes; node; node = node->next)
1227 {
1228 ipa_reference_vars_info_t node_info;
1229 node_info = get_reference_vars_info (node);
1230 /* Get rid of the aux information. */
1231
1232 if (node->aux)
1233 {
1234 free (node->aux);
1235 node->aux = NULL;
1236 }
1237
1238 if (cgraph_function_body_availability (node) == AVAIL_OVERWRITABLE)
1239 clean_function (node);
1240 else if (node_info)
1241 clean_function_local_data (node);
1242 }
1243 bitmap_obstack_release (&local_info_obstack);
1244 return 0;
1245 }
1246
1247
1248 static bool
1249 gate_reference (void)
1250 {
1251 return (flag_ipa_reference
1252 /* Don't bother doing anything if the program has errors. */
1253 && !(errorcount || sorrycount));
1254 }
1255
1256 struct ipa_opt_pass_d pass_ipa_reference =
1257 {
1258 {
1259 IPA_PASS,
1260 "static-var", /* name */
1261 gate_reference, /* gate */
1262 propagate, /* execute */
1263 NULL, /* sub */
1264 NULL, /* next */
1265 0, /* static_pass_number */
1266 TV_IPA_REFERENCE, /* tv_id */
1267 0, /* properties_required */
1268 0, /* properties_provided */
1269 0, /* properties_destroyed */
1270 0, /* todo_flags_start */
1271 0 /* todo_flags_finish */
1272 },
1273 generate_summary, /* generate_summary */
1274 NULL, /* write_summary */
1275 NULL, /* read_summary */
1276 NULL, /* function_read_summary */
1277 0, /* TODOs */
1278 NULL, /* function_transform */
1279 NULL /* variable_transform */
1280 };
1281
1282 #include "gt-ipa-reference.h"