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 "ipa-utils.h"
50 #include "ipa-reference.h"
51 #include "symbol-summary.h"
53 /* The static variables defined within the compilation unit that are
54 loaded or stored directly by function that owns this structure. */
56 struct ipa_reference_local_vars_info_d
59 bitmap statics_written
;
62 /* Statics that are read and written by some set of functions. The
63 local ones are based on the loads and stores local to the function.
64 The global ones are based on the local info as well as the
65 transitive closure of the functions that are called. */
67 struct ipa_reference_global_vars_info_d
70 bitmap statics_written
;
73 /* Information we save about every function after ipa-reference is completed. */
75 struct ipa_reference_optimization_summary_d
77 bitmap statics_not_read
;
78 bitmap statics_not_written
;
81 typedef ipa_reference_local_vars_info_d
*ipa_reference_local_vars_info_t
;
82 typedef ipa_reference_global_vars_info_d
*ipa_reference_global_vars_info_t
;
83 typedef ipa_reference_optimization_summary_d
*
84 ipa_reference_optimization_summary_t
;
86 struct ipa_reference_vars_info_d
88 struct ipa_reference_local_vars_info_d local
;
89 struct ipa_reference_global_vars_info_d global
;
92 typedef struct ipa_reference_vars_info_d
*ipa_reference_vars_info_t
;
94 /* This map contains all of the static variables that are
95 being considered by the compilation level alias analysis. */
96 typedef hash_map
<int_hash
<unsigned int, -1U>, tree
>
97 reference_vars_to_consider_t
;
98 static reference_vars_to_consider_t
*reference_vars_to_consider
;
100 /* Set of all interesting module statics. A bit is set for every module
101 static we are considering. This is added to the local info when asm
102 code is found that clobbers all memory. */
103 static bitmap all_module_statics
;
104 /* Set of all statics that should be ignored because they are touched by
105 -fno-ipa-reference code. */
106 static bitmap ignore_module_statics
;
108 /* Obstack holding bitmaps of local analysis (live from analysis to
110 static bitmap_obstack local_info_obstack
;
111 /* Obstack holding global analysis live forever. */
112 static bitmap_obstack optimization_summary_obstack
;
114 class ipa_ref_var_info_summary_t
: public fast_function_summary
115 <ipa_reference_vars_info_d
*, va_heap
>
118 ipa_ref_var_info_summary_t (symbol_table
*symtab
):
119 fast_function_summary
<ipa_reference_vars_info_d
*, va_heap
> (symtab
) {}
122 static ipa_ref_var_info_summary_t
*ipa_ref_var_info_summaries
= NULL
;
124 class ipa_ref_opt_summary_t
: public fast_function_summary
125 <ipa_reference_optimization_summary_d
*, va_heap
>
128 ipa_ref_opt_summary_t (symbol_table
*symtab
):
129 fast_function_summary
<ipa_reference_optimization_summary_d
*, va_heap
> (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 cannot 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 return fndecl_name (*reference_vars_to_consider
->get (index
));
279 /* Dump a set of static vars to FILE. */
281 dump_static_vars_set_to_file (FILE *f
, bitmap set
)
287 else if (set
== all_module_statics
)
290 EXECUTE_IF_SET_IN_BITMAP (set
, 0, index
, bi
)
292 fprintf (f
, "%s ", get_static_name (index
));
296 /* Compute X |= Y, taking into account the possibility that
297 either X or Y is already the maximum set.
298 Return true if X is the maximum set after taking the union with Y. */
301 union_static_var_sets (bitmap
&x
, bitmap y
)
303 if (x
!= all_module_statics
)
305 if (y
== all_module_statics
)
308 x
= all_module_statics
;
310 else if (bitmap_ior_into (x
, y
))
312 /* The union may have reduced X to the maximum set.
313 In that case, we want to make that visible explicitly.
314 Even though bitmap_equal_p can be very expensive, it
315 turns out to be an overall win to check this here for
316 an LTO bootstrap of GCC itself. Liberally extrapoliate
317 that result to be applicable to all cases. */
318 if (bitmap_equal_p (x
, all_module_statics
))
321 x
= all_module_statics
;
325 return x
== all_module_statics
;
328 /* Return a copy of SET on the bitmap obstack containing SET.
329 But if SET is NULL or the maximum set, return that instead. */
332 copy_static_var_set (bitmap set
)
334 if (set
== NULL
|| set
== all_module_statics
)
336 bitmap_obstack
*o
= set
->obstack
;
337 gcc_checking_assert (o
);
338 bitmap copy
= BITMAP_ALLOC (o
);
339 bitmap_copy (copy
, set
);
343 /* Compute the union all of the statics read and written by every callee of X
344 into X_GLOBAL->statics_read and X_GLOBAL->statics_written. X_GLOBAL is
345 actually the set representing the cycle containing X. If the read and
346 written sets of X_GLOBAL has been reduced to the maximum set, we don't
347 have to look at the remaining callees. */
350 propagate_bits (ipa_reference_global_vars_info_t x_global
, struct cgraph_node
*x
)
352 struct cgraph_edge
*e
;
353 bool read_all
= x_global
->statics_read
== all_module_statics
;
354 bool write_all
= x_global
->statics_written
== all_module_statics
;
356 e
&& !(read_all
&& write_all
);
359 enum availability avail
;
360 struct cgraph_node
*y
= e
->callee
->function_symbol (&avail
);
364 /* Only look into nodes we can propagate something. */
365 int flags
= flags_from_decl_or_type (y
->decl
);
366 if (opt_for_fn (y
->decl
, flag_ipa_reference
)
367 && (avail
> AVAIL_INTERPOSABLE
368 || (avail
== AVAIL_INTERPOSABLE
&& (flags
& ECF_LEAF
))))
370 if (get_reference_vars_info (y
))
372 ipa_reference_vars_info_t y_info
= get_reference_vars_info (y
);
373 ipa_reference_global_vars_info_t y_global
= &y_info
->global
;
375 /* Calls in the current cycle do not have their global set
376 computed yet (but everything else does because we're
377 visiting nodes in topological order). */
378 if (!y_global
->statics_read
)
381 /* If the function is const, it reads no memory even if it
382 seems so to local analysis. */
383 if (flags
& ECF_CONST
)
386 union_static_var_sets (x_global
->statics_read
,
387 y_global
->statics_read
);
389 /* If the function is pure, it has no stores even if it
390 seems so to local analysis. If we cannot return from
391 the function, we can safely ignore the call. */
392 if ((flags
& ECF_PURE
)
393 || e
->cannot_lead_to_return_p ())
396 union_static_var_sets (x_global
->statics_written
,
397 y_global
->statics_written
);
405 static bool ipa_init_p
= false;
407 /* The init routine for analyzing global static variable usage. See
408 comments at top for description. */
418 reference_vars_to_consider
= new reference_vars_to_consider_t(251);
420 bitmap_obstack_initialize (&local_info_obstack
);
421 bitmap_obstack_initialize (&optimization_summary_obstack
);
422 all_module_statics
= BITMAP_ALLOC (&optimization_summary_obstack
);
423 ignore_module_statics
= BITMAP_ALLOC (&optimization_summary_obstack
);
425 if (ipa_ref_var_info_summaries
== NULL
)
426 ipa_ref_var_info_summaries
= new ipa_ref_var_info_summary_t (symtab
);
428 if (ipa_ref_opt_sum_summaries
!= NULL
)
430 delete ipa_ref_opt_sum_summaries
;
431 ipa_ref_opt_sum_summaries
= NULL
;
436 /* Set up the persistent info for FN. */
438 static ipa_reference_local_vars_info_t
439 init_function_info (struct cgraph_node
*fn
)
441 ipa_reference_vars_info_t info
442 = ipa_ref_var_info_summaries
->get_create (fn
);
444 info
->local
.statics_read
= BITMAP_ALLOC (&local_info_obstack
);
445 info
->local
.statics_written
= BITMAP_ALLOC (&local_info_obstack
);
451 /* This is the main routine for finding the reference patterns for
452 global variables within a function FN. */
455 analyze_function (struct cgraph_node
*fn
)
457 ipa_reference_local_vars_info_t local
;
458 struct ipa_ref
*ref
= NULL
;
462 if (!opt_for_fn (fn
->decl
, flag_ipa_reference
))
464 local
= init_function_info (fn
);
465 for (i
= 0; fn
->iterate_reference (i
, ref
); i
++)
467 if (!is_a
<varpool_node
*> (ref
->referred
))
469 var
= ref
->referred
->decl
;
470 if (!is_proper_for_analysis (var
))
472 /* This is a variable we care about. Check if we have seen it
473 before, and if not add it the set of variables we care about. */
474 if (all_module_statics
475 && bitmap_set_bit (all_module_statics
, ipa_reference_var_uid (var
)))
478 reference_vars_to_consider
->put (ipa_reference_var_uid (var
),
484 bitmap_set_bit (local
->statics_read
, ipa_reference_var_uid (var
));
487 if (ref
->cannot_lead_to_return ())
489 bitmap_set_bit (local
->statics_written
, ipa_reference_var_uid (var
));
498 if (fn
->cannot_return_p ())
499 bitmap_clear (local
->statics_written
);
503 /* Called when new clone is inserted to callgraph late. */
506 ipa_ref_opt_summary_t::duplicate (cgraph_node
*, cgraph_node
*,
507 ipa_reference_optimization_summary_d
*ginfo
,
508 ipa_reference_optimization_summary_d
511 dst_ginfo
->statics_not_read
=
512 copy_static_var_set (ginfo
->statics_not_read
);
513 dst_ginfo
->statics_not_written
=
514 copy_static_var_set (ginfo
->statics_not_written
);
517 /* Called when node is removed. */
520 ipa_ref_opt_summary_t::remove (cgraph_node
*,
521 ipa_reference_optimization_summary_d
*ginfo
)
523 if (ginfo
->statics_not_read
524 && ginfo
->statics_not_read
!= all_module_statics
)
525 BITMAP_FREE (ginfo
->statics_not_read
);
527 if (ginfo
->statics_not_written
528 && ginfo
->statics_not_written
!= all_module_statics
)
529 BITMAP_FREE (ginfo
->statics_not_written
);
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 if (!node
->alias
&& !opt_for_fn (node
->decl
, flag_ipa_reference
))
548 struct ipa_ref
*ref
= NULL
;
551 for (i
= 0; node
->iterate_reference (i
, ref
); i
++)
553 if (!is_a
<varpool_node
*> (ref
->referred
))
555 var
= ref
->referred
->decl
;
556 if (!is_proper_for_analysis (var
))
558 bitmap_set_bit (ignore_module_statics
, ipa_reference_var_uid (var
));
561 FOR_EACH_DEFINED_FUNCTION (node
)
562 analyze_function (node
);
565 EXECUTE_IF_SET_IN_BITMAP (all_module_statics
, 0, index
, bi
)
567 fprintf (dump_file
, "\nPromotable global:%s (uid=%u)\n",
568 get_static_name (index
), index
);
572 FOR_EACH_DEFINED_FUNCTION (node
)
573 if (node
->get_availability () >= AVAIL_INTERPOSABLE
574 && opt_for_fn (node
->decl
, flag_ipa_reference
))
576 ipa_reference_local_vars_info_t l
;
580 l
= &get_reference_vars_info (node
)->local
;
582 "\nFunction name:%s:", node
->dump_name ());
583 fprintf (dump_file
, "\n locals read: ");
585 EXECUTE_IF_SET_IN_BITMAP (l
->statics_read
,
588 fprintf (dump_file
, "%s ",
589 get_static_name (index
));
591 fprintf (dump_file
, "\n locals written: ");
592 if (l
->statics_written
)
593 EXECUTE_IF_SET_IN_BITMAP (l
->statics_written
,
596 fprintf (dump_file
, "%s ", get_static_name (index
));
601 /* Set READ_ALL/WRITE_ALL based on decl flags of NODE. */
604 read_write_all_from_decl (struct cgraph_node
*node
,
605 bool &read_all
, bool &write_all
)
607 tree decl
= node
->decl
;
608 int flags
= flags_from_decl_or_type (decl
);
609 if ((flags
& ECF_LEAF
)
610 && node
->get_availability () < AVAIL_INTERPOSABLE
)
612 else if (flags
& ECF_CONST
)
614 else if ((flags
& ECF_PURE
) || node
->cannot_return_p ())
617 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
618 fprintf (dump_file
, " %s -> read all\n", node
->dump_name ());
622 /* TODO: To be able to produce sane results, we should also handle
623 common builtins, in particular throw. */
626 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
627 fprintf (dump_file
, " %s -> read all, write all\n",
632 /* Set READ_ALL/WRITE_ALL based on decl flags of NODE or any member
633 in the cycle of NODE. */
636 get_read_write_all_from_node (struct cgraph_node
*node
,
637 bool &read_all
, bool &write_all
)
639 struct cgraph_edge
*e
, *ie
;
641 /* When function is overwritable, we cannot assume anything. */
642 if (node
->get_availability () <= AVAIL_INTERPOSABLE
643 || (node
->analyzed
&& !opt_for_fn (node
->decl
, flag_ipa_reference
)))
644 read_write_all_from_decl (node
, read_all
, write_all
);
646 for (e
= node
->callees
;
647 e
&& !(read_all
&& write_all
);
650 enum availability avail
;
651 struct cgraph_node
*callee
= e
->callee
->function_symbol (&avail
);
652 gcc_checking_assert (callee
);
653 if (avail
<= AVAIL_INTERPOSABLE
654 || (callee
->analyzed
&& !opt_for_fn (callee
->decl
,
655 flag_ipa_reference
)))
656 read_write_all_from_decl (callee
, read_all
, write_all
);
659 for (ie
= node
->indirect_calls
;
660 ie
&& !(read_all
&& write_all
);
661 ie
= ie
->next_callee
)
662 if (!(ie
->indirect_info
->ecf_flags
& ECF_CONST
))
665 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
666 fprintf (dump_file
, " indirect call -> read all\n");
667 if (!ie
->cannot_lead_to_return_p ()
668 && !(ie
->indirect_info
->ecf_flags
& ECF_PURE
))
670 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
671 fprintf (dump_file
, " indirect call -> write all\n");
677 /* Skip edges from and to nodes without ipa_reference enabled.
678 Ignore not available symbols. This leave
679 them out of strongly connected components and makes them easy to skip in the
680 propagation loop bellow. */
683 ignore_edge_p (cgraph_edge
*e
)
685 enum availability avail
;
686 cgraph_node
*ultimate_target
687 = e
->callee
->function_or_virtual_thunk_symbol (&avail
, e
->caller
);
689 return (avail
< AVAIL_INTERPOSABLE
690 || (avail
== AVAIL_INTERPOSABLE
691 && !(flags_from_decl_or_type (e
->callee
->decl
) & ECF_LEAF
))
692 || !opt_for_fn (e
->caller
->decl
, flag_ipa_reference
)
693 || !opt_for_fn (ultimate_target
->decl
, flag_ipa_reference
));
696 /* Produce the global information by preforming a transitive closure
697 on the local information that was produced by ipa_analyze_function. */
702 struct cgraph_node
*node
;
703 struct cgraph_node
**order
=
704 XCNEWVEC (struct cgraph_node
*, symtab
->cgraph_count
);
710 cgraph_node::dump_cgraph (dump_file
);
712 remove_p
= ipa_discover_variable_flags ();
715 /* Propagate the local information through the call graph to produce
716 the global information. All the nodes within a cycle will have
717 the same info so we collapse cycles first. Then we can do the
718 propagation in one pass from the leaves to the roots. */
719 order_pos
= ipa_reduced_postorder (order
, true, ignore_edge_p
);
721 ipa_print_order (dump_file
, "reduced", order
, order_pos
);
723 for (i
= 0; i
< order_pos
; i
++ )
726 struct cgraph_node
*w
;
727 ipa_reference_vars_info_t node_info
;
728 ipa_reference_global_vars_info_t node_g
;
729 ipa_reference_local_vars_info_t node_l
;
730 bool read_all
= false;
731 bool write_all
= false;
734 if (node
->alias
|| !opt_for_fn (node
->decl
, flag_ipa_reference
))
737 node_info
= get_reference_vars_info (node
);
738 gcc_assert (node_info
);
739 node_l
= &node_info
->local
;
740 node_g
= &node_info
->global
;
742 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
743 fprintf (dump_file
, "Starting cycle with %s\n", node
->dump_name ());
745 vec
<cgraph_node
*> cycle_nodes
= ipa_get_nodes_in_cycle (node
);
747 /* If any node in a cycle is read_all or write_all, they all are. */
748 FOR_EACH_VEC_ELT (cycle_nodes
, x
, w
)
750 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
751 fprintf (dump_file
, " Visiting %s\n", w
->dump_asm_name ());
752 get_read_write_all_from_node (w
, read_all
, write_all
);
753 if (read_all
&& write_all
)
757 /* Initialized the bitmaps global sets for the reduced node. */
759 node_g
->statics_read
= all_module_statics
;
761 node_g
->statics_read
= copy_static_var_set (node_l
->statics_read
);
763 node_g
->statics_written
= all_module_statics
;
765 node_g
->statics_written
= copy_static_var_set (node_l
->statics_written
);
767 /* Merge the sets of this cycle with all sets of callees reached
769 FOR_EACH_VEC_ELT (cycle_nodes
, x
, w
)
771 if (read_all
&& write_all
)
776 ipa_reference_vars_info_t w_ri
= get_reference_vars_info (w
);
777 ipa_reference_local_vars_info_t w_l
= &w_ri
->local
;
778 int flags
= flags_from_decl_or_type (w
->decl
);
780 if (!(flags
& ECF_CONST
))
781 read_all
= union_static_var_sets (node_g
->statics_read
,
783 if (!(flags
& ECF_PURE
)
784 && !w
->cannot_return_p ())
785 write_all
= union_static_var_sets (node_g
->statics_written
,
786 w_l
->statics_written
);
789 propagate_bits (node_g
, w
);
792 /* All nodes within a cycle have the same global info bitmaps. */
793 FOR_EACH_VEC_ELT (cycle_nodes
, x
, w
)
795 ipa_reference_vars_info_t w_ri
= get_reference_vars_info (w
);
796 w_ri
->global
= *node_g
;
799 cycle_nodes
.release ();
804 for (i
= 0; i
< order_pos
; i
++)
807 struct cgraph_node
*w
;
810 if (node
->alias
|| !opt_for_fn (node
->decl
, flag_ipa_reference
))
813 fprintf (dump_file
, "\nFunction name:%s:", node
->dump_asm_name ());
815 ipa_reference_vars_info_t node_info
= get_reference_vars_info (node
);
816 ipa_reference_global_vars_info_t node_g
= &node_info
->global
;
818 vec
<cgraph_node
*> cycle_nodes
= ipa_get_nodes_in_cycle (node
);
819 FOR_EACH_VEC_ELT (cycle_nodes
, x
, w
)
821 ipa_reference_vars_info_t w_ri
= get_reference_vars_info (w
);
822 ipa_reference_local_vars_info_t w_l
= &w_ri
->local
;
824 fprintf (dump_file
, "\n next cycle: %s ", w
->dump_asm_name ());
825 fprintf (dump_file
, "\n locals read: ");
826 dump_static_vars_set_to_file (dump_file
, w_l
->statics_read
);
827 fprintf (dump_file
, "\n locals written: ");
828 dump_static_vars_set_to_file (dump_file
, w_l
->statics_written
);
830 cycle_nodes
.release ();
832 fprintf (dump_file
, "\n globals read: ");
833 dump_static_vars_set_to_file (dump_file
, node_g
->statics_read
);
834 fprintf (dump_file
, "\n globals written: ");
835 dump_static_vars_set_to_file (dump_file
, node_g
->statics_written
);
836 fprintf (dump_file
, "\n");
840 if (ipa_ref_opt_sum_summaries
== NULL
)
841 ipa_ref_opt_sum_summaries
= new ipa_ref_opt_summary_t (symtab
);
844 FOR_EACH_DEFINED_FUNCTION (node
)
846 ipa_reference_vars_info_t node_info
;
847 ipa_reference_global_vars_info_t node_g
;
849 node_info
= get_reference_vars_info (node
);
850 if (!node
->alias
&& opt_for_fn (node
->decl
, flag_ipa_reference
)
851 && (node
->get_availability () > AVAIL_INTERPOSABLE
852 || (flags_from_decl_or_type (node
->decl
) & ECF_LEAF
)))
854 node_g
= &node_info
->global
;
856 ipa_reference_optimization_summary_d
*opt
857 = ipa_ref_opt_sum_summaries
->get_create (node
);
859 /* Create the complimentary sets. */
861 if (bitmap_empty_p (node_g
->statics_read
))
862 opt
->statics_not_read
= all_module_statics
;
865 opt
->statics_not_read
866 = BITMAP_ALLOC (&optimization_summary_obstack
);
867 if (node_g
->statics_read
!= all_module_statics
)
868 bitmap_and_compl (opt
->statics_not_read
,
870 node_g
->statics_read
);
873 if (bitmap_empty_p (node_g
->statics_written
))
874 opt
->statics_not_written
= all_module_statics
;
877 opt
->statics_not_written
878 = BITMAP_ALLOC (&optimization_summary_obstack
);
879 if (node_g
->statics_written
!= all_module_statics
)
880 bitmap_and_compl (opt
->statics_not_written
,
882 node_g
->statics_written
);
887 ipa_free_postorder_info ();
890 bitmap_obstack_release (&local_info_obstack
);
892 if (ipa_ref_var_info_summaries
!= NULL
)
894 delete ipa_ref_var_info_summaries
;
895 ipa_ref_var_info_summaries
= NULL
;
899 delete reference_vars_to_consider
;
900 reference_vars_to_consider
= NULL
;
901 return remove_p
? TODO_remove_functions
: 0;
904 /* Return true if we need to write summary of NODE. */
907 write_node_summary_p (struct cgraph_node
*node
,
908 lto_symtab_encoder_t encoder
,
909 bitmap ltrans_statics
)
911 ipa_reference_optimization_summary_t info
;
913 /* See if we have (non-empty) info. */
914 if (!node
->definition
|| node
->global
.inlined_to
)
916 info
= get_reference_optimization_summary (node
);
918 || (bitmap_empty_p (info
->statics_not_read
)
919 && bitmap_empty_p (info
->statics_not_written
)))
922 /* See if we want to encode it.
923 Encode also referenced functions since constant folding might turn it into
926 In future we might also want to include summaries of functions references
927 by initializers of constant variables references in current unit. */
928 if (!reachable_from_this_partition_p (node
, encoder
)
929 && !referenced_from_this_partition_p (node
, encoder
))
932 /* See if the info has non-empty intersections with vars we want to encode. */
933 if (!bitmap_intersect_p (info
->statics_not_read
, ltrans_statics
)
934 && !bitmap_intersect_p (info
->statics_not_written
, ltrans_statics
))
939 /* Stream out BITS<RANS_STATICS as list of decls to OB.
940 LTRANS_STATICS_BITCOUNT specify number of bits in LTRANS_STATICS
941 or -1. When it is positive, just output -1 when
942 BITS<RANS_STATICS == BITS<RANS_STATICS. */
945 stream_out_bitmap (struct lto_simple_output_block
*ob
,
946 bitmap bits
, bitmap ltrans_statics
,
947 int ltrans_statics_bitcount
)
952 if (bits
== all_module_statics
)
954 streamer_write_hwi_stream (ob
->main_stream
, -1);
957 EXECUTE_IF_AND_IN_BITMAP (bits
, ltrans_statics
, 0, index
, bi
)
959 if (count
== ltrans_statics_bitcount
)
961 streamer_write_hwi_stream (ob
->main_stream
, -1);
964 streamer_write_hwi_stream (ob
->main_stream
, count
);
967 EXECUTE_IF_AND_IN_BITMAP (bits
, ltrans_statics
, 0, index
, bi
)
969 tree decl
= *reference_vars_to_consider
->get (index
);
970 lto_output_var_decl_index (ob
->decl_state
, ob
->main_stream
, decl
);
974 /* Serialize the ipa info for lto. */
977 ipa_reference_write_optimization_summary (void)
979 struct lto_simple_output_block
*ob
980 = lto_create_simple_output_block (LTO_section_ipa_reference
);
981 unsigned int count
= 0;
982 int ltrans_statics_bitcount
= 0;
983 lto_symtab_encoder_t encoder
= ob
->decl_state
->symtab_node_encoder
;
984 auto_bitmap ltrans_statics
;
987 reference_vars_to_consider
= new reference_vars_to_consider_t (251);
989 /* See what variables we are interested in. */
990 for (i
= 0; i
< lto_symtab_encoder_size (encoder
); i
++)
992 symtab_node
*snode
= lto_symtab_encoder_deref (encoder
, i
);
993 varpool_node
*vnode
= dyn_cast
<varpool_node
*> (snode
);
995 && bitmap_bit_p (all_module_statics
,
996 ipa_reference_var_uid (vnode
->decl
))
997 && referenced_from_this_partition_p (vnode
, encoder
))
999 tree decl
= vnode
->decl
;
1000 bitmap_set_bit (ltrans_statics
, ipa_reference_var_uid (decl
));
1001 reference_vars_to_consider
->put
1002 (ipa_reference_var_uid (decl
), decl
);
1003 ltrans_statics_bitcount
++;
1008 if (ltrans_statics_bitcount
)
1009 for (i
= 0; i
< lto_symtab_encoder_size (encoder
); i
++)
1011 symtab_node
*snode
= lto_symtab_encoder_deref (encoder
, i
);
1012 cgraph_node
*cnode
= dyn_cast
<cgraph_node
*> (snode
);
1013 if (cnode
&& write_node_summary_p (cnode
, encoder
, ltrans_statics
))
1017 streamer_write_uhwi_stream (ob
->main_stream
, count
);
1019 stream_out_bitmap (ob
, ltrans_statics
, ltrans_statics
,
1022 /* Process all of the functions. */
1023 if (ltrans_statics_bitcount
)
1024 for (i
= 0; i
< lto_symtab_encoder_size (encoder
); i
++)
1026 symtab_node
*snode
= lto_symtab_encoder_deref (encoder
, i
);
1027 cgraph_node
*cnode
= dyn_cast
<cgraph_node
*> (snode
);
1028 if (cnode
&& write_node_summary_p (cnode
, encoder
, ltrans_statics
))
1030 ipa_reference_optimization_summary_t info
;
1033 info
= get_reference_optimization_summary (cnode
);
1034 node_ref
= lto_symtab_encoder_encode (encoder
, snode
);
1035 streamer_write_uhwi_stream (ob
->main_stream
, node_ref
);
1037 stream_out_bitmap (ob
, info
->statics_not_read
, ltrans_statics
,
1038 ltrans_statics_bitcount
);
1039 stream_out_bitmap (ob
, info
->statics_not_written
, ltrans_statics
,
1040 ltrans_statics_bitcount
);
1043 lto_destroy_simple_output_block (ob
);
1044 delete reference_vars_to_consider
;
1047 /* Deserialize the ipa info for lto. */
1050 ipa_reference_read_optimization_summary (void)
1052 struct lto_file_decl_data
** file_data_vec
1053 = lto_get_file_decl_data ();
1054 struct lto_file_decl_data
* file_data
;
1056 bitmap_obstack_initialize (&optimization_summary_obstack
);
1058 if (ipa_ref_opt_sum_summaries
== NULL
)
1059 ipa_ref_opt_sum_summaries
= new ipa_ref_opt_summary_t (symtab
);
1061 all_module_statics
= BITMAP_ALLOC (&optimization_summary_obstack
);
1063 while ((file_data
= file_data_vec
[j
++]))
1067 class lto_input_block
*ib
1068 = lto_create_simple_input_block (file_data
,
1069 LTO_section_ipa_reference
,
1074 unsigned int f_count
= streamer_read_uhwi (ib
);
1078 b_count
= streamer_read_hwi (ib
);
1080 fprintf (dump_file
, "all module statics:");
1081 for (i
= 0; i
< (unsigned int)b_count
; i
++)
1083 unsigned int var_index
= streamer_read_uhwi (ib
);
1084 tree v_decl
= lto_file_decl_data_get_var_decl (file_data
,
1086 bitmap_set_bit (all_module_statics
,
1087 ipa_reference_var_uid (v_decl
));
1089 fprintf (dump_file
, " %s", fndecl_name (v_decl
));
1092 for (i
= 0; i
< f_count
; i
++)
1094 unsigned int j
, index
;
1095 struct cgraph_node
*node
;
1097 lto_symtab_encoder_t encoder
;
1099 index
= streamer_read_uhwi (ib
);
1100 encoder
= file_data
->symtab_node_encoder
;
1101 node
= dyn_cast
<cgraph_node
*> (lto_symtab_encoder_deref
1104 ipa_reference_optimization_summary_d
*info
1105 = ipa_ref_opt_sum_summaries
->get_create (node
);
1107 info
->statics_not_read
= BITMAP_ALLOC
1108 (&optimization_summary_obstack
);
1109 info
->statics_not_written
= BITMAP_ALLOC
1110 (&optimization_summary_obstack
);
1113 "\nFunction name:%s:\n static not read:",
1114 node
->dump_asm_name ());
1116 /* Set the statics not read. */
1117 v_count
= streamer_read_hwi (ib
);
1120 info
->statics_not_read
= all_module_statics
;
1122 fprintf (dump_file
, " all module statics");
1125 for (j
= 0; j
< (unsigned int)v_count
; j
++)
1127 unsigned int var_index
= streamer_read_uhwi (ib
);
1128 tree v_decl
= lto_file_decl_data_get_var_decl (file_data
,
1130 bitmap_set_bit (info
->statics_not_read
,
1131 ipa_reference_var_uid (v_decl
));
1133 fprintf (dump_file
, " %s", fndecl_name (v_decl
));
1138 "\n static not written:");
1139 /* Set the statics not written. */
1140 v_count
= streamer_read_hwi (ib
);
1143 info
->statics_not_written
= all_module_statics
;
1145 fprintf (dump_file
, " all module statics");
1148 for (j
= 0; j
< (unsigned int)v_count
; j
++)
1150 unsigned int var_index
= streamer_read_uhwi (ib
);
1151 tree v_decl
= lto_file_decl_data_get_var_decl (file_data
,
1153 bitmap_set_bit (info
->statics_not_written
,
1154 ipa_reference_var_uid (v_decl
));
1156 fprintf (dump_file
, " %s", fndecl_name (v_decl
));
1159 fprintf (dump_file
, "\n");
1162 lto_destroy_simple_input_block (file_data
,
1163 LTO_section_ipa_reference
,
1167 /* Fatal error here. We do not want to support compiling ltrans units
1168 with different version of compiler or different flags than
1169 the WPA unit, so this should never happen. */
1170 fatal_error (input_location
,
1171 "ipa reference summary is missing in ltrans unit");
1177 const pass_data pass_data_ipa_reference
=
1179 IPA_PASS
, /* type */
1180 "static-var", /* name */
1181 OPTGROUP_NONE
, /* optinfo_flags */
1182 TV_IPA_REFERENCE
, /* tv_id */
1183 0, /* properties_required */
1184 0, /* properties_provided */
1185 0, /* properties_destroyed */
1186 0, /* todo_flags_start */
1187 0, /* todo_flags_finish */
1190 class pass_ipa_reference
: public ipa_opt_pass_d
1193 pass_ipa_reference (gcc::context
*ctxt
)
1194 : ipa_opt_pass_d (pass_data_ipa_reference
, ctxt
,
1195 NULL
, /* generate_summary */
1196 NULL
, /* write_summary */
1197 NULL
, /* read_summary */
1198 ipa_reference_write_optimization_summary
, /*
1199 write_optimization_summary */
1200 ipa_reference_read_optimization_summary
, /*
1201 read_optimization_summary */
1202 NULL
, /* stmt_fixup */
1203 0, /* function_transform_todo_flags_start */
1204 NULL
, /* function_transform */
1205 NULL
) /* variable_transform */
1208 /* opt_pass methods: */
1209 virtual bool gate (function
*)
1211 return ((in_lto_p
|| flag_ipa_reference
)
1212 /* Don't bother doing anything if the program has errors. */
1216 virtual unsigned int execute (function
*) { return propagate (); }
1218 }; // class pass_ipa_reference
1223 make_pass_ipa_reference (gcc::context
*ctxt
)
1225 return new pass_ipa_reference (ctxt
);
1228 /* Reset all state within ipa-reference.c so that we can rerun the compiler
1229 within the same process. For use by toplev::finalize. */
1232 ipa_reference_c_finalize (void)
1234 if (ipa_ref_opt_sum_summaries
!= NULL
)
1236 delete ipa_ref_opt_sum_summaries
;
1237 ipa_ref_opt_sum_summaries
= NULL
;
1242 bitmap_obstack_release (&optimization_summary_obstack
);