rephrase text
[official-gcc.git] / gcc / ipa-reference.c
blob9eac3b10e8296fedf3b761cdaf3bd7008203902b
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>
6 This file is part of GCC.
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.
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.
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/>. */
22 /* This file gathers information about how variables whose scope is
23 confined to the compilation unit are used.
25 There are two categories of information produced by this pass:
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.
31 2) The transitive call site specific clobber effects are computed
32 for the variables whose scope is contained within this compilation
33 unit.
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.
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. */
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"
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);
82 /* The static variables defined within the compilation unit that are
83 loaded or stored directly by function that owns this structure. */
85 struct ipa_reference_local_vars_info_d
87 bitmap statics_read;
88 bitmap statics_written;
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;
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. */
110 struct ipa_reference_global_vars_info_d
112 bitmap statics_read;
113 bitmap statics_written;
114 bitmap statics_not_read;
115 bitmap statics_not_written;
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
122 ipa_reference_local_vars_info_t local;
123 ipa_reference_global_vars_info_t global;
126 typedef struct ipa_reference_vars_info_d *ipa_reference_vars_info_t;
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;
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;
141 /* This bitmap is used to knock out the module static variables that
142 are not readonly. */
143 static bitmap module_statics_written;
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;
150 static struct pointer_set_t *visited_nodes;
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;
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;
163 enum initialization_status_t
165 UNINITIALIZED,
166 RUNNING,
167 FINISHED
170 tree memory_identifier_string;
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;
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)
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);
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)
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);
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)
202 ipa_reference_vars_info_t info = get_reference_vars_info (fn);
204 if (info)
205 return info->local;
206 else
207 /* This phase was not run. */
208 return NULL;
211 /* Get a bitmap that contains all of the globally referenced static
212 variables for function FN. */
214 static ipa_reference_global_vars_info_t
215 get_global_reference_vars_info (struct cgraph_node *fn)
217 ipa_reference_vars_info_t info = get_reference_vars_info (fn);
219 if (info)
220 return info->global;
221 else
222 /* This phase was not run. */
223 return NULL;
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. */
230 bitmap
231 ipa_reference_get_read_global (struct cgraph_node *fn)
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;
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. */
245 bitmap
246 ipa_reference_get_written_global (struct cgraph_node *fn)
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;
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. */
259 bitmap
260 ipa_reference_get_not_read_global (struct cgraph_node *fn)
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;
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. */
274 bitmap
275 ipa_reference_get_not_written_global (struct cgraph_node *fn)
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;
286 /* Add VAR to all_module_statics and the two
287 reference_vars_to_consider* sets. */
289 static inline void
290 add_static_var (tree var)
292 int uid = DECL_UID (var);
293 gcc_assert (TREE_CODE (var) == VAR_DECL);
294 if (!bitmap_bit_p (all_module_statics, uid))
296 splay_tree_insert (reference_vars_to_consider,
297 uid, (splay_tree_value)var);
298 bitmap_set_bit (all_module_statics, uid);
302 /* Return true if the variable T is the right kind of static variable to
303 perform compilation unit scope escape analysis. */
305 static inline bool
306 has_proper_scope_for_analysis (tree t)
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;
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;
318 /* Do not care about a local automatic that is not static. */
319 if (!TREE_STATIC (t) && !DECL_EXTERNAL (t))
320 return false;
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;
327 /* We cannot touch decls where the type needs constructing. */
328 if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (t)))
329 return false;
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);
336 return true;
339 /* Mark tree T as having address taken. */
341 static void
342 mark_address_taken (tree x)
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));
349 /* Wrapper around mark_address_taken for the stmt walker. */
351 static bool
352 mark_address (gimple stmt ATTRIBUTE_UNUSED, tree addr,
353 void *data ATTRIBUTE_UNUSED)
355 addr = get_base_address (addr);
356 if (addr)
357 mark_address_taken (addr);
358 return false;
361 /* Mark load of T. */
363 static bool
364 mark_load (gimple stmt ATTRIBUTE_UNUSED, tree t, void *data)
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;
374 /* Mark store of T. */
376 static bool
377 mark_store (gimple stmt ATTRIBUTE_UNUSED, tree t, void *data)
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))
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));
391 return false;
394 /* Look for memory clobber and set read_all/write_all if present. */
396 static void
397 check_asm_memory_clobber (ipa_reference_local_vars_info_t local, gimple stmt)
399 size_t i;
400 tree op;
402 for (i = 0; i < gimple_asm_nclobbers (stmt); i++)
404 op = gimple_asm_clobber_op (stmt, i);
405 if (simple_cst_equal(TREE_VALUE (op), memory_identifier_string) == 1)
407 /* Abandon all hope, ye who enter here. */
408 local->calls_read_all = true;
409 local->calls_write_all = true;
414 /* Look for external calls and set read_all/write_all correspondingly. */
416 static void
417 check_call (ipa_reference_local_vars_info_t local, gimple stmt)
419 int flags = gimple_call_flags (stmt);
420 tree callee_t = gimple_call_fndecl (stmt);
422 /* Process indirect calls. All direct calles are handled at propagation
423 time. */
424 if (!callee_t)
426 if (flags & ECF_CONST)
428 else if (flags & ECF_PURE)
429 local->calls_read_all = true;
430 else
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;
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. */
446 static tree
447 scan_stmt_for_static_refs (gimple_stmt_iterator *gsip,
448 struct cgraph_node *fn)
450 gimple stmt = gsi_stmt (*gsip);
451 ipa_reference_local_vars_info_t local = NULL;
453 if (is_gimple_debug (stmt))
454 return NULL;
456 if (fn)
457 local = get_reference_vars_info (fn)->local;
459 /* Look for direct loads and stores. */
460 walk_stmt_load_store_addr_ops (stmt, local, mark_load, mark_store,
461 mark_address);
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);
468 return NULL;
471 /* Call-back to scan variable initializers for static references.
472 Called using walk_tree. */
474 static tree
475 scan_initializer_for_static_refs (tree *tp, int *walk_subtrees,
476 void *data ATTRIBUTE_UNUSED)
478 tree t = *tp;
480 if (TREE_CODE (t) == ADDR_EXPR)
482 mark_address_taken (get_base_var (t));
483 *walk_subtrees = 0;
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;
490 return NULL;
493 /* Lookup the tree node for the static variable that has UID. */
494 static tree
495 get_static_decl (int index)
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;
504 /* Lookup the tree node for the static variable that has UID and
505 convert the name to a string for debugging. */
507 static const char *
508 get_static_name (int index)
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;
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. */
521 static void
522 propagate_bits (ipa_reference_global_vars_info_t x_global, struct cgraph_node *x)
524 struct cgraph_edge *e;
525 for (e = x->callees; e; e = e->next_callee)
527 struct cgraph_node *y = e->callee;
529 /* Only look into nodes we can propagate something. */
530 if (cgraph_function_body_availability (e->callee) > AVAIL_OVERWRITABLE)
532 if (get_reference_vars_info (y))
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;
538 /* Calls in current cycle do not have global computed yet. */
539 if (!y_info->global)
540 continue;
542 if (x_global->statics_read
543 != all_module_statics)
545 if (y_global->statics_read
546 == all_module_statics)
548 BITMAP_FREE (x_global->statics_read);
549 x_global->statics_read
550 = all_module_statics;
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);
560 if (x_global->statics_written
561 != all_module_statics)
563 if (y_global->statics_written
564 == all_module_statics)
566 BITMAP_FREE (x_global->statics_written);
567 x_global->statics_written
568 = all_module_statics;
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);
578 else
579 gcc_unreachable ();
584 /* The init routine for analyzing global static variable usage. See
585 comments at top for description. */
586 static void
587 ipa_init (void)
589 static bool init_p = false;
591 if (init_p)
592 return;
594 init_p = true;
596 memory_identifier_string = build_string(7, "memory");
598 reference_vars_to_consider =
599 splay_tree_new_ggc (splay_tree_compare_ints);
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);
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 ();
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);
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. */
627 static void
628 analyze_variable (struct varpool_node *vnode)
630 struct walk_stmt_info wi;
631 tree global = vnode->decl;
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);
640 /* Set up the persistent info for FN. */
642 static ipa_reference_local_vars_info_t
643 init_function_info (struct cgraph_node *fn)
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);
650 /* Add the info to the tree's annotation. */
651 set_reference_vars_info (fn, info);
653 info->local = l;
654 l->statics_read = BITMAP_ALLOC (&local_info_obstack);
655 l->statics_written = BITMAP_ALLOC (&local_info_obstack);
657 return l;
661 /* This is the main routine for finding the reference patterns for
662 global variables within a function FN. */
664 static void
665 analyze_function (struct cgraph_node *fn)
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;
675 if (dump_file)
676 fprintf (dump_file, "\n local analysis of %s\n", cgraph_node_name (fn));
678 push_cfun (DECL_STRUCT_FUNCTION (decl));
679 current_function_decl = decl;
681 init_function_info (fn);
682 FOR_EACH_BB_FN (this_block, this_cfun)
684 gimple_stmt_iterator gsi;
685 gimple phi;
686 tree op;
687 use_operand_p use;
688 ssa_op_iter iter;
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))
695 phi = gsi_stmt (gsi);
696 FOR_EACH_PHI_ARG (use, phi, iter, SSA_OP_USE)
698 op = USE_FROM_PTR (use);
699 if (TREE_CODE (op) == ADDR_EXPR)
700 mark_address_taken (get_base_var (op));
704 for (gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi))
705 scan_stmt_for_static_refs (&gsi, fn);
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))
712 local->calls_write_all = false;
713 bitmap_clear (local->statics_written);
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);
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))
729 tree var = TREE_VALUE (step);
730 if (TREE_CODE (var) == VAR_DECL
731 && DECL_INITIAL (var)
732 && !TREE_STATIC (var))
733 gcc_unreachable ();
735 #endif
736 pop_cfun ();
737 current_function_decl = NULL;
740 /* Remove local data associated with function FN. */
741 static void
742 clean_function_local_data (struct cgraph_node *fn)
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)
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;
759 /* Remove all data associated with function FN. */
761 static void
762 clean_function (struct cgraph_node *fn)
764 ipa_reference_vars_info_t info = get_reference_vars_info (fn);
765 ipa_reference_global_vars_info_t g = info->global;
767 clean_function_local_data (fn);
768 if (g)
770 if (g->statics_read
771 && g->statics_read != all_module_statics)
772 BITMAP_FREE (g->statics_read);
774 if (g->statics_written
775 && g->statics_written != all_module_statics)
776 BITMAP_FREE (g->statics_written);
778 if (g->statics_not_read
779 && g->statics_not_read != all_module_statics)
780 BITMAP_FREE (g->statics_not_read);
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;
789 free (get_reference_vars_info (fn));
790 set_reference_vars_info (fn, NULL);
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)
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;
805 static bitmap
806 copy_local_bitmap (bitmap src)
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;
818 static bitmap
819 copy_global_bitmap (bitmap src)
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;
831 /* Called when new clone is inserted to callgraph late. */
833 static void
834 duplicate_node_data (struct cgraph_node *src, struct cgraph_node *dst,
835 void *data ATTRIBUTE_UNUSED)
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;
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)
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;
855 if (ginfo)
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);
866 /* Called when node is removed. */
868 static void
869 remove_node_data (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
871 if (get_reference_vars_info (node))
872 clean_function (node);
875 /* Analyze each function in the cgraph to see which global or statics
876 are read or written. */
878 static void
879 generate_summary (void)
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;
888 ipa_init ();
889 module_statics_readonly = BITMAP_ALLOC (&local_info_obstack);
890 bm_temp = BITMAP_ALLOC (&local_info_obstack);
892 /* Process all of the variables first. */
893 FOR_EACH_STATIC_INITIALIZER (vnode)
894 analyze_variable (vnode);
896 /* Process all of the functions next.
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.
907 for (node = cgraph_nodes; node; node = node->next)
908 if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
909 analyze_function (node);
911 pointer_set_destroy (visited_nodes);
912 visited_nodes = NULL;
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)
918 splay_tree_remove (reference_vars_to_consider, index);
921 bitmap_and_compl_into (all_module_statics,
922 module_statics_escape);
924 bitmap_and_compl (module_statics_readonly, all_module_statics,
925 module_statics_written);
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)
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));
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. */
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)
946 tree var = get_static_decl (index);
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)
953 TREE_READONLY (var) = 1;
954 if (dump_file)
955 fprintf (dump_file, "read-only var %s\n",
956 get_static_name (index));
960 BITMAP_FREE(module_statics_escape);
961 BITMAP_FREE(module_statics_written);
962 module_statics_escape = NULL;
963 module_statics_written = NULL;
965 if (dump_file)
966 EXECUTE_IF_SET_IN_BITMAP (all_module_statics, 0, index, bi)
968 fprintf (dump_file, "\nPromotable global:%s",
969 get_static_name (index));
972 for (node = cgraph_nodes; node; node = node->next)
973 if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
975 ipa_reference_local_vars_info_t l;
976 l = get_reference_vars_info (node)->local;
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);
990 BITMAP_FREE(module_statics_readonly);
991 BITMAP_FREE(bm_temp);
993 if (dump_file)
994 for (node = cgraph_nodes; node; node = node->next)
995 if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
997 ipa_reference_local_vars_info_t l;
998 unsigned int index;
999 bitmap_iterator bi;
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)
1010 fprintf (dump_file, "%s ",
1011 get_static_name (index));
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)
1018 fprintf(dump_file, "%s ",
1019 get_static_name (index));
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: ");
1029 /* Return true if we need to write summary of NODE. */
1031 static bool
1032 write_node_summary_p (struct cgraph_node *node)
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);
1040 /* Serialize the ipa info for lto. */
1042 static void
1043 ipa_reference_write_summary (cgraph_node_set set)
1045 struct cgraph_node *node;
1046 struct lto_simple_output_block *ob
1047 = lto_create_simple_output_block (LTO_section_ipa_reference);
1048 unsigned int count = 0;
1049 cgraph_node_set_iterator csi;
1051 for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
1052 if (write_node_summary_p (csi_node (csi)))
1053 count++;
1055 lto_output_uleb128_stream (ob->main_stream, count);
1057 /* Process all of the functions. */
1058 for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
1060 node = csi_node (csi);
1061 if (write_node_summary_p (node))
1063 ipa_reference_local_vars_info_t l
1064 = get_reference_vars_info (node)->local;
1065 unsigned int index;
1066 bitmap_iterator bi;
1067 lto_cgraph_encoder_t encoder;
1068 int node_ref;
1070 encoder = ob->decl_state->cgraph_node_encoder;
1071 node_ref = lto_cgraph_encoder_encode (encoder, node);
1072 lto_output_uleb128_stream (ob->main_stream, node_ref);
1074 /* Stream out the statics read. */
1075 if (l->calls_read_all)
1076 lto_output_sleb128_stream (ob->main_stream, -1);
1077 else
1079 lto_output_sleb128_stream (ob->main_stream,
1080 bitmap_count_bits (l->statics_read));
1081 EXECUTE_IF_SET_IN_BITMAP (l->statics_read, 0, index, bi)
1082 lto_output_var_decl_index(ob->decl_state, ob->main_stream,
1083 get_static_decl (index));
1086 /* Stream out the statics written. */
1087 if (l->calls_write_all)
1088 lto_output_sleb128_stream (ob->main_stream, -1);
1089 else
1091 lto_output_sleb128_stream (ob->main_stream,
1092 bitmap_count_bits (l->statics_written));
1093 EXECUTE_IF_SET_IN_BITMAP (l->statics_written, 0, index, bi)
1094 lto_output_var_decl_index(ob->decl_state, ob->main_stream,
1095 get_static_decl (index));
1099 lto_destroy_simple_output_block (ob);
1103 /* Deserialize the ipa info for lto. */
1105 static void
1106 ipa_reference_read_summary (void)
1108 struct lto_file_decl_data ** file_data_vec
1109 = lto_get_file_decl_data ();
1110 struct lto_file_decl_data * file_data;
1111 unsigned int j = 0;
1113 ipa_init ();
1115 while ((file_data = file_data_vec[j++]))
1117 const char *data;
1118 size_t len;
1119 struct lto_input_block *ib
1120 = lto_create_simple_input_block (file_data,
1121 LTO_section_ipa_reference,
1122 &data, &len);
1123 if (ib)
1125 unsigned int i;
1126 unsigned int f_count = lto_input_uleb128 (ib);
1128 for (i = 0; i < f_count; i++)
1130 unsigned int j, index;
1131 struct cgraph_node *node;
1132 ipa_reference_local_vars_info_t l;
1133 int v_count;
1134 lto_cgraph_encoder_t encoder;
1136 index = lto_input_uleb128 (ib);
1137 encoder = file_data->cgraph_node_encoder;
1138 node = lto_cgraph_encoder_deref (encoder, index);
1139 l = init_function_info (node);
1141 /* Set the statics read. */
1142 v_count = lto_input_sleb128 (ib);
1143 if (v_count == -1)
1144 l->calls_read_all = true;
1145 else
1146 for (j = 0; j < (unsigned int)v_count; j++)
1148 unsigned int var_index = lto_input_uleb128 (ib);
1149 tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1150 var_index);
1151 add_static_var (v_decl);
1152 bitmap_set_bit (l->statics_read, DECL_UID (v_decl));
1155 /* Set the statics written. */
1156 v_count = lto_input_sleb128 (ib);
1157 if (v_count == -1)
1158 l->calls_write_all = true;
1159 else
1160 for (j = 0; j < (unsigned int)v_count; j++)
1162 unsigned int var_index = lto_input_uleb128 (ib);
1163 tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1164 var_index);
1165 add_static_var (v_decl);
1166 bitmap_set_bit (l->statics_written, DECL_UID (v_decl));
1170 lto_destroy_simple_input_block (file_data,
1171 LTO_section_ipa_reference,
1172 ib, data, len);
1179 /* Set READ_ALL/WRITE_ALL based on DECL flags. */
1180 static void
1181 read_write_all_from_decl (tree decl, bool * read_all, bool * write_all)
1183 int flags = flags_from_decl_or_type (decl);
1184 if (flags & ECF_CONST)
1186 else if (flags & ECF_PURE)
1187 *read_all = true;
1188 else
1190 /* TODO: To be able to produce sane results, we should also handle
1191 common builtins, in particular throw.
1192 Indirect calls hsould be only counted and as inliner is replacing them
1193 by direct calls, we can conclude if any indirect calls are left in body */
1194 *read_all = true;
1195 /* When function does not reutrn, it is safe to ignore anythign it writes
1196 to, because the effect will never happen. */
1197 if ((flags & (ECF_NOTHROW | ECF_NORETURN))
1198 != (ECF_NOTHROW | ECF_NORETURN))
1199 *write_all = true;
1203 /* Produce the global information by preforming a transitive closure
1204 on the local information that was produced by ipa_analyze_function
1205 and ipa_analyze_variable. */
1207 static unsigned int
1208 propagate (void)
1210 struct cgraph_node *node;
1211 struct cgraph_node *w;
1212 struct cgraph_node **order =
1213 XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
1214 int order_pos = ipa_utils_reduced_inorder (order, false, true, NULL);
1215 int i;
1217 cgraph_remove_function_insertion_hook (function_insertion_hook_holder);
1218 if (dump_file)
1219 dump_cgraph (dump_file);
1221 /* Propagate the local information thru the call graph to produce
1222 the global information. All the nodes within a cycle will have
1223 the same info so we collapse cycles first. Then we can do the
1224 propagation in one pass from the leaves to the roots. */
1225 order_pos = ipa_utils_reduced_inorder (order, true, true, NULL);
1226 if (dump_file)
1227 ipa_utils_print_order(dump_file, "reduced", order, order_pos);
1229 for (i = 0; i < order_pos; i++ )
1231 ipa_reference_vars_info_t node_info;
1232 ipa_reference_global_vars_info_t node_g =
1233 XCNEW (struct ipa_reference_global_vars_info_d);
1234 ipa_reference_local_vars_info_t node_l;
1235 struct cgraph_edge *e;
1237 bool read_all;
1238 bool write_all;
1239 struct ipa_dfs_info * w_info;
1241 node = order[i];
1242 node_info = get_reference_vars_info (node);
1243 if (!node_info)
1245 dump_cgraph_node (stderr, node);
1246 dump_cgraph (stderr);
1247 gcc_unreachable ();
1250 gcc_assert (!node_info->global);
1251 node_l = node_info->local;
1253 read_all = node_l->calls_read_all;
1254 write_all = node_l->calls_write_all;
1256 /* When function is overwrittable, we can not assume anything. */
1257 if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
1258 read_write_all_from_decl (node->decl, &read_all, &write_all);
1260 for (e = node->callees; e; e = e->next_callee)
1261 if (cgraph_function_body_availability (e->callee) <= AVAIL_OVERWRITABLE)
1262 read_write_all_from_decl (e->callee->decl, &read_all, &write_all);
1265 /* If any node in a cycle is calls_read_all or calls_write_all
1266 they all are. */
1267 w_info = (struct ipa_dfs_info *) node->aux;
1268 w = w_info->next_cycle;
1269 while (w)
1271 ipa_reference_local_vars_info_t w_l =
1272 get_reference_vars_info (w)->local;
1274 /* When function is overwrittable, we can not assume anything. */
1275 if (cgraph_function_body_availability (w) <= AVAIL_OVERWRITABLE)
1276 read_write_all_from_decl (w->decl, &read_all, &write_all);
1278 for (e = w->callees; e; e = e->next_callee)
1279 if (cgraph_function_body_availability (e->callee) <= AVAIL_OVERWRITABLE)
1280 read_write_all_from_decl (e->callee->decl, &read_all, &write_all);
1282 read_all |= w_l->calls_read_all;
1283 write_all |= w_l->calls_write_all;
1285 w_info = (struct ipa_dfs_info *) w->aux;
1286 w = w_info->next_cycle;
1290 /* Initialized the bitmaps for the reduced nodes */
1291 if (read_all)
1292 node_g->statics_read = all_module_statics;
1293 else
1295 node_g->statics_read = BITMAP_ALLOC (&global_info_obstack);
1296 bitmap_copy (node_g->statics_read,
1297 node_l->statics_read);
1299 if (write_all)
1300 node_g->statics_written = all_module_statics;
1301 else
1303 node_g->statics_written = BITMAP_ALLOC (&global_info_obstack);
1304 bitmap_copy (node_g->statics_written,
1305 node_l->statics_written);
1308 propagate_bits (node_g, node);
1309 w_info = (struct ipa_dfs_info *) node->aux;
1310 w = w_info->next_cycle;
1311 while (w)
1313 ipa_reference_vars_info_t w_ri =
1314 get_reference_vars_info (w);
1315 ipa_reference_local_vars_info_t w_l = w_ri->local;
1317 /* These global bitmaps are initialized from the local info
1318 of all of the nodes in the region. However there is no
1319 need to do any work if the bitmaps were set to
1320 all_module_statics. */
1321 if (!read_all)
1322 bitmap_ior_into (node_g->statics_read,
1323 w_l->statics_read);
1324 if (!write_all)
1325 bitmap_ior_into (node_g->statics_written,
1326 w_l->statics_written);
1327 propagate_bits (node_g, w);
1328 w_info = (struct ipa_dfs_info *) w->aux;
1329 w = w_info->next_cycle;
1332 /* All nodes within a cycle have the same global info bitmaps. */
1333 node_info->global = node_g;
1334 w_info = (struct ipa_dfs_info *) node->aux;
1335 w = w_info->next_cycle;
1336 while (w)
1338 ipa_reference_vars_info_t w_ri =
1339 get_reference_vars_info (w);
1341 gcc_assert (!w_ri->global);
1342 w_ri->global = XCNEW (struct ipa_reference_global_vars_info_d);
1343 w_ri->global->statics_read = copy_global_bitmap (node_g->statics_read);
1344 w_ri->global->statics_written = copy_global_bitmap (node_g->statics_written);
1346 w_info = (struct ipa_dfs_info *) w->aux;
1347 w = w_info->next_cycle;
1351 if (dump_file)
1353 for (i = 0; i < order_pos; i++ )
1355 ipa_reference_vars_info_t node_info;
1356 ipa_reference_global_vars_info_t node_g;
1357 ipa_reference_local_vars_info_t node_l;
1358 unsigned int index;
1359 bitmap_iterator bi;
1360 struct ipa_dfs_info * w_info;
1362 node = order[i];
1363 node_info = get_reference_vars_info (node);
1364 node_g = node_info->global;
1365 node_l = node_info->local;
1366 fprintf (dump_file,
1367 "\nFunction name:%s/%i:",
1368 cgraph_node_name (node), node->uid);
1369 fprintf (dump_file, "\n locals read: ");
1370 if (node_l->statics_read)
1371 EXECUTE_IF_SET_IN_BITMAP (node_l->statics_read,
1372 0, index, bi)
1374 fprintf (dump_file, "%s ",
1375 get_static_name (index));
1377 fprintf (dump_file, "\n locals written: ");
1378 if (node_l->statics_written)
1379 EXECUTE_IF_SET_IN_BITMAP (node_l->statics_written,
1380 0, index, bi)
1382 fprintf(dump_file, "%s ",
1383 get_static_name (index));
1386 w_info = (struct ipa_dfs_info *) node->aux;
1387 w = w_info->next_cycle;
1388 while (w)
1390 ipa_reference_vars_info_t w_ri =
1391 get_reference_vars_info (w);
1392 ipa_reference_local_vars_info_t w_l = w_ri->local;
1393 fprintf (dump_file, "\n next cycle: %s/%i ",
1394 cgraph_node_name (w), w->uid);
1395 fprintf (dump_file, "\n locals read: ");
1396 if (w_l->statics_read)
1397 EXECUTE_IF_SET_IN_BITMAP (w_l->statics_read,
1398 0, index, bi)
1400 fprintf (dump_file, "%s ",
1401 get_static_name (index));
1404 fprintf (dump_file, "\n locals written: ");
1405 if (w_l->statics_written)
1406 EXECUTE_IF_SET_IN_BITMAP (w_l->statics_written,
1407 0, index, bi)
1409 fprintf (dump_file, "%s ",
1410 get_static_name (index));
1413 w_info = (struct ipa_dfs_info *) w->aux;
1414 w = w_info->next_cycle;
1416 fprintf (dump_file, "\n globals read: ");
1417 if (node_g->statics_read == all_module_statics)
1418 fprintf (dump_file, "ALL");
1419 else
1420 EXECUTE_IF_SET_IN_BITMAP (node_g->statics_read,
1421 0, index, bi)
1423 fprintf (dump_file, "%s ",
1424 get_static_name (index));
1426 fprintf (dump_file, "\n globals written: ");
1427 if (node_g->statics_written == all_module_statics)
1428 fprintf (dump_file, "ALL");
1429 else
1430 EXECUTE_IF_SET_IN_BITMAP (node_g->statics_written,
1431 0, index, bi)
1433 fprintf (dump_file, "%s ",
1434 get_static_name (index));
1439 /* Cleanup. */
1440 for (i = 0; i < order_pos; i++ )
1442 ipa_reference_vars_info_t node_info;
1443 ipa_reference_global_vars_info_t node_g;
1444 node = order[i];
1445 node_info = get_reference_vars_info (node);
1446 node_g = node_info->global;
1448 /* Create the complimentary sets. These are more useful for
1449 certain apis. */
1450 node_g->statics_not_read = BITMAP_ALLOC (&global_info_obstack);
1451 node_g->statics_not_written = BITMAP_ALLOC (&global_info_obstack);
1453 if (node_g->statics_read != all_module_statics)
1454 bitmap_and_compl (node_g->statics_not_read,
1455 all_module_statics,
1456 node_g->statics_read);
1458 if (node_g->statics_written
1459 != all_module_statics)
1460 bitmap_and_compl (node_g->statics_not_written,
1461 all_module_statics,
1462 node_g->statics_written);
1465 free (order);
1467 for (node = cgraph_nodes; node; node = node->next)
1469 ipa_reference_vars_info_t node_info;
1470 node_info = get_reference_vars_info (node);
1471 /* Get rid of the aux information. */
1473 if (node->aux)
1475 free (node->aux);
1476 node->aux = NULL;
1479 if (cgraph_function_body_availability (node) == AVAIL_OVERWRITABLE)
1480 clean_function (node);
1481 else if (node_info)
1482 clean_function_local_data (node);
1484 bitmap_obstack_release (&local_info_obstack);
1485 return 0;
1489 static bool
1490 gate_reference (void)
1492 return (flag_ipa_reference
1493 /* Don't bother doing anything if the program has errors. */
1494 && !(errorcount || sorrycount));
1497 struct ipa_opt_pass_d pass_ipa_reference =
1500 IPA_PASS,
1501 "static-var", /* name */
1502 gate_reference, /* gate */
1503 propagate, /* execute */
1504 NULL, /* sub */
1505 NULL, /* next */
1506 0, /* static_pass_number */
1507 TV_IPA_REFERENCE, /* tv_id */
1508 0, /* properties_required */
1509 0, /* properties_provided */
1510 0, /* properties_destroyed */
1511 0, /* todo_flags_start */
1512 0 /* todo_flags_finish */
1514 generate_summary, /* generate_summary */
1515 ipa_reference_write_summary, /* write_summary */
1516 ipa_reference_read_summary, /* read_summary */
1517 NULL, /* function_read_summary */
1518 NULL, /* stmt_fixup */
1519 0, /* TODOs */
1520 NULL, /* function_transform */
1521 NULL /* variable_transform */
1524 #include "gt-ipa-reference.h"