1 /* Callgraph based analysis of static variables.
2 Copyright (C) 2004-2019 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"
45 #include "tree-pass.h"
47 #include "data-streamer.h"
49 #include "splay-tree.h"
50 #include "ipa-utils.h"
51 #include "ipa-reference.h"
52 #include "symbol-summary.h"
54 /* The static variables defined within the compilation unit that are
55 loaded or stored directly by function that owns this structure. */
57 struct ipa_reference_local_vars_info_d
60 bitmap statics_written
;
63 /* Statics that are read and written by some set of functions. The
64 local ones are based on the loads and stores local to the function.
65 The global ones are based on the local info as well as the
66 transitive closure of the functions that are called. */
68 struct ipa_reference_global_vars_info_d
71 bitmap statics_written
;
74 /* Information we save about every function after ipa-reference is completed. */
76 struct ipa_reference_optimization_summary_d
78 bitmap statics_not_read
;
79 bitmap statics_not_written
;
82 typedef ipa_reference_local_vars_info_d
*ipa_reference_local_vars_info_t
;
83 typedef ipa_reference_global_vars_info_d
*ipa_reference_global_vars_info_t
;
84 typedef ipa_reference_optimization_summary_d
*
85 ipa_reference_optimization_summary_t
;
87 struct ipa_reference_vars_info_d
89 struct ipa_reference_local_vars_info_d local
;
90 struct ipa_reference_global_vars_info_d global
;
93 typedef struct ipa_reference_vars_info_d
*ipa_reference_vars_info_t
;
95 /* This splay tree contains all of the static variables that are
96 being considered by the compilation level alias analysis. */
97 static splay_tree reference_vars_to_consider
;
99 /* Set of all interesting module statics. A bit is set for every module
100 static we are considering. This is added to the local info when asm
101 code is found that clobbers all memory. */
102 static bitmap all_module_statics
;
103 /* Set of all statics that should be ignored because they are touched by
104 -fno-ipa-reference code. */
105 static bitmap ignore_module_statics
;
107 /* Obstack holding bitmaps of local analysis (live from analysis to
109 static bitmap_obstack local_info_obstack
;
110 /* Obstack holding global analysis live forever. */
111 static bitmap_obstack optimization_summary_obstack
;
113 class ipa_ref_var_info_summary_t
: public function_summary
114 <ipa_reference_vars_info_d
*>
117 ipa_ref_var_info_summary_t (symbol_table
*symtab
):
118 function_summary
<ipa_reference_vars_info_d
*> (symtab
) {}
121 static ipa_ref_var_info_summary_t
*ipa_ref_var_info_summaries
= NULL
;
123 class ipa_ref_opt_summary_t
: public function_summary
124 <ipa_reference_optimization_summary_d
*>
127 ipa_ref_opt_summary_t (symbol_table
*symtab
):
128 function_summary
<ipa_reference_optimization_summary_d
*> (symtab
) {}
131 virtual void remove (cgraph_node
*src_node
,
132 ipa_reference_optimization_summary_d
*data
);
133 virtual void duplicate (cgraph_node
*src_node
, cgraph_node
*dst_node
,
134 ipa_reference_optimization_summary_d
*src_data
,
135 ipa_reference_optimization_summary_d
*dst_data
);
138 static ipa_ref_opt_summary_t
*ipa_ref_opt_sum_summaries
= NULL
;
140 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
141 static inline ipa_reference_vars_info_t
142 get_reference_vars_info (struct cgraph_node
*node
)
144 if (ipa_ref_var_info_summaries
== NULL
)
147 ipa_reference_vars_info_t v
= ipa_ref_var_info_summaries
->get (node
);
148 return v
== NULL
? NULL
: v
;
151 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
152 static inline ipa_reference_optimization_summary_t
153 get_reference_optimization_summary (struct cgraph_node
*node
)
155 if (ipa_ref_opt_sum_summaries
== NULL
)
158 ipa_reference_optimization_summary_t v
159 = ipa_ref_opt_sum_summaries
->get (node
);
161 return v
== NULL
? NULL
: v
;
164 /* Return a bitmap indexed by ipa_reference_var_uid for the static variables
165 that are *not* read during the execution of the function FN. Returns
166 NULL if no data is available. */
169 ipa_reference_get_not_read_global (struct cgraph_node
*fn
)
171 if (!opt_for_fn (current_function_decl
, flag_ipa_reference
))
174 enum availability avail
;
175 struct cgraph_node
*fn2
= fn
->function_symbol (&avail
);
176 ipa_reference_optimization_summary_t info
=
177 get_reference_optimization_summary (fn2
);
180 && (avail
>= AVAIL_AVAILABLE
181 || (avail
== AVAIL_INTERPOSABLE
182 && flags_from_decl_or_type (fn
->decl
) & ECF_LEAF
))
183 && opt_for_fn (fn2
->decl
, flag_ipa_reference
))
184 return info
->statics_not_read
;
185 else if (avail
== AVAIL_NOT_AVAILABLE
186 && flags_from_decl_or_type (fn
->decl
) & ECF_LEAF
)
187 return all_module_statics
;
192 /* Return a bitmap indexed by ipa_reference_var_uid for the static variables
193 that are *not* written during the execution of the function FN. Note
194 that variables written may or may not be read during the function
195 call. Returns NULL if no data is available. */
198 ipa_reference_get_not_written_global (struct cgraph_node
*fn
)
200 if (!opt_for_fn (current_function_decl
, flag_ipa_reference
))
203 enum availability avail
;
204 struct cgraph_node
*fn2
= fn
->function_symbol (&avail
);
205 ipa_reference_optimization_summary_t info
=
206 get_reference_optimization_summary (fn2
);
209 && (avail
>= AVAIL_AVAILABLE
210 || (avail
== AVAIL_INTERPOSABLE
211 && flags_from_decl_or_type (fn
->decl
) & ECF_LEAF
))
212 && opt_for_fn (fn2
->decl
, flag_ipa_reference
))
213 return info
->statics_not_written
;
214 else if (avail
== AVAIL_NOT_AVAILABLE
215 && flags_from_decl_or_type (fn
->decl
) & ECF_LEAF
)
216 return all_module_statics
;
222 /* Hepler for is_proper_for_analysis. */
224 is_improper (symtab_node
*n
, void *v ATTRIBUTE_UNUSED
)
227 /* If the variable has the "used" attribute, treat it as if it had a
228 been touched by the devil. */
229 if (DECL_PRESERVE_P (t
))
232 /* Do not want to do anything with volatile except mark any
233 function that uses one to be not const or pure. */
234 if (TREE_THIS_VOLATILE (t
))
237 /* We do not need to analyze readonly vars, we already know they do not
239 if (TREE_READONLY (t
))
242 /* We can not track variables with address taken. */
243 if (TREE_ADDRESSABLE (t
))
246 /* TODO: We could track public variables that are not addressable, but
247 currently frontends don't give us those. */
254 /* Return true if the variable T is the right kind of static variable to
255 perform compilation unit scope escape analysis. */
258 is_proper_for_analysis (tree t
)
260 if (bitmap_bit_p (ignore_module_statics
, ipa_reference_var_uid (t
)))
263 if (symtab_node::get (t
)
264 ->call_for_symbol_and_aliases (is_improper
, NULL
, true))
270 /* Lookup the tree node for the static variable that has UID and
271 convert the name to a string for debugging. */
274 get_static_name (int index
)
276 splay_tree_node stn
=
277 splay_tree_lookup (reference_vars_to_consider
, index
);
278 return fndecl_name ((tree
)(stn
->value
));
281 /* Dump a set of static vars to FILE. */
283 dump_static_vars_set_to_file (FILE *f
, bitmap set
)
289 else if (set
== all_module_statics
)
292 EXECUTE_IF_SET_IN_BITMAP (set
, 0, index
, bi
)
294 fprintf (f
, "%s ", get_static_name (index
));
298 /* Compute X |= Y, taking into account the possibility that
299 either X or Y is already the maximum set.
300 Return true if X is the maximum set after taking the union with Y. */
303 union_static_var_sets (bitmap
&x
, bitmap y
)
305 if (x
!= all_module_statics
)
307 if (y
== all_module_statics
)
310 x
= all_module_statics
;
312 else if (bitmap_ior_into (x
, y
))
314 /* The union may have reduced X to the maximum set.
315 In that case, we want to make that visible explicitly.
316 Even though bitmap_equal_p can be very expensive, it
317 turns out to be an overall win to check this here for
318 an LTO bootstrap of GCC itself. Liberally extrapoliate
319 that result to be applicable to all cases. */
320 if (bitmap_equal_p (x
, all_module_statics
))
323 x
= all_module_statics
;
327 return x
== all_module_statics
;
330 /* Return a copy of SET on the bitmap obstack containing SET.
331 But if SET is NULL or the maximum set, return that instead. */
334 copy_static_var_set (bitmap set
)
336 if (set
== NULL
|| set
== all_module_statics
)
338 bitmap_obstack
*o
= set
->obstack
;
339 gcc_checking_assert (o
);
340 bitmap copy
= BITMAP_ALLOC (o
);
341 bitmap_copy (copy
, set
);
345 /* Compute the union all of the statics read and written by every callee of X
346 into X_GLOBAL->statics_read and X_GLOBAL->statics_written. X_GLOBAL is
347 actually the set representing the cycle containing X. If the read and
348 written sets of X_GLOBAL has been reduced to the maximum set, we don't
349 have to look at the remaining callees. */
352 propagate_bits (ipa_reference_global_vars_info_t x_global
, struct cgraph_node
*x
)
354 struct cgraph_edge
*e
;
355 bool read_all
= x_global
->statics_read
== all_module_statics
;
356 bool write_all
= x_global
->statics_written
== all_module_statics
;
358 e
&& !(read_all
&& write_all
);
361 enum availability avail
;
362 struct cgraph_node
*y
= e
->callee
->function_symbol (&avail
);
366 /* Only look into nodes we can propagate something. */
367 int flags
= flags_from_decl_or_type (y
->decl
);
368 if (opt_for_fn (y
->decl
, flag_ipa_reference
)
369 && (avail
> AVAIL_INTERPOSABLE
370 || (avail
== AVAIL_INTERPOSABLE
&& (flags
& ECF_LEAF
))))
372 if (get_reference_vars_info (y
))
374 ipa_reference_vars_info_t y_info
= get_reference_vars_info (y
);
375 ipa_reference_global_vars_info_t y_global
= &y_info
->global
;
377 /* Calls in the current cycle do not have their global set
378 computed yet (but everything else does because we're
379 visiting nodes in topological order). */
380 if (!y_global
->statics_read
)
383 /* If the function is const, it reads no memory even if it
384 seems so to local analysis. */
385 if (flags
& ECF_CONST
)
388 union_static_var_sets (x_global
->statics_read
,
389 y_global
->statics_read
);
391 /* If the function is pure, it has no stores even if it
392 seems so to local analysis. If we cannot return from
393 the function, we can safely ignore the call. */
394 if ((flags
& ECF_PURE
)
395 || e
->cannot_lead_to_return_p ())
398 union_static_var_sets (x_global
->statics_written
,
399 y_global
->statics_written
);
407 static bool ipa_init_p
= false;
409 /* The init routine for analyzing global static variable usage. See
410 comments at top for description. */
420 reference_vars_to_consider
= splay_tree_new (splay_tree_compare_ints
, 0, 0);
422 bitmap_obstack_initialize (&local_info_obstack
);
423 bitmap_obstack_initialize (&optimization_summary_obstack
);
424 all_module_statics
= BITMAP_ALLOC (&optimization_summary_obstack
);
425 ignore_module_statics
= BITMAP_ALLOC (&optimization_summary_obstack
);
427 if (ipa_ref_var_info_summaries
== NULL
)
428 ipa_ref_var_info_summaries
= new ipa_ref_var_info_summary_t (symtab
);
430 if (ipa_ref_opt_sum_summaries
!= NULL
)
432 delete ipa_ref_opt_sum_summaries
;
433 ipa_ref_opt_sum_summaries
= NULL
;
438 /* Set up the persistent info for FN. */
440 static ipa_reference_local_vars_info_t
441 init_function_info (struct cgraph_node
*fn
)
443 ipa_reference_vars_info_t info
444 = ipa_ref_var_info_summaries
->get_create (fn
);
446 info
->local
.statics_read
= BITMAP_ALLOC (&local_info_obstack
);
447 info
->local
.statics_written
= BITMAP_ALLOC (&local_info_obstack
);
453 /* This is the main routine for finding the reference patterns for
454 global variables within a function FN. */
457 analyze_function (struct cgraph_node
*fn
)
459 ipa_reference_local_vars_info_t local
;
460 struct ipa_ref
*ref
= NULL
;
464 if (!opt_for_fn (fn
->decl
, flag_ipa_reference
))
466 local
= init_function_info (fn
);
467 for (i
= 0; fn
->iterate_reference (i
, ref
); i
++)
469 if (!is_a
<varpool_node
*> (ref
->referred
))
471 var
= ref
->referred
->decl
;
472 if (!is_proper_for_analysis (var
))
474 /* This is a variable we care about. Check if we have seen it
475 before, and if not add it the set of variables we care about. */
476 if (all_module_statics
477 && bitmap_set_bit (all_module_statics
, ipa_reference_var_uid (var
)))
480 splay_tree_insert (reference_vars_to_consider
,
481 ipa_reference_var_uid (var
),
482 (splay_tree_value
)var
);
487 bitmap_set_bit (local
->statics_read
, ipa_reference_var_uid (var
));
490 if (ref
->cannot_lead_to_return ())
492 bitmap_set_bit (local
->statics_written
, ipa_reference_var_uid (var
));
501 if (fn
->cannot_return_p ())
502 bitmap_clear (local
->statics_written
);
506 /* Called when new clone is inserted to callgraph late. */
509 ipa_ref_opt_summary_t::duplicate (cgraph_node
*, cgraph_node
*,
510 ipa_reference_optimization_summary_d
*ginfo
,
511 ipa_reference_optimization_summary_d
514 dst_ginfo
->statics_not_read
=
515 copy_static_var_set (ginfo
->statics_not_read
);
516 dst_ginfo
->statics_not_written
=
517 copy_static_var_set (ginfo
->statics_not_written
);
520 /* Called when node is removed. */
523 ipa_ref_opt_summary_t::remove (cgraph_node
*,
524 ipa_reference_optimization_summary_d
*ginfo
)
526 if (ginfo
->statics_not_read
527 && ginfo
->statics_not_read
!= all_module_statics
)
528 BITMAP_FREE (ginfo
->statics_not_read
);
530 if (ginfo
->statics_not_written
531 && ginfo
->statics_not_written
!= all_module_statics
)
532 BITMAP_FREE (ginfo
->statics_not_written
);
535 /* Analyze each function in the cgraph to see which global or statics
536 are read or written. */
539 generate_summary (void)
541 struct cgraph_node
*node
;
547 /* Process all of the functions next. */
548 FOR_EACH_DEFINED_FUNCTION (node
)
549 if (!node
->alias
&& !opt_for_fn (node
->decl
, flag_ipa_reference
))
551 struct ipa_ref
*ref
= NULL
;
554 for (i
= 0; node
->iterate_reference (i
, ref
); i
++)
556 if (!is_a
<varpool_node
*> (ref
->referred
))
558 var
= ref
->referred
->decl
;
559 if (!is_proper_for_analysis (var
))
561 bitmap_set_bit (ignore_module_statics
, ipa_reference_var_uid (var
));
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 (node
->get_availability () >= AVAIL_INTERPOSABLE
577 && opt_for_fn (node
->decl
, flag_ipa_reference
))
579 ipa_reference_local_vars_info_t l
;
583 l
= &get_reference_vars_info (node
)->local
;
585 "\nFunction name:%s:", node
->dump_name ());
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 ", get_static_name (index
));
604 /* Set READ_ALL/WRITE_ALL based on decl flags of NODE. */
607 read_write_all_from_decl (struct cgraph_node
*node
,
608 bool &read_all
, bool &write_all
)
610 tree decl
= node
->decl
;
611 int flags
= flags_from_decl_or_type (decl
);
612 if ((flags
& ECF_LEAF
)
613 && node
->get_availability () < AVAIL_INTERPOSABLE
)
615 else if (flags
& ECF_CONST
)
617 else if ((flags
& ECF_PURE
) || node
->cannot_return_p ())
620 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
621 fprintf (dump_file
, " %s -> read all\n", node
->dump_name ());
625 /* TODO: To be able to produce sane results, we should also handle
626 common builtins, in particular throw. */
629 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
630 fprintf (dump_file
, " %s -> read all, write all\n",
635 /* Set READ_ALL/WRITE_ALL based on decl flags of NODE or any member
636 in the cycle of NODE. */
639 get_read_write_all_from_node (struct cgraph_node
*node
,
640 bool &read_all
, bool &write_all
)
642 struct cgraph_edge
*e
, *ie
;
644 /* When function is overwritable, we can not assume anything. */
645 if (node
->get_availability () <= AVAIL_INTERPOSABLE
646 || (node
->analyzed
&& !opt_for_fn (node
->decl
, flag_ipa_reference
)))
647 read_write_all_from_decl (node
, read_all
, write_all
);
649 for (e
= node
->callees
;
650 e
&& !(read_all
&& write_all
);
653 enum availability avail
;
654 struct cgraph_node
*callee
= e
->callee
->function_symbol (&avail
);
655 gcc_checking_assert (callee
);
656 if (avail
<= AVAIL_INTERPOSABLE
657 || (callee
->analyzed
&& !opt_for_fn (callee
->decl
,
658 flag_ipa_reference
)))
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 (!ie
->cannot_lead_to_return_p ()
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 /* Skip edges from and to nodes without ipa_reference enables. This leave
681 them out of strongy connected coponents and makes them easyto skip in the
682 propagation loop bellow. */
685 ignore_edge_p (cgraph_edge
*e
)
687 return (!opt_for_fn (e
->caller
->decl
, flag_ipa_reference
)
688 || !opt_for_fn (e
->callee
->function_symbol ()->decl
,
689 flag_ipa_reference
));
692 /* Produce the global information by preforming a transitive closure
693 on the local information that was produced by ipa_analyze_function. */
698 struct cgraph_node
*node
;
699 struct cgraph_node
**order
=
700 XCNEWVEC (struct cgraph_node
*, symtab
->cgraph_count
);
706 cgraph_node::dump_cgraph (dump_file
);
708 remove_p
= ipa_discover_variable_flags ();
711 /* Propagate the local information through the call graph to produce
712 the global information. All the nodes within a cycle will have
713 the same info so we collapse cycles first. Then we can do the
714 propagation in one pass from the leaves to the roots. */
715 order_pos
= ipa_reduced_postorder (order
, true, true, ignore_edge_p
);
717 ipa_print_order (dump_file
, "reduced", order
, order_pos
);
719 for (i
= 0; i
< order_pos
; i
++ )
722 struct cgraph_node
*w
;
723 ipa_reference_vars_info_t node_info
;
724 ipa_reference_global_vars_info_t node_g
;
725 ipa_reference_local_vars_info_t node_l
;
726 bool read_all
= false;
727 bool write_all
= false;
730 if (node
->alias
|| !opt_for_fn (node
->decl
, flag_ipa_reference
))
733 node_info
= get_reference_vars_info (node
);
734 gcc_assert (node_info
);
735 node_l
= &node_info
->local
;
736 node_g
= &node_info
->global
;
738 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
739 fprintf (dump_file
, "Starting cycle with %s\n", node
->dump_name ());
741 vec
<cgraph_node
*> cycle_nodes
= ipa_get_nodes_in_cycle (node
);
743 /* If any node in a cycle is read_all or write_all, they all are. */
744 FOR_EACH_VEC_ELT (cycle_nodes
, x
, w
)
746 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
747 fprintf (dump_file
, " Visiting %s\n", w
->dump_asm_name ());
748 get_read_write_all_from_node (w
, read_all
, write_all
);
749 if (read_all
&& write_all
)
753 /* Initialized the bitmaps global sets for the reduced node. */
755 node_g
->statics_read
= all_module_statics
;
757 node_g
->statics_read
= copy_static_var_set (node_l
->statics_read
);
759 node_g
->statics_written
= all_module_statics
;
761 node_g
->statics_written
= copy_static_var_set (node_l
->statics_written
);
763 /* Merge the sets of this cycle with all sets of callees reached
765 FOR_EACH_VEC_ELT (cycle_nodes
, x
, w
)
767 if (read_all
&& write_all
)
772 ipa_reference_vars_info_t w_ri
= get_reference_vars_info (w
);
773 ipa_reference_local_vars_info_t w_l
= &w_ri
->local
;
774 int flags
= flags_from_decl_or_type (w
->decl
);
776 if (!(flags
& ECF_CONST
))
777 read_all
= union_static_var_sets (node_g
->statics_read
,
779 if (!(flags
& ECF_PURE
)
780 && !w
->cannot_return_p ())
781 write_all
= union_static_var_sets (node_g
->statics_written
,
782 w_l
->statics_written
);
785 propagate_bits (node_g
, w
);
788 /* All nodes within a cycle have the same global info bitmaps. */
789 FOR_EACH_VEC_ELT (cycle_nodes
, x
, w
)
791 ipa_reference_vars_info_t w_ri
= get_reference_vars_info (w
);
792 w_ri
->global
= *node_g
;
795 cycle_nodes
.release ();
800 for (i
= 0; i
< order_pos
; i
++)
803 struct cgraph_node
*w
;
806 if (node
->alias
|| !opt_for_fn (node
->decl
, flag_ipa_reference
))
809 fprintf (dump_file
, "\nFunction name:%s:", node
->dump_asm_name ());
811 ipa_reference_vars_info_t node_info
= get_reference_vars_info (node
);
812 ipa_reference_global_vars_info_t node_g
= &node_info
->global
;
814 vec
<cgraph_node
*> cycle_nodes
= ipa_get_nodes_in_cycle (node
);
815 FOR_EACH_VEC_ELT (cycle_nodes
, x
, w
)
817 ipa_reference_vars_info_t w_ri
= get_reference_vars_info (w
);
818 ipa_reference_local_vars_info_t w_l
= &w_ri
->local
;
820 fprintf (dump_file
, "\n next cycle: %s ", w
->dump_asm_name ());
821 fprintf (dump_file
, "\n locals read: ");
822 dump_static_vars_set_to_file (dump_file
, w_l
->statics_read
);
823 fprintf (dump_file
, "\n locals written: ");
824 dump_static_vars_set_to_file (dump_file
, w_l
->statics_written
);
826 cycle_nodes
.release ();
828 fprintf (dump_file
, "\n globals read: ");
829 dump_static_vars_set_to_file (dump_file
, node_g
->statics_read
);
830 fprintf (dump_file
, "\n globals written: ");
831 dump_static_vars_set_to_file (dump_file
, node_g
->statics_written
);
832 fprintf (dump_file
, "\n");
836 if (ipa_ref_opt_sum_summaries
== NULL
)
837 ipa_ref_opt_sum_summaries
= new ipa_ref_opt_summary_t (symtab
);
840 FOR_EACH_DEFINED_FUNCTION (node
)
842 ipa_reference_vars_info_t node_info
;
843 ipa_reference_global_vars_info_t node_g
;
845 node_info
= get_reference_vars_info (node
);
846 if (!node
->alias
&& opt_for_fn (node
->decl
, flag_ipa_reference
)
847 && (node
->get_availability () > AVAIL_INTERPOSABLE
848 || (flags_from_decl_or_type (node
->decl
) & ECF_LEAF
)))
850 node_g
= &node_info
->global
;
852 ipa_reference_optimization_summary_d
*opt
853 = ipa_ref_opt_sum_summaries
->get_create (node
);
855 /* Create the complimentary sets. */
857 if (bitmap_empty_p (node_g
->statics_read
))
858 opt
->statics_not_read
= all_module_statics
;
861 opt
->statics_not_read
862 = BITMAP_ALLOC (&optimization_summary_obstack
);
863 if (node_g
->statics_read
!= all_module_statics
)
864 bitmap_and_compl (opt
->statics_not_read
,
866 node_g
->statics_read
);
869 if (bitmap_empty_p (node_g
->statics_written
))
870 opt
->statics_not_written
= all_module_statics
;
873 opt
->statics_not_written
874 = BITMAP_ALLOC (&optimization_summary_obstack
);
875 if (node_g
->statics_written
!= all_module_statics
)
876 bitmap_and_compl (opt
->statics_not_written
,
878 node_g
->statics_written
);
883 ipa_free_postorder_info ();
886 bitmap_obstack_release (&local_info_obstack
);
888 if (ipa_ref_var_info_summaries
== NULL
)
890 delete ipa_ref_var_info_summaries
;
891 ipa_ref_var_info_summaries
= NULL
;
894 ipa_ref_var_info_summaries
= NULL
;
896 splay_tree_delete (reference_vars_to_consider
);
897 reference_vars_to_consider
= NULL
;
898 return remove_p
? TODO_remove_functions
: 0;
901 /* Return true if we need to write summary of NODE. */
904 write_node_summary_p (struct cgraph_node
*node
,
905 lto_symtab_encoder_t encoder
,
906 bitmap ltrans_statics
)
908 ipa_reference_optimization_summary_t info
;
910 /* See if we have (non-empty) info. */
911 if (!node
->definition
|| node
->global
.inlined_to
)
913 info
= get_reference_optimization_summary (node
);
915 || (bitmap_empty_p (info
->statics_not_read
)
916 && bitmap_empty_p (info
->statics_not_written
)))
919 /* See if we want to encode it.
920 Encode also referenced functions since constant folding might turn it into
923 In future we might also want to include summaries of functions references
924 by initializers of constant variables references in current unit. */
925 if (!reachable_from_this_partition_p (node
, encoder
)
926 && !referenced_from_this_partition_p (node
, encoder
))
929 /* See if the info has non-empty intersections with vars we want to encode. */
930 if (!bitmap_intersect_p (info
->statics_not_read
, ltrans_statics
)
931 && !bitmap_intersect_p (info
->statics_not_written
, ltrans_statics
))
936 /* Stream out BITS<RANS_STATICS as list of decls to OB.
937 LTRANS_STATICS_BITCOUNT specify number of bits in LTRANS_STATICS
938 or -1. When it is positive, just output -1 when
939 BITS<RANS_STATICS == BITS<RANS_STATICS. */
942 stream_out_bitmap (struct lto_simple_output_block
*ob
,
943 bitmap bits
, bitmap ltrans_statics
,
944 int ltrans_statics_bitcount
)
949 if (bits
== all_module_statics
)
951 streamer_write_hwi_stream (ob
->main_stream
, -1);
954 EXECUTE_IF_AND_IN_BITMAP (bits
, ltrans_statics
, 0, index
, bi
)
956 if (count
== ltrans_statics_bitcount
)
958 streamer_write_hwi_stream (ob
->main_stream
, -1);
961 streamer_write_hwi_stream (ob
->main_stream
, count
);
964 EXECUTE_IF_AND_IN_BITMAP (bits
, ltrans_statics
, 0, index
, bi
)
966 tree decl
= (tree
)splay_tree_lookup (reference_vars_to_consider
,
968 lto_output_var_decl_index (ob
->decl_state
, ob
->main_stream
, decl
);
972 /* Serialize the ipa info for lto. */
975 ipa_reference_write_optimization_summary (void)
977 struct lto_simple_output_block
*ob
978 = lto_create_simple_output_block (LTO_section_ipa_reference
);
979 unsigned int count
= 0;
980 int ltrans_statics_bitcount
= 0;
981 lto_symtab_encoder_t encoder
= ob
->decl_state
->symtab_node_encoder
;
982 auto_bitmap ltrans_statics
;
985 reference_vars_to_consider
= splay_tree_new (splay_tree_compare_ints
, 0, 0);
987 /* See what variables we are interested in. */
988 for (i
= 0; i
< lto_symtab_encoder_size (encoder
); i
++)
990 symtab_node
*snode
= lto_symtab_encoder_deref (encoder
, i
);
991 varpool_node
*vnode
= dyn_cast
<varpool_node
*> (snode
);
993 && bitmap_bit_p (all_module_statics
,
994 ipa_reference_var_uid (vnode
->decl
))
995 && referenced_from_this_partition_p (vnode
, encoder
))
997 tree decl
= vnode
->decl
;
998 bitmap_set_bit (ltrans_statics
, ipa_reference_var_uid (decl
));
999 splay_tree_insert (reference_vars_to_consider
,
1000 ipa_reference_var_uid (decl
),
1001 (splay_tree_value
)decl
);
1002 ltrans_statics_bitcount
++;
1007 if (ltrans_statics_bitcount
)
1008 for (i
= 0; i
< lto_symtab_encoder_size (encoder
); i
++)
1010 symtab_node
*snode
= lto_symtab_encoder_deref (encoder
, i
);
1011 cgraph_node
*cnode
= dyn_cast
<cgraph_node
*> (snode
);
1012 if (cnode
&& write_node_summary_p (cnode
, encoder
, ltrans_statics
))
1016 streamer_write_uhwi_stream (ob
->main_stream
, count
);
1018 stream_out_bitmap (ob
, ltrans_statics
, ltrans_statics
,
1021 /* Process all of the functions. */
1022 if (ltrans_statics_bitcount
)
1023 for (i
= 0; i
< lto_symtab_encoder_size (encoder
); i
++)
1025 symtab_node
*snode
= lto_symtab_encoder_deref (encoder
, i
);
1026 cgraph_node
*cnode
= dyn_cast
<cgraph_node
*> (snode
);
1027 if (cnode
&& write_node_summary_p (cnode
, encoder
, ltrans_statics
))
1029 ipa_reference_optimization_summary_t info
;
1032 info
= get_reference_optimization_summary (cnode
);
1033 node_ref
= lto_symtab_encoder_encode (encoder
, snode
);
1034 streamer_write_uhwi_stream (ob
->main_stream
, node_ref
);
1036 stream_out_bitmap (ob
, info
->statics_not_read
, ltrans_statics
,
1037 ltrans_statics_bitcount
);
1038 stream_out_bitmap (ob
, info
->statics_not_written
, ltrans_statics
,
1039 ltrans_statics_bitcount
);
1042 lto_destroy_simple_output_block (ob
);
1043 splay_tree_delete (reference_vars_to_consider
);
1046 /* Deserialize the ipa info for lto. */
1049 ipa_reference_read_optimization_summary (void)
1051 struct lto_file_decl_data
** file_data_vec
1052 = lto_get_file_decl_data ();
1053 struct lto_file_decl_data
* file_data
;
1055 bitmap_obstack_initialize (&optimization_summary_obstack
);
1057 if (ipa_ref_opt_sum_summaries
== NULL
)
1058 ipa_ref_opt_sum_summaries
= new ipa_ref_opt_summary_t (symtab
);
1060 all_module_statics
= BITMAP_ALLOC (&optimization_summary_obstack
);
1062 while ((file_data
= file_data_vec
[j
++]))
1066 struct lto_input_block
*ib
1067 = lto_create_simple_input_block (file_data
,
1068 LTO_section_ipa_reference
,
1073 unsigned int f_count
= streamer_read_uhwi (ib
);
1077 b_count
= streamer_read_hwi (ib
);
1079 fprintf (dump_file
, "all module statics:");
1080 for (i
= 0; i
< (unsigned int)b_count
; i
++)
1082 unsigned int var_index
= streamer_read_uhwi (ib
);
1083 tree v_decl
= lto_file_decl_data_get_var_decl (file_data
,
1085 bitmap_set_bit (all_module_statics
,
1086 ipa_reference_var_uid (v_decl
));
1088 fprintf (dump_file
, " %s", fndecl_name (v_decl
));
1091 for (i
= 0; i
< f_count
; i
++)
1093 unsigned int j
, index
;
1094 struct cgraph_node
*node
;
1096 lto_symtab_encoder_t encoder
;
1098 index
= streamer_read_uhwi (ib
);
1099 encoder
= file_data
->symtab_node_encoder
;
1100 node
= dyn_cast
<cgraph_node
*> (lto_symtab_encoder_deref
1103 ipa_reference_optimization_summary_d
*info
1104 = ipa_ref_opt_sum_summaries
->get_create (node
);
1106 info
->statics_not_read
= BITMAP_ALLOC
1107 (&optimization_summary_obstack
);
1108 info
->statics_not_written
= BITMAP_ALLOC
1109 (&optimization_summary_obstack
);
1112 "\nFunction name:%s:\n static not read:",
1113 node
->dump_asm_name ());
1115 /* Set the statics not read. */
1116 v_count
= streamer_read_hwi (ib
);
1119 info
->statics_not_read
= all_module_statics
;
1121 fprintf (dump_file
, " all module statics");
1124 for (j
= 0; j
< (unsigned int)v_count
; j
++)
1126 unsigned int var_index
= streamer_read_uhwi (ib
);
1127 tree v_decl
= lto_file_decl_data_get_var_decl (file_data
,
1129 bitmap_set_bit (info
->statics_not_read
,
1130 ipa_reference_var_uid (v_decl
));
1132 fprintf (dump_file
, " %s", fndecl_name (v_decl
));
1137 "\n static not written:");
1138 /* Set the statics not written. */
1139 v_count
= streamer_read_hwi (ib
);
1142 info
->statics_not_written
= all_module_statics
;
1144 fprintf (dump_file
, " all module statics");
1147 for (j
= 0; j
< (unsigned int)v_count
; j
++)
1149 unsigned int var_index
= streamer_read_uhwi (ib
);
1150 tree v_decl
= lto_file_decl_data_get_var_decl (file_data
,
1152 bitmap_set_bit (info
->statics_not_written
,
1153 ipa_reference_var_uid (v_decl
));
1155 fprintf (dump_file
, " %s", fndecl_name (v_decl
));
1158 fprintf (dump_file
, "\n");
1161 lto_destroy_simple_input_block (file_data
,
1162 LTO_section_ipa_reference
,
1166 /* Fatal error here. We do not want to support compiling ltrans units
1167 with different version of compiler or different flags than
1168 the WPA unit, so this should never happen. */
1169 fatal_error (input_location
,
1170 "ipa reference summary is missing in ltrans unit");
1176 const pass_data pass_data_ipa_reference
=
1178 IPA_PASS
, /* type */
1179 "static-var", /* name */
1180 OPTGROUP_NONE
, /* optinfo_flags */
1181 TV_IPA_REFERENCE
, /* tv_id */
1182 0, /* properties_required */
1183 0, /* properties_provided */
1184 0, /* properties_destroyed */
1185 0, /* todo_flags_start */
1186 0, /* todo_flags_finish */
1189 class pass_ipa_reference
: public ipa_opt_pass_d
1192 pass_ipa_reference (gcc::context
*ctxt
)
1193 : ipa_opt_pass_d (pass_data_ipa_reference
, ctxt
,
1194 NULL
, /* generate_summary */
1195 NULL
, /* write_summary */
1196 NULL
, /* read_summary */
1197 ipa_reference_write_optimization_summary
, /*
1198 write_optimization_summary */
1199 ipa_reference_read_optimization_summary
, /*
1200 read_optimization_summary */
1201 NULL
, /* stmt_fixup */
1202 0, /* function_transform_todo_flags_start */
1203 NULL
, /* function_transform */
1204 NULL
) /* variable_transform */
1207 /* opt_pass methods: */
1208 virtual bool gate (function
*)
1210 return ((in_lto_p
|| flag_ipa_reference
)
1211 /* Don't bother doing anything if the program has errors. */
1215 virtual unsigned int execute (function
*) { return propagate (); }
1217 }; // class pass_ipa_reference
1222 make_pass_ipa_reference (gcc::context
*ctxt
)
1224 return new pass_ipa_reference (ctxt
);
1227 /* Reset all state within ipa-reference.c so that we can rerun the compiler
1228 within the same process. For use by toplev::finalize. */
1231 ipa_reference_c_finalize (void)
1233 if (ipa_ref_opt_sum_summaries
!= NULL
)
1235 delete ipa_ref_opt_sum_summaries
;
1236 ipa_ref_opt_sum_summaries
= NULL
;
1241 bitmap_obstack_release (&optimization_summary_obstack
);