comparison gcc/ipa-reference.c @ 55:77e2b8dfacca gcc-4.4.5

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