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