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"
64 static void remove_node_data (struct cgraph_node
*node
,
65 void *data ATTRIBUTE_UNUSED
);
66 static void duplicate_node_data (struct cgraph_node
*src
,
67 struct cgraph_node
*dst
,
68 void *data ATTRIBUTE_UNUSED
);
70 /* The static variables defined within the compilation unit that are
71 loaded or stored directly by function that owns this structure. */
73 struct ipa_reference_local_vars_info_d
76 bitmap statics_written
;
79 /* Statics that are read and written by some set of functions. The
80 local ones are based on the loads and stores local to the function.
81 The global ones are based on the local info as well as the
82 transitive closure of the functions that are called. */
84 struct ipa_reference_global_vars_info_d
87 bitmap statics_written
;
90 /* Information we save about every function after ipa-reference is completted. */
92 struct ipa_reference_optimization_summary_d
94 bitmap statics_not_read
;
95 bitmap statics_not_written
;
98 typedef struct ipa_reference_local_vars_info_d
*ipa_reference_local_vars_info_t
;
99 typedef struct ipa_reference_global_vars_info_d
*ipa_reference_global_vars_info_t
;
100 typedef struct ipa_reference_optimization_summary_d
*ipa_reference_optimization_summary_t
;
102 struct ipa_reference_vars_info_d
104 struct ipa_reference_local_vars_info_d local
;
105 struct ipa_reference_global_vars_info_d global
;
108 typedef struct ipa_reference_vars_info_d
*ipa_reference_vars_info_t
;
110 /* This splay tree contains all of the static variables that are
111 being considered by the compilation level alias analysis. */
112 static splay_tree reference_vars_to_consider
;
114 /* A bit is set for every module static we are considering. This is
115 ored into the local info when asm code is found that clobbers all
117 static bitmap all_module_statics
;
119 /* Obstack holding bitmaps of local analysis (live from analysis to
121 static bitmap_obstack local_info_obstack
;
122 /* Obstack holding global analysis live forever. */
123 static bitmap_obstack optimization_summary_obstack
;
125 /* Holders of ipa cgraph hooks: */
126 static struct cgraph_2node_hook_list
*node_duplication_hook_holder
;
127 static struct cgraph_node_hook_list
*node_removal_hook_holder
;
129 /* Vector where the reference var infos are actually stored. */
130 DEF_VEC_P (ipa_reference_vars_info_t
);
131 DEF_VEC_ALLOC_P (ipa_reference_vars_info_t
, heap
);
132 static VEC (ipa_reference_vars_info_t
, heap
) *ipa_reference_vars_vector
;
133 DEF_VEC_P (ipa_reference_optimization_summary_t
);
134 DEF_VEC_ALLOC_P (ipa_reference_optimization_summary_t
, heap
);
135 static VEC (ipa_reference_optimization_summary_t
, heap
) *ipa_reference_opt_sum_vector
;
137 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
138 static inline ipa_reference_vars_info_t
139 get_reference_vars_info (struct cgraph_node
*node
)
141 if (!ipa_reference_vars_vector
142 || VEC_length (ipa_reference_vars_info_t
,
143 ipa_reference_vars_vector
) <= (unsigned int) node
->uid
)
145 return VEC_index (ipa_reference_vars_info_t
, ipa_reference_vars_vector
,
149 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
150 static inline ipa_reference_optimization_summary_t
151 get_reference_optimization_summary (struct cgraph_node
*node
)
153 if (!ipa_reference_opt_sum_vector
154 || (VEC_length (ipa_reference_optimization_summary_t
,
155 ipa_reference_opt_sum_vector
)
156 <= (unsigned int) node
->uid
))
158 return VEC_index (ipa_reference_optimization_summary_t
, ipa_reference_opt_sum_vector
,
162 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
164 set_reference_vars_info (struct cgraph_node
*node
,
165 ipa_reference_vars_info_t info
)
167 if (!ipa_reference_vars_vector
168 || VEC_length (ipa_reference_vars_info_t
,
169 ipa_reference_vars_vector
) <= (unsigned int) node
->uid
)
170 VEC_safe_grow_cleared (ipa_reference_vars_info_t
, heap
,
171 ipa_reference_vars_vector
, node
->uid
+ 1);
172 VEC_replace (ipa_reference_vars_info_t
, ipa_reference_vars_vector
,
176 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
178 set_reference_optimization_summary (struct cgraph_node
*node
,
179 ipa_reference_optimization_summary_t info
)
181 if (!ipa_reference_opt_sum_vector
182 || (VEC_length (ipa_reference_optimization_summary_t
,
183 ipa_reference_opt_sum_vector
)
184 <= (unsigned int) node
->uid
))
185 VEC_safe_grow_cleared (ipa_reference_optimization_summary_t
,
186 heap
, ipa_reference_opt_sum_vector
, node
->uid
+ 1);
187 VEC_replace (ipa_reference_optimization_summary_t
,
188 ipa_reference_opt_sum_vector
, node
->uid
, info
);
191 /* Return a bitmap indexed by_DECL_UID uid for the static variables
192 that are not read during the execution of the function FN. Returns
193 NULL if no data is available. */
196 ipa_reference_get_not_read_global (struct cgraph_node
*fn
)
198 ipa_reference_optimization_summary_t info
;
200 info
= get_reference_optimization_summary (fn
);
202 return info
->statics_not_read
;
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
;
226 /* Add VAR to all_module_statics and the two
227 reference_vars_to_consider* sets. */
230 add_static_var (tree var
)
232 int uid
= DECL_UID (var
);
233 gcc_assert (TREE_CODE (var
) == VAR_DECL
);
235 splay_tree_insert (reference_vars_to_consider
,
236 uid
, (splay_tree_value
)var
);
237 bitmap_set_bit (all_module_statics
, uid
);
240 /* Return true if the variable T is the right kind of static variable to
241 perform compilation unit scope escape analysis. */
244 is_proper_for_analysis (tree t
)
246 /* We handle only variables whose address is never taken. */
247 if (TREE_ADDRESSABLE (t
))
250 /* If the variable has the "used" attribute, treat it as if it had a
251 been touched by the devil. */
252 if (DECL_PRESERVE_P (t
))
255 /* Do not want to do anything with volatile except mark any
256 function that uses one to be not const or pure. */
257 if (TREE_THIS_VOLATILE (t
))
260 /* We do not need to analyze readonly vars, we already know they do not
262 if (TREE_READONLY (t
))
265 /* We cannot touch decls where the type needs constructing. */
266 if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (t
)))
269 /* This is a variable we care about. Check if we have seen it
270 before, and if not add it the set of variables we care about. */
271 if (all_module_statics
272 && !bitmap_bit_p (all_module_statics
, DECL_UID (t
)))
278 /* Lookup the tree node for the static variable that has UID and
279 convert the name to a string for debugging. */
282 get_static_name (int index
)
284 splay_tree_node stn
=
285 splay_tree_lookup (reference_vars_to_consider
, index
);
287 return lang_hooks
.decl_printable_name ((tree
)(stn
->value
), 2);
291 /* Or in all of the bits from every callee of X into X_GLOBAL, the caller's cycle,
292 bit vector. There are several cases to check to avoid the sparse
296 propagate_bits (ipa_reference_global_vars_info_t x_global
, struct cgraph_node
*x
)
298 struct cgraph_edge
*e
;
299 for (e
= x
->callees
; e
; e
= e
->next_callee
)
301 struct cgraph_node
*y
= e
->callee
;
303 /* Only look into nodes we can propagate something. */
304 if (cgraph_function_body_availability (e
->callee
) > AVAIL_OVERWRITABLE
)
306 int flags
= flags_from_decl_or_type (e
->callee
->decl
);
307 if (get_reference_vars_info (y
))
309 ipa_reference_vars_info_t y_info
310 = get_reference_vars_info (y
);
311 ipa_reference_global_vars_info_t y_global
= &y_info
->global
;
313 /* Calls in current cycle do not have global computed yet. */
314 if (!y_global
->statics_read
)
317 /* If function is declared const, it reads no memory even if it
318 seems so to local analysis. */
319 if (flags
& ECF_CONST
)
322 if (x_global
->statics_read
323 != all_module_statics
)
325 if (y_global
->statics_read
326 == all_module_statics
)
328 BITMAP_FREE (x_global
->statics_read
);
329 x_global
->statics_read
330 = all_module_statics
;
332 /* Skip bitmaps that are pointer equal to node's bitmap
333 (no reason to spin within the cycle). */
334 else if (x_global
->statics_read
335 != y_global
->statics_read
)
336 bitmap_ior_into (x_global
->statics_read
,
337 y_global
->statics_read
);
340 /* If function is declared pure, it has no stores even if it
341 seems so to local analysis; If we can not return from here,
342 we can safely ignore the call. */
343 if ((flags
& ECF_PURE
)
344 || cgraph_edge_cannot_lead_to_return (e
))
347 if (x_global
->statics_written
348 != all_module_statics
)
350 if (y_global
->statics_written
351 == all_module_statics
)
353 BITMAP_FREE (x_global
->statics_written
);
354 x_global
->statics_written
355 = all_module_statics
;
357 /* Skip bitmaps that are pointer equal to node's bitmap
358 (no reason to spin within the cycle). */
359 else if (x_global
->statics_written
360 != y_global
->statics_written
)
361 bitmap_ior_into (x_global
->statics_written
,
362 y_global
->statics_written
);
371 /* The init routine for analyzing global static variable usage. See
372 comments at top for description. */
376 static bool init_p
= false;
384 reference_vars_to_consider
= splay_tree_new (splay_tree_compare_ints
, 0, 0);
386 bitmap_obstack_initialize (&local_info_obstack
);
387 bitmap_obstack_initialize (&optimization_summary_obstack
);
388 all_module_statics
= BITMAP_ALLOC (&optimization_summary_obstack
);
390 node_removal_hook_holder
=
391 cgraph_add_node_removal_hook (&remove_node_data
, NULL
);
392 node_duplication_hook_holder
=
393 cgraph_add_node_duplication_hook (&duplicate_node_data
, NULL
);
397 /* Set up the persistent info for FN. */
399 static ipa_reference_local_vars_info_t
400 init_function_info (struct cgraph_node
*fn
)
402 ipa_reference_vars_info_t info
403 = XCNEW (struct ipa_reference_vars_info_d
);
405 /* Add the info to the tree's annotation. */
406 set_reference_vars_info (fn
, info
);
408 info
->local
.statics_read
= BITMAP_ALLOC (&local_info_obstack
);
409 info
->local
.statics_written
= BITMAP_ALLOC (&local_info_obstack
);
415 /* This is the main routine for finding the reference patterns for
416 global variables within a function FN. */
419 analyze_function (struct cgraph_node
*fn
)
421 ipa_reference_local_vars_info_t local
;
426 local
= init_function_info (fn
);
427 for (i
= 0; ipa_ref_list_reference_iterate (&fn
->ref_list
, i
, ref
); i
++)
429 if (ref
->refered_type
!= IPA_REF_VARPOOL
)
431 var
= ipa_ref_varpool_node (ref
)->decl
;
432 if (ipa_ref_varpool_node (ref
)->externally_visible
433 || !ipa_ref_varpool_node (ref
)->analyzed
434 || !is_proper_for_analysis (var
))
439 bitmap_set_bit (local
->statics_read
, DECL_UID (var
));
442 if (ipa_ref_cannot_lead_to_return (ref
))
444 bitmap_set_bit (local
->statics_written
, DECL_UID (var
));
452 if (cgraph_node_cannot_return (fn
))
453 bitmap_clear (local
->statics_written
);
457 copy_global_bitmap (bitmap src
)
462 if (src
== all_module_statics
)
463 return all_module_statics
;
464 dst
= BITMAP_ALLOC (&optimization_summary_obstack
);
465 bitmap_copy (dst
, src
);
470 /* Called when new clone is inserted to callgraph late. */
473 duplicate_node_data (struct cgraph_node
*src
, struct cgraph_node
*dst
,
474 void *data ATTRIBUTE_UNUSED
)
476 ipa_reference_optimization_summary_t ginfo
;
477 ipa_reference_optimization_summary_t dst_ginfo
;
479 ginfo
= get_reference_optimization_summary (src
);
482 dst_ginfo
= XCNEW (struct ipa_reference_optimization_summary_d
);
483 set_reference_optimization_summary (dst
, dst_ginfo
);
484 dst_ginfo
->statics_not_read
= copy_global_bitmap (ginfo
->statics_not_read
);
485 dst_ginfo
->statics_not_written
= copy_global_bitmap (ginfo
->statics_not_written
);
488 /* Called when node is removed. */
491 remove_node_data (struct cgraph_node
*node
, void *data ATTRIBUTE_UNUSED
)
493 ipa_reference_optimization_summary_t ginfo
;
494 ginfo
= get_reference_optimization_summary (node
);
497 if (ginfo
->statics_not_read
498 && ginfo
->statics_not_read
!= all_module_statics
)
499 BITMAP_FREE (ginfo
->statics_not_read
);
501 if (ginfo
->statics_not_written
502 && ginfo
->statics_not_written
!= all_module_statics
)
503 BITMAP_FREE (ginfo
->statics_not_written
);
505 set_reference_optimization_summary (node
, NULL
);
509 /* Analyze each function in the cgraph to see which global or statics
510 are read or written. */
513 generate_summary (void)
515 struct cgraph_node
*node
;
521 bm_temp
= BITMAP_ALLOC (&local_info_obstack
);
523 /* Process all of the functions next. */
524 for (node
= cgraph_nodes
; node
; node
= node
->next
)
526 analyze_function (node
);
529 EXECUTE_IF_SET_IN_BITMAP (all_module_statics
, 0, index
, bi
)
531 fprintf (dump_file
, "\nPromotable global:%s",
532 get_static_name (index
));
535 BITMAP_FREE(bm_temp
);
538 for (node
= cgraph_nodes
; node
; node
= node
->next
)
539 if (cgraph_function_body_availability (node
) >= AVAIL_OVERWRITABLE
)
541 ipa_reference_local_vars_info_t l
;
545 l
= &get_reference_vars_info (node
)->local
;
547 "\nFunction name:%s/%i:",
548 cgraph_node_name (node
), node
->uid
);
549 fprintf (dump_file
, "\n locals read: ");
551 EXECUTE_IF_SET_IN_BITMAP (l
->statics_read
,
554 fprintf (dump_file
, "%s ",
555 get_static_name (index
));
557 fprintf (dump_file
, "\n locals written: ");
558 if (l
->statics_written
)
559 EXECUTE_IF_SET_IN_BITMAP (l
->statics_written
,
562 fprintf(dump_file
, "%s ",
563 get_static_name (index
));
568 /* Set READ_ALL/WRITE_ALL based on decl flags of NODE. */
571 read_write_all_from_decl (struct cgraph_node
*node
, bool * read_all
,
574 tree decl
= node
->decl
;
575 int flags
= flags_from_decl_or_type (decl
);
576 if (flags
& ECF_CONST
)
578 else if ((flags
& ECF_PURE
)
579 || cgraph_node_cannot_return (node
))
583 /* TODO: To be able to produce sane results, we should also handle
584 common builtins, in particular throw. */
590 /* Produce the global information by preforming a transitive closure
591 on the local information that was produced by ipa_analyze_function */
596 struct cgraph_node
*node
;
597 struct cgraph_node
*w
;
598 struct cgraph_node
**order
=
599 XCNEWVEC (struct cgraph_node
*, cgraph_n_nodes
);
600 int order_pos
= ipa_utils_reduced_inorder (order
, false, true, NULL
);
604 dump_cgraph (dump_file
);
606 ipa_discover_readonly_nonaddressable_vars ();
609 /* Propagate the local information thru the call graph to produce
610 the global information. All the nodes within a cycle will have
611 the same info so we collapse cycles first. Then we can do the
612 propagation in one pass from the leaves to the roots. */
613 order_pos
= ipa_utils_reduced_inorder (order
, true, true, NULL
);
615 ipa_utils_print_order(dump_file
, "reduced", order
, order_pos
);
617 for (i
= 0; i
< order_pos
; i
++ )
619 ipa_reference_vars_info_t node_info
;
620 ipa_reference_global_vars_info_t node_g
;
621 ipa_reference_local_vars_info_t node_l
;
622 struct cgraph_edge
*e
, *ie
;
626 struct ipa_dfs_info
* w_info
;
629 node_info
= get_reference_vars_info (node
);
630 gcc_assert (node_info
);
632 node_l
= &node_info
->local
;
633 node_g
= &node_info
->global
;
638 /* When function is overwrittable, we can not assume anything. */
639 if (cgraph_function_body_availability (node
) <= AVAIL_OVERWRITABLE
)
640 read_write_all_from_decl (node
, &read_all
, &write_all
);
642 for (e
= node
->callees
; e
; e
= e
->next_callee
)
643 if (cgraph_function_body_availability (e
->callee
) <= AVAIL_OVERWRITABLE
)
644 read_write_all_from_decl (e
->callee
, &read_all
, &write_all
);
646 for (ie
= node
->indirect_calls
; ie
; ie
= ie
->next_callee
)
647 if (!(ie
->indirect_info
->ecf_flags
& ECF_CONST
))
650 if (!cgraph_edge_cannot_lead_to_return (ie
)
651 && !(ie
->indirect_info
->ecf_flags
& ECF_PURE
))
656 /* If any node in a cycle is read_all or write_all
658 w_info
= (struct ipa_dfs_info
*) node
->aux
;
659 w
= w_info
->next_cycle
;
660 while (w
&& (!read_all
|| !write_all
))
662 /* When function is overwrittable, we can not assume anything. */
663 if (cgraph_function_body_availability (w
) <= AVAIL_OVERWRITABLE
)
664 read_write_all_from_decl (w
, &read_all
, &write_all
);
666 for (e
= w
->callees
; e
; e
= e
->next_callee
)
667 if (cgraph_function_body_availability (e
->callee
) <= AVAIL_OVERWRITABLE
)
668 read_write_all_from_decl (e
->callee
, &read_all
, &write_all
);
670 for (ie
= w
->indirect_calls
; ie
; ie
= ie
->next_callee
)
671 if (!(ie
->indirect_info
->ecf_flags
& ECF_CONST
))
674 if (!cgraph_edge_cannot_lead_to_return (ie
)
675 && !(ie
->indirect_info
->ecf_flags
& ECF_PURE
))
679 w_info
= (struct ipa_dfs_info
*) w
->aux
;
680 w
= w_info
->next_cycle
;
684 /* Initialized the bitmaps for the reduced nodes */
686 node_g
->statics_read
= all_module_statics
;
689 node_g
->statics_read
= BITMAP_ALLOC (&local_info_obstack
);
690 bitmap_copy (node_g
->statics_read
,
691 node_l
->statics_read
);
694 node_g
->statics_written
= all_module_statics
;
697 node_g
->statics_written
= BITMAP_ALLOC (&local_info_obstack
);
698 bitmap_copy (node_g
->statics_written
,
699 node_l
->statics_written
);
702 propagate_bits (node_g
, node
);
703 w_info
= (struct ipa_dfs_info
*) node
->aux
;
704 w
= w_info
->next_cycle
;
705 while (w
&& (!read_all
|| !write_all
))
707 ipa_reference_vars_info_t w_ri
=
708 get_reference_vars_info (w
);
709 ipa_reference_local_vars_info_t w_l
= &w_ri
->local
;
710 int flags
= flags_from_decl_or_type (w
->decl
);
712 /* These global bitmaps are initialized from the local info
713 of all of the nodes in the region. However there is no
714 need to do any work if the bitmaps were set to
715 all_module_statics. */
716 if (!read_all
&& !(flags
& ECF_CONST
))
717 bitmap_ior_into (node_g
->statics_read
,
720 && !(flags
& ECF_PURE
)
721 && !cgraph_node_cannot_return (w
))
722 bitmap_ior_into (node_g
->statics_written
,
723 w_l
->statics_written
);
724 propagate_bits (node_g
, w
);
725 w_info
= (struct ipa_dfs_info
*) w
->aux
;
726 w
= w_info
->next_cycle
;
729 /* All nodes within a cycle have the same global info bitmaps. */
730 node_info
->global
= *node_g
;
731 w_info
= (struct ipa_dfs_info
*) node
->aux
;
732 w
= w_info
->next_cycle
;
735 ipa_reference_vars_info_t w_ri
=
736 get_reference_vars_info (w
);
738 w_ri
->global
= *node_g
;
740 w_info
= (struct ipa_dfs_info
*) w
->aux
;
741 w
= w_info
->next_cycle
;
747 for (i
= 0; i
< order_pos
; i
++ )
749 ipa_reference_vars_info_t node_info
;
750 ipa_reference_global_vars_info_t node_g
;
751 ipa_reference_local_vars_info_t node_l
;
754 struct ipa_dfs_info
* w_info
;
757 node_info
= get_reference_vars_info (node
);
758 node_g
= &node_info
->global
;
759 node_l
= &node_info
->local
;
761 "\nFunction name:%s/%i:",
762 cgraph_node_name (node
), node
->uid
);
763 fprintf (dump_file
, "\n locals read: ");
764 if (node_l
->statics_read
)
765 EXECUTE_IF_SET_IN_BITMAP (node_l
->statics_read
,
768 fprintf (dump_file
, "%s ",
769 get_static_name (index
));
771 fprintf (dump_file
, "\n locals written: ");
772 if (node_l
->statics_written
)
773 EXECUTE_IF_SET_IN_BITMAP (node_l
->statics_written
,
776 fprintf(dump_file
, "%s ",
777 get_static_name (index
));
780 w_info
= (struct ipa_dfs_info
*) node
->aux
;
781 w
= w_info
->next_cycle
;
784 ipa_reference_vars_info_t w_ri
=
785 get_reference_vars_info (w
);
786 ipa_reference_local_vars_info_t w_l
= &w_ri
->local
;
787 fprintf (dump_file
, "\n next cycle: %s/%i ",
788 cgraph_node_name (w
), w
->uid
);
789 fprintf (dump_file
, "\n locals read: ");
790 if (w_l
->statics_read
)
791 EXECUTE_IF_SET_IN_BITMAP (w_l
->statics_read
,
794 fprintf (dump_file
, "%s ",
795 get_static_name (index
));
798 fprintf (dump_file
, "\n locals written: ");
799 if (w_l
->statics_written
)
800 EXECUTE_IF_SET_IN_BITMAP (w_l
->statics_written
,
803 fprintf (dump_file
, "%s ",
804 get_static_name (index
));
807 w_info
= (struct ipa_dfs_info
*) w
->aux
;
808 w
= w_info
->next_cycle
;
810 fprintf (dump_file
, "\n globals read: ");
811 if (node_g
->statics_read
== all_module_statics
)
812 fprintf (dump_file
, "ALL");
814 EXECUTE_IF_SET_IN_BITMAP (node_g
->statics_read
,
817 fprintf (dump_file
, "%s ",
818 get_static_name (index
));
820 fprintf (dump_file
, "\n globals written: ");
821 if (node_g
->statics_written
== all_module_statics
)
822 fprintf (dump_file
, "ALL");
824 EXECUTE_IF_SET_IN_BITMAP (node_g
->statics_written
,
827 fprintf (dump_file
, "%s ",
828 get_static_name (index
));
834 for (node
= cgraph_nodes
; node
; node
= node
->next
)
836 ipa_reference_vars_info_t node_info
;
837 ipa_reference_global_vars_info_t node_g
;
838 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. */
853 if (bitmap_empty_p (node_g
->statics_read
))
854 opt
->statics_not_read
= all_module_statics
;
857 opt
->statics_not_read
858 = BITMAP_ALLOC (&optimization_summary_obstack
);
859 if (node_g
->statics_read
!= all_module_statics
)
860 bitmap_and_compl (opt
->statics_not_read
,
862 node_g
->statics_read
);
865 if (bitmap_empty_p (node_g
->statics_written
))
866 opt
->statics_not_written
= all_module_statics
;
869 opt
->statics_not_written
870 = BITMAP_ALLOC (&optimization_summary_obstack
);
871 if (node_g
->statics_written
!= all_module_statics
)
872 bitmap_and_compl (opt
->statics_not_written
,
874 node_g
->statics_written
);
888 bitmap_obstack_release (&local_info_obstack
);
889 VEC_free (ipa_reference_vars_info_t
, heap
, ipa_reference_vars_vector
);
890 ipa_reference_vars_vector
= NULL
;
892 splay_tree_delete (reference_vars_to_consider
);
893 reference_vars_to_consider
= NULL
;
897 /* Return true if we need to write summary of NODE. */
900 write_node_summary_p (struct cgraph_node
*node
,
902 varpool_node_set vset
,
903 bitmap ltrans_statics
)
905 ipa_reference_optimization_summary_t info
;
907 /* See if we have (non-empty) info. */
908 if (!node
->analyzed
|| node
->global
.inlined_to
)
910 info
= get_reference_optimization_summary (node
);
911 if (!info
|| (bitmap_empty_p (info
->statics_not_read
)
912 && bitmap_empty_p (info
->statics_not_written
)))
915 /* See if we want to encode it.
916 Encode also referenced functions since constant folding might turn it into
919 In future we might also want to include summaries of functions references
920 by initializers of constant variables references in current unit. */
921 if (!reachable_from_this_partition_p (node
, set
)
922 && !referenced_from_this_partition_p (&node
->ref_list
, set
, vset
))
925 /* See if the info has non-empty intersections with vars we want to encode. */
926 if (!bitmap_intersect_p (info
->statics_not_read
, ltrans_statics
)
927 && !bitmap_intersect_p (info
->statics_not_written
, ltrans_statics
))
932 /* Stream out BITS<RANS_STATICS as list of decls to OB.
933 LTRANS_STATICS_BITCOUNT specify number of bits in LTRANS_STATICS
934 or -1. When it is positive, just output -1 when
935 BITS<RANS_STATICS == BITS<RANS_STATICS. */
938 stream_out_bitmap (struct lto_simple_output_block
*ob
,
939 bitmap bits
, bitmap ltrans_statics
,
940 int ltrans_statics_bitcount
)
945 if (bits
== all_module_statics
)
947 lto_output_sleb128_stream (ob
->main_stream
, -1);
950 EXECUTE_IF_AND_IN_BITMAP (bits
, ltrans_statics
, 0, index
, bi
)
952 if (count
== ltrans_statics_bitcount
)
954 lto_output_sleb128_stream (ob
->main_stream
, -1);
957 lto_output_sleb128_stream (ob
->main_stream
, count
);
960 EXECUTE_IF_AND_IN_BITMAP (bits
, ltrans_statics
, 0, index
, bi
)
962 tree decl
= (tree
)splay_tree_lookup (reference_vars_to_consider
, index
)->value
;
963 lto_output_var_decl_index(ob
->decl_state
, ob
->main_stream
, decl
);
967 /* Serialize the ipa info for lto. */
970 ipa_reference_write_optimization_summary (cgraph_node_set set
,
971 varpool_node_set vset
)
973 struct cgraph_node
*node
;
974 struct lto_simple_output_block
*ob
975 = lto_create_simple_output_block (LTO_section_ipa_reference
);
976 unsigned int count
= 0;
977 int ltrans_statics_bitcount
= 0;
978 lto_cgraph_encoder_t encoder
= ob
->decl_state
->cgraph_node_encoder
;
979 lto_varpool_encoder_t varpool_encoder
= ob
->decl_state
->varpool_node_encoder
;
980 bitmap ltrans_statics
= BITMAP_ALLOC (NULL
);
983 reference_vars_to_consider
= splay_tree_new (splay_tree_compare_ints
, 0, 0);
985 /* See what variables we are interested in. */
986 for (i
= 0; i
< lto_varpool_encoder_size (varpool_encoder
); i
++)
988 struct varpool_node
*vnode
= lto_varpool_encoder_deref (varpool_encoder
, i
);
989 if (!vnode
->externally_visible
991 && bitmap_bit_p (all_module_statics
, DECL_UID (vnode
->decl
))
992 && referenced_from_this_partition_p (&vnode
->ref_list
, set
, vset
))
994 tree decl
= vnode
->decl
;
995 bitmap_set_bit (ltrans_statics
, DECL_UID (decl
));
996 splay_tree_insert (reference_vars_to_consider
,
997 DECL_UID (decl
), (splay_tree_value
)decl
);
998 ltrans_statics_bitcount
++;
1003 if (ltrans_statics_bitcount
)
1004 for (i
= 0; i
< lto_cgraph_encoder_size (encoder
); i
++)
1005 if (write_node_summary_p (lto_cgraph_encoder_deref (encoder
, i
),
1006 set
, vset
, ltrans_statics
))
1009 lto_output_uleb128_stream (ob
->main_stream
, count
);
1011 stream_out_bitmap (ob
, ltrans_statics
, ltrans_statics
,
1014 /* Process all of the functions. */
1015 if (ltrans_statics_bitcount
)
1016 for (i
= 0; i
< lto_cgraph_encoder_size (encoder
); i
++)
1018 node
= lto_cgraph_encoder_deref (encoder
, i
);
1019 if (write_node_summary_p (node
, set
, vset
, ltrans_statics
))
1021 ipa_reference_optimization_summary_t info
;
1024 info
= get_reference_optimization_summary (node
);
1025 node_ref
= lto_cgraph_encoder_encode (encoder
, node
);
1026 lto_output_uleb128_stream (ob
->main_stream
, node_ref
);
1028 stream_out_bitmap (ob
, info
->statics_not_read
, ltrans_statics
,
1029 ltrans_statics_bitcount
);
1030 stream_out_bitmap (ob
, info
->statics_not_written
, ltrans_statics
,
1031 ltrans_statics_bitcount
);
1034 BITMAP_FREE (ltrans_statics
);
1035 lto_destroy_simple_output_block (ob
);
1036 splay_tree_delete (reference_vars_to_consider
);
1039 /* Deserialize the ipa info for lto. */
1042 ipa_reference_read_optimization_summary (void)
1044 struct lto_file_decl_data
** file_data_vec
1045 = lto_get_file_decl_data ();
1046 struct lto_file_decl_data
* file_data
;
1048 bitmap_obstack_initialize (&optimization_summary_obstack
);
1050 node_removal_hook_holder
=
1051 cgraph_add_node_removal_hook (&remove_node_data
, NULL
);
1052 node_duplication_hook_holder
=
1053 cgraph_add_node_duplication_hook (&duplicate_node_data
, NULL
);
1054 all_module_statics
= BITMAP_ALLOC (&optimization_summary_obstack
);
1056 while ((file_data
= file_data_vec
[j
++]))
1060 struct lto_input_block
*ib
1061 = lto_create_simple_input_block (file_data
,
1062 LTO_section_ipa_reference
,
1067 unsigned int f_count
= lto_input_uleb128 (ib
);
1071 b_count
= lto_input_sleb128 (ib
);
1073 fprintf (dump_file
, "all module statics:");
1074 for (i
= 0; i
< (unsigned int)b_count
; i
++)
1076 unsigned int var_index
= lto_input_uleb128 (ib
);
1077 tree v_decl
= lto_file_decl_data_get_var_decl (file_data
,
1079 bitmap_set_bit (all_module_statics
, DECL_UID (v_decl
));
1081 fprintf (dump_file
, " %s",
1082 lang_hooks
.decl_printable_name (v_decl
, 2));
1085 for (i
= 0; i
< f_count
; i
++)
1087 unsigned int j
, index
;
1088 struct cgraph_node
*node
;
1089 ipa_reference_optimization_summary_t info
;
1091 lto_cgraph_encoder_t encoder
;
1093 index
= lto_input_uleb128 (ib
);
1094 encoder
= file_data
->cgraph_node_encoder
;
1095 node
= lto_cgraph_encoder_deref (encoder
, index
);
1096 info
= XCNEW (struct ipa_reference_optimization_summary_d
);
1097 set_reference_optimization_summary (node
, info
);
1098 info
->statics_not_read
= BITMAP_ALLOC (&optimization_summary_obstack
);
1099 info
->statics_not_written
= BITMAP_ALLOC (&optimization_summary_obstack
);
1102 "\nFunction name:%s/%i:\n static not read:",
1103 cgraph_node_name (node
), node
->uid
);
1105 /* Set the statics not read. */
1106 v_count
= lto_input_sleb128 (ib
);
1109 info
->statics_not_read
= all_module_statics
;
1111 fprintf (dump_file
, " all module statics");
1114 for (j
= 0; j
< (unsigned int)v_count
; j
++)
1116 unsigned int var_index
= lto_input_uleb128 (ib
);
1117 tree v_decl
= lto_file_decl_data_get_var_decl (file_data
,
1119 bitmap_set_bit (info
->statics_not_read
, DECL_UID (v_decl
));
1121 fprintf (dump_file
, " %s",
1122 lang_hooks
.decl_printable_name (v_decl
, 2));
1127 "\n static not written:");
1128 /* Set the statics not written. */
1129 v_count
= lto_input_sleb128 (ib
);
1132 info
->statics_not_written
= all_module_statics
;
1134 fprintf (dump_file
, " all module statics");
1137 for (j
= 0; j
< (unsigned int)v_count
; j
++)
1139 unsigned int var_index
= lto_input_uleb128 (ib
);
1140 tree v_decl
= lto_file_decl_data_get_var_decl (file_data
,
1142 bitmap_set_bit (info
->statics_not_written
, DECL_UID (v_decl
));
1144 fprintf (dump_file
, " %s",
1145 lang_hooks
.decl_printable_name (v_decl
, 2));
1148 fprintf (dump_file
, "\n");
1151 lto_destroy_simple_input_block (file_data
,
1152 LTO_section_ipa_reference
,
1156 /* Fatal error here. We do not want to support compiling ltrans units with
1157 different version of compiler or different flags than the WPA unit, so
1158 this should never happen. */
1159 fatal_error ("ipa reference summary is missing in ltrans unit");
1164 gate_reference (void)
1166 return (flag_ipa_reference
1167 /* Don't bother doing anything if the program has errors. */
1171 struct ipa_opt_pass_d pass_ipa_reference
=
1175 "static-var", /* name */
1176 gate_reference
, /* gate */
1177 propagate
, /* execute */
1180 0, /* static_pass_number */
1181 TV_IPA_REFERENCE
, /* tv_id */
1182 0, /* properties_required */
1183 0, /* properties_provided */
1184 0, /* properties_destroyed */
1185 0, /* todo_flags_start */
1186 0 /* todo_flags_finish */
1188 NULL
, /* generate_summary */
1189 NULL
, /* write_summary */
1190 NULL
, /* read_summary */
1191 ipa_reference_write_optimization_summary
,/* write_optimization_summary */
1192 ipa_reference_read_optimization_summary
,/* read_optimization_summary */
1193 NULL
, /* stmt_fixup */
1195 NULL
, /* function_transform */
1196 NULL
/* variable_transform */