comparison gcc/ipa-reference.c @ 63:b7f97abdc517 gcc-4.6-20100522

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