1 /* Callgraph based analysis of static variables.
2 Copyright (C) 2004, 2005, 2007, 2008, 2009, 2010
3 Free Software Foundation, Inc.
4 Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
22 /* This file gathers information about how variables whose scope is
23 confined to the compilation unit are used.
25 The transitive call site specific clobber effects are computed
26 for the variables whose scope is contained within this compilation
29 First each function and static variable initialization is analyzed
30 to determine which local static variables are either read, written,
31 or have their address taken. Any local static that has its address
32 taken is removed from consideration. Once the local read and
33 writes are determined, a transitive closure of this information is
34 performed over the call graph to determine the worst case set of
35 side effects of each call. In later parts of the compiler, these
36 local and global sets are examined to make the call clobbering less
37 traumatic, promote some statics to registers, and improve aliasing
42 #include "coretypes.h"
45 #include "tree-flow.h"
46 #include "tree-inline.h"
47 #include "tree-pass.h"
48 #include "langhooks.h"
49 #include "pointer-set.h"
50 #include "splay-tree.h"
52 #include "ipa-utils.h"
53 #include "ipa-reference.h"
59 #include "diagnostic.h"
60 #include "langhooks.h"
61 #include "lto-streamer.h"
63 static void remove_node_data (struct cgraph_node
*node
,
64 void *data ATTRIBUTE_UNUSED
);
65 static void duplicate_node_data (struct cgraph_node
*src
,
66 struct cgraph_node
*dst
,
67 void *data ATTRIBUTE_UNUSED
);
69 /* The static variables defined within the compilation unit that are
70 loaded or stored directly by function that owns this structure. */
72 struct ipa_reference_local_vars_info_d
75 bitmap statics_written
;
77 /* Set when this function calls another function external to the
78 compilation unit or if the function has a asm clobber of memory.
79 In general, such calls are modeled as reading and writing all
80 variables (both bits on) but sometime there are attributes on the
81 called function so we can do better. */
86 /* Statics that are read and written by some set of functions. The
87 local ones are based on the loads and stores local to the function.
88 The global ones are based on the local info as well as the
89 transitive closure of the functions that are called. */
91 struct ipa_reference_global_vars_info_d
94 bitmap statics_written
;
97 /* Information we save about every function after ipa-reference is completted. */
99 struct ipa_reference_optimization_summary_d
101 bitmap statics_not_read
;
102 bitmap statics_not_written
;
105 typedef struct ipa_reference_local_vars_info_d
*ipa_reference_local_vars_info_t
;
106 typedef struct ipa_reference_global_vars_info_d
*ipa_reference_global_vars_info_t
;
107 typedef struct ipa_reference_optimization_summary_d
*ipa_reference_optimization_summary_t
;
109 struct ipa_reference_vars_info_d
111 struct ipa_reference_local_vars_info_d local
;
112 struct ipa_reference_global_vars_info_d global
;
115 typedef struct ipa_reference_vars_info_d
*ipa_reference_vars_info_t
;
117 /* This splay tree contains all of the static variables that are
118 being considered by the compilation level alias analysis. */
119 static splay_tree reference_vars_to_consider
;
121 /* A bit is set for every module static we are considering. This is
122 ored into the local info when asm code is found that clobbers all
124 static bitmap all_module_statics
;
126 /* Obstack holding bitmaps of local analysis (live from analysis to
128 static bitmap_obstack local_info_obstack
;
129 /* Obstack holding global analysis live forever. */
130 static bitmap_obstack optimization_summary_obstack
;
132 /* Holders of ipa cgraph hooks: */
133 static struct cgraph_2node_hook_list
*node_duplication_hook_holder
;
134 static struct cgraph_node_hook_list
*node_removal_hook_holder
;
136 /* Vector where the reference var infos are actually stored. */
137 DEF_VEC_P (ipa_reference_vars_info_t
);
138 DEF_VEC_ALLOC_P (ipa_reference_vars_info_t
, heap
);
139 static VEC (ipa_reference_vars_info_t
, heap
) *ipa_reference_vars_vector
;
140 DEF_VEC_P (ipa_reference_optimization_summary_t
);
141 DEF_VEC_ALLOC_P (ipa_reference_optimization_summary_t
, heap
);
142 static VEC (ipa_reference_optimization_summary_t
, heap
) *ipa_reference_opt_sum_vector
;
144 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
145 static inline ipa_reference_vars_info_t
146 get_reference_vars_info (struct cgraph_node
*node
)
148 if (!ipa_reference_vars_vector
149 || VEC_length (ipa_reference_vars_info_t
,
150 ipa_reference_vars_vector
) <= (unsigned int) node
->uid
)
152 return VEC_index (ipa_reference_vars_info_t
, ipa_reference_vars_vector
,
156 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
157 static inline ipa_reference_optimization_summary_t
158 get_reference_optimization_summary (struct cgraph_node
*node
)
160 if (!ipa_reference_opt_sum_vector
161 || (VEC_length (ipa_reference_optimization_summary_t
,
162 ipa_reference_opt_sum_vector
)
163 <= (unsigned int) node
->uid
))
165 return VEC_index (ipa_reference_optimization_summary_t
, ipa_reference_opt_sum_vector
,
169 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
171 set_reference_vars_info (struct cgraph_node
*node
,
172 ipa_reference_vars_info_t info
)
174 if (!ipa_reference_vars_vector
175 || VEC_length (ipa_reference_vars_info_t
,
176 ipa_reference_vars_vector
) <= (unsigned int) node
->uid
)
177 VEC_safe_grow_cleared (ipa_reference_vars_info_t
, heap
,
178 ipa_reference_vars_vector
, node
->uid
+ 1);
179 VEC_replace (ipa_reference_vars_info_t
, ipa_reference_vars_vector
,
183 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
185 set_reference_optimization_summary (struct cgraph_node
*node
,
186 ipa_reference_optimization_summary_t info
)
188 if (!ipa_reference_opt_sum_vector
189 || (VEC_length (ipa_reference_optimization_summary_t
,
190 ipa_reference_opt_sum_vector
)
191 <= (unsigned int) node
->uid
))
192 VEC_safe_grow_cleared (ipa_reference_optimization_summary_t
,
193 heap
, ipa_reference_opt_sum_vector
, node
->uid
+ 1);
194 VEC_replace (ipa_reference_optimization_summary_t
,
195 ipa_reference_opt_sum_vector
, node
->uid
, info
);
198 /* Return a bitmap indexed by_DECL_UID uid for the static variables
199 that are not read during the execution of the function FN. Returns
200 NULL if no data is available. */
203 ipa_reference_get_not_read_global (struct cgraph_node
*fn
)
205 ipa_reference_optimization_summary_t info
;
207 info
= get_reference_optimization_summary (fn
);
209 return info
->statics_not_read
;
214 /* Return a bitmap indexed by DECL_UID uid for the static variables
215 that are not written during the execution of the function FN. Note
216 that variables written may or may not be read during the function
217 call. Returns NULL if no data is available. */
220 ipa_reference_get_not_written_global (struct cgraph_node
*fn
)
222 ipa_reference_optimization_summary_t info
;
224 info
= get_reference_optimization_summary (fn
);
226 return info
->statics_not_written
;
233 /* Add VAR to all_module_statics and the two
234 reference_vars_to_consider* sets. */
237 add_static_var (tree var
)
239 int uid
= DECL_UID (var
);
240 gcc_assert (TREE_CODE (var
) == VAR_DECL
);
241 if (!bitmap_bit_p (all_module_statics
, uid
))
244 splay_tree_insert (reference_vars_to_consider
,
245 uid
, (splay_tree_value
)var
);
246 bitmap_set_bit (all_module_statics
, uid
);
250 /* Return true if the variable T is the right kind of static variable to
251 perform compilation unit scope escape analysis. */
254 is_proper_for_analysis (tree t
)
256 /* We handle only variables whose address is never taken. */
257 if (TREE_ADDRESSABLE (t
))
259 /* If the variable has the "used" attribute, treat it as if it had a
260 been touched by the devil. */
261 if (DECL_PRESERVE_P (t
))
264 /* Do not want to do anything with volatile except mark any
265 function that uses one to be not const or pure. */
266 if (TREE_THIS_VOLATILE (t
))
269 /* We cannot touch decls where the type needs constructing. */
270 if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (t
)))
273 /* This is a variable we care about. Check if we have seen it
274 before, and if not add it the set of variables we care about. */
275 if (!bitmap_bit_p (all_module_statics
, DECL_UID (t
)))
281 /* Lookup the tree node for the static variable that has UID and
282 convert the name to a string for debugging. */
285 get_static_name (int index
)
287 splay_tree_node stn
=
288 splay_tree_lookup (reference_vars_to_consider
, index
);
290 return lang_hooks
.decl_printable_name ((tree
)(stn
->value
), 2);
294 /* Or in all of the bits from every callee of X into X_GLOBAL, the caller's cycle,
295 bit vector. There are several cases to check to avoid the sparse
299 propagate_bits (ipa_reference_global_vars_info_t x_global
, struct cgraph_node
*x
)
301 struct cgraph_edge
*e
;
302 for (e
= x
->callees
; e
; e
= e
->next_callee
)
304 struct cgraph_node
*y
= e
->callee
;
306 /* Only look into nodes we can propagate something. */
307 if (cgraph_function_body_availability (e
->callee
) > AVAIL_OVERWRITABLE
)
309 if (get_reference_vars_info (y
))
311 ipa_reference_vars_info_t y_info
312 = get_reference_vars_info (y
);
313 ipa_reference_global_vars_info_t y_global
= &y_info
->global
;
315 /* Calls in current cycle do not have global computed yet. */
316 if (!y_global
->statics_read
)
319 if (x_global
->statics_read
320 != all_module_statics
)
322 if (y_global
->statics_read
323 == all_module_statics
)
325 BITMAP_FREE (x_global
->statics_read
);
326 x_global
->statics_read
327 = all_module_statics
;
329 /* Skip bitmaps that are pointer equal to node's bitmap
330 (no reason to spin within the cycle). */
331 else if (x_global
->statics_read
332 != y_global
->statics_read
)
333 bitmap_ior_into (x_global
->statics_read
,
334 y_global
->statics_read
);
337 if (x_global
->statics_written
338 != all_module_statics
)
340 if (y_global
->statics_written
341 == all_module_statics
)
343 BITMAP_FREE (x_global
->statics_written
);
344 x_global
->statics_written
345 = all_module_statics
;
347 /* Skip bitmaps that are pointer equal to node's bitmap
348 (no reason to spin within the cycle). */
349 else if (x_global
->statics_written
350 != y_global
->statics_written
)
351 bitmap_ior_into (x_global
->statics_written
,
352 y_global
->statics_written
);
361 /* The init routine for analyzing global static variable usage. See
362 comments at top for description. */
366 static bool init_p
= false;
374 reference_vars_to_consider
= splay_tree_new (splay_tree_compare_ints
, 0, 0);
376 bitmap_obstack_initialize (&local_info_obstack
);
377 bitmap_obstack_initialize (&optimization_summary_obstack
);
378 all_module_statics
= BITMAP_ALLOC (&local_info_obstack
);
380 node_removal_hook_holder
=
381 cgraph_add_node_removal_hook (&remove_node_data
, NULL
);
382 node_duplication_hook_holder
=
383 cgraph_add_node_duplication_hook (&duplicate_node_data
, NULL
);
387 /* Set up the persistent info for FN. */
389 static ipa_reference_local_vars_info_t
390 init_function_info (struct cgraph_node
*fn
)
392 ipa_reference_vars_info_t info
393 = XCNEW (struct ipa_reference_vars_info_d
);
395 /* Add the info to the tree's annotation. */
396 set_reference_vars_info (fn
, info
);
398 info
->local
.statics_read
= BITMAP_ALLOC (&local_info_obstack
);
399 info
->local
.statics_written
= BITMAP_ALLOC (&local_info_obstack
);
405 /* This is the main routine for finding the reference patterns for
406 global variables within a function FN. */
409 analyze_function (struct cgraph_node
*fn
)
411 ipa_reference_local_vars_info_t local
;
415 struct cgraph_edge
*ie
;
417 local
= init_function_info (fn
);
418 /* Process indirect calls. All direct calles are handled at propagation
420 for (ie
= fn
->indirect_calls
; ie
; ie
= ie
->next_callee
)
421 if (!(ie
->indirect_info
->ecf_flags
& ECF_CONST
))
423 local
->calls_read_all
= true;
424 if (!(ie
->indirect_info
->ecf_flags
& ECF_PURE
)
425 && ((ie
->indirect_info
->ecf_flags
& (ECF_NOTHROW
| ECF_NORETURN
))
426 != (ECF_NOTHROW
| ECF_NORETURN
)))
427 local
->calls_write_all
= true;
429 for (i
= 0; ipa_ref_list_reference_iterate (&fn
->ref_list
, i
, ref
); i
++)
431 if (ref
->refered_type
!= IPA_REF_VARPOOL
)
433 var
= ipa_ref_varpool_node (ref
)->decl
;
434 if (ipa_ref_varpool_node (ref
)->externally_visible
435 || !ipa_ref_varpool_node (ref
)->analyzed
436 || !is_proper_for_analysis (var
))
441 bitmap_set_bit (local
->statics_read
, DECL_UID (var
));
444 bitmap_set_bit (local
->statics_written
, DECL_UID (var
));
451 if ((flags_from_decl_or_type (fn
->decl
) & (ECF_NOTHROW
| ECF_NORETURN
))
452 == (ECF_NOTHROW
| ECF_NORETURN
))
454 local
->calls_write_all
= false;
455 bitmap_clear (local
->statics_written
);
458 /* Free bitmaps of direct references if we can not use them anyway. */
459 if (local
->calls_write_all
)
460 BITMAP_FREE (local
->statics_written
);
461 if (local
->calls_read_all
)
462 BITMAP_FREE (local
->statics_read
);
466 copy_global_bitmap (bitmap src
)
471 dst
= BITMAP_ALLOC (&optimization_summary_obstack
);
472 bitmap_copy (dst
, src
);
477 /* Called when new clone is inserted to callgraph late. */
480 duplicate_node_data (struct cgraph_node
*src
, struct cgraph_node
*dst
,
481 void *data ATTRIBUTE_UNUSED
)
483 ipa_reference_optimization_summary_t ginfo
;
484 ipa_reference_optimization_summary_t dst_ginfo
;
486 ginfo
= get_reference_optimization_summary (src
);
489 dst_ginfo
= XCNEW (struct ipa_reference_optimization_summary_d
);
490 set_reference_optimization_summary (dst
, dst_ginfo
);
491 dst_ginfo
->statics_not_read
= copy_global_bitmap (ginfo
->statics_not_read
);
492 dst_ginfo
->statics_not_written
= copy_global_bitmap (ginfo
->statics_not_written
);
495 /* Called when node is removed. */
498 remove_node_data (struct cgraph_node
*node
, void *data ATTRIBUTE_UNUSED
)
500 ipa_reference_optimization_summary_t ginfo
;
501 ginfo
= get_reference_optimization_summary (node
);
504 if (ginfo
->statics_not_read
505 && ginfo
->statics_not_read
!= all_module_statics
)
506 BITMAP_FREE (ginfo
->statics_not_read
);
508 if (ginfo
->statics_not_written
509 && ginfo
->statics_not_written
!= all_module_statics
)
510 BITMAP_FREE (ginfo
->statics_not_written
);
512 set_reference_optimization_summary (node
, NULL
);
516 /* Analyze each function in the cgraph to see which global or statics
517 are read or written. */
520 generate_summary (void)
522 struct cgraph_node
*node
;
528 bm_temp
= BITMAP_ALLOC (&local_info_obstack
);
530 /* Process all of the functions next. */
531 for (node
= cgraph_nodes
; node
; node
= node
->next
)
533 analyze_function (node
);
536 EXECUTE_IF_SET_IN_BITMAP (all_module_statics
, 0, index
, bi
)
538 fprintf (dump_file
, "\nPromotable global:%s",
539 get_static_name (index
));
542 BITMAP_FREE(bm_temp
);
545 for (node
= cgraph_nodes
; node
; node
= node
->next
)
546 if (cgraph_function_body_availability (node
) >= AVAIL_OVERWRITABLE
)
548 ipa_reference_local_vars_info_t l
;
552 l
= &get_reference_vars_info (node
)->local
;
554 "\nFunction name:%s/%i:",
555 cgraph_node_name (node
), node
->uid
);
556 fprintf (dump_file
, "\n locals read: ");
558 EXECUTE_IF_SET_IN_BITMAP (l
->statics_read
,
561 fprintf (dump_file
, "%s ",
562 get_static_name (index
));
564 fprintf (dump_file
, "\n locals written: ");
565 if (l
->statics_written
)
566 EXECUTE_IF_SET_IN_BITMAP (l
->statics_written
,
569 fprintf(dump_file
, "%s ",
570 get_static_name (index
));
572 if (l
->calls_read_all
)
573 fprintf (dump_file
, "\n calls read all: ");
574 if (l
->calls_write_all
)
575 fprintf (dump_file
, "\n calls read all: ");
579 /* Set READ_ALL/WRITE_ALL based on DECL flags. */
582 read_write_all_from_decl (tree decl
, bool * read_all
, bool * write_all
)
584 int flags
= flags_from_decl_or_type (decl
);
585 if (flags
& ECF_CONST
)
587 else if (flags
& ECF_PURE
)
591 /* TODO: To be able to produce sane results, we should also handle
592 common builtins, in particular throw. */
594 /* When function does not return, it is safe to ignore anythign it writes
595 to, because the effect will never happen. */
596 if ((flags
& (ECF_NOTHROW
| ECF_NORETURN
))
597 != (ECF_NOTHROW
| ECF_NORETURN
))
602 /* Produce the global information by preforming a transitive closure
603 on the local information that was produced by ipa_analyze_function */
608 struct cgraph_node
*node
;
609 struct cgraph_node
*w
;
610 struct cgraph_node
**order
=
611 XCNEWVEC (struct cgraph_node
*, cgraph_n_nodes
);
612 int order_pos
= ipa_utils_reduced_inorder (order
, false, true, NULL
);
616 dump_cgraph (dump_file
);
618 ipa_discover_readonly_nonaddressable_vars ();
621 /* Propagate the local information thru the call graph to produce
622 the global information. All the nodes within a cycle will have
623 the same info so we collapse cycles first. Then we can do the
624 propagation in one pass from the leaves to the roots. */
625 order_pos
= ipa_utils_reduced_inorder (order
, true, true, NULL
);
627 ipa_utils_print_order(dump_file
, "reduced", order
, order_pos
);
629 for (i
= 0; i
< order_pos
; i
++ )
631 ipa_reference_vars_info_t node_info
;
632 ipa_reference_global_vars_info_t node_g
;
633 ipa_reference_local_vars_info_t node_l
;
634 struct cgraph_edge
*e
;
638 struct ipa_dfs_info
* w_info
;
641 node_info
= get_reference_vars_info (node
);
644 dump_cgraph_node (stderr
, node
);
645 dump_cgraph (stderr
);
649 node_l
= &node_info
->local
;
650 node_g
= &node_info
->global
;
652 read_all
= node_l
->calls_read_all
;
653 write_all
= node_l
->calls_write_all
;
655 /* When function is overwrittable, we can not assume anything. */
656 if (cgraph_function_body_availability (node
) <= AVAIL_OVERWRITABLE
)
657 read_write_all_from_decl (node
->decl
, &read_all
, &write_all
);
659 for (e
= node
->callees
; e
; e
= e
->next_callee
)
660 if (cgraph_function_body_availability (e
->callee
) <= AVAIL_OVERWRITABLE
)
661 read_write_all_from_decl (e
->callee
->decl
, &read_all
, &write_all
);
664 /* If any node in a cycle is calls_read_all or calls_write_all
666 w_info
= (struct ipa_dfs_info
*) node
->aux
;
667 w
= w_info
->next_cycle
;
670 ipa_reference_local_vars_info_t w_l
=
671 &get_reference_vars_info (w
)->local
;
673 /* When function is overwrittable, we can not assume anything. */
674 if (cgraph_function_body_availability (w
) <= AVAIL_OVERWRITABLE
)
675 read_write_all_from_decl (w
->decl
, &read_all
, &write_all
);
677 for (e
= w
->callees
; e
; e
= e
->next_callee
)
678 if (cgraph_function_body_availability (e
->callee
) <= AVAIL_OVERWRITABLE
)
679 read_write_all_from_decl (e
->callee
->decl
, &read_all
, &write_all
);
681 read_all
|= w_l
->calls_read_all
;
682 write_all
|= w_l
->calls_write_all
;
684 w_info
= (struct ipa_dfs_info
*) w
->aux
;
685 w
= w_info
->next_cycle
;
689 /* Initialized the bitmaps for the reduced nodes */
691 node_g
->statics_read
= all_module_statics
;
694 node_g
->statics_read
= BITMAP_ALLOC (&local_info_obstack
);
695 bitmap_copy (node_g
->statics_read
,
696 node_l
->statics_read
);
699 node_g
->statics_written
= all_module_statics
;
702 node_g
->statics_written
= BITMAP_ALLOC (&local_info_obstack
);
703 bitmap_copy (node_g
->statics_written
,
704 node_l
->statics_written
);
707 propagate_bits (node_g
, node
);
708 w_info
= (struct ipa_dfs_info
*) node
->aux
;
709 w
= w_info
->next_cycle
;
712 ipa_reference_vars_info_t w_ri
=
713 get_reference_vars_info (w
);
714 ipa_reference_local_vars_info_t w_l
= &w_ri
->local
;
716 /* These global bitmaps are initialized from the local info
717 of all of the nodes in the region. However there is no
718 need to do any work if the bitmaps were set to
719 all_module_statics. */
721 bitmap_ior_into (node_g
->statics_read
,
724 bitmap_ior_into (node_g
->statics_written
,
725 w_l
->statics_written
);
726 propagate_bits (node_g
, w
);
727 w_info
= (struct ipa_dfs_info
*) w
->aux
;
728 w
= w_info
->next_cycle
;
731 /* All nodes within a cycle have the same global info bitmaps. */
732 node_info
->global
= *node_g
;
733 w_info
= (struct ipa_dfs_info
*) node
->aux
;
734 w
= w_info
->next_cycle
;
737 ipa_reference_vars_info_t w_ri
=
738 get_reference_vars_info (w
);
740 w_ri
->global
= *node_g
;
742 w_info
= (struct ipa_dfs_info
*) w
->aux
;
743 w
= w_info
->next_cycle
;
749 for (i
= 0; i
< order_pos
; i
++ )
751 ipa_reference_vars_info_t node_info
;
752 ipa_reference_global_vars_info_t node_g
;
753 ipa_reference_local_vars_info_t node_l
;
756 struct ipa_dfs_info
* w_info
;
759 node_info
= get_reference_vars_info (node
);
760 node_g
= &node_info
->global
;
761 node_l
= &node_info
->local
;
763 "\nFunction name:%s/%i:",
764 cgraph_node_name (node
), node
->uid
);
765 fprintf (dump_file
, "\n locals read: ");
766 if (node_l
->statics_read
)
767 EXECUTE_IF_SET_IN_BITMAP (node_l
->statics_read
,
770 fprintf (dump_file
, "%s ",
771 get_static_name (index
));
773 fprintf (dump_file
, "\n locals written: ");
774 if (node_l
->statics_written
)
775 EXECUTE_IF_SET_IN_BITMAP (node_l
->statics_written
,
778 fprintf(dump_file
, "%s ",
779 get_static_name (index
));
782 w_info
= (struct ipa_dfs_info
*) node
->aux
;
783 w
= w_info
->next_cycle
;
786 ipa_reference_vars_info_t w_ri
=
787 get_reference_vars_info (w
);
788 ipa_reference_local_vars_info_t w_l
= &w_ri
->local
;
789 fprintf (dump_file
, "\n next cycle: %s/%i ",
790 cgraph_node_name (w
), w
->uid
);
791 fprintf (dump_file
, "\n locals read: ");
792 if (w_l
->statics_read
)
793 EXECUTE_IF_SET_IN_BITMAP (w_l
->statics_read
,
796 fprintf (dump_file
, "%s ",
797 get_static_name (index
));
800 fprintf (dump_file
, "\n locals written: ");
801 if (w_l
->statics_written
)
802 EXECUTE_IF_SET_IN_BITMAP (w_l
->statics_written
,
805 fprintf (dump_file
, "%s ",
806 get_static_name (index
));
809 w_info
= (struct ipa_dfs_info
*) w
->aux
;
810 w
= w_info
->next_cycle
;
812 fprintf (dump_file
, "\n globals read: ");
813 if (node_g
->statics_read
== all_module_statics
)
814 fprintf (dump_file
, "ALL");
816 EXECUTE_IF_SET_IN_BITMAP (node_g
->statics_read
,
819 fprintf (dump_file
, "%s ",
820 get_static_name (index
));
822 fprintf (dump_file
, "\n globals written: ");
823 if (node_g
->statics_written
== all_module_statics
)
824 fprintf (dump_file
, "ALL");
826 EXECUTE_IF_SET_IN_BITMAP (node_g
->statics_written
,
829 fprintf (dump_file
, "%s ",
830 get_static_name (index
));
836 for (i
= 0; i
< order_pos
; i
++ )
838 ipa_reference_vars_info_t node_info
;
839 ipa_reference_global_vars_info_t node_g
;
840 ipa_reference_optimization_summary_t opt
;
843 node_info
= get_reference_vars_info (node
);
844 if (cgraph_function_body_availability (node
) > AVAIL_OVERWRITABLE
)
846 node_g
= &node_info
->global
;
848 opt
= XCNEW (struct ipa_reference_optimization_summary_d
);
849 set_reference_optimization_summary (node
, opt
);
851 /* Create the complimentary sets. */
852 opt
->statics_not_read
= BITMAP_ALLOC (&optimization_summary_obstack
);
853 opt
->statics_not_written
= BITMAP_ALLOC (&optimization_summary_obstack
);
855 if (node_g
->statics_read
!= all_module_statics
)
856 bitmap_and_compl (opt
->statics_not_read
,
858 node_g
->statics_read
);
860 if (node_g
->statics_written
861 != all_module_statics
)
862 bitmap_and_compl (opt
->statics_not_written
,
864 node_g
->statics_written
);
877 bitmap_obstack_release (&local_info_obstack
);
878 VEC_free (ipa_reference_vars_info_t
, heap
, ipa_reference_vars_vector
);
879 ipa_reference_vars_vector
= NULL
;
881 splay_tree_delete (reference_vars_to_consider
);
882 reference_vars_to_consider
= NULL
;
883 all_module_statics
= NULL
;
889 gate_reference (void)
891 return (flag_ipa_reference
892 /* Don't bother doing anything if the program has errors. */
893 && !(errorcount
|| sorrycount
));
896 struct ipa_opt_pass_d pass_ipa_reference
=
900 "static-var", /* name */
901 gate_reference
, /* gate */
902 propagate
, /* execute */
905 0, /* static_pass_number */
906 TV_IPA_REFERENCE
, /* tv_id */
907 0, /* properties_required */
908 0, /* properties_provided */
909 0, /* properties_destroyed */
910 0, /* todo_flags_start */
911 0 /* todo_flags_finish */
913 NULL
, /* generate_summary */
914 NULL
, /* write_summary */
915 NULL
, /* read_summary */
916 NULL
, /* write_optimization_summary */
917 NULL
, /* read_optimization_summary */
918 NULL
, /* stmt_fixup */
920 NULL
, /* function_transform */
921 NULL
/* variable_transform */