* config/i386/i386.h (ACCUMULATE_OUTGOING_ARGS): Disable accumulation
[official-gcc.git] / gcc / ipa-reference.c
blobd9463804ea2c3e2f7ca19ccc64bc27536deab049
1 /* Callgraph based analysis of static variables.
2 Copyright (C) 2004-2013 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 "tree.h"
44 #include "tree-ssa.h"
45 #include "tree-inline.h"
46 #include "tree-pass.h"
47 #include "pointer-set.h"
48 #include "splay-tree.h"
49 #include "ggc.h"
50 #include "ipa-utils.h"
51 #include "ipa-reference.h"
52 #include "gimple.h"
53 #include "cgraph.h"
54 #include "flags.h"
55 #include "diagnostic.h"
56 #include "data-streamer.h"
57 #include "lto-streamer.h"
59 static void remove_node_data (struct cgraph_node *node,
60 void *data ATTRIBUTE_UNUSED);
61 static void duplicate_node_data (struct cgraph_node *src,
62 struct cgraph_node *dst,
63 void *data ATTRIBUTE_UNUSED);
65 /* The static variables defined within the compilation unit that are
66 loaded or stored directly by function that owns this structure. */
68 struct ipa_reference_local_vars_info_d
70 bitmap statics_read;
71 bitmap statics_written;
74 /* Statics that are read and written by some set of functions. The
75 local ones are based on the loads and stores local to the function.
76 The global ones are based on the local info as well as the
77 transitive closure of the functions that are called. */
79 struct ipa_reference_global_vars_info_d
81 bitmap statics_read;
82 bitmap statics_written;
85 /* Information we save about every function after ipa-reference is completed. */
87 struct ipa_reference_optimization_summary_d
89 bitmap statics_not_read;
90 bitmap statics_not_written;
93 typedef struct ipa_reference_local_vars_info_d *ipa_reference_local_vars_info_t;
94 typedef struct ipa_reference_global_vars_info_d *ipa_reference_global_vars_info_t;
95 typedef struct ipa_reference_optimization_summary_d *ipa_reference_optimization_summary_t;
97 struct ipa_reference_vars_info_d
99 struct ipa_reference_local_vars_info_d local;
100 struct ipa_reference_global_vars_info_d global;
103 typedef struct ipa_reference_vars_info_d *ipa_reference_vars_info_t;
105 /* This splay tree contains all of the static variables that are
106 being considered by the compilation level alias analysis. */
107 static splay_tree reference_vars_to_consider;
109 /* Set of all interesting module statics. A bit is set for every module
110 static we are considering. This is added to the local info when asm
111 code is found that clobbers all memory. */
112 static bitmap all_module_statics;
114 /* Obstack holding bitmaps of local analysis (live from analysis to
115 propagation) */
116 static bitmap_obstack local_info_obstack;
117 /* Obstack holding global analysis live forever. */
118 static bitmap_obstack optimization_summary_obstack;
120 /* Holders of ipa cgraph hooks: */
121 static struct cgraph_2node_hook_list *node_duplication_hook_holder;
122 static struct cgraph_node_hook_list *node_removal_hook_holder;
124 /* Vector where the reference var infos are actually stored.
125 Indexed by UID of call graph nodes. */
126 static vec<ipa_reference_vars_info_t> ipa_reference_vars_vector;
128 static vec<ipa_reference_optimization_summary_t> ipa_reference_opt_sum_vector;
130 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
131 static inline ipa_reference_vars_info_t
132 get_reference_vars_info (struct cgraph_node *node)
134 if (!ipa_reference_vars_vector.exists ()
135 || ipa_reference_vars_vector.length () <= (unsigned int) node->uid)
136 return NULL;
137 return ipa_reference_vars_vector[node->uid];
140 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
141 static inline ipa_reference_optimization_summary_t
142 get_reference_optimization_summary (struct cgraph_node *node)
144 if (!ipa_reference_opt_sum_vector.exists ()
145 || (ipa_reference_opt_sum_vector.length () <= (unsigned int) node->uid))
146 return NULL;
147 return ipa_reference_opt_sum_vector[node->uid];
150 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
151 static inline void
152 set_reference_vars_info (struct cgraph_node *node,
153 ipa_reference_vars_info_t info)
155 if (!ipa_reference_vars_vector.exists ()
156 || ipa_reference_vars_vector.length () <= (unsigned int) node->uid)
157 ipa_reference_vars_vector.safe_grow_cleared (node->uid + 1);
158 ipa_reference_vars_vector[node->uid] = info;
161 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
162 static inline void
163 set_reference_optimization_summary (struct cgraph_node *node,
164 ipa_reference_optimization_summary_t info)
166 if (!ipa_reference_opt_sum_vector.exists ()
167 || (ipa_reference_opt_sum_vector.length () <= (unsigned int) node->uid))
168 ipa_reference_opt_sum_vector.safe_grow_cleared (node->uid + 1);
169 ipa_reference_opt_sum_vector[node->uid] = info;
172 /* Return a bitmap indexed by DECL_UID for the static variables that
173 are *not* read during the execution of the function FN. Returns
174 NULL if no data is available. */
176 bitmap
177 ipa_reference_get_not_read_global (struct cgraph_node *fn)
179 ipa_reference_optimization_summary_t info =
180 get_reference_optimization_summary (cgraph_function_node (fn, NULL));
181 if (info)
182 return info->statics_not_read;
183 else if (flags_from_decl_or_type (fn->symbol.decl) & ECF_LEAF)
184 return all_module_statics;
185 else
186 return NULL;
189 /* Return a bitmap indexed by DECL_UID for the static variables that
190 are *not* written during the execution of the function FN. Note
191 that variables written may or may not be read during the function
192 call. Returns NULL if no data is available. */
194 bitmap
195 ipa_reference_get_not_written_global (struct cgraph_node *fn)
197 ipa_reference_optimization_summary_t info =
198 get_reference_optimization_summary (fn);
199 if (info)
200 return info->statics_not_written;
201 else if (flags_from_decl_or_type (fn->symbol.decl) & ECF_LEAF)
202 return all_module_statics;
203 else
204 return NULL;
209 /* Add VAR to all_module_statics and the two
210 reference_vars_to_consider* sets. */
212 static inline void
213 add_static_var (tree var)
215 int uid = DECL_UID (var);
216 gcc_assert (TREE_CODE (var) == VAR_DECL);
217 if (dump_file)
218 splay_tree_insert (reference_vars_to_consider,
219 uid, (splay_tree_value)var);
220 bitmap_set_bit (all_module_statics, uid);
223 /* Return true if the variable T is the right kind of static variable to
224 perform compilation unit scope escape analysis. */
226 static inline bool
227 is_proper_for_analysis (tree t)
229 /* If the variable has the "used" attribute, treat it as if it had a
230 been touched by the devil. */
231 if (DECL_PRESERVE_P (t))
232 return false;
234 /* Do not want to do anything with volatile except mark any
235 function that uses one to be not const or pure. */
236 if (TREE_THIS_VOLATILE (t))
237 return false;
239 /* We do not need to analyze readonly vars, we already know they do not
240 alias. */
241 if (TREE_READONLY (t))
242 return false;
244 /* This is a variable we care about. Check if we have seen it
245 before, and if not add it the set of variables we care about. */
246 if (all_module_statics
247 && !bitmap_bit_p (all_module_statics, DECL_UID (t)))
248 add_static_var (t);
250 return true;
253 /* Lookup the tree node for the static variable that has UID and
254 convert the name to a string for debugging. */
256 static const char *
257 get_static_name (int index)
259 splay_tree_node stn =
260 splay_tree_lookup (reference_vars_to_consider, index);
261 return fndecl_name ((tree)(stn->value));
264 /* Dump a set of static vars to FILE. */
265 static void
266 dump_static_vars_set_to_file (FILE *f, bitmap set)
268 unsigned int index;
269 bitmap_iterator bi;
270 if (set == NULL)
271 return;
272 else if (set == all_module_statics)
273 fprintf (f, "ALL");
274 else
275 EXECUTE_IF_SET_IN_BITMAP (set, 0, index, bi)
277 fprintf (f, "%s ", get_static_name (index));
281 /* Compute X |= Y, taking into account the possibility that
282 either X or Y is already the maximum set.
283 Return true if X is the maximum set after taking the union with Y. */
285 static bool
286 union_static_var_sets (bitmap &x, bitmap y)
288 if (x != all_module_statics)
290 if (y == all_module_statics)
292 BITMAP_FREE (x);
293 x = all_module_statics;
295 else if (bitmap_ior_into (x, y))
297 /* The union may have reduced X to the maximum set.
298 In that case, we want to make that visible explicitly.
299 Even though bitmap_equal_p can be very expensive, it
300 turns out to be an overall win to check this here for
301 an LTO bootstrap of GCC itself. Liberally extrapoliate
302 that result to be applicable to all cases. */
303 if (bitmap_equal_p (x, all_module_statics))
305 BITMAP_FREE (x);
306 x = all_module_statics;
310 return x == all_module_statics;
313 /* Compute X &= Y, taking into account the possibility that
314 X may become the maximum set. */
316 static bool
317 intersect_static_var_sets (bitmap &x, bitmap y)
319 if (x != all_module_statics)
321 bitmap_and_into (x, y);
322 /* As with union_static_var_sets, reducing to the maximum
323 set as early as possible is an overall win. */
324 if (bitmap_equal_p (x, all_module_statics))
326 BITMAP_FREE (x);
327 x = all_module_statics;
330 return x == all_module_statics;
333 /* Return a copy of SET on the bitmap obstack containing SET.
334 But if SET is NULL or the maximum set, return that instead. */
336 static bitmap
337 copy_static_var_set (bitmap set)
339 if (set == NULL || set == all_module_statics)
340 return set;
341 bitmap_obstack *o = set->obstack;
342 gcc_checking_assert (o);
343 bitmap copy = BITMAP_ALLOC (o);
344 bitmap_copy (copy, set);
345 return copy;
348 /* Compute the union all of the statics read and written by every callee of X
349 into X_GLOBAL->statics_read and X_GLOBAL->statics_written. X_GLOBAL is
350 actually the set representing the cycle containing X. If the read and
351 written sets of X_GLOBAL has been reduced to the maximum set, we don't
352 have to look at the remaining callees. */
354 static void
355 propagate_bits (ipa_reference_global_vars_info_t x_global, struct cgraph_node *x)
357 struct cgraph_edge *e;
358 bool read_all = x_global->statics_read == all_module_statics;
359 bool write_all = x_global->statics_written == all_module_statics;
360 for (e = x->callees;
361 e && !(read_all && write_all);
362 e = e->next_callee)
364 enum availability avail;
365 struct cgraph_node *y = cgraph_function_node (e->callee, &avail);
366 if (!y)
367 continue;
369 /* Only look into nodes we can propagate something. */
370 int flags = flags_from_decl_or_type (y->symbol.decl);
371 if (avail > AVAIL_OVERWRITABLE
372 || (avail == AVAIL_OVERWRITABLE && (flags & ECF_LEAF)))
374 if (get_reference_vars_info (y))
376 ipa_reference_vars_info_t y_info = get_reference_vars_info (y);
377 ipa_reference_global_vars_info_t y_global = &y_info->global;
379 /* Calls in the current cycle do not have their global set
380 computed yet (but everything else does because we're
381 visiting nodes in topological order). */
382 if (!y_global->statics_read)
383 continue;
385 /* If the function is const, it reads no memory even if it
386 seems so to local analysis. */
387 if (flags & ECF_CONST)
388 continue;
390 union_static_var_sets (x_global->statics_read,
391 y_global->statics_read);
393 /* If the function is pure, it has no stores even if it
394 seems so to local analysis. If we cannot return from
395 the function, we can safely ignore the call. */
396 if ((flags & ECF_PURE)
397 || cgraph_edge_cannot_lead_to_return (e))
398 continue;
400 union_static_var_sets (x_global->statics_written,
401 y_global->statics_written);
403 else
404 gcc_unreachable ();
409 /* The init routine for analyzing global static variable usage. See
410 comments at top for description. */
411 static void
412 ipa_init (void)
414 static bool init_p = false;
416 if (init_p)
417 return;
419 init_p = true;
421 if (dump_file)
422 reference_vars_to_consider = splay_tree_new (splay_tree_compare_ints, 0, 0);
424 bitmap_obstack_initialize (&local_info_obstack);
425 bitmap_obstack_initialize (&optimization_summary_obstack);
426 all_module_statics = BITMAP_ALLOC (&optimization_summary_obstack);
428 node_removal_hook_holder =
429 cgraph_add_node_removal_hook (&remove_node_data, NULL);
430 node_duplication_hook_holder =
431 cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
435 /* Set up the persistent info for FN. */
437 static ipa_reference_local_vars_info_t
438 init_function_info (struct cgraph_node *fn)
440 ipa_reference_vars_info_t info
441 = XCNEW (struct ipa_reference_vars_info_d);
443 /* Add the info to the tree's annotation. */
444 set_reference_vars_info (fn, info);
446 info->local.statics_read = BITMAP_ALLOC (&local_info_obstack);
447 info->local.statics_written = BITMAP_ALLOC (&local_info_obstack);
449 return &info->local;
453 /* This is the main routine for finding the reference patterns for
454 global variables within a function FN. */
456 static void
457 analyze_function (struct cgraph_node *fn)
459 ipa_reference_local_vars_info_t local;
460 struct ipa_ref *ref;
461 int i;
462 tree var;
464 local = init_function_info (fn);
465 for (i = 0; ipa_ref_list_reference_iterate (&fn->symbol.ref_list, i, ref); i++)
467 if (!is_a <varpool_node> (ref->referred))
468 continue;
469 var = ipa_ref_varpool_node (ref)->symbol.decl;
470 if (!is_proper_for_analysis (var))
471 continue;
472 switch (ref->use)
474 case IPA_REF_LOAD:
475 bitmap_set_bit (local->statics_read, DECL_UID (var));
476 break;
477 case IPA_REF_STORE:
478 if (ipa_ref_cannot_lead_to_return (ref))
479 break;
480 bitmap_set_bit (local->statics_written, DECL_UID (var));
481 break;
482 case IPA_REF_ADDR:
483 break;
487 if (cgraph_node_cannot_return (fn))
488 bitmap_clear (local->statics_written);
492 /* Called when new clone is inserted to callgraph late. */
494 static void
495 duplicate_node_data (struct cgraph_node *src, struct cgraph_node *dst,
496 void *data ATTRIBUTE_UNUSED)
498 ipa_reference_optimization_summary_t ginfo;
499 ipa_reference_optimization_summary_t dst_ginfo;
501 ginfo = get_reference_optimization_summary (src);
502 if (!ginfo)
503 return;
504 dst_ginfo = XCNEW (struct ipa_reference_optimization_summary_d);
505 set_reference_optimization_summary (dst, dst_ginfo);
506 dst_ginfo->statics_not_read =
507 copy_static_var_set (ginfo->statics_not_read);
508 dst_ginfo->statics_not_written =
509 copy_static_var_set (ginfo->statics_not_written);
512 /* Called when node is removed. */
514 static void
515 remove_node_data (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
517 ipa_reference_optimization_summary_t ginfo;
518 ginfo = get_reference_optimization_summary (node);
519 if (ginfo)
521 if (ginfo->statics_not_read
522 && ginfo->statics_not_read != all_module_statics)
523 BITMAP_FREE (ginfo->statics_not_read);
525 if (ginfo->statics_not_written
526 && ginfo->statics_not_written != all_module_statics)
527 BITMAP_FREE (ginfo->statics_not_written);
528 free (ginfo);
529 set_reference_optimization_summary (node, NULL);
533 /* Analyze each function in the cgraph to see which global or statics
534 are read or written. */
536 static void
537 generate_summary (void)
539 struct cgraph_node *node;
540 unsigned int index;
541 bitmap_iterator bi;
543 ipa_init ();
545 /* Process all of the functions next. */
546 FOR_EACH_DEFINED_FUNCTION (node)
547 analyze_function (node);
549 if (dump_file)
550 EXECUTE_IF_SET_IN_BITMAP (all_module_statics, 0, index, bi)
552 fprintf (dump_file, "\nPromotable global:%s (uid=%u)\n",
553 get_static_name (index), index);
556 if (dump_file)
557 FOR_EACH_DEFINED_FUNCTION (node)
558 if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
560 ipa_reference_local_vars_info_t l;
561 unsigned int index;
562 bitmap_iterator bi;
564 l = &get_reference_vars_info (node)->local;
565 fprintf (dump_file,
566 "\nFunction name:%s/%i:",
567 cgraph_node_asm_name (node), node->symbol.order);
568 fprintf (dump_file, "\n locals read: ");
569 if (l->statics_read)
570 EXECUTE_IF_SET_IN_BITMAP (l->statics_read,
571 0, index, bi)
573 fprintf (dump_file, "%s ",
574 get_static_name (index));
576 fprintf (dump_file, "\n locals written: ");
577 if (l->statics_written)
578 EXECUTE_IF_SET_IN_BITMAP (l->statics_written,
579 0, index, bi)
581 fprintf (dump_file, "%s ", get_static_name (index));
586 /* Set READ_ALL/WRITE_ALL based on decl flags of NODE. */
588 static void
589 read_write_all_from_decl (struct cgraph_node *node,
590 bool &read_all, bool &write_all)
592 tree decl = node->symbol.decl;
593 int flags = flags_from_decl_or_type (decl);
594 if ((flags & ECF_LEAF)
595 && cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
597 else if (flags & ECF_CONST)
599 else if ((flags & ECF_PURE)
600 || cgraph_node_cannot_return (node))
602 read_all = true;
603 if (dump_file && (dump_flags & TDF_DETAILS))
604 fprintf (dump_file, " %s/%i -> read all\n",
605 cgraph_node_asm_name (node), node->symbol.order);
607 else
609 /* TODO: To be able to produce sane results, we should also handle
610 common builtins, in particular throw. */
611 read_all = true;
612 write_all = true;
613 if (dump_file && (dump_flags & TDF_DETAILS))
614 fprintf (dump_file, " %s/%i -> read all, write all\n",
615 cgraph_node_asm_name (node), node->symbol.order);
619 /* Set READ_ALL/WRITE_ALL based on decl flags of NODE or any member
620 in the cycle of NODE. */
622 static void
623 get_read_write_all_from_node (struct cgraph_node *node,
624 bool &read_all, bool &write_all)
626 struct cgraph_edge *e, *ie;
628 /* When function is overwritable, we can not assume anything. */
629 if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
630 read_write_all_from_decl (node, read_all, write_all);
632 for (e = node->callees;
633 e && !(read_all && write_all);
634 e = e->next_callee)
636 enum availability avail;
637 struct cgraph_node *callee = cgraph_function_node (e->callee, &avail);
638 gcc_checking_assert (callee);
639 if (avail <= AVAIL_OVERWRITABLE)
640 read_write_all_from_decl (callee, read_all, write_all);
643 for (ie = node->indirect_calls;
644 ie && !(read_all && write_all);
645 ie = ie->next_callee)
646 if (!(ie->indirect_info->ecf_flags & ECF_CONST))
648 read_all = true;
649 if (dump_file && (dump_flags & TDF_DETAILS))
650 fprintf (dump_file, " indirect call -> read all\n");
651 if (!cgraph_edge_cannot_lead_to_return (ie)
652 && !(ie->indirect_info->ecf_flags & ECF_PURE))
654 if (dump_file && (dump_flags & TDF_DETAILS))
655 fprintf (dump_file, " indirect call -> write all\n");
656 write_all = true;
661 /* Produce the global information by preforming a transitive closure
662 on the local information that was produced by ipa_analyze_function. */
664 static unsigned int
665 propagate (void)
667 struct cgraph_node *node;
668 struct varpool_node *vnode;
669 struct cgraph_node **order =
670 XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
671 int order_pos;
672 int i;
674 if (dump_file)
675 dump_cgraph (dump_file);
677 ipa_discover_readonly_nonaddressable_vars ();
678 generate_summary ();
680 /* Now we know what vars are really statics; prune out those that aren't. */
681 FOR_EACH_VARIABLE (vnode)
682 if (vnode->symbol.externally_visible
683 || TREE_ADDRESSABLE (vnode->symbol.decl)
684 || TREE_READONLY (vnode->symbol.decl)
685 || !is_proper_for_analysis (vnode->symbol.decl)
686 || !vnode->symbol.definition)
687 bitmap_clear_bit (all_module_statics, DECL_UID (vnode->symbol.decl));
689 /* Forget info we collected "just for fun" on variables that turned out to be
690 non-local. */
691 FOR_EACH_DEFINED_FUNCTION (node)
693 ipa_reference_local_vars_info_t node_l;
694 node_l = &get_reference_vars_info (node)->local;
695 intersect_static_var_sets (node_l->statics_read, all_module_statics);
696 intersect_static_var_sets (node_l->statics_written, all_module_statics);
699 /* Propagate the local information through the call graph to produce
700 the global information. All the nodes within a cycle will have
701 the same info so we collapse cycles first. Then we can do the
702 propagation in one pass from the leaves to the roots. */
703 order_pos = ipa_reduced_postorder (order, true, true, NULL);
704 if (dump_file)
705 ipa_print_order (dump_file, "reduced", order, order_pos);
707 for (i = 0; i < order_pos; i++ )
709 unsigned x;
710 struct cgraph_node *w;
711 ipa_reference_vars_info_t node_info;
712 ipa_reference_global_vars_info_t node_g;
713 ipa_reference_local_vars_info_t node_l;
714 bool read_all = false;
715 bool write_all = false;
717 node = order[i];
718 if (node->symbol.alias)
719 continue;
721 node_info = get_reference_vars_info (node);
722 gcc_assert (node_info);
723 node_l = &node_info->local;
724 node_g = &node_info->global;
726 if (dump_file && (dump_flags & TDF_DETAILS))
727 fprintf (dump_file, "Starting cycle with %s/%i\n",
728 cgraph_node_asm_name (node), node->symbol.order);
730 vec<cgraph_node_ptr> cycle_nodes = ipa_get_nodes_in_cycle (node);
732 /* If any node in a cycle is read_all or write_all, they all are. */
733 FOR_EACH_VEC_ELT (cycle_nodes, x, w)
735 if (dump_file && (dump_flags & TDF_DETAILS))
736 fprintf (dump_file, " Visiting %s/%i\n",
737 cgraph_node_asm_name (w), w->symbol.order);
738 get_read_write_all_from_node (w, read_all, write_all);
739 if (read_all && write_all)
740 break;
743 /* Initialized the bitmaps global sets for the reduced node. */
744 if (read_all)
745 node_g->statics_read = all_module_statics;
746 else
747 node_g->statics_read = copy_static_var_set (node_l->statics_read);
748 if (write_all)
749 node_g->statics_written = all_module_statics;
750 else
751 node_g->statics_written = copy_static_var_set (node_l->statics_written);
753 /* Merge the sets of this cycle with all sets of callees reached
754 from this cycle. */
755 FOR_EACH_VEC_ELT (cycle_nodes, x, w)
757 if (read_all && write_all)
758 break;
760 if (w != node)
762 ipa_reference_vars_info_t w_ri = get_reference_vars_info (w);
763 ipa_reference_local_vars_info_t w_l = &w_ri->local;
764 int flags = flags_from_decl_or_type (w->symbol.decl);
766 if (!(flags & ECF_CONST))
767 read_all = union_static_var_sets (node_g->statics_read,
768 w_l->statics_read);
769 if (!(flags & ECF_PURE)
770 && !cgraph_node_cannot_return (w))
771 write_all = union_static_var_sets (node_g->statics_written,
772 w_l->statics_written);
775 propagate_bits (node_g, w);
778 /* All nodes within a cycle have the same global info bitmaps. */
779 FOR_EACH_VEC_ELT (cycle_nodes, x, w)
781 ipa_reference_vars_info_t w_ri = get_reference_vars_info (w);
782 w_ri->global = *node_g;
785 cycle_nodes.release ();
788 if (dump_file)
790 for (i = 0; i < order_pos; i++)
792 unsigned x;
793 struct cgraph_node *w;
795 node = order[i];
796 if (node->symbol.alias)
797 continue;
799 fprintf (dump_file,
800 "\nFunction name:%s/%i:",
801 cgraph_node_asm_name (node), node->symbol.order);
803 ipa_reference_vars_info_t node_info = get_reference_vars_info (node);
804 ipa_reference_global_vars_info_t node_g = &node_info->global;
806 vec<cgraph_node_ptr> cycle_nodes = ipa_get_nodes_in_cycle (node);
807 FOR_EACH_VEC_ELT (cycle_nodes, x, w)
809 ipa_reference_vars_info_t w_ri = get_reference_vars_info (w);
810 ipa_reference_local_vars_info_t w_l = &w_ri->local;
811 if (w != node)
812 fprintf (dump_file, "\n next cycle: %s/%i ",
813 cgraph_node_asm_name (w), w->symbol.order);
814 fprintf (dump_file, "\n locals read: ");
815 dump_static_vars_set_to_file (dump_file, w_l->statics_read);
816 fprintf (dump_file, "\n locals written: ");
817 dump_static_vars_set_to_file (dump_file, w_l->statics_written);
819 cycle_nodes.release ();
821 fprintf (dump_file, "\n globals read: ");
822 dump_static_vars_set_to_file (dump_file, node_g->statics_read);
823 fprintf (dump_file, "\n globals written: ");
824 dump_static_vars_set_to_file (dump_file, node_g->statics_written);
825 fprintf (dump_file, "\n");
829 /* Cleanup. */
830 FOR_EACH_DEFINED_FUNCTION (node)
832 ipa_reference_vars_info_t node_info;
833 ipa_reference_global_vars_info_t node_g;
834 ipa_reference_optimization_summary_t opt;
836 node_info = get_reference_vars_info (node);
837 if (!node->symbol.alias
838 && (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE
839 || (flags_from_decl_or_type (node->symbol.decl) & ECF_LEAF)))
841 node_g = &node_info->global;
843 opt = XCNEW (struct ipa_reference_optimization_summary_d);
844 set_reference_optimization_summary (node, opt);
846 /* Create the complimentary sets. */
848 if (bitmap_empty_p (node_g->statics_read))
849 opt->statics_not_read = all_module_statics;
850 else
852 opt->statics_not_read
853 = BITMAP_ALLOC (&optimization_summary_obstack);
854 if (node_g->statics_read != all_module_statics)
855 bitmap_and_compl (opt->statics_not_read,
856 all_module_statics,
857 node_g->statics_read);
860 if (bitmap_empty_p (node_g->statics_written))
861 opt->statics_not_written = all_module_statics;
862 else
864 opt->statics_not_written
865 = BITMAP_ALLOC (&optimization_summary_obstack);
866 if (node_g->statics_written != all_module_statics)
867 bitmap_and_compl (opt->statics_not_written,
868 all_module_statics,
869 node_g->statics_written);
872 free (node_info);
875 ipa_free_postorder_info ();
876 free (order);
878 bitmap_obstack_release (&local_info_obstack);
879 ipa_reference_vars_vector.release ();
880 if (dump_file)
881 splay_tree_delete (reference_vars_to_consider);
882 reference_vars_to_consider = NULL;
883 return 0;
886 /* Return true if we need to write summary of NODE. */
888 static bool
889 write_node_summary_p (struct cgraph_node *node,
890 lto_symtab_encoder_t encoder,
891 bitmap ltrans_statics)
893 ipa_reference_optimization_summary_t info;
895 /* See if we have (non-empty) info. */
896 if (!node->symbol.definition || node->global.inlined_to)
897 return false;
898 info = get_reference_optimization_summary (node);
899 if (!info || (bitmap_empty_p (info->statics_not_read)
900 && bitmap_empty_p (info->statics_not_written)))
901 return false;
903 /* See if we want to encode it.
904 Encode also referenced functions since constant folding might turn it into
905 a direct call.
907 In future we might also want to include summaries of functions references
908 by initializers of constant variables references in current unit. */
909 if (!reachable_from_this_partition_p (node, encoder)
910 && !referenced_from_this_partition_p (&node->symbol.ref_list, encoder))
911 return false;
913 /* See if the info has non-empty intersections with vars we want to encode. */
914 if (!bitmap_intersect_p (info->statics_not_read, ltrans_statics)
915 && !bitmap_intersect_p (info->statics_not_written, ltrans_statics))
916 return false;
917 return true;
920 /* Stream out BITS&LTRANS_STATICS as list of decls to OB.
921 LTRANS_STATICS_BITCOUNT specify number of bits in LTRANS_STATICS
922 or -1. When it is positive, just output -1 when
923 BITS&LTRANS_STATICS == BITS&LTRANS_STATICS. */
925 static void
926 stream_out_bitmap (struct lto_simple_output_block *ob,
927 bitmap bits, bitmap ltrans_statics,
928 int ltrans_statics_bitcount)
930 int count = 0;
931 unsigned int index;
932 bitmap_iterator bi;
933 if (bits == all_module_statics)
935 streamer_write_hwi_stream (ob->main_stream, -1);
936 return;
938 EXECUTE_IF_AND_IN_BITMAP (bits, ltrans_statics, 0, index, bi)
939 count ++;
940 if (count == ltrans_statics_bitcount)
942 streamer_write_hwi_stream (ob->main_stream, -1);
943 return;
945 streamer_write_hwi_stream (ob->main_stream, count);
946 if (!count)
947 return;
948 EXECUTE_IF_AND_IN_BITMAP (bits, ltrans_statics, 0, index, bi)
950 tree decl = (tree)splay_tree_lookup (reference_vars_to_consider, index)->value;
951 lto_output_var_decl_index (ob->decl_state, ob->main_stream, decl);
955 /* Serialize the ipa info for lto. */
957 static void
958 ipa_reference_write_optimization_summary (void)
960 struct lto_simple_output_block *ob
961 = lto_create_simple_output_block (LTO_section_ipa_reference);
962 unsigned int count = 0;
963 int ltrans_statics_bitcount = 0;
964 lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
965 bitmap ltrans_statics = BITMAP_ALLOC (NULL);
966 int i;
968 reference_vars_to_consider = splay_tree_new (splay_tree_compare_ints, 0, 0);
970 /* See what variables we are interested in. */
971 for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
973 symtab_node snode = lto_symtab_encoder_deref (encoder, i);
974 varpool_node *vnode = dyn_cast <varpool_node> (snode);
975 if (vnode
976 && bitmap_bit_p (all_module_statics, DECL_UID (vnode->symbol.decl))
977 && referenced_from_this_partition_p (&vnode->symbol.ref_list, encoder))
979 tree decl = vnode->symbol.decl;
980 bitmap_set_bit (ltrans_statics, DECL_UID (decl));
981 splay_tree_insert (reference_vars_to_consider,
982 DECL_UID (decl), (splay_tree_value)decl);
983 ltrans_statics_bitcount ++;
988 if (ltrans_statics_bitcount)
989 for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
991 symtab_node snode = lto_symtab_encoder_deref (encoder, i);
992 cgraph_node *cnode = dyn_cast <cgraph_node> (snode);
993 if (cnode && write_node_summary_p (cnode, encoder, ltrans_statics))
994 count++;
997 streamer_write_uhwi_stream (ob->main_stream, count);
998 if (count)
999 stream_out_bitmap (ob, ltrans_statics, ltrans_statics,
1000 -1);
1002 /* Process all of the functions. */
1003 if (ltrans_statics_bitcount)
1004 for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
1006 symtab_node snode = lto_symtab_encoder_deref (encoder, i);
1007 cgraph_node *cnode = dyn_cast <cgraph_node> (snode);
1008 if (cnode && write_node_summary_p (cnode, encoder, ltrans_statics))
1010 ipa_reference_optimization_summary_t info;
1011 int node_ref;
1013 info = get_reference_optimization_summary (cnode);
1014 node_ref = lto_symtab_encoder_encode (encoder, snode);
1015 streamer_write_uhwi_stream (ob->main_stream, node_ref);
1017 stream_out_bitmap (ob, info->statics_not_read, ltrans_statics,
1018 ltrans_statics_bitcount);
1019 stream_out_bitmap (ob, info->statics_not_written, ltrans_statics,
1020 ltrans_statics_bitcount);
1023 BITMAP_FREE (ltrans_statics);
1024 lto_destroy_simple_output_block (ob);
1025 splay_tree_delete (reference_vars_to_consider);
1028 /* Deserialize the ipa info for lto. */
1030 static void
1031 ipa_reference_read_optimization_summary (void)
1033 struct lto_file_decl_data ** file_data_vec
1034 = lto_get_file_decl_data ();
1035 struct lto_file_decl_data * file_data;
1036 unsigned int j = 0;
1037 bitmap_obstack_initialize (&optimization_summary_obstack);
1039 node_removal_hook_holder =
1040 cgraph_add_node_removal_hook (&remove_node_data, NULL);
1041 node_duplication_hook_holder =
1042 cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
1043 all_module_statics = BITMAP_ALLOC (&optimization_summary_obstack);
1045 while ((file_data = file_data_vec[j++]))
1047 const char *data;
1048 size_t len;
1049 struct lto_input_block *ib
1050 = lto_create_simple_input_block (file_data,
1051 LTO_section_ipa_reference,
1052 &data, &len);
1053 if (ib)
1055 unsigned int i;
1056 unsigned int f_count = streamer_read_uhwi (ib);
1057 int b_count;
1058 if (!f_count)
1059 continue;
1060 b_count = streamer_read_hwi (ib);
1061 if (dump_file)
1062 fprintf (dump_file, "all module statics:");
1063 for (i = 0; i < (unsigned int)b_count; i++)
1065 unsigned int var_index = streamer_read_uhwi (ib);
1066 tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1067 var_index);
1068 bitmap_set_bit (all_module_statics, DECL_UID (v_decl));
1069 if (dump_file)
1070 fprintf (dump_file, " %s", fndecl_name (v_decl));
1073 for (i = 0; i < f_count; i++)
1075 unsigned int j, index;
1076 struct cgraph_node *node;
1077 ipa_reference_optimization_summary_t info;
1078 int v_count;
1079 lto_symtab_encoder_t encoder;
1081 index = streamer_read_uhwi (ib);
1082 encoder = file_data->symtab_node_encoder;
1083 node = cgraph (lto_symtab_encoder_deref (encoder, index));
1084 info = XCNEW (struct ipa_reference_optimization_summary_d);
1085 set_reference_optimization_summary (node, info);
1086 info->statics_not_read = BITMAP_ALLOC (&optimization_summary_obstack);
1087 info->statics_not_written = BITMAP_ALLOC (&optimization_summary_obstack);
1088 if (dump_file)
1089 fprintf (dump_file,
1090 "\nFunction name:%s/%i:\n static not read:",
1091 cgraph_node_asm_name (node), node->symbol.order);
1093 /* Set the statics not read. */
1094 v_count = streamer_read_hwi (ib);
1095 if (v_count == -1)
1097 info->statics_not_read = all_module_statics;
1098 if (dump_file)
1099 fprintf (dump_file, " all module statics");
1101 else
1102 for (j = 0; j < (unsigned int)v_count; j++)
1104 unsigned int var_index = streamer_read_uhwi (ib);
1105 tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1106 var_index);
1107 bitmap_set_bit (info->statics_not_read, DECL_UID (v_decl));
1108 if (dump_file)
1109 fprintf (dump_file, " %s", fndecl_name (v_decl));
1112 if (dump_file)
1113 fprintf (dump_file,
1114 "\n static not written:");
1115 /* Set the statics not written. */
1116 v_count = streamer_read_hwi (ib);
1117 if (v_count == -1)
1119 info->statics_not_written = all_module_statics;
1120 if (dump_file)
1121 fprintf (dump_file, " all module statics");
1123 else
1124 for (j = 0; j < (unsigned int)v_count; j++)
1126 unsigned int var_index = streamer_read_uhwi (ib);
1127 tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1128 var_index);
1129 bitmap_set_bit (info->statics_not_written, DECL_UID (v_decl));
1130 if (dump_file)
1131 fprintf (dump_file, " %s", fndecl_name (v_decl));
1133 if (dump_file)
1134 fprintf (dump_file, "\n");
1137 lto_destroy_simple_input_block (file_data,
1138 LTO_section_ipa_reference,
1139 ib, data, len);
1141 else
1142 /* Fatal error here. We do not want to support compiling ltrans units with
1143 different version of compiler or different flags than the WPA unit, so
1144 this should never happen. */
1145 fatal_error ("ipa reference summary is missing in ltrans unit");
1149 static bool
1150 gate_reference (void)
1152 return (flag_ipa_reference
1153 /* Don't bother doing anything if the program has errors. */
1154 && !seen_error ());
1157 namespace {
1159 const pass_data pass_data_ipa_reference =
1161 IPA_PASS, /* type */
1162 "static-var", /* name */
1163 OPTGROUP_NONE, /* optinfo_flags */
1164 true, /* has_gate */
1165 true, /* has_execute */
1166 TV_IPA_REFERENCE, /* tv_id */
1167 0, /* properties_required */
1168 0, /* properties_provided */
1169 0, /* properties_destroyed */
1170 0, /* todo_flags_start */
1171 0, /* todo_flags_finish */
1174 class pass_ipa_reference : public ipa_opt_pass_d
1176 public:
1177 pass_ipa_reference (gcc::context *ctxt)
1178 : ipa_opt_pass_d (pass_data_ipa_reference, ctxt,
1179 NULL, /* generate_summary */
1180 NULL, /* write_summary */
1181 NULL, /* read_summary */
1182 ipa_reference_write_optimization_summary, /*
1183 write_optimization_summary */
1184 ipa_reference_read_optimization_summary, /*
1185 read_optimization_summary */
1186 NULL, /* stmt_fixup */
1187 0, /* function_transform_todo_flags_start */
1188 NULL, /* function_transform */
1189 NULL) /* variable_transform */
1192 /* opt_pass methods: */
1193 bool gate () { return gate_reference (); }
1194 unsigned int execute () { return propagate (); }
1196 }; // class pass_ipa_reference
1198 } // anon namespace
1200 ipa_opt_pass_d *
1201 make_pass_ipa_reference (gcc::context *ctxt)
1203 return new pass_ipa_reference (ctxt);