PR c++/53989
[official-gcc.git] / gcc / ipa-reference.c
blob732f49d71042e8939e00b8cbad33b05ce72c34e4
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 cgraph_node_set set,
960 varpool_node_set vset,
961 bitmap ltrans_statics)
963 ipa_reference_optimization_summary_t info;
965 /* See if we have (non-empty) info. */
966 if (!node->analyzed || node->global.inlined_to)
967 return false;
968 info = get_reference_optimization_summary (node);
969 if (!info || (bitmap_empty_p (info->statics_not_read)
970 && bitmap_empty_p (info->statics_not_written)))
971 return false;
973 /* See if we want to encode it.
974 Encode also referenced functions since constant folding might turn it into
975 a direct call.
977 In future we might also want to include summaries of functions references
978 by initializers of constant variables references in current unit. */
979 if (!reachable_from_this_partition_p (node, set)
980 && !referenced_from_this_partition_p (&node->symbol.ref_list, set, vset))
981 return false;
983 /* See if the info has non-empty intersections with vars we want to encode. */
984 if (!bitmap_intersect_p (info->statics_not_read, ltrans_statics)
985 && !bitmap_intersect_p (info->statics_not_written, ltrans_statics))
986 return false;
987 return true;
990 /* Stream out BITS&LTRANS_STATICS as list of decls to OB.
991 LTRANS_STATICS_BITCOUNT specify number of bits in LTRANS_STATICS
992 or -1. When it is positive, just output -1 when
993 BITS&LTRANS_STATICS == BITS&LTRANS_STATICS. */
995 static void
996 stream_out_bitmap (struct lto_simple_output_block *ob,
997 bitmap bits, bitmap ltrans_statics,
998 int ltrans_statics_bitcount)
1000 int count = 0;
1001 unsigned int index;
1002 bitmap_iterator bi;
1003 if (bits == all_module_statics)
1005 streamer_write_hwi_stream (ob->main_stream, -1);
1006 return;
1008 EXECUTE_IF_AND_IN_BITMAP (bits, ltrans_statics, 0, index, bi)
1009 count ++;
1010 if (count == ltrans_statics_bitcount)
1012 streamer_write_hwi_stream (ob->main_stream, -1);
1013 return;
1015 streamer_write_hwi_stream (ob->main_stream, count);
1016 if (!count)
1017 return;
1018 EXECUTE_IF_AND_IN_BITMAP (bits, ltrans_statics, 0, index, bi)
1020 tree decl = (tree)splay_tree_lookup (reference_vars_to_consider, index)->value;
1021 lto_output_var_decl_index(ob->decl_state, ob->main_stream, decl);
1025 /* Serialize the ipa info for lto. */
1027 static void
1028 ipa_reference_write_optimization_summary (cgraph_node_set set,
1029 varpool_node_set vset)
1031 struct cgraph_node *node;
1032 struct lto_simple_output_block *ob
1033 = lto_create_simple_output_block (LTO_section_ipa_reference);
1034 unsigned int count = 0;
1035 int ltrans_statics_bitcount = 0;
1036 lto_cgraph_encoder_t encoder = ob->decl_state->cgraph_node_encoder;
1037 lto_varpool_encoder_t varpool_encoder = ob->decl_state->varpool_node_encoder;
1038 bitmap ltrans_statics = BITMAP_ALLOC (NULL);
1039 int i;
1041 reference_vars_to_consider = splay_tree_new (splay_tree_compare_ints, 0, 0);
1043 /* See what variables we are interested in. */
1044 for (i = 0; i < lto_varpool_encoder_size (varpool_encoder); i++)
1046 struct varpool_node *vnode = lto_varpool_encoder_deref (varpool_encoder, i);
1047 if (bitmap_bit_p (all_module_statics, DECL_UID (vnode->symbol.decl))
1048 && referenced_from_this_partition_p (&vnode->symbol.ref_list, set, vset))
1050 tree decl = vnode->symbol.decl;
1051 bitmap_set_bit (ltrans_statics, DECL_UID (decl));
1052 splay_tree_insert (reference_vars_to_consider,
1053 DECL_UID (decl), (splay_tree_value)decl);
1054 ltrans_statics_bitcount ++;
1059 if (ltrans_statics_bitcount)
1060 for (i = 0; i < lto_cgraph_encoder_size (encoder); i++)
1061 if (write_node_summary_p (lto_cgraph_encoder_deref (encoder, i),
1062 set, vset, ltrans_statics))
1063 count++;
1065 streamer_write_uhwi_stream (ob->main_stream, count);
1066 if (count)
1067 stream_out_bitmap (ob, ltrans_statics, ltrans_statics,
1068 -1);
1070 /* Process all of the functions. */
1071 if (ltrans_statics_bitcount)
1072 for (i = 0; i < lto_cgraph_encoder_size (encoder); i++)
1074 node = lto_cgraph_encoder_deref (encoder, i);
1075 if (write_node_summary_p (node, set, vset, ltrans_statics))
1077 ipa_reference_optimization_summary_t info;
1078 int node_ref;
1080 info = get_reference_optimization_summary (node);
1081 node_ref = lto_cgraph_encoder_encode (encoder, node);
1082 streamer_write_uhwi_stream (ob->main_stream, node_ref);
1084 stream_out_bitmap (ob, info->statics_not_read, ltrans_statics,
1085 ltrans_statics_bitcount);
1086 stream_out_bitmap (ob, info->statics_not_written, ltrans_statics,
1087 ltrans_statics_bitcount);
1090 BITMAP_FREE (ltrans_statics);
1091 lto_destroy_simple_output_block (ob);
1092 splay_tree_delete (reference_vars_to_consider);
1095 /* Deserialize the ipa info for lto. */
1097 static void
1098 ipa_reference_read_optimization_summary (void)
1100 struct lto_file_decl_data ** file_data_vec
1101 = lto_get_file_decl_data ();
1102 struct lto_file_decl_data * file_data;
1103 unsigned int j = 0;
1104 bitmap_obstack_initialize (&optimization_summary_obstack);
1106 node_removal_hook_holder =
1107 cgraph_add_node_removal_hook (&remove_node_data, NULL);
1108 node_duplication_hook_holder =
1109 cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
1110 all_module_statics = BITMAP_ALLOC (&optimization_summary_obstack);
1112 while ((file_data = file_data_vec[j++]))
1114 const char *data;
1115 size_t len;
1116 struct lto_input_block *ib
1117 = lto_create_simple_input_block (file_data,
1118 LTO_section_ipa_reference,
1119 &data, &len);
1120 if (ib)
1122 unsigned int i;
1123 unsigned int f_count = streamer_read_uhwi (ib);
1124 int b_count;
1125 if (!f_count)
1126 continue;
1127 b_count = streamer_read_hwi (ib);
1128 if (dump_file)
1129 fprintf (dump_file, "all module statics:");
1130 for (i = 0; i < (unsigned int)b_count; i++)
1132 unsigned int var_index = streamer_read_uhwi (ib);
1133 tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1134 var_index);
1135 bitmap_set_bit (all_module_statics, DECL_UID (v_decl));
1136 if (dump_file)
1137 fprintf (dump_file, " %s",
1138 lang_hooks.decl_printable_name (v_decl, 2));
1141 for (i = 0; i < f_count; i++)
1143 unsigned int j, index;
1144 struct cgraph_node *node;
1145 ipa_reference_optimization_summary_t info;
1146 int v_count;
1147 lto_cgraph_encoder_t encoder;
1149 index = streamer_read_uhwi (ib);
1150 encoder = file_data->cgraph_node_encoder;
1151 node = lto_cgraph_encoder_deref (encoder, index);
1152 info = XCNEW (struct ipa_reference_optimization_summary_d);
1153 set_reference_optimization_summary (node, info);
1154 info->statics_not_read = BITMAP_ALLOC (&optimization_summary_obstack);
1155 info->statics_not_written = BITMAP_ALLOC (&optimization_summary_obstack);
1156 if (dump_file)
1157 fprintf (dump_file,
1158 "\nFunction name:%s/%i:\n static not read:",
1159 cgraph_node_asm_name (node), node->symbol.order);
1161 /* Set the statics not read. */
1162 v_count = streamer_read_hwi (ib);
1163 if (v_count == -1)
1165 info->statics_not_read = all_module_statics;
1166 if (dump_file)
1167 fprintf (dump_file, " all module statics");
1169 else
1170 for (j = 0; j < (unsigned int)v_count; j++)
1172 unsigned int var_index = streamer_read_uhwi (ib);
1173 tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1174 var_index);
1175 bitmap_set_bit (info->statics_not_read, DECL_UID (v_decl));
1176 if (dump_file)
1177 fprintf (dump_file, " %s",
1178 lang_hooks.decl_printable_name (v_decl, 2));
1181 if (dump_file)
1182 fprintf (dump_file,
1183 "\n static not written:");
1184 /* Set the statics not written. */
1185 v_count = streamer_read_hwi (ib);
1186 if (v_count == -1)
1188 info->statics_not_written = all_module_statics;
1189 if (dump_file)
1190 fprintf (dump_file, " all module statics");
1192 else
1193 for (j = 0; j < (unsigned int)v_count; j++)
1195 unsigned int var_index = streamer_read_uhwi (ib);
1196 tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1197 var_index);
1198 bitmap_set_bit (info->statics_not_written, DECL_UID (v_decl));
1199 if (dump_file)
1200 fprintf (dump_file, " %s",
1201 lang_hooks.decl_printable_name (v_decl, 2));
1203 if (dump_file)
1204 fprintf (dump_file, "\n");
1207 lto_destroy_simple_input_block (file_data,
1208 LTO_section_ipa_reference,
1209 ib, data, len);
1211 else
1212 /* Fatal error here. We do not want to support compiling ltrans units with
1213 different version of compiler or different flags than the WPA unit, so
1214 this should never happen. */
1215 fatal_error ("ipa reference summary is missing in ltrans unit");
1219 static bool
1220 gate_reference (void)
1222 return (flag_ipa_reference
1223 /* Don't bother doing anything if the program has errors. */
1224 && !seen_error ());
1227 struct ipa_opt_pass_d pass_ipa_reference =
1230 IPA_PASS,
1231 "static-var", /* name */
1232 gate_reference, /* gate */
1233 propagate, /* execute */
1234 NULL, /* sub */
1235 NULL, /* next */
1236 0, /* static_pass_number */
1237 TV_IPA_REFERENCE, /* tv_id */
1238 0, /* properties_required */
1239 0, /* properties_provided */
1240 0, /* properties_destroyed */
1241 0, /* todo_flags_start */
1242 0 /* todo_flags_finish */
1244 NULL, /* generate_summary */
1245 NULL, /* write_summary */
1246 NULL, /* read_summary */
1247 ipa_reference_write_optimization_summary,/* write_optimization_summary */
1248 ipa_reference_read_optimization_summary,/* read_optimization_summary */
1249 NULL, /* stmt_fixup */
1250 0, /* TODOs */
1251 NULL, /* function_transform */
1252 NULL /* variable_transform */