2015-05-12 Pierre-Marie de Rodat <derodat@adacore.com>
[official-gcc.git] / gcc / ipa-reference.c
bloba420cb2042b4084f5c18c8e00087054f67ede462
1 /* Callgraph based analysis of static variables.
2 Copyright (C) 2004-2015 Free Software Foundation, Inc.
3 Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 /* This file gathers information about how variables whose scope is
22 confined to the compilation unit are used.
24 The transitive call site specific clobber effects are computed
25 for the variables whose scope is contained within this compilation
26 unit.
28 First each function and static variable initialization is analyzed
29 to determine which local static variables are either read, written,
30 or have their address taken. Any local static that has its address
31 taken is removed from consideration. Once the local read and
32 writes are determined, a transitive closure of this information is
33 performed over the call graph to determine the worst case set of
34 side effects of each call. In later parts of the compiler, these
35 local and global sets are examined to make the call clobbering less
36 traumatic, promote some statics to registers, and improve aliasing
37 information. */
39 #include "config.h"
40 #include "system.h"
41 #include "coretypes.h"
42 #include "tm.h"
43 #include "hash-set.h"
44 #include "machmode.h"
45 #include "vec.h"
46 #include "double-int.h"
47 #include "input.h"
48 #include "alias.h"
49 #include "symtab.h"
50 #include "options.h"
51 #include "wide-int.h"
52 #include "inchash.h"
53 #include "tree.h"
54 #include "fold-const.h"
55 #include "calls.h"
56 #include "predict.h"
57 #include "hard-reg-set.h"
58 #include "input.h"
59 #include "function.h"
60 #include "basic-block.h"
61 #include "tree-ssa-alias.h"
62 #include "internal-fn.h"
63 #include "gimple-expr.h"
64 #include "is-a.h"
65 #include "gimple.h"
66 #include "tree-inline.h"
67 #include "tree-pass.h"
68 #include "splay-tree.h"
69 #include "hash-map.h"
70 #include "plugin-api.h"
71 #include "ipa-ref.h"
72 #include "cgraph.h"
73 #include "ipa-utils.h"
74 #include "bitmap.h"
75 #include "ipa-reference.h"
76 #include "flags.h"
77 #include "diagnostic.h"
78 #include "data-streamer.h"
79 #include "lto-streamer.h"
81 static void remove_node_data (struct cgraph_node *node,
82 void *data ATTRIBUTE_UNUSED);
83 static void duplicate_node_data (struct cgraph_node *src,
84 struct cgraph_node *dst,
85 void *data ATTRIBUTE_UNUSED);
87 /* The static variables defined within the compilation unit that are
88 loaded or stored directly by function that owns this structure. */
90 struct ipa_reference_local_vars_info_d
92 bitmap statics_read;
93 bitmap statics_written;
96 /* Statics that are read and written by some set of functions. The
97 local ones are based on the loads and stores local to the function.
98 The global ones are based on the local info as well as the
99 transitive closure of the functions that are called. */
101 struct ipa_reference_global_vars_info_d
103 bitmap statics_read;
104 bitmap statics_written;
107 /* Information we save about every function after ipa-reference is completed. */
109 struct ipa_reference_optimization_summary_d
111 bitmap statics_not_read;
112 bitmap statics_not_written;
115 typedef struct ipa_reference_local_vars_info_d *ipa_reference_local_vars_info_t;
116 typedef struct ipa_reference_global_vars_info_d *ipa_reference_global_vars_info_t;
117 typedef struct ipa_reference_optimization_summary_d *ipa_reference_optimization_summary_t;
119 struct ipa_reference_vars_info_d
121 struct ipa_reference_local_vars_info_d local;
122 struct ipa_reference_global_vars_info_d global;
125 typedef struct ipa_reference_vars_info_d *ipa_reference_vars_info_t;
127 /* This splay tree contains all of the static variables that are
128 being considered by the compilation level alias analysis. */
129 static splay_tree reference_vars_to_consider;
131 /* Set of all interesting module statics. A bit is set for every module
132 static we are considering. This is added to the local info when asm
133 code is found that clobbers all memory. */
134 static bitmap all_module_statics;
135 /* Set of all statics that should be ignored becuase they are touched by
136 -fno-ipa-reference code. */
137 static bitmap ignore_module_statics;
139 /* Obstack holding bitmaps of local analysis (live from analysis to
140 propagation) */
141 static bitmap_obstack local_info_obstack;
142 /* Obstack holding global analysis live forever. */
143 static bitmap_obstack optimization_summary_obstack;
145 /* Holders of ipa cgraph hooks: */
146 static struct cgraph_2node_hook_list *node_duplication_hook_holder;
147 static struct cgraph_node_hook_list *node_removal_hook_holder;
149 /* Vector where the reference var infos are actually stored.
150 Indexed by UID of call graph nodes. */
151 static vec<ipa_reference_vars_info_t> ipa_reference_vars_vector;
153 /* TODO: find a place where we should release the vector. */
154 static vec<ipa_reference_optimization_summary_t> ipa_reference_opt_sum_vector;
156 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
157 static inline ipa_reference_vars_info_t
158 get_reference_vars_info (struct cgraph_node *node)
160 if (!ipa_reference_vars_vector.exists ()
161 || ipa_reference_vars_vector.length () <= (unsigned int) node->uid)
162 return NULL;
163 return ipa_reference_vars_vector[node->uid];
166 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
167 static inline ipa_reference_optimization_summary_t
168 get_reference_optimization_summary (struct cgraph_node *node)
170 if (!ipa_reference_opt_sum_vector.exists ()
171 || (ipa_reference_opt_sum_vector.length () <= (unsigned int) node->uid))
172 return NULL;
173 return ipa_reference_opt_sum_vector[node->uid];
176 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
177 static inline void
178 set_reference_vars_info (struct cgraph_node *node,
179 ipa_reference_vars_info_t info)
181 if (!ipa_reference_vars_vector.exists ()
182 || ipa_reference_vars_vector.length () <= (unsigned int) node->uid)
183 ipa_reference_vars_vector.safe_grow_cleared (node->uid + 1);
184 ipa_reference_vars_vector[node->uid] = info;
187 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
188 static inline void
189 set_reference_optimization_summary (struct cgraph_node *node,
190 ipa_reference_optimization_summary_t info)
192 if (!ipa_reference_opt_sum_vector.exists ()
193 || (ipa_reference_opt_sum_vector.length () <= (unsigned int) node->uid))
194 ipa_reference_opt_sum_vector.safe_grow_cleared (node->uid + 1);
195 ipa_reference_opt_sum_vector[node->uid] = info;
198 /* Return a bitmap indexed by DECL_UID for the static variables that
199 are *not* read during the execution of the function FN. Returns
200 NULL if no data is available. */
202 bitmap
203 ipa_reference_get_not_read_global (struct cgraph_node *fn)
205 if (!opt_for_fn (fn->decl, flag_ipa_reference)
206 || !opt_for_fn (current_function_decl, flag_ipa_reference))
207 return NULL;
208 ipa_reference_optimization_summary_t info =
209 get_reference_optimization_summary (fn->function_symbol (NULL));
210 if (info)
211 return info->statics_not_read;
212 else if (flags_from_decl_or_type (fn->decl) & ECF_LEAF)
213 return all_module_statics;
214 else
215 return NULL;
218 /* Return a bitmap indexed by DECL_UID for the static variables that
219 are *not* written during the execution of the function FN. Note
220 that variables written may or may not be read during the function
221 call. Returns NULL if no data is available. */
223 bitmap
224 ipa_reference_get_not_written_global (struct cgraph_node *fn)
226 if (!opt_for_fn (fn->decl, flag_ipa_reference)
227 || !opt_for_fn (current_function_decl, flag_ipa_reference))
228 return NULL;
229 ipa_reference_optimization_summary_t info =
230 get_reference_optimization_summary (fn);
231 if (info)
232 return info->statics_not_written;
233 else if (flags_from_decl_or_type (fn->decl) & ECF_LEAF)
234 return all_module_statics;
235 else
236 return NULL;
240 /* Return true if the variable T is the right kind of static variable to
241 perform compilation unit scope escape analysis. */
243 static inline bool
244 is_proper_for_analysis (tree t)
246 /* If the variable has the "used" attribute, treat it as if it had a
247 been touched by the devil. */
248 if (DECL_PRESERVE_P (t))
249 return false;
251 /* Do not want to do anything with volatile except mark any
252 function that uses one to be not const or pure. */
253 if (TREE_THIS_VOLATILE (t))
254 return false;
256 /* We do not need to analyze readonly vars, we already know they do not
257 alias. */
258 if (TREE_READONLY (t))
259 return false;
261 /* We can not track variables with address taken. */
262 if (TREE_ADDRESSABLE (t))
263 return false;
265 /* TODO: We could track public variables that are not addressable, but currently
266 frontends don't give us those. */
267 if (TREE_PUBLIC (t))
268 return false;
270 /* TODO: Check aliases. */
271 if (bitmap_bit_p (ignore_module_statics, DECL_UID (t)))
272 return false;
274 return true;
277 /* Lookup the tree node for the static variable that has UID and
278 convert the name to a string for debugging. */
280 static const char *
281 get_static_name (int index)
283 splay_tree_node stn =
284 splay_tree_lookup (reference_vars_to_consider, index);
285 return fndecl_name ((tree)(stn->value));
288 /* Dump a set of static vars to FILE. */
289 static void
290 dump_static_vars_set_to_file (FILE *f, bitmap set)
292 unsigned int index;
293 bitmap_iterator bi;
294 if (set == NULL)
295 return;
296 else if (set == all_module_statics)
297 fprintf (f, "ALL");
298 else
299 EXECUTE_IF_SET_IN_BITMAP (set, 0, index, bi)
301 fprintf (f, "%s ", get_static_name (index));
305 /* Compute X |= Y, taking into account the possibility that
306 either X or Y is already the maximum set.
307 Return true if X is the maximum set after taking the union with Y. */
309 static bool
310 union_static_var_sets (bitmap &x, bitmap y)
312 if (x != all_module_statics)
314 if (y == all_module_statics)
316 BITMAP_FREE (x);
317 x = all_module_statics;
319 else if (bitmap_ior_into (x, y))
321 /* The union may have reduced X to the maximum set.
322 In that case, we want to make that visible explicitly.
323 Even though bitmap_equal_p can be very expensive, it
324 turns out to be an overall win to check this here for
325 an LTO bootstrap of GCC itself. Liberally extrapoliate
326 that result to be applicable to all cases. */
327 if (bitmap_equal_p (x, all_module_statics))
329 BITMAP_FREE (x);
330 x = all_module_statics;
334 return x == all_module_statics;
337 /* Return a copy of SET on the bitmap obstack containing SET.
338 But if SET is NULL or the maximum set, return that instead. */
340 static bitmap
341 copy_static_var_set (bitmap set)
343 if (set == NULL || set == all_module_statics)
344 return set;
345 bitmap_obstack *o = set->obstack;
346 gcc_checking_assert (o);
347 bitmap copy = BITMAP_ALLOC (o);
348 bitmap_copy (copy, set);
349 return copy;
352 /* Compute the union all of the statics read and written by every callee of X
353 into X_GLOBAL->statics_read and X_GLOBAL->statics_written. X_GLOBAL is
354 actually the set representing the cycle containing X. If the read and
355 written sets of X_GLOBAL has been reduced to the maximum set, we don't
356 have to look at the remaining callees. */
358 static void
359 propagate_bits (ipa_reference_global_vars_info_t x_global, struct cgraph_node *x)
361 struct cgraph_edge *e;
362 bool read_all = x_global->statics_read == all_module_statics;
363 bool write_all = x_global->statics_written == all_module_statics;
364 for (e = x->callees;
365 e && !(read_all && write_all);
366 e = e->next_callee)
368 enum availability avail;
369 struct cgraph_node *y = e->callee->function_symbol (&avail);
370 if (!y)
371 continue;
373 /* Only look into nodes we can propagate something. */
374 int flags = flags_from_decl_or_type (y->decl);
375 if (opt_for_fn (y->decl, flag_ipa_reference)
376 && (avail > AVAIL_INTERPOSABLE
377 || (avail == AVAIL_INTERPOSABLE && (flags & ECF_LEAF))))
379 if (get_reference_vars_info (y))
381 ipa_reference_vars_info_t y_info = get_reference_vars_info (y);
382 ipa_reference_global_vars_info_t y_global = &y_info->global;
384 /* Calls in the current cycle do not have their global set
385 computed yet (but everything else does because we're
386 visiting nodes in topological order). */
387 if (!y_global->statics_read)
388 continue;
390 /* If the function is const, it reads no memory even if it
391 seems so to local analysis. */
392 if (flags & ECF_CONST)
393 continue;
395 union_static_var_sets (x_global->statics_read,
396 y_global->statics_read);
398 /* If the function is pure, it has no stores even if it
399 seems so to local analysis. If we cannot return from
400 the function, we can safely ignore the call. */
401 if ((flags & ECF_PURE)
402 || e->cannot_lead_to_return_p ())
403 continue;
405 union_static_var_sets (x_global->statics_written,
406 y_global->statics_written);
408 else
409 gcc_unreachable ();
414 static bool ipa_init_p = false;
416 /* The init routine for analyzing global static variable usage. See
417 comments at top for description. */
418 static void
419 ipa_init (void)
421 if (ipa_init_p)
422 return;
424 ipa_init_p = true;
426 if (dump_file)
427 reference_vars_to_consider = splay_tree_new (splay_tree_compare_ints, 0, 0);
429 bitmap_obstack_initialize (&local_info_obstack);
430 bitmap_obstack_initialize (&optimization_summary_obstack);
431 all_module_statics = BITMAP_ALLOC (&optimization_summary_obstack);
432 ignore_module_statics = BITMAP_ALLOC (&optimization_summary_obstack);
434 node_removal_hook_holder =
435 symtab->add_cgraph_removal_hook (&remove_node_data, NULL);
436 node_duplication_hook_holder =
437 symtab->add_cgraph_duplication_hook (&duplicate_node_data, NULL);
441 /* Set up the persistent info for FN. */
443 static ipa_reference_local_vars_info_t
444 init_function_info (struct cgraph_node *fn)
446 ipa_reference_vars_info_t info
447 = XCNEW (struct ipa_reference_vars_info_d);
449 /* Add the info to the tree's annotation. */
450 set_reference_vars_info (fn, info);
452 info->local.statics_read = BITMAP_ALLOC (&local_info_obstack);
453 info->local.statics_written = BITMAP_ALLOC (&local_info_obstack);
455 return &info->local;
459 /* This is the main routine for finding the reference patterns for
460 global variables within a function FN. */
462 static void
463 analyze_function (struct cgraph_node *fn)
465 ipa_reference_local_vars_info_t local;
466 struct ipa_ref *ref = NULL;
467 int i;
468 tree var;
470 if (!opt_for_fn (fn->decl, flag_ipa_reference))
471 return;
472 local = init_function_info (fn);
473 for (i = 0; fn->iterate_reference (i, ref); i++)
475 if (!is_a <varpool_node *> (ref->referred))
476 continue;
477 var = ref->referred->decl;
478 if (!is_proper_for_analysis (var))
479 continue;
480 /* This is a variable we care about. Check if we have seen it
481 before, and if not add it the set of variables we care about. */
482 if (all_module_statics
483 && bitmap_set_bit (all_module_statics, DECL_UID (var)))
485 if (dump_file)
486 splay_tree_insert (reference_vars_to_consider,
487 DECL_UID (var), (splay_tree_value)var);
489 switch (ref->use)
491 case IPA_REF_LOAD:
492 bitmap_set_bit (local->statics_read, DECL_UID (var));
493 break;
494 case IPA_REF_STORE:
495 if (ref->cannot_lead_to_return ())
496 break;
497 bitmap_set_bit (local->statics_written, DECL_UID (var));
498 break;
499 case IPA_REF_ADDR:
500 break;
501 default:
502 gcc_unreachable ();
506 if (fn->cannot_return_p ())
507 bitmap_clear (local->statics_written);
511 /* Called when new clone is inserted to callgraph late. */
513 static void
514 duplicate_node_data (struct cgraph_node *src, struct cgraph_node *dst,
515 void *data ATTRIBUTE_UNUSED)
517 ipa_reference_optimization_summary_t ginfo;
518 ipa_reference_optimization_summary_t dst_ginfo;
520 ginfo = get_reference_optimization_summary (src);
521 if (!ginfo)
522 return;
523 dst_ginfo = XCNEW (struct ipa_reference_optimization_summary_d);
524 set_reference_optimization_summary (dst, dst_ginfo);
525 dst_ginfo->statics_not_read =
526 copy_static_var_set (ginfo->statics_not_read);
527 dst_ginfo->statics_not_written =
528 copy_static_var_set (ginfo->statics_not_written);
531 /* Called when node is removed. */
533 static void
534 remove_node_data (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
536 ipa_reference_optimization_summary_t ginfo;
537 ginfo = get_reference_optimization_summary (node);
538 if (ginfo)
540 if (ginfo->statics_not_read
541 && ginfo->statics_not_read != all_module_statics)
542 BITMAP_FREE (ginfo->statics_not_read);
544 if (ginfo->statics_not_written
545 && ginfo->statics_not_written != all_module_statics)
546 BITMAP_FREE (ginfo->statics_not_written);
547 free (ginfo);
548 set_reference_optimization_summary (node, NULL);
552 /* Analyze each function in the cgraph to see which global or statics
553 are read or written. */
555 static void
556 generate_summary (void)
558 struct cgraph_node *node;
559 unsigned int index;
560 bitmap_iterator bi;
562 ipa_init ();
564 /* Process all of the functions next. */
565 FOR_EACH_DEFINED_FUNCTION (node)
566 if (!node->alias && !opt_for_fn (node->decl, flag_ipa_reference))
568 struct ipa_ref *ref = NULL;
569 int i;
570 tree var;
571 for (i = 0; node->iterate_reference (i, ref); i++)
573 if (!is_a <varpool_node *> (ref->referred))
574 continue;
575 var = ref->referred->decl;
576 if (!is_proper_for_analysis (var))
577 continue;
578 bitmap_set_bit (ignore_module_statics, DECL_UID (var));
581 FOR_EACH_DEFINED_FUNCTION (node)
582 analyze_function (node);
584 if (dump_file)
585 EXECUTE_IF_SET_IN_BITMAP (all_module_statics, 0, index, bi)
587 fprintf (dump_file, "\nPromotable global:%s (uid=%u)\n",
588 get_static_name (index), index);
591 if (dump_file)
592 FOR_EACH_DEFINED_FUNCTION (node)
593 if (node->get_availability () >= AVAIL_INTERPOSABLE
594 && opt_for_fn (node->decl, flag_ipa_reference))
596 ipa_reference_local_vars_info_t l;
597 unsigned int index;
598 bitmap_iterator bi;
600 l = &get_reference_vars_info (node)->local;
601 fprintf (dump_file,
602 "\nFunction name:%s/%i:",
603 node->asm_name (), node->order);
604 fprintf (dump_file, "\n locals read: ");
605 if (l->statics_read)
606 EXECUTE_IF_SET_IN_BITMAP (l->statics_read,
607 0, index, bi)
609 fprintf (dump_file, "%s ",
610 get_static_name (index));
612 fprintf (dump_file, "\n locals written: ");
613 if (l->statics_written)
614 EXECUTE_IF_SET_IN_BITMAP (l->statics_written,
615 0, index, bi)
617 fprintf (dump_file, "%s ", get_static_name (index));
622 /* Set READ_ALL/WRITE_ALL based on decl flags of NODE. */
624 static void
625 read_write_all_from_decl (struct cgraph_node *node,
626 bool &read_all, bool &write_all)
628 tree decl = node->decl;
629 int flags = flags_from_decl_or_type (decl);
630 if ((flags & ECF_LEAF)
631 && node->get_availability () < AVAIL_INTERPOSABLE)
633 else if (flags & ECF_CONST)
635 else if ((flags & ECF_PURE) || node->cannot_return_p ())
637 read_all = true;
638 if (dump_file && (dump_flags & TDF_DETAILS))
639 fprintf (dump_file, " %s/%i -> read all\n",
640 node->asm_name (), node->order);
642 else
644 /* TODO: To be able to produce sane results, we should also handle
645 common builtins, in particular throw. */
646 read_all = true;
647 write_all = true;
648 if (dump_file && (dump_flags & TDF_DETAILS))
649 fprintf (dump_file, " %s/%i -> read all, write all\n",
650 node->asm_name (), node->order);
654 /* Set READ_ALL/WRITE_ALL based on decl flags of NODE or any member
655 in the cycle of NODE. */
657 static void
658 get_read_write_all_from_node (struct cgraph_node *node,
659 bool &read_all, bool &write_all)
661 struct cgraph_edge *e, *ie;
663 /* When function is overwritable, we can not assume anything. */
664 if (node->get_availability () <= AVAIL_INTERPOSABLE
665 || (node->analyzed && !opt_for_fn (node->decl, flag_ipa_reference)))
666 read_write_all_from_decl (node, read_all, write_all);
668 for (e = node->callees;
669 e && !(read_all && write_all);
670 e = e->next_callee)
672 enum availability avail;
673 struct cgraph_node *callee = e->callee->function_symbol (&avail);
674 gcc_checking_assert (callee);
675 if (avail <= AVAIL_INTERPOSABLE
676 || (callee->analyzed && !opt_for_fn (callee->decl, flag_ipa_reference)))
677 read_write_all_from_decl (callee, read_all, write_all);
680 for (ie = node->indirect_calls;
681 ie && !(read_all && write_all);
682 ie = ie->next_callee)
683 if (!(ie->indirect_info->ecf_flags & ECF_CONST))
685 read_all = true;
686 if (dump_file && (dump_flags & TDF_DETAILS))
687 fprintf (dump_file, " indirect call -> read all\n");
688 if (!ie->cannot_lead_to_return_p ()
689 && !(ie->indirect_info->ecf_flags & ECF_PURE))
691 if (dump_file && (dump_flags & TDF_DETAILS))
692 fprintf (dump_file, " indirect call -> write all\n");
693 write_all = true;
698 /* Skip edges from and to nodes without ipa_reference enables. This leave
699 them out of strongy connected coponents and makes them easyto skip in the
700 propagation loop bellow. */
702 static bool
703 ignore_edge_p (cgraph_edge *e)
705 return (!opt_for_fn (e->caller->decl, flag_ipa_reference)
706 || !opt_for_fn (e->callee->function_symbol ()->decl,
707 flag_ipa_reference));
710 /* Produce the global information by preforming a transitive closure
711 on the local information that was produced by ipa_analyze_function. */
713 static unsigned int
714 propagate (void)
716 struct cgraph_node *node;
717 struct cgraph_node **order =
718 XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
719 int order_pos;
720 int i;
721 bool remove_p;
723 if (dump_file)
724 cgraph_node::dump_cgraph (dump_file);
726 remove_p = ipa_discover_readonly_nonaddressable_vars ();
727 generate_summary ();
729 /* Propagate the local information through the call graph to produce
730 the global information. All the nodes within a cycle will have
731 the same info so we collapse cycles first. Then we can do the
732 propagation in one pass from the leaves to the roots. */
733 order_pos = ipa_reduced_postorder (order, true, true, ignore_edge_p);
734 if (dump_file)
735 ipa_print_order (dump_file, "reduced", order, order_pos);
737 for (i = 0; i < order_pos; i++ )
739 unsigned x;
740 struct cgraph_node *w;
741 ipa_reference_vars_info_t node_info;
742 ipa_reference_global_vars_info_t node_g;
743 ipa_reference_local_vars_info_t node_l;
744 bool read_all = false;
745 bool write_all = false;
747 node = order[i];
748 if (node->alias || !opt_for_fn (node->decl, flag_ipa_reference))
749 continue;
751 node_info = get_reference_vars_info (node);
752 gcc_assert (node_info);
753 node_l = &node_info->local;
754 node_g = &node_info->global;
756 if (dump_file && (dump_flags & TDF_DETAILS))
757 fprintf (dump_file, "Starting cycle with %s/%i\n",
758 node->asm_name (), node->order);
760 vec<cgraph_node *> cycle_nodes = ipa_get_nodes_in_cycle (node);
762 /* If any node in a cycle is read_all or write_all, they all are. */
763 FOR_EACH_VEC_ELT (cycle_nodes, x, w)
765 if (dump_file && (dump_flags & TDF_DETAILS))
766 fprintf (dump_file, " Visiting %s/%i\n",
767 w->asm_name (), w->order);
768 get_read_write_all_from_node (w, read_all, write_all);
769 if (read_all && write_all)
770 break;
773 /* Initialized the bitmaps global sets for the reduced node. */
774 if (read_all)
775 node_g->statics_read = all_module_statics;
776 else
777 node_g->statics_read = copy_static_var_set (node_l->statics_read);
778 if (write_all)
779 node_g->statics_written = all_module_statics;
780 else
781 node_g->statics_written = copy_static_var_set (node_l->statics_written);
783 /* Merge the sets of this cycle with all sets of callees reached
784 from this cycle. */
785 FOR_EACH_VEC_ELT (cycle_nodes, x, w)
787 if (read_all && write_all)
788 break;
790 if (w != node)
792 ipa_reference_vars_info_t w_ri = get_reference_vars_info (w);
793 ipa_reference_local_vars_info_t w_l = &w_ri->local;
794 int flags = flags_from_decl_or_type (w->decl);
796 if (!(flags & ECF_CONST))
797 read_all = union_static_var_sets (node_g->statics_read,
798 w_l->statics_read);
799 if (!(flags & ECF_PURE)
800 && !w->cannot_return_p ())
801 write_all = union_static_var_sets (node_g->statics_written,
802 w_l->statics_written);
805 propagate_bits (node_g, w);
808 /* All nodes within a cycle have the same global info bitmaps. */
809 FOR_EACH_VEC_ELT (cycle_nodes, x, w)
811 ipa_reference_vars_info_t w_ri = get_reference_vars_info (w);
812 w_ri->global = *node_g;
815 cycle_nodes.release ();
818 if (dump_file)
820 for (i = 0; i < order_pos; i++)
822 unsigned x;
823 struct cgraph_node *w;
825 node = order[i];
826 if (node->alias || !opt_for_fn (node->decl, flag_ipa_reference))
827 continue;
829 fprintf (dump_file,
830 "\nFunction name:%s/%i:",
831 node->asm_name (), node->order);
833 ipa_reference_vars_info_t node_info = get_reference_vars_info (node);
834 ipa_reference_global_vars_info_t node_g = &node_info->global;
836 vec<cgraph_node *> cycle_nodes = ipa_get_nodes_in_cycle (node);
837 FOR_EACH_VEC_ELT (cycle_nodes, x, w)
839 ipa_reference_vars_info_t w_ri = get_reference_vars_info (w);
840 ipa_reference_local_vars_info_t w_l = &w_ri->local;
841 if (w != node)
842 fprintf (dump_file, "\n next cycle: %s/%i ",
843 w->asm_name (), w->order);
844 fprintf (dump_file, "\n locals read: ");
845 dump_static_vars_set_to_file (dump_file, w_l->statics_read);
846 fprintf (dump_file, "\n locals written: ");
847 dump_static_vars_set_to_file (dump_file, w_l->statics_written);
849 cycle_nodes.release ();
851 fprintf (dump_file, "\n globals read: ");
852 dump_static_vars_set_to_file (dump_file, node_g->statics_read);
853 fprintf (dump_file, "\n globals written: ");
854 dump_static_vars_set_to_file (dump_file, node_g->statics_written);
855 fprintf (dump_file, "\n");
859 /* Cleanup. */
860 FOR_EACH_DEFINED_FUNCTION (node)
862 ipa_reference_vars_info_t node_info;
863 ipa_reference_global_vars_info_t node_g;
864 ipa_reference_optimization_summary_t opt;
866 node_info = get_reference_vars_info (node);
867 if (!node->alias && opt_for_fn (node->decl, flag_ipa_reference)
868 && (node->get_availability () > AVAIL_INTERPOSABLE
869 || (flags_from_decl_or_type (node->decl) & ECF_LEAF)))
871 node_g = &node_info->global;
873 opt = XCNEW (struct ipa_reference_optimization_summary_d);
874 set_reference_optimization_summary (node, opt);
876 /* Create the complimentary sets. */
878 if (bitmap_empty_p (node_g->statics_read))
879 opt->statics_not_read = all_module_statics;
880 else
882 opt->statics_not_read
883 = BITMAP_ALLOC (&optimization_summary_obstack);
884 if (node_g->statics_read != all_module_statics)
885 bitmap_and_compl (opt->statics_not_read,
886 all_module_statics,
887 node_g->statics_read);
890 if (bitmap_empty_p (node_g->statics_written))
891 opt->statics_not_written = all_module_statics;
892 else
894 opt->statics_not_written
895 = BITMAP_ALLOC (&optimization_summary_obstack);
896 if (node_g->statics_written != all_module_statics)
897 bitmap_and_compl (opt->statics_not_written,
898 all_module_statics,
899 node_g->statics_written);
902 free (node_info);
905 ipa_free_postorder_info ();
906 free (order);
908 bitmap_obstack_release (&local_info_obstack);
909 ipa_reference_vars_vector.release ();
910 if (dump_file)
911 splay_tree_delete (reference_vars_to_consider);
912 reference_vars_to_consider = NULL;
913 return remove_p ? TODO_remove_functions : 0;
916 /* Return true if we need to write summary of NODE. */
918 static bool
919 write_node_summary_p (struct cgraph_node *node,
920 lto_symtab_encoder_t encoder,
921 bitmap ltrans_statics)
923 ipa_reference_optimization_summary_t info;
925 /* See if we have (non-empty) info. */
926 if (!node->definition || node->global.inlined_to)
927 return false;
928 info = get_reference_optimization_summary (node);
929 if (!info || (bitmap_empty_p (info->statics_not_read)
930 && bitmap_empty_p (info->statics_not_written)))
931 return false;
933 /* See if we want to encode it.
934 Encode also referenced functions since constant folding might turn it into
935 a direct call.
937 In future we might also want to include summaries of functions references
938 by initializers of constant variables references in current unit. */
939 if (!reachable_from_this_partition_p (node, encoder)
940 && !referenced_from_this_partition_p (node, encoder))
941 return false;
943 /* See if the info has non-empty intersections with vars we want to encode. */
944 if (!bitmap_intersect_p (info->statics_not_read, ltrans_statics)
945 && !bitmap_intersect_p (info->statics_not_written, ltrans_statics))
946 return false;
947 return true;
950 /* Stream out BITS&LTRANS_STATICS as list of decls to OB.
951 LTRANS_STATICS_BITCOUNT specify number of bits in LTRANS_STATICS
952 or -1. When it is positive, just output -1 when
953 BITS&LTRANS_STATICS == BITS&LTRANS_STATICS. */
955 static void
956 stream_out_bitmap (struct lto_simple_output_block *ob,
957 bitmap bits, bitmap ltrans_statics,
958 int ltrans_statics_bitcount)
960 int count = 0;
961 unsigned int index;
962 bitmap_iterator bi;
963 if (bits == all_module_statics)
965 streamer_write_hwi_stream (ob->main_stream, -1);
966 return;
968 EXECUTE_IF_AND_IN_BITMAP (bits, ltrans_statics, 0, index, bi)
969 count ++;
970 if (count == ltrans_statics_bitcount)
972 streamer_write_hwi_stream (ob->main_stream, -1);
973 return;
975 streamer_write_hwi_stream (ob->main_stream, count);
976 if (!count)
977 return;
978 EXECUTE_IF_AND_IN_BITMAP (bits, ltrans_statics, 0, index, bi)
980 tree decl = (tree)splay_tree_lookup (reference_vars_to_consider, index)->value;
981 lto_output_var_decl_index (ob->decl_state, ob->main_stream, decl);
985 /* Serialize the ipa info for lto. */
987 static void
988 ipa_reference_write_optimization_summary (void)
990 struct lto_simple_output_block *ob
991 = lto_create_simple_output_block (LTO_section_ipa_reference);
992 unsigned int count = 0;
993 int ltrans_statics_bitcount = 0;
994 lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
995 bitmap ltrans_statics = BITMAP_ALLOC (NULL);
996 int i;
998 reference_vars_to_consider = splay_tree_new (splay_tree_compare_ints, 0, 0);
1000 /* See what variables we are interested in. */
1001 for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
1003 symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
1004 varpool_node *vnode = dyn_cast <varpool_node *> (snode);
1005 if (vnode
1006 && bitmap_bit_p (all_module_statics, DECL_UID (vnode->decl))
1007 && referenced_from_this_partition_p (vnode, encoder))
1009 tree decl = vnode->decl;
1010 bitmap_set_bit (ltrans_statics, DECL_UID (decl));
1011 splay_tree_insert (reference_vars_to_consider,
1012 DECL_UID (decl), (splay_tree_value)decl);
1013 ltrans_statics_bitcount ++;
1018 if (ltrans_statics_bitcount)
1019 for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
1021 symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
1022 cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
1023 if (cnode && write_node_summary_p (cnode, encoder, ltrans_statics))
1024 count++;
1027 streamer_write_uhwi_stream (ob->main_stream, count);
1028 if (count)
1029 stream_out_bitmap (ob, ltrans_statics, ltrans_statics,
1030 -1);
1032 /* Process all of the functions. */
1033 if (ltrans_statics_bitcount)
1034 for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
1036 symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
1037 cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
1038 if (cnode && write_node_summary_p (cnode, encoder, ltrans_statics))
1040 ipa_reference_optimization_summary_t info;
1041 int node_ref;
1043 info = get_reference_optimization_summary (cnode);
1044 node_ref = lto_symtab_encoder_encode (encoder, snode);
1045 streamer_write_uhwi_stream (ob->main_stream, node_ref);
1047 stream_out_bitmap (ob, info->statics_not_read, ltrans_statics,
1048 ltrans_statics_bitcount);
1049 stream_out_bitmap (ob, info->statics_not_written, ltrans_statics,
1050 ltrans_statics_bitcount);
1053 BITMAP_FREE (ltrans_statics);
1054 lto_destroy_simple_output_block (ob);
1055 splay_tree_delete (reference_vars_to_consider);
1058 /* Deserialize the ipa info for lto. */
1060 static void
1061 ipa_reference_read_optimization_summary (void)
1063 struct lto_file_decl_data ** file_data_vec
1064 = lto_get_file_decl_data ();
1065 struct lto_file_decl_data * file_data;
1066 unsigned int j = 0;
1067 bitmap_obstack_initialize (&optimization_summary_obstack);
1069 node_removal_hook_holder =
1070 symtab->add_cgraph_removal_hook (&remove_node_data, NULL);
1071 node_duplication_hook_holder =
1072 symtab->add_cgraph_duplication_hook (&duplicate_node_data, NULL);
1073 all_module_statics = BITMAP_ALLOC (&optimization_summary_obstack);
1075 while ((file_data = file_data_vec[j++]))
1077 const char *data;
1078 size_t len;
1079 struct lto_input_block *ib
1080 = lto_create_simple_input_block (file_data,
1081 LTO_section_ipa_reference,
1082 &data, &len);
1083 if (ib)
1085 unsigned int i;
1086 unsigned int f_count = streamer_read_uhwi (ib);
1087 int b_count;
1088 if (!f_count)
1089 continue;
1090 b_count = streamer_read_hwi (ib);
1091 if (dump_file)
1092 fprintf (dump_file, "all module statics:");
1093 for (i = 0; i < (unsigned int)b_count; i++)
1095 unsigned int var_index = streamer_read_uhwi (ib);
1096 tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1097 var_index);
1098 bitmap_set_bit (all_module_statics, DECL_UID (v_decl));
1099 if (dump_file)
1100 fprintf (dump_file, " %s", fndecl_name (v_decl));
1103 for (i = 0; i < f_count; i++)
1105 unsigned int j, index;
1106 struct cgraph_node *node;
1107 ipa_reference_optimization_summary_t info;
1108 int v_count;
1109 lto_symtab_encoder_t encoder;
1111 index = streamer_read_uhwi (ib);
1112 encoder = file_data->symtab_node_encoder;
1113 node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref
1114 (encoder, index));
1115 info = XCNEW (struct ipa_reference_optimization_summary_d);
1116 set_reference_optimization_summary (node, info);
1117 info->statics_not_read = BITMAP_ALLOC (&optimization_summary_obstack);
1118 info->statics_not_written = BITMAP_ALLOC (&optimization_summary_obstack);
1119 if (dump_file)
1120 fprintf (dump_file,
1121 "\nFunction name:%s/%i:\n static not read:",
1122 node->asm_name (), node->order);
1124 /* Set the statics not read. */
1125 v_count = streamer_read_hwi (ib);
1126 if (v_count == -1)
1128 info->statics_not_read = all_module_statics;
1129 if (dump_file)
1130 fprintf (dump_file, " all module statics");
1132 else
1133 for (j = 0; j < (unsigned int)v_count; j++)
1135 unsigned int var_index = streamer_read_uhwi (ib);
1136 tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1137 var_index);
1138 bitmap_set_bit (info->statics_not_read, DECL_UID (v_decl));
1139 if (dump_file)
1140 fprintf (dump_file, " %s", fndecl_name (v_decl));
1143 if (dump_file)
1144 fprintf (dump_file,
1145 "\n static not written:");
1146 /* Set the statics not written. */
1147 v_count = streamer_read_hwi (ib);
1148 if (v_count == -1)
1150 info->statics_not_written = all_module_statics;
1151 if (dump_file)
1152 fprintf (dump_file, " all module statics");
1154 else
1155 for (j = 0; j < (unsigned int)v_count; j++)
1157 unsigned int var_index = streamer_read_uhwi (ib);
1158 tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1159 var_index);
1160 bitmap_set_bit (info->statics_not_written, DECL_UID (v_decl));
1161 if (dump_file)
1162 fprintf (dump_file, " %s", fndecl_name (v_decl));
1164 if (dump_file)
1165 fprintf (dump_file, "\n");
1168 lto_destroy_simple_input_block (file_data,
1169 LTO_section_ipa_reference,
1170 ib, data, len);
1172 else
1173 /* Fatal error here. We do not want to support compiling ltrans units with
1174 different version of compiler or different flags than the WPA unit, so
1175 this should never happen. */
1176 fatal_error (input_location,
1177 "ipa reference summary is missing in ltrans unit");
1181 namespace {
1183 const pass_data pass_data_ipa_reference =
1185 IPA_PASS, /* type */
1186 "static-var", /* name */
1187 OPTGROUP_NONE, /* optinfo_flags */
1188 TV_IPA_REFERENCE, /* tv_id */
1189 0, /* properties_required */
1190 0, /* properties_provided */
1191 0, /* properties_destroyed */
1192 0, /* todo_flags_start */
1193 0, /* todo_flags_finish */
1196 class pass_ipa_reference : public ipa_opt_pass_d
1198 public:
1199 pass_ipa_reference (gcc::context *ctxt)
1200 : ipa_opt_pass_d (pass_data_ipa_reference, ctxt,
1201 NULL, /* generate_summary */
1202 NULL, /* write_summary */
1203 NULL, /* read_summary */
1204 ipa_reference_write_optimization_summary, /*
1205 write_optimization_summary */
1206 ipa_reference_read_optimization_summary, /*
1207 read_optimization_summary */
1208 NULL, /* stmt_fixup */
1209 0, /* function_transform_todo_flags_start */
1210 NULL, /* function_transform */
1211 NULL) /* variable_transform */
1214 /* opt_pass methods: */
1215 virtual bool gate (function *)
1217 return ((in_lto_p || flag_ipa_reference)
1218 /* Don't bother doing anything if the program has errors. */
1219 && !seen_error ());
1222 virtual unsigned int execute (function *) { return propagate (); }
1224 }; // class pass_ipa_reference
1226 } // anon namespace
1228 ipa_opt_pass_d *
1229 make_pass_ipa_reference (gcc::context *ctxt)
1231 return new pass_ipa_reference (ctxt);
1234 /* Reset all state within ipa-reference.c so that we can rerun the compiler
1235 within the same process. For use by toplev::finalize. */
1237 void
1238 ipa_reference_c_finalize (void)
1240 if (ipa_init_p)
1242 bitmap_obstack_release (&optimization_summary_obstack);
1243 ipa_init_p = false;
1246 if (node_removal_hook_holder)
1248 symtab->remove_cgraph_removal_hook (node_removal_hook_holder);
1249 node_removal_hook_holder = NULL;
1251 if (node_duplication_hook_holder)
1253 symtab->remove_cgraph_duplication_hook (node_duplication_hook_holder);
1254 node_duplication_hook_holder = NULL;