]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/ipa-reference.c
* output.h (__gcc_host_wide_int__): Move to hwint.h.
[thirdparty/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 "flags.h"
57 #include "timevar.h"
58 #include "diagnostic.h"
59 #include "langhooks.h"
60 #include "data-streamer.h"
61 #include "lto-streamer.h"
62
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);
68
69 /* The static variables defined within the compilation unit that are
70 loaded or stored directly by function that owns this structure. */
71
72 struct ipa_reference_local_vars_info_d
73 {
74 bitmap statics_read;
75 bitmap statics_written;
76 };
77
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. */
82
83 struct ipa_reference_global_vars_info_d
84 {
85 bitmap statics_read;
86 bitmap statics_written;
87 };
88
89 /* Information we save about every function after ipa-reference is completed. */
90
91 struct ipa_reference_optimization_summary_d
92 {
93 bitmap statics_not_read;
94 bitmap statics_not_written;
95 };
96
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;
100
101 struct ipa_reference_vars_info_d
102 {
103 struct ipa_reference_local_vars_info_d local;
104 struct ipa_reference_global_vars_info_d global;
105 };
106
107 typedef struct ipa_reference_vars_info_d *ipa_reference_vars_info_t;
108
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;
112
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;
117
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;
123
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;
127
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;
135
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)
139 {
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);
146 }
147
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)
151 {
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);
159 }
160
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)
165 {
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);
173 }
174
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)
179 {
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);
188 }
189
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. */
193
194 bitmap
195 ipa_reference_get_not_read_global (struct cgraph_node *fn)
196 {
197 ipa_reference_optimization_summary_t info;
198
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->symbol.decl) & ECF_LEAF)
203 return all_module_statics;
204 else
205 return NULL;
206 }
207
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. */
212
213 bitmap
214 ipa_reference_get_not_written_global (struct cgraph_node *fn)
215 {
216 ipa_reference_optimization_summary_t info;
217
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->symbol.decl) & ECF_LEAF)
222 return all_module_statics;
223 else
224 return NULL;
225 }
226
227 \f
228
229 /* Add VAR to all_module_statics and the two
230 reference_vars_to_consider* sets. */
231
232 static inline void
233 add_static_var (tree var)
234 {
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);
241 }
242
243 /* Return true if the variable T is the right kind of static variable to
244 perform compilation unit scope escape analysis. */
245
246 static inline bool
247 is_proper_for_analysis (tree t)
248 {
249 /* If the variable has the "used" attribute, treat it as if it had a
250 been touched by the devil. */
251 if (DECL_PRESERVE_P (t))
252 return false;
253
254 /* Do not want to do anything with volatile except mark any
255 function that uses one to be not const or pure. */
256 if (TREE_THIS_VOLATILE (t))
257 return false;
258
259 /* We do not need to analyze readonly vars, we already know they do not
260 alias. */
261 if (TREE_READONLY (t))
262 return false;
263
264 /* This is a variable we care about. Check if we have seen it
265 before, and if not add it the set of variables we care about. */
266 if (all_module_statics
267 && !bitmap_bit_p (all_module_statics, DECL_UID (t)))
268 add_static_var (t);
269
270 return true;
271 }
272
273 /* Lookup the tree node for the static variable that has UID and
274 convert the name to a string for debugging. */
275
276 static const char *
277 get_static_name (int index)
278 {
279 splay_tree_node stn =
280 splay_tree_lookup (reference_vars_to_consider, index);
281 if (stn)
282 return lang_hooks.decl_printable_name ((tree)(stn->value), 2);
283 return NULL;
284 }
285
286 /* Or in all of the bits from every callee of X into X_GLOBAL, the caller's cycle,
287 bit vector. There are several cases to check to avoid the sparse
288 bitmap oring. */
289
290 static void
291 propagate_bits (ipa_reference_global_vars_info_t x_global, struct cgraph_node *x)
292 {
293 struct cgraph_edge *e;
294 for (e = x->callees; e; e = e->next_callee)
295 {
296 enum availability avail;
297 struct cgraph_node *y = cgraph_function_node (e->callee, &avail);
298
299 if (!y)
300 continue;
301 /* Only look into nodes we can propagate something. */
302 if (avail > AVAIL_OVERWRITABLE
303 || (avail == AVAIL_OVERWRITABLE
304 && (flags_from_decl_or_type (y->symbol.decl) & ECF_LEAF)))
305 {
306 int flags = flags_from_decl_or_type (y->symbol.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->symbol.ref_list, i, ref); i++)
428 {
429 if (!symtab_variable_p (ref->referred))
430 continue;
431 var = ipa_ref_varpool_node (ref)->symbol.decl;
432 if (!is_proper_for_analysis (var))
433 continue;
434 switch (ref->use)
435 {
436 case IPA_REF_LOAD:
437 bitmap_set_bit (local->statics_read, DECL_UID (var));
438 break;
439 case IPA_REF_STORE:
440 if (ipa_ref_cannot_lead_to_return (ref))
441 break;
442 bitmap_set_bit (local->statics_written, DECL_UID (var));
443 break;
444 case IPA_REF_ADDR:
445 break;
446 }
447 }
448
449 if (cgraph_node_cannot_return (fn))
450 bitmap_clear (local->statics_written);
451 }
452
453 static bitmap
454 copy_global_bitmap (bitmap src)
455 {
456 bitmap dst;
457 if (!src)
458 return NULL;
459 if (src == all_module_statics)
460 return all_module_statics;
461 dst = BITMAP_ALLOC (&optimization_summary_obstack);
462 bitmap_copy (dst, src);
463 return dst;
464 }
465
466
467 /* Called when new clone is inserted to callgraph late. */
468
469 static void
470 duplicate_node_data (struct cgraph_node *src, struct cgraph_node *dst,
471 void *data ATTRIBUTE_UNUSED)
472 {
473 ipa_reference_optimization_summary_t ginfo;
474 ipa_reference_optimization_summary_t dst_ginfo;
475
476 ginfo = get_reference_optimization_summary (src);
477 if (!ginfo)
478 return;
479 dst_ginfo = XCNEW (struct ipa_reference_optimization_summary_d);
480 set_reference_optimization_summary (dst, dst_ginfo);
481 dst_ginfo->statics_not_read = copy_global_bitmap (ginfo->statics_not_read);
482 dst_ginfo->statics_not_written = copy_global_bitmap (ginfo->statics_not_written);
483 }
484
485 /* Called when node is removed. */
486
487 static void
488 remove_node_data (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
489 {
490 ipa_reference_optimization_summary_t ginfo;
491 ginfo = get_reference_optimization_summary (node);
492 if (ginfo)
493 {
494 if (ginfo->statics_not_read
495 && ginfo->statics_not_read != all_module_statics)
496 BITMAP_FREE (ginfo->statics_not_read);
497
498 if (ginfo->statics_not_written
499 && ginfo->statics_not_written != all_module_statics)
500 BITMAP_FREE (ginfo->statics_not_written);
501 free (ginfo);
502 set_reference_optimization_summary (node, NULL);
503 }
504 }
505
506 /* Analyze each function in the cgraph to see which global or statics
507 are read or written. */
508
509 static void
510 generate_summary (void)
511 {
512 struct cgraph_node *node;
513 unsigned int index;
514 bitmap_iterator bi;
515 bitmap bm_temp;
516
517 ipa_init ();
518 bm_temp = BITMAP_ALLOC (&local_info_obstack);
519
520 /* Process all of the functions next. */
521 FOR_EACH_DEFINED_FUNCTION (node)
522 analyze_function (node);
523
524 if (dump_file)
525 EXECUTE_IF_SET_IN_BITMAP (all_module_statics, 0, index, bi)
526 {
527 fprintf (dump_file, "\nPromotable global:%s",
528 get_static_name (index));
529 }
530
531 BITMAP_FREE(bm_temp);
532
533 if (dump_file)
534 FOR_EACH_DEFINED_FUNCTION (node)
535 if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
536 {
537 ipa_reference_local_vars_info_t l;
538 unsigned int index;
539 bitmap_iterator bi;
540
541 l = &get_reference_vars_info (node)->local;
542 fprintf (dump_file,
543 "\nFunction name:%s/%i:",
544 cgraph_node_asm_name (node), node->symbol.order);
545 fprintf (dump_file, "\n locals read: ");
546 if (l->statics_read)
547 EXECUTE_IF_SET_IN_BITMAP (l->statics_read,
548 0, index, bi)
549 {
550 fprintf (dump_file, "%s ",
551 get_static_name (index));
552 }
553 fprintf (dump_file, "\n locals written: ");
554 if (l->statics_written)
555 EXECUTE_IF_SET_IN_BITMAP (l->statics_written,
556 0, index, bi)
557 {
558 fprintf(dump_file, "%s ",
559 get_static_name (index));
560 }
561 }
562 }
563 \f
564 /* Set READ_ALL/WRITE_ALL based on decl flags of NODE. */
565
566 static void
567 read_write_all_from_decl (struct cgraph_node *node, bool * read_all,
568 bool * write_all)
569 {
570 tree decl = node->symbol.decl;
571 int flags = flags_from_decl_or_type (decl);
572 if ((flags & ECF_LEAF)
573 && cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
574 ;
575 else if (flags & ECF_CONST)
576 ;
577 else if ((flags & ECF_PURE)
578 || cgraph_node_cannot_return (node))
579 {
580 *read_all = true;
581 if (dump_file && (dump_flags & TDF_DETAILS))
582 fprintf (dump_file, " %s/%i -> read all\n",
583 cgraph_node_asm_name (node), node->symbol.order);
584 }
585 else
586 {
587 /* TODO: To be able to produce sane results, we should also handle
588 common builtins, in particular throw. */
589 *read_all = true;
590 *write_all = true;
591 if (dump_file && (dump_flags & TDF_DETAILS))
592 fprintf (dump_file, " %s/%i -> read all, write all\n",
593 cgraph_node_asm_name (node), node->symbol.order);
594 }
595 }
596
597 /* Produce the global information by preforming a transitive closure
598 on the local information that was produced by ipa_analyze_function */
599
600 static unsigned int
601 propagate (void)
602 {
603 struct cgraph_node *node;
604 struct varpool_node *vnode;
605 struct cgraph_node *w;
606 struct cgraph_node **order =
607 XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
608 int order_pos;
609 int i;
610
611 if (dump_file)
612 dump_cgraph (dump_file);
613
614 ipa_discover_readonly_nonaddressable_vars ();
615 generate_summary ();
616
617 /* Now we know what vars are really statics; prune out those that aren't. */
618 FOR_EACH_VARIABLE (vnode)
619 if (vnode->symbol.externally_visible
620 || TREE_ADDRESSABLE (vnode->symbol.decl)
621 || TREE_READONLY (vnode->symbol.decl)
622 || !is_proper_for_analysis (vnode->symbol.decl)
623 || !vnode->analyzed)
624 bitmap_clear_bit (all_module_statics, DECL_UID (vnode->symbol.decl));
625
626 /* Forget info we collected "just for fun" on variables that turned out to be
627 non-local. */
628 FOR_EACH_DEFINED_FUNCTION (node)
629 {
630 ipa_reference_local_vars_info_t node_l;
631
632 node_l = &get_reference_vars_info (node)->local;
633 if (node_l->statics_read != all_module_statics)
634 bitmap_and_into (node_l->statics_read, all_module_statics);
635 if (node_l->statics_written != all_module_statics)
636 bitmap_and_into (node_l->statics_written, all_module_statics);
637 }
638
639 /* Propagate the local information through the call graph to produce
640 the global information. All the nodes within a cycle will have
641 the same info so we collapse cycles first. Then we can do the
642 propagation in one pass from the leaves to the roots. */
643 order_pos = ipa_reduced_postorder (order, true, true, NULL);
644 if (dump_file)
645 ipa_print_order (dump_file, "reduced", order, order_pos);
646
647 for (i = 0; i < order_pos; i++ )
648 {
649 ipa_reference_vars_info_t node_info;
650 ipa_reference_global_vars_info_t node_g;
651 ipa_reference_local_vars_info_t node_l;
652 struct cgraph_edge *e, *ie;
653
654 bool read_all;
655 bool write_all;
656 struct ipa_dfs_info * w_info;
657
658 node = order[i];
659 if (node->alias)
660 continue;
661 node_info = get_reference_vars_info (node);
662 gcc_assert (node_info);
663
664
665 if (dump_file && (dump_flags & TDF_DETAILS))
666 fprintf (dump_file, "Starting cycle with %s/%i\n",
667 cgraph_node_asm_name (node), node->symbol.order);
668
669 node_l = &node_info->local;
670 node_g = &node_info->global;
671
672 read_all = false;
673 write_all = false;
674
675 /* When function is overwritable, we can not assume anything. */
676 if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
677 read_write_all_from_decl (node, &read_all, &write_all);
678
679 for (e = node->callees; e; e = e->next_callee)
680 {
681 enum availability avail;
682 struct cgraph_node *callee = cgraph_function_node (e->callee, &avail);
683 if (!callee || avail <= AVAIL_OVERWRITABLE)
684 read_write_all_from_decl (callee, &read_all, &write_all);
685 }
686
687 for (ie = node->indirect_calls; ie; ie = ie->next_callee)
688 if (!(ie->indirect_info->ecf_flags & ECF_CONST))
689 {
690 read_all = true;
691 if (dump_file && (dump_flags & TDF_DETAILS))
692 fprintf (dump_file, " indirect call -> read all\n");
693 if (!cgraph_edge_cannot_lead_to_return (ie)
694 && !(ie->indirect_info->ecf_flags & ECF_PURE))
695 {
696 if (dump_file && (dump_flags & TDF_DETAILS))
697 fprintf (dump_file, " indirect call -> write all\n");
698 write_all = true;
699 }
700 }
701
702
703 /* If any node in a cycle is read_all or write_all
704 they all are. */
705 w_info = (struct ipa_dfs_info *) node->symbol.aux;
706 w = w_info->next_cycle;
707 while (w && (!read_all || !write_all))
708 {
709 if (dump_file && (dump_flags & TDF_DETAILS))
710 fprintf (dump_file, " Visiting %s/%i\n",
711 cgraph_node_asm_name (w), w->symbol.order);
712 /* When function is overwritable, we can not assume anything. */
713 if (cgraph_function_body_availability (w) <= AVAIL_OVERWRITABLE)
714 read_write_all_from_decl (w, &read_all, &write_all);
715
716 for (e = w->callees; e; e = e->next_callee)
717 {
718 enum availability avail;
719 struct cgraph_node *callee = cgraph_function_node (e->callee, &avail);
720
721 if (avail <= AVAIL_OVERWRITABLE)
722 read_write_all_from_decl (callee, &read_all, &write_all);
723 }
724
725 for (ie = w->indirect_calls; ie; ie = ie->next_callee)
726 if (!(ie->indirect_info->ecf_flags & ECF_CONST))
727 {
728 read_all = true;
729 if (dump_file && (dump_flags & TDF_DETAILS))
730 fprintf (dump_file, " indirect call -> read all\n");
731 if (!cgraph_edge_cannot_lead_to_return (ie)
732 && !(ie->indirect_info->ecf_flags & ECF_PURE))
733 {
734 write_all = true;
735 if (dump_file && (dump_flags & TDF_DETAILS))
736 fprintf (dump_file, " indirect call -> write all\n");
737 }
738 }
739
740 w_info = (struct ipa_dfs_info *) w->symbol.aux;
741 w = w_info->next_cycle;
742 }
743
744
745 /* Initialized the bitmaps for the reduced nodes */
746 if (read_all)
747 node_g->statics_read = all_module_statics;
748 else
749 {
750 node_g->statics_read = BITMAP_ALLOC (&local_info_obstack);
751 bitmap_copy (node_g->statics_read,
752 node_l->statics_read);
753 }
754 if (write_all)
755 node_g->statics_written = all_module_statics;
756 else
757 {
758 node_g->statics_written = BITMAP_ALLOC (&local_info_obstack);
759 bitmap_copy (node_g->statics_written,
760 node_l->statics_written);
761 }
762
763 propagate_bits (node_g, node);
764 w_info = (struct ipa_dfs_info *) node->symbol.aux;
765 w = w_info->next_cycle;
766 while (w && (!read_all || !write_all))
767 {
768 ipa_reference_vars_info_t w_ri =
769 get_reference_vars_info (w);
770 ipa_reference_local_vars_info_t w_l = &w_ri->local;
771 int flags = flags_from_decl_or_type (w->symbol.decl);
772
773 /* These global bitmaps are initialized from the local info
774 of all of the nodes in the region. However there is no
775 need to do any work if the bitmaps were set to
776 all_module_statics. */
777 if (!read_all && !(flags & ECF_CONST))
778 bitmap_ior_into (node_g->statics_read,
779 w_l->statics_read);
780 if (!write_all
781 && !(flags & ECF_PURE)
782 && !cgraph_node_cannot_return (w))
783 bitmap_ior_into (node_g->statics_written,
784 w_l->statics_written);
785 propagate_bits (node_g, w);
786 w_info = (struct ipa_dfs_info *) w->symbol.aux;
787 w = w_info->next_cycle;
788 }
789
790 /* All nodes within a cycle have the same global info bitmaps. */
791 node_info->global = *node_g;
792 w_info = (struct ipa_dfs_info *) node->symbol.aux;
793 w = w_info->next_cycle;
794 while (w)
795 {
796 ipa_reference_vars_info_t w_ri =
797 get_reference_vars_info (w);
798
799 w_ri->global = *node_g;
800
801 w_info = (struct ipa_dfs_info *) w->symbol.aux;
802 w = w_info->next_cycle;
803 }
804 }
805
806 if (dump_file)
807 {
808 for (i = 0; i < order_pos; i++ )
809 {
810 ipa_reference_vars_info_t node_info;
811 ipa_reference_global_vars_info_t node_g;
812 ipa_reference_local_vars_info_t node_l;
813 unsigned int index;
814 bitmap_iterator bi;
815 struct ipa_dfs_info * w_info;
816
817 node = order[i];
818 if (node->alias)
819 continue;
820 node_info = get_reference_vars_info (node);
821 node_g = &node_info->global;
822 node_l = &node_info->local;
823 fprintf (dump_file,
824 "\nFunction name:%s/%i:",
825 cgraph_node_asm_name (node), node->symbol.order);
826 fprintf (dump_file, "\n locals read: ");
827 if (node_l->statics_read)
828 EXECUTE_IF_SET_IN_BITMAP (node_l->statics_read,
829 0, index, bi)
830 {
831 fprintf (dump_file, "%s ",
832 get_static_name (index));
833 }
834 fprintf (dump_file, "\n locals written: ");
835 if (node_l->statics_written)
836 EXECUTE_IF_SET_IN_BITMAP (node_l->statics_written,
837 0, index, bi)
838 {
839 fprintf(dump_file, "%s ",
840 get_static_name (index));
841 }
842
843 w_info = (struct ipa_dfs_info *) node->symbol.aux;
844 w = w_info->next_cycle;
845 while (w)
846 {
847 ipa_reference_vars_info_t w_ri =
848 get_reference_vars_info (w);
849 ipa_reference_local_vars_info_t w_l = &w_ri->local;
850 fprintf (dump_file, "\n next cycle: %s/%i ",
851 cgraph_node_asm_name (w), w->symbol.order);
852 fprintf (dump_file, "\n locals read: ");
853 if (w_l->statics_read)
854 EXECUTE_IF_SET_IN_BITMAP (w_l->statics_read,
855 0, index, bi)
856 {
857 fprintf (dump_file, "%s ",
858 get_static_name (index));
859 }
860
861 fprintf (dump_file, "\n locals written: ");
862 if (w_l->statics_written)
863 EXECUTE_IF_SET_IN_BITMAP (w_l->statics_written,
864 0, index, bi)
865 {
866 fprintf (dump_file, "%s ",
867 get_static_name (index));
868 }
869
870 w_info = (struct ipa_dfs_info *) w->symbol.aux;
871 w = w_info->next_cycle;
872 }
873 fprintf (dump_file, "\n globals read: ");
874 if (node_g->statics_read == all_module_statics)
875 fprintf (dump_file, "ALL");
876 else
877 EXECUTE_IF_SET_IN_BITMAP (node_g->statics_read,
878 0, index, bi)
879 {
880 fprintf (dump_file, "%s ",
881 get_static_name (index));
882 }
883 fprintf (dump_file, "\n globals written: ");
884 if (node_g->statics_written == all_module_statics)
885 fprintf (dump_file, "ALL");
886 else
887 EXECUTE_IF_SET_IN_BITMAP (node_g->statics_written,
888 0, index, bi)
889 {
890 fprintf (dump_file, "%s ",
891 get_static_name (index));
892 }
893 }
894 }
895
896 /* Cleanup. */
897 FOR_EACH_DEFINED_FUNCTION (node)
898 {
899 ipa_reference_vars_info_t node_info;
900 ipa_reference_global_vars_info_t node_g;
901 ipa_reference_optimization_summary_t opt;
902
903 if (node->alias)
904 continue;
905
906 node_info = get_reference_vars_info (node);
907 if (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE
908 || (flags_from_decl_or_type (node->symbol.decl) & ECF_LEAF))
909 {
910 node_g = &node_info->global;
911
912 opt = XCNEW (struct ipa_reference_optimization_summary_d);
913 set_reference_optimization_summary (node, opt);
914
915 /* Create the complimentary sets. */
916
917 if (bitmap_empty_p (node_g->statics_read))
918 opt->statics_not_read = all_module_statics;
919 else
920 {
921 opt->statics_not_read
922 = BITMAP_ALLOC (&optimization_summary_obstack);
923 if (node_g->statics_read != all_module_statics)
924 bitmap_and_compl (opt->statics_not_read,
925 all_module_statics,
926 node_g->statics_read);
927 }
928
929 if (bitmap_empty_p (node_g->statics_written))
930 opt->statics_not_written = all_module_statics;
931 else
932 {
933 opt->statics_not_written
934 = BITMAP_ALLOC (&optimization_summary_obstack);
935 if (node_g->statics_written != all_module_statics)
936 bitmap_and_compl (opt->statics_not_written,
937 all_module_statics,
938 node_g->statics_written);
939 }
940 }
941 free (node_info);
942 }
943
944 ipa_free_postorder_info ();
945 free (order);
946
947 bitmap_obstack_release (&local_info_obstack);
948 VEC_free (ipa_reference_vars_info_t, heap, ipa_reference_vars_vector);
949 ipa_reference_vars_vector = NULL;
950 if (dump_file)
951 splay_tree_delete (reference_vars_to_consider);
952 reference_vars_to_consider = NULL;
953 return 0;
954 }
955
956 /* Return true if we need to write summary of NODE. */
957
958 static bool
959 write_node_summary_p (struct cgraph_node *node,
960 cgraph_node_set set,
961 varpool_node_set vset,
962 bitmap ltrans_statics)
963 {
964 ipa_reference_optimization_summary_t info;
965
966 /* See if we have (non-empty) info. */
967 if (!node->analyzed || node->global.inlined_to)
968 return false;
969 info = get_reference_optimization_summary (node);
970 if (!info || (bitmap_empty_p (info->statics_not_read)
971 && bitmap_empty_p (info->statics_not_written)))
972 return false;
973
974 /* See if we want to encode it.
975 Encode also referenced functions since constant folding might turn it into
976 a direct call.
977
978 In future we might also want to include summaries of functions references
979 by initializers of constant variables references in current unit. */
980 if (!reachable_from_this_partition_p (node, set)
981 && !referenced_from_this_partition_p (&node->symbol.ref_list, set, vset))
982 return false;
983
984 /* See if the info has non-empty intersections with vars we want to encode. */
985 if (!bitmap_intersect_p (info->statics_not_read, ltrans_statics)
986 && !bitmap_intersect_p (info->statics_not_written, ltrans_statics))
987 return false;
988 return true;
989 }
990
991 /* Stream out BITS&LTRANS_STATICS as list of decls to OB.
992 LTRANS_STATICS_BITCOUNT specify number of bits in LTRANS_STATICS
993 or -1. When it is positive, just output -1 when
994 BITS&LTRANS_STATICS == BITS&LTRANS_STATICS. */
995
996 static void
997 stream_out_bitmap (struct lto_simple_output_block *ob,
998 bitmap bits, bitmap ltrans_statics,
999 int ltrans_statics_bitcount)
1000 {
1001 int count = 0;
1002 unsigned int index;
1003 bitmap_iterator bi;
1004 if (bits == all_module_statics)
1005 {
1006 streamer_write_hwi_stream (ob->main_stream, -1);
1007 return;
1008 }
1009 EXECUTE_IF_AND_IN_BITMAP (bits, ltrans_statics, 0, index, bi)
1010 count ++;
1011 if (count == ltrans_statics_bitcount)
1012 {
1013 streamer_write_hwi_stream (ob->main_stream, -1);
1014 return;
1015 }
1016 streamer_write_hwi_stream (ob->main_stream, count);
1017 if (!count)
1018 return;
1019 EXECUTE_IF_AND_IN_BITMAP (bits, ltrans_statics, 0, index, bi)
1020 {
1021 tree decl = (tree)splay_tree_lookup (reference_vars_to_consider, index)->value;
1022 lto_output_var_decl_index(ob->decl_state, ob->main_stream, decl);
1023 }
1024 }
1025
1026 /* Serialize the ipa info for lto. */
1027
1028 static void
1029 ipa_reference_write_optimization_summary (cgraph_node_set set,
1030 varpool_node_set vset)
1031 {
1032 struct cgraph_node *node;
1033 struct lto_simple_output_block *ob
1034 = lto_create_simple_output_block (LTO_section_ipa_reference);
1035 unsigned int count = 0;
1036 int ltrans_statics_bitcount = 0;
1037 lto_cgraph_encoder_t encoder = ob->decl_state->cgraph_node_encoder;
1038 lto_varpool_encoder_t varpool_encoder = ob->decl_state->varpool_node_encoder;
1039 bitmap ltrans_statics = BITMAP_ALLOC (NULL);
1040 int i;
1041
1042 reference_vars_to_consider = splay_tree_new (splay_tree_compare_ints, 0, 0);
1043
1044 /* See what variables we are interested in. */
1045 for (i = 0; i < lto_varpool_encoder_size (varpool_encoder); i++)
1046 {
1047 struct varpool_node *vnode = lto_varpool_encoder_deref (varpool_encoder, i);
1048 if (bitmap_bit_p (all_module_statics, DECL_UID (vnode->symbol.decl))
1049 && referenced_from_this_partition_p (&vnode->symbol.ref_list, set, vset))
1050 {
1051 tree decl = vnode->symbol.decl;
1052 bitmap_set_bit (ltrans_statics, DECL_UID (decl));
1053 splay_tree_insert (reference_vars_to_consider,
1054 DECL_UID (decl), (splay_tree_value)decl);
1055 ltrans_statics_bitcount ++;
1056 }
1057 }
1058
1059
1060 if (ltrans_statics_bitcount)
1061 for (i = 0; i < lto_cgraph_encoder_size (encoder); i++)
1062 if (write_node_summary_p (lto_cgraph_encoder_deref (encoder, i),
1063 set, vset, ltrans_statics))
1064 count++;
1065
1066 streamer_write_uhwi_stream (ob->main_stream, count);
1067 if (count)
1068 stream_out_bitmap (ob, ltrans_statics, ltrans_statics,
1069 -1);
1070
1071 /* Process all of the functions. */
1072 if (ltrans_statics_bitcount)
1073 for (i = 0; i < lto_cgraph_encoder_size (encoder); i++)
1074 {
1075 node = lto_cgraph_encoder_deref (encoder, i);
1076 if (write_node_summary_p (node, set, vset, ltrans_statics))
1077 {
1078 ipa_reference_optimization_summary_t info;
1079 int node_ref;
1080
1081 info = get_reference_optimization_summary (node);
1082 node_ref = lto_cgraph_encoder_encode (encoder, node);
1083 streamer_write_uhwi_stream (ob->main_stream, node_ref);
1084
1085 stream_out_bitmap (ob, info->statics_not_read, ltrans_statics,
1086 ltrans_statics_bitcount);
1087 stream_out_bitmap (ob, info->statics_not_written, ltrans_statics,
1088 ltrans_statics_bitcount);
1089 }
1090 }
1091 BITMAP_FREE (ltrans_statics);
1092 lto_destroy_simple_output_block (ob);
1093 splay_tree_delete (reference_vars_to_consider);
1094 }
1095
1096 /* Deserialize the ipa info for lto. */
1097
1098 static void
1099 ipa_reference_read_optimization_summary (void)
1100 {
1101 struct lto_file_decl_data ** file_data_vec
1102 = lto_get_file_decl_data ();
1103 struct lto_file_decl_data * file_data;
1104 unsigned int j = 0;
1105 bitmap_obstack_initialize (&optimization_summary_obstack);
1106
1107 node_removal_hook_holder =
1108 cgraph_add_node_removal_hook (&remove_node_data, NULL);
1109 node_duplication_hook_holder =
1110 cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
1111 all_module_statics = BITMAP_ALLOC (&optimization_summary_obstack);
1112
1113 while ((file_data = file_data_vec[j++]))
1114 {
1115 const char *data;
1116 size_t len;
1117 struct lto_input_block *ib
1118 = lto_create_simple_input_block (file_data,
1119 LTO_section_ipa_reference,
1120 &data, &len);
1121 if (ib)
1122 {
1123 unsigned int i;
1124 unsigned int f_count = streamer_read_uhwi (ib);
1125 int b_count;
1126 if (!f_count)
1127 continue;
1128 b_count = streamer_read_hwi (ib);
1129 if (dump_file)
1130 fprintf (dump_file, "all module statics:");
1131 for (i = 0; i < (unsigned int)b_count; i++)
1132 {
1133 unsigned int var_index = streamer_read_uhwi (ib);
1134 tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1135 var_index);
1136 bitmap_set_bit (all_module_statics, DECL_UID (v_decl));
1137 if (dump_file)
1138 fprintf (dump_file, " %s",
1139 lang_hooks.decl_printable_name (v_decl, 2));
1140 }
1141
1142 for (i = 0; i < f_count; i++)
1143 {
1144 unsigned int j, index;
1145 struct cgraph_node *node;
1146 ipa_reference_optimization_summary_t info;
1147 int v_count;
1148 lto_cgraph_encoder_t encoder;
1149
1150 index = streamer_read_uhwi (ib);
1151 encoder = file_data->cgraph_node_encoder;
1152 node = lto_cgraph_encoder_deref (encoder, index);
1153 info = XCNEW (struct ipa_reference_optimization_summary_d);
1154 set_reference_optimization_summary (node, info);
1155 info->statics_not_read = BITMAP_ALLOC (&optimization_summary_obstack);
1156 info->statics_not_written = BITMAP_ALLOC (&optimization_summary_obstack);
1157 if (dump_file)
1158 fprintf (dump_file,
1159 "\nFunction name:%s/%i:\n static not read:",
1160 cgraph_node_asm_name (node), node->symbol.order);
1161
1162 /* Set the statics not read. */
1163 v_count = streamer_read_hwi (ib);
1164 if (v_count == -1)
1165 {
1166 info->statics_not_read = all_module_statics;
1167 if (dump_file)
1168 fprintf (dump_file, " all module statics");
1169 }
1170 else
1171 for (j = 0; j < (unsigned int)v_count; j++)
1172 {
1173 unsigned int var_index = streamer_read_uhwi (ib);
1174 tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1175 var_index);
1176 bitmap_set_bit (info->statics_not_read, DECL_UID (v_decl));
1177 if (dump_file)
1178 fprintf (dump_file, " %s",
1179 lang_hooks.decl_printable_name (v_decl, 2));
1180 }
1181
1182 if (dump_file)
1183 fprintf (dump_file,
1184 "\n static not written:");
1185 /* Set the statics not written. */
1186 v_count = streamer_read_hwi (ib);
1187 if (v_count == -1)
1188 {
1189 info->statics_not_written = all_module_statics;
1190 if (dump_file)
1191 fprintf (dump_file, " all module statics");
1192 }
1193 else
1194 for (j = 0; j < (unsigned int)v_count; j++)
1195 {
1196 unsigned int var_index = streamer_read_uhwi (ib);
1197 tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1198 var_index);
1199 bitmap_set_bit (info->statics_not_written, DECL_UID (v_decl));
1200 if (dump_file)
1201 fprintf (dump_file, " %s",
1202 lang_hooks.decl_printable_name (v_decl, 2));
1203 }
1204 if (dump_file)
1205 fprintf (dump_file, "\n");
1206 }
1207
1208 lto_destroy_simple_input_block (file_data,
1209 LTO_section_ipa_reference,
1210 ib, data, len);
1211 }
1212 else
1213 /* Fatal error here. We do not want to support compiling ltrans units with
1214 different version of compiler or different flags than the WPA unit, so
1215 this should never happen. */
1216 fatal_error ("ipa reference summary is missing in ltrans unit");
1217 }
1218 }
1219
1220 static bool
1221 gate_reference (void)
1222 {
1223 return (flag_ipa_reference
1224 /* Don't bother doing anything if the program has errors. */
1225 && !seen_error ());
1226 }
1227
1228 struct ipa_opt_pass_d pass_ipa_reference =
1229 {
1230 {
1231 IPA_PASS,
1232 "static-var", /* name */
1233 gate_reference, /* gate */
1234 propagate, /* execute */
1235 NULL, /* sub */
1236 NULL, /* next */
1237 0, /* static_pass_number */
1238 TV_IPA_REFERENCE, /* tv_id */
1239 0, /* properties_required */
1240 0, /* properties_provided */
1241 0, /* properties_destroyed */
1242 0, /* todo_flags_start */
1243 0 /* todo_flags_finish */
1244 },
1245 NULL, /* generate_summary */
1246 NULL, /* write_summary */
1247 NULL, /* read_summary */
1248 ipa_reference_write_optimization_summary,/* write_optimization_summary */
1249 ipa_reference_read_optimization_summary,/* read_optimization_summary */
1250 NULL, /* stmt_fixup */
1251 0, /* TODOs */
1252 NULL, /* function_transform */
1253 NULL /* variable_transform */
1254 };