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 bitmap_set_bit (local
->statics_written
, DECL_UID (var
));
450 if (cgraph_node_cannot_return (fn
))
451 bitmap_clear (local
->statics_written
);
455 copy_global_bitmap (bitmap src
)
460 if (src
== all_module_statics
)
461 return all_module_statics
;
462 dst
= BITMAP_ALLOC (&optimization_summary_obstack
);
463 bitmap_copy (dst
, src
);
468 /* Called when new clone is inserted to callgraph late. */
471 duplicate_node_data (struct cgraph_node
*src
, struct cgraph_node
*dst
,
472 void *data ATTRIBUTE_UNUSED
)
474 ipa_reference_optimization_summary_t ginfo
;
475 ipa_reference_optimization_summary_t dst_ginfo
;
477 ginfo
= get_reference_optimization_summary (src
);
480 dst_ginfo
= XCNEW (struct ipa_reference_optimization_summary_d
);
481 set_reference_optimization_summary (dst
, dst_ginfo
);
482 dst_ginfo
->statics_not_read
= copy_global_bitmap (ginfo
->statics_not_read
);
483 dst_ginfo
->statics_not_written
= copy_global_bitmap (ginfo
->statics_not_written
);
486 /* Called when node is removed. */
489 remove_node_data (struct cgraph_node
*node
, void *data ATTRIBUTE_UNUSED
)
491 ipa_reference_optimization_summary_t ginfo
;
492 ginfo
= get_reference_optimization_summary (node
);
495 if (ginfo
->statics_not_read
496 && ginfo
->statics_not_read
!= all_module_statics
)
497 BITMAP_FREE (ginfo
->statics_not_read
);
499 if (ginfo
->statics_not_written
500 && ginfo
->statics_not_written
!= all_module_statics
)
501 BITMAP_FREE (ginfo
->statics_not_written
);
503 set_reference_optimization_summary (node
, NULL
);
507 /* Analyze each function in the cgraph to see which global or statics
508 are read or written. */
511 generate_summary (void)
513 struct cgraph_node
*node
;
519 bm_temp
= BITMAP_ALLOC (&local_info_obstack
);
521 /* Process all of the functions next. */
522 for (node
= cgraph_nodes
; node
; node
= node
->next
)
524 analyze_function (node
);
527 EXECUTE_IF_SET_IN_BITMAP (all_module_statics
, 0, index
, bi
)
529 fprintf (dump_file
, "\nPromotable global:%s",
530 get_static_name (index
));
533 BITMAP_FREE(bm_temp
);
536 for (node
= cgraph_nodes
; node
; node
= node
->next
)
537 if (cgraph_function_body_availability (node
) >= AVAIL_OVERWRITABLE
)
539 ipa_reference_local_vars_info_t l
;
543 l
= &get_reference_vars_info (node
)->local
;
545 "\nFunction name:%s/%i:",
546 cgraph_node_name (node
), node
->uid
);
547 fprintf (dump_file
, "\n locals read: ");
549 EXECUTE_IF_SET_IN_BITMAP (l
->statics_read
,
552 fprintf (dump_file
, "%s ",
553 get_static_name (index
));
555 fprintf (dump_file
, "\n locals written: ");
556 if (l
->statics_written
)
557 EXECUTE_IF_SET_IN_BITMAP (l
->statics_written
,
560 fprintf(dump_file
, "%s ",
561 get_static_name (index
));
566 /* Set READ_ALL/WRITE_ALL based on decl flags of NODE. */
569 read_write_all_from_decl (struct cgraph_node
*node
, bool * read_all
,
572 tree decl
= node
->decl
;
573 int flags
= flags_from_decl_or_type (decl
);
574 if (flags
& ECF_CONST
)
576 else if ((flags
& ECF_PURE
)
577 || cgraph_node_cannot_return (node
))
581 /* TODO: To be able to produce sane results, we should also handle
582 common builtins, in particular throw. */
588 /* Produce the global information by preforming a transitive closure
589 on the local information that was produced by ipa_analyze_function */
594 struct cgraph_node
*node
;
595 struct cgraph_node
*w
;
596 struct cgraph_node
**order
=
597 XCNEWVEC (struct cgraph_node
*, cgraph_n_nodes
);
598 int order_pos
= ipa_utils_reduced_inorder (order
, false, true, NULL
);
602 dump_cgraph (dump_file
);
604 ipa_discover_readonly_nonaddressable_vars ();
607 /* Propagate the local information thru the call graph to produce
608 the global information. All the nodes within a cycle will have
609 the same info so we collapse cycles first. Then we can do the
610 propagation in one pass from the leaves to the roots. */
611 order_pos
= ipa_utils_reduced_inorder (order
, true, true, NULL
);
613 ipa_utils_print_order(dump_file
, "reduced", order
, order_pos
);
615 for (i
= 0; i
< order_pos
; i
++ )
617 ipa_reference_vars_info_t node_info
;
618 ipa_reference_global_vars_info_t node_g
;
619 ipa_reference_local_vars_info_t node_l
;
620 struct cgraph_edge
*e
, *ie
;
624 struct ipa_dfs_info
* w_info
;
627 node_info
= get_reference_vars_info (node
);
628 gcc_assert (node_info
);
630 node_l
= &node_info
->local
;
631 node_g
= &node_info
->global
;
636 /* When function is overwrittable, we can not assume anything. */
637 if (cgraph_function_body_availability (node
) <= AVAIL_OVERWRITABLE
)
638 read_write_all_from_decl (node
, &read_all
, &write_all
);
640 for (e
= node
->callees
; e
; e
= e
->next_callee
)
641 if (cgraph_function_body_availability (e
->callee
) <= AVAIL_OVERWRITABLE
)
642 read_write_all_from_decl (e
->callee
, &read_all
, &write_all
);
644 for (ie
= node
->indirect_calls
; ie
; ie
= ie
->next_callee
)
645 if (!(ie
->indirect_info
->ecf_flags
& ECF_CONST
))
648 if (!cgraph_edge_cannot_lead_to_return (ie
)
649 && !(ie
->indirect_info
->ecf_flags
& ECF_PURE
))
654 /* If any node in a cycle is read_all or write_all
656 w_info
= (struct ipa_dfs_info
*) node
->aux
;
657 w
= w_info
->next_cycle
;
658 while (w
&& (!read_all
|| !write_all
))
660 /* When function is overwrittable, we can not assume anything. */
661 if (cgraph_function_body_availability (w
) <= AVAIL_OVERWRITABLE
)
662 read_write_all_from_decl (w
, &read_all
, &write_all
);
664 for (e
= w
->callees
; e
; e
= e
->next_callee
)
665 if (cgraph_function_body_availability (e
->callee
) <= AVAIL_OVERWRITABLE
)
666 read_write_all_from_decl (e
->callee
, &read_all
, &write_all
);
668 for (ie
= w
->indirect_calls
; ie
; ie
= ie
->next_callee
)
669 if (!(ie
->indirect_info
->ecf_flags
& ECF_CONST
))
672 if (!cgraph_edge_cannot_lead_to_return (ie
)
673 && !(ie
->indirect_info
->ecf_flags
& ECF_PURE
))
677 w_info
= (struct ipa_dfs_info
*) w
->aux
;
678 w
= w_info
->next_cycle
;
682 /* Initialized the bitmaps for the reduced nodes */
684 node_g
->statics_read
= all_module_statics
;
687 node_g
->statics_read
= BITMAP_ALLOC (&local_info_obstack
);
688 bitmap_copy (node_g
->statics_read
,
689 node_l
->statics_read
);
692 node_g
->statics_written
= all_module_statics
;
695 node_g
->statics_written
= BITMAP_ALLOC (&local_info_obstack
);
696 bitmap_copy (node_g
->statics_written
,
697 node_l
->statics_written
);
700 propagate_bits (node_g
, node
);
701 w_info
= (struct ipa_dfs_info
*) node
->aux
;
702 w
= w_info
->next_cycle
;
703 while (w
&& (!read_all
|| !write_all
))
705 ipa_reference_vars_info_t w_ri
=
706 get_reference_vars_info (w
);
707 ipa_reference_local_vars_info_t w_l
= &w_ri
->local
;
708 int flags
= flags_from_decl_or_type (w
->decl
);
710 /* These global bitmaps are initialized from the local info
711 of all of the nodes in the region. However there is no
712 need to do any work if the bitmaps were set to
713 all_module_statics. */
714 if (!read_all
&& !(flags
& ECF_CONST
))
715 bitmap_ior_into (node_g
->statics_read
,
718 && !(flags
& ECF_PURE
)
719 && !cgraph_node_cannot_return (w
))
720 bitmap_ior_into (node_g
->statics_written
,
721 w_l
->statics_written
);
722 propagate_bits (node_g
, w
);
723 w_info
= (struct ipa_dfs_info
*) w
->aux
;
724 w
= w_info
->next_cycle
;
727 /* All nodes within a cycle have the same global info bitmaps. */
728 node_info
->global
= *node_g
;
729 w_info
= (struct ipa_dfs_info
*) node
->aux
;
730 w
= w_info
->next_cycle
;
733 ipa_reference_vars_info_t w_ri
=
734 get_reference_vars_info (w
);
736 w_ri
->global
= *node_g
;
738 w_info
= (struct ipa_dfs_info
*) w
->aux
;
739 w
= w_info
->next_cycle
;
745 for (i
= 0; i
< order_pos
; i
++ )
747 ipa_reference_vars_info_t node_info
;
748 ipa_reference_global_vars_info_t node_g
;
749 ipa_reference_local_vars_info_t node_l
;
752 struct ipa_dfs_info
* w_info
;
755 node_info
= get_reference_vars_info (node
);
756 node_g
= &node_info
->global
;
757 node_l
= &node_info
->local
;
759 "\nFunction name:%s/%i:",
760 cgraph_node_name (node
), node
->uid
);
761 fprintf (dump_file
, "\n locals read: ");
762 if (node_l
->statics_read
)
763 EXECUTE_IF_SET_IN_BITMAP (node_l
->statics_read
,
766 fprintf (dump_file
, "%s ",
767 get_static_name (index
));
769 fprintf (dump_file
, "\n locals written: ");
770 if (node_l
->statics_written
)
771 EXECUTE_IF_SET_IN_BITMAP (node_l
->statics_written
,
774 fprintf(dump_file
, "%s ",
775 get_static_name (index
));
778 w_info
= (struct ipa_dfs_info
*) node
->aux
;
779 w
= w_info
->next_cycle
;
782 ipa_reference_vars_info_t w_ri
=
783 get_reference_vars_info (w
);
784 ipa_reference_local_vars_info_t w_l
= &w_ri
->local
;
785 fprintf (dump_file
, "\n next cycle: %s/%i ",
786 cgraph_node_name (w
), w
->uid
);
787 fprintf (dump_file
, "\n locals read: ");
788 if (w_l
->statics_read
)
789 EXECUTE_IF_SET_IN_BITMAP (w_l
->statics_read
,
792 fprintf (dump_file
, "%s ",
793 get_static_name (index
));
796 fprintf (dump_file
, "\n locals written: ");
797 if (w_l
->statics_written
)
798 EXECUTE_IF_SET_IN_BITMAP (w_l
->statics_written
,
801 fprintf (dump_file
, "%s ",
802 get_static_name (index
));
805 w_info
= (struct ipa_dfs_info
*) w
->aux
;
806 w
= w_info
->next_cycle
;
808 fprintf (dump_file
, "\n globals read: ");
809 if (node_g
->statics_read
== all_module_statics
)
810 fprintf (dump_file
, "ALL");
812 EXECUTE_IF_SET_IN_BITMAP (node_g
->statics_read
,
815 fprintf (dump_file
, "%s ",
816 get_static_name (index
));
818 fprintf (dump_file
, "\n globals written: ");
819 if (node_g
->statics_written
== all_module_statics
)
820 fprintf (dump_file
, "ALL");
822 EXECUTE_IF_SET_IN_BITMAP (node_g
->statics_written
,
825 fprintf (dump_file
, "%s ",
826 get_static_name (index
));
832 for (node
= cgraph_nodes
; node
; node
= node
->next
)
834 ipa_reference_vars_info_t node_info
;
835 ipa_reference_global_vars_info_t node_g
;
836 ipa_reference_optimization_summary_t opt
;
841 node_info
= get_reference_vars_info (node
);
842 if (cgraph_function_body_availability (node
) > AVAIL_OVERWRITABLE
)
844 node_g
= &node_info
->global
;
846 opt
= XCNEW (struct ipa_reference_optimization_summary_d
);
847 set_reference_optimization_summary (node
, opt
);
849 /* Create the complimentary sets. */
851 if (bitmap_empty_p (node_g
->statics_read
))
852 opt
->statics_not_read
= all_module_statics
;
855 opt
->statics_not_read
856 = BITMAP_ALLOC (&optimization_summary_obstack
);
857 if (node_g
->statics_read
!= all_module_statics
)
858 bitmap_and_compl (opt
->statics_not_read
,
860 node_g
->statics_read
);
863 if (bitmap_empty_p (node_g
->statics_written
))
864 opt
->statics_not_written
= all_module_statics
;
867 opt
->statics_not_written
868 = BITMAP_ALLOC (&optimization_summary_obstack
);
869 if (node_g
->statics_written
!= all_module_statics
)
870 bitmap_and_compl (opt
->statics_not_written
,
872 node_g
->statics_written
);
886 bitmap_obstack_release (&local_info_obstack
);
887 VEC_free (ipa_reference_vars_info_t
, heap
, ipa_reference_vars_vector
);
888 ipa_reference_vars_vector
= NULL
;
890 splay_tree_delete (reference_vars_to_consider
);
891 reference_vars_to_consider
= NULL
;
895 /* Return true if we need to write summary of NODE. */
898 write_node_summary_p (struct cgraph_node
*node
,
900 varpool_node_set vset
,
901 bitmap ltrans_statics
)
903 ipa_reference_optimization_summary_t info
;
905 /* See if we have (non-empty) info. */
906 if (!node
->analyzed
|| node
->global
.inlined_to
)
908 info
= get_reference_optimization_summary (node
);
909 if (!info
|| (bitmap_empty_p (info
->statics_not_read
)
910 && bitmap_empty_p (info
->statics_not_written
)))
913 /* See if we want to encode it.
914 Encode also referenced functions since constant folding might turn it into
917 In future we might also want to include summaries of functions references
918 by initializers of constant variables references in current unit. */
919 if (!reachable_from_this_partition_p (node
, set
)
920 && !referenced_from_this_partition_p (&node
->ref_list
, set
, vset
))
923 /* See if the info has non-empty intersections with vars we want to encode. */
924 if (!bitmap_intersect_p (info
->statics_not_read
, ltrans_statics
)
925 && !bitmap_intersect_p (info
->statics_not_written
, ltrans_statics
))
930 /* Stream out BITS<RANS_STATICS as list of decls to OB.
931 LTRANS_STATICS_BITCOUNT specify number of bits in LTRANS_STATICS
932 or -1. When it is positive, just output -1 when
933 BITS<RANS_STATICS == BITS<RANS_STATICS. */
936 stream_out_bitmap (struct lto_simple_output_block
*ob
,
937 bitmap bits
, bitmap ltrans_statics
,
938 int ltrans_statics_bitcount
)
943 if (bits
== all_module_statics
)
945 lto_output_sleb128_stream (ob
->main_stream
, -1);
948 EXECUTE_IF_AND_IN_BITMAP (bits
, ltrans_statics
, 0, index
, bi
)
950 if (count
== ltrans_statics_bitcount
)
952 lto_output_sleb128_stream (ob
->main_stream
, -1);
955 lto_output_sleb128_stream (ob
->main_stream
, count
);
958 EXECUTE_IF_AND_IN_BITMAP (bits
, ltrans_statics
, 0, index
, bi
)
960 tree decl
= (tree
)splay_tree_lookup (reference_vars_to_consider
, index
)->value
;
961 lto_output_var_decl_index(ob
->decl_state
, ob
->main_stream
, decl
);
965 /* Serialize the ipa info for lto. */
968 ipa_reference_write_optimization_summary (cgraph_node_set set
,
969 varpool_node_set vset
)
971 struct cgraph_node
*node
;
972 struct lto_simple_output_block
*ob
973 = lto_create_simple_output_block (LTO_section_ipa_reference
);
974 unsigned int count
= 0;
975 int ltrans_statics_bitcount
= 0;
976 lto_cgraph_encoder_t encoder
= ob
->decl_state
->cgraph_node_encoder
;
977 lto_varpool_encoder_t varpool_encoder
= ob
->decl_state
->varpool_node_encoder
;
978 bitmap ltrans_statics
= BITMAP_ALLOC (NULL
);
981 reference_vars_to_consider
= splay_tree_new (splay_tree_compare_ints
, 0, 0);
983 /* See what variables we are interested in. */
984 for (i
= 0; i
< lto_varpool_encoder_size (varpool_encoder
); i
++)
986 struct varpool_node
*vnode
= lto_varpool_encoder_deref (varpool_encoder
, i
);
987 if (!vnode
->externally_visible
989 && bitmap_bit_p (all_module_statics
, DECL_UID (vnode
->decl
))
990 && referenced_from_this_partition_p (&vnode
->ref_list
, set
, vset
))
992 tree decl
= vnode
->decl
;
993 bitmap_set_bit (ltrans_statics
, DECL_UID (decl
));
994 splay_tree_insert (reference_vars_to_consider
,
995 DECL_UID (decl
), (splay_tree_value
)decl
);
996 ltrans_statics_bitcount
++;
1001 if (ltrans_statics_bitcount
)
1002 for (i
= 0; i
< lto_cgraph_encoder_size (encoder
); i
++)
1003 if (write_node_summary_p (lto_cgraph_encoder_deref (encoder
, i
),
1004 set
, vset
, ltrans_statics
))
1007 lto_output_uleb128_stream (ob
->main_stream
, count
);
1009 stream_out_bitmap (ob
, ltrans_statics
, ltrans_statics
,
1012 /* Process all of the functions. */
1013 if (ltrans_statics_bitcount
)
1014 for (i
= 0; i
< lto_cgraph_encoder_size (encoder
); i
++)
1016 node
= lto_cgraph_encoder_deref (encoder
, i
);
1017 if (write_node_summary_p (node
, set
, vset
, ltrans_statics
))
1019 ipa_reference_optimization_summary_t info
;
1022 info
= get_reference_optimization_summary (node
);
1023 node_ref
= lto_cgraph_encoder_encode (encoder
, node
);
1024 lto_output_uleb128_stream (ob
->main_stream
, node_ref
);
1026 stream_out_bitmap (ob
, info
->statics_not_read
, ltrans_statics
,
1027 ltrans_statics_bitcount
);
1028 stream_out_bitmap (ob
, info
->statics_not_written
, ltrans_statics
,
1029 ltrans_statics_bitcount
);
1032 BITMAP_FREE (ltrans_statics
);
1033 lto_destroy_simple_output_block (ob
);
1034 splay_tree_delete (reference_vars_to_consider
);
1037 /* Deserialize the ipa info for lto. */
1040 ipa_reference_read_optimization_summary (void)
1042 struct lto_file_decl_data
** file_data_vec
1043 = lto_get_file_decl_data ();
1044 struct lto_file_decl_data
* file_data
;
1046 bitmap_obstack_initialize (&optimization_summary_obstack
);
1048 node_removal_hook_holder
=
1049 cgraph_add_node_removal_hook (&remove_node_data
, NULL
);
1050 node_duplication_hook_holder
=
1051 cgraph_add_node_duplication_hook (&duplicate_node_data
, NULL
);
1052 all_module_statics
= BITMAP_ALLOC (&optimization_summary_obstack
);
1054 while ((file_data
= file_data_vec
[j
++]))
1058 struct lto_input_block
*ib
1059 = lto_create_simple_input_block (file_data
,
1060 LTO_section_ipa_reference
,
1065 unsigned int f_count
= lto_input_uleb128 (ib
);
1069 b_count
= lto_input_sleb128 (ib
);
1071 fprintf (dump_file
, "all module statics:");
1072 for (i
= 0; i
< (unsigned int)b_count
; i
++)
1074 unsigned int var_index
= lto_input_uleb128 (ib
);
1075 tree v_decl
= lto_file_decl_data_get_var_decl (file_data
,
1077 bitmap_set_bit (all_module_statics
, DECL_UID (v_decl
));
1079 fprintf (dump_file
, " %s",
1080 lang_hooks
.decl_printable_name (v_decl
, 2));
1083 for (i
= 0; i
< f_count
; i
++)
1085 unsigned int j
, index
;
1086 struct cgraph_node
*node
;
1087 ipa_reference_optimization_summary_t info
;
1089 lto_cgraph_encoder_t encoder
;
1091 index
= lto_input_uleb128 (ib
);
1092 encoder
= file_data
->cgraph_node_encoder
;
1093 node
= lto_cgraph_encoder_deref (encoder
, index
);
1094 info
= XCNEW (struct ipa_reference_optimization_summary_d
);
1095 set_reference_optimization_summary (node
, info
);
1096 info
->statics_not_read
= BITMAP_ALLOC (&optimization_summary_obstack
);
1097 info
->statics_not_written
= BITMAP_ALLOC (&optimization_summary_obstack
);
1100 "\nFunction name:%s/%i:\n static not read:",
1101 cgraph_node_name (node
), node
->uid
);
1103 /* Set the statics not read. */
1104 v_count
= lto_input_sleb128 (ib
);
1107 info
->statics_not_read
= all_module_statics
;
1109 fprintf (dump_file
, " all module statics");
1112 for (j
= 0; j
< (unsigned int)v_count
; j
++)
1114 unsigned int var_index
= lto_input_uleb128 (ib
);
1115 tree v_decl
= lto_file_decl_data_get_var_decl (file_data
,
1117 bitmap_set_bit (info
->statics_not_read
, DECL_UID (v_decl
));
1119 fprintf (dump_file
, " %s",
1120 lang_hooks
.decl_printable_name (v_decl
, 2));
1125 "\n static not written:");
1126 /* Set the statics not written. */
1127 v_count
= lto_input_sleb128 (ib
);
1130 info
->statics_not_written
= all_module_statics
;
1132 fprintf (dump_file
, " all module statics");
1135 for (j
= 0; j
< (unsigned int)v_count
; j
++)
1137 unsigned int var_index
= lto_input_uleb128 (ib
);
1138 tree v_decl
= lto_file_decl_data_get_var_decl (file_data
,
1140 bitmap_set_bit (info
->statics_not_written
, DECL_UID (v_decl
));
1142 fprintf (dump_file
, " %s",
1143 lang_hooks
.decl_printable_name (v_decl
, 2));
1146 fprintf (dump_file
, "\n");
1149 lto_destroy_simple_input_block (file_data
,
1150 LTO_section_ipa_reference
,
1154 /* Fatal error here. We do not want to support compiling ltrans units with
1155 different version of compiler or different flags than the WPA unit, so
1156 this should never happen. */
1157 fatal_error ("ipa reference summary is missing in ltrans unit");
1162 gate_reference (void)
1164 return (flag_ipa_reference
1165 /* Don't bother doing anything if the program has errors. */
1169 struct ipa_opt_pass_d pass_ipa_reference
=
1173 "static-var", /* name */
1174 gate_reference
, /* gate */
1175 propagate
, /* execute */
1178 0, /* static_pass_number */
1179 TV_IPA_REFERENCE
, /* tv_id */
1180 0, /* properties_required */
1181 0, /* properties_provided */
1182 0, /* properties_destroyed */
1183 0, /* todo_flags_start */
1184 0 /* todo_flags_finish */
1186 NULL
, /* generate_summary */
1187 NULL
, /* write_summary */
1188 NULL
, /* read_summary */
1189 ipa_reference_write_optimization_summary
,/* write_optimization_summary */
1190 ipa_reference_read_optimization_summary
,/* read_optimization_summary */
1191 NULL
, /* stmt_fixup */
1193 NULL
, /* function_transform */
1194 NULL
/* variable_transform */