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