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
<tree
, int> reference_vars_map_t
;
97 static reference_vars_map_t
*ipa_reference_vars_map
;
98 static int ipa_reference_vars_uids
;
99 static vec
<tree
> *reference_vars_to_consider
;
100 varpool_node_hook_list
*varpool_node_hooks
;
102 /* Set of all interesting module statics. A bit is set for every module
103 static we are considering. This is added to the local info when asm
104 code is found that clobbers all memory. */
105 static bitmap all_module_statics
;
106 /* Set of all statics that should be ignored because they are touched by
107 -fno-ipa-reference code. */
108 static bitmap ignore_module_statics
;
110 /* Obstack holding bitmaps of local analysis (live from analysis to
112 static bitmap_obstack local_info_obstack
;
113 /* Obstack holding global analysis live forever. */
114 static bitmap_obstack optimization_summary_obstack
;
116 class ipa_ref_var_info_summary_t
: public fast_function_summary
117 <ipa_reference_vars_info_d
*, va_heap
>
120 ipa_ref_var_info_summary_t (symbol_table
*symtab
):
121 fast_function_summary
<ipa_reference_vars_info_d
*, va_heap
> (symtab
) {}
124 static ipa_ref_var_info_summary_t
*ipa_ref_var_info_summaries
= NULL
;
126 class ipa_ref_opt_summary_t
: public fast_function_summary
127 <ipa_reference_optimization_summary_d
*, va_heap
>
130 ipa_ref_opt_summary_t (symbol_table
*symtab
):
131 fast_function_summary
<ipa_reference_optimization_summary_d
*, va_heap
> (symtab
) {}
133 virtual void remove (cgraph_node
*src_node
,
134 ipa_reference_optimization_summary_d
*data
);
135 virtual void duplicate (cgraph_node
*src_node
, cgraph_node
*dst_node
,
136 ipa_reference_optimization_summary_d
*src_data
,
137 ipa_reference_optimization_summary_d
*dst_data
);
140 static ipa_ref_opt_summary_t
*ipa_ref_opt_sum_summaries
= NULL
;
142 /* Return ID used by ipa-reference bitmaps. -1 if failed. */
144 ipa_reference_var_uid (tree t
)
146 if (!ipa_reference_vars_map
)
148 int *id
= ipa_reference_vars_map
->get
149 (symtab_node::get (t
)->ultimate_alias_target (NULL
)->decl
);
155 /* Return ID used by ipa-reference bitmaps. Create new entry if
156 T is not in map. Set EXISTED accordinly */
158 ipa_reference_var_get_or_insert_uid (tree t
, bool *existed
)
160 int &id
= ipa_reference_vars_map
->get_or_insert
161 (symtab_node::get (t
)->ultimate_alias_target (NULL
)->decl
, existed
);
163 id
= ipa_reference_vars_uids
++;
167 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
168 static inline ipa_reference_vars_info_t
169 get_reference_vars_info (struct cgraph_node
*node
)
171 if (ipa_ref_var_info_summaries
== NULL
)
174 ipa_reference_vars_info_t v
= ipa_ref_var_info_summaries
->get (node
);
175 return v
== NULL
? NULL
: v
;
178 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
179 static inline ipa_reference_optimization_summary_t
180 get_reference_optimization_summary (struct cgraph_node
*node
)
182 if (ipa_ref_opt_sum_summaries
== NULL
)
185 ipa_reference_optimization_summary_t v
186 = ipa_ref_opt_sum_summaries
->get (node
);
188 return v
== NULL
? NULL
: v
;
191 /* Return a bitmap indexed by ipa_reference_var_uid for the static variables
192 that are *not* read during the execution of the function FN. Returns
193 NULL if no data is available. */
196 ipa_reference_get_not_read_global (struct cgraph_node
*fn
)
198 if (!opt_for_fn (current_function_decl
, flag_ipa_reference
))
201 enum availability avail
;
202 struct cgraph_node
*fn2
= fn
->function_symbol (&avail
);
203 ipa_reference_optimization_summary_t info
=
204 get_reference_optimization_summary (fn2
);
207 && (avail
>= AVAIL_AVAILABLE
208 || (avail
== AVAIL_INTERPOSABLE
209 && flags_from_decl_or_type (fn
->decl
) & ECF_LEAF
))
210 && opt_for_fn (fn2
->decl
, flag_ipa_reference
))
211 return info
->statics_not_read
;
212 else if (avail
== AVAIL_NOT_AVAILABLE
213 && flags_from_decl_or_type (fn
->decl
) & ECF_LEAF
)
214 return all_module_statics
;
219 /* Return a bitmap indexed by ipa_reference_var_uid for the static variables
220 that are *not* written during the execution of the function FN. Note
221 that variables written may or may not be read during the function
222 call. Returns NULL if no data is available. */
225 ipa_reference_get_not_written_global (struct cgraph_node
*fn
)
227 if (!opt_for_fn (current_function_decl
, flag_ipa_reference
))
230 enum availability avail
;
231 struct cgraph_node
*fn2
= fn
->function_symbol (&avail
);
232 ipa_reference_optimization_summary_t info
=
233 get_reference_optimization_summary (fn2
);
236 && (avail
>= AVAIL_AVAILABLE
237 || (avail
== AVAIL_INTERPOSABLE
238 && flags_from_decl_or_type (fn
->decl
) & ECF_LEAF
))
239 && opt_for_fn (fn2
->decl
, flag_ipa_reference
))
240 return info
->statics_not_written
;
241 else if (avail
== AVAIL_NOT_AVAILABLE
242 && flags_from_decl_or_type (fn
->decl
) & ECF_LEAF
)
243 return all_module_statics
;
249 /* Hepler for is_proper_for_analysis. */
251 is_improper (symtab_node
*n
, void *v ATTRIBUTE_UNUSED
)
254 /* If the variable has the "used" attribute, treat it as if it had a
255 been touched by the devil. */
256 if (DECL_PRESERVE_P (t
))
259 /* Do not want to do anything with volatile except mark any
260 function that uses one to be not const or pure. */
261 if (TREE_THIS_VOLATILE (t
))
264 /* We do not need to analyze readonly vars, we already know they do not
266 if (TREE_READONLY (t
))
269 /* We cannot track variables with address taken. */
270 if (TREE_ADDRESSABLE (t
))
273 /* TODO: We could track public variables that are not addressable, but
274 currently frontends don't give us those. */
281 /* Return true if the variable T is the right kind of static variable to
282 perform compilation unit scope escape analysis. */
285 is_proper_for_analysis (tree t
)
287 int id
= ipa_reference_var_uid (t
);
289 if (id
!= -1 && bitmap_bit_p (ignore_module_statics
, id
))
292 if (symtab_node::get (t
)
293 ->call_for_symbol_and_aliases (is_improper
, NULL
, true))
299 /* Lookup the tree node for the static variable that has UID and
300 convert the name to a string for debugging. */
303 get_static_name (int index
)
305 return fndecl_name ((*reference_vars_to_consider
)[index
]);
308 /* Dump a set of static vars to FILE. */
310 dump_static_vars_set_to_file (FILE *f
, bitmap set
)
316 else if (set
== all_module_statics
)
319 EXECUTE_IF_SET_IN_BITMAP (set
, 0, index
, bi
)
321 fprintf (f
, "%s ", get_static_name (index
));
325 /* Compute X |= Y, taking into account the possibility that
326 either X or Y is already the maximum set.
327 Return true if X is the maximum set after taking the union with Y. */
330 union_static_var_sets (bitmap
&x
, bitmap y
)
332 if (x
!= all_module_statics
)
334 if (y
== all_module_statics
)
337 x
= all_module_statics
;
339 else if (bitmap_ior_into (x
, y
))
341 /* The union may have reduced X to the maximum set.
342 In that case, we want to make that visible explicitly.
343 Even though bitmap_equal_p can be very expensive, it
344 turns out to be an overall win to check this here for
345 an LTO bootstrap of GCC itself. Liberally extrapoliate
346 that result to be applicable to all cases. */
347 if (bitmap_equal_p (x
, all_module_statics
))
350 x
= all_module_statics
;
354 return x
== all_module_statics
;
357 /* Return a copy of SET on the bitmap obstack containing SET.
358 But if SET is NULL or the maximum set, return that instead. */
361 copy_static_var_set (bitmap set
)
363 if (set
== NULL
|| set
== all_module_statics
)
365 bitmap_obstack
*o
= set
->obstack
;
366 gcc_checking_assert (o
);
367 bitmap copy
= BITMAP_ALLOC (o
);
368 bitmap_copy (copy
, set
);
372 /* Compute the union all of the statics read and written by every callee of X
373 into X_GLOBAL->statics_read and X_GLOBAL->statics_written. X_GLOBAL is
374 actually the set representing the cycle containing X. If the read and
375 written sets of X_GLOBAL has been reduced to the maximum set, we don't
376 have to look at the remaining callees. */
379 propagate_bits (ipa_reference_global_vars_info_t x_global
, struct cgraph_node
*x
)
381 struct cgraph_edge
*e
;
382 bool read_all
= x_global
->statics_read
== all_module_statics
;
383 bool write_all
= x_global
->statics_written
== all_module_statics
;
385 e
&& !(read_all
&& write_all
);
388 enum availability avail
;
389 struct cgraph_node
*y
= e
->callee
->function_symbol (&avail
);
393 /* Only look into nodes we can propagate something. */
394 int flags
= flags_from_decl_or_type (y
->decl
);
395 if (opt_for_fn (y
->decl
, flag_ipa_reference
)
396 && (avail
> AVAIL_INTERPOSABLE
397 || (avail
== AVAIL_INTERPOSABLE
&& (flags
& ECF_LEAF
))))
399 if (get_reference_vars_info (y
))
401 ipa_reference_vars_info_t y_info
= get_reference_vars_info (y
);
402 ipa_reference_global_vars_info_t y_global
= &y_info
->global
;
404 /* Calls in the current cycle do not have their global set
405 computed yet (but everything else does because we're
406 visiting nodes in topological order). */
407 if (!y_global
->statics_read
)
410 /* If the function is const, it reads no memory even if it
411 seems so to local analysis. */
412 if (flags
& ECF_CONST
)
415 union_static_var_sets (x_global
->statics_read
,
416 y_global
->statics_read
);
418 /* If the function is pure, it has no stores even if it
419 seems so to local analysis. If we cannot return from
420 the function, we can safely ignore the call. */
421 if ((flags
& ECF_PURE
)
422 || e
->cannot_lead_to_return_p ())
425 union_static_var_sets (x_global
->statics_written
,
426 y_global
->statics_written
);
434 /* Delete NODE from map. */
437 varpool_removal_hook (varpool_node
*node
, void *)
439 int *id
= ipa_reference_vars_map
->get (node
->decl
)
441 ipa_reference_vars_map
->remove (*id
);
444 static bool ipa_init_p
= false;
446 /* The init routine for analyzing global static variable usage. See
447 comments at top for description. */
456 vec_alloc (reference_vars_to_consider
, 10);
459 if (ipa_ref_opt_sum_summaries
!= NULL
)
461 delete ipa_ref_opt_sum_summaries
;
462 ipa_ref_opt_sum_summaries
= NULL
;
463 delete ipa_reference_vars_map
;
465 ipa_reference_vars_map
= new reference_vars_map_t(257);
467 = symtab
->add_varpool_removal_hook (varpool_removal_hook
, NULL
);
468 ipa_reference_vars_uids
= 0;
470 bitmap_obstack_initialize (&local_info_obstack
);
471 bitmap_obstack_initialize (&optimization_summary_obstack
);
472 all_module_statics
= BITMAP_ALLOC (&optimization_summary_obstack
);
473 ignore_module_statics
= BITMAP_ALLOC (&optimization_summary_obstack
);
475 if (ipa_ref_var_info_summaries
== NULL
)
476 ipa_ref_var_info_summaries
= new ipa_ref_var_info_summary_t (symtab
);
480 /* Set up the persistent info for FN. */
482 static ipa_reference_local_vars_info_t
483 init_function_info (struct cgraph_node
*fn
)
485 ipa_reference_vars_info_t info
486 = ipa_ref_var_info_summaries
->get_create (fn
);
488 info
->local
.statics_read
= BITMAP_ALLOC (&local_info_obstack
);
489 info
->local
.statics_written
= BITMAP_ALLOC (&local_info_obstack
);
495 /* This is the main routine for finding the reference patterns for
496 global variables within a function FN. */
499 analyze_function (struct cgraph_node
*fn
)
501 ipa_reference_local_vars_info_t local
;
502 struct ipa_ref
*ref
= NULL
;
506 if (!opt_for_fn (fn
->decl
, flag_ipa_reference
))
508 local
= init_function_info (fn
);
509 for (i
= 0; fn
->iterate_reference (i
, ref
); i
++)
513 if (!is_a
<varpool_node
*> (ref
->referred
))
515 var
= ref
->referred
->decl
;
516 if (!is_proper_for_analysis (var
))
518 /* This is a variable we care about. Check if we have seen it
519 before, and if not add it the set of variables we care about. */
520 id
= ipa_reference_var_get_or_insert_uid (var
, &existed
);
523 bitmap_set_bit (all_module_statics
, id
);
525 reference_vars_to_consider
->safe_push (var
);
530 bitmap_set_bit (local
->statics_read
, id
);
533 if (ref
->cannot_lead_to_return ())
535 bitmap_set_bit (local
->statics_written
, id
);
544 if (fn
->cannot_return_p ())
545 bitmap_clear (local
->statics_written
);
549 /* Called when new clone is inserted to callgraph late. */
552 ipa_ref_opt_summary_t::duplicate (cgraph_node
*, cgraph_node
*,
553 ipa_reference_optimization_summary_d
*ginfo
,
554 ipa_reference_optimization_summary_d
557 dst_ginfo
->statics_not_read
=
558 copy_static_var_set (ginfo
->statics_not_read
);
559 dst_ginfo
->statics_not_written
=
560 copy_static_var_set (ginfo
->statics_not_written
);
563 /* Called when node is removed. */
566 ipa_ref_opt_summary_t::remove (cgraph_node
*,
567 ipa_reference_optimization_summary_d
*ginfo
)
569 if (ginfo
->statics_not_read
570 && ginfo
->statics_not_read
!= all_module_statics
)
571 BITMAP_FREE (ginfo
->statics_not_read
);
573 if (ginfo
->statics_not_written
574 && ginfo
->statics_not_written
!= all_module_statics
)
575 BITMAP_FREE (ginfo
->statics_not_written
);
578 /* Analyze each function in the cgraph to see which global or statics
579 are read or written. */
582 generate_summary (void)
584 struct cgraph_node
*node
;
590 /* Process all of the functions next. */
591 FOR_EACH_DEFINED_FUNCTION (node
)
592 if (!node
->alias
&& !opt_for_fn (node
->decl
, flag_ipa_reference
))
594 struct ipa_ref
*ref
= NULL
;
597 for (i
= 0; node
->iterate_reference (i
, ref
); i
++)
599 if (!is_a
<varpool_node
*> (ref
->referred
))
601 var
= ref
->referred
->decl
;
602 if (!is_proper_for_analysis (var
))
604 bitmap_set_bit (ignore_module_statics
, ipa_reference_var_uid (var
));
607 FOR_EACH_DEFINED_FUNCTION (node
)
608 analyze_function (node
);
611 EXECUTE_IF_SET_IN_BITMAP (all_module_statics
, 0, index
, bi
)
613 fprintf (dump_file
, "\nPromotable global:%s (uid=%u)\n",
614 get_static_name (index
), index
);
618 FOR_EACH_DEFINED_FUNCTION (node
)
619 if (node
->get_availability () >= AVAIL_INTERPOSABLE
620 && opt_for_fn (node
->decl
, flag_ipa_reference
))
622 ipa_reference_local_vars_info_t l
;
626 l
= &get_reference_vars_info (node
)->local
;
628 "\nFunction name:%s:", node
->dump_name ());
629 fprintf (dump_file
, "\n locals read: ");
631 EXECUTE_IF_SET_IN_BITMAP (l
->statics_read
,
634 fprintf (dump_file
, "%s ",
635 get_static_name (index
));
637 fprintf (dump_file
, "\n locals written: ");
638 if (l
->statics_written
)
639 EXECUTE_IF_SET_IN_BITMAP (l
->statics_written
,
642 fprintf (dump_file
, "%s ", get_static_name (index
));
647 /* Set READ_ALL/WRITE_ALL based on decl flags of NODE. */
650 read_write_all_from_decl (struct cgraph_node
*node
,
651 bool &read_all
, bool &write_all
)
653 tree decl
= node
->decl
;
654 int flags
= flags_from_decl_or_type (decl
);
655 if ((flags
& ECF_LEAF
)
656 && node
->get_availability () < AVAIL_INTERPOSABLE
)
658 else if (flags
& ECF_CONST
)
660 else if ((flags
& ECF_PURE
) || node
->cannot_return_p ())
663 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
664 fprintf (dump_file
, " %s -> read all\n", node
->dump_name ());
668 /* TODO: To be able to produce sane results, we should also handle
669 common builtins, in particular throw. */
672 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
673 fprintf (dump_file
, " %s -> read all, write all\n",
678 /* Set READ_ALL/WRITE_ALL based on decl flags of NODE or any member
679 in the cycle of NODE. */
682 get_read_write_all_from_node (struct cgraph_node
*node
,
683 bool &read_all
, bool &write_all
)
685 struct cgraph_edge
*e
, *ie
;
687 /* When function is overwritable, we cannot assume anything. */
688 if (node
->get_availability () <= AVAIL_INTERPOSABLE
689 || (node
->analyzed
&& !opt_for_fn (node
->decl
, flag_ipa_reference
)))
690 read_write_all_from_decl (node
, read_all
, write_all
);
692 for (e
= node
->callees
;
693 e
&& !(read_all
&& write_all
);
696 enum availability avail
;
697 struct cgraph_node
*callee
= e
->callee
->function_symbol (&avail
);
698 gcc_checking_assert (callee
);
699 if (avail
<= AVAIL_INTERPOSABLE
700 || (callee
->analyzed
&& !opt_for_fn (callee
->decl
,
701 flag_ipa_reference
)))
702 read_write_all_from_decl (callee
, read_all
, write_all
);
705 for (ie
= node
->indirect_calls
;
706 ie
&& !(read_all
&& write_all
);
707 ie
= ie
->next_callee
)
708 if (!(ie
->indirect_info
->ecf_flags
& ECF_CONST
))
711 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
712 fprintf (dump_file
, " indirect call -> read all\n");
713 if (!ie
->cannot_lead_to_return_p ()
714 && !(ie
->indirect_info
->ecf_flags
& ECF_PURE
))
716 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
717 fprintf (dump_file
, " indirect call -> write all\n");
723 /* Skip edges from and to nodes without ipa_reference enabled.
724 Ignore not available symbols. This leave
725 them out of strongly connected components and makes them easy to skip in the
726 propagation loop bellow. */
729 ignore_edge_p (cgraph_edge
*e
)
731 enum availability avail
;
732 cgraph_node
*ultimate_target
733 = e
->callee
->function_or_virtual_thunk_symbol (&avail
, e
->caller
);
735 return (avail
< AVAIL_INTERPOSABLE
736 || (avail
== AVAIL_INTERPOSABLE
737 && !(flags_from_decl_or_type (e
->callee
->decl
) & ECF_LEAF
))
738 || !opt_for_fn (e
->caller
->decl
, flag_ipa_reference
)
739 || !opt_for_fn (ultimate_target
->decl
, flag_ipa_reference
));
742 /* Produce the global information by preforming a transitive closure
743 on the local information that was produced by ipa_analyze_function. */
748 struct cgraph_node
*node
;
749 struct cgraph_node
**order
=
750 XCNEWVEC (struct cgraph_node
*, symtab
->cgraph_count
);
756 cgraph_node::dump_cgraph (dump_file
);
758 remove_p
= ipa_discover_variable_flags ();
761 /* Propagate the local information through the call graph to produce
762 the global information. All the nodes within a cycle will have
763 the same info so we collapse cycles first. Then we can do the
764 propagation in one pass from the leaves to the roots. */
765 order_pos
= ipa_reduced_postorder (order
, true, ignore_edge_p
);
767 ipa_print_order (dump_file
, "reduced", order
, order_pos
);
769 for (i
= 0; i
< order_pos
; i
++ )
772 struct cgraph_node
*w
;
773 ipa_reference_vars_info_t node_info
;
774 ipa_reference_global_vars_info_t node_g
;
775 ipa_reference_local_vars_info_t node_l
;
776 bool read_all
= false;
777 bool write_all
= false;
780 if (node
->alias
|| !opt_for_fn (node
->decl
, flag_ipa_reference
))
783 node_info
= get_reference_vars_info (node
);
784 gcc_assert (node_info
);
785 node_l
= &node_info
->local
;
786 node_g
= &node_info
->global
;
788 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
789 fprintf (dump_file
, "Starting cycle with %s\n", node
->dump_name ());
791 vec
<cgraph_node
*> cycle_nodes
= ipa_get_nodes_in_cycle (node
);
793 /* If any node in a cycle is read_all or write_all, they all are. */
794 FOR_EACH_VEC_ELT (cycle_nodes
, x
, w
)
796 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
797 fprintf (dump_file
, " Visiting %s\n", w
->dump_asm_name ());
798 get_read_write_all_from_node (w
, read_all
, write_all
);
799 if (read_all
&& write_all
)
803 /* Initialized the bitmaps global sets for the reduced node. */
805 node_g
->statics_read
= all_module_statics
;
807 node_g
->statics_read
= copy_static_var_set (node_l
->statics_read
);
809 node_g
->statics_written
= all_module_statics
;
811 node_g
->statics_written
= copy_static_var_set (node_l
->statics_written
);
813 /* Merge the sets of this cycle with all sets of callees reached
815 FOR_EACH_VEC_ELT (cycle_nodes
, x
, w
)
817 if (read_all
&& write_all
)
822 ipa_reference_vars_info_t w_ri
= get_reference_vars_info (w
);
823 ipa_reference_local_vars_info_t w_l
= &w_ri
->local
;
824 int flags
= flags_from_decl_or_type (w
->decl
);
826 if (!(flags
& ECF_CONST
))
827 read_all
= union_static_var_sets (node_g
->statics_read
,
829 if (!(flags
& ECF_PURE
)
830 && !w
->cannot_return_p ())
831 write_all
= union_static_var_sets (node_g
->statics_written
,
832 w_l
->statics_written
);
835 propagate_bits (node_g
, w
);
838 /* All nodes within a cycle have the same global info bitmaps. */
839 FOR_EACH_VEC_ELT (cycle_nodes
, x
, w
)
841 ipa_reference_vars_info_t w_ri
= get_reference_vars_info (w
);
842 w_ri
->global
= *node_g
;
845 cycle_nodes
.release ();
850 for (i
= 0; i
< order_pos
; i
++)
853 struct cgraph_node
*w
;
856 if (node
->alias
|| !opt_for_fn (node
->decl
, flag_ipa_reference
))
859 fprintf (dump_file
, "\nFunction name:%s:", node
->dump_asm_name ());
861 ipa_reference_vars_info_t node_info
= get_reference_vars_info (node
);
862 ipa_reference_global_vars_info_t node_g
= &node_info
->global
;
864 vec
<cgraph_node
*> cycle_nodes
= ipa_get_nodes_in_cycle (node
);
865 FOR_EACH_VEC_ELT (cycle_nodes
, x
, w
)
867 ipa_reference_vars_info_t w_ri
= get_reference_vars_info (w
);
868 ipa_reference_local_vars_info_t w_l
= &w_ri
->local
;
870 fprintf (dump_file
, "\n next cycle: %s ", w
->dump_asm_name ());
871 fprintf (dump_file
, "\n locals read: ");
872 dump_static_vars_set_to_file (dump_file
, w_l
->statics_read
);
873 fprintf (dump_file
, "\n locals written: ");
874 dump_static_vars_set_to_file (dump_file
, w_l
->statics_written
);
876 cycle_nodes
.release ();
878 fprintf (dump_file
, "\n globals read: ");
879 dump_static_vars_set_to_file (dump_file
, node_g
->statics_read
);
880 fprintf (dump_file
, "\n globals written: ");
881 dump_static_vars_set_to_file (dump_file
, node_g
->statics_written
);
882 fprintf (dump_file
, "\n");
886 if (ipa_ref_opt_sum_summaries
== NULL
)
887 ipa_ref_opt_sum_summaries
= new ipa_ref_opt_summary_t (symtab
);
890 FOR_EACH_DEFINED_FUNCTION (node
)
892 ipa_reference_vars_info_t node_info
;
893 ipa_reference_global_vars_info_t node_g
;
895 node_info
= get_reference_vars_info (node
);
896 if (!node
->alias
&& opt_for_fn (node
->decl
, flag_ipa_reference
)
897 && (node
->get_availability () > AVAIL_INTERPOSABLE
898 || (flags_from_decl_or_type (node
->decl
) & ECF_LEAF
)))
900 node_g
= &node_info
->global
;
902 ipa_reference_optimization_summary_d
*opt
903 = ipa_ref_opt_sum_summaries
->get_create (node
);
905 /* Create the complimentary sets. */
907 if (bitmap_empty_p (node_g
->statics_read
))
908 opt
->statics_not_read
= all_module_statics
;
911 opt
->statics_not_read
912 = BITMAP_ALLOC (&optimization_summary_obstack
);
913 if (node_g
->statics_read
!= all_module_statics
)
914 bitmap_and_compl (opt
->statics_not_read
,
916 node_g
->statics_read
);
919 if (bitmap_empty_p (node_g
->statics_written
))
920 opt
->statics_not_written
= all_module_statics
;
923 opt
->statics_not_written
924 = BITMAP_ALLOC (&optimization_summary_obstack
);
925 if (node_g
->statics_written
!= all_module_statics
)
926 bitmap_and_compl (opt
->statics_not_written
,
928 node_g
->statics_written
);
933 ipa_free_postorder_info ();
936 bitmap_obstack_release (&local_info_obstack
);
938 if (ipa_ref_var_info_summaries
!= NULL
)
940 delete ipa_ref_var_info_summaries
;
941 ipa_ref_var_info_summaries
= NULL
;
945 vec_free (reference_vars_to_consider
);
946 reference_vars_to_consider
= NULL
;
947 return remove_p
? TODO_remove_functions
: 0;
950 /* Return true if we need to write summary of NODE. */
953 write_node_summary_p (struct cgraph_node
*node
,
954 lto_symtab_encoder_t encoder
,
955 bitmap ltrans_statics
)
957 ipa_reference_optimization_summary_t info
;
959 /* See if we have (non-empty) info. */
960 if (!node
->definition
|| node
->global
.inlined_to
)
962 info
= get_reference_optimization_summary (node
);
964 || (bitmap_empty_p (info
->statics_not_read
)
965 && bitmap_empty_p (info
->statics_not_written
)))
968 /* See if we want to encode it.
969 Encode also referenced functions since constant folding might turn it into
972 In future we might also want to include summaries of functions references
973 by initializers of constant variables references in current unit. */
974 if (!reachable_from_this_partition_p (node
, encoder
)
975 && !referenced_from_this_partition_p (node
, encoder
))
978 /* See if the info has non-empty intersections with vars we want to encode. */
979 if (!bitmap_intersect_p (info
->statics_not_read
, ltrans_statics
)
980 && !bitmap_intersect_p (info
->statics_not_written
, ltrans_statics
))
985 /* Stream out BITS<RANS_STATICS as list of decls to OB.
986 LTRANS_STATICS_BITCOUNT specify number of bits in LTRANS_STATICS
987 or -1. When it is positive, just output -1 when
988 BITS<RANS_STATICS == BITS<RANS_STATICS. */
991 stream_out_bitmap (struct lto_simple_output_block
*ob
,
992 bitmap bits
, bitmap ltrans_statics
,
993 int ltrans_statics_bitcount
)
998 if (bits
== all_module_statics
)
1000 streamer_write_hwi_stream (ob
->main_stream
, -1);
1003 EXECUTE_IF_AND_IN_BITMAP (bits
, ltrans_statics
, 0, index
, bi
)
1005 if (count
== ltrans_statics_bitcount
)
1007 streamer_write_hwi_stream (ob
->main_stream
, -1);
1010 streamer_write_hwi_stream (ob
->main_stream
, count
);
1013 EXECUTE_IF_AND_IN_BITMAP (bits
, ltrans_statics
, 0, index
, bi
)
1015 tree decl
= (*reference_vars_to_consider
) [index
];
1016 lto_output_var_decl_index (ob
->decl_state
, ob
->main_stream
, decl
);
1020 /* Serialize the ipa info for lto. */
1023 ipa_reference_write_optimization_summary (void)
1025 struct lto_simple_output_block
*ob
1026 = lto_create_simple_output_block (LTO_section_ipa_reference
);
1027 unsigned int count
= 0;
1028 int ltrans_statics_bitcount
= 0;
1029 lto_symtab_encoder_t encoder
= ob
->decl_state
->symtab_node_encoder
;
1030 auto_bitmap ltrans_statics
;
1033 vec_alloc (reference_vars_to_consider
, ipa_reference_vars_uids
);
1034 reference_vars_to_consider
->safe_grow (ipa_reference_vars_uids
);
1036 /* See what variables we are interested in. */
1037 for (i
= 0; i
< lto_symtab_encoder_size (encoder
); i
++)
1039 symtab_node
*snode
= lto_symtab_encoder_deref (encoder
, i
);
1040 varpool_node
*vnode
= dyn_cast
<varpool_node
*> (snode
);
1044 && (id
= ipa_reference_var_uid (vnode
->decl
)) != -1
1045 && referenced_from_this_partition_p (vnode
, encoder
))
1047 tree decl
= vnode
->decl
;
1048 bitmap_set_bit (ltrans_statics
, id
);
1049 (*reference_vars_to_consider
)[id
] = decl
;
1050 ltrans_statics_bitcount
++;
1055 if (ltrans_statics_bitcount
)
1056 for (i
= 0; i
< lto_symtab_encoder_size (encoder
); i
++)
1058 symtab_node
*snode
= lto_symtab_encoder_deref (encoder
, i
);
1059 cgraph_node
*cnode
= dyn_cast
<cgraph_node
*> (snode
);
1060 if (cnode
&& write_node_summary_p (cnode
, encoder
, ltrans_statics
))
1064 streamer_write_uhwi_stream (ob
->main_stream
, count
);
1066 stream_out_bitmap (ob
, ltrans_statics
, ltrans_statics
,
1069 /* Process all of the functions. */
1070 if (ltrans_statics_bitcount
)
1071 for (i
= 0; i
< lto_symtab_encoder_size (encoder
); i
++)
1073 symtab_node
*snode
= lto_symtab_encoder_deref (encoder
, i
);
1074 cgraph_node
*cnode
= dyn_cast
<cgraph_node
*> (snode
);
1075 if (cnode
&& write_node_summary_p (cnode
, encoder
, ltrans_statics
))
1077 ipa_reference_optimization_summary_t info
;
1080 info
= get_reference_optimization_summary (cnode
);
1081 node_ref
= lto_symtab_encoder_encode (encoder
, snode
);
1082 streamer_write_uhwi_stream (ob
->main_stream
, node_ref
);
1084 stream_out_bitmap (ob
, info
->statics_not_read
, ltrans_statics
,
1085 ltrans_statics_bitcount
);
1086 stream_out_bitmap (ob
, info
->statics_not_written
, ltrans_statics
,
1087 ltrans_statics_bitcount
);
1090 lto_destroy_simple_output_block (ob
);
1091 delete reference_vars_to_consider
;
1094 /* Deserialize the ipa info for lto. */
1097 ipa_reference_read_optimization_summary (void)
1099 struct lto_file_decl_data
** file_data_vec
1100 = lto_get_file_decl_data ();
1101 struct lto_file_decl_data
* file_data
;
1103 bitmap_obstack_initialize (&optimization_summary_obstack
);
1105 gcc_checking_assert (ipa_ref_opt_sum_summaries
== NULL
);
1106 ipa_ref_opt_sum_summaries
= new ipa_ref_opt_summary_t (symtab
);
1107 ipa_reference_vars_map
= new reference_vars_map_t(257);
1109 = symtab
->add_varpool_removal_hook (varpool_removal_hook
, NULL
);
1110 ipa_reference_vars_uids
= 0;
1112 all_module_statics
= BITMAP_ALLOC (&optimization_summary_obstack
);
1114 while ((file_data
= file_data_vec
[j
++]))
1118 class lto_input_block
*ib
1119 = lto_create_simple_input_block (file_data
,
1120 LTO_section_ipa_reference
,
1125 unsigned int f_count
= streamer_read_uhwi (ib
);
1129 b_count
= streamer_read_hwi (ib
);
1131 fprintf (dump_file
, "all module statics:");
1132 for (i
= 0; i
< (unsigned int)b_count
; i
++)
1134 unsigned int var_index
= streamer_read_uhwi (ib
);
1135 tree v_decl
= lto_file_decl_data_get_var_decl (file_data
,
1138 bitmap_set_bit (all_module_statics
,
1139 ipa_reference_var_get_or_insert_uid
1140 (v_decl
, &existed
));
1141 gcc_checking_assert (!existed
);
1143 fprintf (dump_file
, " %s", fndecl_name (v_decl
));
1146 for (i
= 0; i
< f_count
; i
++)
1148 unsigned int j
, index
;
1149 struct cgraph_node
*node
;
1151 lto_symtab_encoder_t encoder
;
1153 index
= streamer_read_uhwi (ib
);
1154 encoder
= file_data
->symtab_node_encoder
;
1155 node
= dyn_cast
<cgraph_node
*> (lto_symtab_encoder_deref
1158 ipa_reference_optimization_summary_d
*info
1159 = ipa_ref_opt_sum_summaries
->get_create (node
);
1161 info
->statics_not_read
= BITMAP_ALLOC
1162 (&optimization_summary_obstack
);
1163 info
->statics_not_written
= BITMAP_ALLOC
1164 (&optimization_summary_obstack
);
1167 "\nFunction name:%s:\n static not read:",
1168 node
->dump_asm_name ());
1170 /* Set the statics not read. */
1171 v_count
= streamer_read_hwi (ib
);
1174 info
->statics_not_read
= all_module_statics
;
1176 fprintf (dump_file
, " all module statics");
1179 for (j
= 0; j
< (unsigned int)v_count
; j
++)
1181 unsigned int var_index
= streamer_read_uhwi (ib
);
1182 tree v_decl
= lto_file_decl_data_get_var_decl (file_data
,
1184 bitmap_set_bit (info
->statics_not_read
,
1185 ipa_reference_var_uid (v_decl
));
1187 fprintf (dump_file
, " %s", fndecl_name (v_decl
));
1192 "\n static not written:");
1193 /* Set the statics not written. */
1194 v_count
= streamer_read_hwi (ib
);
1197 info
->statics_not_written
= all_module_statics
;
1199 fprintf (dump_file
, " all module statics");
1202 for (j
= 0; j
< (unsigned int)v_count
; j
++)
1204 unsigned int var_index
= streamer_read_uhwi (ib
);
1205 tree v_decl
= lto_file_decl_data_get_var_decl (file_data
,
1207 bitmap_set_bit (info
->statics_not_written
,
1208 ipa_reference_var_uid (v_decl
));
1210 fprintf (dump_file
, " %s", fndecl_name (v_decl
));
1213 fprintf (dump_file
, "\n");
1216 lto_destroy_simple_input_block (file_data
,
1217 LTO_section_ipa_reference
,
1221 /* Fatal error here. We do not want to support compiling ltrans units
1222 with different version of compiler or different flags than
1223 the WPA unit, so this should never happen. */
1224 fatal_error (input_location
,
1225 "ipa reference summary is missing in ltrans unit");
1231 const pass_data pass_data_ipa_reference
=
1233 IPA_PASS
, /* type */
1234 "static-var", /* name */
1235 OPTGROUP_NONE
, /* optinfo_flags */
1236 TV_IPA_REFERENCE
, /* tv_id */
1237 0, /* properties_required */
1238 0, /* properties_provided */
1239 0, /* properties_destroyed */
1240 0, /* todo_flags_start */
1241 0, /* todo_flags_finish */
1244 class pass_ipa_reference
: public ipa_opt_pass_d
1247 pass_ipa_reference (gcc::context
*ctxt
)
1248 : ipa_opt_pass_d (pass_data_ipa_reference
, ctxt
,
1249 NULL
, /* generate_summary */
1250 NULL
, /* write_summary */
1251 NULL
, /* read_summary */
1252 ipa_reference_write_optimization_summary
, /*
1253 write_optimization_summary */
1254 ipa_reference_read_optimization_summary
, /*
1255 read_optimization_summary */
1256 NULL
, /* stmt_fixup */
1257 0, /* function_transform_todo_flags_start */
1258 NULL
, /* function_transform */
1259 NULL
) /* variable_transform */
1262 /* opt_pass methods: */
1263 virtual bool gate (function
*)
1265 return ((in_lto_p
|| flag_ipa_reference
)
1266 /* Don't bother doing anything if the program has errors. */
1270 virtual unsigned int execute (function
*) { return propagate (); }
1272 }; // class pass_ipa_reference
1277 make_pass_ipa_reference (gcc::context
*ctxt
)
1279 return new pass_ipa_reference (ctxt
);
1282 /* Reset all state within ipa-reference.c so that we can rerun the compiler
1283 within the same process. For use by toplev::finalize. */
1286 ipa_reference_c_finalize (void)
1288 if (ipa_ref_opt_sum_summaries
!= NULL
)
1290 delete ipa_ref_opt_sum_summaries
;
1291 ipa_ref_opt_sum_summaries
= NULL
;
1292 delete ipa_reference_vars_map
;
1293 ipa_reference_vars_map
= NULL
;
1294 symtab
->remove_varpool_removal_hook (varpool_node_hooks
)
1299 bitmap_obstack_release (&optimization_summary_obstack
);