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 "pointer-set.h"
49 #include "splay-tree.h"
51 #include "ipa-utils.h"
52 #include "ipa-reference.h"
56 #include "diagnostic.h"
57 #include "data-streamer.h"
58 #include "lto-streamer.h"
60 static void remove_node_data (struct cgraph_node
*node
,
61 void *data ATTRIBUTE_UNUSED
);
62 static void duplicate_node_data (struct cgraph_node
*src
,
63 struct cgraph_node
*dst
,
64 void *data ATTRIBUTE_UNUSED
);
66 /* The static variables defined within the compilation unit that are
67 loaded or stored directly by function that owns this structure. */
69 struct ipa_reference_local_vars_info_d
72 bitmap statics_written
;
75 /* Statics that are read and written by some set of functions. The
76 local ones are based on the loads and stores local to the function.
77 The global ones are based on the local info as well as the
78 transitive closure of the functions that are called. */
80 struct ipa_reference_global_vars_info_d
83 bitmap statics_written
;
86 /* Information we save about every function after ipa-reference is completed. */
88 struct ipa_reference_optimization_summary_d
90 bitmap statics_not_read
;
91 bitmap statics_not_written
;
94 typedef struct ipa_reference_local_vars_info_d
*ipa_reference_local_vars_info_t
;
95 typedef struct ipa_reference_global_vars_info_d
*ipa_reference_global_vars_info_t
;
96 typedef struct ipa_reference_optimization_summary_d
*ipa_reference_optimization_summary_t
;
98 struct ipa_reference_vars_info_d
100 struct ipa_reference_local_vars_info_d local
;
101 struct ipa_reference_global_vars_info_d global
;
104 typedef struct ipa_reference_vars_info_d
*ipa_reference_vars_info_t
;
106 /* This splay tree contains all of the static variables that are
107 being considered by the compilation level alias analysis. */
108 static splay_tree reference_vars_to_consider
;
110 /* Set of all interesting module statics. A bit is set for every module
111 static we are considering. This is added to the local info when asm
112 code is found that clobbers all memory. */
113 static bitmap all_module_statics
;
115 /* Obstack holding bitmaps of local analysis (live from analysis to
117 static bitmap_obstack local_info_obstack
;
118 /* Obstack holding global analysis live forever. */
119 static bitmap_obstack optimization_summary_obstack
;
121 /* Holders of ipa cgraph hooks: */
122 static struct cgraph_2node_hook_list
*node_duplication_hook_holder
;
123 static struct cgraph_node_hook_list
*node_removal_hook_holder
;
125 /* Vector where the reference var infos are actually stored.
126 Indexed by UID of call graph nodes. */
127 DEF_VEC_P (ipa_reference_vars_info_t
);
128 DEF_VEC_ALLOC_P (ipa_reference_vars_info_t
, heap
);
129 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
,
157 ipa_reference_opt_sum_vector
,
161 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
163 set_reference_vars_info (struct cgraph_node
*node
,
164 ipa_reference_vars_info_t info
)
166 if (!ipa_reference_vars_vector
167 || VEC_length (ipa_reference_vars_info_t
,
168 ipa_reference_vars_vector
) <= (unsigned int) node
->uid
)
169 VEC_safe_grow_cleared (ipa_reference_vars_info_t
, heap
,
170 ipa_reference_vars_vector
, node
->uid
+ 1);
171 VEC_replace (ipa_reference_vars_info_t
, ipa_reference_vars_vector
,
175 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
177 set_reference_optimization_summary (struct cgraph_node
*node
,
178 ipa_reference_optimization_summary_t info
)
180 if (!ipa_reference_opt_sum_vector
181 || (VEC_length (ipa_reference_optimization_summary_t
,
182 ipa_reference_opt_sum_vector
)
183 <= (unsigned int) node
->uid
))
184 VEC_safe_grow_cleared (ipa_reference_optimization_summary_t
,
185 heap
, ipa_reference_opt_sum_vector
, node
->uid
+ 1);
186 VEC_replace (ipa_reference_optimization_summary_t
,
187 ipa_reference_opt_sum_vector
, node
->uid
, info
);
190 /* Return a bitmap indexed by DECL_UID for the static variables that
191 are *not* read during the execution of the function FN. Returns
192 NULL if no data is available. */
195 ipa_reference_get_not_read_global (struct cgraph_node
*fn
)
197 ipa_reference_optimization_summary_t info
=
198 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 for the static variables that
208 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
=
216 get_reference_optimization_summary (fn
);
218 return info
->statics_not_written
;
219 else if (flags_from_decl_or_type (fn
->symbol
.decl
) & ECF_LEAF
)
220 return all_module_statics
;
227 /* Add VAR to all_module_statics and the two
228 reference_vars_to_consider* sets. */
231 add_static_var (tree var
)
233 int uid
= DECL_UID (var
);
234 gcc_assert (TREE_CODE (var
) == VAR_DECL
);
236 splay_tree_insert (reference_vars_to_consider
,
237 uid
, (splay_tree_value
)var
);
238 bitmap_set_bit (all_module_statics
, uid
);
241 /* Return true if the variable T is the right kind of static variable to
242 perform compilation unit scope escape analysis. */
245 is_proper_for_analysis (tree t
)
247 /* If the variable has the "used" attribute, treat it as if it had a
248 been touched by the devil. */
249 if (DECL_PRESERVE_P (t
))
252 /* Do not want to do anything with volatile except mark any
253 function that uses one to be not const or pure. */
254 if (TREE_THIS_VOLATILE (t
))
257 /* We do not need to analyze readonly vars, we already know they do not
259 if (TREE_READONLY (t
))
262 /* This is a variable we care about. Check if we have seen it
263 before, and if not add it the set of variables we care about. */
264 if (all_module_statics
265 && !bitmap_bit_p (all_module_statics
, DECL_UID (t
)))
271 /* Lookup the tree node for the static variable that has UID and
272 convert the name to a string for debugging. */
275 get_static_name (int index
)
277 splay_tree_node stn
=
278 splay_tree_lookup (reference_vars_to_consider
, index
);
279 return fndecl_name ((tree
)(stn
->value
));
282 /* Dump a set of static vars to FILE. */
284 dump_static_vars_set_to_file (FILE *f
, bitmap set
)
290 else if (set
== all_module_statics
)
293 EXECUTE_IF_SET_IN_BITMAP (set
, 0, index
, bi
)
295 fprintf (f
, "%s ", get_static_name (index
));
299 /* Compute X |= Y, taking into account the possibility that
300 either X or Y is already the maximum set.
301 Return true if X is the maximum set after taking the union with Y. */
304 union_static_var_sets (bitmap
&x
, bitmap y
)
306 if (x
!= all_module_statics
)
308 if (y
== all_module_statics
)
311 x
= all_module_statics
;
313 else if (bitmap_ior_into (x
, y
))
315 /* The union may have reduced X to the maximum set.
316 In that case, we want to make that visible explicitly.
317 Even though bitmap_equal_p can be very expensive, it
318 turns out to be an overall win to check this here for
319 an LTO bootstrap of GCC itself. Liberally extrapoliate
320 that result to be applicable to all cases. */
321 if (bitmap_equal_p (x
, all_module_statics
))
324 x
= all_module_statics
;
328 return x
== all_module_statics
;
331 /* Compute X &= Y, taking into account the possibility that
332 X may become the maximum set. */
335 intersect_static_var_sets (bitmap
&x
, bitmap y
)
337 if (x
!= all_module_statics
)
339 bitmap_and_into (x
, y
);
340 /* As with union_static_var_sets, reducing to the maximum
341 set as early as possible is an overall win. */
342 if (bitmap_equal_p (x
, all_module_statics
))
345 x
= all_module_statics
;
348 return x
== all_module_statics
;
351 /* Return a copy of SET on the bitmap obstack containing SET.
352 But if SET is NULL or the maximum set, return that instead. */
355 copy_static_var_set (bitmap set
)
357 if (set
== NULL
|| set
== all_module_statics
)
359 bitmap_obstack
*o
= set
->obstack
;
360 gcc_checking_assert (o
);
361 bitmap copy
= BITMAP_ALLOC (o
);
362 bitmap_copy (copy
, set
);
366 /* Compute the union all of the statics read and written by every callee of X
367 into X_GLOBAL->statics_read and X_GLOBAL->statics_written. X_GLOBAL is
368 actually the set representing the cycle containing X. If the read and
369 written sets of X_GLOBAL has been reduced to the maximum set, we don't
370 have to look at the remaining callees. */
373 propagate_bits (ipa_reference_global_vars_info_t x_global
, struct cgraph_node
*x
)
375 struct cgraph_edge
*e
;
376 bool read_all
= x_global
->statics_read
== all_module_statics
;
377 bool write_all
= x_global
->statics_written
== all_module_statics
;
379 e
&& !(read_all
&& write_all
);
382 enum availability avail
;
383 struct cgraph_node
*y
= cgraph_function_node (e
->callee
, &avail
);
387 /* Only look into nodes we can propagate something. */
388 int flags
= flags_from_decl_or_type (y
->symbol
.decl
);
389 if (avail
> AVAIL_OVERWRITABLE
390 || (avail
== AVAIL_OVERWRITABLE
&& (flags
& ECF_LEAF
)))
392 if (get_reference_vars_info (y
))
394 ipa_reference_vars_info_t y_info
= get_reference_vars_info (y
);
395 ipa_reference_global_vars_info_t y_global
= &y_info
->global
;
397 /* Calls in the current cycle do not have their global set
398 computed yet (but everything else does because we're
399 visiting nodes in topological order). */
400 if (!y_global
->statics_read
)
403 /* If the function is const, it reads no memory even if it
404 seems so to local analysis. */
405 if (flags
& ECF_CONST
)
408 union_static_var_sets (x_global
->statics_read
,
409 y_global
->statics_read
);
411 /* If the function is pure, it has no stores even if it
412 seems so to local analysis. If we cannot return from
413 the function, we can safely ignore the call. */
414 if ((flags
& ECF_PURE
)
415 || cgraph_edge_cannot_lead_to_return (e
))
418 union_static_var_sets (x_global
->statics_written
,
419 y_global
->statics_written
);
427 /* The init routine for analyzing global static variable usage. See
428 comments at top for description. */
432 static bool init_p
= false;
440 reference_vars_to_consider
= splay_tree_new (splay_tree_compare_ints
, 0, 0);
442 bitmap_obstack_initialize (&local_info_obstack
);
443 bitmap_obstack_initialize (&optimization_summary_obstack
);
444 all_module_statics
= BITMAP_ALLOC (&optimization_summary_obstack
);
446 node_removal_hook_holder
=
447 cgraph_add_node_removal_hook (&remove_node_data
, NULL
);
448 node_duplication_hook_holder
=
449 cgraph_add_node_duplication_hook (&duplicate_node_data
, NULL
);
453 /* Set up the persistent info for FN. */
455 static ipa_reference_local_vars_info_t
456 init_function_info (struct cgraph_node
*fn
)
458 ipa_reference_vars_info_t info
459 = XCNEW (struct ipa_reference_vars_info_d
);
461 /* Add the info to the tree's annotation. */
462 set_reference_vars_info (fn
, info
);
464 info
->local
.statics_read
= BITMAP_ALLOC (&local_info_obstack
);
465 info
->local
.statics_written
= BITMAP_ALLOC (&local_info_obstack
);
471 /* This is the main routine for finding the reference patterns for
472 global variables within a function FN. */
475 analyze_function (struct cgraph_node
*fn
)
477 ipa_reference_local_vars_info_t local
;
482 local
= init_function_info (fn
);
483 for (i
= 0; ipa_ref_list_reference_iterate (&fn
->symbol
.ref_list
, i
, ref
); i
++)
485 if (!symtab_variable_p (ref
->referred
))
487 var
= ipa_ref_varpool_node (ref
)->symbol
.decl
;
488 if (!is_proper_for_analysis (var
))
493 bitmap_set_bit (local
->statics_read
, DECL_UID (var
));
496 if (ipa_ref_cannot_lead_to_return (ref
))
498 bitmap_set_bit (local
->statics_written
, DECL_UID (var
));
505 if (cgraph_node_cannot_return (fn
))
506 bitmap_clear (local
->statics_written
);
510 /* Called when new clone is inserted to callgraph late. */
513 duplicate_node_data (struct cgraph_node
*src
, struct cgraph_node
*dst
,
514 void *data ATTRIBUTE_UNUSED
)
516 ipa_reference_optimization_summary_t ginfo
;
517 ipa_reference_optimization_summary_t dst_ginfo
;
519 ginfo
= get_reference_optimization_summary (src
);
522 dst_ginfo
= XCNEW (struct ipa_reference_optimization_summary_d
);
523 set_reference_optimization_summary (dst
, dst_ginfo
);
524 dst_ginfo
->statics_not_read
=
525 copy_static_var_set (ginfo
->statics_not_read
);
526 dst_ginfo
->statics_not_written
=
527 copy_static_var_set (ginfo
->statics_not_written
);
530 /* Called when node is removed. */
533 remove_node_data (struct cgraph_node
*node
, void *data ATTRIBUTE_UNUSED
)
535 ipa_reference_optimization_summary_t ginfo
;
536 ginfo
= get_reference_optimization_summary (node
);
539 if (ginfo
->statics_not_read
540 && ginfo
->statics_not_read
!= all_module_statics
)
541 BITMAP_FREE (ginfo
->statics_not_read
);
543 if (ginfo
->statics_not_written
544 && ginfo
->statics_not_written
!= all_module_statics
)
545 BITMAP_FREE (ginfo
->statics_not_written
);
547 set_reference_optimization_summary (node
, NULL
);
551 /* Analyze each function in the cgraph to see which global or statics
552 are read or written. */
555 generate_summary (void)
557 struct cgraph_node
*node
;
563 /* Process all of the functions next. */
564 FOR_EACH_DEFINED_FUNCTION (node
)
565 analyze_function (node
);
568 EXECUTE_IF_SET_IN_BITMAP (all_module_statics
, 0, index
, bi
)
570 fprintf (dump_file
, "\nPromotable global:%s (uid=%u)\n",
571 get_static_name (index
), index
);
575 FOR_EACH_DEFINED_FUNCTION (node
)
576 if (cgraph_function_body_availability (node
) >= AVAIL_OVERWRITABLE
)
578 ipa_reference_local_vars_info_t l
;
582 l
= &get_reference_vars_info (node
)->local
;
584 "\nFunction name:%s/%i:",
585 cgraph_node_asm_name (node
), node
->symbol
.order
);
586 fprintf (dump_file
, "\n locals read: ");
588 EXECUTE_IF_SET_IN_BITMAP (l
->statics_read
,
591 fprintf (dump_file
, "%s ",
592 get_static_name (index
));
594 fprintf (dump_file
, "\n locals written: ");
595 if (l
->statics_written
)
596 EXECUTE_IF_SET_IN_BITMAP (l
->statics_written
,
599 fprintf(dump_file
, "%s ",
600 get_static_name (index
));
605 /* Set READ_ALL/WRITE_ALL based on decl flags of NODE. */
608 read_write_all_from_decl (struct cgraph_node
*node
,
609 bool &read_all
, bool &write_all
)
611 tree decl
= node
->symbol
.decl
;
612 int flags
= flags_from_decl_or_type (decl
);
613 if ((flags
& ECF_LEAF
)
614 && cgraph_function_body_availability (node
) <= AVAIL_OVERWRITABLE
)
616 else if (flags
& ECF_CONST
)
618 else if ((flags
& ECF_PURE
)
619 || cgraph_node_cannot_return (node
))
622 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
623 fprintf (dump_file
, " %s/%i -> read all\n",
624 cgraph_node_asm_name (node
), node
->symbol
.order
);
628 /* TODO: To be able to produce sane results, we should also handle
629 common builtins, in particular throw. */
632 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
633 fprintf (dump_file
, " %s/%i -> read all, write all\n",
634 cgraph_node_asm_name (node
), node
->symbol
.order
);
638 /* Set READ_ALL/WRITE_ALL based on decl flags of NODE or any member
639 in the cycle of NODE. */
642 get_read_write_all_from_node (struct cgraph_node
*node
,
643 bool &read_all
, bool &write_all
)
645 struct cgraph_edge
*e
, *ie
;
647 /* When function is overwritable, we can not assume anything. */
648 if (cgraph_function_body_availability (node
) <= AVAIL_OVERWRITABLE
)
649 read_write_all_from_decl (node
, read_all
, write_all
);
651 for (e
= node
->callees
;
652 e
&& !(read_all
&& write_all
);
655 enum availability avail
;
656 struct cgraph_node
*callee
= cgraph_function_node (e
->callee
, &avail
);
657 gcc_checking_assert (callee
);
658 if (avail
<= AVAIL_OVERWRITABLE
)
659 read_write_all_from_decl (callee
, read_all
, write_all
);
662 for (ie
= node
->indirect_calls
;
663 ie
&& !(read_all
&& write_all
);
664 ie
= ie
->next_callee
)
665 if (!(ie
->indirect_info
->ecf_flags
& ECF_CONST
))
668 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
669 fprintf (dump_file
, " indirect call -> read all\n");
670 if (!cgraph_edge_cannot_lead_to_return (ie
)
671 && !(ie
->indirect_info
->ecf_flags
& ECF_PURE
))
673 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
674 fprintf (dump_file
, " indirect call -> write all\n");
680 /* Produce the global information by preforming a transitive closure
681 on the local information that was produced by ipa_analyze_function. */
686 struct cgraph_node
*node
;
687 struct varpool_node
*vnode
;
688 struct cgraph_node
**order
=
689 XCNEWVEC (struct cgraph_node
*, cgraph_n_nodes
);
694 dump_cgraph (dump_file
);
696 ipa_discover_readonly_nonaddressable_vars ();
699 /* Now we know what vars are really statics; prune out those that aren't. */
700 FOR_EACH_VARIABLE (vnode
)
701 if (vnode
->symbol
.externally_visible
702 || TREE_ADDRESSABLE (vnode
->symbol
.decl
)
703 || TREE_READONLY (vnode
->symbol
.decl
)
704 || !is_proper_for_analysis (vnode
->symbol
.decl
)
706 bitmap_clear_bit (all_module_statics
, DECL_UID (vnode
->symbol
.decl
));
708 /* Forget info we collected "just for fun" on variables that turned out to be
710 FOR_EACH_DEFINED_FUNCTION (node
)
712 ipa_reference_local_vars_info_t node_l
;
713 node_l
= &get_reference_vars_info (node
)->local
;
714 intersect_static_var_sets (node_l
->statics_read
, all_module_statics
);
715 intersect_static_var_sets (node_l
->statics_written
, all_module_statics
);
718 /* Propagate the local information through the call graph to produce
719 the global information. All the nodes within a cycle will have
720 the same info so we collapse cycles first. Then we can do the
721 propagation in one pass from the leaves to the roots. */
722 order_pos
= ipa_reduced_postorder (order
, true, true, NULL
);
724 ipa_print_order (dump_file
, "reduced", order
, order_pos
);
726 for (i
= 0; i
< order_pos
; i
++ )
729 struct cgraph_node
*w
;
730 ipa_reference_vars_info_t node_info
;
731 ipa_reference_global_vars_info_t node_g
;
732 ipa_reference_local_vars_info_t node_l
;
733 bool read_all
= false;
734 bool write_all
= false;
740 node_info
= get_reference_vars_info (node
);
741 gcc_assert (node_info
);
742 node_l
= &node_info
->local
;
743 node_g
= &node_info
->global
;
745 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
746 fprintf (dump_file
, "Starting cycle with %s/%i\n",
747 cgraph_node_asm_name (node
), node
->symbol
.order
);
749 VEC (cgraph_node_p
, heap
) *cycle_nodes
= ipa_get_nodes_in_cycle (node
);
751 /* If any node in a cycle is read_all or write_all, they all are. */
752 FOR_EACH_VEC_ELT (cgraph_node_p
, cycle_nodes
, x
, w
)
754 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
755 fprintf (dump_file
, " Visiting %s/%i\n",
756 cgraph_node_asm_name (w
), w
->symbol
.order
);
757 get_read_write_all_from_node (w
, read_all
, write_all
);
758 if (read_all
&& write_all
)
762 /* Initialized the bitmaps global sets for the reduced node. */
764 node_g
->statics_read
= all_module_statics
;
766 node_g
->statics_read
= copy_static_var_set (node_l
->statics_read
);
768 node_g
->statics_written
= all_module_statics
;
770 node_g
->statics_written
= copy_static_var_set (node_l
->statics_written
);
772 /* Merge the sets of this cycle with all sets of callees reached
774 FOR_EACH_VEC_ELT (cgraph_node_p
, cycle_nodes
, x
, w
)
776 if (read_all
&& write_all
)
781 ipa_reference_vars_info_t w_ri
= get_reference_vars_info (w
);
782 ipa_reference_local_vars_info_t w_l
= &w_ri
->local
;
783 int flags
= flags_from_decl_or_type (w
->symbol
.decl
);
785 if (!(flags
& ECF_CONST
))
786 read_all
= union_static_var_sets (node_g
->statics_read
,
788 if (!(flags
& ECF_PURE
)
789 && !cgraph_node_cannot_return (w
))
790 write_all
= union_static_var_sets (node_g
->statics_written
,
791 w_l
->statics_written
);
794 propagate_bits (node_g
, w
);
797 /* All nodes within a cycle have the same global info bitmaps. */
798 FOR_EACH_VEC_ELT (cgraph_node_p
, cycle_nodes
, x
, w
)
800 ipa_reference_vars_info_t w_ri
= get_reference_vars_info (w
);
801 w_ri
->global
= *node_g
;
804 VEC_free (cgraph_node_p
, heap
, cycle_nodes
);
809 for (i
= 0; i
< order_pos
; i
++)
812 struct cgraph_node
*w
;
819 "\nFunction name:%s/%i:",
820 cgraph_node_asm_name (node
), node
->symbol
.order
);
822 ipa_reference_vars_info_t node_info
= get_reference_vars_info (node
);
823 ipa_reference_global_vars_info_t node_g
= &node_info
->global
;
825 VEC (cgraph_node_p
, heap
) *cycle_nodes
= ipa_get_nodes_in_cycle (node
);
826 FOR_EACH_VEC_ELT (cgraph_node_p
, cycle_nodes
, x
, w
)
828 ipa_reference_vars_info_t w_ri
= get_reference_vars_info (w
);
829 ipa_reference_local_vars_info_t w_l
= &w_ri
->local
;
831 fprintf (dump_file
, "\n next cycle: %s/%i ",
832 cgraph_node_asm_name (w
), w
->symbol
.order
);
833 fprintf (dump_file
, "\n locals read: ");
834 dump_static_vars_set_to_file (dump_file
, w_l
->statics_read
);
835 fprintf (dump_file
, "\n locals written: ");
836 dump_static_vars_set_to_file (dump_file
, w_l
->statics_written
);
838 VEC_free (cgraph_node_p
, heap
, cycle_nodes
);
840 fprintf (dump_file
, "\n globals read: ");
841 dump_static_vars_set_to_file (dump_file
, node_g
->statics_read
);
842 fprintf (dump_file
, "\n globals written: ");
843 dump_static_vars_set_to_file (dump_file
, node_g
->statics_written
);
844 fprintf (dump_file
, "\n");
849 FOR_EACH_DEFINED_FUNCTION (node
)
851 ipa_reference_vars_info_t node_info
;
852 ipa_reference_global_vars_info_t node_g
;
853 ipa_reference_optimization_summary_t opt
;
858 node_info
= get_reference_vars_info (node
);
859 if (cgraph_function_body_availability (node
) > AVAIL_OVERWRITABLE
860 || (flags_from_decl_or_type (node
->symbol
.decl
) & ECF_LEAF
))
862 node_g
= &node_info
->global
;
864 opt
= XCNEW (struct ipa_reference_optimization_summary_d
);
865 set_reference_optimization_summary (node
, opt
);
867 /* Create the complimentary sets. */
869 if (bitmap_empty_p (node_g
->statics_read
))
870 opt
->statics_not_read
= all_module_statics
;
873 opt
->statics_not_read
874 = BITMAP_ALLOC (&optimization_summary_obstack
);
875 if (node_g
->statics_read
!= all_module_statics
)
876 bitmap_and_compl (opt
->statics_not_read
,
878 node_g
->statics_read
);
881 if (bitmap_empty_p (node_g
->statics_written
))
882 opt
->statics_not_written
= all_module_statics
;
885 opt
->statics_not_written
886 = BITMAP_ALLOC (&optimization_summary_obstack
);
887 if (node_g
->statics_written
!= all_module_statics
)
888 bitmap_and_compl (opt
->statics_not_written
,
890 node_g
->statics_written
);
896 ipa_free_postorder_info ();
899 bitmap_obstack_release (&local_info_obstack
);
900 VEC_free (ipa_reference_vars_info_t
, heap
, ipa_reference_vars_vector
);
901 ipa_reference_vars_vector
= NULL
;
903 splay_tree_delete (reference_vars_to_consider
);
904 reference_vars_to_consider
= NULL
;
908 /* Return true if we need to write summary of NODE. */
911 write_node_summary_p (struct cgraph_node
*node
,
912 lto_symtab_encoder_t encoder
,
913 bitmap ltrans_statics
)
915 ipa_reference_optimization_summary_t info
;
917 /* See if we have (non-empty) info. */
918 if (!node
->analyzed
|| node
->global
.inlined_to
)
920 info
= get_reference_optimization_summary (node
);
921 if (!info
|| (bitmap_empty_p (info
->statics_not_read
)
922 && bitmap_empty_p (info
->statics_not_written
)))
925 /* See if we want to encode it.
926 Encode also referenced functions since constant folding might turn it into
929 In future we might also want to include summaries of functions references
930 by initializers of constant variables references in current unit. */
931 if (!reachable_from_this_partition_p (node
, encoder
)
932 && !referenced_from_this_partition_p (&node
->symbol
.ref_list
, encoder
))
935 /* See if the info has non-empty intersections with vars we want to encode. */
936 if (!bitmap_intersect_p (info
->statics_not_read
, ltrans_statics
)
937 && !bitmap_intersect_p (info
->statics_not_written
, ltrans_statics
))
942 /* Stream out BITS<RANS_STATICS as list of decls to OB.
943 LTRANS_STATICS_BITCOUNT specify number of bits in LTRANS_STATICS
944 or -1. When it is positive, just output -1 when
945 BITS<RANS_STATICS == BITS<RANS_STATICS. */
948 stream_out_bitmap (struct lto_simple_output_block
*ob
,
949 bitmap bits
, bitmap ltrans_statics
,
950 int ltrans_statics_bitcount
)
955 if (bits
== all_module_statics
)
957 streamer_write_hwi_stream (ob
->main_stream
, -1);
960 EXECUTE_IF_AND_IN_BITMAP (bits
, ltrans_statics
, 0, index
, bi
)
962 if (count
== ltrans_statics_bitcount
)
964 streamer_write_hwi_stream (ob
->main_stream
, -1);
967 streamer_write_hwi_stream (ob
->main_stream
, count
);
970 EXECUTE_IF_AND_IN_BITMAP (bits
, ltrans_statics
, 0, index
, bi
)
972 tree decl
= (tree
)splay_tree_lookup (reference_vars_to_consider
, index
)->value
;
973 lto_output_var_decl_index(ob
->decl_state
, ob
->main_stream
, decl
);
977 /* Serialize the ipa info for lto. */
980 ipa_reference_write_optimization_summary (void)
982 struct cgraph_node
*node
;
984 struct lto_simple_output_block
*ob
985 = lto_create_simple_output_block (LTO_section_ipa_reference
);
986 unsigned int count
= 0;
987 int ltrans_statics_bitcount
= 0;
988 lto_symtab_encoder_t encoder
= ob
->decl_state
->symtab_node_encoder
;
989 bitmap ltrans_statics
= BITMAP_ALLOC (NULL
);
992 reference_vars_to_consider
= splay_tree_new (splay_tree_compare_ints
, 0, 0);
994 /* See what variables we are interested in. */
995 for (i
= 0; i
< lto_symtab_encoder_size (encoder
); i
++)
997 struct varpool_node
*vnode
;
998 snode
= lto_symtab_encoder_deref (encoder
, i
);
999 if (!symtab_variable_p (snode
))
1001 vnode
= varpool (snode
);
1002 if (bitmap_bit_p (all_module_statics
, DECL_UID (vnode
->symbol
.decl
))
1003 && referenced_from_this_partition_p (&vnode
->symbol
.ref_list
, encoder
))
1005 tree decl
= vnode
->symbol
.decl
;
1006 bitmap_set_bit (ltrans_statics
, DECL_UID (decl
));
1007 splay_tree_insert (reference_vars_to_consider
,
1008 DECL_UID (decl
), (splay_tree_value
)decl
);
1009 ltrans_statics_bitcount
++;
1014 if (ltrans_statics_bitcount
)
1015 for (i
= 0; i
< lto_symtab_encoder_size (encoder
); i
++)
1016 if (symtab_function_p (snode
= lto_symtab_encoder_deref (encoder
, i
))
1017 && write_node_summary_p (cgraph (snode
),
1018 encoder
, ltrans_statics
))
1021 streamer_write_uhwi_stream (ob
->main_stream
, count
);
1023 stream_out_bitmap (ob
, ltrans_statics
, ltrans_statics
,
1026 /* Process all of the functions. */
1027 if (ltrans_statics_bitcount
)
1028 for (i
= 0; i
< lto_symtab_encoder_size (encoder
); i
++)
1030 snode
= lto_symtab_encoder_deref (encoder
, i
);
1031 if (!symtab_function_p (snode
))
1033 node
= cgraph (snode
);
1034 if (write_node_summary_p (node
, encoder
, ltrans_statics
))
1036 ipa_reference_optimization_summary_t info
;
1039 info
= get_reference_optimization_summary (node
);
1040 node_ref
= lto_symtab_encoder_encode (encoder
, (symtab_node
) node
);
1041 streamer_write_uhwi_stream (ob
->main_stream
, node_ref
);
1043 stream_out_bitmap (ob
, info
->statics_not_read
, ltrans_statics
,
1044 ltrans_statics_bitcount
);
1045 stream_out_bitmap (ob
, info
->statics_not_written
, ltrans_statics
,
1046 ltrans_statics_bitcount
);
1049 BITMAP_FREE (ltrans_statics
);
1050 lto_destroy_simple_output_block (ob
);
1051 splay_tree_delete (reference_vars_to_consider
);
1054 /* Deserialize the ipa info for lto. */
1057 ipa_reference_read_optimization_summary (void)
1059 struct lto_file_decl_data
** file_data_vec
1060 = lto_get_file_decl_data ();
1061 struct lto_file_decl_data
* file_data
;
1063 bitmap_obstack_initialize (&optimization_summary_obstack
);
1065 node_removal_hook_holder
=
1066 cgraph_add_node_removal_hook (&remove_node_data
, NULL
);
1067 node_duplication_hook_holder
=
1068 cgraph_add_node_duplication_hook (&duplicate_node_data
, NULL
);
1069 all_module_statics
= BITMAP_ALLOC (&optimization_summary_obstack
);
1071 while ((file_data
= file_data_vec
[j
++]))
1075 struct lto_input_block
*ib
1076 = lto_create_simple_input_block (file_data
,
1077 LTO_section_ipa_reference
,
1082 unsigned int f_count
= streamer_read_uhwi (ib
);
1086 b_count
= streamer_read_hwi (ib
);
1088 fprintf (dump_file
, "all module statics:");
1089 for (i
= 0; i
< (unsigned int)b_count
; i
++)
1091 unsigned int var_index
= streamer_read_uhwi (ib
);
1092 tree v_decl
= lto_file_decl_data_get_var_decl (file_data
,
1094 bitmap_set_bit (all_module_statics
, DECL_UID (v_decl
));
1096 fprintf (dump_file
, " %s", fndecl_name (v_decl
));
1099 for (i
= 0; i
< f_count
; i
++)
1101 unsigned int j
, index
;
1102 struct cgraph_node
*node
;
1103 ipa_reference_optimization_summary_t info
;
1105 lto_symtab_encoder_t encoder
;
1107 index
= streamer_read_uhwi (ib
);
1108 encoder
= file_data
->symtab_node_encoder
;
1109 node
= cgraph (lto_symtab_encoder_deref (encoder
, index
));
1110 info
= XCNEW (struct ipa_reference_optimization_summary_d
);
1111 set_reference_optimization_summary (node
, info
);
1112 info
->statics_not_read
= BITMAP_ALLOC (&optimization_summary_obstack
);
1113 info
->statics_not_written
= BITMAP_ALLOC (&optimization_summary_obstack
);
1116 "\nFunction name:%s/%i:\n static not read:",
1117 cgraph_node_asm_name (node
), node
->symbol
.order
);
1119 /* Set the statics not read. */
1120 v_count
= streamer_read_hwi (ib
);
1123 info
->statics_not_read
= all_module_statics
;
1125 fprintf (dump_file
, " all module statics");
1128 for (j
= 0; j
< (unsigned int)v_count
; j
++)
1130 unsigned int var_index
= streamer_read_uhwi (ib
);
1131 tree v_decl
= lto_file_decl_data_get_var_decl (file_data
,
1133 bitmap_set_bit (info
->statics_not_read
, DECL_UID (v_decl
));
1135 fprintf (dump_file
, " %s", fndecl_name (v_decl
));
1140 "\n static not written:");
1141 /* Set the statics not written. */
1142 v_count
= streamer_read_hwi (ib
);
1145 info
->statics_not_written
= all_module_statics
;
1147 fprintf (dump_file
, " all module statics");
1150 for (j
= 0; j
< (unsigned int)v_count
; j
++)
1152 unsigned int var_index
= streamer_read_uhwi (ib
);
1153 tree v_decl
= lto_file_decl_data_get_var_decl (file_data
,
1155 bitmap_set_bit (info
->statics_not_written
, DECL_UID (v_decl
));
1157 fprintf (dump_file
, " %s", fndecl_name (v_decl
));
1160 fprintf (dump_file
, "\n");
1163 lto_destroy_simple_input_block (file_data
,
1164 LTO_section_ipa_reference
,
1168 /* Fatal error here. We do not want to support compiling ltrans units with
1169 different version of compiler or different flags than the WPA unit, so
1170 this should never happen. */
1171 fatal_error ("ipa reference summary is missing in ltrans unit");
1176 gate_reference (void)
1178 return (flag_ipa_reference
1179 /* Don't bother doing anything if the program has errors. */
1183 struct ipa_opt_pass_d pass_ipa_reference
=
1187 "static-var", /* name */
1188 gate_reference
, /* gate */
1189 propagate
, /* execute */
1192 0, /* static_pass_number */
1193 TV_IPA_REFERENCE
, /* tv_id */
1194 0, /* properties_required */
1195 0, /* properties_provided */
1196 0, /* properties_destroyed */
1197 0, /* todo_flags_start */
1198 0 /* todo_flags_finish */
1200 NULL
, /* generate_summary */
1201 NULL
, /* write_summary */
1202 NULL
, /* read_summary */
1203 ipa_reference_write_optimization_summary
,/* write_optimization_summary */
1204 ipa_reference_read_optimization_summary
,/* read_optimization_summary */
1205 NULL
, /* stmt_fixup */
1207 NULL
, /* function_transform */
1208 NULL
/* variable_transform */