1 /* Callgraph based analysis of static variables.
2 Copyright (C) 2004, 2005, 2007, 2008, 2009, 2010
3 Free Software Foundation, Inc.
4 Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
22 /* This file gathers information about how variables whose scope is
23 confined to the compilation unit are used.
25 The transitive call site specific clobber effects are computed
26 for the variables whose scope is contained within this compilation
29 First each function and static variable initialization is analyzed
30 to determine which local static variables are either read, written,
31 or have their address taken. Any local static that has its address
32 taken is removed from consideration. Once the local read and
33 writes are determined, a transitive closure of this information is
34 performed over the call graph to determine the worst case set of
35 side effects of each call. In later parts of the compiler, these
36 local and global sets are examined to make the call clobbering less
37 traumatic, promote some statics to registers, and improve aliasing
42 #include "coretypes.h"
45 #include "tree-flow.h"
46 #include "tree-inline.h"
47 #include "tree-pass.h"
48 #include "langhooks.h"
49 #include "pointer-set.h"
50 #include "splay-tree.h"
52 #include "ipa-utils.h"
53 #include "ipa-reference.h"
59 #include "diagnostic.h"
60 #include "langhooks.h"
61 #include "lto-streamer.h"
64 static void remove_node_data (struct cgraph_node *node,
65 void *data ATTRIBUTE_UNUSED);
66 static void duplicate_node_data (struct cgraph_node *src,
67 struct cgraph_node *dst,
68 void *data ATTRIBUTE_UNUSED);
70 /* The static variables defined within the compilation unit that are
71 loaded or stored directly by function that owns this structure. */
73 struct ipa_reference_local_vars_info_d
76 bitmap statics_written;
78 /* Set when this function calls another function external to the
79 compilation unit or if the function has a asm clobber of memory.
80 In general, such calls are modeled as reading and writing all
81 variables (both bits on) but sometime there are attributes on the
82 called function so we can do better. */
87 /* Statics that are read and written by some set of functions. The
88 local ones are based on the loads and stores local to the function.
89 The global ones are based on the local info as well as the
90 transitive closure of the functions that are called. */
92 struct ipa_reference_global_vars_info_d
95 bitmap statics_written;
98 /* Information we save about every function after ipa-reference is completted. */
100 struct ipa_reference_optimization_summary_d
102 bitmap statics_not_read;
103 bitmap statics_not_written;
106 typedef struct ipa_reference_local_vars_info_d *ipa_reference_local_vars_info_t;
107 typedef struct ipa_reference_global_vars_info_d *ipa_reference_global_vars_info_t;
108 typedef struct ipa_reference_optimization_summary_d *ipa_reference_optimization_summary_t;
110 struct ipa_reference_vars_info_d
112 struct ipa_reference_local_vars_info_d local;
113 struct ipa_reference_global_vars_info_d global;
116 typedef struct ipa_reference_vars_info_d *ipa_reference_vars_info_t;
118 /* This splay tree contains all of the static variables that are
119 being considered by the compilation level alias analysis. */
120 static splay_tree reference_vars_to_consider;
122 /* A bit is set for every module static we are considering. This is
123 ored into the local info when asm code is found that clobbers all
125 static bitmap all_module_statics;
127 /* Obstack holding bitmaps of local analysis (live from analysis to
129 static bitmap_obstack local_info_obstack;
130 /* Obstack holding global analysis live forever. */
131 static bitmap_obstack optimization_summary_obstack;
133 /* Holders of ipa cgraph hooks: */
134 static struct cgraph_2node_hook_list *node_duplication_hook_holder;
135 static struct cgraph_node_hook_list *node_removal_hook_holder;
137 /* Vector where the reference var infos are actually stored. */
138 DEF_VEC_P (ipa_reference_vars_info_t);
139 DEF_VEC_ALLOC_P (ipa_reference_vars_info_t, heap);
140 static VEC (ipa_reference_vars_info_t, heap) *ipa_reference_vars_vector;
141 DEF_VEC_P (ipa_reference_optimization_summary_t);
142 DEF_VEC_ALLOC_P (ipa_reference_optimization_summary_t, heap);
143 static VEC (ipa_reference_optimization_summary_t, heap) *ipa_reference_opt_sum_vector;
145 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
146 static inline ipa_reference_vars_info_t
147 get_reference_vars_info (struct cgraph_node *node)
149 if (!ipa_reference_vars_vector
150 || VEC_length (ipa_reference_vars_info_t,
151 ipa_reference_vars_vector) <= (unsigned int) node->uid)
153 return VEC_index (ipa_reference_vars_info_t, ipa_reference_vars_vector,
157 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
158 static inline ipa_reference_optimization_summary_t
159 get_reference_optimization_summary (struct cgraph_node *node)
161 if (!ipa_reference_opt_sum_vector
162 || (VEC_length (ipa_reference_optimization_summary_t,
163 ipa_reference_opt_sum_vector)
164 <= (unsigned int) node->uid))
166 return VEC_index (ipa_reference_optimization_summary_t, ipa_reference_opt_sum_vector,
170 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
172 set_reference_vars_info (struct cgraph_node *node,
173 ipa_reference_vars_info_t info)
175 if (!ipa_reference_vars_vector
176 || VEC_length (ipa_reference_vars_info_t,
177 ipa_reference_vars_vector) <= (unsigned int) node->uid)
178 VEC_safe_grow_cleared (ipa_reference_vars_info_t, heap,
179 ipa_reference_vars_vector, node->uid + 1);
180 VEC_replace (ipa_reference_vars_info_t, ipa_reference_vars_vector,
184 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
186 set_reference_optimization_summary (struct cgraph_node *node,
187 ipa_reference_optimization_summary_t info)
189 if (!ipa_reference_opt_sum_vector
190 || (VEC_length (ipa_reference_optimization_summary_t,
191 ipa_reference_opt_sum_vector)
192 <= (unsigned int) node->uid))
193 VEC_safe_grow_cleared (ipa_reference_optimization_summary_t,
194 heap, ipa_reference_opt_sum_vector, node->uid + 1);
195 VEC_replace (ipa_reference_optimization_summary_t,
196 ipa_reference_opt_sum_vector, node->uid, info);
199 /* Return a bitmap indexed by_DECL_UID uid for the static variables
200 that are not read during the execution of the function FN. Returns
201 NULL if no data is available. */
204 ipa_reference_get_not_read_global (struct cgraph_node *fn)
206 ipa_reference_optimization_summary_t info;
208 info = get_reference_optimization_summary (fn);
210 return info->statics_not_read;
215 /* Return a bitmap indexed by DECL_UID uid for the static variables
216 that are not written during the execution of the function FN. Note
217 that variables written may or may not be read during the function
218 call. Returns NULL if no data is available. */
221 ipa_reference_get_not_written_global (struct cgraph_node *fn)
223 ipa_reference_optimization_summary_t info;
225 info = get_reference_optimization_summary (fn);
227 return info->statics_not_written;
234 /* Add VAR to all_module_statics and the two
235 reference_vars_to_consider* sets. */
238 add_static_var (tree var)
240 int uid = DECL_UID (var);
241 gcc_assert (TREE_CODE (var) == VAR_DECL);
242 if (!bitmap_bit_p (all_module_statics, uid))
245 splay_tree_insert (reference_vars_to_consider,
246 uid, (splay_tree_value)var);
247 bitmap_set_bit (all_module_statics, uid);
251 /* Return true if the variable T is the right kind of static variable to
252 perform compilation unit scope escape analysis. */
255 is_proper_for_analysis (tree t)
257 /* We handle only variables whose address is never taken. */
258 if (TREE_ADDRESSABLE (t))
260 /* If the variable has the "used" attribute, treat it as if it had a
261 been touched by the devil. */
262 if (DECL_PRESERVE_P (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 /* We cannot touch decls where the type needs constructing. */
271 if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (t)))
274 /* This is a variable we care about. Check if we have seen it
275 before, and if not add it the set of variables we care about. */
276 if (all_module_statics
277 && !bitmap_bit_p (all_module_statics, DECL_UID (t)))
283 /* Mark tree T as having address taken. */
286 mark_address_taken (tree x)
288 if (TREE_CODE (x) == VAR_DECL
289 && module_statics_escape && has_proper_scope_for_analysis (x))
290 bitmap_set_bit (module_statics_escape, DECL_UID (x));
293 /* Wrapper around mark_address_taken for the stmt walker. */
296 mark_address (gimple stmt ATTRIBUTE_UNUSED, tree addr,
297 void *data ATTRIBUTE_UNUSED)
299 addr = get_base_address (addr);
301 mark_address_taken (addr);
305 /* Mark load of T. */
308 mark_load (gimple stmt ATTRIBUTE_UNUSED, tree t, void *data)
310 ipa_reference_local_vars_info_t local = (ipa_reference_local_vars_info_t)data;
311 t = get_base_address (t);
312 if (t && TREE_CODE (t) == VAR_DECL
313 && has_proper_scope_for_analysis (t))
314 bitmap_set_bit (local->statics_read, DECL_UID (t));
318 /* Mark store of T. */
321 mark_store (gimple stmt ATTRIBUTE_UNUSED, tree t, void *data)
323 ipa_reference_local_vars_info_t local = (ipa_reference_local_vars_info_t)data;
324 t = get_base_address (t);
325 if (t && TREE_CODE (t) == VAR_DECL
326 && has_proper_scope_for_analysis (t))
329 bitmap_set_bit (local->statics_written, DECL_UID (t));
330 /* Mark the write so we can tell which statics are
332 if (module_statics_written)
333 bitmap_set_bit (module_statics_written, DECL_UID (t));
338 /* Look for memory clobber and set read_all/write_all if present. */
341 check_asm_memory_clobber (ipa_reference_local_vars_info_t local, gimple stmt)
346 for (i = 0; i < gimple_asm_nclobbers (stmt); i++)
348 op = gimple_asm_clobber_op (stmt, i);
349 if (simple_cst_equal(TREE_VALUE (op), memory_identifier_string) == 1)
351 /* Abandon all hope, ye who enter here. */
352 local->calls_read_all = true;
353 local->calls_write_all = true;
358 /* Look for external calls and set read_all/write_all correspondingly. */
361 check_call (ipa_reference_local_vars_info_t local, gimple stmt)
363 int flags = gimple_call_flags (stmt);
364 tree callee_t = gimple_call_fndecl (stmt);
366 /* Process indirect calls. All direct calles are handled at propagation
370 if (flags & ECF_CONST)
372 else if (flags & ECF_PURE)
373 local->calls_read_all = true;
376 local->calls_read_all = true;
377 /* When function does not reutrn, it is safe to ignore anythign it writes
378 to, because the effect will never happen. */
379 if ((flags & (ECF_NOTHROW | ECF_NORETURN))
380 != (ECF_NOTHROW | ECF_NORETURN))
381 local->calls_write_all = true;
386 /* TP is the part of the tree currently under the microscope.
387 WALK_SUBTREES is part of the walk_tree api but is unused here.
388 DATA is cgraph_node of the function being walked. */
391 scan_stmt_for_static_refs (gimple_stmt_iterator *gsip,
392 struct cgraph_node *fn)
394 gimple stmt = gsi_stmt (*gsip);
395 ipa_reference_local_vars_info_t local = NULL;
397 if (is_gimple_debug (stmt))
401 local = get_reference_vars_info (fn)->local;
403 /* Look for direct loads and stores. */
404 walk_stmt_load_store_addr_ops (stmt, local, mark_load, mark_store,
407 if (is_gimple_call (stmt))
408 check_call (local, stmt);
409 else if (gimple_code (stmt) == GIMPLE_ASM)
410 check_asm_memory_clobber (local, stmt);
415 /* Call-back to scan variable initializers for static references.
416 Called using walk_tree. */
419 scan_initializer_for_static_refs (tree *tp, int *walk_subtrees,
420 void *data ATTRIBUTE_UNUSED)
424 if (TREE_CODE (t) == ADDR_EXPR)
426 mark_address_taken (get_base_var (t));
429 /* Save some cycles by not walking types and declaration as we
430 won't find anything useful there anyway. */
431 else if (IS_TYPE_OR_DECL_P (*tp))
437 /* Lookup the tree node for the static variable that has UID. */
439 get_static_decl (int index)
441 splay_tree_node stn =
442 splay_tree_lookup (reference_vars_to_consider, index);
444 return (tree)stn->value;
448 /* Lookup the tree node for the static variable that has UID and
449 convert the name to a string for debugging. */
452 get_static_name (int index)
454 splay_tree_node stn =
455 splay_tree_lookup (reference_vars_to_consider, index);
457 return lang_hooks.decl_printable_name ((tree)(stn->value), 2);
461 /* Or in all of the bits from every callee of X into X_GLOBAL, the caller's cycle,
462 bit vector. There are several cases to check to avoid the sparse
466 propagate_bits (ipa_reference_global_vars_info_t x_global, struct cgraph_node *x)
468 struct cgraph_edge *e;
469 for (e = x->callees; e; e = e->next_callee)
471 struct cgraph_node *y = e->callee;
473 /* Only look into nodes we can propagate something. */
474 if (cgraph_function_body_availability (e->callee) > AVAIL_OVERWRITABLE)
476 if (get_reference_vars_info (y))
478 ipa_reference_vars_info_t y_info
479 = get_reference_vars_info (y);
480 ipa_reference_global_vars_info_t y_global = &y_info->global;
482 /* Calls in current cycle do not have global computed yet. */
483 if (!y_global->statics_read)
486 if (x_global->statics_read
487 != all_module_statics)
489 if (y_global->statics_read
490 == all_module_statics)
492 BITMAP_FREE (x_global->statics_read);
493 x_global->statics_read
494 = all_module_statics;
496 /* Skip bitmaps that are pointer equal to node's bitmap
497 (no reason to spin within the cycle). */
498 else if (x_global->statics_read
499 != y_global->statics_read)
500 bitmap_ior_into (x_global->statics_read,
501 y_global->statics_read);
504 if (x_global->statics_written
505 != all_module_statics)
507 if (y_global->statics_written
508 == all_module_statics)
510 BITMAP_FREE (x_global->statics_written);
511 x_global->statics_written
512 = all_module_statics;
514 /* Skip bitmaps that are pointer equal to node's bitmap
515 (no reason to spin within the cycle). */
516 else if (x_global->statics_written
517 != y_global->statics_written)
518 bitmap_ior_into (x_global->statics_written,
519 y_global->statics_written);
528 /* The init routine for analyzing global static variable usage. See
529 comments at top for description. */
533 static bool init_p = false;
541 reference_vars_to_consider = splay_tree_new (splay_tree_compare_ints, 0, 0);
543 bitmap_obstack_initialize (&local_info_obstack);
544 bitmap_obstack_initialize (&optimization_summary_obstack);
545 all_module_statics = BITMAP_ALLOC (&local_info_obstack);
547 node_removal_hook_holder =
548 cgraph_add_node_removal_hook (&remove_node_data, NULL);
549 node_duplication_hook_holder =
550 cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
554 /* Set up the persistent info for FN. */
556 static ipa_reference_local_vars_info_t
557 init_function_info (struct cgraph_node *fn)
559 ipa_reference_vars_info_t info
560 = XCNEW (struct ipa_reference_vars_info_d);
562 /* Add the info to the tree's annotation. */
563 set_reference_vars_info (fn, info);
565 info->local.statics_read = BITMAP_ALLOC (&local_info_obstack);
566 info->local.statics_written = BITMAP_ALLOC (&local_info_obstack);
572 /* This is the main routine for finding the reference patterns for
573 global variables within a function FN. */
576 analyze_function (struct cgraph_node *fn)
578 ipa_reference_local_vars_info_t local;
582 struct cgraph_edge *ie;
584 local = init_function_info (fn);
585 /* Process indirect calls. All direct calles are handled at propagation
587 for (ie = fn->indirect_calls; ie; ie = ie->next_callee)
588 if (!(ie->indirect_info->ecf_flags & ECF_CONST))
590 local->calls_read_all = true;
591 if (!(ie->indirect_info->ecf_flags & ECF_PURE)
592 && ((ie->indirect_info->ecf_flags & (ECF_NOTHROW | ECF_NORETURN))
593 != (ECF_NOTHROW | ECF_NORETURN)))
594 local->calls_write_all = true;
596 for (i = 0; ipa_ref_list_reference_iterate (&fn->ref_list, i, ref); i++)
598 if (ref->refered_type != IPA_REF_VARPOOL)
600 var = ipa_ref_varpool_node (ref)->decl;
601 if (ipa_ref_varpool_node (ref)->externally_visible
602 || !ipa_ref_varpool_node (ref)->analyzed
603 || !is_proper_for_analysis (var))
608 bitmap_set_bit (local->statics_read, DECL_UID (var));
611 bitmap_set_bit (local->statics_written, DECL_UID (var));
618 if ((flags_from_decl_or_type (fn->decl) & (ECF_NOTHROW | ECF_NORETURN))
619 == (ECF_NOTHROW | ECF_NORETURN))
621 local->calls_write_all = false;
622 bitmap_clear (local->statics_written);
625 /* Free bitmaps of direct references if we can not use them anyway. */
626 if (local->calls_write_all)
627 BITMAP_FREE (local->statics_written);
628 if (local->calls_read_all)
629 BITMAP_FREE (local->statics_read);
633 copy_global_bitmap (bitmap src)
638 dst = BITMAP_ALLOC (&optimization_summary_obstack);
639 bitmap_copy (dst, src);
644 /* Called when new clone is inserted to callgraph late. */
647 duplicate_node_data (struct cgraph_node *src, struct cgraph_node *dst,
648 void *data ATTRIBUTE_UNUSED)
650 ipa_reference_optimization_summary_t ginfo;
651 ipa_reference_optimization_summary_t dst_ginfo;
653 ginfo = get_reference_optimization_summary (src);
656 dst_ginfo = XCNEW (struct ipa_reference_optimization_summary_d);
657 set_reference_optimization_summary (dst, dst_ginfo);
658 dst_ginfo->statics_not_read = copy_global_bitmap (ginfo->statics_not_read);
659 dst_ginfo->statics_not_written = copy_global_bitmap (ginfo->statics_not_written);
662 /* Called when node is removed. */
665 remove_node_data (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
667 ipa_reference_optimization_summary_t ginfo;
668 ginfo = get_reference_optimization_summary (node);
671 if (ginfo->statics_not_read
672 && ginfo->statics_not_read != all_module_statics)
673 BITMAP_FREE (ginfo->statics_not_read);
675 if (ginfo->statics_not_written
676 && ginfo->statics_not_written != all_module_statics)
677 BITMAP_FREE (ginfo->statics_not_written);
679 set_reference_optimization_summary (node, NULL);
683 /* Analyze each function in the cgraph to see which global or statics
684 are read or written. */
687 generate_summary (void)
689 struct cgraph_node *node;
695 bm_temp = BITMAP_ALLOC (&local_info_obstack);
697 /* Process all of the functions next. */
698 for (node = cgraph_nodes; node; node = node->next)
700 analyze_function (node);
703 EXECUTE_IF_SET_IN_BITMAP (all_module_statics, 0, index, bi)
705 fprintf (dump_file, "\nPromotable global:%s",
706 get_static_name (index));
709 BITMAP_FREE(bm_temp);
712 for (node = cgraph_nodes; node; node = node->next)
713 if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
715 ipa_reference_local_vars_info_t l;
719 l = &get_reference_vars_info (node)->local;
721 "\nFunction name:%s/%i:",
722 cgraph_node_name (node), node->uid);
723 fprintf (dump_file, "\n locals read: ");
725 EXECUTE_IF_SET_IN_BITMAP (l->statics_read,
728 fprintf (dump_file, "%s ",
729 get_static_name (index));
731 fprintf (dump_file, "\n locals written: ");
732 if (l->statics_written)
733 EXECUTE_IF_SET_IN_BITMAP (l->statics_written,
736 fprintf(dump_file, "%s ",
737 get_static_name (index));
739 if (l->calls_read_all)
740 fprintf (dump_file, "\n calls read all: ");
741 if (l->calls_write_all)
742 fprintf (dump_file, "\n calls read all: ");
746 /* Set READ_ALL/WRITE_ALL based on DECL flags. */
749 read_write_all_from_decl (tree decl, bool * read_all, bool * write_all)
751 int flags = flags_from_decl_or_type (decl);
752 if (flags & ECF_CONST)
754 else if (flags & ECF_PURE)
758 /* TODO: To be able to produce sane results, we should also handle
759 common builtins, in particular throw. */
761 /* When function does not return, it is safe to ignore anythign it writes
762 to, because the effect will never happen. */
763 if ((flags & (ECF_NOTHROW | ECF_NORETURN))
764 != (ECF_NOTHROW | ECF_NORETURN))
769 /* Produce the global information by preforming a transitive closure
770 on the local information that was produced by ipa_analyze_function */
775 struct cgraph_node *node;
776 struct cgraph_node *w;
777 struct cgraph_node **order =
778 XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
779 int order_pos = ipa_utils_reduced_inorder (order, false, true, NULL);
783 dump_cgraph (dump_file);
785 ipa_discover_readonly_nonaddressable_vars ();
788 /* Propagate the local information thru the call graph to produce
789 the global information. All the nodes within a cycle will have
790 the same info so we collapse cycles first. Then we can do the
791 propagation in one pass from the leaves to the roots. */
792 order_pos = ipa_utils_reduced_inorder (order, true, true, NULL);
794 ipa_utils_print_order(dump_file, "reduced", order, order_pos);
796 for (i = 0; i < order_pos; i++ )
798 ipa_reference_vars_info_t node_info;
799 ipa_reference_global_vars_info_t node_g;
800 ipa_reference_local_vars_info_t node_l;
801 struct cgraph_edge *e;
805 struct ipa_dfs_info * w_info;
808 node_info = get_reference_vars_info (node);
811 dump_cgraph_node (stderr, node);
812 dump_cgraph (stderr);
816 node_l = &node_info->local;
817 node_g = &node_info->global;
819 read_all = node_l->calls_read_all;
820 write_all = node_l->calls_write_all;
822 /* When function is overwrittable, we can not assume anything. */
823 if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
824 read_write_all_from_decl (node->decl, &read_all, &write_all);
826 for (e = node->callees; e; e = e->next_callee)
827 if (cgraph_function_body_availability (e->callee) <= AVAIL_OVERWRITABLE)
828 read_write_all_from_decl (e->callee->decl, &read_all, &write_all);
831 /* If any node in a cycle is calls_read_all or calls_write_all
833 w_info = (struct ipa_dfs_info *) node->aux;
834 w = w_info->next_cycle;
837 ipa_reference_local_vars_info_t w_l =
838 &get_reference_vars_info (w)->local;
840 /* When function is overwrittable, we can not assume anything. */
841 if (cgraph_function_body_availability (w) <= AVAIL_OVERWRITABLE)
842 read_write_all_from_decl (w->decl, &read_all, &write_all);
844 for (e = w->callees; e; e = e->next_callee)
845 if (cgraph_function_body_availability (e->callee) <= AVAIL_OVERWRITABLE)
846 read_write_all_from_decl (e->callee->decl, &read_all, &write_all);
848 read_all |= w_l->calls_read_all;
849 write_all |= w_l->calls_write_all;
851 w_info = (struct ipa_dfs_info *) w->aux;
852 w = w_info->next_cycle;
856 /* Initialized the bitmaps for the reduced nodes */
858 node_g->statics_read = all_module_statics;
861 node_g->statics_read = BITMAP_ALLOC (&local_info_obstack);
862 bitmap_copy (node_g->statics_read,
863 node_l->statics_read);
866 node_g->statics_written = all_module_statics;
869 node_g->statics_written = BITMAP_ALLOC (&local_info_obstack);
870 bitmap_copy (node_g->statics_written,
871 node_l->statics_written);
874 propagate_bits (node_g, node);
875 w_info = (struct ipa_dfs_info *) node->aux;
876 w = w_info->next_cycle;
879 ipa_reference_vars_info_t w_ri =
880 get_reference_vars_info (w);
881 ipa_reference_local_vars_info_t w_l = &w_ri->local;
883 /* These global bitmaps are initialized from the local info
884 of all of the nodes in the region. However there is no
885 need to do any work if the bitmaps were set to
886 all_module_statics. */
888 bitmap_ior_into (node_g->statics_read,
891 bitmap_ior_into (node_g->statics_written,
892 w_l->statics_written);
893 propagate_bits (node_g, w);
894 w_info = (struct ipa_dfs_info *) w->aux;
895 w = w_info->next_cycle;
898 /* All nodes within a cycle have the same global info bitmaps. */
899 node_info->global = *node_g;
900 w_info = (struct ipa_dfs_info *) node->aux;
901 w = w_info->next_cycle;
904 ipa_reference_vars_info_t w_ri =
905 get_reference_vars_info (w);
907 w_ri->global = *node_g;
909 w_info = (struct ipa_dfs_info *) w->aux;
910 w = w_info->next_cycle;
916 for (i = 0; i < order_pos; i++ )
918 ipa_reference_vars_info_t node_info;
919 ipa_reference_global_vars_info_t node_g;
920 ipa_reference_local_vars_info_t node_l;
923 struct ipa_dfs_info * w_info;
926 node_info = get_reference_vars_info (node);
927 node_g = &node_info->global;
928 node_l = &node_info->local;
930 "\nFunction name:%s/%i:",
931 cgraph_node_name (node), node->uid);
932 fprintf (dump_file, "\n locals read: ");
933 if (node_l->statics_read)
934 EXECUTE_IF_SET_IN_BITMAP (node_l->statics_read,
937 fprintf (dump_file, "%s ",
938 get_static_name (index));
940 fprintf (dump_file, "\n locals written: ");
941 if (node_l->statics_written)
942 EXECUTE_IF_SET_IN_BITMAP (node_l->statics_written,
945 fprintf(dump_file, "%s ",
946 get_static_name (index));
949 w_info = (struct ipa_dfs_info *) node->aux;
950 w = w_info->next_cycle;
953 ipa_reference_vars_info_t w_ri =
954 get_reference_vars_info (w);
955 ipa_reference_local_vars_info_t w_l = &w_ri->local;
956 fprintf (dump_file, "\n next cycle: %s/%i ",
957 cgraph_node_name (w), w->uid);
958 fprintf (dump_file, "\n locals read: ");
959 if (w_l->statics_read)
960 EXECUTE_IF_SET_IN_BITMAP (w_l->statics_read,
963 fprintf (dump_file, "%s ",
964 get_static_name (index));
967 fprintf (dump_file, "\n locals written: ");
968 if (w_l->statics_written)
969 EXECUTE_IF_SET_IN_BITMAP (w_l->statics_written,
972 fprintf (dump_file, "%s ",
973 get_static_name (index));
976 w_info = (struct ipa_dfs_info *) w->aux;
977 w = w_info->next_cycle;
979 fprintf (dump_file, "\n globals read: ");
980 if (node_g->statics_read == all_module_statics)
981 fprintf (dump_file, "ALL");
983 EXECUTE_IF_SET_IN_BITMAP (node_g->statics_read,
986 fprintf (dump_file, "%s ",
987 get_static_name (index));
989 fprintf (dump_file, "\n globals written: ");
990 if (node_g->statics_written == all_module_statics)
991 fprintf (dump_file, "ALL");
993 EXECUTE_IF_SET_IN_BITMAP (node_g->statics_written,
996 fprintf (dump_file, "%s ",
997 get_static_name (index));
1003 for (node = cgraph_nodes; node; node = node->next)
1005 ipa_reference_vars_info_t node_info;
1006 ipa_reference_global_vars_info_t node_g;
1007 ipa_reference_optimization_summary_t opt;
1009 if (!node->analyzed)
1012 node_info = get_reference_vars_info (node);
1013 if (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE)
1015 node_g = &node_info->global;
1017 opt = XCNEW (struct ipa_reference_optimization_summary_d);
1018 set_reference_optimization_summary (node, opt);
1020 /* Create the complimentary sets. */
1021 opt->statics_not_read = BITMAP_ALLOC (&optimization_summary_obstack);
1022 opt->statics_not_written = BITMAP_ALLOC (&optimization_summary_obstack);
1024 if (node_g->statics_read != all_module_statics)
1025 bitmap_and_compl (opt->statics_not_read,
1027 node_g->statics_read);
1029 if (node_g->statics_written
1030 != all_module_statics)
1031 bitmap_and_compl (opt->statics_not_written,
1033 node_g->statics_written);
1046 bitmap_obstack_release (&local_info_obstack);
1047 VEC_free (ipa_reference_vars_info_t, heap, ipa_reference_vars_vector);
1048 ipa_reference_vars_vector = NULL;
1050 splay_tree_delete (reference_vars_to_consider);
1051 reference_vars_to_consider = NULL;
1052 all_module_statics = NULL;
1056 /* Return true if we need to write summary of NODE. */
1059 write_node_summary_p (struct cgraph_node *node,
1060 cgraph_node_set set,
1061 varpool_node_set vset,
1062 bitmap ltrans_statics)
1064 ipa_reference_optimization_summary_t info;
1066 /* See if we have (non-empty) info. */
1067 if (!node->analyzed || node->global.inlined_to)
1069 info = get_reference_optimization_summary (node);
1070 if (!info || (bitmap_empty_p (info->statics_not_read)
1071 && bitmap_empty_p (info->statics_not_written)))
1074 /* See if we want to encode it.
1075 Encode also referenced functions since constant folding might turn it into
1078 In future we might also want to include summaries of functions references
1079 by initializers of constant variables references in current unit. */
1080 if (!reachable_from_this_partition_p (node, set)
1081 && !referenced_from_this_partition_p (&node->ref_list, set, vset))
1084 /* See if the info has non-empty intersections with vars we want to encode. */
1085 if (!bitmap_intersect_p (info->statics_not_read, ltrans_statics)
1086 && !bitmap_intersect_p (info->statics_not_written, ltrans_statics))
1091 /* Stream out BITS<RANS_STATICS as list of decls to OB. */
1094 stream_out_bitmap (struct lto_simple_output_block *ob,
1095 bitmap bits, bitmap ltrans_statics)
1097 unsigned int count = 0;
1100 EXECUTE_IF_AND_IN_BITMAP (bits, ltrans_statics, 0, index, bi)
1102 lto_output_uleb128_stream (ob->main_stream, count);
1105 EXECUTE_IF_AND_IN_BITMAP (bits, ltrans_statics, 0, index, bi)
1107 tree decl = (tree)splay_tree_lookup (reference_vars_to_consider, index)->value;
1108 lto_output_var_decl_index(ob->decl_state, ob->main_stream, decl);
1112 /* Serialize the ipa info for lto. */
1115 ipa_reference_write_optimization_summary (cgraph_node_set set,
1116 varpool_node_set vset)
1118 struct cgraph_node *node;
1119 struct varpool_node *vnode;
1120 struct lto_simple_output_block *ob
1121 = lto_create_simple_output_block (LTO_section_ipa_reference);
1122 unsigned int count = 0;
1123 lto_cgraph_encoder_t encoder = ob->decl_state->cgraph_node_encoder;
1124 bitmap ltrans_statics = BITMAP_ALLOC (NULL);
1126 reference_vars_to_consider = splay_tree_new (splay_tree_compare_ints, 0, 0);
1128 /* See what variables we are interested in. */
1129 for (vnode = varpool_nodes; vnode; vnode = vnode->next)
1130 if (referenced_from_this_partition_p (&vnode->ref_list, set, vset))
1132 tree decl = vnode->decl;
1133 if (is_proper_for_analysis (decl))
1135 bitmap_set_bit (ltrans_statics, DECL_UID (decl));
1136 splay_tree_insert (reference_vars_to_consider,
1137 DECL_UID (decl), (splay_tree_value)decl);
1141 for (node = cgraph_nodes; node; node = node->next)
1142 if (write_node_summary_p (node, set, vset, ltrans_statics))
1145 lto_output_uleb128_stream (ob->main_stream, count);
1147 /* Process all of the functions. */
1148 for (node = cgraph_nodes; node; node = node->next)
1149 if (write_node_summary_p (node, set, vset, ltrans_statics))
1151 ipa_reference_optimization_summary_t info;
1154 info = get_reference_optimization_summary (node);
1155 node_ref = lto_cgraph_encoder_encode (encoder, node);
1156 lto_output_uleb128_stream (ob->main_stream, node_ref);
1158 stream_out_bitmap (ob, info->statics_not_read, ltrans_statics);
1159 stream_out_bitmap (ob, info->statics_not_written, ltrans_statics);
1161 BITMAP_FREE (ltrans_statics);
1162 lto_destroy_simple_output_block (ob);
1163 splay_tree_delete (reference_vars_to_consider);
1166 /* Deserialize the ipa info for lto. */
1169 ipa_reference_read_optimization_summary (void)
1171 struct lto_file_decl_data ** file_data_vec
1172 = lto_get_file_decl_data ();
1173 struct lto_file_decl_data * file_data;
1175 bitmap_obstack_initialize (&optimization_summary_obstack);
1177 node_removal_hook_holder =
1178 cgraph_add_node_removal_hook (&remove_node_data, NULL);
1179 node_duplication_hook_holder =
1180 cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
1182 while ((file_data = file_data_vec[j++]))
1186 struct lto_input_block *ib
1187 = lto_create_simple_input_block (file_data,
1188 LTO_section_ipa_reference,
1193 unsigned int f_count = lto_input_uleb128 (ib);
1195 for (i = 0; i < f_count; i++)
1197 unsigned int j, index;
1198 struct cgraph_node *node;
1199 ipa_reference_optimization_summary_t info;
1201 lto_cgraph_encoder_t encoder;
1203 index = lto_input_uleb128 (ib);
1204 encoder = file_data->cgraph_node_encoder;
1205 node = lto_cgraph_encoder_deref (encoder, index);
1206 info = XCNEW (struct ipa_reference_optimization_summary_d);
1207 set_reference_optimization_summary (node, info);
1208 info->statics_not_read = BITMAP_ALLOC (&optimization_summary_obstack);
1209 info->statics_not_written = BITMAP_ALLOC (&optimization_summary_obstack);
1212 "\nFunction name:%s/%i:\n static not read:",
1213 cgraph_node_name (node), node->uid);
1215 /* Set the statics not read. */
1216 v_count = lto_input_uleb128 (ib);
1217 for (j = 0; j < (unsigned int)v_count; j++)
1219 unsigned int var_index = lto_input_uleb128 (ib);
1220 tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1222 bitmap_set_bit (info->statics_not_read, DECL_UID (v_decl));
1224 fprintf (dump_file, " %s",
1225 lang_hooks.decl_printable_name (v_decl, 2));
1230 "\n static not written:");
1231 /* Set the statics not written. */
1232 v_count = lto_input_uleb128 (ib);
1233 for (j = 0; j < (unsigned int)v_count; j++)
1235 unsigned int var_index = lto_input_uleb128 (ib);
1236 tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1238 bitmap_set_bit (info->statics_not_written, DECL_UID (v_decl));
1240 fprintf (dump_file, " %s",
1241 lang_hooks.decl_printable_name (v_decl, 2));
1244 fprintf (dump_file, "\n");
1247 lto_destroy_simple_input_block (file_data,
1248 LTO_section_ipa_reference,
1252 /* Fatal error here. We do not want to support compiling ltrans units with
1253 different version of compiler or different flags than the WPA unit, so
1254 this should never happen. */
1255 fatal_error ("ipa reference summary is missing in ltrans unit");
1260 gate_reference (void)
1262 return (flag_ipa_reference
1263 /* Don't bother doing anything if the program has errors. */
1264 && !(errorcount || sorrycount));
1267 struct ipa_opt_pass_d pass_ipa_reference =
1271 "static-var", /* name */
1272 gate_reference, /* gate */
1273 propagate, /* execute */
1276 0, /* static_pass_number */
1277 TV_IPA_REFERENCE, /* tv_id */
1278 0, /* properties_required */
1279 0, /* properties_provided */
1280 0, /* properties_destroyed */
1281 0, /* todo_flags_start */
1282 0 /* todo_flags_finish */
1284 NULL, /* generate_summary */
1285 NULL, /* write_summary */
1286 NULL, /* read_summary */
1287 ipa_reference_write_optimization_summary,/* write_optimization_summary */
1288 ipa_reference_read_optimization_summary,/* read_optimization_summary */
1289 NULL, /* stmt_fixup */
1291 NULL, /* function_transform */
1292 NULL /* variable_transform */