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