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