1 /* Callgraph based analysis of static variables.
2 Copyright (C) 2004, 2005, 2007, 2008, 2009 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 There are two categories of information produced by this pass:
26 1) The addressable (TREE_ADDRESSABLE) bit and readonly
27 (TREE_READONLY) bit associated with these variables is properly set
28 based on scanning all of the code withing the compilation unit.
30 2) The transitive call site specific clobber effects are computed
31 for the variables whose scope is contained within this compilation
34 First each function and static variable initialization is analyzed
35 to determine which local static variables are either read, written,
36 or have their address taken. Any local static that has its address
37 taken is removed from consideration. Once the local read and
38 writes are determined, a transitive closure of this information is
39 performed over the call graph to determine the worst case set of
40 side effects of each call. In later parts of the compiler, these
41 local and global sets are examined to make the call clobbering less
42 traumatic, promote some statics to registers, and improve aliasing
45 Currently must be run after inlining decisions have been made since
46 otherwise, the local sets will not contain information that is
47 consistent with post inlined state. The global sets are not prone
48 to this problem since they are by definition transitive. */
52 #include "coretypes.h"
55 #include "tree-flow.h"
56 #include "tree-inline.h"
57 #include "tree-pass.h"
58 #include "langhooks.h"
59 #include "pointer-set.h"
60 #include "splay-tree.h"
62 #include "ipa-utils.h"
63 #include "ipa-reference.h"
69 #include "diagnostic.h"
70 #include "langhooks.h"
71 #include "lto-streamer.h"
73 static void add_new_function (struct cgraph_node
*node
,
74 void *data ATTRIBUTE_UNUSED
);
75 static void remove_node_data (struct cgraph_node
*node
,
76 void *data ATTRIBUTE_UNUSED
);
77 static void duplicate_node_data (struct cgraph_node
*src
,
78 struct cgraph_node
*dst
,
79 void *data ATTRIBUTE_UNUSED
);
81 /* The static variables defined within the compilation unit that are
82 loaded or stored directly by function that owns this structure. */
84 struct ipa_reference_local_vars_info_d
87 bitmap statics_written
;
89 /* Set when this function calls another function external to the
90 compilation unit or if the function has a asm clobber of memory.
91 In general, such calls are modeled as reading and writing all
92 variables (both bits on) but sometime there are attributes on the
93 called function so we can do better. */
98 /* Statics that are read and written by some set of functions. The
99 local ones are based on the loads and stores local to the function.
100 The global ones are based on the local info as well as the
101 transitive closure of the functions that are called. The
102 structures are separated to allow the global structures to be
103 shared between several functions since every function within a
104 strongly connected component will have the same information. This
105 sharing saves both time and space in the computation of the vectors
106 as well as their translation from decl_uid form to ann_uid
109 struct ipa_reference_global_vars_info_d
112 bitmap statics_written
;
113 bitmap statics_not_read
;
114 bitmap statics_not_written
;
117 typedef struct ipa_reference_local_vars_info_d
*ipa_reference_local_vars_info_t
;
118 typedef struct ipa_reference_global_vars_info_d
*ipa_reference_global_vars_info_t
;
119 struct ipa_reference_vars_info_d
121 ipa_reference_local_vars_info_t local
;
122 ipa_reference_global_vars_info_t global
;
125 typedef struct ipa_reference_vars_info_d
*ipa_reference_vars_info_t
;
127 /* This splay tree contains all of the static variables that are
128 being considered by the compilation level alias analysis. For
129 module_at_a_time compilation, this is the set of static but not
130 public variables. Any variables that either have their address
131 taken or participate in otherwise unsavory operations are deleted
133 static GTY((param1_is(int), param2_is(tree
)))
134 splay_tree reference_vars_to_consider
;
136 /* This bitmap is used to knock out the module static variables whose
137 addresses have been taken and passed around. */
138 static bitmap module_statics_escape
;
140 /* This bitmap is used to knock out the module static variables that
142 static bitmap module_statics_written
;
144 /* A bit is set for every module static we are considering. This is
145 ored into the local info when asm code is found that clobbers all
147 static bitmap all_module_statics
;
149 static struct pointer_set_t
*visited_nodes
;
151 /* Obstack holding bitmaps of local analysis (live from analysis to
153 static bitmap_obstack local_info_obstack
;
154 /* Obstack holding global analysis live forever. */
155 static bitmap_obstack global_info_obstack
;
157 /* Holders of ipa cgraph hooks: */
158 static struct cgraph_node_hook_list
*function_insertion_hook_holder
;
159 static struct cgraph_2node_hook_list
*node_duplication_hook_holder
;
160 static struct cgraph_node_hook_list
*node_removal_hook_holder
;
162 enum initialization_status_t
169 tree memory_identifier_string
;
171 /* Vector where the reference var infos are actually stored. */
172 DEF_VEC_P (ipa_reference_vars_info_t
);
173 DEF_VEC_ALLOC_P (ipa_reference_vars_info_t
, heap
);
174 static VEC (ipa_reference_vars_info_t
, heap
) *ipa_reference_vars_vector
;
176 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
177 static inline ipa_reference_vars_info_t
178 get_reference_vars_info (struct cgraph_node
*node
)
180 if (!ipa_reference_vars_vector
181 || VEC_length (ipa_reference_vars_info_t
, ipa_reference_vars_vector
) <= (unsigned int)node
->uid
)
183 return VEC_index (ipa_reference_vars_info_t
, ipa_reference_vars_vector
, node
->uid
);
186 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
188 set_reference_vars_info (struct cgraph_node
*node
, ipa_reference_vars_info_t info
)
190 if (!ipa_reference_vars_vector
191 || VEC_length (ipa_reference_vars_info_t
, ipa_reference_vars_vector
) <= (unsigned int)node
->uid
)
192 VEC_safe_grow_cleared (ipa_reference_vars_info_t
, heap
, ipa_reference_vars_vector
, node
->uid
+ 1);
193 VEC_replace (ipa_reference_vars_info_t
, ipa_reference_vars_vector
, node
->uid
, info
);
196 /* Get a bitmap that contains all of the locally referenced static
197 variables for function FN. */
198 static ipa_reference_local_vars_info_t
199 get_local_reference_vars_info (struct cgraph_node
*fn
)
201 ipa_reference_vars_info_t info
= get_reference_vars_info (fn
);
206 /* This phase was not run. */
210 /* Get a bitmap that contains all of the globally referenced static
211 variables for function FN. */
213 static ipa_reference_global_vars_info_t
214 get_global_reference_vars_info (struct cgraph_node
*fn
)
216 ipa_reference_vars_info_t info
= get_reference_vars_info (fn
);
221 /* This phase was not run. */
225 /* Return a bitmap indexed by VAR_DECL uid for the static variables
226 that are read during the execution of the function FN. Returns
227 NULL if no data is available. */
230 ipa_reference_get_read_global (struct cgraph_node
*fn
)
232 ipa_reference_global_vars_info_t g
= get_global_reference_vars_info (fn
);
234 return g
->statics_read
;
239 /* Return a bitmap indexed by VAR_DECL uid for the static variables
240 that are written during the execution of the function FN. Note
241 that variables written may or may not be read during the function
242 call. Returns NULL if no data is available. */
245 ipa_reference_get_written_global (struct cgraph_node
*fn
)
247 ipa_reference_global_vars_info_t g
= get_global_reference_vars_info (fn
);
249 return g
->statics_written
;
254 /* Return a bitmap indexed by_DECL_UID uid for the static variables
255 that are not read during the execution of the function FN. Returns
256 NULL if no data is available. */
259 ipa_reference_get_not_read_global (struct cgraph_node
*fn
)
261 ipa_reference_global_vars_info_t g
= get_global_reference_vars_info (fn
);
263 return g
->statics_not_read
;
268 /* Return a bitmap indexed by DECL_UID uid for the static variables
269 that are not written during the execution of the function FN. Note
270 that variables written may or may not be read during the function
271 call. Returns NULL if no data is available. */
274 ipa_reference_get_not_written_global (struct cgraph_node
*fn
)
276 ipa_reference_global_vars_info_t g
= get_global_reference_vars_info (fn
);
278 return g
->statics_not_written
;
285 /* Add VAR to all_module_statics and the two
286 reference_vars_to_consider* sets. */
289 add_static_var (tree var
)
291 int uid
= DECL_UID (var
);
292 gcc_assert (TREE_CODE (var
) == VAR_DECL
);
293 if (!bitmap_bit_p (all_module_statics
, uid
))
295 splay_tree_insert (reference_vars_to_consider
,
296 uid
, (splay_tree_value
)var
);
297 bitmap_set_bit (all_module_statics
, uid
);
301 /* Return true if the variable T is the right kind of static variable to
302 perform compilation unit scope escape analysis. */
305 has_proper_scope_for_analysis (tree t
)
307 /* If the variable has the "used" attribute, treat it as if it had a
308 been touched by the devil. */
309 if (lookup_attribute ("used", DECL_ATTRIBUTES (t
)))
312 /* Do not want to do anything with volatile except mark any
313 function that uses one to be not const or pure. */
314 if (TREE_THIS_VOLATILE (t
))
317 /* Do not care about a local automatic that is not static. */
318 if (!TREE_STATIC (t
) && !DECL_EXTERNAL (t
))
321 /* FIXME: for LTO we should include PUBLIC vars too. This is bit difficult
322 as summarie would need unsharing. */
323 if (DECL_EXTERNAL (t
) || TREE_PUBLIC (t
))
326 /* We cannot touch decls where the type needs constructing. */
327 if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (t
)))
330 /* This is a variable we care about. Check if we have seen it
331 before, and if not add it the set of variables we care about. */
332 if (!bitmap_bit_p (all_module_statics
, DECL_UID (t
)))
338 /* Mark tree T as having address taken. */
341 mark_address_taken (tree x
)
343 if (TREE_CODE (x
) == VAR_DECL
344 && module_statics_escape
&& has_proper_scope_for_analysis (x
))
345 bitmap_set_bit (module_statics_escape
, DECL_UID (x
));
348 /* Wrapper around mark_address_taken for the stmt walker. */
351 mark_address (gimple stmt ATTRIBUTE_UNUSED
, tree addr
,
352 void *data ATTRIBUTE_UNUSED
)
354 while (handled_component_p (addr
))
355 addr
= TREE_OPERAND (addr
, 0);
356 mark_address_taken (addr
);
360 /* Mark load of T. */
363 mark_load (gimple stmt ATTRIBUTE_UNUSED
, tree t
, void *data
)
365 ipa_reference_local_vars_info_t local
= (ipa_reference_local_vars_info_t
)data
;
366 if (TREE_CODE (t
) == VAR_DECL
367 && has_proper_scope_for_analysis (t
))
368 bitmap_set_bit (local
->statics_read
, DECL_UID (t
));
372 /* Mark store of T. */
375 mark_store (gimple stmt ATTRIBUTE_UNUSED
, tree t
, void *data
)
377 ipa_reference_local_vars_info_t local
= (ipa_reference_local_vars_info_t
)data
;
378 if (TREE_CODE (t
) == VAR_DECL
379 && has_proper_scope_for_analysis (t
))
382 bitmap_set_bit (local
->statics_written
, DECL_UID (t
));
383 /* Mark the write so we can tell which statics are
385 if (module_statics_written
)
386 bitmap_set_bit (module_statics_written
, DECL_UID (t
));
391 /* Look for memory clobber and set read_all/write_all if present. */
394 check_asm_memory_clobber (ipa_reference_local_vars_info_t local
, gimple stmt
)
399 for (i
= 0; i
< gimple_asm_nclobbers (stmt
); i
++)
401 op
= gimple_asm_clobber_op (stmt
, i
);
402 if (simple_cst_equal(TREE_VALUE (op
), memory_identifier_string
) == 1)
404 /* Abandon all hope, ye who enter here. */
405 local
->calls_read_all
= true;
406 local
->calls_write_all
= true;
411 /* Look for external calls and set read_all/write_all correspondingly. */
414 check_call (ipa_reference_local_vars_info_t local
, gimple stmt
)
416 int flags
= gimple_call_flags (stmt
);
417 tree callee_t
= gimple_call_fndecl (stmt
);
419 /* Process indirect calls. All direct calles are handled at propagation
423 if (flags
& ECF_CONST
)
425 else if (flags
& ECF_PURE
)
426 local
->calls_read_all
= true;
429 local
->calls_read_all
= true;
430 /* When function does not reutrn, it is safe to ignore anythign it writes
431 to, because the effect will never happen. */
432 if ((flags
& (ECF_NOTHROW
| ECF_NORETURN
))
433 != (ECF_NOTHROW
| ECF_NORETURN
))
434 local
->calls_write_all
= true;
439 /* TP is the part of the tree currently under the microscope.
440 WALK_SUBTREES is part of the walk_tree api but is unused here.
441 DATA is cgraph_node of the function being walked. */
444 scan_stmt_for_static_refs (gimple_stmt_iterator
*gsip
,
445 struct cgraph_node
*fn
)
447 gimple stmt
= gsi_stmt (*gsip
);
448 ipa_reference_local_vars_info_t local
= NULL
;
450 if (is_gimple_debug (stmt
))
454 local
= get_reference_vars_info (fn
)->local
;
456 /* Look for direct loads and stores. */
457 walk_stmt_load_store_addr_ops (stmt
, local
, mark_load
, mark_store
,
460 if (is_gimple_call (stmt
))
461 check_call (local
, stmt
);
462 else if (gimple_code (stmt
) == GIMPLE_ASM
)
463 check_asm_memory_clobber (local
, stmt
);
468 /* Call-back to scan variable initializers for static references.
469 Called using walk_tree. */
472 scan_initializer_for_static_refs (tree
*tp
, int *walk_subtrees
,
473 void *data ATTRIBUTE_UNUSED
)
477 if (TREE_CODE (t
) == ADDR_EXPR
)
479 mark_address_taken (get_base_var (t
));
482 /* Save some cycles by not walking types and declaration as we
483 won't find anything useful there anyway. */
484 else if (IS_TYPE_OR_DECL_P (*tp
))
490 /* Lookup the tree node for the static variable that has UID. */
492 get_static_decl (int index
)
494 splay_tree_node stn
=
495 splay_tree_lookup (reference_vars_to_consider
, index
);
497 return (tree
)stn
->value
;
501 /* Lookup the tree node for the static variable that has UID and
502 convert the name to a string for debugging. */
505 get_static_name (int index
)
507 splay_tree_node stn
=
508 splay_tree_lookup (reference_vars_to_consider
, index
);
510 return lang_hooks
.decl_printable_name ((tree
)(stn
->value
), 2);
514 /* Or in all of the bits from every callee of X into X_GLOBAL, the caller's cycle,
515 bit vector. There are several cases to check to avoid the sparse
519 propagate_bits (ipa_reference_global_vars_info_t x_global
, struct cgraph_node
*x
)
521 struct cgraph_edge
*e
;
522 for (e
= x
->callees
; e
; e
= e
->next_callee
)
524 struct cgraph_node
*y
= e
->callee
;
526 /* Only look into nodes we can propagate something. */
527 if (cgraph_function_body_availability (e
->callee
) > AVAIL_OVERWRITABLE
)
529 if (get_reference_vars_info (y
))
531 ipa_reference_vars_info_t y_info
532 = get_reference_vars_info (y
);
533 ipa_reference_global_vars_info_t y_global
= y_info
->global
;
535 /* Calls in current cycle do not have global computed yet. */
539 if (x_global
->statics_read
540 != all_module_statics
)
542 if (y_global
->statics_read
543 == all_module_statics
)
545 BITMAP_FREE (x_global
->statics_read
);
546 x_global
->statics_read
547 = all_module_statics
;
549 /* Skip bitmaps that are pointer equal to node's bitmap
550 (no reason to spin within the cycle). */
551 else if (x_global
->statics_read
552 != y_global
->statics_read
)
553 bitmap_ior_into (x_global
->statics_read
,
554 y_global
->statics_read
);
557 if (x_global
->statics_written
558 != all_module_statics
)
560 if (y_global
->statics_written
561 == all_module_statics
)
563 BITMAP_FREE (x_global
->statics_written
);
564 x_global
->statics_written
565 = all_module_statics
;
567 /* Skip bitmaps that are pointer equal to node's bitmap
568 (no reason to spin within the cycle). */
569 else if (x_global
->statics_written
570 != y_global
->statics_written
)
571 bitmap_ior_into (x_global
->statics_written
,
572 y_global
->statics_written
);
581 /* The init routine for analyzing global static variable usage. See
582 comments at top for description. */
586 static bool init_p
= false;
593 memory_identifier_string
= build_string(7, "memory");
595 reference_vars_to_consider
=
596 splay_tree_new_ggc (splay_tree_compare_ints
);
598 bitmap_obstack_initialize (&local_info_obstack
);
599 bitmap_obstack_initialize (&global_info_obstack
);
600 module_statics_escape
= BITMAP_ALLOC (&local_info_obstack
);
601 module_statics_written
= BITMAP_ALLOC (&local_info_obstack
);
602 all_module_statics
= BITMAP_ALLOC (&global_info_obstack
);
604 /* There are some shared nodes, in particular the initializers on
605 static declarations. We do not need to scan them more than once
606 since all we would be interested in are the addressof
608 visited_nodes
= pointer_set_create ();
610 function_insertion_hook_holder
=
611 cgraph_add_function_insertion_hook (&add_new_function
, NULL
);
612 node_removal_hook_holder
=
613 cgraph_add_node_removal_hook (&remove_node_data
, NULL
);
614 node_duplication_hook_holder
=
615 cgraph_add_node_duplication_hook (&duplicate_node_data
, NULL
);
618 /* Check out the rhs of a static or global initialization VNODE to see
619 if any of them contain addressof operations. Note that some of
620 these variables may not even be referenced in the code in this
621 compilation unit but their right hand sides may contain references
622 to variables defined within this unit. */
625 analyze_variable (struct varpool_node
*vnode
)
627 struct walk_stmt_info wi
;
628 tree global
= vnode
->decl
;
630 memset (&wi
, 0, sizeof (wi
));
631 wi
.pset
= visited_nodes
;
632 walk_tree (&DECL_INITIAL (global
), scan_initializer_for_static_refs
,
637 /* Set up the persistent info for FN. */
639 static ipa_reference_local_vars_info_t
640 init_function_info (struct cgraph_node
*fn
)
642 ipa_reference_vars_info_t info
643 = XCNEW (struct ipa_reference_vars_info_d
);
644 ipa_reference_local_vars_info_t l
645 = XCNEW (struct ipa_reference_local_vars_info_d
);
647 /* Add the info to the tree's annotation. */
648 set_reference_vars_info (fn
, info
);
651 l
->statics_read
= BITMAP_ALLOC (&local_info_obstack
);
652 l
->statics_written
= BITMAP_ALLOC (&local_info_obstack
);
658 /* This is the main routine for finding the reference patterns for
659 global variables within a function FN. */
662 analyze_function (struct cgraph_node
*fn
)
664 tree decl
= fn
->decl
;
665 struct function
*this_cfun
= DECL_STRUCT_FUNCTION (decl
);
666 basic_block this_block
;
667 #ifdef ENABLE_CHECKING
670 ipa_reference_local_vars_info_t local
;
673 fprintf (dump_file
, "\n local analysis of %s\n", cgraph_node_name (fn
));
675 push_cfun (DECL_STRUCT_FUNCTION (decl
));
676 current_function_decl
= decl
;
678 init_function_info (fn
);
679 FOR_EACH_BB_FN (this_block
, this_cfun
)
681 gimple_stmt_iterator gsi
;
687 /* Find the addresses taken in phi node arguments. */
688 for (gsi
= gsi_start_phis (this_block
);
692 phi
= gsi_stmt (gsi
);
693 FOR_EACH_PHI_ARG (use
, phi
, iter
, SSA_OP_USE
)
695 op
= USE_FROM_PTR (use
);
696 if (TREE_CODE (op
) == ADDR_EXPR
)
697 mark_address_taken (get_base_var (op
));
701 for (gsi
= gsi_start_bb (this_block
); !gsi_end_p (gsi
); gsi_next (&gsi
))
702 scan_stmt_for_static_refs (&gsi
, fn
);
705 local
= get_reference_vars_info (fn
)->local
;
706 if ((flags_from_decl_or_type (decl
) & (ECF_NOTHROW
| ECF_NORETURN
))
707 == (ECF_NOTHROW
| ECF_NORETURN
))
709 local
->calls_write_all
= false;
710 bitmap_clear (local
->statics_written
);
713 /* Free bitmaps of direct references if we can not use them anyway. */
714 if (local
->calls_write_all
)
715 BITMAP_FREE (local
->statics_written
);
716 if (local
->calls_read_all
)
717 BITMAP_FREE (local
->statics_read
);
720 #ifdef ENABLE_CHECKING
721 /* Verify that all local initializers was expanded by gimplifier. */
722 for (step
= DECL_STRUCT_FUNCTION (decl
)->local_decls
;
724 step
= TREE_CHAIN (step
))
726 tree var
= TREE_VALUE (step
);
727 if (TREE_CODE (var
) == VAR_DECL
728 && DECL_INITIAL (var
)
729 && !TREE_STATIC (var
))
734 current_function_decl
= NULL
;
737 /* Remove local data associated with function FN. */
739 clean_function_local_data (struct cgraph_node
*fn
)
741 ipa_reference_vars_info_t info
= get_reference_vars_info (fn
);
742 ipa_reference_local_vars_info_t l
= info
->local
;
746 && l
->statics_read
!= all_module_statics
)
747 BITMAP_FREE (l
->statics_read
);
748 if (l
->statics_written
749 &&l
->statics_written
!= all_module_statics
)
750 BITMAP_FREE (l
->statics_written
);
756 /* Remove all data associated with function FN. */
759 clean_function (struct cgraph_node
*fn
)
761 ipa_reference_vars_info_t info
= get_reference_vars_info (fn
);
762 ipa_reference_global_vars_info_t g
= info
->global
;
764 clean_function_local_data (fn
);
768 && g
->statics_read
!= all_module_statics
)
769 BITMAP_FREE (g
->statics_read
);
771 if (g
->statics_written
772 && g
->statics_written
!= all_module_statics
)
773 BITMAP_FREE (g
->statics_written
);
775 if (g
->statics_not_read
776 && g
->statics_not_read
!= all_module_statics
)
777 BITMAP_FREE (g
->statics_not_read
);
779 if (g
->statics_not_written
780 && g
->statics_not_written
!= all_module_statics
)
781 BITMAP_FREE (g
->statics_not_written
);
786 free (get_reference_vars_info (fn
));
787 set_reference_vars_info (fn
, NULL
);
790 /* Called when new function is inserted to callgraph late. */
792 add_new_function (struct cgraph_node
*node
, void *data ATTRIBUTE_UNUSED
)
794 /* There are some shared nodes, in particular the initializers on
795 static declarations. We do not need to scan them more than once
796 since all we would be interested in are the addressof
798 analyze_function (node
);
799 visited_nodes
= NULL
;
803 copy_local_bitmap (bitmap src
)
808 if (src
== all_module_statics
)
809 return all_module_statics
;
810 dst
= BITMAP_ALLOC (&local_info_obstack
);
811 bitmap_copy (dst
, src
);
816 copy_global_bitmap (bitmap src
)
821 if (src
== all_module_statics
)
822 return all_module_statics
;
823 dst
= BITMAP_ALLOC (&global_info_obstack
);
824 bitmap_copy (dst
, src
);
828 /* Called when new clone is inserted to callgraph late. */
831 duplicate_node_data (struct cgraph_node
*src
, struct cgraph_node
*dst
,
832 void *data ATTRIBUTE_UNUSED
)
834 ipa_reference_global_vars_info_t ginfo
;
835 ipa_reference_local_vars_info_t linfo
;
836 ipa_reference_global_vars_info_t dst_ginfo
;
837 ipa_reference_local_vars_info_t dst_linfo
;
839 ginfo
= get_global_reference_vars_info (src
);
840 linfo
= get_local_reference_vars_info (src
);
841 if (!linfo
&& !ginfo
)
843 init_function_info (dst
);
846 dst_linfo
= get_local_reference_vars_info (dst
);
847 dst_linfo
->statics_read
= copy_local_bitmap (linfo
->statics_read
);
848 dst_linfo
->statics_written
= copy_local_bitmap (linfo
->statics_written
);
849 dst_linfo
->calls_read_all
= linfo
->calls_read_all
;
850 dst_linfo
->calls_write_all
= linfo
->calls_write_all
;
854 get_reference_vars_info (dst
)->global
= XCNEW (struct ipa_reference_global_vars_info_d
);
855 dst_ginfo
= get_global_reference_vars_info (dst
);
856 dst_ginfo
->statics_read
= copy_global_bitmap (ginfo
->statics_read
);
857 dst_ginfo
->statics_written
= copy_global_bitmap (ginfo
->statics_written
);
858 dst_ginfo
->statics_not_read
= copy_global_bitmap (ginfo
->statics_not_read
);
859 dst_ginfo
->statics_not_written
= copy_global_bitmap (ginfo
->statics_not_written
);
863 /* Called when node is removed. */
866 remove_node_data (struct cgraph_node
*node
, void *data ATTRIBUTE_UNUSED
)
868 if (get_reference_vars_info (node
))
869 clean_function (node
);
872 /* Analyze each function in the cgraph to see which global or statics
873 are read or written. */
876 generate_summary (void)
878 struct cgraph_node
*node
;
879 struct varpool_node
*vnode
;
882 bitmap module_statics_readonly
;
886 module_statics_readonly
= BITMAP_ALLOC (&local_info_obstack
);
887 bm_temp
= BITMAP_ALLOC (&local_info_obstack
);
889 /* Process all of the variables first. */
890 FOR_EACH_STATIC_INITIALIZER (vnode
)
891 analyze_variable (vnode
);
893 /* Process all of the functions next.
895 We do not want to process any of the clones so we check that this
896 is a master clone. However, we do need to process any
897 AVAIL_OVERWRITABLE functions (these are never clones) because
898 they may cause a static variable to escape. The code that can
899 overwrite such a function cannot access the statics because it
900 would not be in the same compilation unit. When the analysis is
901 finished, the computed information of these AVAIL_OVERWRITABLE is
902 replaced with worst case info.
904 for (node
= cgraph_nodes
; node
; node
= node
->next
)
905 if (cgraph_function_body_availability (node
) >= AVAIL_OVERWRITABLE
)
906 analyze_function (node
);
908 pointer_set_destroy (visited_nodes
);
909 visited_nodes
= NULL
;
911 /* Prune out the variables that were found to behave badly
912 (i.e. have their address taken). */
913 EXECUTE_IF_SET_IN_BITMAP (module_statics_escape
, 0, index
, bi
)
915 splay_tree_remove (reference_vars_to_consider
, index
);
918 bitmap_and_compl_into (all_module_statics
,
919 module_statics_escape
);
921 bitmap_and_compl (module_statics_readonly
, all_module_statics
,
922 module_statics_written
);
924 /* If the address is not taken, we can unset the addressable bit
926 EXECUTE_IF_SET_IN_BITMAP (all_module_statics
, 0, index
, bi
)
928 tree var
= get_static_decl (index
);
929 TREE_ADDRESSABLE (var
) = 0;
931 fprintf (dump_file
, "Not TREE_ADDRESSABLE var %s\n",
932 get_static_name (index
));
935 /* If the variable is never written, we can set the TREE_READONLY
936 flag. Additionally if it has a DECL_INITIAL that is made up of
937 constants we can treat the entire global as a constant. */
939 bitmap_and_compl (module_statics_readonly
, all_module_statics
,
940 module_statics_written
);
941 EXECUTE_IF_SET_IN_BITMAP (module_statics_readonly
, 0, index
, bi
)
943 tree var
= get_static_decl (index
);
945 /* Ignore variables in named sections - changing TREE_READONLY
946 changes the section flags, potentially causing conflicts with
947 other variables in the same named section. */
948 if (DECL_SECTION_NAME (var
) == NULL_TREE
)
950 TREE_READONLY (var
) = 1;
952 fprintf (dump_file
, "read-only var %s\n",
953 get_static_name (index
));
957 BITMAP_FREE(module_statics_escape
);
958 BITMAP_FREE(module_statics_written
);
959 module_statics_escape
= NULL
;
960 module_statics_written
= NULL
;
963 EXECUTE_IF_SET_IN_BITMAP (all_module_statics
, 0, index
, bi
)
965 fprintf (dump_file
, "\nPromotable global:%s",
966 get_static_name (index
));
969 for (node
= cgraph_nodes
; node
; node
= node
->next
)
970 if (cgraph_function_body_availability (node
) >= AVAIL_OVERWRITABLE
)
972 ipa_reference_local_vars_info_t l
;
973 l
= get_reference_vars_info (node
)->local
;
975 /* Any variables that are not in all_module_statics are
976 removed from the local maps. This will include all of the
977 variables that were found to escape in the function
980 bitmap_and_into (l
->statics_read
,
982 if (l
->statics_written
)
983 bitmap_and_into (l
->statics_written
,
987 BITMAP_FREE(module_statics_readonly
);
988 BITMAP_FREE(bm_temp
);
991 for (node
= cgraph_nodes
; node
; node
= node
->next
)
992 if (cgraph_function_body_availability (node
) >= AVAIL_OVERWRITABLE
)
994 ipa_reference_local_vars_info_t l
;
998 l
= get_reference_vars_info (node
)->local
;
1000 "\nFunction name:%s/%i:",
1001 cgraph_node_name (node
), node
->uid
);
1002 fprintf (dump_file
, "\n locals read: ");
1003 if (l
->statics_read
)
1004 EXECUTE_IF_SET_IN_BITMAP (l
->statics_read
,
1007 fprintf (dump_file
, "%s ",
1008 get_static_name (index
));
1010 fprintf (dump_file
, "\n locals written: ");
1011 if (l
->statics_written
)
1012 EXECUTE_IF_SET_IN_BITMAP (l
->statics_written
,
1015 fprintf(dump_file
, "%s ",
1016 get_static_name (index
));
1018 if (l
->calls_read_all
)
1019 fprintf (dump_file
, "\n calls read all: ");
1020 if (l
->calls_write_all
)
1021 fprintf (dump_file
, "\n calls read all: ");
1026 /* Return true if we need to write summary of NODE. */
1029 write_node_summary_p (struct cgraph_node
*node
)
1031 gcc_assert (node
->global
.inlined_to
== NULL
);
1032 return (node
->analyzed
1033 && cgraph_function_body_availability (node
) >= AVAIL_OVERWRITABLE
1034 && get_reference_vars_info (node
) != NULL
);
1037 /* Serialize the ipa info for lto. */
1040 ipa_reference_write_summary (cgraph_node_set set
)
1042 struct cgraph_node
*node
;
1043 struct lto_simple_output_block
*ob
1044 = lto_create_simple_output_block (LTO_section_ipa_reference
);
1045 unsigned int count
= 0;
1046 cgraph_node_set_iterator csi
;
1048 for (csi
= csi_start (set
); !csi_end_p (csi
); csi_next (&csi
))
1049 if (write_node_summary_p (csi_node (csi
)))
1052 lto_output_uleb128_stream (ob
->main_stream
, count
);
1054 /* Process all of the functions. */
1055 for (csi
= csi_start (set
); !csi_end_p (csi
); csi_next (&csi
))
1057 node
= csi_node (csi
);
1058 if (write_node_summary_p (node
))
1060 ipa_reference_local_vars_info_t l
1061 = get_reference_vars_info (node
)->local
;
1064 lto_cgraph_encoder_t encoder
;
1067 encoder
= ob
->decl_state
->cgraph_node_encoder
;
1068 node_ref
= lto_cgraph_encoder_encode (encoder
, node
);
1069 lto_output_uleb128_stream (ob
->main_stream
, node_ref
);
1071 /* Stream out the statics read. */
1072 if (l
->calls_read_all
)
1073 lto_output_sleb128_stream (ob
->main_stream
, -1);
1076 lto_output_sleb128_stream (ob
->main_stream
,
1077 bitmap_count_bits (l
->statics_read
));
1078 EXECUTE_IF_SET_IN_BITMAP (l
->statics_read
, 0, index
, bi
)
1079 lto_output_var_decl_index(ob
->decl_state
, ob
->main_stream
,
1080 get_static_decl (index
));
1083 /* Stream out the statics written. */
1084 if (l
->calls_write_all
)
1085 lto_output_sleb128_stream (ob
->main_stream
, -1);
1088 lto_output_sleb128_stream (ob
->main_stream
,
1089 bitmap_count_bits (l
->statics_written
));
1090 EXECUTE_IF_SET_IN_BITMAP (l
->statics_written
, 0, index
, bi
)
1091 lto_output_var_decl_index(ob
->decl_state
, ob
->main_stream
,
1092 get_static_decl (index
));
1096 lto_destroy_simple_output_block (ob
);
1100 /* Deserialize the ipa info for lto. */
1103 ipa_reference_read_summary (void)
1105 struct lto_file_decl_data
** file_data_vec
1106 = lto_get_file_decl_data ();
1107 struct lto_file_decl_data
* file_data
;
1112 while ((file_data
= file_data_vec
[j
++]))
1116 struct lto_input_block
*ib
1117 = lto_create_simple_input_block (file_data
,
1118 LTO_section_ipa_reference
,
1123 unsigned int f_count
= lto_input_uleb128 (ib
);
1125 for (i
= 0; i
< f_count
; i
++)
1127 unsigned int j
, index
;
1128 struct cgraph_node
*node
;
1129 ipa_reference_local_vars_info_t l
;
1131 lto_cgraph_encoder_t encoder
;
1133 index
= lto_input_uleb128 (ib
);
1134 encoder
= file_data
->cgraph_node_encoder
;
1135 node
= lto_cgraph_encoder_deref (encoder
, index
);
1136 l
= init_function_info (node
);
1138 /* Set the statics read. */
1139 v_count
= lto_input_sleb128 (ib
);
1141 l
->calls_read_all
= true;
1143 for (j
= 0; j
< (unsigned int)v_count
; j
++)
1145 unsigned int var_index
= lto_input_uleb128 (ib
);
1146 tree v_decl
= lto_file_decl_data_get_var_decl (file_data
,
1148 add_static_var (v_decl
);
1149 bitmap_set_bit (l
->statics_read
, DECL_UID (v_decl
));
1152 /* Set the statics written. */
1153 v_count
= lto_input_sleb128 (ib
);
1155 l
->calls_write_all
= true;
1157 for (j
= 0; j
< (unsigned int)v_count
; j
++)
1159 unsigned int var_index
= lto_input_uleb128 (ib
);
1160 tree v_decl
= lto_file_decl_data_get_var_decl (file_data
,
1162 add_static_var (v_decl
);
1163 bitmap_set_bit (l
->statics_written
, DECL_UID (v_decl
));
1167 lto_destroy_simple_input_block (file_data
,
1168 LTO_section_ipa_reference
,
1176 /* Set READ_ALL/WRITE_ALL based on DECL flags. */
1178 read_write_all_from_decl (tree decl
, bool * read_all
, bool * write_all
)
1180 int flags
= flags_from_decl_or_type (decl
);
1181 if (flags
& ECF_CONST
)
1183 else if (flags
& ECF_PURE
)
1187 /* TODO: To be able to produce sane results, we should also handle
1188 common builtins, in particular throw.
1189 Indirect calls hsould be only counted and as inliner is replacing them
1190 by direct calls, we can conclude if any indirect calls are left in body */
1192 /* When function does not reutrn, it is safe to ignore anythign it writes
1193 to, because the effect will never happen. */
1194 if ((flags
& (ECF_NOTHROW
| ECF_NORETURN
))
1195 != (ECF_NOTHROW
| ECF_NORETURN
))
1200 /* Produce the global information by preforming a transitive closure
1201 on the local information that was produced by ipa_analyze_function
1202 and ipa_analyze_variable. */
1207 struct cgraph_node
*node
;
1208 struct cgraph_node
*w
;
1209 struct cgraph_node
**order
=
1210 XCNEWVEC (struct cgraph_node
*, cgraph_n_nodes
);
1211 int order_pos
= ipa_utils_reduced_inorder (order
, false, true, NULL
);
1214 cgraph_remove_function_insertion_hook (function_insertion_hook_holder
);
1216 dump_cgraph (dump_file
);
1218 /* Propagate the local information thru the call graph to produce
1219 the global information. All the nodes within a cycle will have
1220 the same info so we collapse cycles first. Then we can do the
1221 propagation in one pass from the leaves to the roots. */
1222 order_pos
= ipa_utils_reduced_inorder (order
, true, true, NULL
);
1224 ipa_utils_print_order(dump_file
, "reduced", order
, order_pos
);
1226 for (i
= 0; i
< order_pos
; i
++ )
1228 ipa_reference_vars_info_t node_info
;
1229 ipa_reference_global_vars_info_t node_g
=
1230 XCNEW (struct ipa_reference_global_vars_info_d
);
1231 ipa_reference_local_vars_info_t node_l
;
1232 struct cgraph_edge
*e
;
1236 struct ipa_dfs_info
* w_info
;
1239 node_info
= get_reference_vars_info (node
);
1242 dump_cgraph_node (stderr
, node
);
1243 dump_cgraph (stderr
);
1247 gcc_assert (!node_info
->global
);
1248 node_l
= node_info
->local
;
1250 read_all
= node_l
->calls_read_all
;
1251 write_all
= node_l
->calls_write_all
;
1253 /* When function is overwrittable, we can not assume anything. */
1254 if (cgraph_function_body_availability (node
) <= AVAIL_OVERWRITABLE
)
1255 read_write_all_from_decl (node
->decl
, &read_all
, &write_all
);
1257 for (e
= node
->callees
; e
; e
= e
->next_callee
)
1258 if (cgraph_function_body_availability (e
->callee
) <= AVAIL_OVERWRITABLE
)
1259 read_write_all_from_decl (e
->callee
->decl
, &read_all
, &write_all
);
1262 /* If any node in a cycle is calls_read_all or calls_write_all
1264 w_info
= (struct ipa_dfs_info
*) node
->aux
;
1265 w
= w_info
->next_cycle
;
1268 ipa_reference_local_vars_info_t w_l
=
1269 get_reference_vars_info (w
)->local
;
1271 /* When function is overwrittable, we can not assume anything. */
1272 if (cgraph_function_body_availability (w
) <= AVAIL_OVERWRITABLE
)
1273 read_write_all_from_decl (w
->decl
, &read_all
, &write_all
);
1275 for (e
= w
->callees
; e
; e
= e
->next_callee
)
1276 if (cgraph_function_body_availability (e
->callee
) <= AVAIL_OVERWRITABLE
)
1277 read_write_all_from_decl (e
->callee
->decl
, &read_all
, &write_all
);
1279 read_all
|= w_l
->calls_read_all
;
1280 write_all
|= w_l
->calls_write_all
;
1282 w_info
= (struct ipa_dfs_info
*) w
->aux
;
1283 w
= w_info
->next_cycle
;
1287 /* Initialized the bitmaps for the reduced nodes */
1289 node_g
->statics_read
= all_module_statics
;
1292 node_g
->statics_read
= BITMAP_ALLOC (&global_info_obstack
);
1293 bitmap_copy (node_g
->statics_read
,
1294 node_l
->statics_read
);
1297 node_g
->statics_written
= all_module_statics
;
1300 node_g
->statics_written
= BITMAP_ALLOC (&global_info_obstack
);
1301 bitmap_copy (node_g
->statics_written
,
1302 node_l
->statics_written
);
1305 propagate_bits (node_g
, node
);
1306 w_info
= (struct ipa_dfs_info
*) node
->aux
;
1307 w
= w_info
->next_cycle
;
1310 ipa_reference_vars_info_t w_ri
=
1311 get_reference_vars_info (w
);
1312 ipa_reference_local_vars_info_t w_l
= w_ri
->local
;
1314 /* These global bitmaps are initialized from the local info
1315 of all of the nodes in the region. However there is no
1316 need to do any work if the bitmaps were set to
1317 all_module_statics. */
1319 bitmap_ior_into (node_g
->statics_read
,
1322 bitmap_ior_into (node_g
->statics_written
,
1323 w_l
->statics_written
);
1324 propagate_bits (node_g
, w
);
1325 w_info
= (struct ipa_dfs_info
*) w
->aux
;
1326 w
= w_info
->next_cycle
;
1329 /* All nodes within a cycle have the same global info bitmaps. */
1330 node_info
->global
= node_g
;
1331 w_info
= (struct ipa_dfs_info
*) node
->aux
;
1332 w
= w_info
->next_cycle
;
1335 ipa_reference_vars_info_t w_ri
=
1336 get_reference_vars_info (w
);
1338 gcc_assert (!w_ri
->global
);
1339 w_ri
->global
= XCNEW (struct ipa_reference_global_vars_info_d
);
1340 w_ri
->global
->statics_read
= copy_global_bitmap (node_g
->statics_read
);
1341 w_ri
->global
->statics_written
= copy_global_bitmap (node_g
->statics_written
);
1343 w_info
= (struct ipa_dfs_info
*) w
->aux
;
1344 w
= w_info
->next_cycle
;
1350 for (i
= 0; i
< order_pos
; i
++ )
1352 ipa_reference_vars_info_t node_info
;
1353 ipa_reference_global_vars_info_t node_g
;
1354 ipa_reference_local_vars_info_t node_l
;
1357 struct ipa_dfs_info
* w_info
;
1360 node_info
= get_reference_vars_info (node
);
1361 node_g
= node_info
->global
;
1362 node_l
= node_info
->local
;
1364 "\nFunction name:%s/%i:",
1365 cgraph_node_name (node
), node
->uid
);
1366 fprintf (dump_file
, "\n locals read: ");
1367 if (node_l
->statics_read
)
1368 EXECUTE_IF_SET_IN_BITMAP (node_l
->statics_read
,
1371 fprintf (dump_file
, "%s ",
1372 get_static_name (index
));
1374 fprintf (dump_file
, "\n locals written: ");
1375 if (node_l
->statics_written
)
1376 EXECUTE_IF_SET_IN_BITMAP (node_l
->statics_written
,
1379 fprintf(dump_file
, "%s ",
1380 get_static_name (index
));
1383 w_info
= (struct ipa_dfs_info
*) node
->aux
;
1384 w
= w_info
->next_cycle
;
1387 ipa_reference_vars_info_t w_ri
=
1388 get_reference_vars_info (w
);
1389 ipa_reference_local_vars_info_t w_l
= w_ri
->local
;
1390 fprintf (dump_file
, "\n next cycle: %s/%i ",
1391 cgraph_node_name (w
), w
->uid
);
1392 fprintf (dump_file
, "\n locals read: ");
1393 if (w_l
->statics_read
)
1394 EXECUTE_IF_SET_IN_BITMAP (w_l
->statics_read
,
1397 fprintf (dump_file
, "%s ",
1398 get_static_name (index
));
1401 fprintf (dump_file
, "\n locals written: ");
1402 if (w_l
->statics_written
)
1403 EXECUTE_IF_SET_IN_BITMAP (w_l
->statics_written
,
1406 fprintf (dump_file
, "%s ",
1407 get_static_name (index
));
1410 w_info
= (struct ipa_dfs_info
*) w
->aux
;
1411 w
= w_info
->next_cycle
;
1413 fprintf (dump_file
, "\n globals read: ");
1414 if (node_g
->statics_read
== all_module_statics
)
1415 fprintf (dump_file
, "ALL");
1417 EXECUTE_IF_SET_IN_BITMAP (node_g
->statics_read
,
1420 fprintf (dump_file
, "%s ",
1421 get_static_name (index
));
1423 fprintf (dump_file
, "\n globals written: ");
1424 if (node_g
->statics_written
== all_module_statics
)
1425 fprintf (dump_file
, "ALL");
1427 EXECUTE_IF_SET_IN_BITMAP (node_g
->statics_written
,
1430 fprintf (dump_file
, "%s ",
1431 get_static_name (index
));
1437 for (i
= 0; i
< order_pos
; i
++ )
1439 ipa_reference_vars_info_t node_info
;
1440 ipa_reference_global_vars_info_t node_g
;
1442 node_info
= get_reference_vars_info (node
);
1443 node_g
= node_info
->global
;
1445 /* Create the complimentary sets. These are more useful for
1447 node_g
->statics_not_read
= BITMAP_ALLOC (&global_info_obstack
);
1448 node_g
->statics_not_written
= BITMAP_ALLOC (&global_info_obstack
);
1450 if (node_g
->statics_read
!= all_module_statics
)
1451 bitmap_and_compl (node_g
->statics_not_read
,
1453 node_g
->statics_read
);
1455 if (node_g
->statics_written
1456 != all_module_statics
)
1457 bitmap_and_compl (node_g
->statics_not_written
,
1459 node_g
->statics_written
);
1464 for (node
= cgraph_nodes
; node
; node
= node
->next
)
1466 ipa_reference_vars_info_t node_info
;
1467 node_info
= get_reference_vars_info (node
);
1468 /* Get rid of the aux information. */
1476 if (cgraph_function_body_availability (node
) == AVAIL_OVERWRITABLE
)
1477 clean_function (node
);
1479 clean_function_local_data (node
);
1481 bitmap_obstack_release (&local_info_obstack
);
1487 gate_reference (void)
1489 return (flag_ipa_reference
1490 /* Don't bother doing anything if the program has errors. */
1491 && !(errorcount
|| sorrycount
));
1494 struct ipa_opt_pass_d pass_ipa_reference
=
1498 "static-var", /* name */
1499 gate_reference
, /* gate */
1500 propagate
, /* execute */
1503 0, /* static_pass_number */
1504 TV_IPA_REFERENCE
, /* tv_id */
1505 0, /* properties_required */
1506 0, /* properties_provided */
1507 0, /* properties_destroyed */
1508 0, /* todo_flags_start */
1509 0 /* todo_flags_finish */
1511 generate_summary
, /* generate_summary */
1512 ipa_reference_write_summary
, /* write_summary */
1513 ipa_reference_read_summary
, /* read_summary */
1514 NULL
, /* function_read_summary */
1515 NULL
, /* stmt_fixup */
1517 NULL
, /* function_transform */
1518 NULL
/* variable_transform */
1521 #include "gt-ipa-reference.h"