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