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"
57 #include "diagnostic.h"
58 #include "langhooks.h"
59 #include "data-streamer.h"
60 #include "lto-streamer.h"
62 static void remove_node_data (struct cgraph_node
*node
,
63 void *data ATTRIBUTE_UNUSED
);
64 static void duplicate_node_data (struct cgraph_node
*src
,
65 struct cgraph_node
*dst
,
66 void *data ATTRIBUTE_UNUSED
);
68 /* The static variables defined within the compilation unit that are
69 loaded or stored directly by function that owns this structure. */
71 struct ipa_reference_local_vars_info_d
74 bitmap statics_written
;
77 /* Statics that are read and written by some set of functions. The
78 local ones are based on the loads and stores local to the function.
79 The global ones are based on the local info as well as the
80 transitive closure of the functions that are called. */
82 struct ipa_reference_global_vars_info_d
85 bitmap statics_written
;
88 /* Information we save about every function after ipa-reference is completed. */
90 struct ipa_reference_optimization_summary_d
92 bitmap statics_not_read
;
93 bitmap statics_not_written
;
96 typedef struct ipa_reference_local_vars_info_d
*ipa_reference_local_vars_info_t
;
97 typedef struct ipa_reference_global_vars_info_d
*ipa_reference_global_vars_info_t
;
98 typedef struct ipa_reference_optimization_summary_d
*ipa_reference_optimization_summary_t
;
100 struct ipa_reference_vars_info_d
102 struct ipa_reference_local_vars_info_d local
;
103 struct ipa_reference_global_vars_info_d global
;
106 typedef struct ipa_reference_vars_info_d
*ipa_reference_vars_info_t
;
108 /* This splay tree contains all of the static variables that are
109 being considered by the compilation level alias analysis. */
110 static splay_tree reference_vars_to_consider
;
112 /* A bit is set for every module static we are considering. This is
113 ored into the local info when asm code is found that clobbers all
115 static bitmap all_module_statics
;
117 /* Obstack holding bitmaps of local analysis (live from analysis to
119 static bitmap_obstack local_info_obstack
;
120 /* Obstack holding global analysis live forever. */
121 static bitmap_obstack optimization_summary_obstack
;
123 /* Holders of ipa cgraph hooks: */
124 static struct cgraph_2node_hook_list
*node_duplication_hook_holder
;
125 static struct cgraph_node_hook_list
*node_removal_hook_holder
;
127 /* Vector where the reference var infos are actually stored. */
128 DEF_VEC_P (ipa_reference_vars_info_t
);
129 DEF_VEC_ALLOC_P (ipa_reference_vars_info_t
, heap
);
130 static VEC (ipa_reference_vars_info_t
, heap
) *ipa_reference_vars_vector
;
131 DEF_VEC_P (ipa_reference_optimization_summary_t
);
132 DEF_VEC_ALLOC_P (ipa_reference_optimization_summary_t
, heap
);
133 static VEC (ipa_reference_optimization_summary_t
, heap
) *ipa_reference_opt_sum_vector
;
135 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
136 static inline ipa_reference_vars_info_t
137 get_reference_vars_info (struct cgraph_node
*node
)
139 if (!ipa_reference_vars_vector
140 || VEC_length (ipa_reference_vars_info_t
,
141 ipa_reference_vars_vector
) <= (unsigned int) node
->uid
)
143 return VEC_index (ipa_reference_vars_info_t
, ipa_reference_vars_vector
,
147 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
148 static inline ipa_reference_optimization_summary_t
149 get_reference_optimization_summary (struct cgraph_node
*node
)
151 if (!ipa_reference_opt_sum_vector
152 || (VEC_length (ipa_reference_optimization_summary_t
,
153 ipa_reference_opt_sum_vector
)
154 <= (unsigned int) node
->uid
))
156 return VEC_index (ipa_reference_optimization_summary_t
, ipa_reference_opt_sum_vector
,
160 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
162 set_reference_vars_info (struct cgraph_node
*node
,
163 ipa_reference_vars_info_t info
)
165 if (!ipa_reference_vars_vector
166 || VEC_length (ipa_reference_vars_info_t
,
167 ipa_reference_vars_vector
) <= (unsigned int) node
->uid
)
168 VEC_safe_grow_cleared (ipa_reference_vars_info_t
, heap
,
169 ipa_reference_vars_vector
, node
->uid
+ 1);
170 VEC_replace (ipa_reference_vars_info_t
, ipa_reference_vars_vector
,
174 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
176 set_reference_optimization_summary (struct cgraph_node
*node
,
177 ipa_reference_optimization_summary_t info
)
179 if (!ipa_reference_opt_sum_vector
180 || (VEC_length (ipa_reference_optimization_summary_t
,
181 ipa_reference_opt_sum_vector
)
182 <= (unsigned int) node
->uid
))
183 VEC_safe_grow_cleared (ipa_reference_optimization_summary_t
,
184 heap
, ipa_reference_opt_sum_vector
, node
->uid
+ 1);
185 VEC_replace (ipa_reference_optimization_summary_t
,
186 ipa_reference_opt_sum_vector
, node
->uid
, info
);
189 /* Return a bitmap indexed by_DECL_UID uid for the static variables
190 that are not read during the execution of the function FN. Returns
191 NULL if no data is available. */
194 ipa_reference_get_not_read_global (struct cgraph_node
*fn
)
196 ipa_reference_optimization_summary_t info
;
198 info
= get_reference_optimization_summary (cgraph_function_node (fn
, NULL
));
200 return info
->statics_not_read
;
201 else if (flags_from_decl_or_type (fn
->symbol
.decl
) & ECF_LEAF
)
202 return all_module_statics
;
207 /* Return a bitmap indexed by DECL_UID uid for the static variables
208 that are not written during the execution of the function FN. Note
209 that variables written may or may not be read during the function
210 call. Returns NULL if no data is available. */
213 ipa_reference_get_not_written_global (struct cgraph_node
*fn
)
215 ipa_reference_optimization_summary_t info
;
217 info
= get_reference_optimization_summary (fn
);
219 return info
->statics_not_written
;
220 else if (flags_from_decl_or_type (fn
->symbol
.decl
) & ECF_LEAF
)
221 return all_module_statics
;
228 /* Add VAR to all_module_statics and the two
229 reference_vars_to_consider* sets. */
232 add_static_var (tree var
)
234 int uid
= DECL_UID (var
);
235 gcc_assert (TREE_CODE (var
) == VAR_DECL
);
237 splay_tree_insert (reference_vars_to_consider
,
238 uid
, (splay_tree_value
)var
);
239 bitmap_set_bit (all_module_statics
, uid
);
242 /* Return true if the variable T is the right kind of static variable to
243 perform compilation unit scope escape analysis. */
246 is_proper_for_analysis (tree t
)
248 /* If the variable has the "used" attribute, treat it as if it had a
249 been touched by the devil. */
250 if (DECL_PRESERVE_P (t
))
253 /* Do not want to do anything with volatile except mark any
254 function that uses one to be not const or pure. */
255 if (TREE_THIS_VOLATILE (t
))
258 /* We do not need to analyze readonly vars, we already know they do not
260 if (TREE_READONLY (t
))
263 /* This is a variable we care about. Check if we have seen it
264 before, and if not add it the set of variables we care about. */
265 if (all_module_statics
266 && !bitmap_bit_p (all_module_statics
, DECL_UID (t
)))
272 /* Lookup the tree node for the static variable that has UID and
273 convert the name to a string for debugging. */
276 get_static_name (int index
)
278 splay_tree_node stn
=
279 splay_tree_lookup (reference_vars_to_consider
, index
);
281 return lang_hooks
.decl_printable_name ((tree
)(stn
->value
), 2);
285 /* Or in all of the bits from every callee of X into X_GLOBAL, the caller's cycle,
286 bit vector. There are several cases to check to avoid the sparse
290 propagate_bits (ipa_reference_global_vars_info_t x_global
, struct cgraph_node
*x
)
292 struct cgraph_edge
*e
;
293 for (e
= x
->callees
; e
; e
= e
->next_callee
)
295 enum availability avail
;
296 struct cgraph_node
*y
= cgraph_function_node (e
->callee
, &avail
);
300 /* Only look into nodes we can propagate something. */
301 if (avail
> AVAIL_OVERWRITABLE
302 || (avail
== AVAIL_OVERWRITABLE
303 && (flags_from_decl_or_type (y
->symbol
.decl
) & ECF_LEAF
)))
305 int flags
= flags_from_decl_or_type (y
->symbol
.decl
);
306 if (get_reference_vars_info (y
))
308 ipa_reference_vars_info_t y_info
309 = get_reference_vars_info (y
);
310 ipa_reference_global_vars_info_t y_global
= &y_info
->global
;
312 /* Calls in current cycle do not have global computed yet. */
313 if (!y_global
->statics_read
)
316 /* If function is declared const, it reads no memory even if it
317 seems so to local analysis. */
318 if (flags
& ECF_CONST
)
321 if (x_global
->statics_read
322 != all_module_statics
)
324 if (y_global
->statics_read
325 == all_module_statics
)
327 BITMAP_FREE (x_global
->statics_read
);
328 x_global
->statics_read
329 = all_module_statics
;
331 /* Skip bitmaps that are pointer equal to node's bitmap
332 (no reason to spin within the cycle). */
333 else if (x_global
->statics_read
334 != y_global
->statics_read
)
335 bitmap_ior_into (x_global
->statics_read
,
336 y_global
->statics_read
);
339 /* If function is declared pure, it has no stores even if it
340 seems so to local analysis; If we can not return from here,
341 we can safely ignore the call. */
342 if ((flags
& ECF_PURE
)
343 || cgraph_edge_cannot_lead_to_return (e
))
346 if (x_global
->statics_written
347 != all_module_statics
)
349 if (y_global
->statics_written
350 == all_module_statics
)
352 BITMAP_FREE (x_global
->statics_written
);
353 x_global
->statics_written
354 = all_module_statics
;
356 /* Skip bitmaps that are pointer equal to node's bitmap
357 (no reason to spin within the cycle). */
358 else if (x_global
->statics_written
359 != y_global
->statics_written
)
360 bitmap_ior_into (x_global
->statics_written
,
361 y_global
->statics_written
);
370 /* The init routine for analyzing global static variable usage. See
371 comments at top for description. */
375 static bool init_p
= false;
383 reference_vars_to_consider
= splay_tree_new (splay_tree_compare_ints
, 0, 0);
385 bitmap_obstack_initialize (&local_info_obstack
);
386 bitmap_obstack_initialize (&optimization_summary_obstack
);
387 all_module_statics
= BITMAP_ALLOC (&optimization_summary_obstack
);
389 node_removal_hook_holder
=
390 cgraph_add_node_removal_hook (&remove_node_data
, NULL
);
391 node_duplication_hook_holder
=
392 cgraph_add_node_duplication_hook (&duplicate_node_data
, NULL
);
396 /* Set up the persistent info for FN. */
398 static ipa_reference_local_vars_info_t
399 init_function_info (struct cgraph_node
*fn
)
401 ipa_reference_vars_info_t info
402 = XCNEW (struct ipa_reference_vars_info_d
);
404 /* Add the info to the tree's annotation. */
405 set_reference_vars_info (fn
, info
);
407 info
->local
.statics_read
= BITMAP_ALLOC (&local_info_obstack
);
408 info
->local
.statics_written
= BITMAP_ALLOC (&local_info_obstack
);
414 /* This is the main routine for finding the reference patterns for
415 global variables within a function FN. */
418 analyze_function (struct cgraph_node
*fn
)
420 ipa_reference_local_vars_info_t local
;
425 local
= init_function_info (fn
);
426 for (i
= 0; ipa_ref_list_reference_iterate (&fn
->symbol
.ref_list
, i
, ref
); i
++)
428 if (!symtab_variable_p (ref
->referred
))
430 var
= ipa_ref_varpool_node (ref
)->symbol
.decl
;
431 if (!is_proper_for_analysis (var
))
436 bitmap_set_bit (local
->statics_read
, DECL_UID (var
));
439 if (ipa_ref_cannot_lead_to_return (ref
))
441 bitmap_set_bit (local
->statics_written
, DECL_UID (var
));
448 if (cgraph_node_cannot_return (fn
))
449 bitmap_clear (local
->statics_written
);
453 copy_global_bitmap (bitmap src
)
458 if (src
== all_module_statics
)
459 return all_module_statics
;
460 dst
= BITMAP_ALLOC (&optimization_summary_obstack
);
461 bitmap_copy (dst
, src
);
466 /* Called when new clone is inserted to callgraph late. */
469 duplicate_node_data (struct cgraph_node
*src
, struct cgraph_node
*dst
,
470 void *data ATTRIBUTE_UNUSED
)
472 ipa_reference_optimization_summary_t ginfo
;
473 ipa_reference_optimization_summary_t dst_ginfo
;
475 ginfo
= get_reference_optimization_summary (src
);
478 dst_ginfo
= XCNEW (struct ipa_reference_optimization_summary_d
);
479 set_reference_optimization_summary (dst
, dst_ginfo
);
480 dst_ginfo
->statics_not_read
= copy_global_bitmap (ginfo
->statics_not_read
);
481 dst_ginfo
->statics_not_written
= copy_global_bitmap (ginfo
->statics_not_written
);
484 /* Called when node is removed. */
487 remove_node_data (struct cgraph_node
*node
, void *data ATTRIBUTE_UNUSED
)
489 ipa_reference_optimization_summary_t ginfo
;
490 ginfo
= get_reference_optimization_summary (node
);
493 if (ginfo
->statics_not_read
494 && ginfo
->statics_not_read
!= all_module_statics
)
495 BITMAP_FREE (ginfo
->statics_not_read
);
497 if (ginfo
->statics_not_written
498 && ginfo
->statics_not_written
!= all_module_statics
)
499 BITMAP_FREE (ginfo
->statics_not_written
);
501 set_reference_optimization_summary (node
, NULL
);
505 /* Analyze each function in the cgraph to see which global or statics
506 are read or written. */
509 generate_summary (void)
511 struct cgraph_node
*node
;
517 bm_temp
= BITMAP_ALLOC (&local_info_obstack
);
519 /* Process all of the functions next. */
520 FOR_EACH_DEFINED_FUNCTION (node
)
521 analyze_function (node
);
524 EXECUTE_IF_SET_IN_BITMAP (all_module_statics
, 0, index
, bi
)
526 fprintf (dump_file
, "\nPromotable global:%s",
527 get_static_name (index
));
530 BITMAP_FREE(bm_temp
);
533 FOR_EACH_DEFINED_FUNCTION (node
)
534 if (cgraph_function_body_availability (node
) >= AVAIL_OVERWRITABLE
)
536 ipa_reference_local_vars_info_t l
;
540 l
= &get_reference_vars_info (node
)->local
;
542 "\nFunction name:%s/%i:",
543 cgraph_node_asm_name (node
), node
->symbol
.order
);
544 fprintf (dump_file
, "\n locals read: ");
546 EXECUTE_IF_SET_IN_BITMAP (l
->statics_read
,
549 fprintf (dump_file
, "%s ",
550 get_static_name (index
));
552 fprintf (dump_file
, "\n locals written: ");
553 if (l
->statics_written
)
554 EXECUTE_IF_SET_IN_BITMAP (l
->statics_written
,
557 fprintf(dump_file
, "%s ",
558 get_static_name (index
));
563 /* Set READ_ALL/WRITE_ALL based on decl flags of NODE. */
566 read_write_all_from_decl (struct cgraph_node
*node
, bool * read_all
,
569 tree decl
= node
->symbol
.decl
;
570 int flags
= flags_from_decl_or_type (decl
);
571 if ((flags
& ECF_LEAF
)
572 && cgraph_function_body_availability (node
) <= AVAIL_OVERWRITABLE
)
574 else if (flags
& ECF_CONST
)
576 else if ((flags
& ECF_PURE
)
577 || cgraph_node_cannot_return (node
))
580 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
581 fprintf (dump_file
, " %s/%i -> read all\n",
582 cgraph_node_asm_name (node
), node
->symbol
.order
);
586 /* TODO: To be able to produce sane results, we should also handle
587 common builtins, in particular throw. */
590 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
591 fprintf (dump_file
, " %s/%i -> read all, write all\n",
592 cgraph_node_asm_name (node
), node
->symbol
.order
);
596 /* Produce the global information by preforming a transitive closure
597 on the local information that was produced by ipa_analyze_function */
602 struct cgraph_node
*node
;
603 struct varpool_node
*vnode
;
604 struct cgraph_node
*w
;
605 struct cgraph_node
**order
=
606 XCNEWVEC (struct cgraph_node
*, cgraph_n_nodes
);
611 dump_cgraph (dump_file
);
613 ipa_discover_readonly_nonaddressable_vars ();
616 /* Now we know what vars are really statics; prune out those that aren't. */
617 FOR_EACH_VARIABLE (vnode
)
618 if (vnode
->symbol
.externally_visible
619 || TREE_ADDRESSABLE (vnode
->symbol
.decl
)
620 || TREE_READONLY (vnode
->symbol
.decl
)
621 || !is_proper_for_analysis (vnode
->symbol
.decl
)
623 bitmap_clear_bit (all_module_statics
, DECL_UID (vnode
->symbol
.decl
));
625 /* Forget info we collected "just for fun" on variables that turned out to be
627 FOR_EACH_DEFINED_FUNCTION (node
)
629 ipa_reference_local_vars_info_t node_l
;
631 node_l
= &get_reference_vars_info (node
)->local
;
632 if (node_l
->statics_read
!= all_module_statics
)
633 bitmap_and_into (node_l
->statics_read
, all_module_statics
);
634 if (node_l
->statics_written
!= all_module_statics
)
635 bitmap_and_into (node_l
->statics_written
, all_module_statics
);
638 /* Propagate the local information through the call graph to produce
639 the global information. All the nodes within a cycle will have
640 the same info so we collapse cycles first. Then we can do the
641 propagation in one pass from the leaves to the roots. */
642 order_pos
= ipa_reduced_postorder (order
, true, true, NULL
);
644 ipa_print_order (dump_file
, "reduced", order
, order_pos
);
646 for (i
= 0; i
< order_pos
; i
++ )
648 ipa_reference_vars_info_t node_info
;
649 ipa_reference_global_vars_info_t node_g
;
650 ipa_reference_local_vars_info_t node_l
;
651 struct cgraph_edge
*e
, *ie
;
655 struct ipa_dfs_info
* w_info
;
660 node_info
= get_reference_vars_info (node
);
661 gcc_assert (node_info
);
664 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
665 fprintf (dump_file
, "Starting cycle with %s/%i\n",
666 cgraph_node_asm_name (node
), node
->symbol
.order
);
668 node_l
= &node_info
->local
;
669 node_g
= &node_info
->global
;
674 /* When function is overwritable, we can not assume anything. */
675 if (cgraph_function_body_availability (node
) <= AVAIL_OVERWRITABLE
)
676 read_write_all_from_decl (node
, &read_all
, &write_all
);
678 for (e
= node
->callees
; e
; e
= e
->next_callee
)
680 enum availability avail
;
681 struct cgraph_node
*callee
= cgraph_function_node (e
->callee
, &avail
);
682 if (!callee
|| avail
<= AVAIL_OVERWRITABLE
)
683 read_write_all_from_decl (callee
, &read_all
, &write_all
);
686 for (ie
= node
->indirect_calls
; ie
; ie
= ie
->next_callee
)
687 if (!(ie
->indirect_info
->ecf_flags
& ECF_CONST
))
690 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
691 fprintf (dump_file
, " indirect call -> read all\n");
692 if (!cgraph_edge_cannot_lead_to_return (ie
)
693 && !(ie
->indirect_info
->ecf_flags
& ECF_PURE
))
695 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
696 fprintf (dump_file
, " indirect call -> write all\n");
702 /* If any node in a cycle is read_all or write_all
704 w_info
= (struct ipa_dfs_info
*) node
->symbol
.aux
;
705 w
= w_info
->next_cycle
;
706 while (w
&& (!read_all
|| !write_all
))
708 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
709 fprintf (dump_file
, " Visiting %s/%i\n",
710 cgraph_node_asm_name (w
), w
->symbol
.order
);
711 /* When function is overwritable, we can not assume anything. */
712 if (cgraph_function_body_availability (w
) <= AVAIL_OVERWRITABLE
)
713 read_write_all_from_decl (w
, &read_all
, &write_all
);
715 for (e
= w
->callees
; e
; e
= e
->next_callee
)
717 enum availability avail
;
718 struct cgraph_node
*callee
= cgraph_function_node (e
->callee
, &avail
);
720 if (avail
<= AVAIL_OVERWRITABLE
)
721 read_write_all_from_decl (callee
, &read_all
, &write_all
);
724 for (ie
= w
->indirect_calls
; ie
; ie
= ie
->next_callee
)
725 if (!(ie
->indirect_info
->ecf_flags
& ECF_CONST
))
728 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
729 fprintf (dump_file
, " indirect call -> read all\n");
730 if (!cgraph_edge_cannot_lead_to_return (ie
)
731 && !(ie
->indirect_info
->ecf_flags
& ECF_PURE
))
734 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
735 fprintf (dump_file
, " indirect call -> write all\n");
739 w_info
= (struct ipa_dfs_info
*) w
->symbol
.aux
;
740 w
= w_info
->next_cycle
;
744 /* Initialized the bitmaps for the reduced nodes */
746 node_g
->statics_read
= all_module_statics
;
749 node_g
->statics_read
= BITMAP_ALLOC (&local_info_obstack
);
750 bitmap_copy (node_g
->statics_read
,
751 node_l
->statics_read
);
754 node_g
->statics_written
= all_module_statics
;
757 node_g
->statics_written
= BITMAP_ALLOC (&local_info_obstack
);
758 bitmap_copy (node_g
->statics_written
,
759 node_l
->statics_written
);
762 propagate_bits (node_g
, node
);
763 w_info
= (struct ipa_dfs_info
*) node
->symbol
.aux
;
764 w
= w_info
->next_cycle
;
765 while (w
&& (!read_all
|| !write_all
))
767 ipa_reference_vars_info_t w_ri
=
768 get_reference_vars_info (w
);
769 ipa_reference_local_vars_info_t w_l
= &w_ri
->local
;
770 int flags
= flags_from_decl_or_type (w
->symbol
.decl
);
772 /* These global bitmaps are initialized from the local info
773 of all of the nodes in the region. However there is no
774 need to do any work if the bitmaps were set to
775 all_module_statics. */
776 if (!read_all
&& !(flags
& ECF_CONST
))
777 bitmap_ior_into (node_g
->statics_read
,
780 && !(flags
& ECF_PURE
)
781 && !cgraph_node_cannot_return (w
))
782 bitmap_ior_into (node_g
->statics_written
,
783 w_l
->statics_written
);
784 propagate_bits (node_g
, w
);
785 w_info
= (struct ipa_dfs_info
*) w
->symbol
.aux
;
786 w
= w_info
->next_cycle
;
789 /* All nodes within a cycle have the same global info bitmaps. */
790 node_info
->global
= *node_g
;
791 w_info
= (struct ipa_dfs_info
*) node
->symbol
.aux
;
792 w
= w_info
->next_cycle
;
795 ipa_reference_vars_info_t w_ri
=
796 get_reference_vars_info (w
);
798 w_ri
->global
= *node_g
;
800 w_info
= (struct ipa_dfs_info
*) w
->symbol
.aux
;
801 w
= w_info
->next_cycle
;
807 for (i
= 0; i
< order_pos
; i
++ )
809 ipa_reference_vars_info_t node_info
;
810 ipa_reference_global_vars_info_t node_g
;
811 ipa_reference_local_vars_info_t node_l
;
814 struct ipa_dfs_info
* w_info
;
819 node_info
= get_reference_vars_info (node
);
820 node_g
= &node_info
->global
;
821 node_l
= &node_info
->local
;
823 "\nFunction name:%s/%i:",
824 cgraph_node_asm_name (node
), node
->symbol
.order
);
825 fprintf (dump_file
, "\n locals read: ");
826 if (node_l
->statics_read
)
827 EXECUTE_IF_SET_IN_BITMAP (node_l
->statics_read
,
830 fprintf (dump_file
, "%s ",
831 get_static_name (index
));
833 fprintf (dump_file
, "\n locals written: ");
834 if (node_l
->statics_written
)
835 EXECUTE_IF_SET_IN_BITMAP (node_l
->statics_written
,
838 fprintf(dump_file
, "%s ",
839 get_static_name (index
));
842 w_info
= (struct ipa_dfs_info
*) node
->symbol
.aux
;
843 w
= w_info
->next_cycle
;
846 ipa_reference_vars_info_t w_ri
=
847 get_reference_vars_info (w
);
848 ipa_reference_local_vars_info_t w_l
= &w_ri
->local
;
849 fprintf (dump_file
, "\n next cycle: %s/%i ",
850 cgraph_node_asm_name (w
), w
->symbol
.order
);
851 fprintf (dump_file
, "\n locals read: ");
852 if (w_l
->statics_read
)
853 EXECUTE_IF_SET_IN_BITMAP (w_l
->statics_read
,
856 fprintf (dump_file
, "%s ",
857 get_static_name (index
));
860 fprintf (dump_file
, "\n locals written: ");
861 if (w_l
->statics_written
)
862 EXECUTE_IF_SET_IN_BITMAP (w_l
->statics_written
,
865 fprintf (dump_file
, "%s ",
866 get_static_name (index
));
869 w_info
= (struct ipa_dfs_info
*) w
->symbol
.aux
;
870 w
= w_info
->next_cycle
;
872 fprintf (dump_file
, "\n globals read: ");
873 if (node_g
->statics_read
== all_module_statics
)
874 fprintf (dump_file
, "ALL");
876 EXECUTE_IF_SET_IN_BITMAP (node_g
->statics_read
,
879 fprintf (dump_file
, "%s ",
880 get_static_name (index
));
882 fprintf (dump_file
, "\n globals written: ");
883 if (node_g
->statics_written
== all_module_statics
)
884 fprintf (dump_file
, "ALL");
886 EXECUTE_IF_SET_IN_BITMAP (node_g
->statics_written
,
889 fprintf (dump_file
, "%s ",
890 get_static_name (index
));
896 FOR_EACH_DEFINED_FUNCTION (node
)
898 ipa_reference_vars_info_t node_info
;
899 ipa_reference_global_vars_info_t node_g
;
900 ipa_reference_optimization_summary_t opt
;
905 node_info
= get_reference_vars_info (node
);
906 if (cgraph_function_body_availability (node
) > AVAIL_OVERWRITABLE
907 || (flags_from_decl_or_type (node
->symbol
.decl
) & ECF_LEAF
))
909 node_g
= &node_info
->global
;
911 opt
= XCNEW (struct ipa_reference_optimization_summary_d
);
912 set_reference_optimization_summary (node
, opt
);
914 /* Create the complimentary sets. */
916 if (bitmap_empty_p (node_g
->statics_read
))
917 opt
->statics_not_read
= all_module_statics
;
920 opt
->statics_not_read
921 = BITMAP_ALLOC (&optimization_summary_obstack
);
922 if (node_g
->statics_read
!= all_module_statics
)
923 bitmap_and_compl (opt
->statics_not_read
,
925 node_g
->statics_read
);
928 if (bitmap_empty_p (node_g
->statics_written
))
929 opt
->statics_not_written
= all_module_statics
;
932 opt
->statics_not_written
933 = BITMAP_ALLOC (&optimization_summary_obstack
);
934 if (node_g
->statics_written
!= all_module_statics
)
935 bitmap_and_compl (opt
->statics_not_written
,
937 node_g
->statics_written
);
943 ipa_free_postorder_info ();
946 bitmap_obstack_release (&local_info_obstack
);
947 VEC_free (ipa_reference_vars_info_t
, heap
, ipa_reference_vars_vector
);
948 ipa_reference_vars_vector
= NULL
;
950 splay_tree_delete (reference_vars_to_consider
);
951 reference_vars_to_consider
= NULL
;
955 /* Return true if we need to write summary of NODE. */
958 write_node_summary_p (struct cgraph_node
*node
,
959 lto_symtab_encoder_t encoder
,
960 bitmap ltrans_statics
)
962 ipa_reference_optimization_summary_t info
;
964 /* See if we have (non-empty) info. */
965 if (!node
->analyzed
|| node
->global
.inlined_to
)
967 info
= get_reference_optimization_summary (node
);
968 if (!info
|| (bitmap_empty_p (info
->statics_not_read
)
969 && bitmap_empty_p (info
->statics_not_written
)))
972 /* See if we want to encode it.
973 Encode also referenced functions since constant folding might turn it into
976 In future we might also want to include summaries of functions references
977 by initializers of constant variables references in current unit. */
978 if (!reachable_from_this_partition_p (node
, encoder
)
979 && !referenced_from_this_partition_p (&node
->symbol
.ref_list
, encoder
))
982 /* See if the info has non-empty intersections with vars we want to encode. */
983 if (!bitmap_intersect_p (info
->statics_not_read
, ltrans_statics
)
984 && !bitmap_intersect_p (info
->statics_not_written
, ltrans_statics
))
989 /* Stream out BITS<RANS_STATICS as list of decls to OB.
990 LTRANS_STATICS_BITCOUNT specify number of bits in LTRANS_STATICS
991 or -1. When it is positive, just output -1 when
992 BITS<RANS_STATICS == BITS<RANS_STATICS. */
995 stream_out_bitmap (struct lto_simple_output_block
*ob
,
996 bitmap bits
, bitmap ltrans_statics
,
997 int ltrans_statics_bitcount
)
1002 if (bits
== all_module_statics
)
1004 streamer_write_hwi_stream (ob
->main_stream
, -1);
1007 EXECUTE_IF_AND_IN_BITMAP (bits
, ltrans_statics
, 0, index
, bi
)
1009 if (count
== ltrans_statics_bitcount
)
1011 streamer_write_hwi_stream (ob
->main_stream
, -1);
1014 streamer_write_hwi_stream (ob
->main_stream
, count
);
1017 EXECUTE_IF_AND_IN_BITMAP (bits
, ltrans_statics
, 0, index
, bi
)
1019 tree decl
= (tree
)splay_tree_lookup (reference_vars_to_consider
, index
)->value
;
1020 lto_output_var_decl_index(ob
->decl_state
, ob
->main_stream
, decl
);
1024 /* Serialize the ipa info for lto. */
1027 ipa_reference_write_optimization_summary (void)
1029 struct cgraph_node
*node
;
1031 struct lto_simple_output_block
*ob
1032 = lto_create_simple_output_block (LTO_section_ipa_reference
);
1033 unsigned int count
= 0;
1034 int ltrans_statics_bitcount
= 0;
1035 lto_symtab_encoder_t encoder
= ob
->decl_state
->symtab_node_encoder
;
1036 bitmap ltrans_statics
= BITMAP_ALLOC (NULL
);
1039 reference_vars_to_consider
= splay_tree_new (splay_tree_compare_ints
, 0, 0);
1041 /* See what variables we are interested in. */
1042 for (i
= 0; i
< lto_symtab_encoder_size (encoder
); i
++)
1044 struct varpool_node
*vnode
;
1045 snode
= lto_symtab_encoder_deref (encoder
, i
);
1046 if (!symtab_variable_p (snode
))
1048 vnode
= varpool (snode
);
1049 if (bitmap_bit_p (all_module_statics
, DECL_UID (vnode
->symbol
.decl
))
1050 && referenced_from_this_partition_p (&vnode
->symbol
.ref_list
, encoder
))
1052 tree decl
= vnode
->symbol
.decl
;
1053 bitmap_set_bit (ltrans_statics
, DECL_UID (decl
));
1054 splay_tree_insert (reference_vars_to_consider
,
1055 DECL_UID (decl
), (splay_tree_value
)decl
);
1056 ltrans_statics_bitcount
++;
1061 if (ltrans_statics_bitcount
)
1062 for (i
= 0; i
< lto_symtab_encoder_size (encoder
); i
++)
1063 if (symtab_function_p (snode
= lto_symtab_encoder_deref (encoder
, i
))
1064 && write_node_summary_p (cgraph (snode
),
1065 encoder
, ltrans_statics
))
1068 streamer_write_uhwi_stream (ob
->main_stream
, count
);
1070 stream_out_bitmap (ob
, ltrans_statics
, ltrans_statics
,
1073 /* Process all of the functions. */
1074 if (ltrans_statics_bitcount
)
1075 for (i
= 0; i
< lto_symtab_encoder_size (encoder
); i
++)
1077 snode
= lto_symtab_encoder_deref (encoder
, i
);
1078 if (!symtab_function_p (snode
))
1080 node
= cgraph (snode
);
1081 if (write_node_summary_p (node
, encoder
, ltrans_statics
))
1083 ipa_reference_optimization_summary_t info
;
1086 info
= get_reference_optimization_summary (node
);
1087 node_ref
= lto_symtab_encoder_encode (encoder
, (symtab_node
) node
);
1088 streamer_write_uhwi_stream (ob
->main_stream
, node_ref
);
1090 stream_out_bitmap (ob
, info
->statics_not_read
, ltrans_statics
,
1091 ltrans_statics_bitcount
);
1092 stream_out_bitmap (ob
, info
->statics_not_written
, ltrans_statics
,
1093 ltrans_statics_bitcount
);
1096 BITMAP_FREE (ltrans_statics
);
1097 lto_destroy_simple_output_block (ob
);
1098 splay_tree_delete (reference_vars_to_consider
);
1101 /* Deserialize the ipa info for lto. */
1104 ipa_reference_read_optimization_summary (void)
1106 struct lto_file_decl_data
** file_data_vec
1107 = lto_get_file_decl_data ();
1108 struct lto_file_decl_data
* file_data
;
1110 bitmap_obstack_initialize (&optimization_summary_obstack
);
1112 node_removal_hook_holder
=
1113 cgraph_add_node_removal_hook (&remove_node_data
, NULL
);
1114 node_duplication_hook_holder
=
1115 cgraph_add_node_duplication_hook (&duplicate_node_data
, NULL
);
1116 all_module_statics
= BITMAP_ALLOC (&optimization_summary_obstack
);
1118 while ((file_data
= file_data_vec
[j
++]))
1122 struct lto_input_block
*ib
1123 = lto_create_simple_input_block (file_data
,
1124 LTO_section_ipa_reference
,
1129 unsigned int f_count
= streamer_read_uhwi (ib
);
1133 b_count
= streamer_read_hwi (ib
);
1135 fprintf (dump_file
, "all module statics:");
1136 for (i
= 0; i
< (unsigned int)b_count
; i
++)
1138 unsigned int var_index
= streamer_read_uhwi (ib
);
1139 tree v_decl
= lto_file_decl_data_get_var_decl (file_data
,
1141 bitmap_set_bit (all_module_statics
, DECL_UID (v_decl
));
1143 fprintf (dump_file
, " %s",
1144 lang_hooks
.decl_printable_name (v_decl
, 2));
1147 for (i
= 0; i
< f_count
; i
++)
1149 unsigned int j
, index
;
1150 struct cgraph_node
*node
;
1151 ipa_reference_optimization_summary_t info
;
1153 lto_symtab_encoder_t encoder
;
1155 index
= streamer_read_uhwi (ib
);
1156 encoder
= file_data
->symtab_node_encoder
;
1157 node
= cgraph (lto_symtab_encoder_deref (encoder
, index
));
1158 info
= XCNEW (struct ipa_reference_optimization_summary_d
);
1159 set_reference_optimization_summary (node
, info
);
1160 info
->statics_not_read
= BITMAP_ALLOC (&optimization_summary_obstack
);
1161 info
->statics_not_written
= BITMAP_ALLOC (&optimization_summary_obstack
);
1164 "\nFunction name:%s/%i:\n static not read:",
1165 cgraph_node_asm_name (node
), node
->symbol
.order
);
1167 /* Set the statics not read. */
1168 v_count
= streamer_read_hwi (ib
);
1171 info
->statics_not_read
= all_module_statics
;
1173 fprintf (dump_file
, " all module statics");
1176 for (j
= 0; j
< (unsigned int)v_count
; j
++)
1178 unsigned int var_index
= streamer_read_uhwi (ib
);
1179 tree v_decl
= lto_file_decl_data_get_var_decl (file_data
,
1181 bitmap_set_bit (info
->statics_not_read
, DECL_UID (v_decl
));
1183 fprintf (dump_file
, " %s",
1184 lang_hooks
.decl_printable_name (v_decl
, 2));
1189 "\n static not written:");
1190 /* Set the statics not written. */
1191 v_count
= streamer_read_hwi (ib
);
1194 info
->statics_not_written
= all_module_statics
;
1196 fprintf (dump_file
, " all module statics");
1199 for (j
= 0; j
< (unsigned int)v_count
; j
++)
1201 unsigned int var_index
= streamer_read_uhwi (ib
);
1202 tree v_decl
= lto_file_decl_data_get_var_decl (file_data
,
1204 bitmap_set_bit (info
->statics_not_written
, DECL_UID (v_decl
));
1206 fprintf (dump_file
, " %s",
1207 lang_hooks
.decl_printable_name (v_decl
, 2));
1210 fprintf (dump_file
, "\n");
1213 lto_destroy_simple_input_block (file_data
,
1214 LTO_section_ipa_reference
,
1218 /* Fatal error here. We do not want to support compiling ltrans units with
1219 different version of compiler or different flags than the WPA unit, so
1220 this should never happen. */
1221 fatal_error ("ipa reference summary is missing in ltrans unit");
1226 gate_reference (void)
1228 return (flag_ipa_reference
1229 /* Don't bother doing anything if the program has errors. */
1233 struct ipa_opt_pass_d pass_ipa_reference
=
1237 "static-var", /* name */
1238 gate_reference
, /* gate */
1239 propagate
, /* execute */
1242 0, /* static_pass_number */
1243 TV_IPA_REFERENCE
, /* tv_id */
1244 0, /* properties_required */
1245 0, /* properties_provided */
1246 0, /* properties_destroyed */
1247 0, /* todo_flags_start */
1248 0 /* todo_flags_finish */
1250 NULL
, /* generate_summary */
1251 NULL
, /* write_summary */
1252 NULL
, /* read_summary */
1253 ipa_reference_write_optimization_summary
,/* write_optimization_summary */
1254 ipa_reference_read_optimization_summary
,/* read_optimization_summary */
1255 NULL
, /* stmt_fixup */
1257 NULL
, /* function_transform */
1258 NULL
/* variable_transform */