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