1 /* Callgraph based analysis of static variables.
2 Copyright (C) 2004-2013 Free Software Foundation, Inc.
3 Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 /* This file gathers information about how variables whose scope is
22 confined to the compilation unit are used.
24 The transitive call site specific clobber effects are computed
25 for the variables whose scope is contained within this compilation
28 First each function and static variable initialization is analyzed
29 to determine which local static variables are either read, written,
30 or have their address taken. Any local static that has its address
31 taken is removed from consideration. Once the local read and
32 writes are determined, a transitive closure of this information is
33 performed over the call graph to determine the worst case set of
34 side effects of each call. In later parts of the compiler, these
35 local and global sets are examined to make the call clobbering less
36 traumatic, promote some statics to registers, and improve aliasing
41 #include "coretypes.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"
54 #include "diagnostic.h"
55 #include "data-streamer.h"
56 #include "lto-streamer.h"
58 static void remove_node_data (struct cgraph_node
*node
,
59 void *data ATTRIBUTE_UNUSED
);
60 static void duplicate_node_data (struct cgraph_node
*src
,
61 struct cgraph_node
*dst
,
62 void *data ATTRIBUTE_UNUSED
);
64 /* The static variables defined within the compilation unit that are
65 loaded or stored directly by function that owns this structure. */
67 struct ipa_reference_local_vars_info_d
70 bitmap statics_written
;
73 /* Statics that are read and written by some set of functions. The
74 local ones are based on the loads and stores local to the function.
75 The global ones are based on the local info as well as the
76 transitive closure of the functions that are called. */
78 struct ipa_reference_global_vars_info_d
81 bitmap statics_written
;
84 /* Information we save about every function after ipa-reference is completed. */
86 struct ipa_reference_optimization_summary_d
88 bitmap statics_not_read
;
89 bitmap statics_not_written
;
92 typedef struct ipa_reference_local_vars_info_d
*ipa_reference_local_vars_info_t
;
93 typedef struct ipa_reference_global_vars_info_d
*ipa_reference_global_vars_info_t
;
94 typedef struct ipa_reference_optimization_summary_d
*ipa_reference_optimization_summary_t
;
96 struct ipa_reference_vars_info_d
98 struct ipa_reference_local_vars_info_d local
;
99 struct ipa_reference_global_vars_info_d global
;
102 typedef struct ipa_reference_vars_info_d
*ipa_reference_vars_info_t
;
104 /* This splay tree contains all of the static variables that are
105 being considered by the compilation level alias analysis. */
106 static splay_tree reference_vars_to_consider
;
108 /* Set of all interesting module statics. A bit is set for every module
109 static we are considering. This is added to the local info when asm
110 code is found that clobbers all memory. */
111 static bitmap all_module_statics
;
113 /* Obstack holding bitmaps of local analysis (live from analysis to
115 static bitmap_obstack local_info_obstack
;
116 /* Obstack holding global analysis live forever. */
117 static bitmap_obstack optimization_summary_obstack
;
119 /* Holders of ipa cgraph hooks: */
120 static struct cgraph_2node_hook_list
*node_duplication_hook_holder
;
121 static struct cgraph_node_hook_list
*node_removal_hook_holder
;
123 /* Vector where the reference var infos are actually stored.
124 Indexed by UID of call graph nodes. */
125 static vec
<ipa_reference_vars_info_t
> ipa_reference_vars_vector
;
127 static vec
<ipa_reference_optimization_summary_t
> ipa_reference_opt_sum_vector
;
129 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
130 static inline ipa_reference_vars_info_t
131 get_reference_vars_info (struct cgraph_node
*node
)
133 if (!ipa_reference_vars_vector
.exists ()
134 || ipa_reference_vars_vector
.length () <= (unsigned int) node
->uid
)
136 return ipa_reference_vars_vector
[node
->uid
];
139 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
140 static inline ipa_reference_optimization_summary_t
141 get_reference_optimization_summary (struct cgraph_node
*node
)
143 if (!ipa_reference_opt_sum_vector
.exists ()
144 || (ipa_reference_opt_sum_vector
.length () <= (unsigned int) node
->uid
))
146 return ipa_reference_opt_sum_vector
[node
->uid
];
149 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
151 set_reference_vars_info (struct cgraph_node
*node
,
152 ipa_reference_vars_info_t info
)
154 if (!ipa_reference_vars_vector
.exists ()
155 || ipa_reference_vars_vector
.length () <= (unsigned int) node
->uid
)
156 ipa_reference_vars_vector
.safe_grow_cleared (node
->uid
+ 1);
157 ipa_reference_vars_vector
[node
->uid
] = info
;
160 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
162 set_reference_optimization_summary (struct cgraph_node
*node
,
163 ipa_reference_optimization_summary_t info
)
165 if (!ipa_reference_opt_sum_vector
.exists ()
166 || (ipa_reference_opt_sum_vector
.length () <= (unsigned int) node
->uid
))
167 ipa_reference_opt_sum_vector
.safe_grow_cleared (node
->uid
+ 1);
168 ipa_reference_opt_sum_vector
[node
->uid
] = info
;
171 /* Return a bitmap indexed by DECL_UID for the static variables that
172 are *not* read during the execution of the function FN. Returns
173 NULL if no data is available. */
176 ipa_reference_get_not_read_global (struct cgraph_node
*fn
)
178 ipa_reference_optimization_summary_t info
=
179 get_reference_optimization_summary (cgraph_function_node (fn
, NULL
));
181 return info
->statics_not_read
;
182 else if (flags_from_decl_or_type (fn
->decl
) & ECF_LEAF
)
183 return all_module_statics
;
188 /* Return a bitmap indexed by DECL_UID for the static variables that
189 are *not* written during the execution of the function FN. Note
190 that variables written may or may not be read during the function
191 call. Returns NULL if no data is available. */
194 ipa_reference_get_not_written_global (struct cgraph_node
*fn
)
196 ipa_reference_optimization_summary_t info
=
197 get_reference_optimization_summary (fn
);
199 return info
->statics_not_written
;
200 else if (flags_from_decl_or_type (fn
->decl
) & ECF_LEAF
)
201 return all_module_statics
;
208 /* Add VAR to all_module_statics and the two
209 reference_vars_to_consider* sets. */
212 add_static_var (tree var
)
214 int uid
= DECL_UID (var
);
215 gcc_assert (TREE_CODE (var
) == VAR_DECL
);
217 splay_tree_insert (reference_vars_to_consider
,
218 uid
, (splay_tree_value
)var
);
219 bitmap_set_bit (all_module_statics
, uid
);
222 /* Return true if the variable T is the right kind of static variable to
223 perform compilation unit scope escape analysis. */
226 is_proper_for_analysis (tree t
)
228 /* If the variable has the "used" attribute, treat it as if it had a
229 been touched by the devil. */
230 if (DECL_PRESERVE_P (t
))
233 /* Do not want to do anything with volatile except mark any
234 function that uses one to be not const or pure. */
235 if (TREE_THIS_VOLATILE (t
))
238 /* We do not need to analyze readonly vars, we already know they do not
240 if (TREE_READONLY (t
))
243 /* This is a variable we care about. Check if we have seen it
244 before, and if not add it the set of variables we care about. */
245 if (all_module_statics
246 && !bitmap_bit_p (all_module_statics
, DECL_UID (t
)))
252 /* Lookup the tree node for the static variable that has UID and
253 convert the name to a string for debugging. */
256 get_static_name (int index
)
258 splay_tree_node stn
=
259 splay_tree_lookup (reference_vars_to_consider
, index
);
260 return fndecl_name ((tree
)(stn
->value
));
263 /* Dump a set of static vars to FILE. */
265 dump_static_vars_set_to_file (FILE *f
, bitmap set
)
271 else if (set
== all_module_statics
)
274 EXECUTE_IF_SET_IN_BITMAP (set
, 0, index
, bi
)
276 fprintf (f
, "%s ", get_static_name (index
));
280 /* Compute X |= Y, taking into account the possibility that
281 either X or Y is already the maximum set.
282 Return true if X is the maximum set after taking the union with Y. */
285 union_static_var_sets (bitmap
&x
, bitmap y
)
287 if (x
!= all_module_statics
)
289 if (y
== all_module_statics
)
292 x
= all_module_statics
;
294 else if (bitmap_ior_into (x
, y
))
296 /* The union may have reduced X to the maximum set.
297 In that case, we want to make that visible explicitly.
298 Even though bitmap_equal_p can be very expensive, it
299 turns out to be an overall win to check this here for
300 an LTO bootstrap of GCC itself. Liberally extrapoliate
301 that result to be applicable to all cases. */
302 if (bitmap_equal_p (x
, all_module_statics
))
305 x
= all_module_statics
;
309 return x
== all_module_statics
;
312 /* Compute X &= Y, taking into account the possibility that
313 X may become the maximum set. */
316 intersect_static_var_sets (bitmap
&x
, bitmap y
)
318 if (x
!= all_module_statics
)
320 bitmap_and_into (x
, y
);
321 /* As with union_static_var_sets, reducing to the maximum
322 set as early as possible is an overall win. */
323 if (bitmap_equal_p (x
, all_module_statics
))
326 x
= all_module_statics
;
329 return x
== all_module_statics
;
332 /* Return a copy of SET on the bitmap obstack containing SET.
333 But if SET is NULL or the maximum set, return that instead. */
336 copy_static_var_set (bitmap set
)
338 if (set
== NULL
|| set
== all_module_statics
)
340 bitmap_obstack
*o
= set
->obstack
;
341 gcc_checking_assert (o
);
342 bitmap copy
= BITMAP_ALLOC (o
);
343 bitmap_copy (copy
, set
);
347 /* Compute the union all of the statics read and written by every callee of X
348 into X_GLOBAL->statics_read and X_GLOBAL->statics_written. X_GLOBAL is
349 actually the set representing the cycle containing X. If the read and
350 written sets of X_GLOBAL has been reduced to the maximum set, we don't
351 have to look at the remaining callees. */
354 propagate_bits (ipa_reference_global_vars_info_t x_global
, struct cgraph_node
*x
)
356 struct cgraph_edge
*e
;
357 bool read_all
= x_global
->statics_read
== all_module_statics
;
358 bool write_all
= x_global
->statics_written
== all_module_statics
;
360 e
&& !(read_all
&& write_all
);
363 enum availability avail
;
364 struct cgraph_node
*y
= cgraph_function_node (e
->callee
, &avail
);
368 /* Only look into nodes we can propagate something. */
369 int flags
= flags_from_decl_or_type (y
->decl
);
370 if (avail
> AVAIL_OVERWRITABLE
371 || (avail
== AVAIL_OVERWRITABLE
&& (flags
& ECF_LEAF
)))
373 if (get_reference_vars_info (y
))
375 ipa_reference_vars_info_t y_info
= get_reference_vars_info (y
);
376 ipa_reference_global_vars_info_t y_global
= &y_info
->global
;
378 /* Calls in the current cycle do not have their global set
379 computed yet (but everything else does because we're
380 visiting nodes in topological order). */
381 if (!y_global
->statics_read
)
384 /* If the function is const, it reads no memory even if it
385 seems so to local analysis. */
386 if (flags
& ECF_CONST
)
389 union_static_var_sets (x_global
->statics_read
,
390 y_global
->statics_read
);
392 /* If the function is pure, it has no stores even if it
393 seems so to local analysis. If we cannot return from
394 the function, we can safely ignore the call. */
395 if ((flags
& ECF_PURE
)
396 || cgraph_edge_cannot_lead_to_return (e
))
399 union_static_var_sets (x_global
->statics_written
,
400 y_global
->statics_written
);
408 /* The init routine for analyzing global static variable usage. See
409 comments at top for description. */
413 static bool init_p
= false;
421 reference_vars_to_consider
= splay_tree_new (splay_tree_compare_ints
, 0, 0);
423 bitmap_obstack_initialize (&local_info_obstack
);
424 bitmap_obstack_initialize (&optimization_summary_obstack
);
425 all_module_statics
= BITMAP_ALLOC (&optimization_summary_obstack
);
427 node_removal_hook_holder
=
428 cgraph_add_node_removal_hook (&remove_node_data
, NULL
);
429 node_duplication_hook_holder
=
430 cgraph_add_node_duplication_hook (&duplicate_node_data
, NULL
);
434 /* Set up the persistent info for FN. */
436 static ipa_reference_local_vars_info_t
437 init_function_info (struct cgraph_node
*fn
)
439 ipa_reference_vars_info_t info
440 = XCNEW (struct ipa_reference_vars_info_d
);
442 /* Add the info to the tree's annotation. */
443 set_reference_vars_info (fn
, info
);
445 info
->local
.statics_read
= BITMAP_ALLOC (&local_info_obstack
);
446 info
->local
.statics_written
= BITMAP_ALLOC (&local_info_obstack
);
452 /* This is the main routine for finding the reference patterns for
453 global variables within a function FN. */
456 analyze_function (struct cgraph_node
*fn
)
458 ipa_reference_local_vars_info_t local
;
463 local
= init_function_info (fn
);
464 for (i
= 0; ipa_ref_list_reference_iterate (&fn
->ref_list
, i
, ref
); i
++)
466 if (!is_a
<varpool_node
> (ref
->referred
))
468 var
= ipa_ref_varpool_node (ref
)->decl
;
469 if (!is_proper_for_analysis (var
))
474 bitmap_set_bit (local
->statics_read
, DECL_UID (var
));
477 if (ipa_ref_cannot_lead_to_return (ref
))
479 bitmap_set_bit (local
->statics_written
, DECL_UID (var
));
486 if (cgraph_node_cannot_return (fn
))
487 bitmap_clear (local
->statics_written
);
491 /* Called when new clone is inserted to callgraph late. */
494 duplicate_node_data (struct cgraph_node
*src
, struct cgraph_node
*dst
,
495 void *data ATTRIBUTE_UNUSED
)
497 ipa_reference_optimization_summary_t ginfo
;
498 ipa_reference_optimization_summary_t dst_ginfo
;
500 ginfo
= get_reference_optimization_summary (src
);
503 dst_ginfo
= XCNEW (struct ipa_reference_optimization_summary_d
);
504 set_reference_optimization_summary (dst
, dst_ginfo
);
505 dst_ginfo
->statics_not_read
=
506 copy_static_var_set (ginfo
->statics_not_read
);
507 dst_ginfo
->statics_not_written
=
508 copy_static_var_set (ginfo
->statics_not_written
);
511 /* Called when node is removed. */
514 remove_node_data (struct cgraph_node
*node
, void *data ATTRIBUTE_UNUSED
)
516 ipa_reference_optimization_summary_t ginfo
;
517 ginfo
= get_reference_optimization_summary (node
);
520 if (ginfo
->statics_not_read
521 && ginfo
->statics_not_read
!= all_module_statics
)
522 BITMAP_FREE (ginfo
->statics_not_read
);
524 if (ginfo
->statics_not_written
525 && ginfo
->statics_not_written
!= all_module_statics
)
526 BITMAP_FREE (ginfo
->statics_not_written
);
528 set_reference_optimization_summary (node
, NULL
);
532 /* Analyze each function in the cgraph to see which global or statics
533 are read or written. */
536 generate_summary (void)
538 struct cgraph_node
*node
;
544 /* Process all of the functions next. */
545 FOR_EACH_DEFINED_FUNCTION (node
)
546 analyze_function (node
);
549 EXECUTE_IF_SET_IN_BITMAP (all_module_statics
, 0, index
, bi
)
551 fprintf (dump_file
, "\nPromotable global:%s (uid=%u)\n",
552 get_static_name (index
), index
);
556 FOR_EACH_DEFINED_FUNCTION (node
)
557 if (cgraph_function_body_availability (node
) >= AVAIL_OVERWRITABLE
)
559 ipa_reference_local_vars_info_t l
;
563 l
= &get_reference_vars_info (node
)->local
;
565 "\nFunction name:%s/%i:",
566 node
->asm_name (), node
->order
);
567 fprintf (dump_file
, "\n locals read: ");
569 EXECUTE_IF_SET_IN_BITMAP (l
->statics_read
,
572 fprintf (dump_file
, "%s ",
573 get_static_name (index
));
575 fprintf (dump_file
, "\n locals written: ");
576 if (l
->statics_written
)
577 EXECUTE_IF_SET_IN_BITMAP (l
->statics_written
,
580 fprintf (dump_file
, "%s ", get_static_name (index
));
585 /* Set READ_ALL/WRITE_ALL based on decl flags of NODE. */
588 read_write_all_from_decl (struct cgraph_node
*node
,
589 bool &read_all
, bool &write_all
)
591 tree decl
= node
->decl
;
592 int flags
= flags_from_decl_or_type (decl
);
593 if ((flags
& ECF_LEAF
)
594 && cgraph_function_body_availability (node
) <= AVAIL_OVERWRITABLE
)
596 else if (flags
& ECF_CONST
)
598 else if ((flags
& ECF_PURE
)
599 || cgraph_node_cannot_return (node
))
602 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
603 fprintf (dump_file
, " %s/%i -> read all\n",
604 node
->asm_name (), node
->order
);
608 /* TODO: To be able to produce sane results, we should also handle
609 common builtins, in particular throw. */
612 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
613 fprintf (dump_file
, " %s/%i -> read all, write all\n",
614 node
->asm_name (), node
->order
);
618 /* Set READ_ALL/WRITE_ALL based on decl flags of NODE or any member
619 in the cycle of NODE. */
622 get_read_write_all_from_node (struct cgraph_node
*node
,
623 bool &read_all
, bool &write_all
)
625 struct cgraph_edge
*e
, *ie
;
627 /* When function is overwritable, we can not assume anything. */
628 if (cgraph_function_body_availability (node
) <= AVAIL_OVERWRITABLE
)
629 read_write_all_from_decl (node
, read_all
, write_all
);
631 for (e
= node
->callees
;
632 e
&& !(read_all
&& write_all
);
635 enum availability avail
;
636 struct cgraph_node
*callee
= cgraph_function_node (e
->callee
, &avail
);
637 gcc_checking_assert (callee
);
638 if (avail
<= AVAIL_OVERWRITABLE
)
639 read_write_all_from_decl (callee
, read_all
, write_all
);
642 for (ie
= node
->indirect_calls
;
643 ie
&& !(read_all
&& write_all
);
644 ie
= ie
->next_callee
)
645 if (!(ie
->indirect_info
->ecf_flags
& ECF_CONST
))
648 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
649 fprintf (dump_file
, " indirect call -> read all\n");
650 if (!cgraph_edge_cannot_lead_to_return (ie
)
651 && !(ie
->indirect_info
->ecf_flags
& ECF_PURE
))
653 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
654 fprintf (dump_file
, " indirect call -> write all\n");
660 /* Produce the global information by preforming a transitive closure
661 on the local information that was produced by ipa_analyze_function. */
666 struct cgraph_node
*node
;
667 struct varpool_node
*vnode
;
668 struct cgraph_node
**order
=
669 XCNEWVEC (struct cgraph_node
*, cgraph_n_nodes
);
674 dump_cgraph (dump_file
);
676 ipa_discover_readonly_nonaddressable_vars ();
679 /* Now we know what vars are really statics; prune out those that aren't. */
680 FOR_EACH_VARIABLE (vnode
)
681 if (vnode
->externally_visible
682 || TREE_ADDRESSABLE (vnode
->decl
)
683 || TREE_READONLY (vnode
->decl
)
684 || !is_proper_for_analysis (vnode
->decl
)
685 || !vnode
->definition
)
686 bitmap_clear_bit (all_module_statics
, DECL_UID (vnode
->decl
));
688 /* Forget info we collected "just for fun" on variables that turned out to be
690 FOR_EACH_DEFINED_FUNCTION (node
)
692 ipa_reference_local_vars_info_t node_l
;
693 node_l
= &get_reference_vars_info (node
)->local
;
694 intersect_static_var_sets (node_l
->statics_read
, all_module_statics
);
695 intersect_static_var_sets (node_l
->statics_written
, all_module_statics
);
698 /* Propagate the local information through the call graph to produce
699 the global information. All the nodes within a cycle will have
700 the same info so we collapse cycles first. Then we can do the
701 propagation in one pass from the leaves to the roots. */
702 order_pos
= ipa_reduced_postorder (order
, true, true, NULL
);
704 ipa_print_order (dump_file
, "reduced", order
, order_pos
);
706 for (i
= 0; i
< order_pos
; i
++ )
709 struct cgraph_node
*w
;
710 ipa_reference_vars_info_t node_info
;
711 ipa_reference_global_vars_info_t node_g
;
712 ipa_reference_local_vars_info_t node_l
;
713 bool read_all
= false;
714 bool write_all
= false;
720 node_info
= get_reference_vars_info (node
);
721 gcc_assert (node_info
);
722 node_l
= &node_info
->local
;
723 node_g
= &node_info
->global
;
725 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
726 fprintf (dump_file
, "Starting cycle with %s/%i\n",
727 node
->asm_name (), node
->order
);
729 vec
<cgraph_node_ptr
> cycle_nodes
= ipa_get_nodes_in_cycle (node
);
731 /* If any node in a cycle is read_all or write_all, they all are. */
732 FOR_EACH_VEC_ELT (cycle_nodes
, x
, w
)
734 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
735 fprintf (dump_file
, " Visiting %s/%i\n",
736 w
->asm_name (), w
->order
);
737 get_read_write_all_from_node (w
, read_all
, write_all
);
738 if (read_all
&& write_all
)
742 /* Initialized the bitmaps global sets for the reduced node. */
744 node_g
->statics_read
= all_module_statics
;
746 node_g
->statics_read
= copy_static_var_set (node_l
->statics_read
);
748 node_g
->statics_written
= all_module_statics
;
750 node_g
->statics_written
= copy_static_var_set (node_l
->statics_written
);
752 /* Merge the sets of this cycle with all sets of callees reached
754 FOR_EACH_VEC_ELT (cycle_nodes
, x
, w
)
756 if (read_all
&& write_all
)
761 ipa_reference_vars_info_t w_ri
= get_reference_vars_info (w
);
762 ipa_reference_local_vars_info_t w_l
= &w_ri
->local
;
763 int flags
= flags_from_decl_or_type (w
->decl
);
765 if (!(flags
& ECF_CONST
))
766 read_all
= union_static_var_sets (node_g
->statics_read
,
768 if (!(flags
& ECF_PURE
)
769 && !cgraph_node_cannot_return (w
))
770 write_all
= union_static_var_sets (node_g
->statics_written
,
771 w_l
->statics_written
);
774 propagate_bits (node_g
, w
);
777 /* All nodes within a cycle have the same global info bitmaps. */
778 FOR_EACH_VEC_ELT (cycle_nodes
, x
, w
)
780 ipa_reference_vars_info_t w_ri
= get_reference_vars_info (w
);
781 w_ri
->global
= *node_g
;
784 cycle_nodes
.release ();
789 for (i
= 0; i
< order_pos
; i
++)
792 struct cgraph_node
*w
;
799 "\nFunction name:%s/%i:",
800 node
->asm_name (), node
->order
);
802 ipa_reference_vars_info_t node_info
= get_reference_vars_info (node
);
803 ipa_reference_global_vars_info_t node_g
= &node_info
->global
;
805 vec
<cgraph_node_ptr
> cycle_nodes
= ipa_get_nodes_in_cycle (node
);
806 FOR_EACH_VEC_ELT (cycle_nodes
, x
, w
)
808 ipa_reference_vars_info_t w_ri
= get_reference_vars_info (w
);
809 ipa_reference_local_vars_info_t w_l
= &w_ri
->local
;
811 fprintf (dump_file
, "\n next cycle: %s/%i ",
812 w
->asm_name (), w
->order
);
813 fprintf (dump_file
, "\n locals read: ");
814 dump_static_vars_set_to_file (dump_file
, w_l
->statics_read
);
815 fprintf (dump_file
, "\n locals written: ");
816 dump_static_vars_set_to_file (dump_file
, w_l
->statics_written
);
818 cycle_nodes
.release ();
820 fprintf (dump_file
, "\n globals read: ");
821 dump_static_vars_set_to_file (dump_file
, node_g
->statics_read
);
822 fprintf (dump_file
, "\n globals written: ");
823 dump_static_vars_set_to_file (dump_file
, node_g
->statics_written
);
824 fprintf (dump_file
, "\n");
829 FOR_EACH_DEFINED_FUNCTION (node
)
831 ipa_reference_vars_info_t node_info
;
832 ipa_reference_global_vars_info_t node_g
;
833 ipa_reference_optimization_summary_t opt
;
835 node_info
= get_reference_vars_info (node
);
837 && (cgraph_function_body_availability (node
) > AVAIL_OVERWRITABLE
838 || (flags_from_decl_or_type (node
->decl
) & ECF_LEAF
)))
840 node_g
= &node_info
->global
;
842 opt
= XCNEW (struct ipa_reference_optimization_summary_d
);
843 set_reference_optimization_summary (node
, opt
);
845 /* Create the complimentary sets. */
847 if (bitmap_empty_p (node_g
->statics_read
))
848 opt
->statics_not_read
= all_module_statics
;
851 opt
->statics_not_read
852 = BITMAP_ALLOC (&optimization_summary_obstack
);
853 if (node_g
->statics_read
!= all_module_statics
)
854 bitmap_and_compl (opt
->statics_not_read
,
856 node_g
->statics_read
);
859 if (bitmap_empty_p (node_g
->statics_written
))
860 opt
->statics_not_written
= all_module_statics
;
863 opt
->statics_not_written
864 = BITMAP_ALLOC (&optimization_summary_obstack
);
865 if (node_g
->statics_written
!= all_module_statics
)
866 bitmap_and_compl (opt
->statics_not_written
,
868 node_g
->statics_written
);
874 ipa_free_postorder_info ();
877 bitmap_obstack_release (&local_info_obstack
);
878 ipa_reference_vars_vector
.release ();
880 splay_tree_delete (reference_vars_to_consider
);
881 reference_vars_to_consider
= NULL
;
885 /* Return true if we need to write summary of NODE. */
888 write_node_summary_p (struct cgraph_node
*node
,
889 lto_symtab_encoder_t encoder
,
890 bitmap ltrans_statics
)
892 ipa_reference_optimization_summary_t info
;
894 /* See if we have (non-empty) info. */
895 if (!node
->definition
|| node
->global
.inlined_to
)
897 info
= get_reference_optimization_summary (node
);
898 if (!info
|| (bitmap_empty_p (info
->statics_not_read
)
899 && bitmap_empty_p (info
->statics_not_written
)))
902 /* See if we want to encode it.
903 Encode also referenced functions since constant folding might turn it into
906 In future we might also want to include summaries of functions references
907 by initializers of constant variables references in current unit. */
908 if (!reachable_from_this_partition_p (node
, encoder
)
909 && !referenced_from_this_partition_p (&node
->ref_list
, encoder
))
912 /* See if the info has non-empty intersections with vars we want to encode. */
913 if (!bitmap_intersect_p (info
->statics_not_read
, ltrans_statics
)
914 && !bitmap_intersect_p (info
->statics_not_written
, ltrans_statics
))
919 /* Stream out BITS<RANS_STATICS as list of decls to OB.
920 LTRANS_STATICS_BITCOUNT specify number of bits in LTRANS_STATICS
921 or -1. When it is positive, just output -1 when
922 BITS<RANS_STATICS == BITS<RANS_STATICS. */
925 stream_out_bitmap (struct lto_simple_output_block
*ob
,
926 bitmap bits
, bitmap ltrans_statics
,
927 int ltrans_statics_bitcount
)
932 if (bits
== all_module_statics
)
934 streamer_write_hwi_stream (ob
->main_stream
, -1);
937 EXECUTE_IF_AND_IN_BITMAP (bits
, ltrans_statics
, 0, index
, bi
)
939 if (count
== ltrans_statics_bitcount
)
941 streamer_write_hwi_stream (ob
->main_stream
, -1);
944 streamer_write_hwi_stream (ob
->main_stream
, count
);
947 EXECUTE_IF_AND_IN_BITMAP (bits
, ltrans_statics
, 0, index
, bi
)
949 tree decl
= (tree
)splay_tree_lookup (reference_vars_to_consider
, index
)->value
;
950 lto_output_var_decl_index (ob
->decl_state
, ob
->main_stream
, decl
);
954 /* Serialize the ipa info for lto. */
957 ipa_reference_write_optimization_summary (void)
959 struct lto_simple_output_block
*ob
960 = lto_create_simple_output_block (LTO_section_ipa_reference
);
961 unsigned int count
= 0;
962 int ltrans_statics_bitcount
= 0;
963 lto_symtab_encoder_t encoder
= ob
->decl_state
->symtab_node_encoder
;
964 bitmap ltrans_statics
= BITMAP_ALLOC (NULL
);
967 reference_vars_to_consider
= splay_tree_new (splay_tree_compare_ints
, 0, 0);
969 /* See what variables we are interested in. */
970 for (i
= 0; i
< lto_symtab_encoder_size (encoder
); i
++)
972 symtab_node
*snode
= lto_symtab_encoder_deref (encoder
, i
);
973 varpool_node
*vnode
= dyn_cast
<varpool_node
> (snode
);
975 && bitmap_bit_p (all_module_statics
, DECL_UID (vnode
->decl
))
976 && referenced_from_this_partition_p (&vnode
->ref_list
, encoder
))
978 tree decl
= vnode
->decl
;
979 bitmap_set_bit (ltrans_statics
, DECL_UID (decl
));
980 splay_tree_insert (reference_vars_to_consider
,
981 DECL_UID (decl
), (splay_tree_value
)decl
);
982 ltrans_statics_bitcount
++;
987 if (ltrans_statics_bitcount
)
988 for (i
= 0; i
< lto_symtab_encoder_size (encoder
); i
++)
990 symtab_node
*snode
= lto_symtab_encoder_deref (encoder
, i
);
991 cgraph_node
*cnode
= dyn_cast
<cgraph_node
> (snode
);
992 if (cnode
&& write_node_summary_p (cnode
, encoder
, ltrans_statics
))
996 streamer_write_uhwi_stream (ob
->main_stream
, count
);
998 stream_out_bitmap (ob
, ltrans_statics
, ltrans_statics
,
1001 /* Process all of the functions. */
1002 if (ltrans_statics_bitcount
)
1003 for (i
= 0; i
< lto_symtab_encoder_size (encoder
); i
++)
1005 symtab_node
*snode
= lto_symtab_encoder_deref (encoder
, i
);
1006 cgraph_node
*cnode
= dyn_cast
<cgraph_node
> (snode
);
1007 if (cnode
&& write_node_summary_p (cnode
, encoder
, ltrans_statics
))
1009 ipa_reference_optimization_summary_t info
;
1012 info
= get_reference_optimization_summary (cnode
);
1013 node_ref
= lto_symtab_encoder_encode (encoder
, snode
);
1014 streamer_write_uhwi_stream (ob
->main_stream
, node_ref
);
1016 stream_out_bitmap (ob
, info
->statics_not_read
, ltrans_statics
,
1017 ltrans_statics_bitcount
);
1018 stream_out_bitmap (ob
, info
->statics_not_written
, ltrans_statics
,
1019 ltrans_statics_bitcount
);
1022 BITMAP_FREE (ltrans_statics
);
1023 lto_destroy_simple_output_block (ob
);
1024 splay_tree_delete (reference_vars_to_consider
);
1027 /* Deserialize the ipa info for lto. */
1030 ipa_reference_read_optimization_summary (void)
1032 struct lto_file_decl_data
** file_data_vec
1033 = lto_get_file_decl_data ();
1034 struct lto_file_decl_data
* file_data
;
1036 bitmap_obstack_initialize (&optimization_summary_obstack
);
1038 node_removal_hook_holder
=
1039 cgraph_add_node_removal_hook (&remove_node_data
, NULL
);
1040 node_duplication_hook_holder
=
1041 cgraph_add_node_duplication_hook (&duplicate_node_data
, NULL
);
1042 all_module_statics
= BITMAP_ALLOC (&optimization_summary_obstack
);
1044 while ((file_data
= file_data_vec
[j
++]))
1048 struct lto_input_block
*ib
1049 = lto_create_simple_input_block (file_data
,
1050 LTO_section_ipa_reference
,
1055 unsigned int f_count
= streamer_read_uhwi (ib
);
1059 b_count
= streamer_read_hwi (ib
);
1061 fprintf (dump_file
, "all module statics:");
1062 for (i
= 0; i
< (unsigned int)b_count
; i
++)
1064 unsigned int var_index
= streamer_read_uhwi (ib
);
1065 tree v_decl
= lto_file_decl_data_get_var_decl (file_data
,
1067 bitmap_set_bit (all_module_statics
, DECL_UID (v_decl
));
1069 fprintf (dump_file
, " %s", fndecl_name (v_decl
));
1072 for (i
= 0; i
< f_count
; i
++)
1074 unsigned int j
, index
;
1075 struct cgraph_node
*node
;
1076 ipa_reference_optimization_summary_t info
;
1078 lto_symtab_encoder_t encoder
;
1080 index
= streamer_read_uhwi (ib
);
1081 encoder
= file_data
->symtab_node_encoder
;
1082 node
= cgraph (lto_symtab_encoder_deref (encoder
, index
));
1083 info
= XCNEW (struct ipa_reference_optimization_summary_d
);
1084 set_reference_optimization_summary (node
, info
);
1085 info
->statics_not_read
= BITMAP_ALLOC (&optimization_summary_obstack
);
1086 info
->statics_not_written
= BITMAP_ALLOC (&optimization_summary_obstack
);
1089 "\nFunction name:%s/%i:\n static not read:",
1090 node
->asm_name (), node
->order
);
1092 /* Set the statics not read. */
1093 v_count
= streamer_read_hwi (ib
);
1096 info
->statics_not_read
= all_module_statics
;
1098 fprintf (dump_file
, " all module statics");
1101 for (j
= 0; j
< (unsigned int)v_count
; j
++)
1103 unsigned int var_index
= streamer_read_uhwi (ib
);
1104 tree v_decl
= lto_file_decl_data_get_var_decl (file_data
,
1106 bitmap_set_bit (info
->statics_not_read
, DECL_UID (v_decl
));
1108 fprintf (dump_file
, " %s", fndecl_name (v_decl
));
1113 "\n static not written:");
1114 /* Set the statics not written. */
1115 v_count
= streamer_read_hwi (ib
);
1118 info
->statics_not_written
= all_module_statics
;
1120 fprintf (dump_file
, " all module statics");
1123 for (j
= 0; j
< (unsigned int)v_count
; j
++)
1125 unsigned int var_index
= streamer_read_uhwi (ib
);
1126 tree v_decl
= lto_file_decl_data_get_var_decl (file_data
,
1128 bitmap_set_bit (info
->statics_not_written
, DECL_UID (v_decl
));
1130 fprintf (dump_file
, " %s", fndecl_name (v_decl
));
1133 fprintf (dump_file
, "\n");
1136 lto_destroy_simple_input_block (file_data
,
1137 LTO_section_ipa_reference
,
1141 /* Fatal error here. We do not want to support compiling ltrans units with
1142 different version of compiler or different flags than the WPA unit, so
1143 this should never happen. */
1144 fatal_error ("ipa reference summary is missing in ltrans unit");
1149 gate_reference (void)
1151 return (flag_ipa_reference
1152 /* Don't bother doing anything if the program has errors. */
1158 const pass_data pass_data_ipa_reference
=
1160 IPA_PASS
, /* type */
1161 "static-var", /* name */
1162 OPTGROUP_NONE
, /* optinfo_flags */
1163 true, /* has_gate */
1164 true, /* has_execute */
1165 TV_IPA_REFERENCE
, /* tv_id */
1166 0, /* properties_required */
1167 0, /* properties_provided */
1168 0, /* properties_destroyed */
1169 0, /* todo_flags_start */
1170 0, /* todo_flags_finish */
1173 class pass_ipa_reference
: public ipa_opt_pass_d
1176 pass_ipa_reference (gcc::context
*ctxt
)
1177 : ipa_opt_pass_d (pass_data_ipa_reference
, ctxt
,
1178 NULL
, /* generate_summary */
1179 NULL
, /* write_summary */
1180 NULL
, /* read_summary */
1181 ipa_reference_write_optimization_summary
, /*
1182 write_optimization_summary */
1183 ipa_reference_read_optimization_summary
, /*
1184 read_optimization_summary */
1185 NULL
, /* stmt_fixup */
1186 0, /* function_transform_todo_flags_start */
1187 NULL
, /* function_transform */
1188 NULL
) /* variable_transform */
1191 /* opt_pass methods: */
1192 bool gate () { return gate_reference (); }
1193 unsigned int execute () { return propagate (); }
1195 }; // class pass_ipa_reference
1200 make_pass_ipa_reference (gcc::context
*ctxt
)
1202 return new pass_ipa_reference (ctxt
);