1 /* Callgraph based analysis of static variables.
2 Copyright (C) 2004, 2005, 2007 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.
53 #include "coretypes.h"
56 #include "tree-flow.h"
57 #include "tree-inline.h"
58 #include "tree-pass.h"
59 #include "langhooks.h"
60 #include "pointer-set.h"
62 #include "ipa-utils.h"
63 #include "ipa-reference.h"
65 #include "tree-gimple.h"
70 #include "diagnostic.h"
71 #include "langhooks.h"
73 /* This splay tree contains all of the static variables that are
74 being considered by the compilation level alias analysis. For
75 module_at_a_time compilation, this is the set of static but not
76 public variables. Any variables that either have their address
77 taken or participate in otherwise unsavory operations are deleted
79 static GTY((param1_is(int), param2_is(tree
)))
80 splay_tree reference_vars_to_consider
;
82 /* This bitmap is used to knock out the module static variables whose
83 addresses have been taken and passed around. */
84 static bitmap module_statics_escape
;
86 /* This bitmap is used to knock out the module static variables that
88 static bitmap module_statics_written
;
90 /* A bit is set for every module static we are considering. This is
91 ored into the local info when asm code is found that clobbers all
93 static bitmap all_module_statics
;
95 static struct pointer_set_t
*visited_nodes
;
97 static bitmap_obstack ipa_obstack
;
99 enum initialization_status_t
106 tree memory_identifier_string
;
108 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
109 static inline ipa_reference_vars_info_t
110 get_reference_vars_info_from_cgraph (struct cgraph_node
* node
)
112 return get_function_ann (node
->decl
)->reference_vars_info
;
115 /* Get a bitmap that contains all of the locally referenced static
116 variables for function FN. */
117 static ipa_reference_local_vars_info_t
118 get_local_reference_vars_info (tree fn
)
120 ipa_reference_vars_info_t info
= get_function_ann (fn
)->reference_vars_info
;
125 /* This phase was not run. */
129 /* Get a bitmap that contains all of the globally referenced static
130 variables for function FN. */
132 static ipa_reference_global_vars_info_t
133 get_global_reference_vars_info (tree fn
)
135 ipa_reference_vars_info_t info
= get_function_ann (fn
)->reference_vars_info
;
140 /* This phase was not run. */
144 /* Return a bitmap indexed by VAR_DECL uid for the static variables
145 that may be read locally by the execution of the function fn.
146 Returns NULL if no data is available. */
149 ipa_reference_get_read_local (tree fn
)
151 ipa_reference_local_vars_info_t l
= get_local_reference_vars_info (fn
);
153 return l
->statics_read
;
158 /* Return a bitmap indexed by VAR_DECL uid for the static variables
159 that may be written locally by the execution of the function fn.
160 Returns NULL if no data is available. */
163 ipa_reference_get_written_local (tree fn
)
165 ipa_reference_local_vars_info_t l
= get_local_reference_vars_info (fn
);
167 return l
->statics_written
;
172 /* Return a bitmap indexed by VAR_DECL uid for the static variables
173 that are read during the execution of the function FN. Returns
174 NULL if no data is available. */
177 ipa_reference_get_read_global (tree fn
)
179 ipa_reference_global_vars_info_t g
= get_global_reference_vars_info (fn
);
181 return g
->statics_read
;
186 /* Return a bitmap indexed by VAR_DECL uid for the static variables
187 that are written during the execution of the function FN. Note
188 that variables written may or may not be read during the function
189 call. Returns NULL if no data is available. */
192 ipa_reference_get_written_global (tree fn
)
194 ipa_reference_global_vars_info_t g
= get_global_reference_vars_info (fn
);
196 return g
->statics_written
;
201 /* Return a bitmap indexed by_DECL_UID uid for the static variables
202 that are not read during the execution of the function FN. Returns
203 NULL if no data is available. */
206 ipa_reference_get_not_read_global (tree fn
)
208 ipa_reference_global_vars_info_t g
= get_global_reference_vars_info (fn
);
210 return g
->statics_not_read
;
215 /* Return a bitmap indexed by DECL_UID uid for the static variables
216 that are not written during the execution of the function FN. Note
217 that variables written may or may not be read during the function
218 call. Returns NULL if no data is available. */
221 ipa_reference_get_not_written_global (tree fn
)
223 ipa_reference_global_vars_info_t g
= get_global_reference_vars_info (fn
);
225 return g
->statics_not_written
;
232 /* Add VAR to all_module_statics and the two
233 reference_vars_to_consider* sets. */
236 add_static_var (tree var
)
238 int uid
= DECL_UID (var
);
239 if (!bitmap_bit_p (all_module_statics
, uid
))
241 splay_tree_insert (reference_vars_to_consider
,
242 uid
, (splay_tree_value
)var
);
243 bitmap_set_bit (all_module_statics
, uid
);
247 /* Return true if the variable T is the right kind of static variable to
248 perform compilation unit scope escape analysis. */
251 has_proper_scope_for_analysis (tree t
)
253 /* If the variable has the "used" attribute, treat it as if it had a
254 been touched by the devil. */
255 if (lookup_attribute ("used", DECL_ATTRIBUTES (t
)))
258 /* Do not want to do anything with volatile except mark any
259 function that uses one to be not const or pure. */
260 if (TREE_THIS_VOLATILE (t
))
263 /* Do not care about a local automatic that is not static. */
264 if (!TREE_STATIC (t
) && !DECL_EXTERNAL (t
))
267 if (DECL_EXTERNAL (t
) || TREE_PUBLIC (t
))
270 /* This is a variable we care about. Check if we have seen it
271 before, and if not add it the set of variables we care about. */
272 if (!bitmap_bit_p (all_module_statics
, DECL_UID (t
)))
278 /* If T is a VAR_DECL for a static that we are interested in, add the
279 uid to the bitmap. */
282 check_operand (ipa_reference_local_vars_info_t local
,
283 tree t
, bool checking_write
)
287 if ((TREE_CODE (t
) == VAR_DECL
|| TREE_CODE (t
) == FUNCTION_DECL
)
288 && (has_proper_scope_for_analysis (t
)))
293 bitmap_set_bit (local
->statics_written
, DECL_UID (t
));
294 /* Mark the write so we can tell which statics are
296 bitmap_set_bit (module_statics_written
, DECL_UID (t
));
299 bitmap_set_bit (local
->statics_read
, DECL_UID (t
));
303 /* Examine tree T for references to static variables. All internal
304 references like array references or indirect references are added
305 to the READ_BM. Direct references are added to either READ_BM or
306 WRITE_BM depending on the value of CHECKING_WRITE. */
309 check_tree (ipa_reference_local_vars_info_t local
, tree t
, bool checking_write
)
311 if ((TREE_CODE (t
) == EXC_PTR_EXPR
) || (TREE_CODE (t
) == FILTER_EXPR
))
314 while (TREE_CODE (t
) == REALPART_EXPR
315 || TREE_CODE (t
) == IMAGPART_EXPR
316 || handled_component_p (t
))
318 if (TREE_CODE (t
) == ARRAY_REF
)
319 check_operand (local
, TREE_OPERAND (t
, 1), false);
320 t
= TREE_OPERAND (t
, 0);
323 /* The bottom of an indirect reference can only be read, not
324 written. So just recurse and whatever we find, check it against
327 /* if (INDIRECT_REF_P (t) || TREE_CODE (t) == MEM_REF) */
328 /* FIXME when we have array_ref's of pointers. */
329 if (INDIRECT_REF_P (t
))
330 check_tree (local
, TREE_OPERAND (t
, 0), false);
333 check_operand (local
, t
, checking_write
);
336 /* Scan tree T to see if there are any addresses taken in within T. */
339 look_for_address_of (tree t
)
341 if (TREE_CODE (t
) == ADDR_EXPR
)
343 tree x
= get_base_var (t
);
344 if (TREE_CODE (x
) == VAR_DECL
|| TREE_CODE (x
) == FUNCTION_DECL
)
345 if (has_proper_scope_for_analysis (x
))
346 bitmap_set_bit (module_statics_escape
, DECL_UID (x
));
350 /* Check to see if T is a read or address of operation on a static var
351 we are interested in analyzing. LOCAL is passed in to get access
352 to its bit vectors. Local is NULL if this is called from a static
356 check_rhs_var (ipa_reference_local_vars_info_t local
, tree t
)
358 look_for_address_of (t
);
363 check_tree(local
, t
, false);
366 /* Check to see if T is an assignment to a static var we are
367 interested in analyzing. LOCAL is passed in to get access to its bit
371 check_lhs_var (ipa_reference_local_vars_info_t local
, tree t
)
376 check_tree(local
, t
, true);
379 /* This is a scaled down version of get_asm_expr_operands from
380 tree_ssa_operands.c. The version there runs much later and assumes
381 that aliasing information is already available. Here we are just
382 trying to find if the set of inputs and outputs contain references
383 or address of operations to local static variables. FN is the
384 function being analyzed and STMT is the actual asm statement. */
387 get_asm_expr_operands (ipa_reference_local_vars_info_t local
, tree stmt
)
389 int noutputs
= list_length (ASM_OUTPUTS (stmt
));
390 const char **oconstraints
391 = (const char **) alloca ((noutputs
) * sizeof (const char *));
394 const char *constraint
;
395 bool allows_mem
, allows_reg
, is_inout
;
397 for (i
=0, link
= ASM_OUTPUTS (stmt
); link
; ++i
, link
= TREE_CHAIN (link
))
399 oconstraints
[i
] = constraint
400 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link
)));
401 parse_output_constraint (&constraint
, i
, 0, 0,
402 &allows_mem
, &allows_reg
, &is_inout
);
404 check_lhs_var (local
, TREE_VALUE (link
));
407 for (link
= ASM_INPUTS (stmt
); link
; link
= TREE_CHAIN (link
))
410 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link
)));
411 parse_input_constraint (&constraint
, 0, 0, noutputs
, 0,
412 oconstraints
, &allows_mem
, &allows_reg
);
414 check_rhs_var (local
, TREE_VALUE (link
));
417 for (link
= ASM_CLOBBERS (stmt
); link
; link
= TREE_CHAIN (link
))
418 if (simple_cst_equal(TREE_VALUE (link
), memory_identifier_string
) == 1)
420 /* Abandon all hope, ye who enter here. */
421 local
->calls_read_all
= true;
422 local
->calls_write_all
= true;
426 /* Check the parameters of a function call from CALLER to CALL_EXPR to
427 see if any of them are static vars. Also check to see if this is
428 either an indirect call, a call outside the compilation unit, or
429 has special attributes that effect the clobbers. The caller
430 parameter is the tree node for the caller and the second operand is
431 the tree node for the entire call expression. */
434 check_call (ipa_reference_local_vars_info_t local
, tree call_expr
)
436 int flags
= call_expr_flags (call_expr
);
437 tree operand_list
= TREE_OPERAND (call_expr
, 1);
439 tree callee_t
= get_callee_fndecl (call_expr
);
440 enum availability avail
= AVAIL_NOT_AVAILABLE
;
442 for (operand
= operand_list
;
443 operand
!= NULL_TREE
;
444 operand
= TREE_CHAIN (operand
))
446 tree argument
= TREE_VALUE (operand
);
447 check_rhs_var (local
, argument
);
452 struct cgraph_node
* callee
= cgraph_node(callee_t
);
453 avail
= cgraph_function_body_availability (callee
);
456 if (avail
== AVAIL_NOT_AVAILABLE
|| avail
== AVAIL_OVERWRITABLE
)
459 if (flags
& ECF_PURE
)
460 local
->calls_read_all
= true;
463 local
->calls_read_all
= true;
464 local
->calls_write_all
= true;
469 /* TP is the part of the tree currently under the microscope.
470 WALK_SUBTREES is part of the walk_tree api but is unused here.
471 DATA is cgraph_node of the function being walked. */
473 /* FIXME: When this is converted to run over SSA form, this code
474 should be converted to use the operand scanner. */
477 scan_for_static_refs (tree
*tp
,
481 struct cgraph_node
*fn
= data
;
483 ipa_reference_local_vars_info_t local
= NULL
;
485 local
= get_reference_vars_info_from_cgraph (fn
)->local
;
487 switch (TREE_CODE (t
))
490 if (DECL_INITIAL (t
))
491 walk_tree (&DECL_INITIAL (t
), scan_for_static_refs
, fn
, visited_nodes
);
497 /* First look on the lhs and see what variable is stored to */
498 tree lhs
= TREE_OPERAND (t
, 0);
499 tree rhs
= TREE_OPERAND (t
, 1);
500 check_lhs_var (local
, lhs
);
502 /* For the purposes of figuring out what the cast affects */
504 /* Next check the operands on the rhs to see if they are ok. */
505 switch (TREE_CODE_CLASS (TREE_CODE (rhs
)))
510 tree op0
= TREE_OPERAND (rhs
, 0);
511 tree op1
= TREE_OPERAND (rhs
, 1);
512 check_rhs_var (local
, op0
);
513 check_rhs_var (local
, op1
);
518 tree op0
= TREE_OPERAND (rhs
, 0);
519 check_rhs_var (local
, op0
);
524 check_rhs_var (local
, rhs
);
526 case tcc_declaration
:
527 check_rhs_var (local
, rhs
);
530 switch (TREE_CODE (rhs
))
533 check_rhs_var (local
, rhs
);
536 check_call (local
, rhs
);
550 /* This case is here to find addresses on rhs of constructors in
551 decl_initial of static variables. */
552 check_rhs_var (local
, t
);
557 if (DECL_NONLOCAL (TREE_OPERAND (t
, 0)))
559 /* Target of long jump. */
560 local
->calls_read_all
= true;
561 local
->calls_write_all
= true;
566 check_call (local
, t
);
571 get_asm_expr_operands (local
, t
);
582 /* Lookup the tree node for the static variable that has UID. */
584 get_static_decl (int index
)
586 splay_tree_node stn
=
587 splay_tree_lookup (reference_vars_to_consider
, index
);
589 return (tree
)stn
->value
;
593 /* Lookup the tree node for the static variable that has UID and
594 convert the name to a string for debugging. */
597 get_static_name (int index
)
599 splay_tree_node stn
=
600 splay_tree_lookup (reference_vars_to_consider
, index
);
602 return lang_hooks
.decl_printable_name ((tree
)(stn
->value
), 2);
606 /* Or in all of the bits from every callee into X, the caller's, bit
607 vector. There are several cases to check to avoid the sparse
611 propagate_bits (struct cgraph_node
*x
)
613 ipa_reference_vars_info_t x_info
= get_reference_vars_info_from_cgraph (x
);
614 ipa_reference_global_vars_info_t x_global
= x_info
->global
;
616 struct cgraph_edge
*e
;
617 for (e
= x
->callees
; e
; e
= e
->next_callee
)
619 struct cgraph_node
*y
= e
->callee
;
621 /* Only look at the master nodes and skip external nodes. */
622 y
= cgraph_master_clone (y
);
625 if (get_reference_vars_info_from_cgraph (y
))
627 ipa_reference_vars_info_t y_info
= get_reference_vars_info_from_cgraph (y
);
628 ipa_reference_global_vars_info_t y_global
= y_info
->global
;
630 if (x_global
->statics_read
631 != all_module_statics
)
633 if (y_global
->statics_read
634 == all_module_statics
)
636 BITMAP_FREE (x_global
->statics_read
);
637 x_global
->statics_read
638 = all_module_statics
;
640 /* Skip bitmaps that are pointer equal to node's bitmap
641 (no reason to spin within the cycle). */
642 else if (x_global
->statics_read
643 != y_global
->statics_read
)
644 bitmap_ior_into (x_global
->statics_read
,
645 y_global
->statics_read
);
648 if (x_global
->statics_written
649 != all_module_statics
)
651 if (y_global
->statics_written
652 == all_module_statics
)
654 BITMAP_FREE (x_global
->statics_written
);
655 x_global
->statics_written
656 = all_module_statics
;
658 /* Skip bitmaps that are pointer equal to node's bitmap
659 (no reason to spin within the cycle). */
660 else if (x_global
->statics_written
661 != y_global
->statics_written
)
662 bitmap_ior_into (x_global
->statics_written
,
663 y_global
->statics_written
);
674 /* Look at all of the callees of X to see which ones represent inlined
675 calls. For each of these callees, merge their local info into
676 TARGET and check their children recursively.
678 This function goes away when Jan changes the inliner and IPA
679 analysis so that this is not run between the time when inlining
680 decisions are made and when the inlining actually occurs. */
683 merge_callee_local_info (struct cgraph_node
*target
,
684 struct cgraph_node
*x
)
686 struct cgraph_edge
*e
;
687 ipa_reference_local_vars_info_t x_l
=
688 get_reference_vars_info_from_cgraph (target
)->local
;
690 /* Make the world safe for tail recursion. */
691 struct ipa_dfs_info
*node_info
= x
->aux
;
698 for (e
= x
->callees
; e
; e
= e
->next_callee
)
700 struct cgraph_node
*y
= e
->callee
;
701 if (y
->global
.inlined_to
)
703 ipa_reference_vars_info_t y_info
;
704 ipa_reference_local_vars_info_t y_l
;
705 struct cgraph_node
* orig_y
= y
;
707 y
= cgraph_master_clone (y
);
710 y_info
= get_reference_vars_info_from_cgraph (y
);
714 bitmap_ior_into (x_l
->statics_read
,
716 bitmap_ior_into (x_l
->statics_written
,
717 y_l
->statics_written
);
719 x_l
->calls_read_all
|= y_l
->calls_read_all
;
720 x_l
->calls_write_all
|= y_l
->calls_write_all
;
721 merge_callee_local_info (target
, y
);
725 fprintf(stderr
, "suspect inlining of ");
726 dump_cgraph_node (stderr
, orig_y
);
727 fprintf(stderr
, "\ninto ");
728 dump_cgraph_node (stderr
, target
);
729 dump_cgraph (stderr
);
735 node_info
->aux
= NULL
;
738 /* The init routine for analyzing global static variable usage. See
739 comments at top for description. */
743 struct cgraph_node
*node
;
744 memory_identifier_string
= build_string(7, "memory");
746 reference_vars_to_consider
=
747 splay_tree_new_ggc (splay_tree_compare_ints
);
749 bitmap_obstack_initialize (&ipa_obstack
);
750 module_statics_escape
= BITMAP_ALLOC (&ipa_obstack
);
751 module_statics_written
= BITMAP_ALLOC (&ipa_obstack
);
752 all_module_statics
= BITMAP_ALLOC (&ipa_obstack
);
754 /* This will add NODE->DECL to the splay trees. */
755 for (node
= cgraph_nodes
; node
; node
= node
->next
)
756 has_proper_scope_for_analysis (node
->decl
);
758 /* There are some shared nodes, in particular the initializers on
759 static declarations. We do not need to scan them more than once
760 since all we would be interested in are the addressof
762 visited_nodes
= pointer_set_create ();
765 /* Check out the rhs of a static or global initialization VNODE to see
766 if any of them contain addressof operations. Note that some of
767 these variables may not even be referenced in the code in this
768 compilation unit but their right hand sides may contain references
769 to variables defined within this unit. */
772 analyze_variable (struct cgraph_varpool_node
*vnode
)
774 tree global
= vnode
->decl
;
775 if (TREE_CODE (global
) == VAR_DECL
)
777 if (DECL_INITIAL (global
))
778 walk_tree (&DECL_INITIAL (global
), scan_for_static_refs
,
779 NULL
, visited_nodes
);
781 else gcc_unreachable ();
784 /* This is the main routine for finding the reference patterns for
785 global variables within a function FN. */
788 analyze_function (struct cgraph_node
*fn
)
790 ipa_reference_vars_info_t info
791 = xcalloc (1, sizeof (struct ipa_reference_vars_info_d
));
792 ipa_reference_local_vars_info_t l
793 = xcalloc (1, sizeof (struct ipa_reference_local_vars_info_d
));
794 tree decl
= fn
->decl
;
796 /* Add the info to the tree's annotation. */
797 get_function_ann (fn
->decl
)->reference_vars_info
= info
;
800 l
->statics_read
= BITMAP_ALLOC (&ipa_obstack
);
801 l
->statics_written
= BITMAP_ALLOC (&ipa_obstack
);
804 fprintf (dump_file
, "\n local analysis of %s\n", cgraph_node_name (fn
));
807 struct function
*this_cfun
= DECL_STRUCT_FUNCTION (decl
);
808 basic_block this_block
;
810 FOR_EACH_BB_FN (this_block
, this_cfun
)
812 block_stmt_iterator bsi
;
813 for (bsi
= bsi_start (this_block
); !bsi_end_p (bsi
); bsi_next (&bsi
))
814 walk_tree (bsi_stmt_ptr (bsi
), scan_for_static_refs
,
819 /* There may be const decls with interesting right hand sides. */
820 if (DECL_STRUCT_FUNCTION (decl
))
823 for (step
= DECL_STRUCT_FUNCTION (decl
)->unexpanded_var_list
;
825 step
= TREE_CHAIN (step
))
827 tree var
= TREE_VALUE (step
);
828 if (TREE_CODE (var
) == VAR_DECL
829 && DECL_INITIAL (var
)
830 && !TREE_STATIC (var
))
831 walk_tree (&DECL_INITIAL (var
), scan_for_static_refs
,
837 /* If FN is avail == AVAIL_OVERWRITABLE, replace the effects bit
838 vectors with worst case bit vectors. We had to analyze it above to
839 find out if it took the address of any statics. However, now that
840 we know that, we can get rid of all of the other side effects. */
843 clean_function (struct cgraph_node
*fn
)
845 ipa_reference_vars_info_t info
= get_reference_vars_info_from_cgraph (fn
);
846 ipa_reference_local_vars_info_t l
= info
->local
;
847 ipa_reference_global_vars_info_t g
= info
->global
;
852 && l
->statics_read
!= all_module_statics
)
853 BITMAP_FREE (l
->statics_read
);
854 if (l
->statics_written
855 &&l
->statics_written
!= all_module_statics
)
856 BITMAP_FREE (l
->statics_written
);
863 && g
->statics_read
!= all_module_statics
)
864 BITMAP_FREE (g
->statics_read
);
866 if (g
->statics_written
867 && g
->statics_written
!= all_module_statics
)
868 BITMAP_FREE (g
->statics_written
);
870 if (g
->statics_not_read
871 && g
->statics_not_read
!= all_module_statics
)
872 BITMAP_FREE (g
->statics_not_read
);
874 if (g
->statics_not_written
875 && g
->statics_not_written
!= all_module_statics
)
876 BITMAP_FREE (g
->statics_not_written
);
881 free (get_function_ann (fn
->decl
)->reference_vars_info
);
882 get_function_ann (fn
->decl
)->reference_vars_info
= NULL
;
886 /* Produce the global information by preforming a transitive closure
887 on the local information that was produced by ipa_analyze_function
888 and ipa_analyze_variable. */
891 static_execute (void)
893 struct cgraph_node
*node
;
894 struct cgraph_varpool_node
*vnode
;
895 struct cgraph_node
*w
;
896 struct cgraph_node
**order
=
897 xcalloc (cgraph_n_nodes
, sizeof (struct cgraph_node
*));
898 int order_pos
= order_pos
= ipa_utils_reduced_inorder (order
, false, true);
903 /* Process all of the variables first. */
904 for (vnode
= cgraph_varpool_nodes_queue
; vnode
; vnode
= vnode
->next_needed
)
905 analyze_variable (vnode
);
907 /* Process all of the functions next.
909 We do not want to process any of the clones so we check that this
910 is a master clone. However, we do need to process any
911 AVAIL_OVERWRITABLE functions (these are never clones) because
912 they may cause a static variable to escape. The code that can
913 overwrite such a function cannot access the statics because it
914 would not be in the same compilation unit. When the analysis is
915 finished, the computed information of these AVAIL_OVERWRITABLE is
916 replaced with worst case info.
918 for (node
= cgraph_nodes
; node
; node
= node
->next
)
920 && (cgraph_is_master_clone (node
)
921 || (cgraph_function_body_availability (node
)
922 == AVAIL_OVERWRITABLE
)))
923 analyze_function (node
);
925 pointer_set_destroy (visited_nodes
);
926 visited_nodes
= NULL
;
928 dump_cgraph (dump_file
);
930 /* Prune out the variables that were found to behave badly
931 (i.e. have their address taken). */
935 bitmap module_statics_readonly
= BITMAP_ALLOC (&ipa_obstack
);
936 bitmap module_statics_const
= BITMAP_ALLOC (&ipa_obstack
);
937 bitmap bm_temp
= BITMAP_ALLOC (&ipa_obstack
);
939 EXECUTE_IF_SET_IN_BITMAP (module_statics_escape
, 0, index
, bi
)
941 splay_tree_remove (reference_vars_to_consider
, index
);
944 bitmap_and_compl_into (all_module_statics
,
945 module_statics_escape
);
947 bitmap_and_compl (module_statics_readonly
, all_module_statics
,
948 module_statics_written
);
950 /* If the address is not taken, we can unset the addressable bit
952 EXECUTE_IF_SET_IN_BITMAP (all_module_statics
, 0, index
, bi
)
954 tree var
= get_static_decl (index
);
955 TREE_ADDRESSABLE (var
) = 0;
957 fprintf (dump_file
, "Not TREE_ADDRESSABLE var %s\n",
958 get_static_name (index
));
961 /* If the variable is never written, we can set the TREE_READONLY
962 flag. Additionally if it has a DECL_INITIAL that is made up of
963 constants we can treat the entire global as a constant. */
965 bitmap_and_compl (module_statics_readonly
, all_module_statics
,
966 module_statics_written
);
967 EXECUTE_IF_SET_IN_BITMAP (module_statics_readonly
, 0, index
, bi
)
969 tree var
= get_static_decl (index
);
971 /* Readonly on a function decl is very different from the
973 if (TREE_CODE (var
) == FUNCTION_DECL
)
976 /* Ignore variables in named sections - changing TREE_READONLY
977 changes the section flags, potentially causing conflicts with
978 other variables in the same named section. */
979 if (DECL_SECTION_NAME (var
) == NULL_TREE
)
981 TREE_READONLY (var
) = 1;
983 fprintf (dump_file
, "read-only var %s\n",
984 get_static_name (index
));
986 if (DECL_INITIAL (var
)
987 && is_gimple_min_invariant (DECL_INITIAL (var
)))
989 bitmap_set_bit (module_statics_const
, index
);
991 fprintf (dump_file
, "read-only constant %s\n",
992 get_static_name (index
));
996 BITMAP_FREE(module_statics_escape
);
997 BITMAP_FREE(module_statics_written
);
1000 EXECUTE_IF_SET_IN_BITMAP (all_module_statics
, 0, index
, bi
)
1002 fprintf (dump_file
, "\nPromotable global:%s",
1003 get_static_name (index
));
1006 for (i
= 0; i
< order_pos
; i
++ )
1008 ipa_reference_local_vars_info_t l
;
1010 l
= get_reference_vars_info_from_cgraph (node
)->local
;
1012 /* Any variables that are not in all_module_statics are
1013 removed from the local maps. This will include all of the
1014 variables that were found to escape in the function
1016 bitmap_and_into (l
->statics_read
,
1017 all_module_statics
);
1018 bitmap_and_into (l
->statics_written
,
1019 all_module_statics
);
1022 BITMAP_FREE(module_statics_readonly
);
1023 BITMAP_FREE(module_statics_const
);
1024 BITMAP_FREE(bm_temp
);
1029 for (i
= 0; i
< order_pos
; i
++ )
1032 ipa_reference_local_vars_info_t l
;
1036 l
= get_reference_vars_info_from_cgraph (node
)->local
;
1038 "\nFunction name:%s/%i:",
1039 cgraph_node_name (node
), node
->uid
);
1040 fprintf (dump_file
, "\n locals read: ");
1041 EXECUTE_IF_SET_IN_BITMAP (l
->statics_read
,
1044 fprintf (dump_file
, "%s ",
1045 get_static_name (index
));
1047 fprintf (dump_file
, "\n locals written: ");
1048 EXECUTE_IF_SET_IN_BITMAP (l
->statics_written
,
1051 fprintf(dump_file
, "%s ",
1052 get_static_name (index
));
1057 /* Propagate the local information thru the call graph to produce
1058 the global information. All the nodes within a cycle will have
1059 the same info so we collapse cycles first. Then we can do the
1060 propagation in one pass from the leaves to the roots. */
1061 order_pos
= ipa_utils_reduced_inorder (order
, true, true);
1063 ipa_utils_print_order(dump_file
, "reduced", order
, order_pos
);
1065 for (i
= 0; i
< order_pos
; i
++ )
1067 ipa_reference_vars_info_t node_info
;
1068 ipa_reference_global_vars_info_t node_g
=
1069 xcalloc (1, sizeof (struct ipa_reference_global_vars_info_d
));
1070 ipa_reference_local_vars_info_t node_l
;
1074 struct ipa_dfs_info
* w_info
;
1077 node_info
= get_reference_vars_info_from_cgraph (node
);
1080 dump_cgraph_node (stderr
, node
);
1081 dump_cgraph (stderr
);
1085 node_info
->global
= node_g
;
1086 node_l
= node_info
->local
;
1088 read_all
= node_l
->calls_read_all
;
1089 write_all
= node_l
->calls_write_all
;
1091 /* If any node in a cycle is calls_read_all or calls_write_all
1094 w
= w_info
->next_cycle
;
1097 ipa_reference_local_vars_info_t w_l
=
1098 get_reference_vars_info_from_cgraph (w
)->local
;
1099 read_all
|= w_l
->calls_read_all
;
1100 write_all
|= w_l
->calls_write_all
;
1103 w
= w_info
->next_cycle
;
1106 /* Initialized the bitmaps for the reduced nodes */
1108 node_g
->statics_read
= all_module_statics
;
1111 node_g
->statics_read
= BITMAP_ALLOC (&ipa_obstack
);
1112 bitmap_copy (node_g
->statics_read
,
1113 node_l
->statics_read
);
1117 node_g
->statics_written
= all_module_statics
;
1120 node_g
->statics_written
= BITMAP_ALLOC (&ipa_obstack
);
1121 bitmap_copy (node_g
->statics_written
,
1122 node_l
->statics_written
);
1126 w
= w_info
->next_cycle
;
1129 ipa_reference_vars_info_t w_ri
=
1130 get_reference_vars_info_from_cgraph (w
);
1131 ipa_reference_local_vars_info_t w_l
= w_ri
->local
;
1133 /* All nodes within a cycle share the same global info bitmaps. */
1134 w_ri
->global
= node_g
;
1136 /* These global bitmaps are initialized from the local info
1137 of all of the nodes in the region. However there is no
1138 need to do any work if the bitmaps were set to
1139 all_module_statics. */
1141 bitmap_ior_into (node_g
->statics_read
,
1144 bitmap_ior_into (node_g
->statics_written
,
1145 w_l
->statics_written
);
1147 w
= w_info
->next_cycle
;
1155 w
= w_info
->next_cycle
;
1159 /* Need to fix up the local information sets. The information that
1160 has been gathered so far is preinlining. However, the
1161 compilation will progress post inlining so the local sets for the
1162 inlined calls need to be merged into the callers. Note that the
1163 local sets are not shared between all of the nodes in a cycle so
1164 those nodes in the cycle must be processed explicitly. */
1165 for (i
= 0; i
< order_pos
; i
++ )
1167 struct ipa_dfs_info
* w_info
;
1169 merge_callee_local_info (node
, node
);
1172 w
= w_info
->next_cycle
;
1175 merge_callee_local_info (w
, w
);
1177 w
= w_info
->next_cycle
;
1183 for (i
= 0; i
< order_pos
; i
++ )
1185 ipa_reference_vars_info_t node_info
;
1186 ipa_reference_global_vars_info_t node_g
;
1187 ipa_reference_local_vars_info_t node_l
;
1190 struct ipa_dfs_info
* w_info
;
1193 node_info
= get_reference_vars_info_from_cgraph (node
);
1194 node_g
= node_info
->global
;
1195 node_l
= node_info
->local
;
1197 "\nFunction name:%s/%i:",
1198 cgraph_node_name (node
), node
->uid
);
1199 fprintf (dump_file
, "\n locals read: ");
1200 EXECUTE_IF_SET_IN_BITMAP (node_l
->statics_read
,
1203 fprintf (dump_file
, "%s ",
1204 get_static_name (index
));
1206 fprintf (dump_file
, "\n locals written: ");
1207 EXECUTE_IF_SET_IN_BITMAP (node_l
->statics_written
,
1210 fprintf(dump_file
, "%s ",
1211 get_static_name (index
));
1215 w
= w_info
->next_cycle
;
1218 ipa_reference_vars_info_t w_ri
=
1219 get_reference_vars_info_from_cgraph (w
);
1220 ipa_reference_local_vars_info_t w_l
= w_ri
->local
;
1221 fprintf (dump_file
, "\n next cycle: %s/%i ",
1222 cgraph_node_name (w
), w
->uid
);
1223 fprintf (dump_file
, "\n locals read: ");
1224 EXECUTE_IF_SET_IN_BITMAP (w_l
->statics_read
,
1227 fprintf (dump_file
, "%s ",
1228 get_static_name (index
));
1231 fprintf (dump_file
, "\n locals written: ");
1232 EXECUTE_IF_SET_IN_BITMAP (w_l
->statics_written
,
1235 fprintf(dump_file
, "%s ",
1236 get_static_name (index
));
1241 w
= w_info
->next_cycle
;
1243 fprintf (dump_file
, "\n globals read: ");
1244 EXECUTE_IF_SET_IN_BITMAP (node_g
->statics_read
,
1247 fprintf (dump_file
, "%s ",
1248 get_static_name (index
));
1250 fprintf (dump_file
, "\n globals written: ");
1251 EXECUTE_IF_SET_IN_BITMAP (node_g
->statics_written
,
1254 fprintf (dump_file
, "%s ",
1255 get_static_name (index
));
1261 for (i
= 0; i
< order_pos
; i
++ )
1263 ipa_reference_vars_info_t node_info
;
1264 ipa_reference_global_vars_info_t node_g
;
1266 node_info
= get_reference_vars_info_from_cgraph (node
);
1267 node_g
= node_info
->global
;
1269 /* Create the complimentary sets. These are more useful for
1271 node_g
->statics_not_read
= BITMAP_ALLOC (&ipa_obstack
);
1272 node_g
->statics_not_written
= BITMAP_ALLOC (&ipa_obstack
);
1274 if (node_g
->statics_read
!= all_module_statics
)
1276 bitmap_and_compl (node_g
->statics_not_read
,
1278 node_g
->statics_read
);
1281 if (node_g
->statics_written
1282 != all_module_statics
)
1283 bitmap_and_compl (node_g
->statics_not_written
,
1285 node_g
->statics_written
);
1290 for (node
= cgraph_nodes
; node
; node
= node
->next
)
1292 /* Get rid of the aux information. */
1301 && (cgraph_function_body_availability (node
) == AVAIL_OVERWRITABLE
))
1302 clean_function (node
);
1309 gate_reference (void)
1311 return (flag_unit_at_a_time
!= 0 && flag_ipa_reference
1312 /* Don't bother doing anything if the program has errors. */
1313 && !(errorcount
|| sorrycount
));
1316 struct tree_opt_pass pass_ipa_reference
=
1318 "static-var", /* name */
1319 gate_reference
, /* gate */
1320 static_execute
, /* execute */
1323 0, /* static_pass_number */
1324 TV_IPA_REFERENCE
, /* tv_id */
1325 0, /* properties_required */
1326 0, /* properties_provided */
1327 0, /* properties_destroyed */
1328 0, /* todo_flags_start */
1329 0, /* todo_flags_finish */
1333 #include "gt-ipa-reference.h"