2012-09-04 Janus Weil <janus@gcc.gnu.org>
[official-gcc.git] / gcc / ipa-reference.c
blob0d2ef287576b9b2feaf820b671d0940e6489e5f5
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 "flags.h"
57 #include "diagnostic.h"
58 #include "langhooks.h"
59 #include "data-streamer.h"
60 #include "lto-streamer.h"
62 static void remove_node_data (struct cgraph_node *node,
63 void *data ATTRIBUTE_UNUSED);
64 static void duplicate_node_data (struct cgraph_node *src,
65 struct cgraph_node *dst,
66 void *data ATTRIBUTE_UNUSED);
68 /* The static variables defined within the compilation unit that are
69 loaded or stored directly by function that owns this structure. */
71 struct ipa_reference_local_vars_info_d
73 bitmap statics_read;
74 bitmap statics_written;
77 /* Statics that are read and written by some set of functions. The
78 local ones are based on the loads and stores local to the function.
79 The global ones are based on the local info as well as the
80 transitive closure of the functions that are called. */
82 struct ipa_reference_global_vars_info_d
84 bitmap statics_read;
85 bitmap statics_written;
88 /* Information we save about every function after ipa-reference is completed. */
90 struct ipa_reference_optimization_summary_d
92 bitmap statics_not_read;
93 bitmap statics_not_written;
96 typedef struct ipa_reference_local_vars_info_d *ipa_reference_local_vars_info_t;
97 typedef struct ipa_reference_global_vars_info_d *ipa_reference_global_vars_info_t;
98 typedef struct ipa_reference_optimization_summary_d *ipa_reference_optimization_summary_t;
100 struct ipa_reference_vars_info_d
102 struct ipa_reference_local_vars_info_d local;
103 struct ipa_reference_global_vars_info_d global;
106 typedef struct ipa_reference_vars_info_d *ipa_reference_vars_info_t;
108 /* This splay tree contains all of the static variables that are
109 being considered by the compilation level alias analysis. */
110 static splay_tree reference_vars_to_consider;
112 /* A bit is set for every module static we are considering. This is
113 ored into the local info when asm code is found that clobbers all
114 memory. */
115 static bitmap all_module_statics;
117 /* Obstack holding bitmaps of local analysis (live from analysis to
118 propagation) */
119 static bitmap_obstack local_info_obstack;
120 /* Obstack holding global analysis live forever. */
121 static bitmap_obstack optimization_summary_obstack;
123 /* Holders of ipa cgraph hooks: */
124 static struct cgraph_2node_hook_list *node_duplication_hook_holder;
125 static struct cgraph_node_hook_list *node_removal_hook_holder;
127 /* Vector where the reference var infos are actually stored. */
128 DEF_VEC_P (ipa_reference_vars_info_t);
129 DEF_VEC_ALLOC_P (ipa_reference_vars_info_t, heap);
130 static VEC (ipa_reference_vars_info_t, heap) *ipa_reference_vars_vector;
131 DEF_VEC_P (ipa_reference_optimization_summary_t);
132 DEF_VEC_ALLOC_P (ipa_reference_optimization_summary_t, heap);
133 static VEC (ipa_reference_optimization_summary_t, heap) *ipa_reference_opt_sum_vector;
135 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
136 static inline ipa_reference_vars_info_t
137 get_reference_vars_info (struct cgraph_node *node)
139 if (!ipa_reference_vars_vector
140 || VEC_length (ipa_reference_vars_info_t,
141 ipa_reference_vars_vector) <= (unsigned int) node->uid)
142 return NULL;
143 return VEC_index (ipa_reference_vars_info_t, ipa_reference_vars_vector,
144 node->uid);
147 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
148 static inline ipa_reference_optimization_summary_t
149 get_reference_optimization_summary (struct cgraph_node *node)
151 if (!ipa_reference_opt_sum_vector
152 || (VEC_length (ipa_reference_optimization_summary_t,
153 ipa_reference_opt_sum_vector)
154 <= (unsigned int) node->uid))
155 return NULL;
156 return VEC_index (ipa_reference_optimization_summary_t, ipa_reference_opt_sum_vector,
157 node->uid);
160 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
161 static inline void
162 set_reference_vars_info (struct cgraph_node *node,
163 ipa_reference_vars_info_t info)
165 if (!ipa_reference_vars_vector
166 || VEC_length (ipa_reference_vars_info_t,
167 ipa_reference_vars_vector) <= (unsigned int) node->uid)
168 VEC_safe_grow_cleared (ipa_reference_vars_info_t, heap,
169 ipa_reference_vars_vector, node->uid + 1);
170 VEC_replace (ipa_reference_vars_info_t, ipa_reference_vars_vector,
171 node->uid, info);
174 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
175 static inline void
176 set_reference_optimization_summary (struct cgraph_node *node,
177 ipa_reference_optimization_summary_t info)
179 if (!ipa_reference_opt_sum_vector
180 || (VEC_length (ipa_reference_optimization_summary_t,
181 ipa_reference_opt_sum_vector)
182 <= (unsigned int) node->uid))
183 VEC_safe_grow_cleared (ipa_reference_optimization_summary_t,
184 heap, ipa_reference_opt_sum_vector, node->uid + 1);
185 VEC_replace (ipa_reference_optimization_summary_t,
186 ipa_reference_opt_sum_vector, node->uid, info);
189 /* Return a bitmap indexed by_DECL_UID uid for the static variables
190 that are not read during the execution of the function FN. Returns
191 NULL if no data is available. */
193 bitmap
194 ipa_reference_get_not_read_global (struct cgraph_node *fn)
196 ipa_reference_optimization_summary_t info;
198 info = get_reference_optimization_summary (cgraph_function_node (fn, NULL));
199 if (info)
200 return info->statics_not_read;
201 else if (flags_from_decl_or_type (fn->symbol.decl) & ECF_LEAF)
202 return all_module_statics;
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 if (flags_from_decl_or_type (fn->symbol.decl) & ECF_LEAF)
221 return all_module_statics;
222 else
223 return NULL;
228 /* Add VAR to all_module_statics and the two
229 reference_vars_to_consider* sets. */
231 static inline void
232 add_static_var (tree var)
234 int uid = DECL_UID (var);
235 gcc_assert (TREE_CODE (var) == VAR_DECL);
236 if (dump_file)
237 splay_tree_insert (reference_vars_to_consider,
238 uid, (splay_tree_value)var);
239 bitmap_set_bit (all_module_statics, uid);
242 /* Return true if the variable T is the right kind of static variable to
243 perform compilation unit scope escape analysis. */
245 static inline bool
246 is_proper_for_analysis (tree t)
248 /* If the variable has the "used" attribute, treat it as if it had a
249 been touched by the devil. */
250 if (DECL_PRESERVE_P (t))
251 return false;
253 /* Do not want to do anything with volatile except mark any
254 function that uses one to be not const or pure. */
255 if (TREE_THIS_VOLATILE (t))
256 return false;
258 /* We do not need to analyze readonly vars, we already know they do not
259 alias. */
260 if (TREE_READONLY (t))
261 return false;
263 /* This is a variable we care about. Check if we have seen it
264 before, and if not add it the set of variables we care about. */
265 if (all_module_statics
266 && !bitmap_bit_p (all_module_statics, DECL_UID (t)))
267 add_static_var (t);
269 return true;
272 /* Lookup the tree node for the static variable that has UID and
273 convert the name to a string for debugging. */
275 static const char *
276 get_static_name (int index)
278 splay_tree_node stn =
279 splay_tree_lookup (reference_vars_to_consider, index);
280 if (stn)
281 return lang_hooks.decl_printable_name ((tree)(stn->value), 2);
282 return NULL;
285 /* Or in all of the bits from every callee of X into X_GLOBAL, the caller's cycle,
286 bit vector. There are several cases to check to avoid the sparse
287 bitmap oring. */
289 static void
290 propagate_bits (ipa_reference_global_vars_info_t x_global, struct cgraph_node *x)
292 struct cgraph_edge *e;
293 for (e = x->callees; e; e = e->next_callee)
295 enum availability avail;
296 struct cgraph_node *y = cgraph_function_node (e->callee, &avail);
298 if (!y)
299 continue;
300 /* Only look into nodes we can propagate something. */
301 if (avail > AVAIL_OVERWRITABLE
302 || (avail == AVAIL_OVERWRITABLE
303 && (flags_from_decl_or_type (y->symbol.decl) & ECF_LEAF)))
305 int flags = flags_from_decl_or_type (y->symbol.decl);
306 if (get_reference_vars_info (y))
308 ipa_reference_vars_info_t y_info
309 = get_reference_vars_info (y);
310 ipa_reference_global_vars_info_t y_global = &y_info->global;
312 /* Calls in current cycle do not have global computed yet. */
313 if (!y_global->statics_read)
314 continue;
316 /* If function is declared const, it reads no memory even if it
317 seems so to local analysis. */
318 if (flags & ECF_CONST)
319 continue;
321 if (x_global->statics_read
322 != all_module_statics)
324 if (y_global->statics_read
325 == all_module_statics)
327 BITMAP_FREE (x_global->statics_read);
328 x_global->statics_read
329 = all_module_statics;
331 /* Skip bitmaps that are pointer equal to node's bitmap
332 (no reason to spin within the cycle). */
333 else if (x_global->statics_read
334 != y_global->statics_read)
335 bitmap_ior_into (x_global->statics_read,
336 y_global->statics_read);
339 /* If function is declared pure, it has no stores even if it
340 seems so to local analysis; If we can not return from here,
341 we can safely ignore the call. */
342 if ((flags & ECF_PURE)
343 || cgraph_edge_cannot_lead_to_return (e))
344 continue;
346 if (x_global->statics_written
347 != all_module_statics)
349 if (y_global->statics_written
350 == all_module_statics)
352 BITMAP_FREE (x_global->statics_written);
353 x_global->statics_written
354 = all_module_statics;
356 /* Skip bitmaps that are pointer equal to node's bitmap
357 (no reason to spin within the cycle). */
358 else if (x_global->statics_written
359 != y_global->statics_written)
360 bitmap_ior_into (x_global->statics_written,
361 y_global->statics_written);
364 else
365 gcc_unreachable ();
370 /* The init routine for analyzing global static variable usage. See
371 comments at top for description. */
372 static void
373 ipa_init (void)
375 static bool init_p = false;
377 if (init_p)
378 return;
380 init_p = true;
382 if (dump_file)
383 reference_vars_to_consider = splay_tree_new (splay_tree_compare_ints, 0, 0);
385 bitmap_obstack_initialize (&local_info_obstack);
386 bitmap_obstack_initialize (&optimization_summary_obstack);
387 all_module_statics = BITMAP_ALLOC (&optimization_summary_obstack);
389 node_removal_hook_holder =
390 cgraph_add_node_removal_hook (&remove_node_data, NULL);
391 node_duplication_hook_holder =
392 cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
396 /* Set up the persistent info for FN. */
398 static ipa_reference_local_vars_info_t
399 init_function_info (struct cgraph_node *fn)
401 ipa_reference_vars_info_t info
402 = XCNEW (struct ipa_reference_vars_info_d);
404 /* Add the info to the tree's annotation. */
405 set_reference_vars_info (fn, info);
407 info->local.statics_read = BITMAP_ALLOC (&local_info_obstack);
408 info->local.statics_written = BITMAP_ALLOC (&local_info_obstack);
410 return &info->local;
414 /* This is the main routine for finding the reference patterns for
415 global variables within a function FN. */
417 static void
418 analyze_function (struct cgraph_node *fn)
420 ipa_reference_local_vars_info_t local;
421 struct ipa_ref *ref;
422 int i;
423 tree var;
425 local = init_function_info (fn);
426 for (i = 0; ipa_ref_list_reference_iterate (&fn->symbol.ref_list, i, ref); i++)
428 if (!symtab_variable_p (ref->referred))
429 continue;
430 var = ipa_ref_varpool_node (ref)->symbol.decl;
431 if (!is_proper_for_analysis (var))
432 continue;
433 switch (ref->use)
435 case IPA_REF_LOAD:
436 bitmap_set_bit (local->statics_read, DECL_UID (var));
437 break;
438 case IPA_REF_STORE:
439 if (ipa_ref_cannot_lead_to_return (ref))
440 break;
441 bitmap_set_bit (local->statics_written, DECL_UID (var));
442 break;
443 case IPA_REF_ADDR:
444 break;
448 if (cgraph_node_cannot_return (fn))
449 bitmap_clear (local->statics_written);
452 static bitmap
453 copy_global_bitmap (bitmap src)
455 bitmap dst;
456 if (!src)
457 return NULL;
458 if (src == all_module_statics)
459 return all_module_statics;
460 dst = BITMAP_ALLOC (&optimization_summary_obstack);
461 bitmap_copy (dst, src);
462 return dst;
466 /* Called when new clone is inserted to callgraph late. */
468 static void
469 duplicate_node_data (struct cgraph_node *src, struct cgraph_node *dst,
470 void *data ATTRIBUTE_UNUSED)
472 ipa_reference_optimization_summary_t ginfo;
473 ipa_reference_optimization_summary_t dst_ginfo;
475 ginfo = get_reference_optimization_summary (src);
476 if (!ginfo)
477 return;
478 dst_ginfo = XCNEW (struct ipa_reference_optimization_summary_d);
479 set_reference_optimization_summary (dst, dst_ginfo);
480 dst_ginfo->statics_not_read = copy_global_bitmap (ginfo->statics_not_read);
481 dst_ginfo->statics_not_written = copy_global_bitmap (ginfo->statics_not_written);
484 /* Called when node is removed. */
486 static void
487 remove_node_data (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
489 ipa_reference_optimization_summary_t ginfo;
490 ginfo = get_reference_optimization_summary (node);
491 if (ginfo)
493 if (ginfo->statics_not_read
494 && ginfo->statics_not_read != all_module_statics)
495 BITMAP_FREE (ginfo->statics_not_read);
497 if (ginfo->statics_not_written
498 && ginfo->statics_not_written != all_module_statics)
499 BITMAP_FREE (ginfo->statics_not_written);
500 free (ginfo);
501 set_reference_optimization_summary (node, NULL);
505 /* Analyze each function in the cgraph to see which global or statics
506 are read or written. */
508 static void
509 generate_summary (void)
511 struct cgraph_node *node;
512 unsigned int index;
513 bitmap_iterator bi;
514 bitmap bm_temp;
516 ipa_init ();
517 bm_temp = BITMAP_ALLOC (&local_info_obstack);
519 /* Process all of the functions next. */
520 FOR_EACH_DEFINED_FUNCTION (node)
521 analyze_function (node);
523 if (dump_file)
524 EXECUTE_IF_SET_IN_BITMAP (all_module_statics, 0, index, bi)
526 fprintf (dump_file, "\nPromotable global:%s",
527 get_static_name (index));
530 BITMAP_FREE(bm_temp);
532 if (dump_file)
533 FOR_EACH_DEFINED_FUNCTION (node)
534 if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
536 ipa_reference_local_vars_info_t l;
537 unsigned int index;
538 bitmap_iterator bi;
540 l = &get_reference_vars_info (node)->local;
541 fprintf (dump_file,
542 "\nFunction name:%s/%i:",
543 cgraph_node_asm_name (node), node->symbol.order);
544 fprintf (dump_file, "\n locals read: ");
545 if (l->statics_read)
546 EXECUTE_IF_SET_IN_BITMAP (l->statics_read,
547 0, index, bi)
549 fprintf (dump_file, "%s ",
550 get_static_name (index));
552 fprintf (dump_file, "\n locals written: ");
553 if (l->statics_written)
554 EXECUTE_IF_SET_IN_BITMAP (l->statics_written,
555 0, index, bi)
557 fprintf(dump_file, "%s ",
558 get_static_name (index));
563 /* Set READ_ALL/WRITE_ALL based on decl flags of NODE. */
565 static void
566 read_write_all_from_decl (struct cgraph_node *node, bool * read_all,
567 bool * write_all)
569 tree decl = node->symbol.decl;
570 int flags = flags_from_decl_or_type (decl);
571 if ((flags & ECF_LEAF)
572 && cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
574 else if (flags & ECF_CONST)
576 else if ((flags & ECF_PURE)
577 || cgraph_node_cannot_return (node))
579 *read_all = true;
580 if (dump_file && (dump_flags & TDF_DETAILS))
581 fprintf (dump_file, " %s/%i -> read all\n",
582 cgraph_node_asm_name (node), node->symbol.order);
584 else
586 /* TODO: To be able to produce sane results, we should also handle
587 common builtins, in particular throw. */
588 *read_all = true;
589 *write_all = true;
590 if (dump_file && (dump_flags & TDF_DETAILS))
591 fprintf (dump_file, " %s/%i -> read all, write all\n",
592 cgraph_node_asm_name (node), node->symbol.order);
596 /* Produce the global information by preforming a transitive closure
597 on the local information that was produced by ipa_analyze_function */
599 static unsigned int
600 propagate (void)
602 struct cgraph_node *node;
603 struct varpool_node *vnode;
604 struct cgraph_node *w;
605 struct cgraph_node **order =
606 XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
607 int order_pos;
608 int i;
610 if (dump_file)
611 dump_cgraph (dump_file);
613 ipa_discover_readonly_nonaddressable_vars ();
614 generate_summary ();
616 /* Now we know what vars are really statics; prune out those that aren't. */
617 FOR_EACH_VARIABLE (vnode)
618 if (vnode->symbol.externally_visible
619 || TREE_ADDRESSABLE (vnode->symbol.decl)
620 || TREE_READONLY (vnode->symbol.decl)
621 || !is_proper_for_analysis (vnode->symbol.decl)
622 || !vnode->analyzed)
623 bitmap_clear_bit (all_module_statics, DECL_UID (vnode->symbol.decl));
625 /* Forget info we collected "just for fun" on variables that turned out to be
626 non-local. */
627 FOR_EACH_DEFINED_FUNCTION (node)
629 ipa_reference_local_vars_info_t node_l;
631 node_l = &get_reference_vars_info (node)->local;
632 if (node_l->statics_read != all_module_statics)
633 bitmap_and_into (node_l->statics_read, all_module_statics);
634 if (node_l->statics_written != all_module_statics)
635 bitmap_and_into (node_l->statics_written, all_module_statics);
638 /* Propagate the local information through the call graph to produce
639 the global information. All the nodes within a cycle will have
640 the same info so we collapse cycles first. Then we can do the
641 propagation in one pass from the leaves to the roots. */
642 order_pos = ipa_reduced_postorder (order, true, true, NULL);
643 if (dump_file)
644 ipa_print_order (dump_file, "reduced", order, order_pos);
646 for (i = 0; i < order_pos; i++ )
648 ipa_reference_vars_info_t node_info;
649 ipa_reference_global_vars_info_t node_g;
650 ipa_reference_local_vars_info_t node_l;
651 struct cgraph_edge *e, *ie;
653 bool read_all;
654 bool write_all;
655 struct ipa_dfs_info * w_info;
657 node = order[i];
658 if (node->alias)
659 continue;
660 node_info = get_reference_vars_info (node);
661 gcc_assert (node_info);
664 if (dump_file && (dump_flags & TDF_DETAILS))
665 fprintf (dump_file, "Starting cycle with %s/%i\n",
666 cgraph_node_asm_name (node), node->symbol.order);
668 node_l = &node_info->local;
669 node_g = &node_info->global;
671 read_all = false;
672 write_all = false;
674 /* When function is overwritable, we can not assume anything. */
675 if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
676 read_write_all_from_decl (node, &read_all, &write_all);
678 for (e = node->callees; e; e = e->next_callee)
680 enum availability avail;
681 struct cgraph_node *callee = cgraph_function_node (e->callee, &avail);
682 if (!callee || avail <= AVAIL_OVERWRITABLE)
683 read_write_all_from_decl (callee, &read_all, &write_all);
686 for (ie = node->indirect_calls; ie; ie = ie->next_callee)
687 if (!(ie->indirect_info->ecf_flags & ECF_CONST))
689 read_all = true;
690 if (dump_file && (dump_flags & TDF_DETAILS))
691 fprintf (dump_file, " indirect call -> read all\n");
692 if (!cgraph_edge_cannot_lead_to_return (ie)
693 && !(ie->indirect_info->ecf_flags & ECF_PURE))
695 if (dump_file && (dump_flags & TDF_DETAILS))
696 fprintf (dump_file, " indirect call -> write all\n");
697 write_all = true;
702 /* If any node in a cycle is read_all or write_all
703 they all are. */
704 w_info = (struct ipa_dfs_info *) node->symbol.aux;
705 w = w_info->next_cycle;
706 while (w && (!read_all || !write_all))
708 if (dump_file && (dump_flags & TDF_DETAILS))
709 fprintf (dump_file, " Visiting %s/%i\n",
710 cgraph_node_asm_name (w), w->symbol.order);
711 /* When function is overwritable, we can not assume anything. */
712 if (cgraph_function_body_availability (w) <= AVAIL_OVERWRITABLE)
713 read_write_all_from_decl (w, &read_all, &write_all);
715 for (e = w->callees; e; e = e->next_callee)
717 enum availability avail;
718 struct cgraph_node *callee = cgraph_function_node (e->callee, &avail);
720 if (avail <= AVAIL_OVERWRITABLE)
721 read_write_all_from_decl (callee, &read_all, &write_all);
724 for (ie = w->indirect_calls; ie; ie = ie->next_callee)
725 if (!(ie->indirect_info->ecf_flags & ECF_CONST))
727 read_all = true;
728 if (dump_file && (dump_flags & TDF_DETAILS))
729 fprintf (dump_file, " indirect call -> read all\n");
730 if (!cgraph_edge_cannot_lead_to_return (ie)
731 && !(ie->indirect_info->ecf_flags & ECF_PURE))
733 write_all = true;
734 if (dump_file && (dump_flags & TDF_DETAILS))
735 fprintf (dump_file, " indirect call -> write all\n");
739 w_info = (struct ipa_dfs_info *) w->symbol.aux;
740 w = w_info->next_cycle;
744 /* Initialized the bitmaps for the reduced nodes */
745 if (read_all)
746 node_g->statics_read = all_module_statics;
747 else
749 node_g->statics_read = BITMAP_ALLOC (&local_info_obstack);
750 bitmap_copy (node_g->statics_read,
751 node_l->statics_read);
753 if (write_all)
754 node_g->statics_written = all_module_statics;
755 else
757 node_g->statics_written = BITMAP_ALLOC (&local_info_obstack);
758 bitmap_copy (node_g->statics_written,
759 node_l->statics_written);
762 propagate_bits (node_g, node);
763 w_info = (struct ipa_dfs_info *) node->symbol.aux;
764 w = w_info->next_cycle;
765 while (w && (!read_all || !write_all))
767 ipa_reference_vars_info_t w_ri =
768 get_reference_vars_info (w);
769 ipa_reference_local_vars_info_t w_l = &w_ri->local;
770 int flags = flags_from_decl_or_type (w->symbol.decl);
772 /* These global bitmaps are initialized from the local info
773 of all of the nodes in the region. However there is no
774 need to do any work if the bitmaps were set to
775 all_module_statics. */
776 if (!read_all && !(flags & ECF_CONST))
777 bitmap_ior_into (node_g->statics_read,
778 w_l->statics_read);
779 if (!write_all
780 && !(flags & ECF_PURE)
781 && !cgraph_node_cannot_return (w))
782 bitmap_ior_into (node_g->statics_written,
783 w_l->statics_written);
784 propagate_bits (node_g, w);
785 w_info = (struct ipa_dfs_info *) w->symbol.aux;
786 w = w_info->next_cycle;
789 /* All nodes within a cycle have the same global info bitmaps. */
790 node_info->global = *node_g;
791 w_info = (struct ipa_dfs_info *) node->symbol.aux;
792 w = w_info->next_cycle;
793 while (w)
795 ipa_reference_vars_info_t w_ri =
796 get_reference_vars_info (w);
798 w_ri->global = *node_g;
800 w_info = (struct ipa_dfs_info *) w->symbol.aux;
801 w = w_info->next_cycle;
805 if (dump_file)
807 for (i = 0; i < order_pos; i++ )
809 ipa_reference_vars_info_t node_info;
810 ipa_reference_global_vars_info_t node_g;
811 ipa_reference_local_vars_info_t node_l;
812 unsigned int index;
813 bitmap_iterator bi;
814 struct ipa_dfs_info * w_info;
816 node = order[i];
817 if (node->alias)
818 continue;
819 node_info = get_reference_vars_info (node);
820 node_g = &node_info->global;
821 node_l = &node_info->local;
822 fprintf (dump_file,
823 "\nFunction name:%s/%i:",
824 cgraph_node_asm_name (node), node->symbol.order);
825 fprintf (dump_file, "\n locals read: ");
826 if (node_l->statics_read)
827 EXECUTE_IF_SET_IN_BITMAP (node_l->statics_read,
828 0, index, bi)
830 fprintf (dump_file, "%s ",
831 get_static_name (index));
833 fprintf (dump_file, "\n locals written: ");
834 if (node_l->statics_written)
835 EXECUTE_IF_SET_IN_BITMAP (node_l->statics_written,
836 0, index, bi)
838 fprintf(dump_file, "%s ",
839 get_static_name (index));
842 w_info = (struct ipa_dfs_info *) node->symbol.aux;
843 w = w_info->next_cycle;
844 while (w)
846 ipa_reference_vars_info_t w_ri =
847 get_reference_vars_info (w);
848 ipa_reference_local_vars_info_t w_l = &w_ri->local;
849 fprintf (dump_file, "\n next cycle: %s/%i ",
850 cgraph_node_asm_name (w), w->symbol.order);
851 fprintf (dump_file, "\n locals read: ");
852 if (w_l->statics_read)
853 EXECUTE_IF_SET_IN_BITMAP (w_l->statics_read,
854 0, index, bi)
856 fprintf (dump_file, "%s ",
857 get_static_name (index));
860 fprintf (dump_file, "\n locals written: ");
861 if (w_l->statics_written)
862 EXECUTE_IF_SET_IN_BITMAP (w_l->statics_written,
863 0, index, bi)
865 fprintf (dump_file, "%s ",
866 get_static_name (index));
869 w_info = (struct ipa_dfs_info *) w->symbol.aux;
870 w = w_info->next_cycle;
872 fprintf (dump_file, "\n globals read: ");
873 if (node_g->statics_read == all_module_statics)
874 fprintf (dump_file, "ALL");
875 else
876 EXECUTE_IF_SET_IN_BITMAP (node_g->statics_read,
877 0, index, bi)
879 fprintf (dump_file, "%s ",
880 get_static_name (index));
882 fprintf (dump_file, "\n globals written: ");
883 if (node_g->statics_written == all_module_statics)
884 fprintf (dump_file, "ALL");
885 else
886 EXECUTE_IF_SET_IN_BITMAP (node_g->statics_written,
887 0, index, bi)
889 fprintf (dump_file, "%s ",
890 get_static_name (index));
895 /* Cleanup. */
896 FOR_EACH_DEFINED_FUNCTION (node)
898 ipa_reference_vars_info_t node_info;
899 ipa_reference_global_vars_info_t node_g;
900 ipa_reference_optimization_summary_t opt;
902 if (node->alias)
903 continue;
905 node_info = get_reference_vars_info (node);
906 if (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE
907 || (flags_from_decl_or_type (node->symbol.decl) & ECF_LEAF))
909 node_g = &node_info->global;
911 opt = XCNEW (struct ipa_reference_optimization_summary_d);
912 set_reference_optimization_summary (node, opt);
914 /* Create the complimentary sets. */
916 if (bitmap_empty_p (node_g->statics_read))
917 opt->statics_not_read = all_module_statics;
918 else
920 opt->statics_not_read
921 = BITMAP_ALLOC (&optimization_summary_obstack);
922 if (node_g->statics_read != all_module_statics)
923 bitmap_and_compl (opt->statics_not_read,
924 all_module_statics,
925 node_g->statics_read);
928 if (bitmap_empty_p (node_g->statics_written))
929 opt->statics_not_written = all_module_statics;
930 else
932 opt->statics_not_written
933 = BITMAP_ALLOC (&optimization_summary_obstack);
934 if (node_g->statics_written != all_module_statics)
935 bitmap_and_compl (opt->statics_not_written,
936 all_module_statics,
937 node_g->statics_written);
940 free (node_info);
943 ipa_free_postorder_info ();
944 free (order);
946 bitmap_obstack_release (&local_info_obstack);
947 VEC_free (ipa_reference_vars_info_t, heap, ipa_reference_vars_vector);
948 ipa_reference_vars_vector = NULL;
949 if (dump_file)
950 splay_tree_delete (reference_vars_to_consider);
951 reference_vars_to_consider = NULL;
952 return 0;
955 /* Return true if we need to write summary of NODE. */
957 static bool
958 write_node_summary_p (struct cgraph_node *node,
959 lto_symtab_encoder_t encoder,
960 bitmap ltrans_statics)
962 ipa_reference_optimization_summary_t info;
964 /* See if we have (non-empty) info. */
965 if (!node->analyzed || node->global.inlined_to)
966 return false;
967 info = get_reference_optimization_summary (node);
968 if (!info || (bitmap_empty_p (info->statics_not_read)
969 && bitmap_empty_p (info->statics_not_written)))
970 return false;
972 /* See if we want to encode it.
973 Encode also referenced functions since constant folding might turn it into
974 a direct call.
976 In future we might also want to include summaries of functions references
977 by initializers of constant variables references in current unit. */
978 if (!reachable_from_this_partition_p (node, encoder)
979 && !referenced_from_this_partition_p (&node->symbol.ref_list, encoder))
980 return false;
982 /* See if the info has non-empty intersections with vars we want to encode. */
983 if (!bitmap_intersect_p (info->statics_not_read, ltrans_statics)
984 && !bitmap_intersect_p (info->statics_not_written, ltrans_statics))
985 return false;
986 return true;
989 /* Stream out BITS&LTRANS_STATICS as list of decls to OB.
990 LTRANS_STATICS_BITCOUNT specify number of bits in LTRANS_STATICS
991 or -1. When it is positive, just output -1 when
992 BITS&LTRANS_STATICS == BITS&LTRANS_STATICS. */
994 static void
995 stream_out_bitmap (struct lto_simple_output_block *ob,
996 bitmap bits, bitmap ltrans_statics,
997 int ltrans_statics_bitcount)
999 int count = 0;
1000 unsigned int index;
1001 bitmap_iterator bi;
1002 if (bits == all_module_statics)
1004 streamer_write_hwi_stream (ob->main_stream, -1);
1005 return;
1007 EXECUTE_IF_AND_IN_BITMAP (bits, ltrans_statics, 0, index, bi)
1008 count ++;
1009 if (count == ltrans_statics_bitcount)
1011 streamer_write_hwi_stream (ob->main_stream, -1);
1012 return;
1014 streamer_write_hwi_stream (ob->main_stream, count);
1015 if (!count)
1016 return;
1017 EXECUTE_IF_AND_IN_BITMAP (bits, ltrans_statics, 0, index, bi)
1019 tree decl = (tree)splay_tree_lookup (reference_vars_to_consider, index)->value;
1020 lto_output_var_decl_index(ob->decl_state, ob->main_stream, decl);
1024 /* Serialize the ipa info for lto. */
1026 static void
1027 ipa_reference_write_optimization_summary (void)
1029 struct cgraph_node *node;
1030 symtab_node snode;
1031 struct lto_simple_output_block *ob
1032 = lto_create_simple_output_block (LTO_section_ipa_reference);
1033 unsigned int count = 0;
1034 int ltrans_statics_bitcount = 0;
1035 lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
1036 bitmap ltrans_statics = BITMAP_ALLOC (NULL);
1037 int i;
1039 reference_vars_to_consider = splay_tree_new (splay_tree_compare_ints, 0, 0);
1041 /* See what variables we are interested in. */
1042 for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
1044 struct varpool_node *vnode;
1045 snode = lto_symtab_encoder_deref (encoder, i);
1046 if (!symtab_variable_p (snode))
1047 continue;
1048 vnode = varpool (snode);
1049 if (bitmap_bit_p (all_module_statics, DECL_UID (vnode->symbol.decl))
1050 && referenced_from_this_partition_p (&vnode->symbol.ref_list, encoder))
1052 tree decl = vnode->symbol.decl;
1053 bitmap_set_bit (ltrans_statics, DECL_UID (decl));
1054 splay_tree_insert (reference_vars_to_consider,
1055 DECL_UID (decl), (splay_tree_value)decl);
1056 ltrans_statics_bitcount ++;
1061 if (ltrans_statics_bitcount)
1062 for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
1063 if (symtab_function_p (snode = lto_symtab_encoder_deref (encoder, i))
1064 && write_node_summary_p (cgraph (snode),
1065 encoder, ltrans_statics))
1066 count++;
1068 streamer_write_uhwi_stream (ob->main_stream, count);
1069 if (count)
1070 stream_out_bitmap (ob, ltrans_statics, ltrans_statics,
1071 -1);
1073 /* Process all of the functions. */
1074 if (ltrans_statics_bitcount)
1075 for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
1077 snode = lto_symtab_encoder_deref (encoder, i);
1078 if (!symtab_function_p (snode))
1079 continue;
1080 node = cgraph (snode);
1081 if (write_node_summary_p (node, encoder, ltrans_statics))
1083 ipa_reference_optimization_summary_t info;
1084 int node_ref;
1086 info = get_reference_optimization_summary (node);
1087 node_ref = lto_symtab_encoder_encode (encoder, (symtab_node) node);
1088 streamer_write_uhwi_stream (ob->main_stream, node_ref);
1090 stream_out_bitmap (ob, info->statics_not_read, ltrans_statics,
1091 ltrans_statics_bitcount);
1092 stream_out_bitmap (ob, info->statics_not_written, ltrans_statics,
1093 ltrans_statics_bitcount);
1096 BITMAP_FREE (ltrans_statics);
1097 lto_destroy_simple_output_block (ob);
1098 splay_tree_delete (reference_vars_to_consider);
1101 /* Deserialize the ipa info for lto. */
1103 static void
1104 ipa_reference_read_optimization_summary (void)
1106 struct lto_file_decl_data ** file_data_vec
1107 = lto_get_file_decl_data ();
1108 struct lto_file_decl_data * file_data;
1109 unsigned int j = 0;
1110 bitmap_obstack_initialize (&optimization_summary_obstack);
1112 node_removal_hook_holder =
1113 cgraph_add_node_removal_hook (&remove_node_data, NULL);
1114 node_duplication_hook_holder =
1115 cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
1116 all_module_statics = BITMAP_ALLOC (&optimization_summary_obstack);
1118 while ((file_data = file_data_vec[j++]))
1120 const char *data;
1121 size_t len;
1122 struct lto_input_block *ib
1123 = lto_create_simple_input_block (file_data,
1124 LTO_section_ipa_reference,
1125 &data, &len);
1126 if (ib)
1128 unsigned int i;
1129 unsigned int f_count = streamer_read_uhwi (ib);
1130 int b_count;
1131 if (!f_count)
1132 continue;
1133 b_count = streamer_read_hwi (ib);
1134 if (dump_file)
1135 fprintf (dump_file, "all module statics:");
1136 for (i = 0; i < (unsigned int)b_count; i++)
1138 unsigned int var_index = streamer_read_uhwi (ib);
1139 tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1140 var_index);
1141 bitmap_set_bit (all_module_statics, DECL_UID (v_decl));
1142 if (dump_file)
1143 fprintf (dump_file, " %s",
1144 lang_hooks.decl_printable_name (v_decl, 2));
1147 for (i = 0; i < f_count; i++)
1149 unsigned int j, index;
1150 struct cgraph_node *node;
1151 ipa_reference_optimization_summary_t info;
1152 int v_count;
1153 lto_symtab_encoder_t encoder;
1155 index = streamer_read_uhwi (ib);
1156 encoder = file_data->symtab_node_encoder;
1157 node = cgraph (lto_symtab_encoder_deref (encoder, index));
1158 info = XCNEW (struct ipa_reference_optimization_summary_d);
1159 set_reference_optimization_summary (node, info);
1160 info->statics_not_read = BITMAP_ALLOC (&optimization_summary_obstack);
1161 info->statics_not_written = BITMAP_ALLOC (&optimization_summary_obstack);
1162 if (dump_file)
1163 fprintf (dump_file,
1164 "\nFunction name:%s/%i:\n static not read:",
1165 cgraph_node_asm_name (node), node->symbol.order);
1167 /* Set the statics not read. */
1168 v_count = streamer_read_hwi (ib);
1169 if (v_count == -1)
1171 info->statics_not_read = all_module_statics;
1172 if (dump_file)
1173 fprintf (dump_file, " all module statics");
1175 else
1176 for (j = 0; j < (unsigned int)v_count; j++)
1178 unsigned int var_index = streamer_read_uhwi (ib);
1179 tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1180 var_index);
1181 bitmap_set_bit (info->statics_not_read, DECL_UID (v_decl));
1182 if (dump_file)
1183 fprintf (dump_file, " %s",
1184 lang_hooks.decl_printable_name (v_decl, 2));
1187 if (dump_file)
1188 fprintf (dump_file,
1189 "\n static not written:");
1190 /* Set the statics not written. */
1191 v_count = streamer_read_hwi (ib);
1192 if (v_count == -1)
1194 info->statics_not_written = all_module_statics;
1195 if (dump_file)
1196 fprintf (dump_file, " all module statics");
1198 else
1199 for (j = 0; j < (unsigned int)v_count; j++)
1201 unsigned int var_index = streamer_read_uhwi (ib);
1202 tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1203 var_index);
1204 bitmap_set_bit (info->statics_not_written, DECL_UID (v_decl));
1205 if (dump_file)
1206 fprintf (dump_file, " %s",
1207 lang_hooks.decl_printable_name (v_decl, 2));
1209 if (dump_file)
1210 fprintf (dump_file, "\n");
1213 lto_destroy_simple_input_block (file_data,
1214 LTO_section_ipa_reference,
1215 ib, data, len);
1217 else
1218 /* Fatal error here. We do not want to support compiling ltrans units with
1219 different version of compiler or different flags than the WPA unit, so
1220 this should never happen. */
1221 fatal_error ("ipa reference summary is missing in ltrans unit");
1225 static bool
1226 gate_reference (void)
1228 return (flag_ipa_reference
1229 /* Don't bother doing anything if the program has errors. */
1230 && !seen_error ());
1233 struct ipa_opt_pass_d pass_ipa_reference =
1236 IPA_PASS,
1237 "static-var", /* name */
1238 gate_reference, /* gate */
1239 propagate, /* execute */
1240 NULL, /* sub */
1241 NULL, /* next */
1242 0, /* static_pass_number */
1243 TV_IPA_REFERENCE, /* tv_id */
1244 0, /* properties_required */
1245 0, /* properties_provided */
1246 0, /* properties_destroyed */
1247 0, /* todo_flags_start */
1248 0 /* todo_flags_finish */
1250 NULL, /* generate_summary */
1251 NULL, /* write_summary */
1252 NULL, /* read_summary */
1253 ipa_reference_write_optimization_summary,/* write_optimization_summary */
1254 ipa_reference_read_optimization_summary,/* read_optimization_summary */
1255 NULL, /* stmt_fixup */
1256 0, /* TODOs */
1257 NULL, /* function_transform */
1258 NULL /* variable_transform */