1 /* Callgraph based analysis of static variables.
2 Copyright (C) 2004, 2005, 2007, 2008 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"
61 #include "ipa-utils.h"
62 #include "ipa-reference.h"
69 #include "diagnostic.h"
70 #include "langhooks.h"
72 /* This splay tree contains all of the static variables that are
73 being considered by the compilation level alias analysis. For
74 module_at_a_time compilation, this is the set of static but not
75 public variables. Any variables that either have their address
76 taken or participate in otherwise unsavory operations are deleted
78 static GTY((param1_is(int), param2_is(tree)))
79 splay_tree reference_vars_to_consider;
81 /* This bitmap is used to knock out the module static variables whose
82 addresses have been taken and passed around. */
83 static bitmap module_statics_escape;
85 /* This bitmap is used to knock out the module static variables that
87 static bitmap module_statics_written;
89 /* A bit is set for every module static we are considering. This is
90 ored into the local info when asm code is found that clobbers all
92 static bitmap all_module_statics;
94 static struct pointer_set_t *visited_nodes;
96 static bitmap_obstack ipa_obstack;
98 enum initialization_status_t
105 tree memory_identifier_string;
107 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
108 static inline ipa_reference_vars_info_t
109 get_reference_vars_info_from_cgraph (struct cgraph_node * node)
111 return get_function_ann (node->decl)->reference_vars_info;
114 /* Get a bitmap that contains all of the locally referenced static
115 variables for function FN. */
116 static ipa_reference_local_vars_info_t
117 get_local_reference_vars_info (tree fn)
119 ipa_reference_vars_info_t info = get_function_ann (fn)->reference_vars_info;
124 /* This phase was not run. */
128 /* Get a bitmap that contains all of the globally referenced static
129 variables for function FN. */
131 static ipa_reference_global_vars_info_t
132 get_global_reference_vars_info (tree fn)
134 ipa_reference_vars_info_t info = get_function_ann (fn)->reference_vars_info;
139 /* This phase was not run. */
143 /* Return a bitmap indexed by VAR_DECL uid for the static variables
144 that may be read locally by the execution of the function fn.
145 Returns NULL if no data is available. */
148 ipa_reference_get_read_local (tree fn)
150 ipa_reference_local_vars_info_t l = get_local_reference_vars_info (fn);
152 return l->statics_read;
157 /* Return a bitmap indexed by VAR_DECL uid for the static variables
158 that may be written locally by the execution of the function fn.
159 Returns NULL if no data is available. */
162 ipa_reference_get_written_local (tree fn)
164 ipa_reference_local_vars_info_t l = get_local_reference_vars_info (fn);
166 return l->statics_written;
171 /* Return a bitmap indexed by VAR_DECL uid for the static variables
172 that are read during the execution of the function FN. Returns
173 NULL if no data is available. */
176 ipa_reference_get_read_global (tree fn)
178 ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
180 return g->statics_read;
185 /* Return a bitmap indexed by VAR_DECL uid for the static variables
186 that are written during the execution of the function FN. Note
187 that variables written may or may not be read during the function
188 call. Returns NULL if no data is available. */
191 ipa_reference_get_written_global (tree fn)
193 ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
195 return g->statics_written;
200 /* Return a bitmap indexed by_DECL_UID uid for the static variables
201 that are not read during the execution of the function FN. Returns
202 NULL if no data is available. */
205 ipa_reference_get_not_read_global (tree fn)
207 ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
209 return g->statics_not_read;
214 /* Return a bitmap indexed by DECL_UID uid for the static variables
215 that are not written during the execution of the function FN. Note
216 that variables written may or may not be read during the function
217 call. Returns NULL if no data is available. */
220 ipa_reference_get_not_written_global (tree fn)
222 ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
224 return g->statics_not_written;
231 /* Add VAR to all_module_statics and the two
232 reference_vars_to_consider* sets. */
235 add_static_var (tree var)
237 int uid = DECL_UID (var);
238 if (!bitmap_bit_p (all_module_statics, uid))
240 splay_tree_insert (reference_vars_to_consider,
241 uid, (splay_tree_value)var);
242 bitmap_set_bit (all_module_statics, uid);
246 /* Return true if the variable T is the right kind of static variable to
247 perform compilation unit scope escape analysis. */
250 has_proper_scope_for_analysis (tree t)
252 /* If the variable has the "used" attribute, treat it as if it had a
253 been touched by the devil. */
254 if (lookup_attribute ("used", DECL_ATTRIBUTES (t)))
257 /* Do not want to do anything with volatile except mark any
258 function that uses one to be not const or pure. */
259 if (TREE_THIS_VOLATILE (t))
262 /* Do not care about a local automatic that is not static. */
263 if (!TREE_STATIC (t) && !DECL_EXTERNAL (t))
266 if (DECL_EXTERNAL (t) || TREE_PUBLIC (t))
269 /* We cannot touch decls where the type needs constructing. */
270 if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (t)))
273 /* This is a variable we care about. Check if we have seen it
274 before, and if not add it the set of variables we care about. */
275 if (!bitmap_bit_p (all_module_statics, DECL_UID (t)))
281 /* If T is a VAR_DECL for a static that we are interested in, add the
282 uid to the bitmap. */
285 check_operand (ipa_reference_local_vars_info_t local,
286 tree t, bool checking_write)
290 if ((TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == FUNCTION_DECL)
291 && (has_proper_scope_for_analysis (t)))
296 bitmap_set_bit (local->statics_written, DECL_UID (t));
297 /* Mark the write so we can tell which statics are
299 bitmap_set_bit (module_statics_written, DECL_UID (t));
302 bitmap_set_bit (local->statics_read, DECL_UID (t));
306 /* Examine tree T for references to static variables. All internal
307 references like array references or indirect references are added
308 to the READ_BM. Direct references are added to either READ_BM or
309 WRITE_BM depending on the value of CHECKING_WRITE. */
312 check_tree (ipa_reference_local_vars_info_t local, tree t, bool checking_write)
314 if ((TREE_CODE (t) == EXC_PTR_EXPR) || (TREE_CODE (t) == FILTER_EXPR))
317 while (TREE_CODE (t) == REALPART_EXPR
318 || TREE_CODE (t) == IMAGPART_EXPR
319 || handled_component_p (t))
321 if (TREE_CODE (t) == ARRAY_REF)
322 check_operand (local, TREE_OPERAND (t, 1), false);
323 t = TREE_OPERAND (t, 0);
326 /* The bottom of an indirect reference can only be read, not
327 written. So just recurse and whatever we find, check it against
330 /* if (INDIRECT_REF_P (t) || TREE_CODE (t) == MEM_REF) */
331 /* FIXME when we have array_ref's of pointers. */
332 if (INDIRECT_REF_P (t))
333 check_tree (local, TREE_OPERAND (t, 0), false);
336 check_operand (local, t, checking_write);
339 /* Scan tree T to see if there are any addresses taken in within T. */
342 look_for_address_of (tree t)
344 if (TREE_CODE (t) == ADDR_EXPR)
346 tree x = get_base_var (t);
347 if (TREE_CODE (x) == VAR_DECL || TREE_CODE (x) == FUNCTION_DECL)
348 if (has_proper_scope_for_analysis (x))
349 bitmap_set_bit (module_statics_escape, DECL_UID (x));
353 /* Check to see if T is a read or address of operation on a static var
354 we are interested in analyzing. LOCAL is passed in to get access
355 to its bit vectors. Local is NULL if this is called from a static
359 check_rhs_var (ipa_reference_local_vars_info_t local, tree t)
361 look_for_address_of (t);
366 check_tree(local, t, false);
369 /* Check to see if T is an assignment to a static var we are
370 interested in analyzing. LOCAL is passed in to get access to its bit
374 check_lhs_var (ipa_reference_local_vars_info_t local, tree t)
379 check_tree(local, t, true);
382 /* This is a scaled down version of get_asm_expr_operands from
383 tree_ssa_operands.c. The version there runs much later and assumes
384 that aliasing information is already available. Here we are just
385 trying to find if the set of inputs and outputs contain references
386 or address of operations to local static variables. FN is the
387 function being analyzed and STMT is the actual asm statement. */
390 get_asm_stmt_operands (ipa_reference_local_vars_info_t local, gimple stmt)
392 size_t noutputs = gimple_asm_noutputs (stmt);
393 const char **oconstraints
394 = (const char **) alloca ((noutputs) * sizeof (const char *));
397 const char *constraint;
398 bool allows_mem, allows_reg, is_inout;
400 for (i = 0; i < noutputs; i++)
402 op = gimple_asm_output_op (stmt, i);
403 oconstraints[i] = constraint
404 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
405 parse_output_constraint (&constraint, i, 0, 0,
406 &allows_mem, &allows_reg, &is_inout);
408 check_lhs_var (local, TREE_VALUE (op));
411 for (i = 0; i < gimple_asm_ninputs (stmt); i++)
413 op = gimple_asm_input_op (stmt, i);
415 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
416 parse_input_constraint (&constraint, 0, 0, noutputs, 0,
417 oconstraints, &allows_mem, &allows_reg);
419 check_rhs_var (local, TREE_VALUE (op));
422 for (i = 0; i < gimple_asm_nclobbers (stmt); i++)
424 op = gimple_asm_clobber_op (stmt, i);
425 if (simple_cst_equal(TREE_VALUE (op), memory_identifier_string) == 1)
427 /* Abandon all hope, ye who enter here. */
428 local->calls_read_all = true;
429 local->calls_write_all = true;
434 /* Check the parameters of a function call from CALLER to CALL_EXPR to
435 see if any of them are static vars. Also check to see if this is
436 either an indirect call, a call outside the compilation unit, or
437 has special attributes that effect the clobbers. The caller
438 parameter is the tree node for the caller and the second operand is
439 the tree node for the entire call expression. */
442 check_call (ipa_reference_local_vars_info_t local, gimple stmt)
444 int flags = gimple_call_flags (stmt);
446 tree callee_t = gimple_call_fndecl (stmt);
447 enum availability avail = AVAIL_NOT_AVAILABLE;
450 if ((operand = gimple_call_lhs (stmt)) != NULL)
451 check_lhs_var (local, operand);
453 for (i = 0; i < gimple_call_num_args (stmt); i++)
454 check_rhs_var (local, gimple_call_arg (stmt, i));
458 struct cgraph_node* callee = cgraph_node(callee_t);
459 avail = cgraph_function_body_availability (callee);
462 if (avail == AVAIL_NOT_AVAILABLE || avail == AVAIL_OVERWRITABLE)
465 if (flags & ECF_PURE)
466 local->calls_read_all = true;
469 local->calls_read_all = true;
470 local->calls_write_all = true;
475 /* TP is the part of the tree currently under the microscope.
476 WALK_SUBTREES is part of the walk_tree api but is unused here.
477 DATA is cgraph_node of the function being walked. */
479 /* FIXME: When this is converted to run over SSA form, this code
480 should be converted to use the operand scanner. */
483 scan_stmt_for_static_refs (gimple_stmt_iterator *gsip, bool *handled_ops_p,
484 struct walk_stmt_info *data)
486 struct cgraph_node *fn = (struct cgraph_node *) data->info;
487 gimple stmt = gsi_stmt (*gsip);
488 ipa_reference_local_vars_info_t local = NULL;
490 local = get_reference_vars_info_from_cgraph (fn)->local;
492 switch (gimple_code (stmt))
496 /* First look on the lhs and see what variable is stored to */
497 tree lhs = gimple_assign_lhs (stmt);
498 tree rhs1 = gimple_assign_rhs1 (stmt);
499 tree rhs2 = gimple_assign_rhs2 (stmt);
500 enum tree_code code = gimple_assign_rhs_code (stmt);
502 check_lhs_var (local, lhs);
504 /* For the purposes of figuring out what the cast affects */
506 /* Next check the operands on the rhs to see if they are ok. */
507 switch (TREE_CODE_CLASS (code))
511 check_rhs_var (local, rhs1);
512 check_rhs_var (local, rhs2);
517 case tcc_declaration:
518 check_rhs_var (local, rhs1);
525 check_rhs_var (local, rhs1);
534 *handled_ops_p = true;
539 if (DECL_NONLOCAL (gimple_label_label (stmt)))
541 /* Target of long jump. */
542 local->calls_read_all = true;
543 local->calls_write_all = true;
548 check_call (local, stmt);
549 *handled_ops_p = true;
553 get_asm_stmt_operands (local, stmt);
554 *handled_ops_p = true;
563 /* Call-back to scan GIMPLE operands for static references. This is supposed
564 to work with scan_stmt_for_static_refs so the real call-back data is stored
565 inside a walk_stmt_info struct. Callers using the walk_tree interface must
566 also wrap the call-back data in a walk_stmt_info struct. */
569 scan_op_for_static_refs (tree *tp, int *walk_subtrees, void *data)
571 struct walk_stmt_info *wi = (struct walk_stmt_info*) data;
572 struct cgraph_node *fn = (struct cgraph_node *) wi->info;
574 ipa_reference_local_vars_info_t local = NULL;
576 local = get_reference_vars_info_from_cgraph (fn)->local;
578 switch (TREE_CODE (t))
581 if (DECL_INITIAL (t))
582 walk_tree (&DECL_INITIAL (t), scan_op_for_static_refs, data,
588 /* This case is here to find addresses on rhs of constructors in
589 decl_initial of static variables. */
590 check_rhs_var (local, t);
600 /* Lookup the tree node for the static variable that has UID. */
602 get_static_decl (int index)
604 splay_tree_node stn =
605 splay_tree_lookup (reference_vars_to_consider, index);
607 return (tree)stn->value;
611 /* Lookup the tree node for the static variable that has UID and
612 convert the name to a string for debugging. */
615 get_static_name (int index)
617 splay_tree_node stn =
618 splay_tree_lookup (reference_vars_to_consider, index);
620 return lang_hooks.decl_printable_name ((tree)(stn->value), 2);
624 /* Or in all of the bits from every callee into X, the caller's, bit
625 vector. There are several cases to check to avoid the sparse
629 propagate_bits (struct cgraph_node *x)
631 ipa_reference_vars_info_t x_info = get_reference_vars_info_from_cgraph (x);
632 ipa_reference_global_vars_info_t x_global = x_info->global;
634 struct cgraph_edge *e;
635 for (e = x->callees; e; e = e->next_callee)
637 struct cgraph_node *y = e->callee;
639 /* Only look at the master nodes and skip external nodes. */
640 y = cgraph_master_clone (y);
643 if (get_reference_vars_info_from_cgraph (y))
645 ipa_reference_vars_info_t y_info
646 = get_reference_vars_info_from_cgraph (y);
647 ipa_reference_global_vars_info_t y_global = y_info->global;
649 if (x_global->statics_read
650 != all_module_statics)
652 if (y_global->statics_read
653 == all_module_statics)
655 BITMAP_FREE (x_global->statics_read);
656 x_global->statics_read
657 = all_module_statics;
659 /* Skip bitmaps that are pointer equal to node's bitmap
660 (no reason to spin within the cycle). */
661 else if (x_global->statics_read
662 != y_global->statics_read)
663 bitmap_ior_into (x_global->statics_read,
664 y_global->statics_read);
667 if (x_global->statics_written
668 != all_module_statics)
670 if (y_global->statics_written
671 == all_module_statics)
673 BITMAP_FREE (x_global->statics_written);
674 x_global->statics_written
675 = all_module_statics;
677 /* Skip bitmaps that are pointer equal to node's bitmap
678 (no reason to spin within the cycle). */
679 else if (x_global->statics_written
680 != y_global->statics_written)
681 bitmap_ior_into (x_global->statics_written,
682 y_global->statics_written);
693 /* Look at all of the callees of X to see which ones represent inlined
694 calls. For each of these callees, merge their local info into
695 TARGET and check their children recursively.
697 This function goes away when Jan changes the inliner and IPA
698 analysis so that this is not run between the time when inlining
699 decisions are made and when the inlining actually occurs. */
702 merge_callee_local_info (struct cgraph_node *target,
703 struct cgraph_node *x)
705 struct cgraph_edge *e;
706 ipa_reference_local_vars_info_t x_l =
707 get_reference_vars_info_from_cgraph (target)->local;
709 /* Make the world safe for tail recursion. */
710 struct ipa_dfs_info *node_info = (struct ipa_dfs_info *) x->aux;
717 for (e = x->callees; e; e = e->next_callee)
719 struct cgraph_node *y = e->callee;
720 if (y->global.inlined_to)
722 ipa_reference_vars_info_t y_info;
723 ipa_reference_local_vars_info_t y_l;
724 struct cgraph_node* orig_y = y;
726 y = cgraph_master_clone (y);
729 y_info = get_reference_vars_info_from_cgraph (y);
733 bitmap_ior_into (x_l->statics_read,
735 bitmap_ior_into (x_l->statics_written,
736 y_l->statics_written);
738 x_l->calls_read_all |= y_l->calls_read_all;
739 x_l->calls_write_all |= y_l->calls_write_all;
740 merge_callee_local_info (target, y);
744 fprintf(stderr, "suspect inlining of ");
745 dump_cgraph_node (stderr, orig_y);
746 fprintf(stderr, "\ninto ");
747 dump_cgraph_node (stderr, target);
748 dump_cgraph (stderr);
754 node_info->aux = NULL;
757 /* The init routine for analyzing global static variable usage. See
758 comments at top for description. */
762 struct cgraph_node *node;
763 memory_identifier_string = build_string(7, "memory");
765 reference_vars_to_consider =
766 splay_tree_new_ggc (splay_tree_compare_ints);
768 bitmap_obstack_initialize (&ipa_obstack);
769 module_statics_escape = BITMAP_ALLOC (&ipa_obstack);
770 module_statics_written = BITMAP_ALLOC (&ipa_obstack);
771 all_module_statics = BITMAP_ALLOC (&ipa_obstack);
773 /* This will add NODE->DECL to the splay trees. */
774 for (node = cgraph_nodes; node; node = node->next)
775 has_proper_scope_for_analysis (node->decl);
777 /* There are some shared nodes, in particular the initializers on
778 static declarations. We do not need to scan them more than once
779 since all we would be interested in are the addressof
781 visited_nodes = pointer_set_create ();
784 /* Check out the rhs of a static or global initialization VNODE to see
785 if any of them contain addressof operations. Note that some of
786 these variables may not even be referenced in the code in this
787 compilation unit but their right hand sides may contain references
788 to variables defined within this unit. */
791 analyze_variable (struct varpool_node *vnode)
793 struct walk_stmt_info wi;
794 tree global = vnode->decl;
796 memset (&wi, 0, sizeof (wi));
797 wi.pset = visited_nodes;
798 walk_tree (&DECL_INITIAL (global), scan_op_for_static_refs,
802 /* Set up the persistent info for FN. */
804 static ipa_reference_local_vars_info_t
805 init_function_info (struct cgraph_node *fn)
807 ipa_reference_vars_info_t info
808 = XCNEW (struct ipa_reference_vars_info_d);
809 ipa_reference_local_vars_info_t l
810 = XCNEW (struct ipa_reference_local_vars_info_d);
811 tree decl = fn->decl;
813 /* Add the info to the tree's annotation. */
814 get_function_ann (decl)->reference_vars_info = info;
817 l->statics_read = BITMAP_ALLOC (&ipa_obstack);
818 l->statics_written = BITMAP_ALLOC (&ipa_obstack);
823 /* This is the main routine for finding the reference patterns for
824 global variables within a function FN. */
827 analyze_function (struct cgraph_node *fn)
829 ipa_reference_local_vars_info_t l = init_function_info (fn);
830 tree decl = fn->decl;
831 struct walk_stmt_info wi;
832 struct function *this_cfun = DECL_STRUCT_FUNCTION (decl);
833 basic_block this_block;
836 fprintf (dump_file, "\n local analysis of %s\n", cgraph_node_name (fn));
838 FOR_EACH_BB_FN (this_block, this_cfun)
840 gimple_stmt_iterator gsi;
846 /* Find the addresses taken in phi node arguments. */
847 for (gsi = gsi_start_phis (this_block);
851 phi = gsi_stmt (gsi);
852 FOR_EACH_PHI_ARG (use, phi, iter, SSA_OP_USE)
854 op = USE_FROM_PTR (use);
855 if (TREE_CODE (op) == ADDR_EXPR)
856 check_rhs_var (l, op);
860 memset (&wi, 0, sizeof (wi));
862 wi.pset = visited_nodes;
863 for (gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi))
864 walk_gimple_stmt (&gsi, scan_stmt_for_static_refs,
865 scan_op_for_static_refs, &wi);
868 /* There may be const decls with interesting right hand sides. */
869 if (DECL_STRUCT_FUNCTION (decl))
872 for (step = DECL_STRUCT_FUNCTION (decl)->local_decls;
874 step = TREE_CHAIN (step))
876 tree var = TREE_VALUE (step);
877 if (TREE_CODE (var) == VAR_DECL
878 && DECL_INITIAL (var)
879 && !TREE_STATIC (var))
881 memset (&wi, 0, sizeof (wi));
883 wi.pset = visited_nodes;
884 walk_tree (&DECL_INITIAL (var), scan_op_for_static_refs,
891 /* If FN is avail == AVAIL_OVERWRITABLE, replace the effects bit
892 vectors with worst case bit vectors. We had to analyze it above to
893 find out if it took the address of any statics. However, now that
894 we know that, we can get rid of all of the other side effects. */
897 clean_function (struct cgraph_node *fn)
899 ipa_reference_vars_info_t info = get_reference_vars_info_from_cgraph (fn);
900 ipa_reference_local_vars_info_t l = info->local;
901 ipa_reference_global_vars_info_t g = info->global;
906 && l->statics_read != all_module_statics)
907 BITMAP_FREE (l->statics_read);
908 if (l->statics_written
909 &&l->statics_written != all_module_statics)
910 BITMAP_FREE (l->statics_written);
917 && g->statics_read != all_module_statics)
918 BITMAP_FREE (g->statics_read);
920 if (g->statics_written
921 && g->statics_written != all_module_statics)
922 BITMAP_FREE (g->statics_written);
924 if (g->statics_not_read
925 && g->statics_not_read != all_module_statics)
926 BITMAP_FREE (g->statics_not_read);
928 if (g->statics_not_written
929 && g->statics_not_written != all_module_statics)
930 BITMAP_FREE (g->statics_not_written);
934 free (get_function_ann (fn->decl)->reference_vars_info);
935 get_function_ann (fn->decl)->reference_vars_info = NULL;
939 /* Analyze each function in the cgraph to see which global or statics
940 are read or written. */
943 generate_summary (void)
945 struct cgraph_node *node;
946 struct varpool_node *vnode;
949 bitmap module_statics_readonly;
953 module_statics_readonly = BITMAP_ALLOC (&ipa_obstack);
954 bm_temp = BITMAP_ALLOC (&ipa_obstack);
956 /* Process all of the variables first. */
957 FOR_EACH_STATIC_INITIALIZER (vnode)
958 analyze_variable (vnode);
960 /* Process all of the functions next.
962 We do not want to process any of the clones so we check that this
963 is a master clone. However, we do need to process any
964 AVAIL_OVERWRITABLE functions (these are never clones) because
965 they may cause a static variable to escape. The code that can
966 overwrite such a function cannot access the statics because it
967 would not be in the same compilation unit. When the analysis is
968 finished, the computed information of these AVAIL_OVERWRITABLE is
969 replaced with worst case info.
971 for (node = cgraph_nodes; node; node = node->next)
973 && (cgraph_is_master_clone (node)
974 || (cgraph_function_body_availability (node)
975 == AVAIL_OVERWRITABLE)))
976 analyze_function (node);
978 pointer_set_destroy (visited_nodes);
979 visited_nodes = NULL;
981 /* Prune out the variables that were found to behave badly
982 (i.e. have their address taken). */
983 EXECUTE_IF_SET_IN_BITMAP (module_statics_escape, 0, index, bi)
985 splay_tree_remove (reference_vars_to_consider, index);
988 bitmap_and_compl_into (all_module_statics,
989 module_statics_escape);
991 bitmap_and_compl (module_statics_readonly, all_module_statics,
992 module_statics_written);
994 /* If the address is not taken, we can unset the addressable bit
996 EXECUTE_IF_SET_IN_BITMAP (all_module_statics, 0, index, bi)
998 tree var = get_static_decl (index);
999 TREE_ADDRESSABLE (var) = 0;
1001 fprintf (dump_file, "Not TREE_ADDRESSABLE var %s\n",
1002 get_static_name (index));
1005 /* If the variable is never written, we can set the TREE_READONLY
1006 flag. Additionally if it has a DECL_INITIAL that is made up of
1007 constants we can treat the entire global as a constant. */
1009 bitmap_and_compl (module_statics_readonly, all_module_statics,
1010 module_statics_written);
1011 EXECUTE_IF_SET_IN_BITMAP (module_statics_readonly, 0, index, bi)
1013 tree var = get_static_decl (index);
1015 /* Readonly on a function decl is very different from the
1017 if (TREE_CODE (var) == FUNCTION_DECL)
1020 /* Ignore variables in named sections - changing TREE_READONLY
1021 changes the section flags, potentially causing conflicts with
1022 other variables in the same named section. */
1023 if (DECL_SECTION_NAME (var) == NULL_TREE)
1025 TREE_READONLY (var) = 1;
1027 fprintf (dump_file, "read-only var %s\n",
1028 get_static_name (index));
1032 BITMAP_FREE(module_statics_escape);
1033 BITMAP_FREE(module_statics_written);
1036 EXECUTE_IF_SET_IN_BITMAP (all_module_statics, 0, index, bi)
1038 fprintf (dump_file, "\nPromotable global:%s",
1039 get_static_name (index));
1042 for (node = cgraph_nodes; node; node = node->next)
1044 && (cgraph_is_master_clone (node)
1045 || (cgraph_function_body_availability (node)
1046 == AVAIL_OVERWRITABLE)))
1048 ipa_reference_local_vars_info_t l;
1049 l = get_reference_vars_info_from_cgraph (node)->local;
1051 /* Any variables that are not in all_module_statics are
1052 removed from the local maps. This will include all of the
1053 variables that were found to escape in the function
1055 bitmap_and_into (l->statics_read,
1056 all_module_statics);
1057 bitmap_and_into (l->statics_written,
1058 all_module_statics);
1061 BITMAP_FREE(module_statics_readonly);
1062 BITMAP_FREE(bm_temp);
1065 for (node = cgraph_nodes; node; node = node->next)
1067 && (cgraph_is_master_clone (node)
1068 || (cgraph_function_body_availability (node)
1069 == AVAIL_OVERWRITABLE)))
1071 ipa_reference_local_vars_info_t l;
1075 l = get_reference_vars_info_from_cgraph (node)->local;
1077 "\nFunction name:%s/%i:",
1078 cgraph_node_name (node), node->uid);
1079 fprintf (dump_file, "\n locals read: ");
1080 EXECUTE_IF_SET_IN_BITMAP (l->statics_read,
1083 fprintf (dump_file, "%s ",
1084 get_static_name (index));
1086 fprintf (dump_file, "\n locals written: ");
1087 EXECUTE_IF_SET_IN_BITMAP (l->statics_written,
1090 fprintf(dump_file, "%s ",
1091 get_static_name (index));
1096 /* Produce the global information by preforming a transitive closure
1097 on the local information that was produced by ipa_analyze_function
1098 and ipa_analyze_variable. */
1103 struct cgraph_node *node;
1104 struct cgraph_node *w;
1105 struct cgraph_node **order =
1106 XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
1107 int order_pos = ipa_utils_reduced_inorder (order, false, true);
1111 dump_cgraph (dump_file);
1113 /* Propagate the local information thru the call graph to produce
1114 the global information. All the nodes within a cycle will have
1115 the same info so we collapse cycles first. Then we can do the
1116 propagation in one pass from the leaves to the roots. */
1117 order_pos = ipa_utils_reduced_inorder (order, true, true);
1119 ipa_utils_print_order(dump_file, "reduced", order, order_pos);
1121 for (i = 0; i < order_pos; i++ )
1123 ipa_reference_vars_info_t node_info;
1124 ipa_reference_global_vars_info_t node_g =
1125 XCNEW (struct ipa_reference_global_vars_info_d);
1126 ipa_reference_local_vars_info_t node_l;
1130 struct ipa_dfs_info * w_info;
1133 node_info = get_reference_vars_info_from_cgraph (node);
1136 dump_cgraph_node (stderr, node);
1137 dump_cgraph (stderr);
1141 node_info->global = node_g;
1142 node_l = node_info->local;
1144 read_all = node_l->calls_read_all;
1145 write_all = node_l->calls_write_all;
1147 /* If any node in a cycle is calls_read_all or calls_write_all
1149 w_info = (struct ipa_dfs_info *) node->aux;
1150 w = w_info->next_cycle;
1153 ipa_reference_local_vars_info_t w_l =
1154 get_reference_vars_info_from_cgraph (w)->local;
1155 read_all |= w_l->calls_read_all;
1156 write_all |= w_l->calls_write_all;
1158 w_info = (struct ipa_dfs_info *) w->aux;
1159 w = w_info->next_cycle;
1162 /* Initialized the bitmaps for the reduced nodes */
1164 node_g->statics_read = all_module_statics;
1167 node_g->statics_read = BITMAP_ALLOC (&ipa_obstack);
1168 bitmap_copy (node_g->statics_read,
1169 node_l->statics_read);
1173 node_g->statics_written = all_module_statics;
1176 node_g->statics_written = BITMAP_ALLOC (&ipa_obstack);
1177 bitmap_copy (node_g->statics_written,
1178 node_l->statics_written);
1181 w_info = (struct ipa_dfs_info *) node->aux;
1182 w = w_info->next_cycle;
1185 ipa_reference_vars_info_t w_ri =
1186 get_reference_vars_info_from_cgraph (w);
1187 ipa_reference_local_vars_info_t w_l = w_ri->local;
1189 /* All nodes within a cycle share the same global info bitmaps. */
1190 w_ri->global = node_g;
1192 /* These global bitmaps are initialized from the local info
1193 of all of the nodes in the region. However there is no
1194 need to do any work if the bitmaps were set to
1195 all_module_statics. */
1197 bitmap_ior_into (node_g->statics_read,
1200 bitmap_ior_into (node_g->statics_written,
1201 w_l->statics_written);
1202 w_info = (struct ipa_dfs_info *) w->aux;
1203 w = w_info->next_cycle;
1210 w_info = (struct ipa_dfs_info *) w->aux;
1211 w = w_info->next_cycle;
1215 /* Need to fix up the local information sets. The information that
1216 has been gathered so far is preinlining. However, the
1217 compilation will progress post inlining so the local sets for the
1218 inlined calls need to be merged into the callers. Note that the
1219 local sets are not shared between all of the nodes in a cycle so
1220 those nodes in the cycle must be processed explicitly. */
1221 for (i = 0; i < order_pos; i++ )
1223 struct ipa_dfs_info * w_info;
1225 merge_callee_local_info (node, node);
1227 w_info = (struct ipa_dfs_info *) node->aux;
1228 w = w_info->next_cycle;
1231 merge_callee_local_info (w, w);
1232 w_info = (struct ipa_dfs_info *) w->aux;
1233 w = w_info->next_cycle;
1239 for (i = 0; i < order_pos; i++ )
1241 ipa_reference_vars_info_t node_info;
1242 ipa_reference_global_vars_info_t node_g;
1243 ipa_reference_local_vars_info_t node_l;
1246 struct ipa_dfs_info * w_info;
1249 node_info = get_reference_vars_info_from_cgraph (node);
1250 node_g = node_info->global;
1251 node_l = node_info->local;
1253 "\nFunction name:%s/%i:",
1254 cgraph_node_name (node), node->uid);
1255 fprintf (dump_file, "\n locals read: ");
1256 EXECUTE_IF_SET_IN_BITMAP (node_l->statics_read,
1259 fprintf (dump_file, "%s ",
1260 get_static_name (index));
1262 fprintf (dump_file, "\n locals written: ");
1263 EXECUTE_IF_SET_IN_BITMAP (node_l->statics_written,
1266 fprintf(dump_file, "%s ",
1267 get_static_name (index));
1270 w_info = (struct ipa_dfs_info *) node->aux;
1271 w = w_info->next_cycle;
1274 ipa_reference_vars_info_t w_ri =
1275 get_reference_vars_info_from_cgraph (w);
1276 ipa_reference_local_vars_info_t w_l = w_ri->local;
1277 fprintf (dump_file, "\n next cycle: %s/%i ",
1278 cgraph_node_name (w), w->uid);
1279 fprintf (dump_file, "\n locals read: ");
1280 EXECUTE_IF_SET_IN_BITMAP (w_l->statics_read,
1283 fprintf (dump_file, "%s ",
1284 get_static_name (index));
1287 fprintf (dump_file, "\n locals written: ");
1288 EXECUTE_IF_SET_IN_BITMAP (w_l->statics_written,
1291 fprintf(dump_file, "%s ",
1292 get_static_name (index));
1296 w_info = (struct ipa_dfs_info *) w->aux;
1297 w = w_info->next_cycle;
1299 fprintf (dump_file, "\n globals read: ");
1300 EXECUTE_IF_SET_IN_BITMAP (node_g->statics_read,
1303 fprintf (dump_file, "%s ",
1304 get_static_name (index));
1306 fprintf (dump_file, "\n globals written: ");
1307 EXECUTE_IF_SET_IN_BITMAP (node_g->statics_written,
1310 fprintf (dump_file, "%s ",
1311 get_static_name (index));
1317 for (i = 0; i < order_pos; i++ )
1319 ipa_reference_vars_info_t node_info;
1320 ipa_reference_global_vars_info_t node_g;
1322 node_info = get_reference_vars_info_from_cgraph (node);
1323 node_g = node_info->global;
1325 /* Create the complimentary sets. These are more useful for
1327 node_g->statics_not_read = BITMAP_ALLOC (&ipa_obstack);
1328 node_g->statics_not_written = BITMAP_ALLOC (&ipa_obstack);
1330 if (node_g->statics_read != all_module_statics)
1332 bitmap_and_compl (node_g->statics_not_read,
1334 node_g->statics_read);
1337 if (node_g->statics_written
1338 != all_module_statics)
1339 bitmap_and_compl (node_g->statics_not_written,
1341 node_g->statics_written);
1346 for (node = cgraph_nodes; node; node = node->next)
1348 /* Get rid of the aux information. */
1357 && (cgraph_function_body_availability (node) == AVAIL_OVERWRITABLE))
1358 clean_function (node);
1365 gate_reference (void)
1367 return (flag_ipa_reference
1368 /* Don't bother doing anything if the program has errors. */
1369 && !(errorcount || sorrycount));
1372 struct ipa_opt_pass pass_ipa_reference =
1376 "static-var", /* name */
1377 gate_reference, /* gate */
1378 propagate, /* execute */
1381 0, /* static_pass_number */
1382 TV_IPA_REFERENCE, /* tv_id */
1383 0, /* properties_required */
1384 0, /* properties_provided */
1385 0, /* properties_destroyed */
1386 0, /* todo_flags_start */
1387 0 /* todo_flags_finish */
1389 generate_summary, /* generate_summary */
1390 NULL, /* write_summary */
1391 NULL, /* read_summary */
1392 NULL, /* function_read_summary */
1394 NULL, /* function_transform */
1395 NULL /* variable_transform */
1398 #include "gt-ipa-reference.h"