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