]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/ipa-reference.c
re PR other/44038 (ICE: verify_stmts failed)
[thirdparty/gcc.git] / gcc / ipa-reference.c
CommitLineData
ea900239 1/* Callgraph based analysis of static variables.
c75c517d
SB
2 Copyright (C) 2004, 2005, 2007, 2008, 2009, 2010
3 Free Software Foundation, Inc.
ea900239
DB
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
9dcd6f09 10Software Foundation; either version 3, or (at your option) any later
ea900239
DB
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
9dcd6f09
NC
19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
ea900239
DB
21
22/* This file gathers information about how variables whose scope is
b8698a0f 23 confined to the compilation unit are used.
ea900239 24
4a444e58 25 The transitive call site specific clobber effects are computed
ea900239
DB
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
4a444e58 38 information. */
ea900239
DB
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"
ea264ca5 50#include "splay-tree.h"
ea900239
DB
51#include "ggc.h"
52#include "ipa-utils.h"
53#include "ipa-reference.h"
726a989a 54#include "gimple.h"
ea900239
DB
55#include "cgraph.h"
56#include "output.h"
57#include "flags.h"
58#include "timevar.h"
59#include "diagnostic.h"
60#include "langhooks.h"
d7f09764
DN
61#include "lto-streamer.h"
62
d7f09764
DN
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);
ea900239 68
e2c9111c 69/* The static variables defined within the compilation unit that are
b8698a0f 70 loaded or stored directly by function that owns this structure. */
e2c9111c 71
b8698a0f 72struct ipa_reference_local_vars_info_d
e2c9111c
JH
73{
74 bitmap statics_read;
75 bitmap statics_written;
76
77 /* Set when this function calls another function external to the
78 compilation unit or if the function has a asm clobber of memory.
79 In general, such calls are modeled as reading and writing all
80 variables (both bits on) but sometime there are attributes on the
81 called function so we can do better. */
82 bool calls_read_all;
83 bool calls_write_all;
84};
85
86/* Statics that are read and written by some set of functions. The
87 local ones are based on the loads and stores local to the function.
88 The global ones are based on the local info as well as the
46c30019 89 transitive closure of the functions that are called. */
e2c9111c
JH
90
91struct ipa_reference_global_vars_info_d
92{
93 bitmap statics_read;
94 bitmap statics_written;
46c30019
JH
95};
96
97/* Information we save about every function after ipa-reference is completted. */
98
99struct ipa_reference_optimization_summary_d
100{
e2c9111c
JH
101 bitmap statics_not_read;
102 bitmap statics_not_written;
103};
104
105typedef struct ipa_reference_local_vars_info_d *ipa_reference_local_vars_info_t;
106typedef struct ipa_reference_global_vars_info_d *ipa_reference_global_vars_info_t;
46c30019
JH
107typedef struct ipa_reference_optimization_summary_d *ipa_reference_optimization_summary_t;
108
b8698a0f 109struct ipa_reference_vars_info_d
e2c9111c 110{
46c30019
JH
111 struct ipa_reference_local_vars_info_d local;
112 struct ipa_reference_global_vars_info_d global;
e2c9111c
JH
113};
114
115typedef struct ipa_reference_vars_info_d *ipa_reference_vars_info_t;
116
ea900239 117/* This splay tree contains all of the static variables that are
46c30019
JH
118 being considered by the compilation level alias analysis. */
119static splay_tree reference_vars_to_consider;
ea900239 120
ea900239
DB
121/* A bit is set for every module static we are considering. This is
122 ored into the local info when asm code is found that clobbers all
123 memory. */
124static bitmap all_module_statics;
125
ebcf9dc8
JH
126/* Obstack holding bitmaps of local analysis (live from analysis to
127 propagation) */
128static bitmap_obstack local_info_obstack;
129/* Obstack holding global analysis live forever. */
46c30019 130static bitmap_obstack optimization_summary_obstack;
ea900239 131
129a37fc 132/* Holders of ipa cgraph hooks: */
e2c9111c
JH
133static struct cgraph_2node_hook_list *node_duplication_hook_holder;
134static struct cgraph_node_hook_list *node_removal_hook_holder;
129a37fc 135
e2c9111c
JH
136/* Vector where the reference var infos are actually stored. */
137DEF_VEC_P (ipa_reference_vars_info_t);
138DEF_VEC_ALLOC_P (ipa_reference_vars_info_t, heap);
139static VEC (ipa_reference_vars_info_t, heap) *ipa_reference_vars_vector;
46c30019
JH
140DEF_VEC_P (ipa_reference_optimization_summary_t);
141DEF_VEC_ALLOC_P (ipa_reference_optimization_summary_t, heap);
142static VEC (ipa_reference_optimization_summary_t, heap) *ipa_reference_opt_sum_vector;
e2c9111c 143
ea900239
DB
144/* Return the ipa_reference_vars structure starting from the cgraph NODE. */
145static inline ipa_reference_vars_info_t
e2c9111c
JH
146get_reference_vars_info (struct cgraph_node *node)
147{
148 if (!ipa_reference_vars_vector
46c30019
JH
149 || VEC_length (ipa_reference_vars_info_t,
150 ipa_reference_vars_vector) <= (unsigned int) node->uid)
e2c9111c 151 return NULL;
46c30019
JH
152 return VEC_index (ipa_reference_vars_info_t, ipa_reference_vars_vector,
153 node->uid);
e2c9111c
JH
154}
155
156/* Return the ipa_reference_vars structure starting from the cgraph NODE. */
46c30019
JH
157static inline ipa_reference_optimization_summary_t
158get_reference_optimization_summary (struct cgraph_node *node)
ea900239 159{
46c30019
JH
160 if (!ipa_reference_opt_sum_vector
161 || (VEC_length (ipa_reference_optimization_summary_t,
162 ipa_reference_opt_sum_vector)
163 <= (unsigned int) node->uid))
ea900239 164 return NULL;
46c30019
JH
165 return VEC_index (ipa_reference_optimization_summary_t, ipa_reference_opt_sum_vector,
166 node->uid);
ea900239
DB
167}
168
46c30019
JH
169/* Return the ipa_reference_vars structure starting from the cgraph NODE. */
170static inline void
171set_reference_vars_info (struct cgraph_node *node,
172 ipa_reference_vars_info_t info)
ea900239 173{
46c30019
JH
174 if (!ipa_reference_vars_vector
175 || VEC_length (ipa_reference_vars_info_t,
176 ipa_reference_vars_vector) <= (unsigned int) node->uid)
177 VEC_safe_grow_cleared (ipa_reference_vars_info_t, heap,
178 ipa_reference_vars_vector, node->uid + 1);
179 VEC_replace (ipa_reference_vars_info_t, ipa_reference_vars_vector,
180 node->uid, info);
ea900239
DB
181}
182
46c30019
JH
183/* Return the ipa_reference_vars structure starting from the cgraph NODE. */
184static inline void
185set_reference_optimization_summary (struct cgraph_node *node,
186 ipa_reference_optimization_summary_t info)
ea900239 187{
46c30019
JH
188 if (!ipa_reference_opt_sum_vector
189 || (VEC_length (ipa_reference_optimization_summary_t,
190 ipa_reference_opt_sum_vector)
191 <= (unsigned int) node->uid))
192 VEC_safe_grow_cleared (ipa_reference_optimization_summary_t,
193 heap, ipa_reference_opt_sum_vector, node->uid + 1);
194 VEC_replace (ipa_reference_optimization_summary_t,
195 ipa_reference_opt_sum_vector, node->uid, info);
ea900239
DB
196}
197
198/* Return a bitmap indexed by_DECL_UID uid for the static variables
199 that are not read during the execution of the function FN. Returns
200 NULL if no data is available. */
201
b8698a0f
L
202bitmap
203ipa_reference_get_not_read_global (struct cgraph_node *fn)
ea900239 204{
46c30019
JH
205 ipa_reference_optimization_summary_t info;
206
207 info = get_reference_optimization_summary (fn);
208 if (info)
209 return info->statics_not_read;
ea900239
DB
210 else
211 return NULL;
212}
213
214/* Return a bitmap indexed by DECL_UID uid for the static variables
215 that are not written during the execution of the function FN. Note
216 that variables written may or may not be read during the function
217 call. Returns NULL if no data is available. */
218
b8698a0f
L
219bitmap
220ipa_reference_get_not_written_global (struct cgraph_node *fn)
ea900239 221{
46c30019
JH
222 ipa_reference_optimization_summary_t info;
223
224 info = get_reference_optimization_summary (fn);
225 if (info)
226 return info->statics_not_written;
ea900239
DB
227 else
228 return NULL;
229}
230
231\f
232
233/* Add VAR to all_module_statics and the two
234 reference_vars_to_consider* sets. */
235
b8698a0f
L
236static inline void
237add_static_var (tree var)
ea900239
DB
238{
239 int uid = DECL_UID (var);
ebcf9dc8 240 gcc_assert (TREE_CODE (var) == VAR_DECL);
ea900239
DB
241 if (!bitmap_bit_p (all_module_statics, uid))
242 {
46c30019
JH
243 if (dump_file)
244 splay_tree_insert (reference_vars_to_consider,
245 uid, (splay_tree_value)var);
ea900239
DB
246 bitmap_set_bit (all_module_statics, uid);
247 }
248}
249
250/* Return true if the variable T is the right kind of static variable to
251 perform compilation unit scope escape analysis. */
252
b8698a0f 253static inline bool
5f902d76 254is_proper_for_analysis (tree t)
ea900239 255{
46c30019
JH
256 /* We handle only variables whose address is never taken. */
257 if (TREE_ADDRESSABLE (t))
258 return false;
ea900239
DB
259 /* If the variable has the "used" attribute, treat it as if it had a
260 been touched by the devil. */
b42186f1 261 if (DECL_PRESERVE_P (t))
ea900239
DB
262 return false;
263
264 /* Do not want to do anything with volatile except mark any
265 function that uses one to be not const or pure. */
b8698a0f 266 if (TREE_THIS_VOLATILE (t))
ea900239
DB
267 return false;
268
2276d5ed
AP
269 /* We cannot touch decls where the type needs constructing. */
270 if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (t)))
271 return false;
272
ea900239
DB
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. */
275 if (!bitmap_bit_p (all_module_statics, DECL_UID (t)))
276 add_static_var (t);
277
278 return true;
279}
280
ea900239 281/* Lookup the tree node for the static variable that has UID and
a4174ebf 282 convert the name to a string for debugging. */
ea900239
DB
283
284static const char *
285get_static_name (int index)
286{
b8698a0f 287 splay_tree_node stn =
ea900239
DB
288 splay_tree_lookup (reference_vars_to_consider, index);
289 if (stn)
290 return lang_hooks.decl_printable_name ((tree)(stn->value), 2);
291 return NULL;
292}
293
e2c9111c
JH
294/* Or in all of the bits from every callee of X into X_GLOBAL, the caller's cycle,
295 bit vector. There are several cases to check to avoid the sparse
ea900239
DB
296 bitmap oring. */
297
298static void
e2c9111c 299propagate_bits (ipa_reference_global_vars_info_t x_global, struct cgraph_node *x)
ea900239 300{
ea900239 301 struct cgraph_edge *e;
b8698a0f 302 for (e = x->callees; e; e = e->next_callee)
ea900239
DB
303 {
304 struct cgraph_node *y = e->callee;
305
c59f5d1b 306 /* Only look into nodes we can propagate something. */
e2c9111c 307 if (cgraph_function_body_availability (e->callee) > AVAIL_OVERWRITABLE)
ea900239 308 {
e2c9111c 309 if (get_reference_vars_info (y))
ea900239 310 {
b8698a0f 311 ipa_reference_vars_info_t y_info
e2c9111c 312 = get_reference_vars_info (y);
46c30019 313 ipa_reference_global_vars_info_t y_global = &y_info->global;
e2c9111c
JH
314
315 /* Calls in current cycle do not have global computed yet. */
46c30019 316 if (!y_global->statics_read)
e2c9111c 317 continue;
b8698a0f 318
ea900239
DB
319 if (x_global->statics_read
320 != all_module_statics)
321 {
b8698a0f 322 if (y_global->statics_read
ea900239
DB
323 == all_module_statics)
324 {
325 BITMAP_FREE (x_global->statics_read);
b8698a0f 326 x_global->statics_read
ea900239
DB
327 = all_module_statics;
328 }
329 /* Skip bitmaps that are pointer equal to node's bitmap
330 (no reason to spin within the cycle). */
b8698a0f 331 else if (x_global->statics_read
ea900239
DB
332 != y_global->statics_read)
333 bitmap_ior_into (x_global->statics_read,
334 y_global->statics_read);
335 }
b8698a0f
L
336
337 if (x_global->statics_written
ea900239
DB
338 != all_module_statics)
339 {
b8698a0f 340 if (y_global->statics_written
ea900239
DB
341 == all_module_statics)
342 {
343 BITMAP_FREE (x_global->statics_written);
b8698a0f 344 x_global->statics_written
ea900239
DB
345 = all_module_statics;
346 }
347 /* Skip bitmaps that are pointer equal to node's bitmap
348 (no reason to spin within the cycle). */
b8698a0f 349 else if (x_global->statics_written
ea900239
DB
350 != y_global->statics_written)
351 bitmap_ior_into (x_global->statics_written,
352 y_global->statics_written);
353 }
354 }
b8698a0f 355 else
ebcf9dc8 356 gcc_unreachable ();
ea900239
DB
357 }
358 }
359}
360
ea900239
DB
361/* The init routine for analyzing global static variable usage. See
362 comments at top for description. */
b8698a0f
L
363static void
364ipa_init (void)
ea900239 365{
d7f09764
DN
366 static bool init_p = false;
367
368 if (init_p)
369 return;
370
371 init_p = true;
372
46c30019
JH
373 if (dump_file)
374 reference_vars_to_consider = splay_tree_new (splay_tree_compare_ints, 0, 0);
ea900239 375
ebcf9dc8 376 bitmap_obstack_initialize (&local_info_obstack);
46c30019
JH
377 bitmap_obstack_initialize (&optimization_summary_obstack);
378 all_module_statics = BITMAP_ALLOC (&local_info_obstack);
7dbca013 379
d7f09764
DN
380 node_removal_hook_holder =
381 cgraph_add_node_removal_hook (&remove_node_data, NULL);
382 node_duplication_hook_holder =
383 cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
ea900239
DB
384}
385
d7f09764 386
812dbce5 387/* Set up the persistent info for FN. */
ea900239 388
812dbce5
JH
389static ipa_reference_local_vars_info_t
390init_function_info (struct cgraph_node *fn)
ea900239 391{
b8698a0f 392 ipa_reference_vars_info_t info
c5274326 393 = XCNEW (struct ipa_reference_vars_info_d);
ea900239
DB
394
395 /* Add the info to the tree's annotation. */
e2c9111c 396 set_reference_vars_info (fn, info);
ea900239 397
46c30019
JH
398 info->local.statics_read = BITMAP_ALLOC (&local_info_obstack);
399 info->local.statics_written = BITMAP_ALLOC (&local_info_obstack);
ea900239 400
46c30019 401 return &info->local;
812dbce5
JH
402}
403
d7f09764 404
812dbce5
JH
405/* This is the main routine for finding the reference patterns for
406 global variables within a function FN. */
d7f09764 407
812dbce5
JH
408static void
409analyze_function (struct cgraph_node *fn)
410{
8b583a06 411 ipa_reference_local_vars_info_t local;
5f902d76
JH
412 struct ipa_ref *ref;
413 int i;
414 tree var;
415 struct cgraph_edge *ie;
812dbce5 416
5f902d76
JH
417 local = init_function_info (fn);
418 /* Process indirect calls. All direct calles are handled at propagation
419 time. */
420 for (ie = fn->indirect_calls; ie; ie = ie->next_callee)
421 if (!(ie->indirect_info->ecf_flags & ECF_CONST))
422 {
423 local->calls_read_all = true;
424 if (!(ie->indirect_info->ecf_flags & ECF_PURE)
425 && ((ie->indirect_info->ecf_flags & (ECF_NOTHROW | ECF_NORETURN))
426 != (ECF_NOTHROW | ECF_NORETURN)))
427 local->calls_write_all = true;
428 }
429 for (i = 0; ipa_ref_list_reference_iterate (&fn->ref_list, i, ref); i++)
812dbce5 430 {
5f902d76
JH
431 if (ref->refered_type != IPA_REF_VARPOOL)
432 continue;
433 var = ipa_ref_varpool_node (ref)->decl;
434 if (ipa_ref_varpool_node (ref)->externally_visible
435 || !ipa_ref_varpool_node (ref)->analyzed
436 || !is_proper_for_analysis (var))
437 continue;
438 switch (ref->use)
812dbce5 439 {
5f902d76
JH
440 case IPA_REF_LOAD:
441 bitmap_set_bit (local->statics_read, DECL_UID (var));
442 break;
443 case IPA_REF_STORE:
444 bitmap_set_bit (local->statics_written, DECL_UID (var));
5f902d76
JH
445 break;
446 case IPA_REF_ADDR:
5f902d76 447 break;
812dbce5 448 }
812dbce5 449 }
ea900239 450
5f902d76 451 if ((flags_from_decl_or_type (fn->decl) & (ECF_NOTHROW | ECF_NORETURN))
8b583a06
JH
452 == (ECF_NOTHROW | ECF_NORETURN))
453 {
454 local->calls_write_all = false;
455 bitmap_clear (local->statics_written);
456 }
457
458 /* Free bitmaps of direct references if we can not use them anyway. */
459 if (local->calls_write_all)
460 BITMAP_FREE (local->statics_written);
461 if (local->calls_read_all)
462 BITMAP_FREE (local->statics_read);
ea900239
DB
463}
464
e2c9111c
JH
465static bitmap
466copy_global_bitmap (bitmap src)
467{
468 bitmap dst;
469 if (!src)
470 return NULL;
46c30019 471 dst = BITMAP_ALLOC (&optimization_summary_obstack);
e2c9111c
JH
472 bitmap_copy (dst, src);
473 return dst;
474}
475
5f902d76 476
e2c9111c
JH
477/* Called when new clone is inserted to callgraph late. */
478
479static void
480duplicate_node_data (struct cgraph_node *src, struct cgraph_node *dst,
481 void *data ATTRIBUTE_UNUSED)
482{
46c30019
JH
483 ipa_reference_optimization_summary_t ginfo;
484 ipa_reference_optimization_summary_t dst_ginfo;
e2c9111c 485
46c30019 486 ginfo = get_reference_optimization_summary (src);
5f902d76 487 if (!ginfo)
e2c9111c 488 return;
46c30019
JH
489 dst_ginfo = XCNEW (struct ipa_reference_optimization_summary_d);
490 set_reference_optimization_summary (dst, dst_ginfo);
491 dst_ginfo->statics_not_read = copy_global_bitmap (ginfo->statics_not_read);
492 dst_ginfo->statics_not_written = copy_global_bitmap (ginfo->statics_not_written);
e2c9111c
JH
493}
494
495/* Called when node is removed. */
496
497static void
498remove_node_data (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
499{
46c30019
JH
500 ipa_reference_optimization_summary_t ginfo;
501 ginfo = get_reference_optimization_summary (node);
502 if (ginfo)
503 {
504 if (ginfo->statics_not_read
505 && ginfo->statics_not_read != all_module_statics)
506 BITMAP_FREE (ginfo->statics_not_read);
507
508 if (ginfo->statics_not_written
509 && ginfo->statics_not_written != all_module_statics)
510 BITMAP_FREE (ginfo->statics_not_written);
511 free (ginfo);
512 set_reference_optimization_summary (node, NULL);
513 }
e2c9111c
JH
514}
515
812dbce5
JH
516/* Analyze each function in the cgraph to see which global or statics
517 are read or written. */
518
b8698a0f 519static void
812dbce5 520generate_summary (void)
ea900239
DB
521{
522 struct cgraph_node *node;
812dbce5
JH
523 unsigned int index;
524 bitmap_iterator bi;
812dbce5 525 bitmap bm_temp;
b8698a0f 526
ea900239 527 ipa_init ();
ebcf9dc8 528 bm_temp = BITMAP_ALLOC (&local_info_obstack);
ea900239 529
5f902d76 530 /* Process all of the functions next. */
ea900239 531 for (node = cgraph_nodes; node; node = node->next)
5f902d76 532 if (node->analyzed)
ea900239
DB
533 analyze_function (node);
534
812dbce5 535 if (dump_file)
ea900239
DB
536 EXECUTE_IF_SET_IN_BITMAP (all_module_statics, 0, index, bi)
537 {
812dbce5
JH
538 fprintf (dump_file, "\nPromotable global:%s",
539 get_static_name (index));
ea900239 540 }
b8698a0f 541
812dbce5 542 BITMAP_FREE(bm_temp);
b8698a0f 543
ea900239 544 if (dump_file)
812dbce5 545 for (node = cgraph_nodes; node; node = node->next)
e2c9111c 546 if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
ea900239 547 {
ea900239 548 ipa_reference_local_vars_info_t l;
812dbce5 549 unsigned int index;
ea900239 550 bitmap_iterator bi;
b8698a0f 551
46c30019 552 l = &get_reference_vars_info (node)->local;
b8698a0f
L
553 fprintf (dump_file,
554 "\nFunction name:%s/%i:",
ea900239
DB
555 cgraph_node_name (node), node->uid);
556 fprintf (dump_file, "\n locals read: ");
8b583a06
JH
557 if (l->statics_read)
558 EXECUTE_IF_SET_IN_BITMAP (l->statics_read,
559 0, index, bi)
560 {
561 fprintf (dump_file, "%s ",
562 get_static_name (index));
563 }
ea900239 564 fprintf (dump_file, "\n locals written: ");
8b583a06
JH
565 if (l->statics_written)
566 EXECUTE_IF_SET_IN_BITMAP (l->statics_written,
567 0, index, bi)
568 {
569 fprintf(dump_file, "%s ",
570 get_static_name (index));
571 }
e2c9111c
JH
572 if (l->calls_read_all)
573 fprintf (dump_file, "\n calls read all: ");
574 if (l->calls_write_all)
575 fprintf (dump_file, "\n calls read all: ");
ea900239 576 }
812dbce5
JH
577}
578\f
c59f5d1b 579/* Set READ_ALL/WRITE_ALL based on DECL flags. */
46c30019 580
c59f5d1b
JH
581static void
582read_write_all_from_decl (tree decl, bool * read_all, bool * write_all)
583{
584 int flags = flags_from_decl_or_type (decl);
585 if (flags & ECF_CONST)
586 ;
587 else if (flags & ECF_PURE)
588 *read_all = true;
589 else
590 {
591 /* TODO: To be able to produce sane results, we should also handle
46c30019 592 common builtins, in particular throw. */
c59f5d1b 593 *read_all = true;
46c30019 594 /* When function does not return, it is safe to ignore anythign it writes
8b583a06
JH
595 to, because the effect will never happen. */
596 if ((flags & (ECF_NOTHROW | ECF_NORETURN))
597 != (ECF_NOTHROW | ECF_NORETURN))
598 *write_all = true;
c59f5d1b
JH
599 }
600}
601
812dbce5 602/* Produce the global information by preforming a transitive closure
46c30019 603 on the local information that was produced by ipa_analyze_function */
812dbce5
JH
604
605static unsigned int
606propagate (void)
607{
608 struct cgraph_node *node;
609 struct cgraph_node *w;
610 struct cgraph_node **order =
611 XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
2505c5ed 612 int order_pos = ipa_utils_reduced_inorder (order, false, true, NULL);
812dbce5
JH
613 int i;
614
b8698a0f 615 if (dump_file)
812dbce5 616 dump_cgraph (dump_file);
ea900239 617
46c30019 618 ipa_discover_readonly_nonaddressable_vars ();
5f902d76
JH
619 generate_summary ();
620
ea900239
DB
621 /* Propagate the local information thru the call graph to produce
622 the global information. All the nodes within a cycle will have
623 the same info so we collapse cycles first. Then we can do the
624 propagation in one pass from the leaves to the roots. */
2505c5ed 625 order_pos = ipa_utils_reduced_inorder (order, true, true, NULL);
ea900239
DB
626 if (dump_file)
627 ipa_utils_print_order(dump_file, "reduced", order, order_pos);
628
629 for (i = 0; i < order_pos; i++ )
630 {
631 ipa_reference_vars_info_t node_info;
46c30019 632 ipa_reference_global_vars_info_t node_g;
ea900239 633 ipa_reference_local_vars_info_t node_l;
c59f5d1b 634 struct cgraph_edge *e;
b8698a0f 635
ea900239
DB
636 bool read_all;
637 bool write_all;
638 struct ipa_dfs_info * w_info;
639
640 node = order[i];
e2c9111c 641 node_info = get_reference_vars_info (node);
b8698a0f 642 if (!node_info)
ea900239
DB
643 {
644 dump_cgraph_node (stderr, node);
645 dump_cgraph (stderr);
646 gcc_unreachable ();
647 }
648
46c30019
JH
649 node_l = &node_info->local;
650 node_g = &node_info->global;
ea900239
DB
651
652 read_all = node_l->calls_read_all;
653 write_all = node_l->calls_write_all;
654
c59f5d1b
JH
655 /* When function is overwrittable, we can not assume anything. */
656 if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
657 read_write_all_from_decl (node->decl, &read_all, &write_all);
658
b8698a0f 659 for (e = node->callees; e; e = e->next_callee)
c59f5d1b
JH
660 if (cgraph_function_body_availability (e->callee) <= AVAIL_OVERWRITABLE)
661 read_write_all_from_decl (e->callee->decl, &read_all, &write_all);
662
663
ea900239
DB
664 /* If any node in a cycle is calls_read_all or calls_write_all
665 they all are. */
c5274326 666 w_info = (struct ipa_dfs_info *) node->aux;
ea900239
DB
667 w = w_info->next_cycle;
668 while (w)
669 {
b8698a0f 670 ipa_reference_local_vars_info_t w_l =
46c30019 671 &get_reference_vars_info (w)->local;
c59f5d1b
JH
672
673 /* When function is overwrittable, we can not assume anything. */
674 if (cgraph_function_body_availability (w) <= AVAIL_OVERWRITABLE)
675 read_write_all_from_decl (w->decl, &read_all, &write_all);
676
b8698a0f 677 for (e = w->callees; e; e = e->next_callee)
c59f5d1b
JH
678 if (cgraph_function_body_availability (e->callee) <= AVAIL_OVERWRITABLE)
679 read_write_all_from_decl (e->callee->decl, &read_all, &write_all);
680
ea900239
DB
681 read_all |= w_l->calls_read_all;
682 write_all |= w_l->calls_write_all;
683
c5274326 684 w_info = (struct ipa_dfs_info *) w->aux;
ea900239
DB
685 w = w_info->next_cycle;
686 }
687
c59f5d1b 688
ea900239 689 /* Initialized the bitmaps for the reduced nodes */
b8698a0f 690 if (read_all)
ea900239 691 node_g->statics_read = all_module_statics;
b8698a0f 692 else
ea900239 693 {
46c30019 694 node_g->statics_read = BITMAP_ALLOC (&local_info_obstack);
b8698a0f 695 bitmap_copy (node_g->statics_read,
ea900239
DB
696 node_l->statics_read);
697 }
b8698a0f 698 if (write_all)
ea900239
DB
699 node_g->statics_written = all_module_statics;
700 else
701 {
46c30019 702 node_g->statics_written = BITMAP_ALLOC (&local_info_obstack);
b8698a0f 703 bitmap_copy (node_g->statics_written,
ea900239
DB
704 node_l->statics_written);
705 }
706
e2c9111c 707 propagate_bits (node_g, node);
c5274326 708 w_info = (struct ipa_dfs_info *) node->aux;
ea900239
DB
709 w = w_info->next_cycle;
710 while (w)
711 {
b8698a0f 712 ipa_reference_vars_info_t w_ri =
e2c9111c 713 get_reference_vars_info (w);
46c30019 714 ipa_reference_local_vars_info_t w_l = &w_ri->local;
b8698a0f 715
ea900239
DB
716 /* These global bitmaps are initialized from the local info
717 of all of the nodes in the region. However there is no
718 need to do any work if the bitmaps were set to
719 all_module_statics. */
720 if (!read_all)
721 bitmap_ior_into (node_g->statics_read,
722 w_l->statics_read);
723 if (!write_all)
724 bitmap_ior_into (node_g->statics_written,
725 w_l->statics_written);
e2c9111c 726 propagate_bits (node_g, w);
c5274326 727 w_info = (struct ipa_dfs_info *) w->aux;
ea900239
DB
728 w = w_info->next_cycle;
729 }
730
e2c9111c 731 /* All nodes within a cycle have the same global info bitmaps. */
46c30019 732 node_info->global = *node_g;
c5274326 733 w_info = (struct ipa_dfs_info *) node->aux;
ea900239
DB
734 w = w_info->next_cycle;
735 while (w)
736 {
b8698a0f 737 ipa_reference_vars_info_t w_ri =
e2c9111c
JH
738 get_reference_vars_info (w);
739
46c30019 740 w_ri->global = *node_g;
e2c9111c 741
c5274326 742 w_info = (struct ipa_dfs_info *) w->aux;
ea900239
DB
743 w = w_info->next_cycle;
744 }
745 }
746
747 if (dump_file)
748 {
749 for (i = 0; i < order_pos; i++ )
750 {
751 ipa_reference_vars_info_t node_info;
752 ipa_reference_global_vars_info_t node_g;
753 ipa_reference_local_vars_info_t node_l;
754 unsigned int index;
755 bitmap_iterator bi;
756 struct ipa_dfs_info * w_info;
757
758 node = order[i];
e2c9111c 759 node_info = get_reference_vars_info (node);
46c30019
JH
760 node_g = &node_info->global;
761 node_l = &node_info->local;
b8698a0f
L
762 fprintf (dump_file,
763 "\nFunction name:%s/%i:",
ea900239
DB
764 cgraph_node_name (node), node->uid);
765 fprintf (dump_file, "\n locals read: ");
8b583a06
JH
766 if (node_l->statics_read)
767 EXECUTE_IF_SET_IN_BITMAP (node_l->statics_read,
768 0, index, bi)
769 {
770 fprintf (dump_file, "%s ",
771 get_static_name (index));
772 }
ea900239 773 fprintf (dump_file, "\n locals written: ");
8b583a06
JH
774 if (node_l->statics_written)
775 EXECUTE_IF_SET_IN_BITMAP (node_l->statics_written,
776 0, index, bi)
777 {
778 fprintf(dump_file, "%s ",
779 get_static_name (index));
780 }
ea900239 781
c5274326 782 w_info = (struct ipa_dfs_info *) node->aux;
ea900239 783 w = w_info->next_cycle;
b8698a0f 784 while (w)
ea900239 785 {
b8698a0f 786 ipa_reference_vars_info_t w_ri =
e2c9111c 787 get_reference_vars_info (w);
46c30019 788 ipa_reference_local_vars_info_t w_l = &w_ri->local;
ea900239
DB
789 fprintf (dump_file, "\n next cycle: %s/%i ",
790 cgraph_node_name (w), w->uid);
40513dd3
JJ
791 fprintf (dump_file, "\n locals read: ");
792 if (w_l->statics_read)
793 EXECUTE_IF_SET_IN_BITMAP (w_l->statics_read,
794 0, index, bi)
795 {
796 fprintf (dump_file, "%s ",
797 get_static_name (index));
798 }
ea900239
DB
799
800 fprintf (dump_file, "\n locals written: ");
40513dd3
JJ
801 if (w_l->statics_written)
802 EXECUTE_IF_SET_IN_BITMAP (w_l->statics_written,
803 0, index, bi)
804 {
805 fprintf (dump_file, "%s ",
806 get_static_name (index));
807 }
ea900239 808
c5274326 809 w_info = (struct ipa_dfs_info *) w->aux;
ea900239
DB
810 w = w_info->next_cycle;
811 }
812 fprintf (dump_file, "\n globals read: ");
8b583a06
JH
813 if (node_g->statics_read == all_module_statics)
814 fprintf (dump_file, "ALL");
815 else
816 EXECUTE_IF_SET_IN_BITMAP (node_g->statics_read,
817 0, index, bi)
818 {
819 fprintf (dump_file, "%s ",
820 get_static_name (index));
821 }
ea900239 822 fprintf (dump_file, "\n globals written: ");
8b583a06
JH
823 if (node_g->statics_written == all_module_statics)
824 fprintf (dump_file, "ALL");
825 else
826 EXECUTE_IF_SET_IN_BITMAP (node_g->statics_written,
827 0, index, bi)
828 {
829 fprintf (dump_file, "%s ",
830 get_static_name (index));
831 }
ea900239
DB
832 }
833 }
834
835 /* Cleanup. */
836 for (i = 0; i < order_pos; i++ )
837 {
838 ipa_reference_vars_info_t node_info;
839 ipa_reference_global_vars_info_t node_g;
46c30019
JH
840 ipa_reference_optimization_summary_t opt;
841
ea900239 842 node = order[i];
e2c9111c 843 node_info = get_reference_vars_info (node);
46c30019
JH
844 if (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE)
845 {
846 node_g = &node_info->global;
ea900239 847
46c30019
JH
848 opt = XCNEW (struct ipa_reference_optimization_summary_d);
849 set_reference_optimization_summary (node, opt);
ea900239 850
46c30019
JH
851 /* Create the complimentary sets. */
852 opt->statics_not_read = BITMAP_ALLOC (&optimization_summary_obstack);
853 opt->statics_not_written = BITMAP_ALLOC (&optimization_summary_obstack);
854
855 if (node_g->statics_read != all_module_statics)
856 bitmap_and_compl (opt->statics_not_read,
857 all_module_statics,
858 node_g->statics_read);
b8698a0f 859
46c30019
JH
860 if (node_g->statics_written
861 != all_module_statics)
862 bitmap_and_compl (opt->statics_not_written,
863 all_module_statics,
864 node_g->statics_written);
865 }
866 if (node_info)
867 free (node_info);
ea900239
DB
868 if (node->aux)
869 {
870 free (node->aux);
871 node->aux = NULL;
872 }
46c30019
JH
873 }
874
875 free (order);
b8698a0f 876
ebcf9dc8 877 bitmap_obstack_release (&local_info_obstack);
46c30019
JH
878 VEC_free (ipa_reference_vars_info_t, heap, ipa_reference_vars_vector);
879 ipa_reference_vars_vector = NULL;
880 if (dump_file)
881 splay_tree_delete (reference_vars_to_consider);
882 reference_vars_to_consider = NULL;
883 all_module_statics = NULL;
c2924966 884 return 0;
ea900239
DB
885}
886
887
888static bool
889gate_reference (void)
890{
7e8b322a 891 return (flag_ipa_reference
ea900239
DB
892 /* Don't bother doing anything if the program has errors. */
893 && !(errorcount || sorrycount));
894}
895
7e5487a2 896struct ipa_opt_pass_d pass_ipa_reference =
ea900239 897{
8ddbbcae 898 {
812dbce5 899 IPA_PASS,
ea900239
DB
900 "static-var", /* name */
901 gate_reference, /* gate */
812dbce5 902 propagate, /* execute */
ea900239
DB
903 NULL, /* sub */
904 NULL, /* next */
905 0, /* static_pass_number */
906 TV_IPA_REFERENCE, /* tv_id */
907 0, /* properties_required */
908 0, /* properties_provided */
909 0, /* properties_destroyed */
910 0, /* todo_flags_start */
8ddbbcae 911 0 /* todo_flags_finish */
812dbce5 912 },
5f902d76
JH
913 NULL, /* generate_summary */
914 NULL, /* write_summary */
915 NULL, /* read_summary */
e792884f
JH
916 NULL, /* write_optimization_summary */
917 NULL, /* read_optimization_summary */
2c5721d9 918 NULL, /* stmt_fixup */
812dbce5
JH
919 0, /* TODOs */
920 NULL, /* function_transform */
921 NULL /* variable_transform */
ea900239 922};