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