ipa-reference.c (ipa_reference_local_vars_info_d): Remove calls_read_all and calls_wr...
[gcc.git] / gcc / ipa-reference.c
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>
5
6 This file is part of GCC.
7
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.
12
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.
17
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/>. */
21
22 /* This file gathers information about how variables whose scope is
23 confined to the compilation unit are used.
24
25 The transitive call site specific clobber effects are computed
26 for the variables whose scope is contained within this compilation
27 unit.
28
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. */
39
40 #include "config.h"
41 #include "system.h"
42 #include "coretypes.h"
43 #include "tm.h"
44 #include "tree.h"
45 #include "tree-flow.h"
46 #include "tree-inline.h"
47 #include "tree-pass.h"
48 #include "langhooks.h"
49 #include "pointer-set.h"
50 #include "splay-tree.h"
51 #include "ggc.h"
52 #include "ipa-utils.h"
53 #include "ipa-reference.h"
54 #include "gimple.h"
55 #include "cgraph.h"
56 #include "output.h"
57 #include "flags.h"
58 #include "timevar.h"
59 #include "diagnostic.h"
60 #include "langhooks.h"
61 #include "lto-streamer.h"
62 #include "toplev.h"
63
64 static void remove_node_data (struct cgraph_node *node,
65 void *data ATTRIBUTE_UNUSED);
66 static void duplicate_node_data (struct cgraph_node *src,
67 struct cgraph_node *dst,
68 void *data ATTRIBUTE_UNUSED);
69
70 /* The static variables defined within the compilation unit that are
71 loaded or stored directly by function that owns this structure. */
72
73 struct ipa_reference_local_vars_info_d
74 {
75 bitmap statics_read;
76 bitmap statics_written;
77 };
78
79 /* Statics that are read and written by some set of functions. The
80 local ones are based on the loads and stores local to the function.
81 The global ones are based on the local info as well as the
82 transitive closure of the functions that are called. */
83
84 struct ipa_reference_global_vars_info_d
85 {
86 bitmap statics_read;
87 bitmap statics_written;
88 };
89
90 /* Information we save about every function after ipa-reference is completted. */
91
92 struct ipa_reference_optimization_summary_d
93 {
94 bitmap statics_not_read;
95 bitmap statics_not_written;
96 };
97
98 typedef struct ipa_reference_local_vars_info_d *ipa_reference_local_vars_info_t;
99 typedef struct ipa_reference_global_vars_info_d *ipa_reference_global_vars_info_t;
100 typedef struct ipa_reference_optimization_summary_d *ipa_reference_optimization_summary_t;
101
102 struct ipa_reference_vars_info_d
103 {
104 struct ipa_reference_local_vars_info_d local;
105 struct ipa_reference_global_vars_info_d global;
106 };
107
108 typedef struct ipa_reference_vars_info_d *ipa_reference_vars_info_t;
109
110 /* This splay tree contains all of the static variables that are
111 being considered by the compilation level alias analysis. */
112 static splay_tree reference_vars_to_consider;
113
114 /* A bit is set for every module static we are considering. This is
115 ored into the local info when asm code is found that clobbers all
116 memory. */
117 static bitmap all_module_statics;
118
119 /* Obstack holding bitmaps of local analysis (live from analysis to
120 propagation) */
121 static bitmap_obstack local_info_obstack;
122 /* Obstack holding global analysis live forever. */
123 static bitmap_obstack optimization_summary_obstack;
124
125 /* Holders of ipa cgraph hooks: */
126 static struct cgraph_2node_hook_list *node_duplication_hook_holder;
127 static struct cgraph_node_hook_list *node_removal_hook_holder;
128
129 /* Vector where the reference var infos are actually stored. */
130 DEF_VEC_P (ipa_reference_vars_info_t);
131 DEF_VEC_ALLOC_P (ipa_reference_vars_info_t, heap);
132 static VEC (ipa_reference_vars_info_t, heap) *ipa_reference_vars_vector;
133 DEF_VEC_P (ipa_reference_optimization_summary_t);
134 DEF_VEC_ALLOC_P (ipa_reference_optimization_summary_t, heap);
135 static VEC (ipa_reference_optimization_summary_t, heap) *ipa_reference_opt_sum_vector;
136
137 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
138 static inline ipa_reference_vars_info_t
139 get_reference_vars_info (struct cgraph_node *node)
140 {
141 if (!ipa_reference_vars_vector
142 || VEC_length (ipa_reference_vars_info_t,
143 ipa_reference_vars_vector) <= (unsigned int) node->uid)
144 return NULL;
145 return VEC_index (ipa_reference_vars_info_t, ipa_reference_vars_vector,
146 node->uid);
147 }
148
149 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
150 static inline ipa_reference_optimization_summary_t
151 get_reference_optimization_summary (struct cgraph_node *node)
152 {
153 if (!ipa_reference_opt_sum_vector
154 || (VEC_length (ipa_reference_optimization_summary_t,
155 ipa_reference_opt_sum_vector)
156 <= (unsigned int) node->uid))
157 return NULL;
158 return VEC_index (ipa_reference_optimization_summary_t, ipa_reference_opt_sum_vector,
159 node->uid);
160 }
161
162 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
163 static inline void
164 set_reference_vars_info (struct cgraph_node *node,
165 ipa_reference_vars_info_t info)
166 {
167 if (!ipa_reference_vars_vector
168 || VEC_length (ipa_reference_vars_info_t,
169 ipa_reference_vars_vector) <= (unsigned int) node->uid)
170 VEC_safe_grow_cleared (ipa_reference_vars_info_t, heap,
171 ipa_reference_vars_vector, node->uid + 1);
172 VEC_replace (ipa_reference_vars_info_t, ipa_reference_vars_vector,
173 node->uid, info);
174 }
175
176 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
177 static inline void
178 set_reference_optimization_summary (struct cgraph_node *node,
179 ipa_reference_optimization_summary_t info)
180 {
181 if (!ipa_reference_opt_sum_vector
182 || (VEC_length (ipa_reference_optimization_summary_t,
183 ipa_reference_opt_sum_vector)
184 <= (unsigned int) node->uid))
185 VEC_safe_grow_cleared (ipa_reference_optimization_summary_t,
186 heap, ipa_reference_opt_sum_vector, node->uid + 1);
187 VEC_replace (ipa_reference_optimization_summary_t,
188 ipa_reference_opt_sum_vector, node->uid, info);
189 }
190
191 /* Return a bitmap indexed by_DECL_UID uid for the static variables
192 that are not read during the execution of the function FN. Returns
193 NULL if no data is available. */
194
195 bitmap
196 ipa_reference_get_not_read_global (struct cgraph_node *fn)
197 {
198 ipa_reference_optimization_summary_t info;
199
200 info = get_reference_optimization_summary (fn);
201 if (info)
202 return info->statics_not_read;
203 else
204 return NULL;
205 }
206
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. */
211
212 bitmap
213 ipa_reference_get_not_written_global (struct cgraph_node *fn)
214 {
215 ipa_reference_optimization_summary_t info;
216
217 info = get_reference_optimization_summary (fn);
218 if (info)
219 return info->statics_not_written;
220 else
221 return NULL;
222 }
223
224 \f
225
226 /* Add VAR to all_module_statics and the two
227 reference_vars_to_consider* sets. */
228
229 static inline void
230 add_static_var (tree var)
231 {
232 int uid = DECL_UID (var);
233 gcc_assert (TREE_CODE (var) == VAR_DECL);
234 if (dump_file)
235 splay_tree_insert (reference_vars_to_consider,
236 uid, (splay_tree_value)var);
237 bitmap_set_bit (all_module_statics, uid);
238 }
239
240 /* Return true if the variable T is the right kind of static variable to
241 perform compilation unit scope escape analysis. */
242
243 static inline bool
244 is_proper_for_analysis (tree t)
245 {
246 /* We handle only variables whose address is never taken. */
247 if (TREE_ADDRESSABLE (t))
248 return false;
249
250 /* If the variable has the "used" attribute, treat it as if it had a
251 been touched by the devil. */
252 if (DECL_PRESERVE_P (t))
253 return false;
254
255 /* Do not want to do anything with volatile except mark any
256 function that uses one to be not const or pure. */
257 if (TREE_THIS_VOLATILE (t))
258 return false;
259
260 /* We do not need to analyze readonly vars, we already know they do not
261 alias. */
262 if (TREE_READONLY (t))
263 return false;
264
265 /* We cannot touch decls where the type needs constructing. */
266 if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (t)))
267 return false;
268
269 /* This is a variable we care about. Check if we have seen it
270 before, and if not add it the set of variables we care about. */
271 if (all_module_statics
272 && !bitmap_bit_p (all_module_statics, DECL_UID (t)))
273 add_static_var (t);
274
275 return true;
276 }
277
278 /* Lookup the tree node for the static variable that has UID and
279 convert the name to a string for debugging. */
280
281 static const char *
282 get_static_name (int index)
283 {
284 splay_tree_node stn =
285 splay_tree_lookup (reference_vars_to_consider, index);
286 if (stn)
287 return lang_hooks.decl_printable_name ((tree)(stn->value), 2);
288 return NULL;
289 }
290
291 /* Or in all of the bits from every callee of X into X_GLOBAL, the caller's cycle,
292 bit vector. There are several cases to check to avoid the sparse
293 bitmap oring. */
294
295 static void
296 propagate_bits (ipa_reference_global_vars_info_t x_global, struct cgraph_node *x)
297 {
298 struct cgraph_edge *e;
299 for (e = x->callees; e; e = e->next_callee)
300 {
301 struct cgraph_node *y = e->callee;
302
303 /* Only look into nodes we can propagate something. */
304 if (cgraph_function_body_availability (e->callee) > AVAIL_OVERWRITABLE)
305 {
306 int flags = flags_from_decl_or_type (e->callee->decl);
307 if (get_reference_vars_info (y))
308 {
309 ipa_reference_vars_info_t y_info
310 = get_reference_vars_info (y);
311 ipa_reference_global_vars_info_t y_global = &y_info->global;
312
313 /* Calls in current cycle do not have global computed yet. */
314 if (!y_global->statics_read)
315 continue;
316
317 /* If function is declared const, it reads no memory even if it
318 seems so to local analysis. */
319 if (flags & ECF_CONST)
320 continue;
321
322 if (x_global->statics_read
323 != all_module_statics)
324 {
325 if (y_global->statics_read
326 == all_module_statics)
327 {
328 BITMAP_FREE (x_global->statics_read);
329 x_global->statics_read
330 = all_module_statics;
331 }
332 /* Skip bitmaps that are pointer equal to node's bitmap
333 (no reason to spin within the cycle). */
334 else if (x_global->statics_read
335 != y_global->statics_read)
336 bitmap_ior_into (x_global->statics_read,
337 y_global->statics_read);
338 }
339
340 /* If function is declared pure, it has no stores even if it
341 seems so to local analysis; If we can not return from here,
342 we can safely ignore the call. */
343 if ((flags & ECF_PURE)
344 || cgraph_edge_cannot_lead_to_return (e))
345 continue;
346
347 if (x_global->statics_written
348 != all_module_statics)
349 {
350 if (y_global->statics_written
351 == all_module_statics)
352 {
353 BITMAP_FREE (x_global->statics_written);
354 x_global->statics_written
355 = all_module_statics;
356 }
357 /* Skip bitmaps that are pointer equal to node's bitmap
358 (no reason to spin within the cycle). */
359 else if (x_global->statics_written
360 != y_global->statics_written)
361 bitmap_ior_into (x_global->statics_written,
362 y_global->statics_written);
363 }
364 }
365 else
366 gcc_unreachable ();
367 }
368 }
369 }
370
371 /* The init routine for analyzing global static variable usage. See
372 comments at top for description. */
373 static void
374 ipa_init (void)
375 {
376 static bool init_p = false;
377
378 if (init_p)
379 return;
380
381 init_p = true;
382
383 if (dump_file)
384 reference_vars_to_consider = splay_tree_new (splay_tree_compare_ints, 0, 0);
385
386 bitmap_obstack_initialize (&local_info_obstack);
387 bitmap_obstack_initialize (&optimization_summary_obstack);
388 all_module_statics = BITMAP_ALLOC (&optimization_summary_obstack);
389
390 node_removal_hook_holder =
391 cgraph_add_node_removal_hook (&remove_node_data, NULL);
392 node_duplication_hook_holder =
393 cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
394 }
395
396
397 /* Set up the persistent info for FN. */
398
399 static ipa_reference_local_vars_info_t
400 init_function_info (struct cgraph_node *fn)
401 {
402 ipa_reference_vars_info_t info
403 = XCNEW (struct ipa_reference_vars_info_d);
404
405 /* Add the info to the tree's annotation. */
406 set_reference_vars_info (fn, info);
407
408 info->local.statics_read = BITMAP_ALLOC (&local_info_obstack);
409 info->local.statics_written = BITMAP_ALLOC (&local_info_obstack);
410
411 return &info->local;
412 }
413
414
415 /* This is the main routine for finding the reference patterns for
416 global variables within a function FN. */
417
418 static void
419 analyze_function (struct cgraph_node *fn)
420 {
421 ipa_reference_local_vars_info_t local;
422 struct ipa_ref *ref;
423 int i;
424 tree var;
425
426 local = init_function_info (fn);
427 for (i = 0; ipa_ref_list_reference_iterate (&fn->ref_list, i, ref); i++)
428 {
429 if (ref->refered_type != IPA_REF_VARPOOL)
430 continue;
431 var = ipa_ref_varpool_node (ref)->decl;
432 if (ipa_ref_varpool_node (ref)->externally_visible
433 || !ipa_ref_varpool_node (ref)->analyzed
434 || !is_proper_for_analysis (var))
435 continue;
436 switch (ref->use)
437 {
438 case IPA_REF_LOAD:
439 bitmap_set_bit (local->statics_read, DECL_UID (var));
440 break;
441 case IPA_REF_STORE:
442 bitmap_set_bit (local->statics_written, DECL_UID (var));
443 break;
444 case IPA_REF_ADDR:
445 gcc_unreachable ();
446 break;
447 }
448 }
449
450 if (cgraph_node_cannot_return (fn))
451 bitmap_clear (local->statics_written);
452 }
453
454 static bitmap
455 copy_global_bitmap (bitmap src)
456 {
457 bitmap dst;
458 if (!src)
459 return NULL;
460 if (src == all_module_statics)
461 return all_module_statics;
462 dst = BITMAP_ALLOC (&optimization_summary_obstack);
463 bitmap_copy (dst, src);
464 return dst;
465 }
466
467
468 /* Called when new clone is inserted to callgraph late. */
469
470 static void
471 duplicate_node_data (struct cgraph_node *src, struct cgraph_node *dst,
472 void *data ATTRIBUTE_UNUSED)
473 {
474 ipa_reference_optimization_summary_t ginfo;
475 ipa_reference_optimization_summary_t dst_ginfo;
476
477 ginfo = get_reference_optimization_summary (src);
478 if (!ginfo)
479 return;
480 dst_ginfo = XCNEW (struct ipa_reference_optimization_summary_d);
481 set_reference_optimization_summary (dst, dst_ginfo);
482 dst_ginfo->statics_not_read = copy_global_bitmap (ginfo->statics_not_read);
483 dst_ginfo->statics_not_written = copy_global_bitmap (ginfo->statics_not_written);
484 }
485
486 /* Called when node is removed. */
487
488 static void
489 remove_node_data (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
490 {
491 ipa_reference_optimization_summary_t ginfo;
492 ginfo = get_reference_optimization_summary (node);
493 if (ginfo)
494 {
495 if (ginfo->statics_not_read
496 && ginfo->statics_not_read != all_module_statics)
497 BITMAP_FREE (ginfo->statics_not_read);
498
499 if (ginfo->statics_not_written
500 && ginfo->statics_not_written != all_module_statics)
501 BITMAP_FREE (ginfo->statics_not_written);
502 free (ginfo);
503 set_reference_optimization_summary (node, NULL);
504 }
505 }
506
507 /* Analyze each function in the cgraph to see which global or statics
508 are read or written. */
509
510 static void
511 generate_summary (void)
512 {
513 struct cgraph_node *node;
514 unsigned int index;
515 bitmap_iterator bi;
516 bitmap bm_temp;
517
518 ipa_init ();
519 bm_temp = BITMAP_ALLOC (&local_info_obstack);
520
521 /* Process all of the functions next. */
522 for (node = cgraph_nodes; node; node = node->next)
523 if (node->analyzed)
524 analyze_function (node);
525
526 if (dump_file)
527 EXECUTE_IF_SET_IN_BITMAP (all_module_statics, 0, index, bi)
528 {
529 fprintf (dump_file, "\nPromotable global:%s",
530 get_static_name (index));
531 }
532
533 BITMAP_FREE(bm_temp);
534
535 if (dump_file)
536 for (node = cgraph_nodes; node; node = node->next)
537 if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
538 {
539 ipa_reference_local_vars_info_t l;
540 unsigned int index;
541 bitmap_iterator bi;
542
543 l = &get_reference_vars_info (node)->local;
544 fprintf (dump_file,
545 "\nFunction name:%s/%i:",
546 cgraph_node_name (node), node->uid);
547 fprintf (dump_file, "\n locals read: ");
548 if (l->statics_read)
549 EXECUTE_IF_SET_IN_BITMAP (l->statics_read,
550 0, index, bi)
551 {
552 fprintf (dump_file, "%s ",
553 get_static_name (index));
554 }
555 fprintf (dump_file, "\n locals written: ");
556 if (l->statics_written)
557 EXECUTE_IF_SET_IN_BITMAP (l->statics_written,
558 0, index, bi)
559 {
560 fprintf(dump_file, "%s ",
561 get_static_name (index));
562 }
563 }
564 }
565 \f
566 /* Set READ_ALL/WRITE_ALL based on decl flags of NODE. */
567
568 static void
569 read_write_all_from_decl (struct cgraph_node *node, bool * read_all,
570 bool * write_all)
571 {
572 tree decl = node->decl;
573 int flags = flags_from_decl_or_type (decl);
574 if (flags & ECF_CONST)
575 ;
576 else if ((flags & ECF_PURE)
577 || cgraph_node_cannot_return (node))
578 *read_all = true;
579 else
580 {
581 /* TODO: To be able to produce sane results, we should also handle
582 common builtins, in particular throw. */
583 *read_all = true;
584 *write_all = true;
585 }
586 }
587
588 /* Produce the global information by preforming a transitive closure
589 on the local information that was produced by ipa_analyze_function */
590
591 static unsigned int
592 propagate (void)
593 {
594 struct cgraph_node *node;
595 struct cgraph_node *w;
596 struct cgraph_node **order =
597 XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
598 int order_pos = ipa_utils_reduced_inorder (order, false, true, NULL);
599 int i;
600
601 if (dump_file)
602 dump_cgraph (dump_file);
603
604 ipa_discover_readonly_nonaddressable_vars ();
605 generate_summary ();
606
607 /* Propagate the local information thru the call graph to produce
608 the global information. All the nodes within a cycle will have
609 the same info so we collapse cycles first. Then we can do the
610 propagation in one pass from the leaves to the roots. */
611 order_pos = ipa_utils_reduced_inorder (order, true, true, NULL);
612 if (dump_file)
613 ipa_utils_print_order(dump_file, "reduced", order, order_pos);
614
615 for (i = 0; i < order_pos; i++ )
616 {
617 ipa_reference_vars_info_t node_info;
618 ipa_reference_global_vars_info_t node_g;
619 ipa_reference_local_vars_info_t node_l;
620 struct cgraph_edge *e, *ie;
621
622 bool read_all;
623 bool write_all;
624 struct ipa_dfs_info * w_info;
625
626 node = order[i];
627 node_info = get_reference_vars_info (node);
628 gcc_assert (node_info);
629
630 node_l = &node_info->local;
631 node_g = &node_info->global;
632
633 read_all = false;
634 write_all = false;
635
636 /* When function is overwrittable, we can not assume anything. */
637 if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
638 read_write_all_from_decl (node, &read_all, &write_all);
639
640 for (e = node->callees; e; e = e->next_callee)
641 if (cgraph_function_body_availability (e->callee) <= AVAIL_OVERWRITABLE)
642 read_write_all_from_decl (e->callee, &read_all, &write_all);
643
644 for (ie = node->indirect_calls; ie; ie = ie->next_callee)
645 if (!(ie->indirect_info->ecf_flags & ECF_CONST))
646 {
647 read_all = true;
648 if (!cgraph_edge_cannot_lead_to_return (ie)
649 && !(ie->indirect_info->ecf_flags & ECF_PURE))
650 write_all = true;
651 }
652
653
654 /* If any node in a cycle is read_all or write_all
655 they all are. */
656 w_info = (struct ipa_dfs_info *) node->aux;
657 w = w_info->next_cycle;
658 while (w && (!read_all || !write_all))
659 {
660 /* When function is overwrittable, we can not assume anything. */
661 if (cgraph_function_body_availability (w) <= AVAIL_OVERWRITABLE)
662 read_write_all_from_decl (w, &read_all, &write_all);
663
664 for (e = w->callees; e; e = e->next_callee)
665 if (cgraph_function_body_availability (e->callee) <= AVAIL_OVERWRITABLE)
666 read_write_all_from_decl (e->callee, &read_all, &write_all);
667
668 for (ie = w->indirect_calls; ie; ie = ie->next_callee)
669 if (!(ie->indirect_info->ecf_flags & ECF_CONST))
670 {
671 read_all = true;
672 if (!cgraph_edge_cannot_lead_to_return (ie)
673 && !(ie->indirect_info->ecf_flags & ECF_PURE))
674 write_all = true;
675 }
676
677 w_info = (struct ipa_dfs_info *) w->aux;
678 w = w_info->next_cycle;
679 }
680
681
682 /* Initialized the bitmaps for the reduced nodes */
683 if (read_all)
684 node_g->statics_read = all_module_statics;
685 else
686 {
687 node_g->statics_read = BITMAP_ALLOC (&local_info_obstack);
688 bitmap_copy (node_g->statics_read,
689 node_l->statics_read);
690 }
691 if (write_all)
692 node_g->statics_written = all_module_statics;
693 else
694 {
695 node_g->statics_written = BITMAP_ALLOC (&local_info_obstack);
696 bitmap_copy (node_g->statics_written,
697 node_l->statics_written);
698 }
699
700 propagate_bits (node_g, node);
701 w_info = (struct ipa_dfs_info *) node->aux;
702 w = w_info->next_cycle;
703 while (w && (!read_all || !write_all))
704 {
705 ipa_reference_vars_info_t w_ri =
706 get_reference_vars_info (w);
707 ipa_reference_local_vars_info_t w_l = &w_ri->local;
708 int flags = flags_from_decl_or_type (w->decl);
709
710 /* These global bitmaps are initialized from the local info
711 of all of the nodes in the region. However there is no
712 need to do any work if the bitmaps were set to
713 all_module_statics. */
714 if (!read_all && !(flags & ECF_CONST))
715 bitmap_ior_into (node_g->statics_read,
716 w_l->statics_read);
717 if (!write_all
718 && !(flags & ECF_PURE)
719 && !cgraph_node_cannot_return (w))
720 bitmap_ior_into (node_g->statics_written,
721 w_l->statics_written);
722 propagate_bits (node_g, w);
723 w_info = (struct ipa_dfs_info *) w->aux;
724 w = w_info->next_cycle;
725 }
726
727 /* All nodes within a cycle have the same global info bitmaps. */
728 node_info->global = *node_g;
729 w_info = (struct ipa_dfs_info *) node->aux;
730 w = w_info->next_cycle;
731 while (w)
732 {
733 ipa_reference_vars_info_t w_ri =
734 get_reference_vars_info (w);
735
736 w_ri->global = *node_g;
737
738 w_info = (struct ipa_dfs_info *) w->aux;
739 w = w_info->next_cycle;
740 }
741 }
742
743 if (dump_file)
744 {
745 for (i = 0; i < order_pos; i++ )
746 {
747 ipa_reference_vars_info_t node_info;
748 ipa_reference_global_vars_info_t node_g;
749 ipa_reference_local_vars_info_t node_l;
750 unsigned int index;
751 bitmap_iterator bi;
752 struct ipa_dfs_info * w_info;
753
754 node = order[i];
755 node_info = get_reference_vars_info (node);
756 node_g = &node_info->global;
757 node_l = &node_info->local;
758 fprintf (dump_file,
759 "\nFunction name:%s/%i:",
760 cgraph_node_name (node), node->uid);
761 fprintf (dump_file, "\n locals read: ");
762 if (node_l->statics_read)
763 EXECUTE_IF_SET_IN_BITMAP (node_l->statics_read,
764 0, index, bi)
765 {
766 fprintf (dump_file, "%s ",
767 get_static_name (index));
768 }
769 fprintf (dump_file, "\n locals written: ");
770 if (node_l->statics_written)
771 EXECUTE_IF_SET_IN_BITMAP (node_l->statics_written,
772 0, index, bi)
773 {
774 fprintf(dump_file, "%s ",
775 get_static_name (index));
776 }
777
778 w_info = (struct ipa_dfs_info *) node->aux;
779 w = w_info->next_cycle;
780 while (w)
781 {
782 ipa_reference_vars_info_t w_ri =
783 get_reference_vars_info (w);
784 ipa_reference_local_vars_info_t w_l = &w_ri->local;
785 fprintf (dump_file, "\n next cycle: %s/%i ",
786 cgraph_node_name (w), w->uid);
787 fprintf (dump_file, "\n locals read: ");
788 if (w_l->statics_read)
789 EXECUTE_IF_SET_IN_BITMAP (w_l->statics_read,
790 0, index, bi)
791 {
792 fprintf (dump_file, "%s ",
793 get_static_name (index));
794 }
795
796 fprintf (dump_file, "\n locals written: ");
797 if (w_l->statics_written)
798 EXECUTE_IF_SET_IN_BITMAP (w_l->statics_written,
799 0, index, bi)
800 {
801 fprintf (dump_file, "%s ",
802 get_static_name (index));
803 }
804
805 w_info = (struct ipa_dfs_info *) w->aux;
806 w = w_info->next_cycle;
807 }
808 fprintf (dump_file, "\n globals read: ");
809 if (node_g->statics_read == all_module_statics)
810 fprintf (dump_file, "ALL");
811 else
812 EXECUTE_IF_SET_IN_BITMAP (node_g->statics_read,
813 0, index, bi)
814 {
815 fprintf (dump_file, "%s ",
816 get_static_name (index));
817 }
818 fprintf (dump_file, "\n globals written: ");
819 if (node_g->statics_written == all_module_statics)
820 fprintf (dump_file, "ALL");
821 else
822 EXECUTE_IF_SET_IN_BITMAP (node_g->statics_written,
823 0, index, bi)
824 {
825 fprintf (dump_file, "%s ",
826 get_static_name (index));
827 }
828 }
829 }
830
831 /* Cleanup. */
832 for (node = cgraph_nodes; node; node = node->next)
833 {
834 ipa_reference_vars_info_t node_info;
835 ipa_reference_global_vars_info_t node_g;
836 ipa_reference_optimization_summary_t opt;
837
838 if (!node->analyzed)
839 continue;
840
841 node_info = get_reference_vars_info (node);
842 if (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE)
843 {
844 node_g = &node_info->global;
845
846 opt = XCNEW (struct ipa_reference_optimization_summary_d);
847 set_reference_optimization_summary (node, opt);
848
849 /* Create the complimentary sets. */
850
851 if (bitmap_empty_p (node_g->statics_read))
852 opt->statics_not_read = all_module_statics;
853 else
854 {
855 opt->statics_not_read
856 = BITMAP_ALLOC (&optimization_summary_obstack);
857 if (node_g->statics_read != all_module_statics)
858 bitmap_and_compl (opt->statics_not_read,
859 all_module_statics,
860 node_g->statics_read);
861 }
862
863 if (bitmap_empty_p (node_g->statics_written))
864 opt->statics_not_written = all_module_statics;
865 else
866 {
867 opt->statics_not_written
868 = BITMAP_ALLOC (&optimization_summary_obstack);
869 if (node_g->statics_written != all_module_statics)
870 bitmap_and_compl (opt->statics_not_written,
871 all_module_statics,
872 node_g->statics_written);
873 }
874 }
875 if (node_info)
876 free (node_info);
877 if (node->aux)
878 {
879 free (node->aux);
880 node->aux = NULL;
881 }
882 }
883
884 free (order);
885
886 bitmap_obstack_release (&local_info_obstack);
887 VEC_free (ipa_reference_vars_info_t, heap, ipa_reference_vars_vector);
888 ipa_reference_vars_vector = NULL;
889 if (dump_file)
890 splay_tree_delete (reference_vars_to_consider);
891 reference_vars_to_consider = NULL;
892 return 0;
893 }
894
895 /* Return true if we need to write summary of NODE. */
896
897 static bool
898 write_node_summary_p (struct cgraph_node *node,
899 cgraph_node_set set,
900 varpool_node_set vset,
901 bitmap ltrans_statics)
902 {
903 ipa_reference_optimization_summary_t info;
904
905 /* See if we have (non-empty) info. */
906 if (!node->analyzed || node->global.inlined_to)
907 return false;
908 info = get_reference_optimization_summary (node);
909 if (!info || (bitmap_empty_p (info->statics_not_read)
910 && bitmap_empty_p (info->statics_not_written)))
911 return false;
912
913 /* See if we want to encode it.
914 Encode also referenced functions since constant folding might turn it into
915 a direct call.
916
917 In future we might also want to include summaries of functions references
918 by initializers of constant variables references in current unit. */
919 if (!reachable_from_this_partition_p (node, set)
920 && !referenced_from_this_partition_p (&node->ref_list, set, vset))
921 return false;
922
923 /* See if the info has non-empty intersections with vars we want to encode. */
924 if (!bitmap_intersect_p (info->statics_not_read, ltrans_statics)
925 && !bitmap_intersect_p (info->statics_not_written, ltrans_statics))
926 return false;
927 return true;
928 }
929
930 /* Stream out BITS&LTRANS_STATICS as list of decls to OB.
931 LTRANS_STATICS_BITCOUNT specify number of bits in LTRANS_STATICS
932 or -1. When it is positive, just output -1 when
933 BITS&LTRANS_STATICS == BITS&LTRANS_STATICS. */
934
935 static void
936 stream_out_bitmap (struct lto_simple_output_block *ob,
937 bitmap bits, bitmap ltrans_statics,
938 int ltrans_statics_bitcount)
939 {
940 int count = 0;
941 unsigned int index;
942 bitmap_iterator bi;
943 if (bits == all_module_statics)
944 {
945 lto_output_sleb128_stream (ob->main_stream, -1);
946 return;
947 }
948 EXECUTE_IF_AND_IN_BITMAP (bits, ltrans_statics, 0, index, bi)
949 count ++;
950 if (count == ltrans_statics_bitcount)
951 {
952 lto_output_sleb128_stream (ob->main_stream, -1);
953 return;
954 }
955 lto_output_sleb128_stream (ob->main_stream, count);
956 if (!count)
957 return;
958 EXECUTE_IF_AND_IN_BITMAP (bits, ltrans_statics, 0, index, bi)
959 {
960 tree decl = (tree)splay_tree_lookup (reference_vars_to_consider, index)->value;
961 lto_output_var_decl_index(ob->decl_state, ob->main_stream, decl);
962 }
963 }
964
965 /* Serialize the ipa info for lto. */
966
967 static void
968 ipa_reference_write_optimization_summary (cgraph_node_set set,
969 varpool_node_set vset)
970 {
971 struct cgraph_node *node;
972 struct lto_simple_output_block *ob
973 = lto_create_simple_output_block (LTO_section_ipa_reference);
974 unsigned int count = 0;
975 int ltrans_statics_bitcount = 0;
976 lto_cgraph_encoder_t encoder = ob->decl_state->cgraph_node_encoder;
977 lto_varpool_encoder_t varpool_encoder = ob->decl_state->varpool_node_encoder;
978 bitmap ltrans_statics = BITMAP_ALLOC (NULL);
979 int i;
980
981 reference_vars_to_consider = splay_tree_new (splay_tree_compare_ints, 0, 0);
982
983 /* See what variables we are interested in. */
984 for (i = 0; i < lto_varpool_encoder_size (varpool_encoder); i++)
985 {
986 struct varpool_node *vnode = lto_varpool_encoder_deref (varpool_encoder, i);
987 if (!vnode->externally_visible
988 && vnode->analyzed
989 && bitmap_bit_p (all_module_statics, DECL_UID (vnode->decl))
990 && referenced_from_this_partition_p (&vnode->ref_list, set, vset))
991 {
992 tree decl = vnode->decl;
993 bitmap_set_bit (ltrans_statics, DECL_UID (decl));
994 splay_tree_insert (reference_vars_to_consider,
995 DECL_UID (decl), (splay_tree_value)decl);
996 ltrans_statics_bitcount ++;
997 }
998 }
999
1000
1001 if (ltrans_statics_bitcount)
1002 for (i = 0; i < lto_cgraph_encoder_size (encoder); i++)
1003 if (write_node_summary_p (lto_cgraph_encoder_deref (encoder, i),
1004 set, vset, ltrans_statics))
1005 count++;
1006
1007 lto_output_uleb128_stream (ob->main_stream, count);
1008 if (count)
1009 stream_out_bitmap (ob, ltrans_statics, ltrans_statics,
1010 -1);
1011
1012 /* Process all of the functions. */
1013 if (ltrans_statics_bitcount)
1014 for (i = 0; i < lto_cgraph_encoder_size (encoder); i++)
1015 {
1016 node = lto_cgraph_encoder_deref (encoder, i);
1017 if (write_node_summary_p (node, set, vset, ltrans_statics))
1018 {
1019 ipa_reference_optimization_summary_t info;
1020 int node_ref;
1021
1022 info = get_reference_optimization_summary (node);
1023 node_ref = lto_cgraph_encoder_encode (encoder, node);
1024 lto_output_uleb128_stream (ob->main_stream, node_ref);
1025
1026 stream_out_bitmap (ob, info->statics_not_read, ltrans_statics,
1027 ltrans_statics_bitcount);
1028 stream_out_bitmap (ob, info->statics_not_written, ltrans_statics,
1029 ltrans_statics_bitcount);
1030 }
1031 }
1032 BITMAP_FREE (ltrans_statics);
1033 lto_destroy_simple_output_block (ob);
1034 splay_tree_delete (reference_vars_to_consider);
1035 }
1036
1037 /* Deserialize the ipa info for lto. */
1038
1039 static void
1040 ipa_reference_read_optimization_summary (void)
1041 {
1042 struct lto_file_decl_data ** file_data_vec
1043 = lto_get_file_decl_data ();
1044 struct lto_file_decl_data * file_data;
1045 unsigned int j = 0;
1046 bitmap_obstack_initialize (&optimization_summary_obstack);
1047
1048 node_removal_hook_holder =
1049 cgraph_add_node_removal_hook (&remove_node_data, NULL);
1050 node_duplication_hook_holder =
1051 cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
1052 all_module_statics = BITMAP_ALLOC (&optimization_summary_obstack);
1053
1054 while ((file_data = file_data_vec[j++]))
1055 {
1056 const char *data;
1057 size_t len;
1058 struct lto_input_block *ib
1059 = lto_create_simple_input_block (file_data,
1060 LTO_section_ipa_reference,
1061 &data, &len);
1062 if (ib)
1063 {
1064 unsigned int i;
1065 unsigned int f_count = lto_input_uleb128 (ib);
1066 int b_count;
1067 if (!f_count)
1068 continue;
1069 b_count = lto_input_sleb128 (ib);
1070 if (dump_file)
1071 fprintf (dump_file, "all module statics:");
1072 for (i = 0; i < (unsigned int)b_count; i++)
1073 {
1074 unsigned int var_index = lto_input_uleb128 (ib);
1075 tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1076 var_index);
1077 bitmap_set_bit (all_module_statics, DECL_UID (v_decl));
1078 if (dump_file)
1079 fprintf (dump_file, " %s",
1080 lang_hooks.decl_printable_name (v_decl, 2));
1081 }
1082
1083 for (i = 0; i < f_count; i++)
1084 {
1085 unsigned int j, index;
1086 struct cgraph_node *node;
1087 ipa_reference_optimization_summary_t info;
1088 int v_count;
1089 lto_cgraph_encoder_t encoder;
1090
1091 index = lto_input_uleb128 (ib);
1092 encoder = file_data->cgraph_node_encoder;
1093 node = lto_cgraph_encoder_deref (encoder, index);
1094 info = XCNEW (struct ipa_reference_optimization_summary_d);
1095 set_reference_optimization_summary (node, info);
1096 info->statics_not_read = BITMAP_ALLOC (&optimization_summary_obstack);
1097 info->statics_not_written = BITMAP_ALLOC (&optimization_summary_obstack);
1098 if (dump_file)
1099 fprintf (dump_file,
1100 "\nFunction name:%s/%i:\n static not read:",
1101 cgraph_node_name (node), node->uid);
1102
1103 /* Set the statics not read. */
1104 v_count = lto_input_sleb128 (ib);
1105 if (v_count == -1)
1106 {
1107 info->statics_not_read = all_module_statics;
1108 if (dump_file)
1109 fprintf (dump_file, " all module statics");
1110 }
1111 else
1112 for (j = 0; j < (unsigned int)v_count; j++)
1113 {
1114 unsigned int var_index = lto_input_uleb128 (ib);
1115 tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1116 var_index);
1117 bitmap_set_bit (info->statics_not_read, DECL_UID (v_decl));
1118 if (dump_file)
1119 fprintf (dump_file, " %s",
1120 lang_hooks.decl_printable_name (v_decl, 2));
1121 }
1122
1123 if (dump_file)
1124 fprintf (dump_file,
1125 "\n static not written:");
1126 /* Set the statics not written. */
1127 v_count = lto_input_sleb128 (ib);
1128 if (v_count == -1)
1129 {
1130 info->statics_not_written = all_module_statics;
1131 if (dump_file)
1132 fprintf (dump_file, " all module statics");
1133 }
1134 else
1135 for (j = 0; j < (unsigned int)v_count; j++)
1136 {
1137 unsigned int var_index = lto_input_uleb128 (ib);
1138 tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1139 var_index);
1140 bitmap_set_bit (info->statics_not_written, DECL_UID (v_decl));
1141 if (dump_file)
1142 fprintf (dump_file, " %s",
1143 lang_hooks.decl_printable_name (v_decl, 2));
1144 }
1145 if (dump_file)
1146 fprintf (dump_file, "\n");
1147 }
1148
1149 lto_destroy_simple_input_block (file_data,
1150 LTO_section_ipa_reference,
1151 ib, data, len);
1152 }
1153 else
1154 /* Fatal error here. We do not want to support compiling ltrans units with
1155 different version of compiler or different flags than the WPA unit, so
1156 this should never happen. */
1157 fatal_error ("ipa reference summary is missing in ltrans unit");
1158 }
1159 }
1160
1161 static bool
1162 gate_reference (void)
1163 {
1164 return (flag_ipa_reference
1165 /* Don't bother doing anything if the program has errors. */
1166 && !seen_error ());
1167 }
1168
1169 struct ipa_opt_pass_d pass_ipa_reference =
1170 {
1171 {
1172 IPA_PASS,
1173 "static-var", /* name */
1174 gate_reference, /* gate */
1175 propagate, /* execute */
1176 NULL, /* sub */
1177 NULL, /* next */
1178 0, /* static_pass_number */
1179 TV_IPA_REFERENCE, /* tv_id */
1180 0, /* properties_required */
1181 0, /* properties_provided */
1182 0, /* properties_destroyed */
1183 0, /* todo_flags_start */
1184 0 /* todo_flags_finish */
1185 },
1186 NULL, /* generate_summary */
1187 NULL, /* write_summary */
1188 NULL, /* read_summary */
1189 ipa_reference_write_optimization_summary,/* write_optimization_summary */
1190 ipa_reference_read_optimization_summary,/* read_optimization_summary */
1191 NULL, /* stmt_fixup */
1192 0, /* TODOs */
1193 NULL, /* function_transform */
1194 NULL /* variable_transform */
1195 };