* lto-symtab.c (lto_symtab_entry_def) Add vnode.
[gcc.git] / gcc / ipa-reference.c
1 /* Callgraph based analysis of static variables.
2 Copyright (C) 2004, 2005, 2007, 2008, 2009, 2010
3 Free Software Foundation, Inc.
4 Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
21
22 /* This file gathers information about how variables whose scope is
23 confined to the compilation unit are used.
24
25 There are two categories of information produced by this pass:
26
27 1) The addressable (TREE_ADDRESSABLE) bit and readonly
28 (TREE_READONLY) bit associated with these variables is properly set
29 based on scanning all of the code withing the compilation unit.
30
31 2) The transitive call site specific clobber effects are computed
32 for the variables whose scope is contained within this compilation
33 unit.
34
35 First each function and static variable initialization is analyzed
36 to determine which local static variables are either read, written,
37 or have their address taken. Any local static that has its address
38 taken is removed from consideration. Once the local read and
39 writes are determined, a transitive closure of this information is
40 performed over the call graph to determine the worst case set of
41 side effects of each call. In later parts of the compiler, these
42 local and global sets are examined to make the call clobbering less
43 traumatic, promote some statics to registers, and improve aliasing
44 information.
45
46 Currently must be run after inlining decisions have been made since
47 otherwise, the local sets will not contain information that is
48 consistent with post inlined state. The global sets are not prone
49 to this problem since they are by definition transitive. */
50
51 #include "config.h"
52 #include "system.h"
53 #include "coretypes.h"
54 #include "tm.h"
55 #include "tree.h"
56 #include "tree-flow.h"
57 #include "tree-inline.h"
58 #include "tree-pass.h"
59 #include "langhooks.h"
60 #include "pointer-set.h"
61 #include "splay-tree.h"
62 #include "ggc.h"
63 #include "ipa-utils.h"
64 #include "ipa-reference.h"
65 #include "gimple.h"
66 #include "cgraph.h"
67 #include "output.h"
68 #include "flags.h"
69 #include "timevar.h"
70 #include "diagnostic.h"
71 #include "langhooks.h"
72 #include "lto-streamer.h"
73
74 static void add_new_function (struct cgraph_node *node,
75 void *data ATTRIBUTE_UNUSED);
76 static void remove_node_data (struct cgraph_node *node,
77 void *data ATTRIBUTE_UNUSED);
78 static void duplicate_node_data (struct cgraph_node *src,
79 struct cgraph_node *dst,
80 void *data ATTRIBUTE_UNUSED);
81
82 /* The static variables defined within the compilation unit that are
83 loaded or stored directly by function that owns this structure. */
84
85 struct ipa_reference_local_vars_info_d
86 {
87 bitmap statics_read;
88 bitmap statics_written;
89
90 /* Set when this function calls another function external to the
91 compilation unit or if the function has a asm clobber of memory.
92 In general, such calls are modeled as reading and writing all
93 variables (both bits on) but sometime there are attributes on the
94 called function so we can do better. */
95 bool calls_read_all;
96 bool calls_write_all;
97 };
98
99 /* Statics that are read and written by some set of functions. The
100 local ones are based on the loads and stores local to the function.
101 The global ones are based on the local info as well as the
102 transitive closure of the functions that are called. The
103 structures are separated to allow the global structures to be
104 shared between several functions since every function within a
105 strongly connected component will have the same information. This
106 sharing saves both time and space in the computation of the vectors
107 as well as their translation from decl_uid form to ann_uid
108 form. */
109
110 struct ipa_reference_global_vars_info_d
111 {
112 bitmap statics_read;
113 bitmap statics_written;
114 bitmap statics_not_read;
115 bitmap statics_not_written;
116 };
117
118 typedef struct ipa_reference_local_vars_info_d *ipa_reference_local_vars_info_t;
119 typedef struct ipa_reference_global_vars_info_d *ipa_reference_global_vars_info_t;
120 struct ipa_reference_vars_info_d
121 {
122 ipa_reference_local_vars_info_t local;
123 ipa_reference_global_vars_info_t global;
124 };
125
126 typedef struct ipa_reference_vars_info_d *ipa_reference_vars_info_t;
127
128 /* This splay tree contains all of the static variables that are
129 being considered by the compilation level alias analysis. For
130 module_at_a_time compilation, this is the set of static but not
131 public variables. Any variables that either have their address
132 taken or participate in otherwise unsavory operations are deleted
133 from this list. */
134 static GTY((param1_is(int), param2_is(tree)))
135 splay_tree reference_vars_to_consider;
136
137 /* This bitmap is used to knock out the module static variables whose
138 addresses have been taken and passed around. */
139 static bitmap module_statics_escape;
140
141 /* This bitmap is used to knock out the module static variables that
142 are not readonly. */
143 static bitmap module_statics_written;
144
145 /* A bit is set for every module static we are considering. This is
146 ored into the local info when asm code is found that clobbers all
147 memory. */
148 static bitmap all_module_statics;
149
150 static struct pointer_set_t *visited_nodes;
151
152 /* Obstack holding bitmaps of local analysis (live from analysis to
153 propagation) */
154 static bitmap_obstack local_info_obstack;
155 /* Obstack holding global analysis live forever. */
156 static bitmap_obstack global_info_obstack;
157
158 /* Holders of ipa cgraph hooks: */
159 static struct cgraph_node_hook_list *function_insertion_hook_holder;
160 static struct cgraph_2node_hook_list *node_duplication_hook_holder;
161 static struct cgraph_node_hook_list *node_removal_hook_holder;
162
163 enum initialization_status_t
164 {
165 UNINITIALIZED,
166 RUNNING,
167 FINISHED
168 };
169
170 tree memory_identifier_string;
171
172 /* Vector where the reference var infos are actually stored. */
173 DEF_VEC_P (ipa_reference_vars_info_t);
174 DEF_VEC_ALLOC_P (ipa_reference_vars_info_t, heap);
175 static VEC (ipa_reference_vars_info_t, heap) *ipa_reference_vars_vector;
176
177 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
178 static inline ipa_reference_vars_info_t
179 get_reference_vars_info (struct cgraph_node *node)
180 {
181 if (!ipa_reference_vars_vector
182 || VEC_length (ipa_reference_vars_info_t, ipa_reference_vars_vector) <= (unsigned int)node->uid)
183 return NULL;
184 return VEC_index (ipa_reference_vars_info_t, ipa_reference_vars_vector, node->uid);
185 }
186
187 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
188 static inline void
189 set_reference_vars_info (struct cgraph_node *node, ipa_reference_vars_info_t info)
190 {
191 if (!ipa_reference_vars_vector
192 || VEC_length (ipa_reference_vars_info_t, ipa_reference_vars_vector) <= (unsigned int)node->uid)
193 VEC_safe_grow_cleared (ipa_reference_vars_info_t, heap, ipa_reference_vars_vector, node->uid + 1);
194 VEC_replace (ipa_reference_vars_info_t, ipa_reference_vars_vector, node->uid, info);
195 }
196
197 /* Get a bitmap that contains all of the locally referenced static
198 variables for function FN. */
199 static ipa_reference_local_vars_info_t
200 get_local_reference_vars_info (struct cgraph_node *fn)
201 {
202 ipa_reference_vars_info_t info = get_reference_vars_info (fn);
203
204 if (info)
205 return info->local;
206 else
207 /* This phase was not run. */
208 return NULL;
209 }
210
211 /* Get a bitmap that contains all of the globally referenced static
212 variables for function FN. */
213
214 static ipa_reference_global_vars_info_t
215 get_global_reference_vars_info (struct cgraph_node *fn)
216 {
217 ipa_reference_vars_info_t info = get_reference_vars_info (fn);
218
219 if (info)
220 return info->global;
221 else
222 /* This phase was not run. */
223 return NULL;
224 }
225
226 /* Return a bitmap indexed by VAR_DECL uid for the static variables
227 that are read during the execution of the function FN. Returns
228 NULL if no data is available. */
229
230 bitmap
231 ipa_reference_get_read_global (struct cgraph_node *fn)
232 {
233 ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
234 if (g)
235 return g->statics_read;
236 else
237 return NULL;
238 }
239
240 /* Return a bitmap indexed by VAR_DECL uid for the static variables
241 that are written during the execution of the function FN. Note
242 that variables written may or may not be read during the function
243 call. Returns NULL if no data is available. */
244
245 bitmap
246 ipa_reference_get_written_global (struct cgraph_node *fn)
247 {
248 ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
249 if (g)
250 return g->statics_written;
251 else
252 return NULL;
253 }
254
255 /* Return a bitmap indexed by_DECL_UID uid for the static variables
256 that are not read during the execution of the function FN. Returns
257 NULL if no data is available. */
258
259 bitmap
260 ipa_reference_get_not_read_global (struct cgraph_node *fn)
261 {
262 ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
263 if (g)
264 return g->statics_not_read;
265 else
266 return NULL;
267 }
268
269 /* Return a bitmap indexed by DECL_UID uid for the static variables
270 that are not written during the execution of the function FN. Note
271 that variables written may or may not be read during the function
272 call. Returns NULL if no data is available. */
273
274 bitmap
275 ipa_reference_get_not_written_global (struct cgraph_node *fn)
276 {
277 ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
278 if (g)
279 return g->statics_not_written;
280 else
281 return NULL;
282 }
283
284 \f
285
286 /* Add VAR to all_module_statics and the two
287 reference_vars_to_consider* sets. */
288
289 static inline void
290 add_static_var (tree var)
291 {
292 int uid = DECL_UID (var);
293 gcc_assert (TREE_CODE (var) == VAR_DECL);
294 if (!bitmap_bit_p (all_module_statics, uid))
295 {
296 splay_tree_insert (reference_vars_to_consider,
297 uid, (splay_tree_value)var);
298 bitmap_set_bit (all_module_statics, uid);
299 }
300 }
301
302 /* Return true if the variable T is the right kind of static variable to
303 perform compilation unit scope escape analysis. */
304
305 static inline bool
306 has_proper_scope_for_analysis (tree t)
307 {
308 /* If the variable has the "used" attribute, treat it as if it had a
309 been touched by the devil. */
310 if (DECL_PRESERVE_P (t))
311 return false;
312
313 /* Do not want to do anything with volatile except mark any
314 function that uses one to be not const or pure. */
315 if (TREE_THIS_VOLATILE (t))
316 return false;
317
318 /* Do not care about a local automatic that is not static. */
319 if (!TREE_STATIC (t) && !DECL_EXTERNAL (t))
320 return false;
321
322 /* FIXME: for LTO we should include PUBLIC vars too. This is bit difficult
323 as summarie would need unsharing. */
324 if (DECL_EXTERNAL (t) || TREE_PUBLIC (t))
325 return false;
326
327 /* We cannot touch decls where the type needs constructing. */
328 if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (t)))
329 return false;
330
331 /* This is a variable we care about. Check if we have seen it
332 before, and if not add it the set of variables we care about. */
333 if (!bitmap_bit_p (all_module_statics, DECL_UID (t)))
334 add_static_var (t);
335
336 return true;
337 }
338
339 /* Mark tree T as having address taken. */
340
341 static void
342 mark_address_taken (tree x)
343 {
344 if (TREE_CODE (x) == VAR_DECL
345 && module_statics_escape && has_proper_scope_for_analysis (x))
346 bitmap_set_bit (module_statics_escape, DECL_UID (x));
347 }
348
349 /* Wrapper around mark_address_taken for the stmt walker. */
350
351 static bool
352 mark_address (gimple stmt ATTRIBUTE_UNUSED, tree addr,
353 void *data ATTRIBUTE_UNUSED)
354 {
355 addr = get_base_address (addr);
356 if (addr)
357 mark_address_taken (addr);
358 return false;
359 }
360
361 /* Mark load of T. */
362
363 static bool
364 mark_load (gimple stmt ATTRIBUTE_UNUSED, tree t, void *data)
365 {
366 ipa_reference_local_vars_info_t local = (ipa_reference_local_vars_info_t)data;
367 t = get_base_address (t);
368 if (t && TREE_CODE (t) == VAR_DECL
369 && has_proper_scope_for_analysis (t))
370 bitmap_set_bit (local->statics_read, DECL_UID (t));
371 return false;
372 }
373
374 /* Mark store of T. */
375
376 static bool
377 mark_store (gimple stmt ATTRIBUTE_UNUSED, tree t, void *data)
378 {
379 ipa_reference_local_vars_info_t local = (ipa_reference_local_vars_info_t)data;
380 t = get_base_address (t);
381 if (t && TREE_CODE (t) == VAR_DECL
382 && has_proper_scope_for_analysis (t))
383 {
384 if (local)
385 bitmap_set_bit (local->statics_written, DECL_UID (t));
386 /* Mark the write so we can tell which statics are
387 readonly. */
388 if (module_statics_written)
389 bitmap_set_bit (module_statics_written, DECL_UID (t));
390 }
391 return false;
392 }
393
394 /* Look for memory clobber and set read_all/write_all if present. */
395
396 static void
397 check_asm_memory_clobber (ipa_reference_local_vars_info_t local, gimple stmt)
398 {
399 size_t i;
400 tree op;
401
402 for (i = 0; i < gimple_asm_nclobbers (stmt); i++)
403 {
404 op = gimple_asm_clobber_op (stmt, i);
405 if (simple_cst_equal(TREE_VALUE (op), memory_identifier_string) == 1)
406 {
407 /* Abandon all hope, ye who enter here. */
408 local->calls_read_all = true;
409 local->calls_write_all = true;
410 }
411 }
412 }
413
414 /* Look for external calls and set read_all/write_all correspondingly. */
415
416 static void
417 check_call (ipa_reference_local_vars_info_t local, gimple stmt)
418 {
419 int flags = gimple_call_flags (stmt);
420 tree callee_t = gimple_call_fndecl (stmt);
421
422 /* Process indirect calls. All direct calles are handled at propagation
423 time. */
424 if (!callee_t)
425 {
426 if (flags & ECF_CONST)
427 ;
428 else if (flags & ECF_PURE)
429 local->calls_read_all = true;
430 else
431 {
432 local->calls_read_all = true;
433 /* When function does not reutrn, it is safe to ignore anythign it writes
434 to, because the effect will never happen. */
435 if ((flags & (ECF_NOTHROW | ECF_NORETURN))
436 != (ECF_NOTHROW | ECF_NORETURN))
437 local->calls_write_all = true;
438 }
439 }
440 }
441
442 /* TP is the part of the tree currently under the microscope.
443 WALK_SUBTREES is part of the walk_tree api but is unused here.
444 DATA is cgraph_node of the function being walked. */
445
446 static tree
447 scan_stmt_for_static_refs (gimple_stmt_iterator *gsip,
448 struct cgraph_node *fn)
449 {
450 gimple stmt = gsi_stmt (*gsip);
451 ipa_reference_local_vars_info_t local = NULL;
452
453 if (is_gimple_debug (stmt))
454 return NULL;
455
456 if (fn)
457 local = get_reference_vars_info (fn)->local;
458
459 /* Look for direct loads and stores. */
460 walk_stmt_load_store_addr_ops (stmt, local, mark_load, mark_store,
461 mark_address);
462
463 if (is_gimple_call (stmt))
464 check_call (local, stmt);
465 else if (gimple_code (stmt) == GIMPLE_ASM)
466 check_asm_memory_clobber (local, stmt);
467
468 return NULL;
469 }
470
471 /* Call-back to scan variable initializers for static references.
472 Called using walk_tree. */
473
474 static tree
475 scan_initializer_for_static_refs (tree *tp, int *walk_subtrees,
476 void *data ATTRIBUTE_UNUSED)
477 {
478 tree t = *tp;
479
480 if (TREE_CODE (t) == ADDR_EXPR)
481 {
482 mark_address_taken (get_base_var (t));
483 *walk_subtrees = 0;
484 }
485 /* Save some cycles by not walking types and declaration as we
486 won't find anything useful there anyway. */
487 else if (IS_TYPE_OR_DECL_P (*tp))
488 *walk_subtrees = 0;
489
490 return NULL;
491 }
492
493 /* Lookup the tree node for the static variable that has UID. */
494 static tree
495 get_static_decl (int index)
496 {
497 splay_tree_node stn =
498 splay_tree_lookup (reference_vars_to_consider, index);
499 if (stn)
500 return (tree)stn->value;
501 return NULL;
502 }
503
504 /* Lookup the tree node for the static variable that has UID and
505 convert the name to a string for debugging. */
506
507 static const char *
508 get_static_name (int index)
509 {
510 splay_tree_node stn =
511 splay_tree_lookup (reference_vars_to_consider, index);
512 if (stn)
513 return lang_hooks.decl_printable_name ((tree)(stn->value), 2);
514 return NULL;
515 }
516
517 /* Or in all of the bits from every callee of X into X_GLOBAL, the caller's cycle,
518 bit vector. There are several cases to check to avoid the sparse
519 bitmap oring. */
520
521 static void
522 propagate_bits (ipa_reference_global_vars_info_t x_global, struct cgraph_node *x)
523 {
524 struct cgraph_edge *e;
525 for (e = x->callees; e; e = e->next_callee)
526 {
527 struct cgraph_node *y = e->callee;
528
529 /* Only look into nodes we can propagate something. */
530 if (cgraph_function_body_availability (e->callee) > AVAIL_OVERWRITABLE)
531 {
532 if (get_reference_vars_info (y))
533 {
534 ipa_reference_vars_info_t y_info
535 = get_reference_vars_info (y);
536 ipa_reference_global_vars_info_t y_global = y_info->global;
537
538 /* Calls in current cycle do not have global computed yet. */
539 if (!y_info->global)
540 continue;
541
542 if (x_global->statics_read
543 != all_module_statics)
544 {
545 if (y_global->statics_read
546 == all_module_statics)
547 {
548 BITMAP_FREE (x_global->statics_read);
549 x_global->statics_read
550 = all_module_statics;
551 }
552 /* Skip bitmaps that are pointer equal to node's bitmap
553 (no reason to spin within the cycle). */
554 else if (x_global->statics_read
555 != y_global->statics_read)
556 bitmap_ior_into (x_global->statics_read,
557 y_global->statics_read);
558 }
559
560 if (x_global->statics_written
561 != all_module_statics)
562 {
563 if (y_global->statics_written
564 == all_module_statics)
565 {
566 BITMAP_FREE (x_global->statics_written);
567 x_global->statics_written
568 = all_module_statics;
569 }
570 /* Skip bitmaps that are pointer equal to node's bitmap
571 (no reason to spin within the cycle). */
572 else if (x_global->statics_written
573 != y_global->statics_written)
574 bitmap_ior_into (x_global->statics_written,
575 y_global->statics_written);
576 }
577 }
578 else
579 gcc_unreachable ();
580 }
581 }
582 }
583
584 /* The init routine for analyzing global static variable usage. See
585 comments at top for description. */
586 static void
587 ipa_init (void)
588 {
589 static bool init_p = false;
590
591 if (init_p)
592 return;
593
594 init_p = true;
595
596 memory_identifier_string = build_string(7, "memory");
597
598 reference_vars_to_consider =
599 splay_tree_new_ggc (splay_tree_compare_ints);
600
601 bitmap_obstack_initialize (&local_info_obstack);
602 bitmap_obstack_initialize (&global_info_obstack);
603 module_statics_escape = BITMAP_ALLOC (&local_info_obstack);
604 module_statics_written = BITMAP_ALLOC (&local_info_obstack);
605 all_module_statics = BITMAP_ALLOC (&global_info_obstack);
606
607 /* There are some shared nodes, in particular the initializers on
608 static declarations. We do not need to scan them more than once
609 since all we would be interested in are the addressof
610 operations. */
611 visited_nodes = pointer_set_create ();
612
613 function_insertion_hook_holder =
614 cgraph_add_function_insertion_hook (&add_new_function, NULL);
615 node_removal_hook_holder =
616 cgraph_add_node_removal_hook (&remove_node_data, NULL);
617 node_duplication_hook_holder =
618 cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
619 }
620
621 /* Check out the rhs of a static or global initialization VNODE to see
622 if any of them contain addressof operations. Note that some of
623 these variables may not even be referenced in the code in this
624 compilation unit but their right hand sides may contain references
625 to variables defined within this unit. */
626
627 static void
628 analyze_variable (struct varpool_node *vnode)
629 {
630 struct walk_stmt_info wi;
631 tree global = vnode->decl;
632
633 memset (&wi, 0, sizeof (wi));
634 wi.pset = visited_nodes;
635 walk_tree (&DECL_INITIAL (global), scan_initializer_for_static_refs,
636 &wi, wi.pset);
637 }
638
639
640 /* Set up the persistent info for FN. */
641
642 static ipa_reference_local_vars_info_t
643 init_function_info (struct cgraph_node *fn)
644 {
645 ipa_reference_vars_info_t info
646 = XCNEW (struct ipa_reference_vars_info_d);
647 ipa_reference_local_vars_info_t l
648 = XCNEW (struct ipa_reference_local_vars_info_d);
649
650 /* Add the info to the tree's annotation. */
651 set_reference_vars_info (fn, info);
652
653 info->local = l;
654 l->statics_read = BITMAP_ALLOC (&local_info_obstack);
655 l->statics_written = BITMAP_ALLOC (&local_info_obstack);
656
657 return l;
658 }
659
660
661 /* This is the main routine for finding the reference patterns for
662 global variables within a function FN. */
663
664 static void
665 analyze_function (struct cgraph_node *fn)
666 {
667 tree decl = fn->decl;
668 struct function *this_cfun = DECL_STRUCT_FUNCTION (decl);
669 basic_block this_block;
670 #ifdef ENABLE_CHECKING
671 tree step;
672 #endif
673 ipa_reference_local_vars_info_t local;
674
675 if (dump_file)
676 fprintf (dump_file, "\n local analysis of %s\n", cgraph_node_name (fn));
677
678 push_cfun (DECL_STRUCT_FUNCTION (decl));
679 current_function_decl = decl;
680
681 init_function_info (fn);
682 FOR_EACH_BB_FN (this_block, this_cfun)
683 {
684 gimple_stmt_iterator gsi;
685 gimple phi;
686 tree op;
687 use_operand_p use;
688 ssa_op_iter iter;
689
690 /* Find the addresses taken in phi node arguments. */
691 for (gsi = gsi_start_phis (this_block);
692 !gsi_end_p (gsi);
693 gsi_next (&gsi))
694 {
695 phi = gsi_stmt (gsi);
696 FOR_EACH_PHI_ARG (use, phi, iter, SSA_OP_USE)
697 {
698 op = USE_FROM_PTR (use);
699 if (TREE_CODE (op) == ADDR_EXPR)
700 mark_address_taken (get_base_var (op));
701 }
702 }
703
704 for (gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi))
705 scan_stmt_for_static_refs (&gsi, fn);
706 }
707
708 local = get_reference_vars_info (fn)->local;
709 if ((flags_from_decl_or_type (decl) & (ECF_NOTHROW | ECF_NORETURN))
710 == (ECF_NOTHROW | ECF_NORETURN))
711 {
712 local->calls_write_all = false;
713 bitmap_clear (local->statics_written);
714 }
715
716 /* Free bitmaps of direct references if we can not use them anyway. */
717 if (local->calls_write_all)
718 BITMAP_FREE (local->statics_written);
719 if (local->calls_read_all)
720 BITMAP_FREE (local->statics_read);
721
722
723 #ifdef ENABLE_CHECKING
724 /* Verify that all local initializers was expanded by gimplifier. */
725 for (step = DECL_STRUCT_FUNCTION (decl)->local_decls;
726 step;
727 step = TREE_CHAIN (step))
728 {
729 tree var = TREE_VALUE (step);
730 if (TREE_CODE (var) == VAR_DECL
731 && DECL_INITIAL (var)
732 && !TREE_STATIC (var))
733 gcc_unreachable ();
734 }
735 #endif
736 pop_cfun ();
737 current_function_decl = NULL;
738 }
739
740 /* Remove local data associated with function FN. */
741 static void
742 clean_function_local_data (struct cgraph_node *fn)
743 {
744 ipa_reference_vars_info_t info = get_reference_vars_info (fn);
745 ipa_reference_local_vars_info_t l = info->local;
746 if (l)
747 {
748 if (l->statics_read
749 && l->statics_read != all_module_statics)
750 BITMAP_FREE (l->statics_read);
751 if (l->statics_written
752 &&l->statics_written != all_module_statics)
753 BITMAP_FREE (l->statics_written);
754 free (l);
755 info->local = NULL;
756 }
757 }
758
759 /* Remove all data associated with function FN. */
760
761 static void
762 clean_function (struct cgraph_node *fn)
763 {
764 ipa_reference_vars_info_t info = get_reference_vars_info (fn);
765 ipa_reference_global_vars_info_t g = info->global;
766
767 clean_function_local_data (fn);
768 if (g)
769 {
770 if (g->statics_read
771 && g->statics_read != all_module_statics)
772 BITMAP_FREE (g->statics_read);
773
774 if (g->statics_written
775 && g->statics_written != all_module_statics)
776 BITMAP_FREE (g->statics_written);
777
778 if (g->statics_not_read
779 && g->statics_not_read != all_module_statics)
780 BITMAP_FREE (g->statics_not_read);
781
782 if (g->statics_not_written
783 && g->statics_not_written != all_module_statics)
784 BITMAP_FREE (g->statics_not_written);
785 free (g);
786 info->global = NULL;
787 }
788
789 free (get_reference_vars_info (fn));
790 set_reference_vars_info (fn, NULL);
791 }
792
793 /* Called when new function is inserted to callgraph late. */
794 static void
795 add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
796 {
797 /* There are some shared nodes, in particular the initializers on
798 static declarations. We do not need to scan them more than once
799 since all we would be interested in are the addressof
800 operations. */
801 analyze_function (node);
802 visited_nodes = NULL;
803 }
804
805 static bitmap
806 copy_local_bitmap (bitmap src)
807 {
808 bitmap dst;
809 if (!src)
810 return NULL;
811 if (src == all_module_statics)
812 return all_module_statics;
813 dst = BITMAP_ALLOC (&local_info_obstack);
814 bitmap_copy (dst, src);
815 return dst;
816 }
817
818 static bitmap
819 copy_global_bitmap (bitmap src)
820 {
821 bitmap dst;
822 if (!src)
823 return NULL;
824 if (src == all_module_statics)
825 return all_module_statics;
826 dst = BITMAP_ALLOC (&global_info_obstack);
827 bitmap_copy (dst, src);
828 return dst;
829 }
830
831 /* Called when new clone is inserted to callgraph late. */
832
833 static void
834 duplicate_node_data (struct cgraph_node *src, struct cgraph_node *dst,
835 void *data ATTRIBUTE_UNUSED)
836 {
837 ipa_reference_global_vars_info_t ginfo;
838 ipa_reference_local_vars_info_t linfo;
839 ipa_reference_global_vars_info_t dst_ginfo;
840 ipa_reference_local_vars_info_t dst_linfo;
841
842 ginfo = get_global_reference_vars_info (src);
843 linfo = get_local_reference_vars_info (src);
844 if (!linfo && !ginfo)
845 return;
846 init_function_info (dst);
847 if (linfo)
848 {
849 dst_linfo = get_local_reference_vars_info (dst);
850 dst_linfo->statics_read = copy_local_bitmap (linfo->statics_read);
851 dst_linfo->statics_written = copy_local_bitmap (linfo->statics_written);
852 dst_linfo->calls_read_all = linfo->calls_read_all;
853 dst_linfo->calls_write_all = linfo->calls_write_all;
854 }
855 if (ginfo)
856 {
857 get_reference_vars_info (dst)->global = XCNEW (struct ipa_reference_global_vars_info_d);
858 dst_ginfo = get_global_reference_vars_info (dst);
859 dst_ginfo->statics_read = copy_global_bitmap (ginfo->statics_read);
860 dst_ginfo->statics_written = copy_global_bitmap (ginfo->statics_written);
861 dst_ginfo->statics_not_read = copy_global_bitmap (ginfo->statics_not_read);
862 dst_ginfo->statics_not_written = copy_global_bitmap (ginfo->statics_not_written);
863 }
864 }
865
866 /* Called when node is removed. */
867
868 static void
869 remove_node_data (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
870 {
871 if (get_reference_vars_info (node))
872 clean_function (node);
873 }
874
875 /* Analyze each function in the cgraph to see which global or statics
876 are read or written. */
877
878 static void
879 generate_summary (void)
880 {
881 struct cgraph_node *node;
882 struct varpool_node *vnode;
883 unsigned int index;
884 bitmap_iterator bi;
885 bitmap module_statics_readonly;
886 bitmap bm_temp;
887
888 ipa_init ();
889 module_statics_readonly = BITMAP_ALLOC (&local_info_obstack);
890 bm_temp = BITMAP_ALLOC (&local_info_obstack);
891
892 /* Process all of the variables first. */
893 FOR_EACH_STATIC_INITIALIZER (vnode)
894 analyze_variable (vnode);
895
896 /* Process all of the functions next.
897
898 We do not want to process any of the clones so we check that this
899 is a master clone. However, we do need to process any
900 AVAIL_OVERWRITABLE functions (these are never clones) because
901 they may cause a static variable to escape. The code that can
902 overwrite such a function cannot access the statics because it
903 would not be in the same compilation unit. When the analysis is
904 finished, the computed information of these AVAIL_OVERWRITABLE is
905 replaced with worst case info.
906 */
907 for (node = cgraph_nodes; node; node = node->next)
908 if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
909 analyze_function (node);
910
911 pointer_set_destroy (visited_nodes);
912 visited_nodes = NULL;
913
914 /* Prune out the variables that were found to behave badly
915 (i.e. have their address taken). */
916 EXECUTE_IF_SET_IN_BITMAP (module_statics_escape, 0, index, bi)
917 {
918 splay_tree_remove (reference_vars_to_consider, index);
919 }
920
921 bitmap_and_compl_into (all_module_statics,
922 module_statics_escape);
923
924 bitmap_and_compl (module_statics_readonly, all_module_statics,
925 module_statics_written);
926
927 /* If the address is not taken, we can unset the addressable bit
928 on this variable. */
929 EXECUTE_IF_SET_IN_BITMAP (all_module_statics, 0, index, bi)
930 {
931 tree var = get_static_decl (index);
932 TREE_ADDRESSABLE (var) = 0;
933 if (dump_file)
934 fprintf (dump_file, "Not TREE_ADDRESSABLE var %s\n",
935 get_static_name (index));
936 }
937
938 /* If the variable is never written, we can set the TREE_READONLY
939 flag. Additionally if it has a DECL_INITIAL that is made up of
940 constants we can treat the entire global as a constant. */
941
942 bitmap_and_compl (module_statics_readonly, all_module_statics,
943 module_statics_written);
944 EXECUTE_IF_SET_IN_BITMAP (module_statics_readonly, 0, index, bi)
945 {
946 tree var = get_static_decl (index);
947
948 /* Ignore variables in named sections - changing TREE_READONLY
949 changes the section flags, potentially causing conflicts with
950 other variables in the same named section. */
951 if (DECL_SECTION_NAME (var) == NULL_TREE)
952 {
953 TREE_READONLY (var) = 1;
954 if (dump_file)
955 fprintf (dump_file, "read-only var %s\n",
956 get_static_name (index));
957 }
958 }
959
960 BITMAP_FREE(module_statics_escape);
961 BITMAP_FREE(module_statics_written);
962 module_statics_escape = NULL;
963 module_statics_written = NULL;
964
965 if (dump_file)
966 EXECUTE_IF_SET_IN_BITMAP (all_module_statics, 0, index, bi)
967 {
968 fprintf (dump_file, "\nPromotable global:%s",
969 get_static_name (index));
970 }
971
972 for (node = cgraph_nodes; node; node = node->next)
973 if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
974 {
975 ipa_reference_local_vars_info_t l;
976 l = get_reference_vars_info (node)->local;
977
978 /* Any variables that are not in all_module_statics are
979 removed from the local maps. This will include all of the
980 variables that were found to escape in the function
981 scanning. */
982 if (l->statics_read)
983 bitmap_and_into (l->statics_read,
984 all_module_statics);
985 if (l->statics_written)
986 bitmap_and_into (l->statics_written,
987 all_module_statics);
988 }
989
990 BITMAP_FREE(module_statics_readonly);
991 BITMAP_FREE(bm_temp);
992
993 if (dump_file)
994 for (node = cgraph_nodes; node; node = node->next)
995 if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
996 {
997 ipa_reference_local_vars_info_t l;
998 unsigned int index;
999 bitmap_iterator bi;
1000
1001 l = get_reference_vars_info (node)->local;
1002 fprintf (dump_file,
1003 "\nFunction name:%s/%i:",
1004 cgraph_node_name (node), node->uid);
1005 fprintf (dump_file, "\n locals read: ");
1006 if (l->statics_read)
1007 EXECUTE_IF_SET_IN_BITMAP (l->statics_read,
1008 0, index, bi)
1009 {
1010 fprintf (dump_file, "%s ",
1011 get_static_name (index));
1012 }
1013 fprintf (dump_file, "\n locals written: ");
1014 if (l->statics_written)
1015 EXECUTE_IF_SET_IN_BITMAP (l->statics_written,
1016 0, index, bi)
1017 {
1018 fprintf(dump_file, "%s ",
1019 get_static_name (index));
1020 }
1021 if (l->calls_read_all)
1022 fprintf (dump_file, "\n calls read all: ");
1023 if (l->calls_write_all)
1024 fprintf (dump_file, "\n calls read all: ");
1025 }
1026 }
1027
1028
1029 /* Return true if we need to write summary of NODE. */
1030
1031 static bool
1032 write_node_summary_p (struct cgraph_node *node)
1033 {
1034 gcc_assert (node->global.inlined_to == NULL);
1035 return (node->analyzed
1036 && cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE
1037 && get_reference_vars_info (node) != NULL);
1038 }
1039
1040 /* Serialize the ipa info for lto. */
1041
1042 static void
1043 ipa_reference_write_summary (cgraph_node_set set,
1044 varpool_node_set vset ATTRIBUTE_UNUSED)
1045 {
1046 struct cgraph_node *node;
1047 struct lto_simple_output_block *ob
1048 = lto_create_simple_output_block (LTO_section_ipa_reference);
1049 unsigned int count = 0;
1050 cgraph_node_set_iterator csi;
1051
1052 for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
1053 if (write_node_summary_p (csi_node (csi)))
1054 count++;
1055
1056 lto_output_uleb128_stream (ob->main_stream, count);
1057
1058 /* Process all of the functions. */
1059 for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
1060 {
1061 node = csi_node (csi);
1062 if (write_node_summary_p (node))
1063 {
1064 ipa_reference_local_vars_info_t l
1065 = get_reference_vars_info (node)->local;
1066 unsigned int index;
1067 bitmap_iterator bi;
1068 lto_cgraph_encoder_t encoder;
1069 int node_ref;
1070
1071 encoder = ob->decl_state->cgraph_node_encoder;
1072 node_ref = lto_cgraph_encoder_encode (encoder, node);
1073 lto_output_uleb128_stream (ob->main_stream, node_ref);
1074
1075 /* Stream out the statics read. */
1076 if (l->calls_read_all)
1077 lto_output_sleb128_stream (ob->main_stream, -1);
1078 else
1079 {
1080 lto_output_sleb128_stream (ob->main_stream,
1081 bitmap_count_bits (l->statics_read));
1082 EXECUTE_IF_SET_IN_BITMAP (l->statics_read, 0, index, bi)
1083 lto_output_var_decl_index(ob->decl_state, ob->main_stream,
1084 get_static_decl (index));
1085 }
1086
1087 /* Stream out the statics written. */
1088 if (l->calls_write_all)
1089 lto_output_sleb128_stream (ob->main_stream, -1);
1090 else
1091 {
1092 lto_output_sleb128_stream (ob->main_stream,
1093 bitmap_count_bits (l->statics_written));
1094 EXECUTE_IF_SET_IN_BITMAP (l->statics_written, 0, index, bi)
1095 lto_output_var_decl_index(ob->decl_state, ob->main_stream,
1096 get_static_decl (index));
1097 }
1098 }
1099 }
1100 lto_destroy_simple_output_block (ob);
1101 }
1102
1103
1104 /* Deserialize the ipa info for lto. */
1105
1106 static void
1107 ipa_reference_read_summary (void)
1108 {
1109 struct lto_file_decl_data ** file_data_vec
1110 = lto_get_file_decl_data ();
1111 struct lto_file_decl_data * file_data;
1112 unsigned int j = 0;
1113
1114 ipa_init ();
1115
1116 while ((file_data = file_data_vec[j++]))
1117 {
1118 const char *data;
1119 size_t len;
1120 struct lto_input_block *ib
1121 = lto_create_simple_input_block (file_data,
1122 LTO_section_ipa_reference,
1123 &data, &len);
1124 if (ib)
1125 {
1126 unsigned int i;
1127 unsigned int f_count = lto_input_uleb128 (ib);
1128
1129 for (i = 0; i < f_count; i++)
1130 {
1131 unsigned int j, index;
1132 struct cgraph_node *node;
1133 ipa_reference_local_vars_info_t l;
1134 int v_count;
1135 lto_cgraph_encoder_t encoder;
1136
1137 index = lto_input_uleb128 (ib);
1138 encoder = file_data->cgraph_node_encoder;
1139 node = lto_cgraph_encoder_deref (encoder, index);
1140 l = init_function_info (node);
1141
1142 /* Set the statics read. */
1143 v_count = lto_input_sleb128 (ib);
1144 if (v_count == -1)
1145 l->calls_read_all = true;
1146 else
1147 for (j = 0; j < (unsigned int)v_count; j++)
1148 {
1149 unsigned int var_index = lto_input_uleb128 (ib);
1150 tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1151 var_index);
1152 add_static_var (v_decl);
1153 bitmap_set_bit (l->statics_read, DECL_UID (v_decl));
1154 }
1155
1156 /* Set the statics written. */
1157 v_count = lto_input_sleb128 (ib);
1158 if (v_count == -1)
1159 l->calls_write_all = true;
1160 else
1161 for (j = 0; j < (unsigned int)v_count; j++)
1162 {
1163 unsigned int var_index = lto_input_uleb128 (ib);
1164 tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1165 var_index);
1166 add_static_var (v_decl);
1167 bitmap_set_bit (l->statics_written, DECL_UID (v_decl));
1168 }
1169 }
1170
1171 lto_destroy_simple_input_block (file_data,
1172 LTO_section_ipa_reference,
1173 ib, data, len);
1174 }
1175 }
1176 }
1177
1178
1179 \f
1180 /* Set READ_ALL/WRITE_ALL based on DECL flags. */
1181 static void
1182 read_write_all_from_decl (tree decl, bool * read_all, bool * write_all)
1183 {
1184 int flags = flags_from_decl_or_type (decl);
1185 if (flags & ECF_CONST)
1186 ;
1187 else if (flags & ECF_PURE)
1188 *read_all = true;
1189 else
1190 {
1191 /* TODO: To be able to produce sane results, we should also handle
1192 common builtins, in particular throw.
1193 Indirect calls hsould be only counted and as inliner is replacing them
1194 by direct calls, we can conclude if any indirect calls are left in body */
1195 *read_all = true;
1196 /* When function does not reutrn, it is safe to ignore anythign it writes
1197 to, because the effect will never happen. */
1198 if ((flags & (ECF_NOTHROW | ECF_NORETURN))
1199 != (ECF_NOTHROW | ECF_NORETURN))
1200 *write_all = true;
1201 }
1202 }
1203
1204 /* Produce the global information by preforming a transitive closure
1205 on the local information that was produced by ipa_analyze_function
1206 and ipa_analyze_variable. */
1207
1208 static unsigned int
1209 propagate (void)
1210 {
1211 struct cgraph_node *node;
1212 struct cgraph_node *w;
1213 struct cgraph_node **order =
1214 XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
1215 int order_pos = ipa_utils_reduced_inorder (order, false, true, NULL);
1216 int i;
1217
1218 cgraph_remove_function_insertion_hook (function_insertion_hook_holder);
1219 if (dump_file)
1220 dump_cgraph (dump_file);
1221
1222 /* Propagate the local information thru the call graph to produce
1223 the global information. All the nodes within a cycle will have
1224 the same info so we collapse cycles first. Then we can do the
1225 propagation in one pass from the leaves to the roots. */
1226 order_pos = ipa_utils_reduced_inorder (order, true, true, NULL);
1227 if (dump_file)
1228 ipa_utils_print_order(dump_file, "reduced", order, order_pos);
1229
1230 for (i = 0; i < order_pos; i++ )
1231 {
1232 ipa_reference_vars_info_t node_info;
1233 ipa_reference_global_vars_info_t node_g =
1234 XCNEW (struct ipa_reference_global_vars_info_d);
1235 ipa_reference_local_vars_info_t node_l;
1236 struct cgraph_edge *e;
1237
1238 bool read_all;
1239 bool write_all;
1240 struct ipa_dfs_info * w_info;
1241
1242 node = order[i];
1243 node_info = get_reference_vars_info (node);
1244 if (!node_info)
1245 {
1246 dump_cgraph_node (stderr, node);
1247 dump_cgraph (stderr);
1248 gcc_unreachable ();
1249 }
1250
1251 gcc_assert (!node_info->global);
1252 node_l = node_info->local;
1253
1254 read_all = node_l->calls_read_all;
1255 write_all = node_l->calls_write_all;
1256
1257 /* When function is overwrittable, we can not assume anything. */
1258 if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
1259 read_write_all_from_decl (node->decl, &read_all, &write_all);
1260
1261 for (e = node->callees; e; e = e->next_callee)
1262 if (cgraph_function_body_availability (e->callee) <= AVAIL_OVERWRITABLE)
1263 read_write_all_from_decl (e->callee->decl, &read_all, &write_all);
1264
1265
1266 /* If any node in a cycle is calls_read_all or calls_write_all
1267 they all are. */
1268 w_info = (struct ipa_dfs_info *) node->aux;
1269 w = w_info->next_cycle;
1270 while (w)
1271 {
1272 ipa_reference_local_vars_info_t w_l =
1273 get_reference_vars_info (w)->local;
1274
1275 /* When function is overwrittable, we can not assume anything. */
1276 if (cgraph_function_body_availability (w) <= AVAIL_OVERWRITABLE)
1277 read_write_all_from_decl (w->decl, &read_all, &write_all);
1278
1279 for (e = w->callees; e; e = e->next_callee)
1280 if (cgraph_function_body_availability (e->callee) <= AVAIL_OVERWRITABLE)
1281 read_write_all_from_decl (e->callee->decl, &read_all, &write_all);
1282
1283 read_all |= w_l->calls_read_all;
1284 write_all |= w_l->calls_write_all;
1285
1286 w_info = (struct ipa_dfs_info *) w->aux;
1287 w = w_info->next_cycle;
1288 }
1289
1290
1291 /* Initialized the bitmaps for the reduced nodes */
1292 if (read_all)
1293 node_g->statics_read = all_module_statics;
1294 else
1295 {
1296 node_g->statics_read = BITMAP_ALLOC (&global_info_obstack);
1297 bitmap_copy (node_g->statics_read,
1298 node_l->statics_read);
1299 }
1300 if (write_all)
1301 node_g->statics_written = all_module_statics;
1302 else
1303 {
1304 node_g->statics_written = BITMAP_ALLOC (&global_info_obstack);
1305 bitmap_copy (node_g->statics_written,
1306 node_l->statics_written);
1307 }
1308
1309 propagate_bits (node_g, node);
1310 w_info = (struct ipa_dfs_info *) node->aux;
1311 w = w_info->next_cycle;
1312 while (w)
1313 {
1314 ipa_reference_vars_info_t w_ri =
1315 get_reference_vars_info (w);
1316 ipa_reference_local_vars_info_t w_l = w_ri->local;
1317
1318 /* These global bitmaps are initialized from the local info
1319 of all of the nodes in the region. However there is no
1320 need to do any work if the bitmaps were set to
1321 all_module_statics. */
1322 if (!read_all)
1323 bitmap_ior_into (node_g->statics_read,
1324 w_l->statics_read);
1325 if (!write_all)
1326 bitmap_ior_into (node_g->statics_written,
1327 w_l->statics_written);
1328 propagate_bits (node_g, w);
1329 w_info = (struct ipa_dfs_info *) w->aux;
1330 w = w_info->next_cycle;
1331 }
1332
1333 /* All nodes within a cycle have the same global info bitmaps. */
1334 node_info->global = node_g;
1335 w_info = (struct ipa_dfs_info *) node->aux;
1336 w = w_info->next_cycle;
1337 while (w)
1338 {
1339 ipa_reference_vars_info_t w_ri =
1340 get_reference_vars_info (w);
1341
1342 gcc_assert (!w_ri->global);
1343 w_ri->global = XCNEW (struct ipa_reference_global_vars_info_d);
1344 w_ri->global->statics_read = copy_global_bitmap (node_g->statics_read);
1345 w_ri->global->statics_written = copy_global_bitmap (node_g->statics_written);
1346
1347 w_info = (struct ipa_dfs_info *) w->aux;
1348 w = w_info->next_cycle;
1349 }
1350 }
1351
1352 if (dump_file)
1353 {
1354 for (i = 0; i < order_pos; i++ )
1355 {
1356 ipa_reference_vars_info_t node_info;
1357 ipa_reference_global_vars_info_t node_g;
1358 ipa_reference_local_vars_info_t node_l;
1359 unsigned int index;
1360 bitmap_iterator bi;
1361 struct ipa_dfs_info * w_info;
1362
1363 node = order[i];
1364 node_info = get_reference_vars_info (node);
1365 node_g = node_info->global;
1366 node_l = node_info->local;
1367 fprintf (dump_file,
1368 "\nFunction name:%s/%i:",
1369 cgraph_node_name (node), node->uid);
1370 fprintf (dump_file, "\n locals read: ");
1371 if (node_l->statics_read)
1372 EXECUTE_IF_SET_IN_BITMAP (node_l->statics_read,
1373 0, index, bi)
1374 {
1375 fprintf (dump_file, "%s ",
1376 get_static_name (index));
1377 }
1378 fprintf (dump_file, "\n locals written: ");
1379 if (node_l->statics_written)
1380 EXECUTE_IF_SET_IN_BITMAP (node_l->statics_written,
1381 0, index, bi)
1382 {
1383 fprintf(dump_file, "%s ",
1384 get_static_name (index));
1385 }
1386
1387 w_info = (struct ipa_dfs_info *) node->aux;
1388 w = w_info->next_cycle;
1389 while (w)
1390 {
1391 ipa_reference_vars_info_t w_ri =
1392 get_reference_vars_info (w);
1393 ipa_reference_local_vars_info_t w_l = w_ri->local;
1394 fprintf (dump_file, "\n next cycle: %s/%i ",
1395 cgraph_node_name (w), w->uid);
1396 fprintf (dump_file, "\n locals read: ");
1397 if (w_l->statics_read)
1398 EXECUTE_IF_SET_IN_BITMAP (w_l->statics_read,
1399 0, index, bi)
1400 {
1401 fprintf (dump_file, "%s ",
1402 get_static_name (index));
1403 }
1404
1405 fprintf (dump_file, "\n locals written: ");
1406 if (w_l->statics_written)
1407 EXECUTE_IF_SET_IN_BITMAP (w_l->statics_written,
1408 0, index, bi)
1409 {
1410 fprintf (dump_file, "%s ",
1411 get_static_name (index));
1412 }
1413
1414 w_info = (struct ipa_dfs_info *) w->aux;
1415 w = w_info->next_cycle;
1416 }
1417 fprintf (dump_file, "\n globals read: ");
1418 if (node_g->statics_read == all_module_statics)
1419 fprintf (dump_file, "ALL");
1420 else
1421 EXECUTE_IF_SET_IN_BITMAP (node_g->statics_read,
1422 0, index, bi)
1423 {
1424 fprintf (dump_file, "%s ",
1425 get_static_name (index));
1426 }
1427 fprintf (dump_file, "\n globals written: ");
1428 if (node_g->statics_written == all_module_statics)
1429 fprintf (dump_file, "ALL");
1430 else
1431 EXECUTE_IF_SET_IN_BITMAP (node_g->statics_written,
1432 0, index, bi)
1433 {
1434 fprintf (dump_file, "%s ",
1435 get_static_name (index));
1436 }
1437 }
1438 }
1439
1440 /* Cleanup. */
1441 for (i = 0; i < order_pos; i++ )
1442 {
1443 ipa_reference_vars_info_t node_info;
1444 ipa_reference_global_vars_info_t node_g;
1445 node = order[i];
1446 node_info = get_reference_vars_info (node);
1447 node_g = node_info->global;
1448
1449 /* Create the complimentary sets. These are more useful for
1450 certain apis. */
1451 node_g->statics_not_read = BITMAP_ALLOC (&global_info_obstack);
1452 node_g->statics_not_written = BITMAP_ALLOC (&global_info_obstack);
1453
1454 if (node_g->statics_read != all_module_statics)
1455 bitmap_and_compl (node_g->statics_not_read,
1456 all_module_statics,
1457 node_g->statics_read);
1458
1459 if (node_g->statics_written
1460 != all_module_statics)
1461 bitmap_and_compl (node_g->statics_not_written,
1462 all_module_statics,
1463 node_g->statics_written);
1464 }
1465
1466 free (order);
1467
1468 for (node = cgraph_nodes; node; node = node->next)
1469 {
1470 ipa_reference_vars_info_t node_info;
1471 node_info = get_reference_vars_info (node);
1472 /* Get rid of the aux information. */
1473
1474 if (node->aux)
1475 {
1476 free (node->aux);
1477 node->aux = NULL;
1478 }
1479
1480 if (cgraph_function_body_availability (node) == AVAIL_OVERWRITABLE)
1481 clean_function (node);
1482 else if (node_info)
1483 clean_function_local_data (node);
1484 }
1485 bitmap_obstack_release (&local_info_obstack);
1486 return 0;
1487 }
1488
1489
1490 static bool
1491 gate_reference (void)
1492 {
1493 return (flag_ipa_reference
1494 /* Don't bother doing anything if the program has errors. */
1495 && !(errorcount || sorrycount));
1496 }
1497
1498 struct ipa_opt_pass_d pass_ipa_reference =
1499 {
1500 {
1501 IPA_PASS,
1502 "static-var", /* name */
1503 gate_reference, /* gate */
1504 propagate, /* execute */
1505 NULL, /* sub */
1506 NULL, /* next */
1507 0, /* static_pass_number */
1508 TV_IPA_REFERENCE, /* tv_id */
1509 0, /* properties_required */
1510 0, /* properties_provided */
1511 0, /* properties_destroyed */
1512 0, /* todo_flags_start */
1513 0 /* todo_flags_finish */
1514 },
1515 generate_summary, /* generate_summary */
1516 ipa_reference_write_summary, /* write_summary */
1517 ipa_reference_read_summary, /* read_summary */
1518 NULL, /* write_optimization_summary */
1519 NULL, /* read_optimization_summary */
1520 NULL, /* stmt_fixup */
1521 0, /* TODOs */
1522 NULL, /* function_transform */
1523 NULL /* variable_transform */
1524 };
1525
1526 #include "gt-ipa-reference.h"