re PR libfortran/41683 (F2003 Repeat specification after P descriptor rejected)
[official-gcc.git] / gcc / ipa-reference.c
blob795684692bf419a88979ca65893c00833d9ffc4b
1 /* Callgraph based analysis of static variables.
2 Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
3 Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
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. */
50 #include "config.h"
51 #include "system.h"
52 #include "coretypes.h"
53 #include "tm.h"
54 #include "tree.h"
55 #include "tree-flow.h"
56 #include "tree-inline.h"
57 #include "tree-pass.h"
58 #include "langhooks.h"
59 #include "pointer-set.h"
60 #include "splay-tree.h"
61 #include "ggc.h"
62 #include "ipa-utils.h"
63 #include "ipa-reference.h"
64 #include "gimple.h"
65 #include "cgraph.h"
66 #include "output.h"
67 #include "flags.h"
68 #include "timevar.h"
69 #include "diagnostic.h"
70 #include "langhooks.h"
71 #include "lto-streamer.h"
73 static void add_new_function (struct cgraph_node *node,
74 void *data ATTRIBUTE_UNUSED);
75 static void remove_node_data (struct cgraph_node *node,
76 void *data ATTRIBUTE_UNUSED);
77 static void duplicate_node_data (struct cgraph_node *src,
78 struct cgraph_node *dst,
79 void *data ATTRIBUTE_UNUSED);
81 /* The static variables defined within the compilation unit that are
82 loaded or stored directly by function that owns this structure. */
84 struct ipa_reference_local_vars_info_d
86 bitmap statics_read;
87 bitmap statics_written;
89 /* Set when this function calls another function external to the
90 compilation unit or if the function has a asm clobber of memory.
91 In general, such calls are modeled as reading and writing all
92 variables (both bits on) but sometime there are attributes on the
93 called function so we can do better. */
94 bool calls_read_all;
95 bool calls_write_all;
98 /* Statics that are read and written by some set of functions. The
99 local ones are based on the loads and stores local to the function.
100 The global ones are based on the local info as well as the
101 transitive closure of the functions that are called. The
102 structures are separated to allow the global structures to be
103 shared between several functions since every function within a
104 strongly connected component will have the same information. This
105 sharing saves both time and space in the computation of the vectors
106 as well as their translation from decl_uid form to ann_uid
107 form. */
109 struct ipa_reference_global_vars_info_d
111 bitmap statics_read;
112 bitmap statics_written;
113 bitmap statics_not_read;
114 bitmap statics_not_written;
117 typedef struct ipa_reference_local_vars_info_d *ipa_reference_local_vars_info_t;
118 typedef struct ipa_reference_global_vars_info_d *ipa_reference_global_vars_info_t;
119 struct ipa_reference_vars_info_d
121 ipa_reference_local_vars_info_t local;
122 ipa_reference_global_vars_info_t global;
125 typedef struct ipa_reference_vars_info_d *ipa_reference_vars_info_t;
127 /* This splay tree contains all of the static variables that are
128 being considered by the compilation level alias analysis. For
129 module_at_a_time compilation, this is the set of static but not
130 public variables. Any variables that either have their address
131 taken or participate in otherwise unsavory operations are deleted
132 from this list. */
133 static GTY((param1_is(int), param2_is(tree)))
134 splay_tree reference_vars_to_consider;
136 /* This bitmap is used to knock out the module static variables whose
137 addresses have been taken and passed around. */
138 static bitmap module_statics_escape;
140 /* This bitmap is used to knock out the module static variables that
141 are not readonly. */
142 static bitmap module_statics_written;
144 /* A bit is set for every module static we are considering. This is
145 ored into the local info when asm code is found that clobbers all
146 memory. */
147 static bitmap all_module_statics;
149 static struct pointer_set_t *visited_nodes;
151 /* Obstack holding bitmaps of local analysis (live from analysis to
152 propagation) */
153 static bitmap_obstack local_info_obstack;
154 /* Obstack holding global analysis live forever. */
155 static bitmap_obstack global_info_obstack;
157 /* Holders of ipa cgraph hooks: */
158 static struct cgraph_node_hook_list *function_insertion_hook_holder;
159 static struct cgraph_2node_hook_list *node_duplication_hook_holder;
160 static struct cgraph_node_hook_list *node_removal_hook_holder;
162 enum initialization_status_t
164 UNINITIALIZED,
165 RUNNING,
166 FINISHED
169 tree memory_identifier_string;
171 /* Vector where the reference var infos are actually stored. */
172 DEF_VEC_P (ipa_reference_vars_info_t);
173 DEF_VEC_ALLOC_P (ipa_reference_vars_info_t, heap);
174 static VEC (ipa_reference_vars_info_t, heap) *ipa_reference_vars_vector;
176 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
177 static inline ipa_reference_vars_info_t
178 get_reference_vars_info (struct cgraph_node *node)
180 if (!ipa_reference_vars_vector
181 || VEC_length (ipa_reference_vars_info_t, ipa_reference_vars_vector) <= (unsigned int)node->uid)
182 return NULL;
183 return VEC_index (ipa_reference_vars_info_t, ipa_reference_vars_vector, node->uid);
186 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
187 static inline void
188 set_reference_vars_info (struct cgraph_node *node, ipa_reference_vars_info_t info)
190 if (!ipa_reference_vars_vector
191 || VEC_length (ipa_reference_vars_info_t, ipa_reference_vars_vector) <= (unsigned int)node->uid)
192 VEC_safe_grow_cleared (ipa_reference_vars_info_t, heap, ipa_reference_vars_vector, node->uid + 1);
193 VEC_replace (ipa_reference_vars_info_t, ipa_reference_vars_vector, node->uid, info);
196 /* Get a bitmap that contains all of the locally referenced static
197 variables for function FN. */
198 static ipa_reference_local_vars_info_t
199 get_local_reference_vars_info (struct cgraph_node *fn)
201 ipa_reference_vars_info_t info = get_reference_vars_info (fn);
203 if (info)
204 return info->local;
205 else
206 /* This phase was not run. */
207 return NULL;
210 /* Get a bitmap that contains all of the globally referenced static
211 variables for function FN. */
213 static ipa_reference_global_vars_info_t
214 get_global_reference_vars_info (struct cgraph_node *fn)
216 ipa_reference_vars_info_t info = get_reference_vars_info (fn);
218 if (info)
219 return info->global;
220 else
221 /* This phase was not run. */
222 return NULL;
225 /* Return a bitmap indexed by VAR_DECL uid for the static variables
226 that are read during the execution of the function FN. Returns
227 NULL if no data is available. */
229 bitmap
230 ipa_reference_get_read_global (struct cgraph_node *fn)
232 ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
233 if (g)
234 return g->statics_read;
235 else
236 return NULL;
239 /* Return a bitmap indexed by VAR_DECL uid for the static variables
240 that are written during the execution of the function FN. Note
241 that variables written may or may not be read during the function
242 call. Returns NULL if no data is available. */
244 bitmap
245 ipa_reference_get_written_global (struct cgraph_node *fn)
247 ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
248 if (g)
249 return g->statics_written;
250 else
251 return NULL;
254 /* Return a bitmap indexed by_DECL_UID uid for the static variables
255 that are not read during the execution of the function FN. Returns
256 NULL if no data is available. */
258 bitmap
259 ipa_reference_get_not_read_global (struct cgraph_node *fn)
261 ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
262 if (g)
263 return g->statics_not_read;
264 else
265 return NULL;
268 /* Return a bitmap indexed by DECL_UID uid for the static variables
269 that are not written during the execution of the function FN. Note
270 that variables written may or may not be read during the function
271 call. Returns NULL if no data is available. */
273 bitmap
274 ipa_reference_get_not_written_global (struct cgraph_node *fn)
276 ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
277 if (g)
278 return g->statics_not_written;
279 else
280 return NULL;
285 /* Add VAR to all_module_statics and the two
286 reference_vars_to_consider* sets. */
288 static inline void
289 add_static_var (tree var)
291 int uid = DECL_UID (var);
292 gcc_assert (TREE_CODE (var) == VAR_DECL);
293 if (!bitmap_bit_p (all_module_statics, uid))
295 splay_tree_insert (reference_vars_to_consider,
296 uid, (splay_tree_value)var);
297 bitmap_set_bit (all_module_statics, uid);
301 /* Return true if the variable T is the right kind of static variable to
302 perform compilation unit scope escape analysis. */
304 static inline bool
305 has_proper_scope_for_analysis (tree t)
307 /* If the variable has the "used" attribute, treat it as if it had a
308 been touched by the devil. */
309 if (lookup_attribute ("used", DECL_ATTRIBUTES (t)))
310 return false;
312 /* Do not want to do anything with volatile except mark any
313 function that uses one to be not const or pure. */
314 if (TREE_THIS_VOLATILE (t))
315 return false;
317 /* Do not care about a local automatic that is not static. */
318 if (!TREE_STATIC (t) && !DECL_EXTERNAL (t))
319 return false;
321 if (DECL_EXTERNAL (t) || TREE_PUBLIC (t))
322 return false;
324 /* We cannot touch decls where the type needs constructing. */
325 if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (t)))
326 return false;
328 /* This is a variable we care about. Check if we have seen it
329 before, and if not add it the set of variables we care about. */
330 if (!bitmap_bit_p (all_module_statics, DECL_UID (t)))
331 add_static_var (t);
333 return true;
336 /* Mark tree T as having address taken. */
338 static void
339 mark_address_taken (tree x)
341 if (TREE_CODE (x) == VAR_DECL
342 && module_statics_escape && has_proper_scope_for_analysis (x))
343 bitmap_set_bit (module_statics_escape, DECL_UID (x));
346 /* Wrapper around mark_address_taken for the stmt walker. */
348 static bool
349 mark_address (gimple stmt ATTRIBUTE_UNUSED, tree addr,
350 void *data ATTRIBUTE_UNUSED)
352 while (handled_component_p (addr))
353 addr = TREE_OPERAND (addr, 0);
354 mark_address_taken (addr);
355 return false;
358 /* Mark load of T. */
360 static bool
361 mark_load (gimple stmt ATTRIBUTE_UNUSED, tree t, void *data)
363 ipa_reference_local_vars_info_t local = (ipa_reference_local_vars_info_t)data;
364 if (TREE_CODE (t) == VAR_DECL
365 && has_proper_scope_for_analysis (t))
366 bitmap_set_bit (local->statics_read, DECL_UID (t));
367 return false;
370 /* Mark store of T. */
372 static bool
373 mark_store (gimple stmt ATTRIBUTE_UNUSED, tree t, void *data)
375 ipa_reference_local_vars_info_t local = (ipa_reference_local_vars_info_t)data;
376 if (TREE_CODE (t) == VAR_DECL
377 && has_proper_scope_for_analysis (t))
379 if (local)
380 bitmap_set_bit (local->statics_written, DECL_UID (t));
381 /* Mark the write so we can tell which statics are
382 readonly. */
383 if (module_statics_written)
384 bitmap_set_bit (module_statics_written, DECL_UID (t));
386 return false;
389 /* Look for memory clobber and set read_all/write_all if present. */
391 static void
392 check_asm_memory_clobber (ipa_reference_local_vars_info_t local, gimple stmt)
394 size_t i;
395 tree op;
397 for (i = 0; i < gimple_asm_nclobbers (stmt); i++)
399 op = gimple_asm_clobber_op (stmt, i);
400 if (simple_cst_equal(TREE_VALUE (op), memory_identifier_string) == 1)
402 /* Abandon all hope, ye who enter here. */
403 local->calls_read_all = true;
404 local->calls_write_all = true;
409 /* Look for external calls and set read_all/write_all correspondingly. */
411 static void
412 check_call (ipa_reference_local_vars_info_t local, gimple stmt)
414 int flags = gimple_call_flags (stmt);
415 tree callee_t = gimple_call_fndecl (stmt);
416 enum availability avail = AVAIL_NOT_AVAILABLE;
418 if (callee_t)
420 struct cgraph_node* callee = cgraph_node(callee_t);
421 avail = cgraph_function_body_availability (callee);
424 if (avail <= AVAIL_OVERWRITABLE)
425 if (local)
427 if (flags & ECF_CONST)
429 else if (flags & ECF_PURE)
430 local->calls_read_all = true;
431 else
433 local->calls_read_all = true;
434 local->calls_write_all = true;
437 /* TODO: To be able to produce sane results, we should also handle
438 common builtins, in particular throw.
439 Indirect calls hsould be only counted and as inliner is replacing them
440 by direct calls, we can conclude if any indirect calls are left in body */
443 /* TP is the part of the tree currently under the microscope.
444 WALK_SUBTREES is part of the walk_tree api but is unused here.
445 DATA is cgraph_node of the function being walked. */
447 static tree
448 scan_stmt_for_static_refs (gimple_stmt_iterator *gsip,
449 struct cgraph_node *fn)
451 gimple stmt = gsi_stmt (*gsip);
452 ipa_reference_local_vars_info_t local = NULL;
454 if (is_gimple_debug (stmt))
455 return NULL;
457 if (fn)
458 local = get_reference_vars_info (fn)->local;
460 /* Look for direct loads and stores. */
461 walk_stmt_load_store_addr_ops (stmt, local, mark_load, mark_store,
462 mark_address);
464 if (is_gimple_call (stmt))
465 check_call (local, stmt);
466 else if (gimple_code (stmt) == GIMPLE_ASM)
467 check_asm_memory_clobber (local, stmt);
469 return NULL;
472 /* Call-back to scan variable initializers for static references.
473 Called using walk_tree. */
475 static tree
476 scan_initializer_for_static_refs (tree *tp, int *walk_subtrees,
477 void *data ATTRIBUTE_UNUSED)
479 tree t = *tp;
481 if (TREE_CODE (t) == ADDR_EXPR)
483 mark_address_taken (get_base_var (t));
484 *walk_subtrees = 0;
486 /* Save some cycles by not walking types and declaration as we
487 won't find anything useful there anyway. */
488 else if (IS_TYPE_OR_DECL_P (*tp))
489 *walk_subtrees = 0;
491 return NULL;
494 /* Lookup the tree node for the static variable that has UID. */
495 static tree
496 get_static_decl (int index)
498 splay_tree_node stn =
499 splay_tree_lookup (reference_vars_to_consider, index);
500 if (stn)
501 return (tree)stn->value;
502 return NULL;
505 /* Lookup the tree node for the static variable that has UID and
506 convert the name to a string for debugging. */
508 static const char *
509 get_static_name (int index)
511 splay_tree_node stn =
512 splay_tree_lookup (reference_vars_to_consider, index);
513 if (stn)
514 return lang_hooks.decl_printable_name ((tree)(stn->value), 2);
515 return NULL;
518 /* Or in all of the bits from every callee of X into X_GLOBAL, the caller's cycle,
519 bit vector. There are several cases to check to avoid the sparse
520 bitmap oring. */
522 static void
523 propagate_bits (ipa_reference_global_vars_info_t x_global, struct cgraph_node *x)
525 struct cgraph_edge *e;
526 for (e = x->callees; e; e = e->next_callee)
528 struct cgraph_node *y = e->callee;
530 /* Only look at the master nodes and skip external nodes. */
531 if (cgraph_function_body_availability (e->callee) > AVAIL_OVERWRITABLE)
533 if (get_reference_vars_info (y))
535 ipa_reference_vars_info_t y_info
536 = get_reference_vars_info (y);
537 ipa_reference_global_vars_info_t y_global = y_info->global;
539 /* Calls in current cycle do not have global computed yet. */
540 if (!y_info->global)
541 continue;
543 if (x_global->statics_read
544 != all_module_statics)
546 if (y_global->statics_read
547 == all_module_statics)
549 BITMAP_FREE (x_global->statics_read);
550 x_global->statics_read
551 = all_module_statics;
553 /* Skip bitmaps that are pointer equal to node's bitmap
554 (no reason to spin within the cycle). */
555 else if (x_global->statics_read
556 != y_global->statics_read)
557 bitmap_ior_into (x_global->statics_read,
558 y_global->statics_read);
561 if (x_global->statics_written
562 != all_module_statics)
564 if (y_global->statics_written
565 == all_module_statics)
567 BITMAP_FREE (x_global->statics_written);
568 x_global->statics_written
569 = all_module_statics;
571 /* Skip bitmaps that are pointer equal to node's bitmap
572 (no reason to spin within the cycle). */
573 else if (x_global->statics_written
574 != y_global->statics_written)
575 bitmap_ior_into (x_global->statics_written,
576 y_global->statics_written);
579 else
580 gcc_unreachable ();
585 /* The init routine for analyzing global static variable usage. See
586 comments at top for description. */
587 static void
588 ipa_init (void)
590 static bool init_p = false;
592 if (init_p)
593 return;
595 init_p = true;
597 memory_identifier_string = build_string(7, "memory");
599 reference_vars_to_consider =
600 splay_tree_new_ggc (splay_tree_compare_ints);
602 bitmap_obstack_initialize (&local_info_obstack);
603 bitmap_obstack_initialize (&global_info_obstack);
604 module_statics_escape = BITMAP_ALLOC (&local_info_obstack);
605 module_statics_written = BITMAP_ALLOC (&local_info_obstack);
606 all_module_statics = BITMAP_ALLOC (&global_info_obstack);
608 /* There are some shared nodes, in particular the initializers on
609 static declarations. We do not need to scan them more than once
610 since all we would be interested in are the addressof
611 operations. */
612 visited_nodes = pointer_set_create ();
614 function_insertion_hook_holder =
615 cgraph_add_function_insertion_hook (&add_new_function, NULL);
616 node_removal_hook_holder =
617 cgraph_add_node_removal_hook (&remove_node_data, NULL);
618 node_duplication_hook_holder =
619 cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
622 /* Check out the rhs of a static or global initialization VNODE to see
623 if any of them contain addressof operations. Note that some of
624 these variables may not even be referenced in the code in this
625 compilation unit but their right hand sides may contain references
626 to variables defined within this unit. */
628 static void
629 analyze_variable (struct varpool_node *vnode)
631 struct walk_stmt_info wi;
632 tree global = vnode->decl;
634 memset (&wi, 0, sizeof (wi));
635 wi.pset = visited_nodes;
636 walk_tree (&DECL_INITIAL (global), scan_initializer_for_static_refs,
637 &wi, wi.pset);
641 /* Set up the persistent info for FN. */
643 static ipa_reference_local_vars_info_t
644 init_function_info (struct cgraph_node *fn)
646 ipa_reference_vars_info_t info
647 = XCNEW (struct ipa_reference_vars_info_d);
648 ipa_reference_local_vars_info_t l
649 = XCNEW (struct ipa_reference_local_vars_info_d);
651 /* Add the info to the tree's annotation. */
652 set_reference_vars_info (fn, info);
654 info->local = l;
655 l->statics_read = BITMAP_ALLOC (&local_info_obstack);
656 l->statics_written = BITMAP_ALLOC (&local_info_obstack);
658 return l;
662 /* This is the main routine for finding the reference patterns for
663 global variables within a function FN. */
665 static void
666 analyze_function (struct cgraph_node *fn)
668 tree decl = fn->decl;
669 struct function *this_cfun = DECL_STRUCT_FUNCTION (decl);
670 basic_block this_block;
671 #ifdef ENABLE_CHECKING
672 tree step;
673 #endif
675 if (dump_file)
676 fprintf (dump_file, "\n local analysis of %s\n", cgraph_node_name (fn));
678 push_cfun (DECL_STRUCT_FUNCTION (decl));
679 current_function_decl = decl;
681 init_function_info (fn);
682 FOR_EACH_BB_FN (this_block, this_cfun)
684 gimple_stmt_iterator gsi;
685 gimple phi;
686 tree op;
687 use_operand_p use;
688 ssa_op_iter iter;
690 /* Find the addresses taken in phi node arguments. */
691 for (gsi = gsi_start_phis (this_block);
692 !gsi_end_p (gsi);
693 gsi_next (&gsi))
695 phi = gsi_stmt (gsi);
696 FOR_EACH_PHI_ARG (use, phi, iter, SSA_OP_USE)
698 op = USE_FROM_PTR (use);
699 if (TREE_CODE (op) == ADDR_EXPR)
700 mark_address_taken (get_base_var (op));
704 for (gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi))
705 scan_stmt_for_static_refs (&gsi, fn);
708 #ifdef ENABLE_CHECKING
709 /* Verify that all local initializers was expanded by gimplifier. */
710 for (step = DECL_STRUCT_FUNCTION (decl)->local_decls;
711 step;
712 step = TREE_CHAIN (step))
714 tree var = TREE_VALUE (step);
715 if (TREE_CODE (var) == VAR_DECL
716 && DECL_INITIAL (var)
717 && !TREE_STATIC (var))
718 gcc_unreachable ();
720 #endif
721 pop_cfun ();
722 current_function_decl = NULL;
725 /* Remove local data associated with function FN. */
726 static void
727 clean_function_local_data (struct cgraph_node *fn)
729 ipa_reference_vars_info_t info = get_reference_vars_info (fn);
730 ipa_reference_local_vars_info_t l = info->local;
731 if (l)
733 if (l->statics_read
734 && l->statics_read != all_module_statics)
735 BITMAP_FREE (l->statics_read);
736 if (l->statics_written
737 &&l->statics_written != all_module_statics)
738 BITMAP_FREE (l->statics_written);
739 free (l);
740 info->local = NULL;
744 /* Remove all data associated with function FN. */
746 static void
747 clean_function (struct cgraph_node *fn)
749 ipa_reference_vars_info_t info = get_reference_vars_info (fn);
750 ipa_reference_global_vars_info_t g = info->global;
752 clean_function_local_data (fn);
753 if (g)
755 if (g->statics_read
756 && g->statics_read != all_module_statics)
757 BITMAP_FREE (g->statics_read);
759 if (g->statics_written
760 && g->statics_written != all_module_statics)
761 BITMAP_FREE (g->statics_written);
763 if (g->statics_not_read
764 && g->statics_not_read != all_module_statics)
765 BITMAP_FREE (g->statics_not_read);
767 if (g->statics_not_written
768 && g->statics_not_written != all_module_statics)
769 BITMAP_FREE (g->statics_not_written);
770 free (g);
771 info->global = NULL;
774 free (get_reference_vars_info (fn));
775 set_reference_vars_info (fn, NULL);
778 /* Called when new function is inserted to callgraph late. */
779 static void
780 add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
782 /* There are some shared nodes, in particular the initializers on
783 static declarations. We do not need to scan them more than once
784 since all we would be interested in are the addressof
785 operations. */
786 analyze_function (node);
787 visited_nodes = NULL;
790 static bitmap
791 copy_local_bitmap (bitmap src)
793 bitmap dst;
794 if (!src)
795 return NULL;
796 if (src == all_module_statics)
797 return all_module_statics;
798 dst = BITMAP_ALLOC (&local_info_obstack);
799 bitmap_copy (dst, src);
800 return dst;
803 static bitmap
804 copy_global_bitmap (bitmap src)
806 bitmap dst;
807 if (!src)
808 return NULL;
809 if (src == all_module_statics)
810 return all_module_statics;
811 dst = BITMAP_ALLOC (&global_info_obstack);
812 bitmap_copy (dst, src);
813 return dst;
816 /* Called when new clone is inserted to callgraph late. */
818 static void
819 duplicate_node_data (struct cgraph_node *src, struct cgraph_node *dst,
820 void *data ATTRIBUTE_UNUSED)
822 ipa_reference_global_vars_info_t ginfo;
823 ipa_reference_local_vars_info_t linfo;
824 ipa_reference_global_vars_info_t dst_ginfo;
825 ipa_reference_local_vars_info_t dst_linfo;
827 ginfo = get_global_reference_vars_info (src);
828 linfo = get_local_reference_vars_info (src);
829 if (!linfo && !ginfo)
830 return;
831 init_function_info (dst);
832 if (linfo)
834 dst_linfo = get_local_reference_vars_info (dst);
835 dst_linfo->statics_read = copy_local_bitmap (linfo->statics_read);
836 dst_linfo->statics_written = copy_local_bitmap (linfo->statics_written);
837 dst_linfo->calls_read_all = linfo->calls_read_all;
838 dst_linfo->calls_write_all = linfo->calls_write_all;
840 if (ginfo)
842 get_reference_vars_info (dst)->global = XCNEW (struct ipa_reference_global_vars_info_d);
843 dst_ginfo = get_global_reference_vars_info (dst);
844 dst_ginfo->statics_read = copy_global_bitmap (ginfo->statics_read);
845 dst_ginfo->statics_written = copy_global_bitmap (ginfo->statics_written);
846 dst_ginfo->statics_not_read = copy_global_bitmap (ginfo->statics_not_read);
847 dst_ginfo->statics_not_written = copy_global_bitmap (ginfo->statics_not_written);
851 /* Called when node is removed. */
853 static void
854 remove_node_data (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
856 if (get_reference_vars_info (node))
857 clean_function (node);
860 /* Analyze each function in the cgraph to see which global or statics
861 are read or written. */
863 static void
864 generate_summary (void)
866 struct cgraph_node *node;
867 struct varpool_node *vnode;
868 unsigned int index;
869 bitmap_iterator bi;
870 bitmap module_statics_readonly;
871 bitmap bm_temp;
873 ipa_init ();
874 module_statics_readonly = BITMAP_ALLOC (&local_info_obstack);
875 bm_temp = BITMAP_ALLOC (&local_info_obstack);
877 /* Process all of the variables first. */
878 FOR_EACH_STATIC_INITIALIZER (vnode)
879 analyze_variable (vnode);
881 /* Process all of the functions next.
883 We do not want to process any of the clones so we check that this
884 is a master clone. However, we do need to process any
885 AVAIL_OVERWRITABLE functions (these are never clones) because
886 they may cause a static variable to escape. The code that can
887 overwrite such a function cannot access the statics because it
888 would not be in the same compilation unit. When the analysis is
889 finished, the computed information of these AVAIL_OVERWRITABLE is
890 replaced with worst case info.
892 for (node = cgraph_nodes; node; node = node->next)
893 if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
894 analyze_function (node);
896 pointer_set_destroy (visited_nodes);
897 visited_nodes = NULL;
899 /* Prune out the variables that were found to behave badly
900 (i.e. have their address taken). */
901 EXECUTE_IF_SET_IN_BITMAP (module_statics_escape, 0, index, bi)
903 splay_tree_remove (reference_vars_to_consider, index);
906 bitmap_and_compl_into (all_module_statics,
907 module_statics_escape);
909 bitmap_and_compl (module_statics_readonly, all_module_statics,
910 module_statics_written);
912 /* If the address is not taken, we can unset the addressable bit
913 on this variable. */
914 EXECUTE_IF_SET_IN_BITMAP (all_module_statics, 0, index, bi)
916 tree var = get_static_decl (index);
917 TREE_ADDRESSABLE (var) = 0;
918 if (dump_file)
919 fprintf (dump_file, "Not TREE_ADDRESSABLE var %s\n",
920 get_static_name (index));
923 /* If the variable is never written, we can set the TREE_READONLY
924 flag. Additionally if it has a DECL_INITIAL that is made up of
925 constants we can treat the entire global as a constant. */
927 bitmap_and_compl (module_statics_readonly, all_module_statics,
928 module_statics_written);
929 EXECUTE_IF_SET_IN_BITMAP (module_statics_readonly, 0, index, bi)
931 tree var = get_static_decl (index);
933 /* Ignore variables in named sections - changing TREE_READONLY
934 changes the section flags, potentially causing conflicts with
935 other variables in the same named section. */
936 if (DECL_SECTION_NAME (var) == NULL_TREE)
938 TREE_READONLY (var) = 1;
939 if (dump_file)
940 fprintf (dump_file, "read-only var %s\n",
941 get_static_name (index));
945 BITMAP_FREE(module_statics_escape);
946 BITMAP_FREE(module_statics_written);
947 module_statics_escape = NULL;
948 module_statics_written = NULL;
950 if (dump_file)
951 EXECUTE_IF_SET_IN_BITMAP (all_module_statics, 0, index, bi)
953 fprintf (dump_file, "\nPromotable global:%s",
954 get_static_name (index));
957 for (node = cgraph_nodes; node; node = node->next)
958 if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
960 ipa_reference_local_vars_info_t l;
961 l = get_reference_vars_info (node)->local;
963 /* Any variables that are not in all_module_statics are
964 removed from the local maps. This will include all of the
965 variables that were found to escape in the function
966 scanning. */
967 bitmap_and_into (l->statics_read,
968 all_module_statics);
969 bitmap_and_into (l->statics_written,
970 all_module_statics);
973 BITMAP_FREE(module_statics_readonly);
974 BITMAP_FREE(bm_temp);
976 if (dump_file)
977 for (node = cgraph_nodes; node; node = node->next)
978 if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
980 ipa_reference_local_vars_info_t l;
981 unsigned int index;
982 bitmap_iterator bi;
984 l = get_reference_vars_info (node)->local;
985 fprintf (dump_file,
986 "\nFunction name:%s/%i:",
987 cgraph_node_name (node), node->uid);
988 fprintf (dump_file, "\n locals read: ");
989 EXECUTE_IF_SET_IN_BITMAP (l->statics_read,
990 0, index, bi)
992 fprintf (dump_file, "%s ",
993 get_static_name (index));
995 fprintf (dump_file, "\n locals written: ");
996 EXECUTE_IF_SET_IN_BITMAP (l->statics_written,
997 0, index, bi)
999 fprintf(dump_file, "%s ",
1000 get_static_name (index));
1002 if (l->calls_read_all)
1003 fprintf (dump_file, "\n calls read all: ");
1004 if (l->calls_write_all)
1005 fprintf (dump_file, "\n calls read all: ");
1010 /* Return true if we need to write summary of NODE. */
1012 static bool
1013 write_node_summary_p (struct cgraph_node *node)
1015 return (node->analyzed
1016 && node->global.inlined_to == NULL
1017 && cgraph_function_body_availability (node) == AVAIL_OVERWRITABLE
1018 && get_reference_vars_info (node) != NULL);
1021 /* Serialize the ipa info for lto. */
1023 static void
1024 ipa_reference_write_summary (cgraph_node_set set)
1026 struct cgraph_node *node;
1027 struct lto_simple_output_block *ob
1028 = lto_create_simple_output_block (LTO_section_ipa_reference);
1029 unsigned int count = 0;
1030 cgraph_node_set_iterator csi;
1032 for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
1033 if (write_node_summary_p (csi_node (csi)))
1034 count++;
1036 lto_output_uleb128_stream (ob->main_stream, count);
1038 /* Process all of the functions. */
1039 for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
1041 node = csi_node (csi);
1042 if (write_node_summary_p (node))
1044 ipa_reference_local_vars_info_t l
1045 = get_reference_vars_info (node)->local;
1046 unsigned int index;
1047 bitmap_iterator bi;
1048 lto_cgraph_encoder_t encoder;
1049 int node_ref;
1051 encoder = ob->decl_state->cgraph_node_encoder;
1052 node_ref = lto_cgraph_encoder_encode (encoder, node);
1053 lto_output_uleb128_stream (ob->main_stream, node_ref);
1055 /* Stream out the statics read. */
1056 lto_output_uleb128_stream (ob->main_stream,
1057 bitmap_count_bits (l->statics_read));
1058 EXECUTE_IF_SET_IN_BITMAP (l->statics_read, 0, index, bi)
1059 lto_output_var_decl_index(ob->decl_state, ob->main_stream,
1060 get_static_decl (index));
1062 /* Stream out the statics written. */
1063 lto_output_uleb128_stream (ob->main_stream,
1064 bitmap_count_bits (l->statics_written));
1065 EXECUTE_IF_SET_IN_BITMAP (l->statics_written, 0, index, bi)
1066 lto_output_var_decl_index(ob->decl_state, ob->main_stream,
1067 get_static_decl (index));
1070 lto_destroy_simple_output_block (ob);
1074 /* Deserialize the ipa info for lto. */
1076 static void
1077 ipa_reference_read_summary (void)
1079 struct lto_file_decl_data ** file_data_vec
1080 = lto_get_file_decl_data ();
1081 struct lto_file_decl_data * file_data;
1082 unsigned int j = 0;
1084 ipa_init ();
1086 while ((file_data = file_data_vec[j++]))
1088 const char *data;
1089 size_t len;
1090 struct lto_input_block *ib
1091 = lto_create_simple_input_block (file_data,
1092 LTO_section_ipa_reference,
1093 &data, &len);
1094 if (ib)
1096 unsigned int i;
1097 unsigned int f_count = lto_input_uleb128 (ib);
1099 for (i = 0; i < f_count; i++)
1101 unsigned int j, index;
1102 struct cgraph_node *node;
1103 ipa_reference_local_vars_info_t l;
1104 unsigned int v_count;
1105 lto_cgraph_encoder_t encoder;
1107 index = lto_input_uleb128 (ib);
1108 encoder = file_data->cgraph_node_encoder;
1109 node = lto_cgraph_encoder_deref (encoder, index);
1110 l = init_function_info (node);
1112 /* Set the statics read. */
1113 v_count = lto_input_uleb128 (ib);
1114 for (j = 0; j < v_count; j++)
1116 unsigned int var_index = lto_input_uleb128 (ib);
1117 tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1118 var_index);
1119 add_static_var (v_decl);
1120 bitmap_set_bit (l->statics_read, DECL_UID (v_decl));
1123 /* Set the statics written. */
1124 v_count = lto_input_uleb128 (ib);
1125 for (j = 0; j < v_count; j++)
1127 unsigned int var_index = lto_input_uleb128 (ib);
1128 tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1129 var_index);
1130 add_static_var (v_decl);
1131 bitmap_set_bit (l->statics_written, DECL_UID (v_decl));
1135 lto_destroy_simple_input_block (file_data,
1136 LTO_section_ipa_reference,
1137 ib, data, len);
1144 /* Produce the global information by preforming a transitive closure
1145 on the local information that was produced by ipa_analyze_function
1146 and ipa_analyze_variable. */
1148 static unsigned int
1149 propagate (void)
1151 struct cgraph_node *node;
1152 struct cgraph_node *w;
1153 struct cgraph_node **order =
1154 XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
1155 int order_pos = ipa_utils_reduced_inorder (order, false, true, NULL);
1156 int i;
1158 cgraph_remove_function_insertion_hook (function_insertion_hook_holder);
1159 if (dump_file)
1160 dump_cgraph (dump_file);
1162 /* Propagate the local information thru the call graph to produce
1163 the global information. All the nodes within a cycle will have
1164 the same info so we collapse cycles first. Then we can do the
1165 propagation in one pass from the leaves to the roots. */
1166 order_pos = ipa_utils_reduced_inorder (order, true, true, NULL);
1167 if (dump_file)
1168 ipa_utils_print_order(dump_file, "reduced", order, order_pos);
1170 for (i = 0; i < order_pos; i++ )
1172 ipa_reference_vars_info_t node_info;
1173 ipa_reference_global_vars_info_t node_g =
1174 XCNEW (struct ipa_reference_global_vars_info_d);
1175 ipa_reference_local_vars_info_t node_l;
1177 bool read_all;
1178 bool write_all;
1179 struct ipa_dfs_info * w_info;
1181 node = order[i];
1182 node_info = get_reference_vars_info (node);
1183 if (!node_info)
1185 dump_cgraph_node (stderr, node);
1186 dump_cgraph (stderr);
1187 gcc_unreachable ();
1190 gcc_assert (!node_info->global);
1191 node_l = node_info->local;
1193 read_all = node_l->calls_read_all;
1194 write_all = node_l->calls_write_all;
1196 /* If any node in a cycle is calls_read_all or calls_write_all
1197 they all are. */
1198 w_info = (struct ipa_dfs_info *) node->aux;
1199 w = w_info->next_cycle;
1200 while (w)
1202 ipa_reference_local_vars_info_t w_l =
1203 get_reference_vars_info (w)->local;
1204 read_all |= w_l->calls_read_all;
1205 write_all |= w_l->calls_write_all;
1207 w_info = (struct ipa_dfs_info *) w->aux;
1208 w = w_info->next_cycle;
1211 /* Initialized the bitmaps for the reduced nodes */
1212 if (read_all)
1213 node_g->statics_read = all_module_statics;
1214 else
1216 node_g->statics_read = BITMAP_ALLOC (&global_info_obstack);
1217 bitmap_copy (node_g->statics_read,
1218 node_l->statics_read);
1221 if (write_all)
1222 node_g->statics_written = all_module_statics;
1223 else
1225 node_g->statics_written = BITMAP_ALLOC (&global_info_obstack);
1226 bitmap_copy (node_g->statics_written,
1227 node_l->statics_written);
1230 propagate_bits (node_g, node);
1231 w_info = (struct ipa_dfs_info *) node->aux;
1232 w = w_info->next_cycle;
1233 while (w)
1235 ipa_reference_vars_info_t w_ri =
1236 get_reference_vars_info (w);
1237 ipa_reference_local_vars_info_t w_l = w_ri->local;
1239 /* These global bitmaps are initialized from the local info
1240 of all of the nodes in the region. However there is no
1241 need to do any work if the bitmaps were set to
1242 all_module_statics. */
1243 if (!read_all)
1244 bitmap_ior_into (node_g->statics_read,
1245 w_l->statics_read);
1246 if (!write_all)
1247 bitmap_ior_into (node_g->statics_written,
1248 w_l->statics_written);
1249 propagate_bits (node_g, w);
1250 w_info = (struct ipa_dfs_info *) w->aux;
1251 w = w_info->next_cycle;
1254 /* All nodes within a cycle have the same global info bitmaps. */
1255 node_info->global = node_g;
1256 w_info = (struct ipa_dfs_info *) node->aux;
1257 w = w_info->next_cycle;
1258 while (w)
1260 ipa_reference_vars_info_t w_ri =
1261 get_reference_vars_info (w);
1263 gcc_assert (!w_ri->global);
1264 w_ri->global = XCNEW (struct ipa_reference_global_vars_info_d);
1265 w_ri->global->statics_read = copy_global_bitmap (node_g->statics_read);
1266 w_ri->global->statics_written = copy_global_bitmap (node_g->statics_written);
1268 w_info = (struct ipa_dfs_info *) w->aux;
1269 w = w_info->next_cycle;
1273 if (dump_file)
1275 for (i = 0; i < order_pos; i++ )
1277 ipa_reference_vars_info_t node_info;
1278 ipa_reference_global_vars_info_t node_g;
1279 ipa_reference_local_vars_info_t node_l;
1280 unsigned int index;
1281 bitmap_iterator bi;
1282 struct ipa_dfs_info * w_info;
1284 node = order[i];
1285 node_info = get_reference_vars_info (node);
1286 node_g = node_info->global;
1287 node_l = node_info->local;
1288 fprintf (dump_file,
1289 "\nFunction name:%s/%i:",
1290 cgraph_node_name (node), node->uid);
1291 fprintf (dump_file, "\n locals read: ");
1292 EXECUTE_IF_SET_IN_BITMAP (node_l->statics_read,
1293 0, index, bi)
1295 fprintf (dump_file, "%s ",
1296 get_static_name (index));
1298 fprintf (dump_file, "\n locals written: ");
1299 EXECUTE_IF_SET_IN_BITMAP (node_l->statics_written,
1300 0, index, bi)
1302 fprintf(dump_file, "%s ",
1303 get_static_name (index));
1306 w_info = (struct ipa_dfs_info *) node->aux;
1307 w = w_info->next_cycle;
1308 while (w)
1310 ipa_reference_vars_info_t w_ri =
1311 get_reference_vars_info (w);
1312 ipa_reference_local_vars_info_t w_l = w_ri->local;
1313 fprintf (dump_file, "\n next cycle: %s/%i ",
1314 cgraph_node_name (w), w->uid);
1315 fprintf (dump_file, "\n locals read: ");
1316 EXECUTE_IF_SET_IN_BITMAP (w_l->statics_read,
1317 0, index, bi)
1319 fprintf (dump_file, "%s ",
1320 get_static_name (index));
1323 fprintf (dump_file, "\n locals written: ");
1324 EXECUTE_IF_SET_IN_BITMAP (w_l->statics_written,
1325 0, index, bi)
1327 fprintf(dump_file, "%s ",
1328 get_static_name (index));
1332 w_info = (struct ipa_dfs_info *) w->aux;
1333 w = w_info->next_cycle;
1335 fprintf (dump_file, "\n globals read: ");
1336 EXECUTE_IF_SET_IN_BITMAP (node_g->statics_read,
1337 0, index, bi)
1339 fprintf (dump_file, "%s ",
1340 get_static_name (index));
1342 fprintf (dump_file, "\n globals written: ");
1343 EXECUTE_IF_SET_IN_BITMAP (node_g->statics_written,
1344 0, index, bi)
1346 fprintf (dump_file, "%s ",
1347 get_static_name (index));
1352 /* Cleanup. */
1353 for (i = 0; i < order_pos; i++ )
1355 ipa_reference_vars_info_t node_info;
1356 ipa_reference_global_vars_info_t node_g;
1357 node = order[i];
1358 node_info = get_reference_vars_info (node);
1359 node_g = node_info->global;
1361 /* Create the complimentary sets. These are more useful for
1362 certain apis. */
1363 node_g->statics_not_read = BITMAP_ALLOC (&global_info_obstack);
1364 node_g->statics_not_written = BITMAP_ALLOC (&global_info_obstack);
1366 if (node_g->statics_read != all_module_statics)
1367 bitmap_and_compl (node_g->statics_not_read,
1368 all_module_statics,
1369 node_g->statics_read);
1371 if (node_g->statics_written
1372 != all_module_statics)
1373 bitmap_and_compl (node_g->statics_not_written,
1374 all_module_statics,
1375 node_g->statics_written);
1378 free (order);
1380 for (node = cgraph_nodes; node; node = node->next)
1382 ipa_reference_vars_info_t node_info;
1383 node_info = get_reference_vars_info (node);
1384 /* Get rid of the aux information. */
1386 if (node->aux)
1388 free (node->aux);
1389 node->aux = NULL;
1392 if (cgraph_function_body_availability (node) == AVAIL_OVERWRITABLE)
1393 clean_function (node);
1394 else if (node_info)
1395 clean_function_local_data (node);
1397 bitmap_obstack_release (&local_info_obstack);
1398 return 0;
1402 static bool
1403 gate_reference (void)
1405 return (flag_ipa_reference
1406 /* Don't bother doing anything if the program has errors. */
1407 && !(errorcount || sorrycount));
1410 struct ipa_opt_pass_d pass_ipa_reference =
1413 IPA_PASS,
1414 "static-var", /* name */
1415 gate_reference, /* gate */
1416 propagate, /* execute */
1417 NULL, /* sub */
1418 NULL, /* next */
1419 0, /* static_pass_number */
1420 TV_IPA_REFERENCE, /* tv_id */
1421 0, /* properties_required */
1422 0, /* properties_provided */
1423 0, /* properties_destroyed */
1424 0, /* todo_flags_start */
1425 0 /* todo_flags_finish */
1427 generate_summary, /* generate_summary */
1428 ipa_reference_write_summary, /* write_summary */
1429 ipa_reference_read_summary, /* read_summary */
1430 NULL, /* function_read_summary */
1431 0, /* TODOs */
1432 NULL, /* function_transform */
1433 NULL /* variable_transform */
1436 #include "gt-ipa-reference.h"