Merged trunk at revision 161680 into branch.
[official-gcc.git] / gcc / ipa-reference.c
blob64ccb4ead27d7359cad4028c711e66c5b7afbfbf
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
11 version.
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
16 for more details.
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
27 unit.
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
38 information. */
40 #include "config.h"
41 #include "system.h"
42 #include "coretypes.h"
43 #include "tm.h"
44 #include "tree.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"
51 #include "ggc.h"
52 #include "ipa-utils.h"
53 #include "ipa-reference.h"
54 #include "gimple.h"
55 #include "cgraph.h"
56 #include "output.h"
57 #include "flags.h"
58 #include "timevar.h"
59 #include "diagnostic.h"
60 #include "langhooks.h"
61 #include "lto-streamer.h"
62 #include "toplev.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
75 bitmap statics_read;
76 bitmap statics_written;
79 /* Statics that are read and written by some set of functions. The
80 local ones are based on the loads and stores local to the function.
81 The global ones are based on the local info as well as the
82 transitive closure of the functions that are called. */
84 struct ipa_reference_global_vars_info_d
86 bitmap statics_read;
87 bitmap statics_written;
90 /* Information we save about every function after ipa-reference is completted. */
92 struct ipa_reference_optimization_summary_d
94 bitmap statics_not_read;
95 bitmap statics_not_written;
98 typedef struct ipa_reference_local_vars_info_d *ipa_reference_local_vars_info_t;
99 typedef struct ipa_reference_global_vars_info_d *ipa_reference_global_vars_info_t;
100 typedef struct ipa_reference_optimization_summary_d *ipa_reference_optimization_summary_t;
102 struct ipa_reference_vars_info_d
104 struct ipa_reference_local_vars_info_d local;
105 struct ipa_reference_global_vars_info_d global;
108 typedef struct ipa_reference_vars_info_d *ipa_reference_vars_info_t;
110 /* This splay tree contains all of the static variables that are
111 being considered by the compilation level alias analysis. */
112 static splay_tree reference_vars_to_consider;
114 /* A bit is set for every module static we are considering. This is
115 ored into the local info when asm code is found that clobbers all
116 memory. */
117 static bitmap all_module_statics;
119 /* Obstack holding bitmaps of local analysis (live from analysis to
120 propagation) */
121 static bitmap_obstack local_info_obstack;
122 /* Obstack holding global analysis live forever. */
123 static bitmap_obstack optimization_summary_obstack;
125 /* Holders of ipa cgraph hooks: */
126 static struct cgraph_2node_hook_list *node_duplication_hook_holder;
127 static struct cgraph_node_hook_list *node_removal_hook_holder;
129 /* Vector where the reference var infos are actually stored. */
130 DEF_VEC_P (ipa_reference_vars_info_t);
131 DEF_VEC_ALLOC_P (ipa_reference_vars_info_t, heap);
132 static VEC (ipa_reference_vars_info_t, heap) *ipa_reference_vars_vector;
133 DEF_VEC_P (ipa_reference_optimization_summary_t);
134 DEF_VEC_ALLOC_P (ipa_reference_optimization_summary_t, heap);
135 static VEC (ipa_reference_optimization_summary_t, heap) *ipa_reference_opt_sum_vector;
137 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
138 static inline ipa_reference_vars_info_t
139 get_reference_vars_info (struct cgraph_node *node)
141 if (!ipa_reference_vars_vector
142 || VEC_length (ipa_reference_vars_info_t,
143 ipa_reference_vars_vector) <= (unsigned int) node->uid)
144 return NULL;
145 return VEC_index (ipa_reference_vars_info_t, ipa_reference_vars_vector,
146 node->uid);
149 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
150 static inline ipa_reference_optimization_summary_t
151 get_reference_optimization_summary (struct cgraph_node *node)
153 if (!ipa_reference_opt_sum_vector
154 || (VEC_length (ipa_reference_optimization_summary_t,
155 ipa_reference_opt_sum_vector)
156 <= (unsigned int) node->uid))
157 return NULL;
158 return VEC_index (ipa_reference_optimization_summary_t, ipa_reference_opt_sum_vector,
159 node->uid);
162 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
163 static inline void
164 set_reference_vars_info (struct cgraph_node *node,
165 ipa_reference_vars_info_t info)
167 if (!ipa_reference_vars_vector
168 || VEC_length (ipa_reference_vars_info_t,
169 ipa_reference_vars_vector) <= (unsigned int) node->uid)
170 VEC_safe_grow_cleared (ipa_reference_vars_info_t, heap,
171 ipa_reference_vars_vector, node->uid + 1);
172 VEC_replace (ipa_reference_vars_info_t, ipa_reference_vars_vector,
173 node->uid, info);
176 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
177 static inline void
178 set_reference_optimization_summary (struct cgraph_node *node,
179 ipa_reference_optimization_summary_t info)
181 if (!ipa_reference_opt_sum_vector
182 || (VEC_length (ipa_reference_optimization_summary_t,
183 ipa_reference_opt_sum_vector)
184 <= (unsigned int) node->uid))
185 VEC_safe_grow_cleared (ipa_reference_optimization_summary_t,
186 heap, ipa_reference_opt_sum_vector, node->uid + 1);
187 VEC_replace (ipa_reference_optimization_summary_t,
188 ipa_reference_opt_sum_vector, node->uid, info);
191 /* Return a bitmap indexed by_DECL_UID uid for the static variables
192 that are not read during the execution of the function FN. Returns
193 NULL if no data is available. */
195 bitmap
196 ipa_reference_get_not_read_global (struct cgraph_node *fn)
198 ipa_reference_optimization_summary_t info;
200 info = get_reference_optimization_summary (fn);
201 if (info)
202 return info->statics_not_read;
203 else
204 return NULL;
207 /* Return a bitmap indexed by DECL_UID uid for the static variables
208 that are not written during the execution of the function FN. Note
209 that variables written may or may not be read during the function
210 call. Returns NULL if no data is available. */
212 bitmap
213 ipa_reference_get_not_written_global (struct cgraph_node *fn)
215 ipa_reference_optimization_summary_t info;
217 info = get_reference_optimization_summary (fn);
218 if (info)
219 return info->statics_not_written;
220 else
221 return NULL;
226 /* Add VAR to all_module_statics and the two
227 reference_vars_to_consider* sets. */
229 static inline void
230 add_static_var (tree var)
232 int uid = DECL_UID (var);
233 gcc_assert (TREE_CODE (var) == VAR_DECL);
234 if (dump_file)
235 splay_tree_insert (reference_vars_to_consider,
236 uid, (splay_tree_value)var);
237 bitmap_set_bit (all_module_statics, uid);
240 /* Return true if the variable T is the right kind of static variable to
241 perform compilation unit scope escape analysis. */
243 static inline bool
244 is_proper_for_analysis (tree t)
246 /* We handle only variables whose address is never taken. */
247 if (TREE_ADDRESSABLE (t))
248 return false;
250 /* If the variable has the "used" attribute, treat it as if it had a
251 been touched by the devil. */
252 if (DECL_PRESERVE_P (t))
253 return false;
255 /* Do not want to do anything with volatile except mark any
256 function that uses one to be not const or pure. */
257 if (TREE_THIS_VOLATILE (t))
258 return false;
260 /* We do not need to analyze readonly vars, we already know they do not
261 alias. */
262 if (TREE_READONLY (t))
263 return false;
265 /* We cannot touch decls where the type needs constructing. */
266 if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (t)))
267 return false;
269 /* This is a variable we care about. Check if we have seen it
270 before, and if not add it the set of variables we care about. */
271 if (all_module_statics
272 && !bitmap_bit_p (all_module_statics, DECL_UID (t)))
273 add_static_var (t);
275 return true;
278 /* Lookup the tree node for the static variable that has UID and
279 convert the name to a string for debugging. */
281 static const char *
282 get_static_name (int index)
284 splay_tree_node stn =
285 splay_tree_lookup (reference_vars_to_consider, index);
286 if (stn)
287 return lang_hooks.decl_printable_name ((tree)(stn->value), 2);
288 return NULL;
291 /* Or in all of the bits from every callee of X into X_GLOBAL, the caller's cycle,
292 bit vector. There are several cases to check to avoid the sparse
293 bitmap oring. */
295 static void
296 propagate_bits (ipa_reference_global_vars_info_t x_global, struct cgraph_node *x)
298 struct cgraph_edge *e;
299 for (e = x->callees; e; e = e->next_callee)
301 struct cgraph_node *y = e->callee;
303 /* Only look into nodes we can propagate something. */
304 if (cgraph_function_body_availability (e->callee) > AVAIL_OVERWRITABLE)
306 int flags = flags_from_decl_or_type (e->callee->decl);
307 if (get_reference_vars_info (y))
309 ipa_reference_vars_info_t y_info
310 = get_reference_vars_info (y);
311 ipa_reference_global_vars_info_t y_global = &y_info->global;
313 /* Calls in current cycle do not have global computed yet. */
314 if (!y_global->statics_read)
315 continue;
317 /* If function is declared const, it reads no memory even if it
318 seems so to local analysis. */
319 if (flags & ECF_CONST)
320 continue;
322 if (x_global->statics_read
323 != all_module_statics)
325 if (y_global->statics_read
326 == all_module_statics)
328 BITMAP_FREE (x_global->statics_read);
329 x_global->statics_read
330 = all_module_statics;
332 /* Skip bitmaps that are pointer equal to node's bitmap
333 (no reason to spin within the cycle). */
334 else if (x_global->statics_read
335 != y_global->statics_read)
336 bitmap_ior_into (x_global->statics_read,
337 y_global->statics_read);
340 /* If function is declared pure, it has no stores even if it
341 seems so to local analysis; If we can not return from here,
342 we can safely ignore the call. */
343 if ((flags & ECF_PURE)
344 || cgraph_edge_cannot_lead_to_return (e))
345 continue;
347 if (x_global->statics_written
348 != all_module_statics)
350 if (y_global->statics_written
351 == all_module_statics)
353 BITMAP_FREE (x_global->statics_written);
354 x_global->statics_written
355 = all_module_statics;
357 /* Skip bitmaps that are pointer equal to node's bitmap
358 (no reason to spin within the cycle). */
359 else if (x_global->statics_written
360 != y_global->statics_written)
361 bitmap_ior_into (x_global->statics_written,
362 y_global->statics_written);
365 else
366 gcc_unreachable ();
371 /* The init routine for analyzing global static variable usage. See
372 comments at top for description. */
373 static void
374 ipa_init (void)
376 static bool init_p = false;
378 if (init_p)
379 return;
381 init_p = true;
383 if (dump_file)
384 reference_vars_to_consider = splay_tree_new (splay_tree_compare_ints, 0, 0);
386 bitmap_obstack_initialize (&local_info_obstack);
387 bitmap_obstack_initialize (&optimization_summary_obstack);
388 all_module_statics = BITMAP_ALLOC (&optimization_summary_obstack);
390 node_removal_hook_holder =
391 cgraph_add_node_removal_hook (&remove_node_data, NULL);
392 node_duplication_hook_holder =
393 cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
397 /* Set up the persistent info for FN. */
399 static ipa_reference_local_vars_info_t
400 init_function_info (struct cgraph_node *fn)
402 ipa_reference_vars_info_t info
403 = XCNEW (struct ipa_reference_vars_info_d);
405 /* Add the info to the tree's annotation. */
406 set_reference_vars_info (fn, info);
408 info->local.statics_read = BITMAP_ALLOC (&local_info_obstack);
409 info->local.statics_written = BITMAP_ALLOC (&local_info_obstack);
411 return &info->local;
415 /* This is the main routine for finding the reference patterns for
416 global variables within a function FN. */
418 static void
419 analyze_function (struct cgraph_node *fn)
421 ipa_reference_local_vars_info_t local;
422 struct ipa_ref *ref;
423 int i;
424 tree var;
426 local = init_function_info (fn);
427 for (i = 0; ipa_ref_list_reference_iterate (&fn->ref_list, i, ref); i++)
429 if (ref->refered_type != IPA_REF_VARPOOL)
430 continue;
431 var = ipa_ref_varpool_node (ref)->decl;
432 if (ipa_ref_varpool_node (ref)->externally_visible
433 || !ipa_ref_varpool_node (ref)->analyzed
434 || !is_proper_for_analysis (var))
435 continue;
436 switch (ref->use)
438 case IPA_REF_LOAD:
439 bitmap_set_bit (local->statics_read, DECL_UID (var));
440 break;
441 case IPA_REF_STORE:
442 if (ipa_ref_cannot_lead_to_return (ref))
443 break;
444 bitmap_set_bit (local->statics_written, DECL_UID (var));
445 break;
446 case IPA_REF_ADDR:
447 gcc_unreachable ();
448 break;
452 if (cgraph_node_cannot_return (fn))
453 bitmap_clear (local->statics_written);
456 static bitmap
457 copy_global_bitmap (bitmap src)
459 bitmap dst;
460 if (!src)
461 return NULL;
462 if (src == all_module_statics)
463 return all_module_statics;
464 dst = BITMAP_ALLOC (&optimization_summary_obstack);
465 bitmap_copy (dst, src);
466 return dst;
470 /* Called when new clone is inserted to callgraph late. */
472 static void
473 duplicate_node_data (struct cgraph_node *src, struct cgraph_node *dst,
474 void *data ATTRIBUTE_UNUSED)
476 ipa_reference_optimization_summary_t ginfo;
477 ipa_reference_optimization_summary_t dst_ginfo;
479 ginfo = get_reference_optimization_summary (src);
480 if (!ginfo)
481 return;
482 dst_ginfo = XCNEW (struct ipa_reference_optimization_summary_d);
483 set_reference_optimization_summary (dst, dst_ginfo);
484 dst_ginfo->statics_not_read = copy_global_bitmap (ginfo->statics_not_read);
485 dst_ginfo->statics_not_written = copy_global_bitmap (ginfo->statics_not_written);
488 /* Called when node is removed. */
490 static void
491 remove_node_data (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
493 ipa_reference_optimization_summary_t ginfo;
494 ginfo = get_reference_optimization_summary (node);
495 if (ginfo)
497 if (ginfo->statics_not_read
498 && ginfo->statics_not_read != all_module_statics)
499 BITMAP_FREE (ginfo->statics_not_read);
501 if (ginfo->statics_not_written
502 && ginfo->statics_not_written != all_module_statics)
503 BITMAP_FREE (ginfo->statics_not_written);
504 free (ginfo);
505 set_reference_optimization_summary (node, NULL);
509 /* Analyze each function in the cgraph to see which global or statics
510 are read or written. */
512 static void
513 generate_summary (void)
515 struct cgraph_node *node;
516 unsigned int index;
517 bitmap_iterator bi;
518 bitmap bm_temp;
520 ipa_init ();
521 bm_temp = BITMAP_ALLOC (&local_info_obstack);
523 /* Process all of the functions next. */
524 for (node = cgraph_nodes; node; node = node->next)
525 if (node->analyzed)
526 analyze_function (node);
528 if (dump_file)
529 EXECUTE_IF_SET_IN_BITMAP (all_module_statics, 0, index, bi)
531 fprintf (dump_file, "\nPromotable global:%s",
532 get_static_name (index));
535 BITMAP_FREE(bm_temp);
537 if (dump_file)
538 for (node = cgraph_nodes; node; node = node->next)
539 if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
541 ipa_reference_local_vars_info_t l;
542 unsigned int index;
543 bitmap_iterator bi;
545 l = &get_reference_vars_info (node)->local;
546 fprintf (dump_file,
547 "\nFunction name:%s/%i:",
548 cgraph_node_name (node), node->uid);
549 fprintf (dump_file, "\n locals read: ");
550 if (l->statics_read)
551 EXECUTE_IF_SET_IN_BITMAP (l->statics_read,
552 0, index, bi)
554 fprintf (dump_file, "%s ",
555 get_static_name (index));
557 fprintf (dump_file, "\n locals written: ");
558 if (l->statics_written)
559 EXECUTE_IF_SET_IN_BITMAP (l->statics_written,
560 0, index, bi)
562 fprintf(dump_file, "%s ",
563 get_static_name (index));
568 /* Set READ_ALL/WRITE_ALL based on decl flags of NODE. */
570 static void
571 read_write_all_from_decl (struct cgraph_node *node, bool * read_all,
572 bool * write_all)
574 tree decl = node->decl;
575 int flags = flags_from_decl_or_type (decl);
576 if (flags & ECF_CONST)
578 else if ((flags & ECF_PURE)
579 || cgraph_node_cannot_return (node))
580 *read_all = true;
581 else
583 /* TODO: To be able to produce sane results, we should also handle
584 common builtins, in particular throw. */
585 *read_all = true;
586 *write_all = true;
590 /* Produce the global information by preforming a transitive closure
591 on the local information that was produced by ipa_analyze_function */
593 static unsigned int
594 propagate (void)
596 struct cgraph_node *node;
597 struct cgraph_node *w;
598 struct cgraph_node **order =
599 XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
600 int order_pos = ipa_utils_reduced_inorder (order, false, true, NULL);
601 int i;
603 if (dump_file)
604 dump_cgraph (dump_file);
606 ipa_discover_readonly_nonaddressable_vars ();
607 generate_summary ();
609 /* Propagate the local information thru the call graph to produce
610 the global information. All the nodes within a cycle will have
611 the same info so we collapse cycles first. Then we can do the
612 propagation in one pass from the leaves to the roots. */
613 order_pos = ipa_utils_reduced_inorder (order, true, true, NULL);
614 if (dump_file)
615 ipa_utils_print_order(dump_file, "reduced", order, order_pos);
617 for (i = 0; i < order_pos; i++ )
619 ipa_reference_vars_info_t node_info;
620 ipa_reference_global_vars_info_t node_g;
621 ipa_reference_local_vars_info_t node_l;
622 struct cgraph_edge *e, *ie;
624 bool read_all;
625 bool write_all;
626 struct ipa_dfs_info * w_info;
628 node = order[i];
629 node_info = get_reference_vars_info (node);
630 gcc_assert (node_info);
632 node_l = &node_info->local;
633 node_g = &node_info->global;
635 read_all = false;
636 write_all = false;
638 /* When function is overwrittable, we can not assume anything. */
639 if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
640 read_write_all_from_decl (node, &read_all, &write_all);
642 for (e = node->callees; e; e = e->next_callee)
643 if (cgraph_function_body_availability (e->callee) <= AVAIL_OVERWRITABLE)
644 read_write_all_from_decl (e->callee, &read_all, &write_all);
646 for (ie = node->indirect_calls; ie; ie = ie->next_callee)
647 if (!(ie->indirect_info->ecf_flags & ECF_CONST))
649 read_all = true;
650 if (!cgraph_edge_cannot_lead_to_return (ie)
651 && !(ie->indirect_info->ecf_flags & ECF_PURE))
652 write_all = true;
656 /* If any node in a cycle is read_all or write_all
657 they all are. */
658 w_info = (struct ipa_dfs_info *) node->aux;
659 w = w_info->next_cycle;
660 while (w && (!read_all || !write_all))
662 /* When function is overwrittable, we can not assume anything. */
663 if (cgraph_function_body_availability (w) <= AVAIL_OVERWRITABLE)
664 read_write_all_from_decl (w, &read_all, &write_all);
666 for (e = w->callees; e; e = e->next_callee)
667 if (cgraph_function_body_availability (e->callee) <= AVAIL_OVERWRITABLE)
668 read_write_all_from_decl (e->callee, &read_all, &write_all);
670 for (ie = w->indirect_calls; ie; ie = ie->next_callee)
671 if (!(ie->indirect_info->ecf_flags & ECF_CONST))
673 read_all = true;
674 if (!cgraph_edge_cannot_lead_to_return (ie)
675 && !(ie->indirect_info->ecf_flags & ECF_PURE))
676 write_all = true;
679 w_info = (struct ipa_dfs_info *) w->aux;
680 w = w_info->next_cycle;
684 /* Initialized the bitmaps for the reduced nodes */
685 if (read_all)
686 node_g->statics_read = all_module_statics;
687 else
689 node_g->statics_read = BITMAP_ALLOC (&local_info_obstack);
690 bitmap_copy (node_g->statics_read,
691 node_l->statics_read);
693 if (write_all)
694 node_g->statics_written = all_module_statics;
695 else
697 node_g->statics_written = BITMAP_ALLOC (&local_info_obstack);
698 bitmap_copy (node_g->statics_written,
699 node_l->statics_written);
702 propagate_bits (node_g, node);
703 w_info = (struct ipa_dfs_info *) node->aux;
704 w = w_info->next_cycle;
705 while (w && (!read_all || !write_all))
707 ipa_reference_vars_info_t w_ri =
708 get_reference_vars_info (w);
709 ipa_reference_local_vars_info_t w_l = &w_ri->local;
710 int flags = flags_from_decl_or_type (w->decl);
712 /* These global bitmaps are initialized from the local info
713 of all of the nodes in the region. However there is no
714 need to do any work if the bitmaps were set to
715 all_module_statics. */
716 if (!read_all && !(flags & ECF_CONST))
717 bitmap_ior_into (node_g->statics_read,
718 w_l->statics_read);
719 if (!write_all
720 && !(flags & ECF_PURE)
721 && !cgraph_node_cannot_return (w))
722 bitmap_ior_into (node_g->statics_written,
723 w_l->statics_written);
724 propagate_bits (node_g, w);
725 w_info = (struct ipa_dfs_info *) w->aux;
726 w = w_info->next_cycle;
729 /* All nodes within a cycle have the same global info bitmaps. */
730 node_info->global = *node_g;
731 w_info = (struct ipa_dfs_info *) node->aux;
732 w = w_info->next_cycle;
733 while (w)
735 ipa_reference_vars_info_t w_ri =
736 get_reference_vars_info (w);
738 w_ri->global = *node_g;
740 w_info = (struct ipa_dfs_info *) w->aux;
741 w = w_info->next_cycle;
745 if (dump_file)
747 for (i = 0; i < order_pos; i++ )
749 ipa_reference_vars_info_t node_info;
750 ipa_reference_global_vars_info_t node_g;
751 ipa_reference_local_vars_info_t node_l;
752 unsigned int index;
753 bitmap_iterator bi;
754 struct ipa_dfs_info * w_info;
756 node = order[i];
757 node_info = get_reference_vars_info (node);
758 node_g = &node_info->global;
759 node_l = &node_info->local;
760 fprintf (dump_file,
761 "\nFunction name:%s/%i:",
762 cgraph_node_name (node), node->uid);
763 fprintf (dump_file, "\n locals read: ");
764 if (node_l->statics_read)
765 EXECUTE_IF_SET_IN_BITMAP (node_l->statics_read,
766 0, index, bi)
768 fprintf (dump_file, "%s ",
769 get_static_name (index));
771 fprintf (dump_file, "\n locals written: ");
772 if (node_l->statics_written)
773 EXECUTE_IF_SET_IN_BITMAP (node_l->statics_written,
774 0, index, bi)
776 fprintf(dump_file, "%s ",
777 get_static_name (index));
780 w_info = (struct ipa_dfs_info *) node->aux;
781 w = w_info->next_cycle;
782 while (w)
784 ipa_reference_vars_info_t w_ri =
785 get_reference_vars_info (w);
786 ipa_reference_local_vars_info_t w_l = &w_ri->local;
787 fprintf (dump_file, "\n next cycle: %s/%i ",
788 cgraph_node_name (w), w->uid);
789 fprintf (dump_file, "\n locals read: ");
790 if (w_l->statics_read)
791 EXECUTE_IF_SET_IN_BITMAP (w_l->statics_read,
792 0, index, bi)
794 fprintf (dump_file, "%s ",
795 get_static_name (index));
798 fprintf (dump_file, "\n locals written: ");
799 if (w_l->statics_written)
800 EXECUTE_IF_SET_IN_BITMAP (w_l->statics_written,
801 0, index, bi)
803 fprintf (dump_file, "%s ",
804 get_static_name (index));
807 w_info = (struct ipa_dfs_info *) w->aux;
808 w = w_info->next_cycle;
810 fprintf (dump_file, "\n globals read: ");
811 if (node_g->statics_read == all_module_statics)
812 fprintf (dump_file, "ALL");
813 else
814 EXECUTE_IF_SET_IN_BITMAP (node_g->statics_read,
815 0, index, bi)
817 fprintf (dump_file, "%s ",
818 get_static_name (index));
820 fprintf (dump_file, "\n globals written: ");
821 if (node_g->statics_written == all_module_statics)
822 fprintf (dump_file, "ALL");
823 else
824 EXECUTE_IF_SET_IN_BITMAP (node_g->statics_written,
825 0, index, bi)
827 fprintf (dump_file, "%s ",
828 get_static_name (index));
833 /* Cleanup. */
834 for (node = cgraph_nodes; node; node = node->next)
836 ipa_reference_vars_info_t node_info;
837 ipa_reference_global_vars_info_t node_g;
838 ipa_reference_optimization_summary_t opt;
840 if (!node->analyzed)
841 continue;
843 node_info = get_reference_vars_info (node);
844 if (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE)
846 node_g = &node_info->global;
848 opt = XCNEW (struct ipa_reference_optimization_summary_d);
849 set_reference_optimization_summary (node, opt);
851 /* Create the complimentary sets. */
853 if (bitmap_empty_p (node_g->statics_read))
854 opt->statics_not_read = all_module_statics;
855 else
857 opt->statics_not_read
858 = BITMAP_ALLOC (&optimization_summary_obstack);
859 if (node_g->statics_read != all_module_statics)
860 bitmap_and_compl (opt->statics_not_read,
861 all_module_statics,
862 node_g->statics_read);
865 if (bitmap_empty_p (node_g->statics_written))
866 opt->statics_not_written = all_module_statics;
867 else
869 opt->statics_not_written
870 = BITMAP_ALLOC (&optimization_summary_obstack);
871 if (node_g->statics_written != all_module_statics)
872 bitmap_and_compl (opt->statics_not_written,
873 all_module_statics,
874 node_g->statics_written);
877 if (node_info)
878 free (node_info);
879 if (node->aux)
881 free (node->aux);
882 node->aux = NULL;
886 free (order);
888 bitmap_obstack_release (&local_info_obstack);
889 VEC_free (ipa_reference_vars_info_t, heap, ipa_reference_vars_vector);
890 ipa_reference_vars_vector = NULL;
891 if (dump_file)
892 splay_tree_delete (reference_vars_to_consider);
893 reference_vars_to_consider = NULL;
894 return 0;
897 /* Return true if we need to write summary of NODE. */
899 static bool
900 write_node_summary_p (struct cgraph_node *node,
901 cgraph_node_set set,
902 varpool_node_set vset,
903 bitmap ltrans_statics)
905 ipa_reference_optimization_summary_t info;
907 /* See if we have (non-empty) info. */
908 if (!node->analyzed || node->global.inlined_to)
909 return false;
910 info = get_reference_optimization_summary (node);
911 if (!info || (bitmap_empty_p (info->statics_not_read)
912 && bitmap_empty_p (info->statics_not_written)))
913 return false;
915 /* See if we want to encode it.
916 Encode also referenced functions since constant folding might turn it into
917 a direct call.
919 In future we might also want to include summaries of functions references
920 by initializers of constant variables references in current unit. */
921 if (!reachable_from_this_partition_p (node, set)
922 && !referenced_from_this_partition_p (&node->ref_list, set, vset))
923 return false;
925 /* See if the info has non-empty intersections with vars we want to encode. */
926 if (!bitmap_intersect_p (info->statics_not_read, ltrans_statics)
927 && !bitmap_intersect_p (info->statics_not_written, ltrans_statics))
928 return false;
929 return true;
932 /* Stream out BITS&LTRANS_STATICS as list of decls to OB.
933 LTRANS_STATICS_BITCOUNT specify number of bits in LTRANS_STATICS
934 or -1. When it is positive, just output -1 when
935 BITS&LTRANS_STATICS == BITS&LTRANS_STATICS. */
937 static void
938 stream_out_bitmap (struct lto_simple_output_block *ob,
939 bitmap bits, bitmap ltrans_statics,
940 int ltrans_statics_bitcount)
942 int count = 0;
943 unsigned int index;
944 bitmap_iterator bi;
945 if (bits == all_module_statics)
947 lto_output_sleb128_stream (ob->main_stream, -1);
948 return;
950 EXECUTE_IF_AND_IN_BITMAP (bits, ltrans_statics, 0, index, bi)
951 count ++;
952 if (count == ltrans_statics_bitcount)
954 lto_output_sleb128_stream (ob->main_stream, -1);
955 return;
957 lto_output_sleb128_stream (ob->main_stream, count);
958 if (!count)
959 return;
960 EXECUTE_IF_AND_IN_BITMAP (bits, ltrans_statics, 0, index, bi)
962 tree decl = (tree)splay_tree_lookup (reference_vars_to_consider, index)->value;
963 lto_output_var_decl_index(ob->decl_state, ob->main_stream, decl);
967 /* Serialize the ipa info for lto. */
969 static void
970 ipa_reference_write_optimization_summary (cgraph_node_set set,
971 varpool_node_set vset)
973 struct cgraph_node *node;
974 struct lto_simple_output_block *ob
975 = lto_create_simple_output_block (LTO_section_ipa_reference);
976 unsigned int count = 0;
977 int ltrans_statics_bitcount = 0;
978 lto_cgraph_encoder_t encoder = ob->decl_state->cgraph_node_encoder;
979 lto_varpool_encoder_t varpool_encoder = ob->decl_state->varpool_node_encoder;
980 bitmap ltrans_statics = BITMAP_ALLOC (NULL);
981 int i;
983 reference_vars_to_consider = splay_tree_new (splay_tree_compare_ints, 0, 0);
985 /* See what variables we are interested in. */
986 for (i = 0; i < lto_varpool_encoder_size (varpool_encoder); i++)
988 struct varpool_node *vnode = lto_varpool_encoder_deref (varpool_encoder, i);
989 if (!vnode->externally_visible
990 && vnode->analyzed
991 && bitmap_bit_p (all_module_statics, DECL_UID (vnode->decl))
992 && referenced_from_this_partition_p (&vnode->ref_list, set, vset))
994 tree decl = vnode->decl;
995 bitmap_set_bit (ltrans_statics, DECL_UID (decl));
996 splay_tree_insert (reference_vars_to_consider,
997 DECL_UID (decl), (splay_tree_value)decl);
998 ltrans_statics_bitcount ++;
1003 if (ltrans_statics_bitcount)
1004 for (i = 0; i < lto_cgraph_encoder_size (encoder); i++)
1005 if (write_node_summary_p (lto_cgraph_encoder_deref (encoder, i),
1006 set, vset, ltrans_statics))
1007 count++;
1009 lto_output_uleb128_stream (ob->main_stream, count);
1010 if (count)
1011 stream_out_bitmap (ob, ltrans_statics, ltrans_statics,
1012 -1);
1014 /* Process all of the functions. */
1015 if (ltrans_statics_bitcount)
1016 for (i = 0; i < lto_cgraph_encoder_size (encoder); i++)
1018 node = lto_cgraph_encoder_deref (encoder, i);
1019 if (write_node_summary_p (node, set, vset, ltrans_statics))
1021 ipa_reference_optimization_summary_t info;
1022 int node_ref;
1024 info = get_reference_optimization_summary (node);
1025 node_ref = lto_cgraph_encoder_encode (encoder, node);
1026 lto_output_uleb128_stream (ob->main_stream, node_ref);
1028 stream_out_bitmap (ob, info->statics_not_read, ltrans_statics,
1029 ltrans_statics_bitcount);
1030 stream_out_bitmap (ob, info->statics_not_written, ltrans_statics,
1031 ltrans_statics_bitcount);
1034 BITMAP_FREE (ltrans_statics);
1035 lto_destroy_simple_output_block (ob);
1036 splay_tree_delete (reference_vars_to_consider);
1039 /* Deserialize the ipa info for lto. */
1041 static void
1042 ipa_reference_read_optimization_summary (void)
1044 struct lto_file_decl_data ** file_data_vec
1045 = lto_get_file_decl_data ();
1046 struct lto_file_decl_data * file_data;
1047 unsigned int j = 0;
1048 bitmap_obstack_initialize (&optimization_summary_obstack);
1050 node_removal_hook_holder =
1051 cgraph_add_node_removal_hook (&remove_node_data, NULL);
1052 node_duplication_hook_holder =
1053 cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
1054 all_module_statics = BITMAP_ALLOC (&optimization_summary_obstack);
1056 while ((file_data = file_data_vec[j++]))
1058 const char *data;
1059 size_t len;
1060 struct lto_input_block *ib
1061 = lto_create_simple_input_block (file_data,
1062 LTO_section_ipa_reference,
1063 &data, &len);
1064 if (ib)
1066 unsigned int i;
1067 unsigned int f_count = lto_input_uleb128 (ib);
1068 int b_count;
1069 if (!f_count)
1070 continue;
1071 b_count = lto_input_sleb128 (ib);
1072 if (dump_file)
1073 fprintf (dump_file, "all module statics:");
1074 for (i = 0; i < (unsigned int)b_count; i++)
1076 unsigned int var_index = lto_input_uleb128 (ib);
1077 tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1078 var_index);
1079 bitmap_set_bit (all_module_statics, DECL_UID (v_decl));
1080 if (dump_file)
1081 fprintf (dump_file, " %s",
1082 lang_hooks.decl_printable_name (v_decl, 2));
1085 for (i = 0; i < f_count; i++)
1087 unsigned int j, index;
1088 struct cgraph_node *node;
1089 ipa_reference_optimization_summary_t info;
1090 int v_count;
1091 lto_cgraph_encoder_t encoder;
1093 index = lto_input_uleb128 (ib);
1094 encoder = file_data->cgraph_node_encoder;
1095 node = lto_cgraph_encoder_deref (encoder, index);
1096 info = XCNEW (struct ipa_reference_optimization_summary_d);
1097 set_reference_optimization_summary (node, info);
1098 info->statics_not_read = BITMAP_ALLOC (&optimization_summary_obstack);
1099 info->statics_not_written = BITMAP_ALLOC (&optimization_summary_obstack);
1100 if (dump_file)
1101 fprintf (dump_file,
1102 "\nFunction name:%s/%i:\n static not read:",
1103 cgraph_node_name (node), node->uid);
1105 /* Set the statics not read. */
1106 v_count = lto_input_sleb128 (ib);
1107 if (v_count == -1)
1109 info->statics_not_read = all_module_statics;
1110 if (dump_file)
1111 fprintf (dump_file, " all module statics");
1113 else
1114 for (j = 0; j < (unsigned int)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 bitmap_set_bit (info->statics_not_read, DECL_UID (v_decl));
1120 if (dump_file)
1121 fprintf (dump_file, " %s",
1122 lang_hooks.decl_printable_name (v_decl, 2));
1125 if (dump_file)
1126 fprintf (dump_file,
1127 "\n static not written:");
1128 /* Set the statics not written. */
1129 v_count = lto_input_sleb128 (ib);
1130 if (v_count == -1)
1132 info->statics_not_written = all_module_statics;
1133 if (dump_file)
1134 fprintf (dump_file, " all module statics");
1136 else
1137 for (j = 0; j < (unsigned int)v_count; j++)
1139 unsigned int var_index = lto_input_uleb128 (ib);
1140 tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1141 var_index);
1142 bitmap_set_bit (info->statics_not_written, DECL_UID (v_decl));
1143 if (dump_file)
1144 fprintf (dump_file, " %s",
1145 lang_hooks.decl_printable_name (v_decl, 2));
1147 if (dump_file)
1148 fprintf (dump_file, "\n");
1151 lto_destroy_simple_input_block (file_data,
1152 LTO_section_ipa_reference,
1153 ib, data, len);
1155 else
1156 /* Fatal error here. We do not want to support compiling ltrans units with
1157 different version of compiler or different flags than the WPA unit, so
1158 this should never happen. */
1159 fatal_error ("ipa reference summary is missing in ltrans unit");
1163 static bool
1164 gate_reference (void)
1166 return (flag_ipa_reference
1167 /* Don't bother doing anything if the program has errors. */
1168 && !seen_error ());
1171 struct ipa_opt_pass_d pass_ipa_reference =
1174 IPA_PASS,
1175 "static-var", /* name */
1176 gate_reference, /* gate */
1177 propagate, /* execute */
1178 NULL, /* sub */
1179 NULL, /* next */
1180 0, /* static_pass_number */
1181 TV_IPA_REFERENCE, /* tv_id */
1182 0, /* properties_required */
1183 0, /* properties_provided */
1184 0, /* properties_destroyed */
1185 0, /* todo_flags_start */
1186 0 /* todo_flags_finish */
1188 NULL, /* generate_summary */
1189 NULL, /* write_summary */
1190 NULL, /* read_summary */
1191 ipa_reference_write_optimization_summary,/* write_optimization_summary */
1192 ipa_reference_read_optimization_summary,/* read_optimization_summary */
1193 NULL, /* stmt_fixup */
1194 0, /* TODOs */
1195 NULL, /* function_transform */
1196 NULL /* variable_transform */