* rw.po: Remove.
[official-gcc.git] / gcc / ipa-reference.c
blob6bf273185bd9351da43ed0ec56430fec6f96d71a
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
10 version.
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
15 for more details.
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
32 unit.
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
43 information.
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.
51 #include "config.h"
52 #include "system.h"
53 #include "coretypes.h"
54 #include "tm.h"
55 #include "tree.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"
61 #include "ggc.h"
62 #include "ipa-utils.h"
63 #include "ipa-reference.h"
64 #include "c-common.h"
65 #include "tree-gimple.h"
66 #include "cgraph.h"
67 #include "output.h"
68 #include "flags.h"
69 #include "timevar.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
78 from this list. */
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
87 are not readonly. */
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
92 memory. */
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
101 UNINITIALIZED,
102 RUNNING,
103 FINISHED
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;
122 if (info)
123 return info->local;
124 else
125 /* This phase was not run. */
126 return NULL;
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;
137 if (info)
138 return info->global;
139 else
140 /* This phase was not run. */
141 return NULL;
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. */
148 bitmap
149 ipa_reference_get_read_local (tree fn)
151 ipa_reference_local_vars_info_t l = get_local_reference_vars_info (fn);
152 if (l)
153 return l->statics_read;
154 else
155 return NULL;
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. */
162 bitmap
163 ipa_reference_get_written_local (tree fn)
165 ipa_reference_local_vars_info_t l = get_local_reference_vars_info (fn);
166 if (l)
167 return l->statics_written;
168 else
169 return NULL;
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. */
176 bitmap
177 ipa_reference_get_read_global (tree fn)
179 ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
180 if (g)
181 return g->statics_read;
182 else
183 return NULL;
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. */
191 bitmap
192 ipa_reference_get_written_global (tree fn)
194 ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
195 if (g)
196 return g->statics_written;
197 else
198 return NULL;
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. */
205 bitmap
206 ipa_reference_get_not_read_global (tree fn)
208 ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
209 if (g)
210 return g->statics_not_read;
211 else
212 return NULL;
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. */
220 bitmap
221 ipa_reference_get_not_written_global (tree fn)
223 ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
224 if (g)
225 return g->statics_not_written;
226 else
227 return NULL;
232 /* Add VAR to all_module_statics and the two
233 reference_vars_to_consider* sets. */
235 static inline void
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. */
250 static inline bool
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)))
256 return false;
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))
261 return false;
263 /* Do not care about a local automatic that is not static. */
264 if (!TREE_STATIC (t) && !DECL_EXTERNAL (t))
265 return false;
267 if (DECL_EXTERNAL (t) || TREE_PUBLIC (t))
268 return false;
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)))
273 add_static_var (t);
275 return true;
278 /* If T is a VAR_DECL for a static that we are interested in, add the
279 uid to the bitmap. */
281 static void
282 check_operand (ipa_reference_local_vars_info_t local,
283 tree t, bool checking_write)
285 if (!t) return;
287 if ((TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == FUNCTION_DECL)
288 && (has_proper_scope_for_analysis (t)))
290 if (checking_write)
292 if (local)
293 bitmap_set_bit (local->statics_written, DECL_UID (t));
294 /* Mark the write so we can tell which statics are
295 readonly. */
296 bitmap_set_bit (module_statics_written, DECL_UID (t));
298 else if (local)
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. */
308 static void
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))
312 return;
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
325 the read bitmaps. */
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);
332 if (SSA_VAR_P (t))
333 check_operand (local, t, checking_write);
336 /* Scan tree T to see if there are any addresses taken in within T. */
338 static void
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
353 initializer. */
355 static void
356 check_rhs_var (ipa_reference_local_vars_info_t local, tree t)
358 look_for_address_of (t);
360 if (local == NULL)
361 return;
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
368 vectors. */
370 static void
371 check_lhs_var (ipa_reference_local_vars_info_t local, tree t)
373 if (local == NULL)
374 return;
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. */
386 static void
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 *));
392 int i;
393 tree link;
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))
409 constraint
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. */
433 static void
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);
438 tree operand;
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);
450 if (callee_t)
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)
457 if (local)
459 if (flags & ECF_PURE)
460 local->calls_read_all = true;
461 else
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. */
476 static tree
477 scan_for_static_refs (tree *tp,
478 int *walk_subtrees,
479 void *data)
481 struct cgraph_node *fn = data;
482 tree t = *tp;
483 ipa_reference_local_vars_info_t local = NULL;
484 if (fn)
485 local = get_reference_vars_info_from_cgraph (fn)->local;
487 switch (TREE_CODE (t))
489 case VAR_DECL:
490 if (DECL_INITIAL (t))
491 walk_tree (&DECL_INITIAL (t), scan_for_static_refs, fn, visited_nodes);
492 *walk_subtrees = 0;
493 break;
495 case MODIFY_EXPR:
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)))
507 case tcc_binary:
508 case tcc_comparison:
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);
515 break;
516 case tcc_unary:
518 tree op0 = TREE_OPERAND (rhs, 0);
519 check_rhs_var (local, op0);
522 break;
523 case tcc_reference:
524 check_rhs_var (local, rhs);
525 break;
526 case tcc_declaration:
527 check_rhs_var (local, rhs);
528 break;
529 case tcc_expression:
530 switch (TREE_CODE (rhs))
532 case ADDR_EXPR:
533 check_rhs_var (local, rhs);
534 break;
535 case CALL_EXPR:
536 check_call (local, rhs);
537 break;
538 default:
539 break;
541 break;
542 default:
543 break;
545 *walk_subtrees = 0;
547 break;
549 case ADDR_EXPR:
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);
553 *walk_subtrees = 0;
554 break;
556 case LABEL_EXPR:
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;
563 break;
565 case CALL_EXPR:
566 check_call (local, t);
567 *walk_subtrees = 0;
568 break;
570 case ASM_EXPR:
571 get_asm_expr_operands (local, t);
572 *walk_subtrees = 0;
573 break;
575 default:
576 break;
578 return NULL;
582 /* Lookup the tree node for the static variable that has UID. */
583 static tree
584 get_static_decl (int index)
586 splay_tree_node stn =
587 splay_tree_lookup (reference_vars_to_consider, index);
588 if (stn)
589 return (tree)stn->value;
590 return NULL;
593 /* Lookup the tree node for the static variable that has UID and
594 convert the name to a string for debugging. */
596 static const char *
597 get_static_name (int index)
599 splay_tree_node stn =
600 splay_tree_lookup (reference_vars_to_consider, index);
601 if (stn)
602 return lang_hooks.decl_printable_name ((tree)(stn->value), 2);
603 return NULL;
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
608 bitmap oring. */
610 static void
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);
623 if (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);
666 else
668 gcc_unreachable ();
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. */
682 static void
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;
693 if (node_info->aux)
694 return;
696 node_info->aux = x;
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);
708 if (y)
710 y_info = get_reference_vars_info_from_cgraph (y);
711 y_l = y_info->local;
712 if (x_l != y_l)
714 bitmap_ior_into (x_l->statics_read,
715 y_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);
723 else
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);
730 gcc_assert(false);
735 node_info->aux = NULL;
738 /* The init routine for analyzing global static variable usage. See
739 comments at top for description. */
740 static void
741 ipa_init (void)
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
761 operations. */
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. */
771 static void
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. */
787 static void
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;
799 info->local = l;
800 l->statics_read = BITMAP_ALLOC (&ipa_obstack);
801 l->statics_written = BITMAP_ALLOC (&ipa_obstack);
803 if (dump_file)
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,
815 fn, visited_nodes);
819 /* There may be const decls with interesting right hand sides. */
820 if (DECL_STRUCT_FUNCTION (decl))
822 tree step;
823 for (step = DECL_STRUCT_FUNCTION (decl)->unexpanded_var_list;
824 step;
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,
832 fn, visited_nodes);
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. */
842 static void
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;
849 if (l)
851 if (l->statics_read
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);
857 free (l);
860 if (g)
862 if (g->statics_read
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);
877 free (g);
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. */
890 static unsigned int
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);
899 int i;
901 ipa_init ();
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)
919 if (node->analyzed
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;
927 if (dump_file)
928 dump_cgraph (dump_file);
930 /* Prune out the variables that were found to behave badly
931 (i.e. have their address taken). */
933 unsigned int index;
934 bitmap_iterator bi;
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
951 on this variable. */
952 EXECUTE_IF_SET_IN_BITMAP (all_module_statics, 0, index, bi)
954 tree var = get_static_decl (index);
955 TREE_ADDRESSABLE (var) = 0;
956 if (dump_file)
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
972 variable. */
973 if (TREE_CODE (var) == FUNCTION_DECL)
974 continue;
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;
982 if (dump_file)
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);
990 if (dump_file)
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);
999 if (dump_file)
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;
1009 node = order[i];
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
1015 scanning. */
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);
1027 if (dump_file)
1029 for (i = 0; i < order_pos; i++ )
1031 unsigned int index;
1032 ipa_reference_local_vars_info_t l;
1033 bitmap_iterator bi;
1035 node = order[i];
1036 l = get_reference_vars_info_from_cgraph (node)->local;
1037 fprintf (dump_file,
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,
1042 0, index, bi)
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,
1049 0, index, bi)
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);
1062 if (dump_file)
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;
1072 bool read_all;
1073 bool write_all;
1074 struct ipa_dfs_info * w_info;
1076 node = order[i];
1077 node_info = get_reference_vars_info_from_cgraph (node);
1078 if (!node_info)
1080 dump_cgraph_node (stderr, node);
1081 dump_cgraph (stderr);
1082 gcc_unreachable ();
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
1092 they all are. */
1093 w_info = node->aux;
1094 w = w_info->next_cycle;
1095 while (w)
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;
1102 w_info = w->aux;
1103 w = w_info->next_cycle;
1106 /* Initialized the bitmaps for the reduced nodes */
1107 if (read_all)
1108 node_g->statics_read = all_module_statics;
1109 else
1111 node_g->statics_read = BITMAP_ALLOC (&ipa_obstack);
1112 bitmap_copy (node_g->statics_read,
1113 node_l->statics_read);
1116 if (write_all)
1117 node_g->statics_written = all_module_statics;
1118 else
1120 node_g->statics_written = BITMAP_ALLOC (&ipa_obstack);
1121 bitmap_copy (node_g->statics_written,
1122 node_l->statics_written);
1125 w_info = node->aux;
1126 w = w_info->next_cycle;
1127 while (w)
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. */
1140 if (!read_all)
1141 bitmap_ior_into (node_g->statics_read,
1142 w_l->statics_read);
1143 if (!write_all)
1144 bitmap_ior_into (node_g->statics_written,
1145 w_l->statics_written);
1146 w_info = w->aux;
1147 w = w_info->next_cycle;
1150 w = node;
1151 while (w)
1153 propagate_bits (w);
1154 w_info = w->aux;
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;
1168 node = order[i];
1169 merge_callee_local_info (node, node);
1171 w_info = node->aux;
1172 w = w_info->next_cycle;
1173 while (w)
1175 merge_callee_local_info (w, w);
1176 w_info = w->aux;
1177 w = w_info->next_cycle;
1181 if (dump_file)
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;
1188 unsigned int index;
1189 bitmap_iterator bi;
1190 struct ipa_dfs_info * w_info;
1192 node = order[i];
1193 node_info = get_reference_vars_info_from_cgraph (node);
1194 node_g = node_info->global;
1195 node_l = node_info->local;
1196 fprintf (dump_file,
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,
1201 0, index, bi)
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,
1208 0, index, bi)
1210 fprintf(dump_file, "%s ",
1211 get_static_name (index));
1214 w_info = node->aux;
1215 w = w_info->next_cycle;
1216 while (w)
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,
1225 0, index, bi)
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,
1233 0, index, bi)
1235 fprintf(dump_file, "%s ",
1236 get_static_name (index));
1240 w_info = w->aux;
1241 w = w_info->next_cycle;
1243 fprintf (dump_file, "\n globals read: ");
1244 EXECUTE_IF_SET_IN_BITMAP (node_g->statics_read,
1245 0, index, bi)
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,
1252 0, index, bi)
1254 fprintf (dump_file, "%s ",
1255 get_static_name (index));
1260 /* Cleanup. */
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;
1265 node = order[i];
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
1270 certain apis. */
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,
1277 all_module_statics,
1278 node_g->statics_read);
1281 if (node_g->statics_written
1282 != all_module_statics)
1283 bitmap_and_compl (node_g->statics_not_written,
1284 all_module_statics,
1285 node_g->statics_written);
1288 free (order);
1290 for (node = cgraph_nodes; node; node = node->next)
1292 /* Get rid of the aux information. */
1294 if (node->aux)
1296 free (node->aux);
1297 node->aux = NULL;
1300 if (node->analyzed
1301 && (cgraph_function_body_availability (node) == AVAIL_OVERWRITABLE))
1302 clean_function (node);
1304 return 0;
1308 static bool
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 */
1321 NULL, /* sub */
1322 NULL, /* next */
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 */
1330 0 /* letter */
1333 #include "gt-ipa-reference.h"