1/* Data flow functions for trees. 2 Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. 3 Contributed by Diego Novillo <dnovillo@redhat.com> 4 5This file is part of GCC. 6 7GCC is free software; you can redistribute it and/or modify 8it under the terms of the GNU General Public License as published by 9the Free Software Foundation; either version 2, or (at your option) 10any later version. 11 12GCC is distributed in the hope that it will be useful, 13but WITHOUT ANY WARRANTY; without even the implied warranty of 14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15GNU General Public License for more details. 16 17You should have received a copy of the GNU General Public License 18along with GCC; see the file COPYING. If not, write to 19the Free Software Foundation, 51 Franklin Street, Fifth Floor, 20Boston, MA 02110-1301, USA. */ 21 22#include "config.h" 23#include "system.h" 24#include "coretypes.h" 25#include "tm.h" 26#include "hashtab.h" 27#include "pointer-set.h" 28#include "tree.h" 29#include "rtl.h" 30#include "tm_p.h" 31#include "hard-reg-set.h" 32#include "basic-block.h" 33#include "output.h" 34#include "timevar.h" 35#include "expr.h" 36#include "ggc.h" 37#include "langhooks.h" 38#include "flags.h" 39#include "function.h" 40#include "diagnostic.h" 41#include "tree-dump.h" 42#include "tree-gimple.h" 43#include "tree-flow.h" 44#include "tree-inline.h" 45#include "tree-pass.h" 46#include "convert.h" 47#include "params.h" 48#include "cgraph.h" 49 50/* Build and maintain data flow information for trees. */ 51 52/* Counters used to display DFA and SSA statistics. */ 53struct dfa_stats_d 54{ 55 long num_stmt_anns; 56 long num_var_anns; 57 long num_defs; 58 long num_uses; 59 long num_phis; 60 long num_phi_args; 61 int max_num_phi_args; 62 long num_v_may_defs; 63 long num_vuses; 64 long num_v_must_defs; 65}; 66 67 68/* Local functions. */ 69static void collect_dfa_stats (struct dfa_stats_d *); 70static tree collect_dfa_stats_r (tree *, int *, void *); 71static tree find_vars_r (tree *, int *, void *); 72static void add_referenced_var (tree, bool); 73 74 75/* Global declarations. */ 76 77/* Array of all variables referenced in the function. */ 78htab_t referenced_vars; 79 80 81/*--------------------------------------------------------------------------- 82 Dataflow analysis (DFA) routines 83---------------------------------------------------------------------------*/ 84/* Find all the variables referenced in the function. This function 85 builds the global arrays REFERENCED_VARS and CALL_CLOBBERED_VARS. 86 87 Note that this function does not look for statement operands, it simply 88 determines what variables are referenced in the program and detects 89 various attributes for each variable used by alias analysis and the 90 optimizer. */ 91 92static void 93find_referenced_vars (void) 94{ 95 basic_block bb; 96 block_stmt_iterator si; 97 98 FOR_EACH_BB (bb) 99 for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si)) 100 { 101 tree *stmt_p = bsi_stmt_ptr (si); 102 walk_tree (stmt_p, find_vars_r, NULL, NULL); 103 } 104 105} 106 107struct tree_opt_pass pass_referenced_vars = 108{ 109 NULL, /* name */ 110 NULL, /* gate */ 111 find_referenced_vars, /* execute */ 112 NULL, /* sub */ 113 NULL, /* next */ 114 0, /* static_pass_number */ 115 TV_FIND_REFERENCED_VARS, /* tv_id */ 116 PROP_gimple_leh | PROP_cfg, /* properties_required */ 117 PROP_referenced_vars, /* properties_provided */ 118 0, /* properties_destroyed */ 119 0, /* todo_flags_start */ 120 0, /* todo_flags_finish */ 121 0 /* letter */ 122}; 123 124 125/*--------------------------------------------------------------------------- 126 Manage annotations 127---------------------------------------------------------------------------*/ 128/* Create a new annotation for a _DECL node T. */ 129 130var_ann_t 131create_var_ann (tree t) 132{ 133 var_ann_t ann; 134 135 gcc_assert (t); 136 gcc_assert (DECL_P (t)); 137 gcc_assert (!t->common.ann || t->common.ann->common.type == VAR_ANN); 138 139 ann = ggc_alloc (sizeof (*ann)); 140 memset ((void *) ann, 0, sizeof (*ann)); 141 142 ann->common.type = VAR_ANN; 143 144 t->common.ann = (tree_ann_t) ann; 145 146 return ann; 147} 148 149 150/* Create a new annotation for a statement node T. */ 151 152stmt_ann_t 153create_stmt_ann (tree t) 154{ 155 stmt_ann_t ann; 156 157 gcc_assert (is_gimple_stmt (t)); 158 gcc_assert (!t->common.ann || t->common.ann->common.type == STMT_ANN); 159 160 ann = ggc_alloc (sizeof (*ann)); 161 memset ((void *) ann, 0, sizeof (*ann)); 162 163 ann->common.type = STMT_ANN; 164 165 /* Since we just created the annotation, mark the statement modified. */ 166 ann->modified = true; 167 168 t->common.ann = (tree_ann_t) ann; 169 170 return ann; 171} 172 173/* Create a new annotation for a tree T. */ 174 175tree_ann_t 176create_tree_ann (tree t) 177{ 178 tree_ann_t ann; 179 180 gcc_assert (t); 181 gcc_assert (!t->common.ann || t->common.ann->common.type == TREE_ANN_COMMON); 182 183 ann = ggc_alloc (sizeof (*ann)); 184 memset ((void *) ann, 0, sizeof (*ann)); 185 186 ann->common.type = TREE_ANN_COMMON; 187 t->common.ann = ann; 188 189 return ann; 190} 191 192/* Build a temporary. Make sure and register it to be renamed. */ 193 194tree 195make_rename_temp (tree type, const char *prefix) 196{ 197 tree t = create_tmp_var (type, prefix); 198 199 if (TREE_CODE (type) == COMPLEX_TYPE) 200 DECL_COMPLEX_GIMPLE_REG_P (t) = 1; 201 202 if (referenced_vars) 203 { 204 add_referenced_tmp_var (t); 205 mark_sym_for_renaming (t); 206 } 207 208 return t; 209} 210 211 212 213/*--------------------------------------------------------------------------- 214 Debugging functions 215---------------------------------------------------------------------------*/ 216/* Dump the list of all the referenced variables in the current function to 217 FILE. */ 218 219void 220dump_referenced_vars (FILE *file) 221{ 222 tree var; 223 referenced_var_iterator rvi; 224 225 fprintf (file, "\nReferenced variables in %s: %u\n\n", 226 get_name (current_function_decl), (unsigned) num_referenced_vars); 227 228 FOR_EACH_REFERENCED_VAR (var, rvi) 229 { 230 fprintf (file, "Variable: "); 231 dump_variable (file, var); 232 fprintf (file, "\n"); 233 } 234} 235 236 237/* Dump the list of all the referenced variables to stderr. */ 238 239void 240debug_referenced_vars (void) 241{ 242 dump_referenced_vars (stderr); 243} 244 245 246/* Dump sub-variables for VAR to FILE. */ 247 248void 249dump_subvars_for (FILE *file, tree var) 250{ 251 subvar_t sv = get_subvars_for_var (var); 252 253 if (!sv) 254 return; 255 256 fprintf (file, "{ "); 257 258 for (; sv; sv = sv->next) 259 { 260 print_generic_expr (file, sv->var, dump_flags); 261 fprintf (file, " "); 262 } 263 264 fprintf (file, "}"); 265} 266 267 268/* Dumb sub-variables for VAR to stderr. */ 269 270void 271debug_subvars_for (tree var) 272{ 273 dump_subvars_for (stderr, var); 274} 275 276 277/* Dump variable VAR and its may-aliases to FILE. */ 278 279void 280dump_variable (FILE *file, tree var) 281{ 282 var_ann_t ann; 283 284 if (TREE_CODE (var) == SSA_NAME) 285 { 286 if (POINTER_TYPE_P (TREE_TYPE (var))) 287 dump_points_to_info_for (file, var); 288 var = SSA_NAME_VAR (var); 289 } 290 291 if (var == NULL_TREE) 292 { 293 fprintf (file, "<nil>"); 294 return; 295 } 296 297 print_generic_expr (file, var, dump_flags); 298 299 ann = var_ann (var); 300 301 fprintf (file, ", UID %u", (unsigned) DECL_UID (var)); 302 303 fprintf (file, ", "); 304 print_generic_expr (file, TREE_TYPE (var), dump_flags); 305 306 if (ann && ann->type_mem_tag) 307 { 308 fprintf (file, ", type memory tag: "); 309 print_generic_expr (file, ann->type_mem_tag, dump_flags); 310 } 311 312 if (ann && ann->is_alias_tag) 313 fprintf (file, ", is an alias tag"); 314 315 if (TREE_ADDRESSABLE (var)) 316 fprintf (file, ", is addressable"); 317 318 if (is_global_var (var)) 319 fprintf (file, ", is global"); 320 321 if (TREE_THIS_VOLATILE (var)) 322 fprintf (file, ", is volatile"); 323 324 if (is_call_clobbered (var)) 325 fprintf (file, ", call clobbered"); 326 327 if (default_def (var)) 328 { 329 fprintf (file, ", default def: "); 330 print_generic_expr (file, default_def (var), dump_flags); 331 } 332 333 if (may_aliases (var)) 334 { 335 fprintf (file, ", may aliases: "); 336 dump_may_aliases_for (file, var); 337 } 338 339 if (get_subvars_for_var (var)) 340 { 341 fprintf (file, ", sub-vars: "); 342 dump_subvars_for (file, var); 343 } 344 345 fprintf (file, "\n"); 346} 347 348 349/* Dump variable VAR and its may-aliases to stderr. */ 350 351void 352debug_variable (tree var) 353{ 354 dump_variable (stderr, var); 355} 356 357 358/* Dump various DFA statistics to FILE. */ 359 360void 361dump_dfa_stats (FILE *file) 362{ 363 struct dfa_stats_d dfa_stats; 364 365 unsigned long size, total = 0; 366 const char * const fmt_str = "%-30s%-13s%12s\n"; 367 const char * const fmt_str_1 = "%-30s%13lu%11lu%c\n"; 368 const char * const fmt_str_3 = "%-43s%11lu%c\n"; 369 const char *funcname 370 = lang_hooks.decl_printable_name (current_function_decl, 2); 371 372 collect_dfa_stats (&dfa_stats); 373 374 fprintf (file, "\nDFA Statistics for %s\n\n", funcname); 375 376 fprintf (file, "---------------------------------------------------------\n"); 377 fprintf (file, fmt_str, "", " Number of ", "Memory"); 378 fprintf (file, fmt_str, "", " instances ", "used "); 379 fprintf (file, "---------------------------------------------------------\n"); 380 381 size = num_referenced_vars * sizeof (tree); 382 total += size; 383 fprintf (file, fmt_str_1, "Referenced variables", (unsigned long)num_referenced_vars, 384 SCALE (size), LABEL (size)); 385 386 size = dfa_stats.num_stmt_anns * sizeof (struct stmt_ann_d); 387 total += size; 388 fprintf (file, fmt_str_1, "Statements annotated", dfa_stats.num_stmt_anns, 389 SCALE (size), LABEL (size)); 390 391 size = dfa_stats.num_var_anns * sizeof (struct var_ann_d); 392 total += size; 393 fprintf (file, fmt_str_1, "Variables annotated", dfa_stats.num_var_anns, 394 SCALE (size), LABEL (size)); 395 396 size = dfa_stats.num_uses * sizeof (tree *); 397 total += size; 398 fprintf (file, fmt_str_1, "USE operands", dfa_stats.num_uses, 399 SCALE (size), LABEL (size)); 400 401 size = dfa_stats.num_defs * sizeof (tree *); 402 total += size; 403 fprintf (file, fmt_str_1, "DEF operands", dfa_stats.num_defs, 404 SCALE (size), LABEL (size)); 405 406 size = dfa_stats.num_vuses * sizeof (tree *); 407 total += size; 408 fprintf (file, fmt_str_1, "VUSE operands", dfa_stats.num_vuses, 409 SCALE (size), LABEL (size)); 410 411 size = dfa_stats.num_v_may_defs * sizeof (tree *); 412 total += size; 413 fprintf (file, fmt_str_1, "V_MAY_DEF operands", dfa_stats.num_v_may_defs, 414 SCALE (size), LABEL (size)); 415 416 size = dfa_stats.num_v_must_defs * sizeof (tree *); 417 total += size; 418 fprintf (file, fmt_str_1, "V_MUST_DEF operands", dfa_stats.num_v_must_defs, 419 SCALE (size), LABEL (size)); 420 421 size = dfa_stats.num_phis * sizeof (struct tree_phi_node); 422 total += size; 423 fprintf (file, fmt_str_1, "PHI nodes", dfa_stats.num_phis, 424 SCALE (size), LABEL (size)); 425 426 size = dfa_stats.num_phi_args * sizeof (struct phi_arg_d); 427 total += size; 428 fprintf (file, fmt_str_1, "PHI arguments", dfa_stats.num_phi_args, 429 SCALE (size), LABEL (size)); 430 431 fprintf (file, "---------------------------------------------------------\n"); 432 fprintf (file, fmt_str_3, "Total memory used by DFA/SSA data", SCALE (total), 433 LABEL (total)); 434 fprintf (file, "---------------------------------------------------------\n"); 435 fprintf (file, "\n"); 436 437 if (dfa_stats.num_phis) 438 fprintf (file, "Average number of arguments per PHI node: %.1f (max: %d)\n", 439 (float) dfa_stats.num_phi_args / (float) dfa_stats.num_phis, 440 dfa_stats.max_num_phi_args); 441 442 fprintf (file, "\n"); 443} 444 445 446/* Dump DFA statistics on stderr. */ 447 448void 449debug_dfa_stats (void) 450{ 451 dump_dfa_stats (stderr); 452} 453 454 455/* Collect DFA statistics and store them in the structure pointed to by 456 DFA_STATS_P. */ 457 458static void 459collect_dfa_stats (struct dfa_stats_d *dfa_stats_p) 460{ 461 struct pointer_set_t *pset; 462 basic_block bb; 463 block_stmt_iterator i; 464 465 gcc_assert (dfa_stats_p); 466 467 memset ((void *)dfa_stats_p, 0, sizeof (struct dfa_stats_d)); 468 469 /* Walk all the trees in the function counting references. Start at 470 basic block 0, but don't stop at block boundaries. */ 471 pset = pointer_set_create (); 472 473 for (i = bsi_start (BASIC_BLOCK (0)); !bsi_end_p (i); bsi_next (&i)) 474 walk_tree (bsi_stmt_ptr (i), collect_dfa_stats_r, (void *) dfa_stats_p, 475 pset); 476 477 pointer_set_destroy (pset); 478 479 FOR_EACH_BB (bb) 480 { 481 tree phi; 482 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi)) 483 { 484 dfa_stats_p->num_phis++; 485 dfa_stats_p->num_phi_args += PHI_NUM_ARGS (phi); 486 if (PHI_NUM_ARGS (phi) > dfa_stats_p->max_num_phi_args) 487 dfa_stats_p->max_num_phi_args = PHI_NUM_ARGS (phi); 488 } 489 } 490} 491 492 493/* Callback for walk_tree to collect DFA statistics for a tree and its 494 children. */ 495 496static tree 497collect_dfa_stats_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, 498 void *data) 499{ 500 tree t = *tp; 501 struct dfa_stats_d *dfa_stats_p = (struct dfa_stats_d *)data; 502 503 if (t->common.ann) 504 { 505 switch (ann_type (t->common.ann)) 506 { 507 case STMT_ANN: 508 { 509 dfa_stats_p->num_stmt_anns++; 510 dfa_stats_p->num_defs += NUM_SSA_OPERANDS (t, SSA_OP_DEF); 511 dfa_stats_p->num_uses += NUM_SSA_OPERANDS (t, SSA_OP_USE); 512 dfa_stats_p->num_v_may_defs += NUM_SSA_OPERANDS (t, SSA_OP_VMAYDEF); 513 dfa_stats_p->num_vuses += NUM_SSA_OPERANDS (t, SSA_OP_VUSE); 514 dfa_stats_p->num_v_must_defs += 515 NUM_SSA_OPERANDS (t, SSA_OP_VMUSTDEF); 516 break; 517 } 518 519 case VAR_ANN: 520 dfa_stats_p->num_var_anns++; 521 break; 522 523 default: 524 break; 525 } 526 } 527 528 return NULL; 529} 530 531 532/*--------------------------------------------------------------------------- 533 Miscellaneous helpers 534---------------------------------------------------------------------------*/ 535/* Callback for walk_tree. Used to collect variables referenced in 536 the function. */ 537 538static tree 539find_vars_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) 540{ 541 /* If T is a regular variable that the optimizers are interested 542 in, add it to the list of variables. */ 543 if (SSA_VAR_P (*tp)) 544 add_referenced_var (*tp, false); 545 546 /* Type, _DECL and constant nodes have no interesting children. 547 Ignore them. */ 548 else if (IS_TYPE_OR_DECL_P (*tp) || CONSTANT_CLASS_P (*tp)) 549 *walk_subtrees = 0; 550 551 return NULL_TREE; 552} 553 554 555/* Lookup UID in the referenced_vars hashtable and return the associated 556 variable or NULL if it is not there. */ 557 558tree 559referenced_var_lookup_if_exists (unsigned int uid) 560{ 561 struct int_tree_map *h, in; 562 in.uid = uid; 563 h = htab_find_with_hash (referenced_vars, &in, uid); 564 if (h) 565 return h->to; 566 return NULL_TREE; 567} 568 569/* Lookup UID in the referenced_vars hashtable and return the associated 570 variable. */ 571 572tree 573referenced_var_lookup (unsigned int uid) 574{ 575 struct int_tree_map *h, in; 576 in.uid = uid; 577 h = htab_find_with_hash (referenced_vars, &in, uid); 578 gcc_assert (h || uid == 0); 579 if (h) 580 return h->to; 581 return NULL_TREE; 582} 583 584/* Insert the pair UID, TO into the referenced_vars hashtable. */ 585 586static void 587referenced_var_insert (unsigned int uid, tree to) 588{ 589 struct int_tree_map *h; 590 void **loc; 591 592 h = ggc_alloc (sizeof (struct int_tree_map)); 593 h->uid = uid; 594 h->to = to; 595 loc = htab_find_slot_with_hash (referenced_vars, h, uid, INSERT); 596 /* This assert can only trigger if a variable with the same UID has been 597 inserted already. */ 598 gcc_assert ((*(struct int_tree_map **)loc) == NULL); 599 *(struct int_tree_map **) loc = h; 600} 601 602/* Add VAR to the list of dereferenced variables. 603 604 WALK_STATE contains a hash table used to avoid adding the same 605 variable more than once. Note that this function assumes that 606 VAR is a valid SSA variable. If WALK_STATE is NULL, no 607 duplicate checking is done. */ 608 609static void 610add_referenced_var (tree var, bool always) 611{ 612 var_ann_t v_ann; 613 tree ref; 614 615 v_ann = get_var_ann (var); 616 gcc_assert (DECL_P (var)); 617 618 ref = referenced_var_lookup_if_exists (DECL_UID (var)); 619 620 /* Catch PRs 26757 and 27793. If this assert triggers, REF and VAR are 621 two different variables in this function with the same DECL_UID. */ 622 gcc_assert (!ref || ref == var); 623 624 if (always || ref == NULL_TREE) 625 { 626 /* This is the first time we find this variable, add it to the 627 REFERENCED_VARS array and annotate it with attributes that are 628 intrinsic to the variable. */ 629 630 referenced_var_insert (DECL_UID (var), var); 631 632 /* Global variables are always call-clobbered. */ 633 if (is_global_var (var)) 634 mark_call_clobbered (var); 635 636 /* Scan DECL_INITIAL for pointer variables as they may contain 637 address arithmetic referencing the address of other 638 variables. */ 639 if (DECL_INITIAL (var) 640 /* Initializers of external variables are not useful to the 641 optimizers. */ 642 && !DECL_EXTERNAL (var) 643 /* It's not necessary to walk the initial value of non-constant 644 variables because it cannot be propagated by the 645 optimizers. */ 646 && (TREE_CONSTANT (var) || TREE_READONLY (var))) 647 walk_tree (&DECL_INITIAL (var), find_vars_r, NULL, 0); 648 } 649} 650 651 652/* Return the virtual variable associated to the non-scalar variable VAR. */ 653 654tree 655get_virtual_var (tree var) 656{ 657 STRIP_NOPS (var); 658 659 if (TREE_CODE (var) == SSA_NAME) 660 var = SSA_NAME_VAR (var); 661 662 while (TREE_CODE (var) == REALPART_EXPR || TREE_CODE (var) == IMAGPART_EXPR 663 || handled_component_p (var)) 664 var = TREE_OPERAND (var, 0); 665 666 /* Treating GIMPLE registers as virtual variables makes no sense. 667 Also complain if we couldn't extract a _DECL out of the original 668 expression. */ 669 gcc_assert (SSA_VAR_P (var)); 670 gcc_assert (!is_gimple_reg (var)); 671 672 return var; 673} 674 675/* Add a temporary variable to REFERENCED_VARS. This is similar to 676 add_referenced_var, but is used by passes that need to add new temps to 677 the REFERENCED_VARS array after the program has been scanned for 678 variables. The variable will just receive a new UID and be added 679 to the REFERENCED_VARS array without checking for duplicates. */ 680 681void 682add_referenced_tmp_var (tree var) 683{ 684 add_referenced_var (var, true); 685} 686 687 688/* Mark all the non-SSA variables found in STMT's operands to be 689 processed by update_ssa. */ 690 691void 692mark_new_vars_to_rename (tree stmt) 693{ 694 ssa_op_iter iter; 695 tree val; 696 bitmap vars_in_vops_to_rename; 697 bool found_exposed_symbol = false; 698 int v_may_defs_before, v_may_defs_after; 699 int v_must_defs_before, v_must_defs_after; 700 701 if (TREE_CODE (stmt) == PHI_NODE) 702 return; 703 704 vars_in_vops_to_rename = BITMAP_ALLOC (NULL); 705 706 /* Before re-scanning the statement for operands, mark the existing 707 virtual operands to be renamed again. We do this because when new 708 symbols are exposed, the virtual operands that were here before due to 709 aliasing will probably be removed by the call to get_stmt_operand. 710 Therefore, we need to flag them to be renamed beforehand. 711 712 We flag them in a separate bitmap because we don't really want to 713 rename them if there are not any newly exposed symbols in the 714 statement operands. */ 715 v_may_defs_before = NUM_SSA_OPERANDS (stmt, SSA_OP_VMAYDEF); 716 v_must_defs_before = NUM_SSA_OPERANDS (stmt, SSA_OP_VMUSTDEF); 717 718 FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, 719 SSA_OP_VMAYDEF | SSA_OP_VUSE | SSA_OP_VMUSTDEF) 720 { 721 if (!DECL_P (val)) 722 val = SSA_NAME_VAR (val); 723 bitmap_set_bit (vars_in_vops_to_rename, DECL_UID (val)); 724 } 725 726 /* Now force an operand re-scan on the statement and mark any newly 727 exposed variables. */ 728 update_stmt (stmt); 729 730 v_may_defs_after = NUM_SSA_OPERANDS (stmt, SSA_OP_VMAYDEF); 731 v_must_defs_after = NUM_SSA_OPERANDS (stmt, SSA_OP_VMUSTDEF); 732 733 FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, SSA_OP_ALL_OPERANDS) 734 if (DECL_P (val)) 735 { 736 found_exposed_symbol = true; 737 mark_sym_for_renaming (val); 738 } 739 740 /* If we found any newly exposed symbols, or if there are fewer VDEF 741 operands in the statement, add the variables we had set in 742 VARS_IN_VOPS_TO_RENAME to VARS_TO_RENAME. We need to check for 743 vanishing VDEFs because in those cases, the names that were formerly 744 generated by this statement are not going to be available anymore. */ 745 if (found_exposed_symbol 746 || v_may_defs_before > v_may_defs_after 747 || v_must_defs_before > v_must_defs_after) 748 mark_set_for_renaming (vars_in_vops_to_rename); 749 750 BITMAP_FREE (vars_in_vops_to_rename); 751} 752 753/* Find all variables within the gimplified statement that were not previously 754 visible to the function and add them to the referenced variables list. */ 755 756static tree 757find_new_referenced_vars_1 (tree *tp, int *walk_subtrees, 758 void *data ATTRIBUTE_UNUSED) 759{ 760 tree t = *tp; 761 762 if (TREE_CODE (t) == VAR_DECL && !var_ann (t)) 763 { 764 add_referenced_tmp_var (t); 765 mark_sym_for_renaming (t); 766 } 767 768 if (IS_TYPE_OR_DECL_P (t)) 769 *walk_subtrees = 0; 770 771 return NULL; 772} 773 774void 775find_new_referenced_vars (tree *stmt_p) 776{ 777 walk_tree (stmt_p, find_new_referenced_vars_1, NULL, NULL); 778} 779 780 781/* If REF is a COMPONENT_REF for a structure that can have sub-variables, and 782 we know where REF is accessing, return the variable in REF that has the 783 sub-variables. If the return value is not NULL, POFFSET will be the 784 offset, in bits, of REF inside the return value, and PSIZE will be the 785 size, in bits, of REF inside the return value. */ 786 787tree 788okay_component_ref_for_subvars (tree ref, unsigned HOST_WIDE_INT *poffset, 789 unsigned HOST_WIDE_INT *psize) 790{ 791 tree result = NULL; 792 HOST_WIDE_INT bitsize; 793 HOST_WIDE_INT bitpos; 794 tree offset; 795 enum machine_mode mode; 796 int unsignedp; 797 int volatilep; 798 799 gcc_assert (!SSA_VAR_P (ref)); 800 *poffset = 0; 801 *psize = (unsigned int) -1; 802 803 if (ref_contains_array_ref (ref)) 804 return result; 805 ref = get_inner_reference (ref, &bitsize, &bitpos, &offset, &mode, 806 &unsignedp, &volatilep, false); 807 if (TREE_CODE (ref) == INDIRECT_REF) 808 return result; 809 else if (offset == NULL && bitsize != -1 && SSA_VAR_P (ref)) 810 { 811 *poffset = bitpos; 812 *psize = bitsize; 813 if (get_subvars_for_var (ref) != NULL) 814 return ref; 815 } 816 else if (SSA_VAR_P (ref)) 817 { 818 if (get_subvars_for_var (ref) != NULL) 819 return ref; 820 } 821 return NULL_TREE; 822} 823