20090811-1.c: Skip for incompatible options, do not override other options.
[official-gcc.git] / gcc / ipa-reference.c
blob7ee52dacda1dccc11625a6c92f78f190fa075693
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"
63 static void remove_node_data (struct cgraph_node *node,
64 void *data ATTRIBUTE_UNUSED);
65 static void duplicate_node_data (struct cgraph_node *src,
66 struct cgraph_node *dst,
67 void *data ATTRIBUTE_UNUSED);
69 /* The static variables defined within the compilation unit that are
70 loaded or stored directly by function that owns this structure. */
72 struct ipa_reference_local_vars_info_d
74 bitmap statics_read;
75 bitmap statics_written;
78 /* Statics that are read and written by some set of functions. The
79 local ones are based on the loads and stores local to the function.
80 The global ones are based on the local info as well as the
81 transitive closure of the functions that are called. */
83 struct ipa_reference_global_vars_info_d
85 bitmap statics_read;
86 bitmap statics_written;
89 /* Information we save about every function after ipa-reference is completed. */
91 struct ipa_reference_optimization_summary_d
93 bitmap statics_not_read;
94 bitmap statics_not_written;
97 typedef struct ipa_reference_local_vars_info_d *ipa_reference_local_vars_info_t;
98 typedef struct ipa_reference_global_vars_info_d *ipa_reference_global_vars_info_t;
99 typedef struct ipa_reference_optimization_summary_d *ipa_reference_optimization_summary_t;
101 struct ipa_reference_vars_info_d
103 struct ipa_reference_local_vars_info_d local;
104 struct ipa_reference_global_vars_info_d global;
107 typedef struct ipa_reference_vars_info_d *ipa_reference_vars_info_t;
109 /* This splay tree contains all of the static variables that are
110 being considered by the compilation level alias analysis. */
111 static splay_tree reference_vars_to_consider;
113 /* A bit is set for every module static we are considering. This is
114 ored into the local info when asm code is found that clobbers all
115 memory. */
116 static bitmap all_module_statics;
118 /* Obstack holding bitmaps of local analysis (live from analysis to
119 propagation) */
120 static bitmap_obstack local_info_obstack;
121 /* Obstack holding global analysis live forever. */
122 static bitmap_obstack optimization_summary_obstack;
124 /* Holders of ipa cgraph hooks: */
125 static struct cgraph_2node_hook_list *node_duplication_hook_holder;
126 static struct cgraph_node_hook_list *node_removal_hook_holder;
128 /* Vector where the reference var infos are actually stored. */
129 DEF_VEC_P (ipa_reference_vars_info_t);
130 DEF_VEC_ALLOC_P (ipa_reference_vars_info_t, heap);
131 static VEC (ipa_reference_vars_info_t, heap) *ipa_reference_vars_vector;
132 DEF_VEC_P (ipa_reference_optimization_summary_t);
133 DEF_VEC_ALLOC_P (ipa_reference_optimization_summary_t, heap);
134 static VEC (ipa_reference_optimization_summary_t, heap) *ipa_reference_opt_sum_vector;
136 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
137 static inline ipa_reference_vars_info_t
138 get_reference_vars_info (struct cgraph_node *node)
140 if (!ipa_reference_vars_vector
141 || VEC_length (ipa_reference_vars_info_t,
142 ipa_reference_vars_vector) <= (unsigned int) node->uid)
143 return NULL;
144 return VEC_index (ipa_reference_vars_info_t, ipa_reference_vars_vector,
145 node->uid);
148 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
149 static inline ipa_reference_optimization_summary_t
150 get_reference_optimization_summary (struct cgraph_node *node)
152 if (!ipa_reference_opt_sum_vector
153 || (VEC_length (ipa_reference_optimization_summary_t,
154 ipa_reference_opt_sum_vector)
155 <= (unsigned int) node->uid))
156 return NULL;
157 return VEC_index (ipa_reference_optimization_summary_t, ipa_reference_opt_sum_vector,
158 node->uid);
161 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
162 static inline void
163 set_reference_vars_info (struct cgraph_node *node,
164 ipa_reference_vars_info_t info)
166 if (!ipa_reference_vars_vector
167 || VEC_length (ipa_reference_vars_info_t,
168 ipa_reference_vars_vector) <= (unsigned int) node->uid)
169 VEC_safe_grow_cleared (ipa_reference_vars_info_t, heap,
170 ipa_reference_vars_vector, node->uid + 1);
171 VEC_replace (ipa_reference_vars_info_t, ipa_reference_vars_vector,
172 node->uid, info);
175 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
176 static inline void
177 set_reference_optimization_summary (struct cgraph_node *node,
178 ipa_reference_optimization_summary_t info)
180 if (!ipa_reference_opt_sum_vector
181 || (VEC_length (ipa_reference_optimization_summary_t,
182 ipa_reference_opt_sum_vector)
183 <= (unsigned int) node->uid))
184 VEC_safe_grow_cleared (ipa_reference_optimization_summary_t,
185 heap, ipa_reference_opt_sum_vector, node->uid + 1);
186 VEC_replace (ipa_reference_optimization_summary_t,
187 ipa_reference_opt_sum_vector, node->uid, info);
190 /* Return a bitmap indexed by_DECL_UID uid for the static variables
191 that are not read during the execution of the function FN. Returns
192 NULL if no data is available. */
194 bitmap
195 ipa_reference_get_not_read_global (struct cgraph_node *fn)
197 ipa_reference_optimization_summary_t info;
199 info = get_reference_optimization_summary (cgraph_function_node (fn, NULL));
200 if (info)
201 return info->statics_not_read;
202 else if (flags_from_decl_or_type (fn->decl) & ECF_LEAF)
203 return all_module_statics;
204 else
205 return NULL;
208 /* Return a bitmap indexed by DECL_UID uid for the static variables
209 that are not written during the execution of the function FN. Note
210 that variables written may or may not be read during the function
211 call. Returns NULL if no data is available. */
213 bitmap
214 ipa_reference_get_not_written_global (struct cgraph_node *fn)
216 ipa_reference_optimization_summary_t info;
218 info = get_reference_optimization_summary (fn);
219 if (info)
220 return info->statics_not_written;
221 else if (flags_from_decl_or_type (fn->decl) & ECF_LEAF)
222 return all_module_statics;
223 else
224 return NULL;
229 /* Add VAR to all_module_statics and the two
230 reference_vars_to_consider* sets. */
232 static inline void
233 add_static_var (tree var)
235 int uid = DECL_UID (var);
236 gcc_assert (TREE_CODE (var) == VAR_DECL);
237 if (dump_file)
238 splay_tree_insert (reference_vars_to_consider,
239 uid, (splay_tree_value)var);
240 bitmap_set_bit (all_module_statics, uid);
243 /* Return true if the variable T is the right kind of static variable to
244 perform compilation unit scope escape analysis. */
246 static inline bool
247 is_proper_for_analysis (tree t)
249 /* We handle only variables whose address is never taken. */
250 if (TREE_ADDRESSABLE (t))
251 return false;
253 /* If the variable has the "used" attribute, treat it as if it had a
254 been touched by the devil. */
255 if (DECL_PRESERVE_P (t))
256 return false;
258 /* Do not want to do anything with volatile except mark any
259 function that uses one to be not const or pure. */
260 if (TREE_THIS_VOLATILE (t))
261 return false;
263 /* We do not need to analyze readonly vars, we already know they do not
264 alias. */
265 if (TREE_READONLY (t))
266 return false;
268 /* We cannot touch decls where the type needs constructing. */
269 if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (t)))
270 return false;
272 /* This is a variable we care about. Check if we have seen it
273 before, and if not add it the set of variables we care about. */
274 if (all_module_statics
275 && !bitmap_bit_p (all_module_statics, DECL_UID (t)))
276 add_static_var (t);
278 return true;
281 /* Lookup the tree node for the static variable that has UID and
282 convert the name to a string for debugging. */
284 static const char *
285 get_static_name (int index)
287 splay_tree_node stn =
288 splay_tree_lookup (reference_vars_to_consider, index);
289 if (stn)
290 return lang_hooks.decl_printable_name ((tree)(stn->value), 2);
291 return NULL;
294 /* Or in all of the bits from every callee of X into X_GLOBAL, the caller's cycle,
295 bit vector. There are several cases to check to avoid the sparse
296 bitmap oring. */
298 static void
299 propagate_bits (ipa_reference_global_vars_info_t x_global, struct cgraph_node *x)
301 struct cgraph_edge *e;
302 for (e = x->callees; e; e = e->next_callee)
304 enum availability avail;
305 struct cgraph_node *y = cgraph_function_node (e->callee, &avail);
307 if (!y)
308 continue;
309 /* Only look into nodes we can propagate something. */
310 if (avail > AVAIL_OVERWRITABLE
311 || (avail == AVAIL_OVERWRITABLE
312 && (flags_from_decl_or_type (y->decl) & ECF_LEAF)))
314 int flags = flags_from_decl_or_type (y->decl);
315 if (get_reference_vars_info (y))
317 ipa_reference_vars_info_t y_info
318 = get_reference_vars_info (y);
319 ipa_reference_global_vars_info_t y_global = &y_info->global;
321 /* Calls in current cycle do not have global computed yet. */
322 if (!y_global->statics_read)
323 continue;
325 /* If function is declared const, it reads no memory even if it
326 seems so to local analysis. */
327 if (flags & ECF_CONST)
328 continue;
330 if (x_global->statics_read
331 != all_module_statics)
333 if (y_global->statics_read
334 == all_module_statics)
336 BITMAP_FREE (x_global->statics_read);
337 x_global->statics_read
338 = all_module_statics;
340 /* Skip bitmaps that are pointer equal to node's bitmap
341 (no reason to spin within the cycle). */
342 else if (x_global->statics_read
343 != y_global->statics_read)
344 bitmap_ior_into (x_global->statics_read,
345 y_global->statics_read);
348 /* If function is declared pure, it has no stores even if it
349 seems so to local analysis; If we can not return from here,
350 we can safely ignore the call. */
351 if ((flags & ECF_PURE)
352 || cgraph_edge_cannot_lead_to_return (e))
353 continue;
355 if (x_global->statics_written
356 != all_module_statics)
358 if (y_global->statics_written
359 == all_module_statics)
361 BITMAP_FREE (x_global->statics_written);
362 x_global->statics_written
363 = all_module_statics;
365 /* Skip bitmaps that are pointer equal to node's bitmap
366 (no reason to spin within the cycle). */
367 else if (x_global->statics_written
368 != y_global->statics_written)
369 bitmap_ior_into (x_global->statics_written,
370 y_global->statics_written);
373 else
374 gcc_unreachable ();
379 /* The init routine for analyzing global static variable usage. See
380 comments at top for description. */
381 static void
382 ipa_init (void)
384 static bool init_p = false;
386 if (init_p)
387 return;
389 init_p = true;
391 if (dump_file)
392 reference_vars_to_consider = splay_tree_new (splay_tree_compare_ints, 0, 0);
394 bitmap_obstack_initialize (&local_info_obstack);
395 bitmap_obstack_initialize (&optimization_summary_obstack);
396 all_module_statics = BITMAP_ALLOC (&optimization_summary_obstack);
398 node_removal_hook_holder =
399 cgraph_add_node_removal_hook (&remove_node_data, NULL);
400 node_duplication_hook_holder =
401 cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
405 /* Set up the persistent info for FN. */
407 static ipa_reference_local_vars_info_t
408 init_function_info (struct cgraph_node *fn)
410 ipa_reference_vars_info_t info
411 = XCNEW (struct ipa_reference_vars_info_d);
413 /* Add the info to the tree's annotation. */
414 set_reference_vars_info (fn, info);
416 info->local.statics_read = BITMAP_ALLOC (&local_info_obstack);
417 info->local.statics_written = BITMAP_ALLOC (&local_info_obstack);
419 return &info->local;
423 /* This is the main routine for finding the reference patterns for
424 global variables within a function FN. */
426 static void
427 analyze_function (struct cgraph_node *fn)
429 ipa_reference_local_vars_info_t local;
430 struct ipa_ref *ref;
431 int i;
432 tree var;
434 local = init_function_info (fn);
435 for (i = 0; ipa_ref_list_reference_iterate (&fn->ref_list, i, ref); i++)
437 if (ref->refered_type != IPA_REF_VARPOOL)
438 continue;
439 var = ipa_ref_varpool_node (ref)->decl;
440 if (ipa_ref_varpool_node (ref)->externally_visible
441 || !ipa_ref_varpool_node (ref)->analyzed
442 || !is_proper_for_analysis (var))
443 continue;
444 switch (ref->use)
446 case IPA_REF_LOAD:
447 bitmap_set_bit (local->statics_read, DECL_UID (var));
448 break;
449 case IPA_REF_STORE:
450 if (ipa_ref_cannot_lead_to_return (ref))
451 break;
452 bitmap_set_bit (local->statics_written, DECL_UID (var));
453 break;
454 case IPA_REF_ADDR:
455 gcc_unreachable ();
456 break;
460 if (cgraph_node_cannot_return (fn))
461 bitmap_clear (local->statics_written);
464 static bitmap
465 copy_global_bitmap (bitmap src)
467 bitmap dst;
468 if (!src)
469 return NULL;
470 if (src == all_module_statics)
471 return all_module_statics;
472 dst = BITMAP_ALLOC (&optimization_summary_obstack);
473 bitmap_copy (dst, src);
474 return dst;
478 /* Called when new clone is inserted to callgraph late. */
480 static void
481 duplicate_node_data (struct cgraph_node *src, struct cgraph_node *dst,
482 void *data ATTRIBUTE_UNUSED)
484 ipa_reference_optimization_summary_t ginfo;
485 ipa_reference_optimization_summary_t dst_ginfo;
487 ginfo = get_reference_optimization_summary (src);
488 if (!ginfo)
489 return;
490 dst_ginfo = XCNEW (struct ipa_reference_optimization_summary_d);
491 set_reference_optimization_summary (dst, dst_ginfo);
492 dst_ginfo->statics_not_read = copy_global_bitmap (ginfo->statics_not_read);
493 dst_ginfo->statics_not_written = copy_global_bitmap (ginfo->statics_not_written);
496 /* Called when node is removed. */
498 static void
499 remove_node_data (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
501 ipa_reference_optimization_summary_t ginfo;
502 ginfo = get_reference_optimization_summary (node);
503 if (ginfo)
505 if (ginfo->statics_not_read
506 && ginfo->statics_not_read != all_module_statics)
507 BITMAP_FREE (ginfo->statics_not_read);
509 if (ginfo->statics_not_written
510 && ginfo->statics_not_written != all_module_statics)
511 BITMAP_FREE (ginfo->statics_not_written);
512 free (ginfo);
513 set_reference_optimization_summary (node, NULL);
517 /* Analyze each function in the cgraph to see which global or statics
518 are read or written. */
520 static void
521 generate_summary (void)
523 struct cgraph_node *node;
524 unsigned int index;
525 bitmap_iterator bi;
526 bitmap bm_temp;
528 ipa_init ();
529 bm_temp = BITMAP_ALLOC (&local_info_obstack);
531 /* Process all of the functions next. */
532 for (node = cgraph_nodes; node; node = node->next)
533 if (node->analyzed)
534 analyze_function (node);
536 if (dump_file)
537 EXECUTE_IF_SET_IN_BITMAP (all_module_statics, 0, index, bi)
539 fprintf (dump_file, "\nPromotable global:%s",
540 get_static_name (index));
543 BITMAP_FREE(bm_temp);
545 if (dump_file)
546 for (node = cgraph_nodes; node; node = node->next)
547 if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
549 ipa_reference_local_vars_info_t l;
550 unsigned int index;
551 bitmap_iterator bi;
553 l = &get_reference_vars_info (node)->local;
554 fprintf (dump_file,
555 "\nFunction name:%s/%i:",
556 cgraph_node_name (node), node->uid);
557 fprintf (dump_file, "\n locals read: ");
558 if (l->statics_read)
559 EXECUTE_IF_SET_IN_BITMAP (l->statics_read,
560 0, index, bi)
562 fprintf (dump_file, "%s ",
563 get_static_name (index));
565 fprintf (dump_file, "\n locals written: ");
566 if (l->statics_written)
567 EXECUTE_IF_SET_IN_BITMAP (l->statics_written,
568 0, index, bi)
570 fprintf(dump_file, "%s ",
571 get_static_name (index));
576 /* Set READ_ALL/WRITE_ALL based on decl flags of NODE. */
578 static void
579 read_write_all_from_decl (struct cgraph_node *node, bool * read_all,
580 bool * write_all)
582 tree decl = node->decl;
583 int flags = flags_from_decl_or_type (decl);
584 if ((flags & ECF_LEAF)
585 && cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
587 else if (flags & ECF_CONST)
589 else if ((flags & ECF_PURE)
590 || cgraph_node_cannot_return (node))
592 *read_all = true;
593 if (dump_file && (dump_flags & TDF_DETAILS))
594 fprintf (dump_file, " %s/%i -> read all\n",
595 cgraph_node_name (node), node->uid);
597 else
599 /* TODO: To be able to produce sane results, we should also handle
600 common builtins, in particular throw. */
601 *read_all = true;
602 *write_all = true;
603 if (dump_file && (dump_flags & TDF_DETAILS))
604 fprintf (dump_file, " %s/%i -> read all, write all\n",
605 cgraph_node_name (node), node->uid);
609 /* Produce the global information by preforming a transitive closure
610 on the local information that was produced by ipa_analyze_function */
612 static unsigned int
613 propagate (void)
615 struct cgraph_node *node;
616 struct cgraph_node *w;
617 struct cgraph_node **order =
618 XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
619 int order_pos;
620 int i;
622 if (dump_file)
623 dump_cgraph (dump_file);
625 ipa_discover_readonly_nonaddressable_vars ();
626 generate_summary ();
628 /* Propagate the local information thru the call graph to produce
629 the global information. All the nodes within a cycle will have
630 the same info so we collapse cycles first. Then we can do the
631 propagation in one pass from the leaves to the roots. */
632 order_pos = ipa_reduced_postorder (order, true, true, NULL);
633 if (dump_file)
634 ipa_print_order (dump_file, "reduced", order, order_pos);
636 for (i = 0; i < order_pos; i++ )
638 ipa_reference_vars_info_t node_info;
639 ipa_reference_global_vars_info_t node_g;
640 ipa_reference_local_vars_info_t node_l;
641 struct cgraph_edge *e, *ie;
643 bool read_all;
644 bool write_all;
645 struct ipa_dfs_info * w_info;
647 node = order[i];
648 node_info = get_reference_vars_info (node);
649 gcc_assert (node_info);
652 if (dump_file && (dump_flags & TDF_DETAILS))
653 fprintf (dump_file, "Starting cycle with %s/%i\n",
654 cgraph_node_name (node), node->uid);
656 node_l = &node_info->local;
657 node_g = &node_info->global;
659 read_all = false;
660 write_all = false;
662 /* When function is overwritable, we can not assume anything. */
663 if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
664 read_write_all_from_decl (node, &read_all, &write_all);
666 for (e = node->callees; e; e = e->next_callee)
668 enum availability avail;
669 struct cgraph_node *callee = cgraph_function_node (e->callee, &avail);
670 if (!callee || avail <= AVAIL_OVERWRITABLE)
671 read_write_all_from_decl (callee, &read_all, &write_all);
674 for (ie = node->indirect_calls; ie; ie = ie->next_callee)
675 if (!(ie->indirect_info->ecf_flags & ECF_CONST))
677 read_all = true;
678 if (dump_file && (dump_flags & TDF_DETAILS))
679 fprintf (dump_file, " indirect call -> read all\n");
680 if (!cgraph_edge_cannot_lead_to_return (ie)
681 && !(ie->indirect_info->ecf_flags & ECF_PURE))
683 if (dump_file && (dump_flags & TDF_DETAILS))
684 fprintf (dump_file, " indirect call -> write all\n");
685 write_all = true;
690 /* If any node in a cycle is read_all or write_all
691 they all are. */
692 w_info = (struct ipa_dfs_info *) node->aux;
693 w = w_info->next_cycle;
694 while (w && (!read_all || !write_all))
696 if (dump_file && (dump_flags & TDF_DETAILS))
697 fprintf (dump_file, " Visiting %s/%i\n",
698 cgraph_node_name (w), w->uid);
699 /* When function is overwritable, we can not assume anything. */
700 if (cgraph_function_body_availability (w) <= AVAIL_OVERWRITABLE)
701 read_write_all_from_decl (w, &read_all, &write_all);
703 for (e = w->callees; e; e = e->next_callee)
705 enum availability avail;
706 struct cgraph_node *callee = cgraph_function_node (e->callee, &avail);
708 if (avail <= AVAIL_OVERWRITABLE)
709 read_write_all_from_decl (callee, &read_all, &write_all);
712 for (ie = w->indirect_calls; ie; ie = ie->next_callee)
713 if (!(ie->indirect_info->ecf_flags & ECF_CONST))
715 read_all = true;
716 if (dump_file && (dump_flags & TDF_DETAILS))
717 fprintf (dump_file, " indirect call -> read all\n");
718 if (!cgraph_edge_cannot_lead_to_return (ie)
719 && !(ie->indirect_info->ecf_flags & ECF_PURE))
721 write_all = true;
722 if (dump_file && (dump_flags & TDF_DETAILS))
723 fprintf (dump_file, " indirect call -> write all\n");
727 w_info = (struct ipa_dfs_info *) w->aux;
728 w = w_info->next_cycle;
732 /* Initialized the bitmaps for the reduced nodes */
733 if (read_all)
734 node_g->statics_read = all_module_statics;
735 else
737 node_g->statics_read = BITMAP_ALLOC (&local_info_obstack);
738 bitmap_copy (node_g->statics_read,
739 node_l->statics_read);
741 if (write_all)
742 node_g->statics_written = all_module_statics;
743 else
745 node_g->statics_written = BITMAP_ALLOC (&local_info_obstack);
746 bitmap_copy (node_g->statics_written,
747 node_l->statics_written);
750 propagate_bits (node_g, node);
751 w_info = (struct ipa_dfs_info *) node->aux;
752 w = w_info->next_cycle;
753 while (w && (!read_all || !write_all))
755 ipa_reference_vars_info_t w_ri =
756 get_reference_vars_info (w);
757 ipa_reference_local_vars_info_t w_l = &w_ri->local;
758 int flags = flags_from_decl_or_type (w->decl);
760 /* These global bitmaps are initialized from the local info
761 of all of the nodes in the region. However there is no
762 need to do any work if the bitmaps were set to
763 all_module_statics. */
764 if (!read_all && !(flags & ECF_CONST))
765 bitmap_ior_into (node_g->statics_read,
766 w_l->statics_read);
767 if (!write_all
768 && !(flags & ECF_PURE)
769 && !cgraph_node_cannot_return (w))
770 bitmap_ior_into (node_g->statics_written,
771 w_l->statics_written);
772 propagate_bits (node_g, w);
773 w_info = (struct ipa_dfs_info *) w->aux;
774 w = w_info->next_cycle;
777 /* All nodes within a cycle have the same global info bitmaps. */
778 node_info->global = *node_g;
779 w_info = (struct ipa_dfs_info *) node->aux;
780 w = w_info->next_cycle;
781 while (w)
783 ipa_reference_vars_info_t w_ri =
784 get_reference_vars_info (w);
786 w_ri->global = *node_g;
788 w_info = (struct ipa_dfs_info *) w->aux;
789 w = w_info->next_cycle;
793 if (dump_file)
795 for (i = 0; i < order_pos; i++ )
797 ipa_reference_vars_info_t node_info;
798 ipa_reference_global_vars_info_t node_g;
799 ipa_reference_local_vars_info_t node_l;
800 unsigned int index;
801 bitmap_iterator bi;
802 struct ipa_dfs_info * w_info;
804 node = order[i];
805 node_info = get_reference_vars_info (node);
806 node_g = &node_info->global;
807 node_l = &node_info->local;
808 fprintf (dump_file,
809 "\nFunction name:%s/%i:",
810 cgraph_node_name (node), node->uid);
811 fprintf (dump_file, "\n locals read: ");
812 if (node_l->statics_read)
813 EXECUTE_IF_SET_IN_BITMAP (node_l->statics_read,
814 0, index, bi)
816 fprintf (dump_file, "%s ",
817 get_static_name (index));
819 fprintf (dump_file, "\n locals written: ");
820 if (node_l->statics_written)
821 EXECUTE_IF_SET_IN_BITMAP (node_l->statics_written,
822 0, index, bi)
824 fprintf(dump_file, "%s ",
825 get_static_name (index));
828 w_info = (struct ipa_dfs_info *) node->aux;
829 w = w_info->next_cycle;
830 while (w)
832 ipa_reference_vars_info_t w_ri =
833 get_reference_vars_info (w);
834 ipa_reference_local_vars_info_t w_l = &w_ri->local;
835 fprintf (dump_file, "\n next cycle: %s/%i ",
836 cgraph_node_name (w), w->uid);
837 fprintf (dump_file, "\n locals read: ");
838 if (w_l->statics_read)
839 EXECUTE_IF_SET_IN_BITMAP (w_l->statics_read,
840 0, index, bi)
842 fprintf (dump_file, "%s ",
843 get_static_name (index));
846 fprintf (dump_file, "\n locals written: ");
847 if (w_l->statics_written)
848 EXECUTE_IF_SET_IN_BITMAP (w_l->statics_written,
849 0, index, bi)
851 fprintf (dump_file, "%s ",
852 get_static_name (index));
855 w_info = (struct ipa_dfs_info *) w->aux;
856 w = w_info->next_cycle;
858 fprintf (dump_file, "\n globals read: ");
859 if (node_g->statics_read == all_module_statics)
860 fprintf (dump_file, "ALL");
861 else
862 EXECUTE_IF_SET_IN_BITMAP (node_g->statics_read,
863 0, index, bi)
865 fprintf (dump_file, "%s ",
866 get_static_name (index));
868 fprintf (dump_file, "\n globals written: ");
869 if (node_g->statics_written == all_module_statics)
870 fprintf (dump_file, "ALL");
871 else
872 EXECUTE_IF_SET_IN_BITMAP (node_g->statics_written,
873 0, index, bi)
875 fprintf (dump_file, "%s ",
876 get_static_name (index));
881 /* Cleanup. */
882 for (node = cgraph_nodes; node; node = node->next)
884 ipa_reference_vars_info_t node_info;
885 ipa_reference_global_vars_info_t node_g;
886 ipa_reference_optimization_summary_t opt;
888 if (!node->analyzed)
889 continue;
891 node_info = get_reference_vars_info (node);
892 if (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE
893 || (flags_from_decl_or_type (node->decl) & ECF_LEAF))
895 node_g = &node_info->global;
897 opt = XCNEW (struct ipa_reference_optimization_summary_d);
898 set_reference_optimization_summary (node, opt);
900 /* Create the complimentary sets. */
902 if (bitmap_empty_p (node_g->statics_read))
903 opt->statics_not_read = all_module_statics;
904 else
906 opt->statics_not_read
907 = BITMAP_ALLOC (&optimization_summary_obstack);
908 if (node_g->statics_read != all_module_statics)
909 bitmap_and_compl (opt->statics_not_read,
910 all_module_statics,
911 node_g->statics_read);
914 if (bitmap_empty_p (node_g->statics_written))
915 opt->statics_not_written = all_module_statics;
916 else
918 opt->statics_not_written
919 = BITMAP_ALLOC (&optimization_summary_obstack);
920 if (node_g->statics_written != all_module_statics)
921 bitmap_and_compl (opt->statics_not_written,
922 all_module_statics,
923 node_g->statics_written);
926 free (node_info);
929 ipa_free_postorder_info ();
930 free (order);
932 bitmap_obstack_release (&local_info_obstack);
933 VEC_free (ipa_reference_vars_info_t, heap, ipa_reference_vars_vector);
934 ipa_reference_vars_vector = NULL;
935 if (dump_file)
936 splay_tree_delete (reference_vars_to_consider);
937 reference_vars_to_consider = NULL;
938 return 0;
941 /* Return true if we need to write summary of NODE. */
943 static bool
944 write_node_summary_p (struct cgraph_node *node,
945 cgraph_node_set set,
946 varpool_node_set vset,
947 bitmap ltrans_statics)
949 ipa_reference_optimization_summary_t info;
951 /* See if we have (non-empty) info. */
952 if (!node->analyzed || node->global.inlined_to)
953 return false;
954 info = get_reference_optimization_summary (node);
955 if (!info || (bitmap_empty_p (info->statics_not_read)
956 && bitmap_empty_p (info->statics_not_written)))
957 return false;
959 /* See if we want to encode it.
960 Encode also referenced functions since constant folding might turn it into
961 a direct call.
963 In future we might also want to include summaries of functions references
964 by initializers of constant variables references in current unit. */
965 if (!reachable_from_this_partition_p (node, set)
966 && !referenced_from_this_partition_p (&node->ref_list, set, vset))
967 return false;
969 /* See if the info has non-empty intersections with vars we want to encode. */
970 if (!bitmap_intersect_p (info->statics_not_read, ltrans_statics)
971 && !bitmap_intersect_p (info->statics_not_written, ltrans_statics))
972 return false;
973 return true;
976 /* Stream out BITS&LTRANS_STATICS as list of decls to OB.
977 LTRANS_STATICS_BITCOUNT specify number of bits in LTRANS_STATICS
978 or -1. When it is positive, just output -1 when
979 BITS&LTRANS_STATICS == BITS&LTRANS_STATICS. */
981 static void
982 stream_out_bitmap (struct lto_simple_output_block *ob,
983 bitmap bits, bitmap ltrans_statics,
984 int ltrans_statics_bitcount)
986 int count = 0;
987 unsigned int index;
988 bitmap_iterator bi;
989 if (bits == all_module_statics)
991 lto_output_sleb128_stream (ob->main_stream, -1);
992 return;
994 EXECUTE_IF_AND_IN_BITMAP (bits, ltrans_statics, 0, index, bi)
995 count ++;
996 if (count == ltrans_statics_bitcount)
998 lto_output_sleb128_stream (ob->main_stream, -1);
999 return;
1001 lto_output_sleb128_stream (ob->main_stream, count);
1002 if (!count)
1003 return;
1004 EXECUTE_IF_AND_IN_BITMAP (bits, ltrans_statics, 0, index, bi)
1006 tree decl = (tree)splay_tree_lookup (reference_vars_to_consider, index)->value;
1007 lto_output_var_decl_index(ob->decl_state, ob->main_stream, decl);
1011 /* Serialize the ipa info for lto. */
1013 static void
1014 ipa_reference_write_optimization_summary (cgraph_node_set set,
1015 varpool_node_set vset)
1017 struct cgraph_node *node;
1018 struct lto_simple_output_block *ob
1019 = lto_create_simple_output_block (LTO_section_ipa_reference);
1020 unsigned int count = 0;
1021 int ltrans_statics_bitcount = 0;
1022 lto_cgraph_encoder_t encoder = ob->decl_state->cgraph_node_encoder;
1023 lto_varpool_encoder_t varpool_encoder = ob->decl_state->varpool_node_encoder;
1024 bitmap ltrans_statics = BITMAP_ALLOC (NULL);
1025 int i;
1027 reference_vars_to_consider = splay_tree_new (splay_tree_compare_ints, 0, 0);
1029 /* See what variables we are interested in. */
1030 for (i = 0; i < lto_varpool_encoder_size (varpool_encoder); i++)
1032 struct varpool_node *vnode = lto_varpool_encoder_deref (varpool_encoder, i);
1033 if (!vnode->externally_visible
1034 && vnode->analyzed
1035 && bitmap_bit_p (all_module_statics, DECL_UID (vnode->decl))
1036 && referenced_from_this_partition_p (&vnode->ref_list, set, vset))
1038 tree decl = vnode->decl;
1039 bitmap_set_bit (ltrans_statics, DECL_UID (decl));
1040 splay_tree_insert (reference_vars_to_consider,
1041 DECL_UID (decl), (splay_tree_value)decl);
1042 ltrans_statics_bitcount ++;
1047 if (ltrans_statics_bitcount)
1048 for (i = 0; i < lto_cgraph_encoder_size (encoder); i++)
1049 if (write_node_summary_p (lto_cgraph_encoder_deref (encoder, i),
1050 set, vset, ltrans_statics))
1051 count++;
1053 lto_output_uleb128_stream (ob->main_stream, count);
1054 if (count)
1055 stream_out_bitmap (ob, ltrans_statics, ltrans_statics,
1056 -1);
1058 /* Process all of the functions. */
1059 if (ltrans_statics_bitcount)
1060 for (i = 0; i < lto_cgraph_encoder_size (encoder); i++)
1062 node = lto_cgraph_encoder_deref (encoder, i);
1063 if (write_node_summary_p (node, set, vset, ltrans_statics))
1065 ipa_reference_optimization_summary_t info;
1066 int node_ref;
1068 info = get_reference_optimization_summary (node);
1069 node_ref = lto_cgraph_encoder_encode (encoder, node);
1070 lto_output_uleb128_stream (ob->main_stream, node_ref);
1072 stream_out_bitmap (ob, info->statics_not_read, ltrans_statics,
1073 ltrans_statics_bitcount);
1074 stream_out_bitmap (ob, info->statics_not_written, ltrans_statics,
1075 ltrans_statics_bitcount);
1078 BITMAP_FREE (ltrans_statics);
1079 lto_destroy_simple_output_block (ob);
1080 splay_tree_delete (reference_vars_to_consider);
1083 /* Deserialize the ipa info for lto. */
1085 static void
1086 ipa_reference_read_optimization_summary (void)
1088 struct lto_file_decl_data ** file_data_vec
1089 = lto_get_file_decl_data ();
1090 struct lto_file_decl_data * file_data;
1091 unsigned int j = 0;
1092 bitmap_obstack_initialize (&optimization_summary_obstack);
1094 node_removal_hook_holder =
1095 cgraph_add_node_removal_hook (&remove_node_data, NULL);
1096 node_duplication_hook_holder =
1097 cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
1098 all_module_statics = BITMAP_ALLOC (&optimization_summary_obstack);
1100 while ((file_data = file_data_vec[j++]))
1102 const char *data;
1103 size_t len;
1104 struct lto_input_block *ib
1105 = lto_create_simple_input_block (file_data,
1106 LTO_section_ipa_reference,
1107 &data, &len);
1108 if (ib)
1110 unsigned int i;
1111 unsigned int f_count = lto_input_uleb128 (ib);
1112 int b_count;
1113 if (!f_count)
1114 continue;
1115 b_count = lto_input_sleb128 (ib);
1116 if (dump_file)
1117 fprintf (dump_file, "all module statics:");
1118 for (i = 0; i < (unsigned int)b_count; i++)
1120 unsigned int var_index = lto_input_uleb128 (ib);
1121 tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1122 var_index);
1123 bitmap_set_bit (all_module_statics, DECL_UID (v_decl));
1124 if (dump_file)
1125 fprintf (dump_file, " %s",
1126 lang_hooks.decl_printable_name (v_decl, 2));
1129 for (i = 0; i < f_count; i++)
1131 unsigned int j, index;
1132 struct cgraph_node *node;
1133 ipa_reference_optimization_summary_t info;
1134 int v_count;
1135 lto_cgraph_encoder_t encoder;
1137 index = lto_input_uleb128 (ib);
1138 encoder = file_data->cgraph_node_encoder;
1139 node = lto_cgraph_encoder_deref (encoder, index);
1140 info = XCNEW (struct ipa_reference_optimization_summary_d);
1141 set_reference_optimization_summary (node, info);
1142 info->statics_not_read = BITMAP_ALLOC (&optimization_summary_obstack);
1143 info->statics_not_written = BITMAP_ALLOC (&optimization_summary_obstack);
1144 if (dump_file)
1145 fprintf (dump_file,
1146 "\nFunction name:%s/%i:\n static not read:",
1147 cgraph_node_name (node), node->uid);
1149 /* Set the statics not read. */
1150 v_count = lto_input_sleb128 (ib);
1151 if (v_count == -1)
1153 info->statics_not_read = all_module_statics;
1154 if (dump_file)
1155 fprintf (dump_file, " all module statics");
1157 else
1158 for (j = 0; j < (unsigned int)v_count; j++)
1160 unsigned int var_index = lto_input_uleb128 (ib);
1161 tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1162 var_index);
1163 bitmap_set_bit (info->statics_not_read, DECL_UID (v_decl));
1164 if (dump_file)
1165 fprintf (dump_file, " %s",
1166 lang_hooks.decl_printable_name (v_decl, 2));
1169 if (dump_file)
1170 fprintf (dump_file,
1171 "\n static not written:");
1172 /* Set the statics not written. */
1173 v_count = lto_input_sleb128 (ib);
1174 if (v_count == -1)
1176 info->statics_not_written = all_module_statics;
1177 if (dump_file)
1178 fprintf (dump_file, " all module statics");
1180 else
1181 for (j = 0; j < (unsigned int)v_count; j++)
1183 unsigned int var_index = lto_input_uleb128 (ib);
1184 tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1185 var_index);
1186 bitmap_set_bit (info->statics_not_written, DECL_UID (v_decl));
1187 if (dump_file)
1188 fprintf (dump_file, " %s",
1189 lang_hooks.decl_printable_name (v_decl, 2));
1191 if (dump_file)
1192 fprintf (dump_file, "\n");
1195 lto_destroy_simple_input_block (file_data,
1196 LTO_section_ipa_reference,
1197 ib, data, len);
1199 else
1200 /* Fatal error here. We do not want to support compiling ltrans units with
1201 different version of compiler or different flags than the WPA unit, so
1202 this should never happen. */
1203 fatal_error ("ipa reference summary is missing in ltrans unit");
1207 static bool
1208 gate_reference (void)
1210 return (flag_ipa_reference
1211 /* Don't bother doing anything if the program has errors. */
1212 && !seen_error ());
1215 struct ipa_opt_pass_d pass_ipa_reference =
1218 IPA_PASS,
1219 "static-var", /* name */
1220 gate_reference, /* gate */
1221 propagate, /* execute */
1222 NULL, /* sub */
1223 NULL, /* next */
1224 0, /* static_pass_number */
1225 TV_IPA_REFERENCE, /* tv_id */
1226 0, /* properties_required */
1227 0, /* properties_provided */
1228 0, /* properties_destroyed */
1229 0, /* todo_flags_start */
1230 0 /* todo_flags_finish */
1232 NULL, /* generate_summary */
1233 NULL, /* write_summary */
1234 NULL, /* read_summary */
1235 ipa_reference_write_optimization_summary,/* write_optimization_summary */
1236 ipa_reference_read_optimization_summary,/* read_optimization_summary */
1237 NULL, /* stmt_fixup */
1238 0, /* TODOs */
1239 NULL, /* function_transform */
1240 NULL /* variable_transform */