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