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 /* Obstack holding bitmaps of local analysis (live from analysis to
98 static bitmap_obstack local_info_obstack;
99 /* Obstack holding global analysis live forever. */
100 static bitmap_obstack global_info_obstack;
102 /* Holders of ipa cgraph hooks: */
103 static struct cgraph_node_hook_list *function_insertion_hook_holder;
105 enum initialization_status_t
112 tree memory_identifier_string;
114 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
115 static inline ipa_reference_vars_info_t
116 get_reference_vars_info_from_cgraph (struct cgraph_node * node)
118 return get_function_ann (node->decl)->reference_vars_info;
121 /* Get a bitmap that contains all of the locally referenced static
122 variables for function FN. */
123 static ipa_reference_local_vars_info_t
124 get_local_reference_vars_info (tree fn)
126 ipa_reference_vars_info_t info = get_function_ann (fn)->reference_vars_info;
131 /* This phase was not run. */
135 /* Get a bitmap that contains all of the globally referenced static
136 variables for function FN. */
138 static ipa_reference_global_vars_info_t
139 get_global_reference_vars_info (tree fn)
141 ipa_reference_vars_info_t info = get_function_ann (fn)->reference_vars_info;
146 /* This phase was not run. */
150 /* Return a bitmap indexed by VAR_DECL uid for the static variables
151 that may be read locally by the execution of the function fn.
152 Returns NULL if no data is available. */
155 ipa_reference_get_read_local (tree fn)
157 ipa_reference_local_vars_info_t l = get_local_reference_vars_info (fn);
159 return l->statics_read;
164 /* Return a bitmap indexed by VAR_DECL uid for the static variables
165 that may be written locally by the execution of the function fn.
166 Returns NULL if no data is available. */
169 ipa_reference_get_written_local (tree fn)
171 ipa_reference_local_vars_info_t l = get_local_reference_vars_info (fn);
173 return l->statics_written;
178 /* Return a bitmap indexed by VAR_DECL uid for the static variables
179 that are read during the execution of the function FN. Returns
180 NULL if no data is available. */
183 ipa_reference_get_read_global (tree fn)
185 ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
187 return g->statics_read;
192 /* Return a bitmap indexed by VAR_DECL uid for the static variables
193 that are written during the execution of the function FN. Note
194 that variables written may or may not be read during the function
195 call. Returns NULL if no data is available. */
198 ipa_reference_get_written_global (tree fn)
200 ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
202 return g->statics_written;
207 /* Return a bitmap indexed by_DECL_UID uid for the static variables
208 that are not read during the execution of the function FN. Returns
209 NULL if no data is available. */
212 ipa_reference_get_not_read_global (tree fn)
214 ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
216 return g->statics_not_read;
221 /* Return a bitmap indexed by DECL_UID uid for the static variables
222 that are not written during the execution of the function FN. Note
223 that variables written may or may not be read during the function
224 call. Returns NULL if no data is available. */
227 ipa_reference_get_not_written_global (tree fn)
229 ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
231 return g->statics_not_written;
238 /* Add VAR to all_module_statics and the two
239 reference_vars_to_consider* sets. */
242 add_static_var (tree var)
244 int uid = DECL_UID (var);
245 gcc_assert (TREE_CODE (var) == VAR_DECL);
246 if (!bitmap_bit_p (all_module_statics, uid))
248 splay_tree_insert (reference_vars_to_consider,
249 uid, (splay_tree_value)var);
250 bitmap_set_bit (all_module_statics, uid);
254 /* Return true if the variable T is the right kind of static variable to
255 perform compilation unit scope escape analysis. */
258 has_proper_scope_for_analysis (tree t)
260 /* If the variable has the "used" attribute, treat it as if it had a
261 been touched by the devil. */
262 if (lookup_attribute ("used", DECL_ATTRIBUTES (t)))
265 /* Do not want to do anything with volatile except mark any
266 function that uses one to be not const or pure. */
267 if (TREE_THIS_VOLATILE (t))
270 /* Do not care about a local automatic that is not static. */
271 if (!TREE_STATIC (t) && !DECL_EXTERNAL (t))
274 if (DECL_EXTERNAL (t) || TREE_PUBLIC (t))
277 /* We cannot touch decls where the type needs constructing. */
278 if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (t)))
281 /* This is a variable we care about. Check if we have seen it
282 before, and if not add it the set of variables we care about. */
283 if (!bitmap_bit_p (all_module_statics, DECL_UID (t)))
289 /* Mark tree T as having address taken. */
292 mark_address_taken (tree x)
294 if (TREE_CODE (x) == VAR_DECL
295 && module_statics_escape && has_proper_scope_for_analysis (x))
296 bitmap_set_bit (module_statics_escape, DECL_UID (x));
299 /* Mark load of T. */
302 mark_load (ipa_reference_local_vars_info_t local,
305 if (TREE_CODE (t) == VAR_DECL
306 && has_proper_scope_for_analysis (t))
307 bitmap_set_bit (local->statics_read, DECL_UID (t));
310 /* Mark store of T. */
313 mark_store (ipa_reference_local_vars_info_t local,
316 if (TREE_CODE (t) == VAR_DECL
317 && has_proper_scope_for_analysis (t))
320 bitmap_set_bit (local->statics_written, DECL_UID (t));
321 /* Mark the write so we can tell which statics are
323 if (module_statics_written)
324 bitmap_set_bit (module_statics_written, DECL_UID (t));
328 /* Look for memory clobber and set read_all/write_all if present. */
331 check_asm_memory_clobber (ipa_reference_local_vars_info_t local, gimple stmt)
336 for (i = 0; i < gimple_asm_nclobbers (stmt); i++)
338 op = gimple_asm_clobber_op (stmt, i);
339 if (simple_cst_equal(TREE_VALUE (op), memory_identifier_string) == 1)
341 /* Abandon all hope, ye who enter here. */
342 local->calls_read_all = true;
343 local->calls_write_all = true;
348 /* Look for external calls and set read_all/write_all correspondingly. */
351 check_call (ipa_reference_local_vars_info_t local, gimple stmt)
353 int flags = gimple_call_flags (stmt);
354 tree callee_t = gimple_call_fndecl (stmt);
355 enum availability avail = AVAIL_NOT_AVAILABLE;
359 struct cgraph_node* callee = cgraph_node(callee_t);
360 avail = cgraph_function_body_availability (callee);
363 if (avail == AVAIL_NOT_AVAILABLE || avail == AVAIL_OVERWRITABLE)
366 if (flags & ECF_CONST)
368 else if (flags & ECF_PURE)
369 local->calls_read_all = true;
372 local->calls_read_all = true;
373 local->calls_write_all = true;
376 /* TODO: To be able to produce sane results, we should also handle
377 common builtins, in particular throw.
378 Indirect calls hsould be only counted and as inliner is replacing them
379 by direct calls, we can conclude if any indirect calls are left in body */
382 /* TP is the part of the tree currently under the microscope.
383 WALK_SUBTREES is part of the walk_tree api but is unused here.
384 DATA is cgraph_node of the function being walked. */
387 scan_stmt_for_static_refs (gimple_stmt_iterator *gsip,
388 struct cgraph_node *fn)
390 gimple stmt = gsi_stmt (*gsip);
391 ipa_reference_local_vars_info_t local = NULL;
396 local = get_reference_vars_info_from_cgraph (fn)->local;
398 if (gimple_loaded_syms (stmt))
399 EXECUTE_IF_SET_IN_BITMAP (gimple_loaded_syms (stmt), 0, i, bi)
400 mark_load (local, referenced_var_lookup (i));
401 if (gimple_stored_syms (stmt))
402 EXECUTE_IF_SET_IN_BITMAP (gimple_stored_syms (stmt), 0, i, bi)
403 mark_store (local, referenced_var_lookup (i));
404 if (gimple_addresses_taken (stmt))
405 EXECUTE_IF_SET_IN_BITMAP (gimple_addresses_taken (stmt), 0, i, bi)
406 mark_address_taken (referenced_var_lookup (i));
408 switch (gimple_code (stmt))
411 check_call (local, stmt);
415 check_asm_memory_clobber (local, stmt);
418 /* We used to check nonlocal labels here and set them as potentially modifying
419 everything. This is not needed, since we can get to nonlocal label only
420 from callee and thus we will get info propagated. */
429 /* Call-back to scan variable initializers for static references.
430 Called using walk_tree. */
433 scan_initializer_for_static_refs (tree *tp, int *walk_subtrees,
434 void *data ATTRIBUTE_UNUSED)
438 if (TREE_CODE (t) == ADDR_EXPR)
440 mark_address_taken (get_base_var (t));
443 /* Save some cycles by not walking types and declaration as we
444 won't find anything useful there anyway. */
445 else if (IS_TYPE_OR_DECL_P (*tp))
451 /* Lookup the tree node for the static variable that has UID. */
453 get_static_decl (int index)
455 splay_tree_node stn =
456 splay_tree_lookup (reference_vars_to_consider, index);
458 return (tree)stn->value;
462 /* Lookup the tree node for the static variable that has UID and
463 convert the name to a string for debugging. */
466 get_static_name (int index)
468 splay_tree_node stn =
469 splay_tree_lookup (reference_vars_to_consider, index);
471 return lang_hooks.decl_printable_name ((tree)(stn->value), 2);
475 /* Or in all of the bits from every callee into X, the caller's, bit
476 vector. There are several cases to check to avoid the sparse
480 propagate_bits (struct cgraph_node *x)
482 ipa_reference_vars_info_t x_info = get_reference_vars_info_from_cgraph (x);
483 ipa_reference_global_vars_info_t x_global = x_info->global;
485 struct cgraph_edge *e;
486 for (e = x->callees; e; e = e->next_callee)
488 struct cgraph_node *y = e->callee;
490 /* Only look at the master nodes and skip external nodes. */
491 y = cgraph_master_clone (y);
494 if (get_reference_vars_info_from_cgraph (y))
496 ipa_reference_vars_info_t y_info
497 = get_reference_vars_info_from_cgraph (y);
498 ipa_reference_global_vars_info_t y_global = y_info->global;
500 if (x_global->statics_read
501 != all_module_statics)
503 if (y_global->statics_read
504 == all_module_statics)
506 BITMAP_FREE (x_global->statics_read);
507 x_global->statics_read
508 = all_module_statics;
510 /* Skip bitmaps that are pointer equal to node's bitmap
511 (no reason to spin within the cycle). */
512 else if (x_global->statics_read
513 != y_global->statics_read)
514 bitmap_ior_into (x_global->statics_read,
515 y_global->statics_read);
518 if (x_global->statics_written
519 != all_module_statics)
521 if (y_global->statics_written
522 == all_module_statics)
524 BITMAP_FREE (x_global->statics_written);
525 x_global->statics_written
526 = all_module_statics;
528 /* Skip bitmaps that are pointer equal to node's bitmap
529 (no reason to spin within the cycle). */
530 else if (x_global->statics_written
531 != y_global->statics_written)
532 bitmap_ior_into (x_global->statics_written,
533 y_global->statics_written);
542 /* Look at all of the callees of X to see which ones represent inlined
543 calls. For each of these callees, merge their local info into
544 TARGET and check their children recursively.
546 This function goes away when Jan changes the inliner and IPA
547 analysis so that this is not run between the time when inlining
548 decisions are made and when the inlining actually occurs. */
551 merge_callee_local_info (struct cgraph_node *target,
552 struct cgraph_node *x)
554 struct cgraph_edge *e;
555 ipa_reference_local_vars_info_t x_l =
556 get_reference_vars_info_from_cgraph (target)->local;
558 /* Make the world safe for tail recursion. */
559 struct ipa_dfs_info *node_info = (struct ipa_dfs_info *) x->aux;
566 for (e = x->callees; e; e = e->next_callee)
568 struct cgraph_node *y = e->callee;
569 if (y->global.inlined_to)
571 ipa_reference_vars_info_t y_info;
572 ipa_reference_local_vars_info_t y_l;
573 struct cgraph_node* orig_y = y;
575 y = cgraph_master_clone (y);
578 y_info = get_reference_vars_info_from_cgraph (y);
582 bitmap_ior_into (x_l->statics_read,
584 bitmap_ior_into (x_l->statics_written,
585 y_l->statics_written);
587 x_l->calls_read_all |= y_l->calls_read_all;
588 x_l->calls_write_all |= y_l->calls_write_all;
589 merge_callee_local_info (target, y);
593 fprintf(stderr, "suspect inlining of ");
594 dump_cgraph_node (stderr, orig_y);
595 fprintf(stderr, "\ninto ");
596 dump_cgraph_node (stderr, target);
597 dump_cgraph (stderr);
603 node_info->aux = NULL;
606 /* The init routine for analyzing global static variable usage. See
607 comments at top for description. */
611 memory_identifier_string = build_string(7, "memory");
613 reference_vars_to_consider =
614 splay_tree_new_ggc (splay_tree_compare_ints);
616 bitmap_obstack_initialize (&local_info_obstack);
617 bitmap_obstack_initialize (&global_info_obstack);
618 module_statics_escape = BITMAP_ALLOC (&local_info_obstack);
619 module_statics_written = BITMAP_ALLOC (&local_info_obstack);
620 all_module_statics = BITMAP_ALLOC (&global_info_obstack);
622 /* There are some shared nodes, in particular the initializers on
623 static declarations. We do not need to scan them more than once
624 since all we would be interested in are the addressof
626 visited_nodes = pointer_set_create ();
629 /* Check out the rhs of a static or global initialization VNODE to see
630 if any of them contain addressof operations. Note that some of
631 these variables may not even be referenced in the code in this
632 compilation unit but their right hand sides may contain references
633 to variables defined within this unit. */
636 analyze_variable (struct varpool_node *vnode)
638 struct walk_stmt_info wi;
639 tree global = vnode->decl;
641 memset (&wi, 0, sizeof (wi));
642 wi.pset = visited_nodes;
643 walk_tree (&DECL_INITIAL (global), scan_initializer_for_static_refs,
647 /* Set up the persistent info for FN. */
649 static ipa_reference_local_vars_info_t
650 init_function_info (struct cgraph_node *fn)
652 ipa_reference_vars_info_t info
653 = XCNEW (struct ipa_reference_vars_info_d);
654 ipa_reference_local_vars_info_t l
655 = XCNEW (struct ipa_reference_local_vars_info_d);
656 tree decl = fn->decl;
658 /* Add the info to the tree's annotation. */
659 get_function_ann (decl)->reference_vars_info = info;
662 l->statics_read = BITMAP_ALLOC (&local_info_obstack);
663 l->statics_written = BITMAP_ALLOC (&local_info_obstack);
668 /* This is the main routine for finding the reference patterns for
669 global variables within a function FN. */
672 analyze_function (struct cgraph_node *fn)
674 tree decl = fn->decl;
675 struct function *this_cfun = DECL_STRUCT_FUNCTION (decl);
676 basic_block this_block;
677 #ifdef ENABLE_CHECKING
682 fprintf (dump_file, "\n local analysis of %s\n", cgraph_node_name (fn));
684 push_cfun (DECL_STRUCT_FUNCTION (decl));
685 current_function_decl = decl;
687 init_function_info (fn);
688 FOR_EACH_BB_FN (this_block, this_cfun)
690 gimple_stmt_iterator gsi;
696 /* Find the addresses taken in phi node arguments. */
697 for (gsi = gsi_start_phis (this_block);
701 phi = gsi_stmt (gsi);
702 FOR_EACH_PHI_ARG (use, phi, iter, SSA_OP_USE)
704 op = USE_FROM_PTR (use);
705 if (TREE_CODE (op) == ADDR_EXPR)
706 mark_address_taken (get_base_var (op));
710 for (gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi))
711 scan_stmt_for_static_refs (&gsi, fn);
714 #ifdef ENABLE_CHECKING
715 /* Verify that all local initializers was expanded by gimplifier. */
716 for (step = DECL_STRUCT_FUNCTION (decl)->local_decls;
718 step = TREE_CHAIN (step))
720 tree var = TREE_VALUE (step);
721 if (TREE_CODE (var) == VAR_DECL
722 && DECL_INITIAL (var)
723 && !TREE_STATIC (var))
728 current_function_decl = NULL;
731 /* If FN is avail == AVAIL_OVERWRITABLE, replace the effects bit
732 vectors with worst case bit vectors. We had to analyze it above to
733 find out if it took the address of any statics. However, now that
734 we know that, we can get rid of all of the other side effects. */
737 clean_function (struct cgraph_node *fn)
739 ipa_reference_vars_info_t info = get_reference_vars_info_from_cgraph (fn);
740 ipa_reference_local_vars_info_t l = info->local;
741 ipa_reference_global_vars_info_t g = info->global;
746 && l->statics_read != all_module_statics)
747 BITMAP_FREE (l->statics_read);
748 if (l->statics_written
749 &&l->statics_written != all_module_statics)
750 BITMAP_FREE (l->statics_written);
757 && g->statics_read != all_module_statics)
758 BITMAP_FREE (g->statics_read);
760 if (g->statics_written
761 && g->statics_written != all_module_statics)
762 BITMAP_FREE (g->statics_written);
764 if (g->statics_not_read
765 && g->statics_not_read != all_module_statics)
766 BITMAP_FREE (g->statics_not_read);
768 if (g->statics_not_written
769 && g->statics_not_written != all_module_statics)
770 BITMAP_FREE (g->statics_not_written);
774 free (get_function_ann (fn->decl)->reference_vars_info);
775 get_function_ann (fn->decl)->reference_vars_info = NULL;
778 /* Called when new function is inserted to callgraph late. */
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
786 analyze_function (node);
787 visited_nodes = NULL;
790 /* Analyze each function in the cgraph to see which global or statics
791 are read or written. */
794 generate_summary (void)
796 struct cgraph_node *node;
797 struct varpool_node *vnode;
800 bitmap module_statics_readonly;
803 function_insertion_hook_holder =
804 cgraph_add_function_insertion_hook (&add_new_function, NULL);
806 module_statics_readonly = BITMAP_ALLOC (&local_info_obstack);
807 bm_temp = BITMAP_ALLOC (&local_info_obstack);
809 /* Process all of the variables first. */
810 FOR_EACH_STATIC_INITIALIZER (vnode)
811 analyze_variable (vnode);
813 /* Process all of the functions next.
815 We do not want to process any of the clones so we check that this
816 is a master clone. However, we do need to process any
817 AVAIL_OVERWRITABLE functions (these are never clones) because
818 they may cause a static variable to escape. The code that can
819 overwrite such a function cannot access the statics because it
820 would not be in the same compilation unit. When the analysis is
821 finished, the computed information of these AVAIL_OVERWRITABLE is
822 replaced with worst case info.
824 for (node = cgraph_nodes; node; node = node->next)
826 && (cgraph_is_master_clone (node)
827 || (cgraph_function_body_availability (node)
828 == AVAIL_OVERWRITABLE)))
829 analyze_function (node);
831 pointer_set_destroy (visited_nodes);
832 visited_nodes = NULL;
834 /* Prune out the variables that were found to behave badly
835 (i.e. have their address taken). */
836 EXECUTE_IF_SET_IN_BITMAP (module_statics_escape, 0, index, bi)
838 splay_tree_remove (reference_vars_to_consider, index);
841 bitmap_and_compl_into (all_module_statics,
842 module_statics_escape);
844 bitmap_and_compl (module_statics_readonly, all_module_statics,
845 module_statics_written);
847 /* If the address is not taken, we can unset the addressable bit
849 EXECUTE_IF_SET_IN_BITMAP (all_module_statics, 0, index, bi)
851 tree var = get_static_decl (index);
852 TREE_ADDRESSABLE (var) = 0;
854 fprintf (dump_file, "Not TREE_ADDRESSABLE var %s\n",
855 get_static_name (index));
858 /* If the variable is never written, we can set the TREE_READONLY
859 flag. Additionally if it has a DECL_INITIAL that is made up of
860 constants we can treat the entire global as a constant. */
862 bitmap_and_compl (module_statics_readonly, all_module_statics,
863 module_statics_written);
864 EXECUTE_IF_SET_IN_BITMAP (module_statics_readonly, 0, index, bi)
866 tree var = get_static_decl (index);
868 /* Ignore variables in named sections - changing TREE_READONLY
869 changes the section flags, potentially causing conflicts with
870 other variables in the same named section. */
871 if (DECL_SECTION_NAME (var) == NULL_TREE)
873 TREE_READONLY (var) = 1;
875 fprintf (dump_file, "read-only var %s\n",
876 get_static_name (index));
880 BITMAP_FREE(module_statics_escape);
881 BITMAP_FREE(module_statics_written);
882 module_statics_escape = NULL;
883 module_statics_written = NULL;
886 EXECUTE_IF_SET_IN_BITMAP (all_module_statics, 0, index, bi)
888 fprintf (dump_file, "\nPromotable global:%s",
889 get_static_name (index));
892 for (node = cgraph_nodes; node; node = node->next)
894 && (cgraph_is_master_clone (node)
895 || (cgraph_function_body_availability (node)
896 == AVAIL_OVERWRITABLE)))
898 ipa_reference_local_vars_info_t l;
899 l = get_reference_vars_info_from_cgraph (node)->local;
901 /* Any variables that are not in all_module_statics are
902 removed from the local maps. This will include all of the
903 variables that were found to escape in the function
905 bitmap_and_into (l->statics_read,
907 bitmap_and_into (l->statics_written,
911 BITMAP_FREE(module_statics_readonly);
912 BITMAP_FREE(bm_temp);
915 for (node = cgraph_nodes; node; node = node->next)
917 && (cgraph_is_master_clone (node)
918 || (cgraph_function_body_availability (node)
919 == AVAIL_OVERWRITABLE)))
921 ipa_reference_local_vars_info_t l;
925 l = get_reference_vars_info_from_cgraph (node)->local;
927 "\nFunction name:%s/%i:",
928 cgraph_node_name (node), node->uid);
929 fprintf (dump_file, "\n locals read: ");
930 EXECUTE_IF_SET_IN_BITMAP (l->statics_read,
933 fprintf (dump_file, "%s ",
934 get_static_name (index));
936 fprintf (dump_file, "\n locals written: ");
937 EXECUTE_IF_SET_IN_BITMAP (l->statics_written,
940 fprintf(dump_file, "%s ",
941 get_static_name (index));
946 /* Produce the global information by preforming a transitive closure
947 on the local information that was produced by ipa_analyze_function
948 and ipa_analyze_variable. */
953 struct cgraph_node *node;
954 struct cgraph_node *w;
955 struct cgraph_node **order =
956 XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
957 int order_pos = ipa_utils_reduced_inorder (order, false, true);
960 cgraph_remove_function_insertion_hook (function_insertion_hook_holder);
962 dump_cgraph (dump_file);
964 /* Propagate the local information thru the call graph to produce
965 the global information. All the nodes within a cycle will have
966 the same info so we collapse cycles first. Then we can do the
967 propagation in one pass from the leaves to the roots. */
968 order_pos = ipa_utils_reduced_inorder (order, true, true);
970 ipa_utils_print_order(dump_file, "reduced", order, order_pos);
972 for (i = 0; i < order_pos; i++ )
974 ipa_reference_vars_info_t node_info;
975 ipa_reference_global_vars_info_t node_g =
976 XCNEW (struct ipa_reference_global_vars_info_d);
977 ipa_reference_local_vars_info_t node_l;
981 struct ipa_dfs_info * w_info;
984 node_info = get_reference_vars_info_from_cgraph (node);
987 dump_cgraph_node (stderr, node);
988 dump_cgraph (stderr);
992 node_info->global = node_g;
993 node_l = node_info->local;
995 read_all = node_l->calls_read_all;
996 write_all = node_l->calls_write_all;
998 /* If any node in a cycle is calls_read_all or calls_write_all
1000 w_info = (struct ipa_dfs_info *) node->aux;
1001 w = w_info->next_cycle;
1004 ipa_reference_local_vars_info_t w_l =
1005 get_reference_vars_info_from_cgraph (w)->local;
1006 read_all |= w_l->calls_read_all;
1007 write_all |= w_l->calls_write_all;
1009 w_info = (struct ipa_dfs_info *) w->aux;
1010 w = w_info->next_cycle;
1013 /* Initialized the bitmaps for the reduced nodes */
1015 node_g->statics_read = all_module_statics;
1018 node_g->statics_read = BITMAP_ALLOC (&global_info_obstack);
1019 bitmap_copy (node_g->statics_read,
1020 node_l->statics_read);
1024 node_g->statics_written = all_module_statics;
1027 node_g->statics_written = BITMAP_ALLOC (&global_info_obstack);
1028 bitmap_copy (node_g->statics_written,
1029 node_l->statics_written);
1032 w_info = (struct ipa_dfs_info *) node->aux;
1033 w = w_info->next_cycle;
1036 ipa_reference_vars_info_t w_ri =
1037 get_reference_vars_info_from_cgraph (w);
1038 ipa_reference_local_vars_info_t w_l = w_ri->local;
1040 /* All nodes within a cycle share the same global info bitmaps. */
1041 w_ri->global = node_g;
1043 /* These global bitmaps are initialized from the local info
1044 of all of the nodes in the region. However there is no
1045 need to do any work if the bitmaps were set to
1046 all_module_statics. */
1048 bitmap_ior_into (node_g->statics_read,
1051 bitmap_ior_into (node_g->statics_written,
1052 w_l->statics_written);
1053 w_info = (struct ipa_dfs_info *) w->aux;
1054 w = w_info->next_cycle;
1061 w_info = (struct ipa_dfs_info *) w->aux;
1062 w = w_info->next_cycle;
1066 /* Need to fix up the local information sets. The information that
1067 has been gathered so far is preinlining. However, the
1068 compilation will progress post inlining so the local sets for the
1069 inlined calls need to be merged into the callers. Note that the
1070 local sets are not shared between all of the nodes in a cycle so
1071 those nodes in the cycle must be processed explicitly. */
1072 for (i = 0; i < order_pos; i++ )
1074 struct ipa_dfs_info * w_info;
1076 merge_callee_local_info (node, node);
1078 w_info = (struct ipa_dfs_info *) node->aux;
1079 w = w_info->next_cycle;
1082 merge_callee_local_info (w, w);
1083 w_info = (struct ipa_dfs_info *) w->aux;
1084 w = w_info->next_cycle;
1090 for (i = 0; i < order_pos; i++ )
1092 ipa_reference_vars_info_t node_info;
1093 ipa_reference_global_vars_info_t node_g;
1094 ipa_reference_local_vars_info_t node_l;
1097 struct ipa_dfs_info * w_info;
1100 node_info = get_reference_vars_info_from_cgraph (node);
1101 node_g = node_info->global;
1102 node_l = node_info->local;
1104 "\nFunction name:%s/%i:",
1105 cgraph_node_name (node), node->uid);
1106 fprintf (dump_file, "\n locals read: ");
1107 EXECUTE_IF_SET_IN_BITMAP (node_l->statics_read,
1110 fprintf (dump_file, "%s ",
1111 get_static_name (index));
1113 fprintf (dump_file, "\n locals written: ");
1114 EXECUTE_IF_SET_IN_BITMAP (node_l->statics_written,
1117 fprintf(dump_file, "%s ",
1118 get_static_name (index));
1121 w_info = (struct ipa_dfs_info *) node->aux;
1122 w = w_info->next_cycle;
1125 ipa_reference_vars_info_t w_ri =
1126 get_reference_vars_info_from_cgraph (w);
1127 ipa_reference_local_vars_info_t w_l = w_ri->local;
1128 fprintf (dump_file, "\n next cycle: %s/%i ",
1129 cgraph_node_name (w), w->uid);
1130 fprintf (dump_file, "\n locals read: ");
1131 EXECUTE_IF_SET_IN_BITMAP (w_l->statics_read,
1134 fprintf (dump_file, "%s ",
1135 get_static_name (index));
1138 fprintf (dump_file, "\n locals written: ");
1139 EXECUTE_IF_SET_IN_BITMAP (w_l->statics_written,
1142 fprintf(dump_file, "%s ",
1143 get_static_name (index));
1147 w_info = (struct ipa_dfs_info *) w->aux;
1148 w = w_info->next_cycle;
1150 fprintf (dump_file, "\n globals read: ");
1151 EXECUTE_IF_SET_IN_BITMAP (node_g->statics_read,
1154 fprintf (dump_file, "%s ",
1155 get_static_name (index));
1157 fprintf (dump_file, "\n globals written: ");
1158 EXECUTE_IF_SET_IN_BITMAP (node_g->statics_written,
1161 fprintf (dump_file, "%s ",
1162 get_static_name (index));
1168 for (i = 0; i < order_pos; i++ )
1170 ipa_reference_vars_info_t node_info;
1171 ipa_reference_global_vars_info_t node_g;
1173 node_info = get_reference_vars_info_from_cgraph (node);
1174 node_g = node_info->global;
1176 /* Create the complimentary sets. These are more useful for
1178 node_g->statics_not_read = BITMAP_ALLOC (&global_info_obstack);
1179 node_g->statics_not_written = BITMAP_ALLOC (&global_info_obstack);
1181 if (node_g->statics_read != all_module_statics)
1183 bitmap_and_compl (node_g->statics_not_read,
1185 node_g->statics_read);
1188 if (node_g->statics_written
1189 != all_module_statics)
1190 bitmap_and_compl (node_g->statics_not_written,
1192 node_g->statics_written);
1197 for (node = cgraph_nodes; node; node = node->next)
1199 ipa_reference_vars_info_t node_info;
1200 node_info = get_reference_vars_info_from_cgraph (node);
1201 /* Get rid of the aux information. */
1210 && (cgraph_function_body_availability (node) == AVAIL_OVERWRITABLE))
1211 clean_function (node);
1214 /* Remove local info we no longer need. */
1215 if (node_info->local->statics_read
1216 && node_info->local->statics_read != all_module_statics)
1217 BITMAP_FREE (node_info->local->statics_read);
1218 if (node_info->local->statics_written
1219 && node_info->local->statics_written != all_module_statics)
1220 BITMAP_FREE (node_info->local->statics_written);
1223 bitmap_obstack_release (&local_info_obstack);
1229 gate_reference (void)
1231 return (flag_ipa_reference
1232 /* Don't bother doing anything if the program has errors. */
1233 && !(errorcount || sorrycount));
1236 struct ipa_opt_pass pass_ipa_reference =
1240 "static-var", /* name */
1241 gate_reference, /* gate */
1242 propagate, /* execute */
1245 0, /* static_pass_number */
1246 TV_IPA_REFERENCE, /* tv_id */
1247 0, /* properties_required */
1248 0, /* properties_provided */
1249 0, /* properties_destroyed */
1250 0, /* todo_flags_start */
1251 0 /* todo_flags_finish */
1253 generate_summary, /* generate_summary */
1254 NULL, /* write_summary */
1255 NULL, /* read_summary */
1256 NULL, /* function_read_summary */
1258 NULL, /* function_transform */
1259 NULL /* variable_transform */
1262 #include "gt-ipa-reference.h"