1 /* Scalar Replacement of Aggregates (SRA) converts some structure 2 references into scalar references, exposing them to the scalar 3 optimizers. 4 Copyright (C) 2008-2018 Free Software Foundation, Inc. 5 Contributed by Martin Jambor <mjambor@suse.cz> 6 7 This file is part of GCC. 8 9 GCC is free software; you can redistribute it and/or modify it under 10 the terms of the GNU General Public License as published by the Free 11 Software Foundation; either version 3, or (at your option) any later 12 version. 13 14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 15 WARRANTY; without even the implied warranty of MERCHANTABILITY or 16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17 for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with GCC; see the file COPYING3. If not see 21 <http://www.gnu.org/licenses/>. */ 22 23 /* This file implements Scalar Reduction of Aggregates (SRA). SRA is run 24 twice, once in the early stages of compilation (early SRA) and once in the 25 late stages (late SRA). The aim of both is to turn references to scalar 26 parts of aggregates into uses of independent scalar variables. 27 28 The two passes are nearly identical, the only difference is that early SRA 29 does not scalarize unions which are used as the result in a GIMPLE_RETURN 30 statement because together with inlining this can lead to weird type 31 conversions. 32 33 Both passes operate in four stages: 34 35 1. The declarations that have properties which make them candidates for 36 scalarization are identified in function find_var_candidates(). The 37 candidates are stored in candidate_bitmap. 38 39 2. The function body is scanned. In the process, declarations which are 40 used in a manner that prevent their scalarization are removed from the 41 candidate bitmap. More importantly, for every access into an aggregate, 42 an access structure (struct access) is created by create_access() and 43 stored in a vector associated with the aggregate. Among other 44 information, the aggregate declaration, the offset and size of the access 45 and its type are stored in the structure. 46 47 On a related note, assign_link structures are created for every assign 48 statement between candidate aggregates and attached to the related 49 accesses. 50 51 3. The vectors of accesses are analyzed. They are first sorted according to 52 their offset and size and then scanned for partially overlapping accesses 53 (i.e. those which overlap but one is not entirely within another). Such 54 an access disqualifies the whole aggregate from being scalarized. 55 56 If there is no such inhibiting overlap, a representative access structure 57 is chosen for every unique combination of offset and size. Afterwards, 58 the pass builds a set of trees from these structures, in which children 59 of an access are within their parent (in terms of offset and size). 60 61 Then accesses are propagated whenever possible (i.e. in cases when it 62 does not create a partially overlapping access) across assign_links from 63 the right hand side to the left hand side. 64 65 Then the set of trees for each declaration is traversed again and those 66 accesses which should be replaced by a scalar are identified. 67 68 4. The function is traversed again, and for every reference into an 69 aggregate that has some component which is about to be scalarized, 70 statements are amended and new statements are created as necessary. 71 Finally, if a parameter got scalarized, the scalar replacements are 72 initialized with values from respective parameter aggregates. */ 73 74 #include "config.h" 75 #include "system.h" 76 #include "coretypes.h" 77 #include "backend.h" 78 #include "target.h" 79 #include "rtl.h" 80 #include "tree.h" 81 #include "gimple.h" 82 #include "predict.h" 83 #include "alloc-pool.h" 84 #include "tree-pass.h" 85 #include "ssa.h" 86 #include "cgraph.h" 87 #include "gimple-pretty-print.h" 88 #include "alias.h" 89 #include "fold-const.h" 90 #include "tree-eh.h" 91 #include "stor-layout.h" 92 #include "gimplify.h" 93 #include "gimple-iterator.h" 94 #include "gimplify-me.h" 95 #include "gimple-walk.h" 96 #include "tree-cfg.h" 97 #include "tree-dfa.h" 98 #include "tree-ssa.h" 99 #include "symbol-summary.h" 100 #include "ipa-param-manipulation.h" 101 #include "ipa-prop.h" 102 #include "params.h" 103 #include "dbgcnt.h" 104 #include "tree-inline.h" 105 #include "ipa-fnsummary.h" 106 #include "ipa-utils.h" 107 #include "builtins.h" 108 109 /* Enumeration of all aggregate reductions we can do. */ 110 enum sra_mode { SRA_MODE_EARLY_IPA, /* early call regularization */ 111 SRA_MODE_EARLY_INTRA, /* early intraprocedural SRA */ 112 SRA_MODE_INTRA }; /* late intraprocedural SRA */ 113 114 /* Global variable describing which aggregate reduction we are performing at 115 the moment. */ 116 static enum sra_mode sra_mode; 117 118 struct assign_link; 119 120 /* ACCESS represents each access to an aggregate variable (as a whole or a 121 part). It can also represent a group of accesses that refer to exactly the 122 same fragment of an aggregate (i.e. those that have exactly the same offset 123 and size). Such representatives for a single aggregate, once determined, 124 are linked in a linked list and have the group fields set. 125 126 Moreover, when doing intraprocedural SRA, a tree is built from those 127 representatives (by the means of first_child and next_sibling pointers), in 128 which all items in a subtree are "within" the root, i.e. their offset is 129 greater or equal to offset of the root and offset+size is smaller or equal 130 to offset+size of the root. Children of an access are sorted by offset. 131 132 Note that accesses to parts of vector and complex number types always 133 represented by an access to the whole complex number or a vector. It is a 134 duty of the modifying functions to replace them appropriately. */ 135 136 struct access 137 { 138 /* Values returned by `get_ref_base_and_extent' for each component reference 139 If EXPR isn't a component reference just set `BASE = EXPR', `OFFSET = 0', 140 `SIZE = TREE_SIZE (TREE_TYPE (expr))'. */ 141 HOST_WIDE_INT offset; 142 HOST_WIDE_INT size; 143 tree base; 144 145 /* Expression. It is context dependent so do not use it to create new 146 expressions to access the original aggregate. See PR 42154 for a 147 testcase. */ 148 tree expr; 149 /* Type. */ 150 tree type; 151 152 /* The statement this access belongs to. */ 153 gimple *stmt; 154 155 /* Next group representative for this aggregate. */ 156 struct access *next_grp; 157 158 /* Pointer to the group representative. Pointer to itself if the struct is 159 the representative. */ 160 struct access *group_representative; 161 162 /* After access tree has been constructed, this points to the parent of the 163 current access, if there is one. NULL for roots. */ 164 struct access *parent; 165 166 /* If this access has any children (in terms of the definition above), this 167 points to the first one. */ 168 struct access *first_child; 169 170 /* In intraprocedural SRA, pointer to the next sibling in the access tree as 171 described above. In IPA-SRA this is a pointer to the next access 172 belonging to the same group (having the same representative). */ 173 struct access *next_sibling; 174 175 /* Pointers to the first and last element in the linked list of assign 176 links. */ 177 struct assign_link *first_link, *last_link; 178 179 /* Pointer to the next access in the work queue. */ 180 struct access *next_queued; 181 182 /* Replacement variable for this access "region." Never to be accessed 183 directly, always only by the means of get_access_replacement() and only 184 when grp_to_be_replaced flag is set. */ 185 tree replacement_decl; 186 187 /* Is this access an access to a non-addressable field? */ 188 unsigned non_addressable : 1; 189 190 /* Is this access made in reverse storage order? */ 191 unsigned reverse : 1; 192 193 /* Is this particular access write access? */ 194 unsigned write : 1; 195 196 /* Is this access currently in the work queue? */ 197 unsigned grp_queued : 1; 198 199 /* Does this group contain a write access? This flag is propagated down the 200 access tree. */ 201 unsigned grp_write : 1; 202 203 /* Does this group contain a read access? This flag is propagated down the 204 access tree. */ 205 unsigned grp_read : 1; 206 207 /* Does this group contain a read access that comes from an assignment 208 statement? This flag is propagated down the access tree. */ 209 unsigned grp_assignment_read : 1; 210 211 /* Does this group contain a write access that comes from an assignment 212 statement? This flag is propagated down the access tree. */ 213 unsigned grp_assignment_write : 1; 214 215 /* Does this group contain a read access through a scalar type? This flag is 216 not propagated in the access tree in any direction. */ 217 unsigned grp_scalar_read : 1; 218 219 /* Does this group contain a write access through a scalar type? This flag 220 is not propagated in the access tree in any direction. */ 221 unsigned grp_scalar_write : 1; 222 223 /* Is this access an artificial one created to scalarize some record 224 entirely? */ 225 unsigned grp_total_scalarization : 1; 226 227 /* Other passes of the analysis use this bit to make function 228 analyze_access_subtree create scalar replacements for this group if 229 possible. */ 230 unsigned grp_hint : 1; 231 232 /* Is the subtree rooted in this access fully covered by scalar 233 replacements? */ 234 unsigned grp_covered : 1; 235 236 /* If set to true, this access and all below it in an access tree must not be 237 scalarized. */ 238 unsigned grp_unscalarizable_region : 1; 239 240 /* Whether data have been written to parts of the aggregate covered by this 241 access which is not to be scalarized. This flag is propagated up in the 242 access tree. */ 243 unsigned grp_unscalarized_data : 1; 244 245 /* Does this access and/or group contain a write access through a 246 BIT_FIELD_REF? */ 247 unsigned grp_partial_lhs : 1; 248 249 /* Set when a scalar replacement should be created for this variable. */ 250 unsigned grp_to_be_replaced : 1; 251 252 /* Set when we want a replacement for the sole purpose of having it in 253 generated debug statements. */ 254 unsigned grp_to_be_debug_replaced : 1; 255 256 /* Should TREE_NO_WARNING of a replacement be set? */ 257 unsigned grp_no_warning : 1; 258 259 /* Is it possible that the group refers to data which might be (directly or 260 otherwise) modified? */ 261 unsigned grp_maybe_modified : 1; 262 263 /* Set when this is a representative of a pointer to scalar (i.e. by 264 reference) parameter which we consider for turning into a plain scalar 265 (i.e. a by value parameter). */ 266 unsigned grp_scalar_ptr : 1; 267 268 /* Set when we discover that this pointer is not safe to dereference in the 269 caller. */ 270 unsigned grp_not_necessarilly_dereferenced : 1; 271 }; 272 273 typedef struct access *access_p; 274 275 276 /* Alloc pool for allocating access structures. */ 277 static object_allocator<struct access> access_pool ("SRA accesses"); 278 279 /* A structure linking lhs and rhs accesses from an aggregate assignment. They 280 are used to propagate subaccesses from rhs to lhs as long as they don't 281 conflict with what is already there. */ 282 struct assign_link 283 { 284 struct access *lacc, *racc; 285 struct assign_link *next; 286 }; 287 288 /* Alloc pool for allocating assign link structures. */ 289 static object_allocator<assign_link> assign_link_pool ("SRA links"); 290 291 /* Base (tree) -> Vector (vec<access_p> *) map. */ 292 static hash_map<tree, auto_vec<access_p> > *base_access_vec; 293 294 /* Candidate hash table helpers. */ 295 296 struct uid_decl_hasher : nofree_ptr_hash <tree_node> 297 { 298 static inline hashval_t hash (const tree_node *); 299 static inline bool equal (const tree_node *, const tree_node *); 300 }; 301 302 /* Hash a tree in a uid_decl_map. */ 303 304 inline hashval_t 305 uid_decl_hasher::hash (const tree_node *item) 306 { 307 return item->decl_minimal.uid; 308 } 309 310 /* Return true if the DECL_UID in both trees are equal. */ 311 312 inline bool 313 uid_decl_hasher::equal (const tree_node *a, const tree_node *b) 314 { 315 return (a->decl_minimal.uid == b->decl_minimal.uid); 316 } 317 318 /* Set of candidates. */ 319 static bitmap candidate_bitmap; 320 static hash_table<uid_decl_hasher> *candidates; 321 322 /* For a candidate UID return the candidates decl. */ 323 324 static inline tree 325 candidate (unsigned uid) 326 { 327 tree_node t; 328 t.decl_minimal.uid = uid; 329 return candidates->find_with_hash (&t, static_cast <hashval_t> (uid)); 330 } 331 332 /* Bitmap of candidates which we should try to entirely scalarize away and 333 those which cannot be (because they are and need be used as a whole). */ 334 static bitmap should_scalarize_away_bitmap, cannot_scalarize_away_bitmap; 335 336 /* Bitmap of candidates in the constant pool, which cannot be scalarized 337 because this would produce non-constant expressions (e.g. Ada). */ 338 static bitmap disqualified_constants; 339 340 /* Obstack for creation of fancy names. */ 341 static struct obstack name_obstack; 342 343 /* Head of a linked list of accesses that need to have its subaccesses 344 propagated to their assignment counterparts. */ 345 static struct access *work_queue_head; 346 347 /* Number of parameters of the analyzed function when doing early ipa SRA. */ 348 static int func_param_count; 349 350 /* scan_function sets the following to true if it encounters a call to 351 __builtin_apply_args. */ 352 static bool encountered_apply_args; 353 354 /* Set by scan_function when it finds a recursive call. */ 355 static bool encountered_recursive_call; 356 357 /* Set by scan_function when it finds a recursive call with less actual 358 arguments than formal parameters.. */ 359 static bool encountered_unchangable_recursive_call; 360 361 /* This is a table in which for each basic block and parameter there is a 362 distance (offset + size) in that parameter which is dereferenced and 363 accessed in that BB. */ 364 static HOST_WIDE_INT *bb_dereferences; 365 /* Bitmap of BBs that can cause the function to "stop" progressing by 366 returning, throwing externally, looping infinitely or calling a function 367 which might abort etc.. */ 368 static bitmap final_bbs; 369 370 /* Representative of no accesses at all. */ 371 static struct access no_accesses_representant; 372 373 /* Predicate to test the special value. */ 374 375 static inline bool 376 no_accesses_p (struct access *access) 377 { 378 return access == &no_accesses_representant; 379 } 380 381 /* Dump contents of ACCESS to file F in a human friendly way. If GRP is true, 382 representative fields are dumped, otherwise those which only describe the 383 individual access are. */ 384 385 static struct 386 { 387 /* Number of processed aggregates is readily available in 388 analyze_all_variable_accesses and so is not stored here. */ 389 390 /* Number of created scalar replacements. */ 391 int replacements; 392 393 /* Number of times sra_modify_expr or sra_modify_assign themselves changed an 394 expression. */ 395 int exprs; 396 397 /* Number of statements created by generate_subtree_copies. */ 398 int subtree_copies; 399 400 /* Number of statements created by load_assign_lhs_subreplacements. */ 401 int subreplacements; 402 403 /* Number of times sra_modify_assign has deleted a statement. */ 404 int deleted; 405 406 /* Number of times sra_modify_assign has to deal with subaccesses of LHS and 407 RHS reparately due to type conversions or nonexistent matching 408 references. */ 409 int separate_lhs_rhs_handling; 410 411 /* Number of parameters that were removed because they were unused. */ 412 int deleted_unused_parameters; 413 414 /* Number of scalars passed as parameters by reference that have been 415 converted to be passed by value. */ 416 int scalar_by_ref_to_by_val; 417 418 /* Number of aggregate parameters that were replaced by one or more of their 419 components. */ 420 int aggregate_params_reduced; 421 422 /* Numbber of components created when splitting aggregate parameters. */ 423 int param_reductions_created; 424 } sra_stats; 425 426 static void 427 dump_access (FILE *f, struct access *access, bool grp) 428 { 429 fprintf (f, "access { "); 430 fprintf (f, "base = (%d)'", DECL_UID (access->base)); 431 print_generic_expr (f, access->base); 432 fprintf (f, "', offset = " HOST_WIDE_INT_PRINT_DEC, access->offset); 433 fprintf (f, ", size = " HOST_WIDE_INT_PRINT_DEC, access->size); 434 fprintf (f, ", expr = "); 435 print_generic_expr (f, access->expr); 436 fprintf (f, ", type = "); 437 print_generic_expr (f, access->type); 438 fprintf (f, ", non_addressable = %d, reverse = %d", 439 access->non_addressable, access->reverse); 440 if (grp) 441 fprintf (f, ", grp_read = %d, grp_write = %d, grp_assignment_read = %d, " 442 "grp_assignment_write = %d, grp_scalar_read = %d, " 443 "grp_scalar_write = %d, grp_total_scalarization = %d, " 444 "grp_hint = %d, grp_covered = %d, " 445 "grp_unscalarizable_region = %d, grp_unscalarized_data = %d, " 446 "grp_partial_lhs = %d, grp_to_be_replaced = %d, " 447 "grp_to_be_debug_replaced = %d, grp_maybe_modified = %d, " 448 "grp_not_necessarilly_dereferenced = %d\n", 449 access->grp_read, access->grp_write, access->grp_assignment_read, 450 access->grp_assignment_write, access->grp_scalar_read, 451 access->grp_scalar_write, access->grp_total_scalarization, 452 access->grp_hint, access->grp_covered, 453 access->grp_unscalarizable_region, access->grp_unscalarized_data, 454 access->grp_partial_lhs, access->grp_to_be_replaced, 455 access->grp_to_be_debug_replaced, access->grp_maybe_modified, 456 access->grp_not_necessarilly_dereferenced); 457 else 458 fprintf (f, ", write = %d, grp_total_scalarization = %d, " 459 "grp_partial_lhs = %d\n", 460 access->write, access->grp_total_scalarization, 461 access->grp_partial_lhs); 462 } 463 464 /* Dump a subtree rooted in ACCESS to file F, indent by LEVEL. */ 465 466 static void 467 dump_access_tree_1 (FILE *f, struct access *access, int level) 468 { 469 do 470 { 471 int i; 472 473 for (i = 0; i < level; i++) 474 fputs ("* ", f); 475 476 dump_access (f, access, true); 477 478 if (access->first_child) 479 dump_access_tree_1 (f, access->first_child, level + 1); 480 481 access = access->next_sibling; 482 } 483 while (access); 484 } 485 486 /* Dump all access trees for a variable, given the pointer to the first root in 487 ACCESS. */ 488 489 static void 490 dump_access_tree (FILE *f, struct access *access) 491 { 492 for (; access; access = access->next_grp) 493 dump_access_tree_1 (f, access, 0); 494 } 495 496 /* Return true iff ACC is non-NULL and has subaccesses. */ 497 498 static inline bool 499 access_has_children_p (struct access *acc) 500 { 501 return acc && acc->first_child; 502 } 503 504 /* Return true iff ACC is (partly) covered by at least one replacement. */ 505 506 static bool 507 access_has_replacements_p (struct access *acc) 508 { 509 struct access *child; 510 if (acc->grp_to_be_replaced) 511 return true; 512 for (child = acc->first_child; child; child = child->next_sibling) 513 if (access_has_replacements_p (child)) 514 return true; 515 return false; 516 } 517 518 /* Return a vector of pointers to accesses for the variable given in BASE or 519 NULL if there is none. */ 520 521 static vec<access_p> * 522 get_base_access_vector (tree base) 523 { 524 return base_access_vec->get (base); 525 } 526 527 /* Find an access with required OFFSET and SIZE in a subtree of accesses rooted 528 in ACCESS. Return NULL if it cannot be found. */ 529 530 static struct access * 531 find_access_in_subtree (struct access *access, HOST_WIDE_INT offset, 532 HOST_WIDE_INT size) 533 { 534 while (access && (access->offset != offset || access->size != size)) 535 { 536 struct access *child = access->first_child; 537 538 while (child && (child->offset + child->size <= offset)) 539 child = child->next_sibling; 540 access = child; 541 } 542 543 return access; 544 } 545 546 /* Return the first group representative for DECL or NULL if none exists. */ 547 548 static struct access * 549 get_first_repr_for_decl (tree base) 550 { 551 vec<access_p> *access_vec; 552 553 access_vec = get_base_access_vector (base); 554 if (!access_vec) 555 return NULL; 556 557 return (*access_vec)[0]; 558 } 559 560 /* Find an access representative for the variable BASE and given OFFSET and 561 SIZE. Requires that access trees have already been built. Return NULL if 562 it cannot be found. */ 563 564 static struct access * 565 get_var_base_offset_size_access (tree base, HOST_WIDE_INT offset, 566 HOST_WIDE_INT size) 567 { 568 struct access *access; 569 570 access = get_first_repr_for_decl (base); 571 while (access && (access->offset + access->size <= offset)) 572 access = access->next_grp; 573 if (!access) 574 return NULL; 575 576 return find_access_in_subtree (access, offset, size); 577 } 578 579 /* Add LINK to the linked list of assign links of RACC. */ 580 static void 581 add_link_to_rhs (struct access *racc, struct assign_link *link) 582 { 583 gcc_assert (link->racc == racc); 584 585 if (!racc->first_link) 586 { 587 gcc_assert (!racc->last_link); 588 racc->first_link = link; 589 } 590 else 591 racc->last_link->next = link; 592 593 racc->last_link = link; 594 link->next = NULL; 595 } 596 597 /* Move all link structures in their linked list in OLD_RACC to the linked list 598 in NEW_RACC. */ 599 static void 600 relink_to_new_repr (struct access *new_racc, struct access *old_racc) 601 { 602 if (!old_racc->first_link) 603 { 604 gcc_assert (!old_racc->last_link); 605 return; 606 } 607 608 if (new_racc->first_link) 609 { 610 gcc_assert (!new_racc->last_link->next); 611 gcc_assert (!old_racc->last_link || !old_racc->last_link->next); 612 613 new_racc->last_link->next = old_racc->first_link; 614 new_racc->last_link = old_racc->last_link; 615 } 616 else 617 { 618 gcc_assert (!new_racc->last_link); 619 620 new_racc->first_link = old_racc->first_link; 621 new_racc->last_link = old_racc->last_link; 622 } 623 old_racc->first_link = old_racc->last_link = NULL; 624 } 625 626 /* Add ACCESS to the work queue (which is actually a stack). */ 627 628 static void 629 add_access_to_work_queue (struct access *access) 630 { 631 if (access->first_link && !access->grp_queued) 632 { 633 gcc_assert (!access->next_queued); 634 access->next_queued = work_queue_head; 635 access->grp_queued = 1; 636 work_queue_head = access; 637 } 638 } 639 640 /* Pop an access from the work queue, and return it, assuming there is one. */ 641 642 static struct access * 643 pop_access_from_work_queue (void) 644 { 645 struct access *access = work_queue_head; 646 647 work_queue_head = access->next_queued; 648 access->next_queued = NULL; 649 access->grp_queued = 0; 650 return access; 651 } 652 653 654 /* Allocate necessary structures. */ 655 656 static void 657 sra_initialize (void) 658 { 659 candidate_bitmap = BITMAP_ALLOC (NULL); 660 candidates = new hash_table<uid_decl_hasher> 661 (vec_safe_length (cfun->local_decls) / 2); 662 should_scalarize_away_bitmap = BITMAP_ALLOC (NULL); 663 cannot_scalarize_away_bitmap = BITMAP_ALLOC (NULL); 664 disqualified_constants = BITMAP_ALLOC (NULL); 665 gcc_obstack_init (&name_obstack); 666 base_access_vec = new hash_map<tree, auto_vec<access_p> >; 667 memset (&sra_stats, 0, sizeof (sra_stats)); 668 encountered_apply_args = false; 669 encountered_recursive_call = false; 670 encountered_unchangable_recursive_call = false; 671 } 672 673 /* Deallocate all general structures. */ 674 675 static void 676 sra_deinitialize (void) 677 { 678 BITMAP_FREE (candidate_bitmap); 679 delete candidates; 680 candidates = NULL; 681 BITMAP_FREE (should_scalarize_away_bitmap); 682 BITMAP_FREE (cannot_scalarize_away_bitmap); 683 BITMAP_FREE (disqualified_constants); 684 access_pool.release (); 685 assign_link_pool.release (); 686 obstack_free (&name_obstack, NULL); 687 688 delete base_access_vec; 689 } 690 691 /* Return true if DECL is a VAR_DECL in the constant pool, false otherwise. */ 692 693 static bool constant_decl_p (tree decl) 694 { 695 return VAR_P (decl) && DECL_IN_CONSTANT_POOL (decl); 696 } 697 698 /* Remove DECL from candidates for SRA and write REASON to the dump file if 699 there is one. */ 700 701 static void 702 disqualify_candidate (tree decl, const char *reason) 703 { 704 if (bitmap_clear_bit (candidate_bitmap, DECL_UID (decl))) 705 candidates->remove_elt_with_hash (decl, DECL_UID (decl)); 706 if (constant_decl_p (decl)) 707 bitmap_set_bit (disqualified_constants, DECL_UID (decl)); 708 709 if (dump_file && (dump_flags & TDF_DETAILS)) 710 { 711 fprintf (dump_file, "! Disqualifying "); 712 print_generic_expr (dump_file, decl); 713 fprintf (dump_file, " - %s\n", reason); 714 } 715 } 716 717 /* Return true iff the type contains a field or an element which does not allow 718 scalarization. */ 719 720 static bool 721 type_internals_preclude_sra_p (tree type, const char **msg) 722 { 723 tree fld; 724 tree et; 725 726 switch (TREE_CODE (type)) 727 { 728 case RECORD_TYPE: 729 case UNION_TYPE: 730 case QUAL_UNION_TYPE: 731 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld)) 732 if (TREE_CODE (fld) == FIELD_DECL) 733 { 734 tree ft = TREE_TYPE (fld); 735 736 if (TREE_THIS_VOLATILE (fld)) 737 { 738 *msg = "volatile structure field"; 739 return true; 740 } 741 if (!DECL_FIELD_OFFSET (fld)) 742 { 743 *msg = "no structure field offset"; 744 return true; 745 } 746 if (!DECL_SIZE (fld)) 747 { 748 *msg = "zero structure field size"; 749 return true; 750 } 751 if (!tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld))) 752 { 753 *msg = "structure field offset not fixed"; 754 return true; 755 } 756 if (!tree_fits_uhwi_p (DECL_SIZE (fld))) 757 { 758 *msg = "structure field size not fixed"; 759 return true; 760 } 761 if (!tree_fits_shwi_p (bit_position (fld))) 762 { 763 *msg = "structure field size too big"; 764 return true; 765 } 766 if (AGGREGATE_TYPE_P (ft) 767 && int_bit_position (fld) % BITS_PER_UNIT != 0) 768 { 769 *msg = "structure field is bit field"; 770 return true; 771 } 772 773 if (AGGREGATE_TYPE_P (ft) && type_internals_preclude_sra_p (ft, msg)) 774 return true; 775 } 776 777 return false; 778 779 case ARRAY_TYPE: 780 et = TREE_TYPE (type); 781 782 if (TYPE_VOLATILE (et)) 783 { 784 *msg = "element type is volatile"; 785 return true; 786 } 787 788 if (AGGREGATE_TYPE_P (et) && type_internals_preclude_sra_p (et, msg)) 789 return true; 790 791 return false; 792 793 default: 794 return false; 795 } 796 } 797 798 /* If T is an SSA_NAME, return NULL if it is not a default def or return its 799 base variable if it is. Return T if it is not an SSA_NAME. */ 800 801 static tree 802 get_ssa_base_param (tree t) 803 { 804 if (TREE_CODE (t) == SSA_NAME) 805 { 806 if (SSA_NAME_IS_DEFAULT_DEF (t)) 807 return SSA_NAME_VAR (t); 808 else 809 return NULL_TREE; 810 } 811 return t; 812 } 813 814 /* Mark a dereference of BASE of distance DIST in a basic block tht STMT 815 belongs to, unless the BB has already been marked as a potentially 816 final. */ 817 818 static void 819 mark_parm_dereference (tree base, HOST_WIDE_INT dist, gimple *stmt) 820 { 821 basic_block bb = gimple_bb (stmt); 822 int idx, parm_index = 0; 823 tree parm; 824 825 if (bitmap_bit_p (final_bbs, bb->index)) 826 return; 827 828 for (parm = DECL_ARGUMENTS (current_function_decl); 829 parm && parm != base; 830 parm = DECL_CHAIN (parm)) 831 parm_index++; 832 833 gcc_assert (parm_index < func_param_count); 834 835 idx = bb->index * func_param_count + parm_index; 836 if (bb_dereferences[idx] < dist) 837 bb_dereferences[idx] = dist; 838 } 839 840 /* Allocate an access structure for BASE, OFFSET and SIZE, clear it, fill in 841 the three fields. Also add it to the vector of accesses corresponding to 842 the base. Finally, return the new access. */ 843 844 static struct access * 845 create_access_1 (tree base, HOST_WIDE_INT offset, HOST_WIDE_INT size) 846 { 847 struct access *access = access_pool.allocate (); 848 849 memset (access, 0, sizeof (struct access)); 850 access->base = base; 851 access->offset = offset; 852 access->size = size; 853 854 base_access_vec->get_or_insert (base).safe_push (access); 855 856 return access; 857 } 858 859 static bool maybe_add_sra_candidate (tree); 860 861 /* Create and insert access for EXPR. Return created access, or NULL if it is 862 not possible. Also scan for uses of constant pool as we go along and add 863 to candidates. */ 864 865 static struct access * 866 create_access (tree expr, gimple *stmt, bool write) 867 { 868 struct access *access; 869 poly_int64 poffset, psize, pmax_size; 870 HOST_WIDE_INT offset, size, max_size; 871 tree base = expr; 872 bool reverse, ptr, unscalarizable_region = false; 873 874 base = get_ref_base_and_extent (expr, &poffset, &psize, &pmax_size, 875 &reverse); 876 if (!poffset.is_constant (&offset) 877 || !psize.is_constant (&size) 878 || !pmax_size.is_constant (&max_size)) 879 { 880 disqualify_candidate (base, "Encountered a polynomial-sized access."); 881 return NULL; 882 } 883 884 if (sra_mode == SRA_MODE_EARLY_IPA 885 && TREE_CODE (base) == MEM_REF) 886 { 887 base = get_ssa_base_param (TREE_OPERAND (base, 0)); 888 if (!base) 889 return NULL; 890 ptr = true; 891 } 892 else 893 ptr = false; 894 895 /* For constant-pool entries, check we can substitute the constant value. */ 896 if (constant_decl_p (base) 897 && (sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)) 898 { 899 gcc_assert (!bitmap_bit_p (disqualified_constants, DECL_UID (base))); 900 if (expr != base 901 && !is_gimple_reg_type (TREE_TYPE (expr)) 902 && dump_file && (dump_flags & TDF_DETAILS)) 903 { 904 /* This occurs in Ada with accesses to ARRAY_RANGE_REFs, 905 and elements of multidimensional arrays (which are 906 multi-element arrays in their own right). */ 907 fprintf (dump_file, "Allowing non-reg-type load of part" 908 " of constant-pool entry: "); 909 print_generic_expr (dump_file, expr); 910 } 911 maybe_add_sra_candidate (base); 912 } 913 914 if (!DECL_P (base) || !bitmap_bit_p (candidate_bitmap, DECL_UID (base))) 915 return NULL; 916 917 if (sra_mode == SRA_MODE_EARLY_IPA) 918 { 919 if (size < 0 || size != max_size) 920 { 921 disqualify_candidate (base, "Encountered a variable sized access."); 922 return NULL; 923 } 924 if (TREE_CODE (expr) == COMPONENT_REF 925 && DECL_BIT_FIELD (TREE_OPERAND (expr, 1))) 926 { 927 disqualify_candidate (base, "Encountered a bit-field access."); 928 return NULL; 929 } 930 gcc_checking_assert ((offset % BITS_PER_UNIT) == 0); 931 932 if (ptr) 933 mark_parm_dereference (base, offset + size, stmt); 934 } 935 else 936 { 937 if (size != max_size) 938 { 939 size = max_size; 940 unscalarizable_region = true; 941 } 942 if (size < 0) 943 { 944 disqualify_candidate (base, "Encountered an unconstrained access."); 945 return NULL; 946 } 947 } 948 949 access = create_access_1 (base, offset, size); 950 access->expr = expr; 951 access->type = TREE_TYPE (expr); 952 access->write = write; 953 access->grp_unscalarizable_region = unscalarizable_region; 954 access->stmt = stmt; 955 access->reverse = reverse; 956 957 if (TREE_CODE (expr) == COMPONENT_REF 958 && DECL_NONADDRESSABLE_P (TREE_OPERAND (expr, 1))) 959 access->non_addressable = 1; 960 961 return access; 962 } 963 964 965 /* Return true iff TYPE is scalarizable - i.e. a RECORD_TYPE or fixed-length 966 ARRAY_TYPE with fields that are either of gimple register types (excluding 967 bit-fields) or (recursively) scalarizable types. CONST_DECL must be true if 968 we are considering a decl from constant pool. If it is false, char arrays 969 will be refused. */ 970 971 static bool 972 scalarizable_type_p (tree type, bool const_decl) 973 { 974 gcc_assert (!is_gimple_reg_type (type)); 975 if (type_contains_placeholder_p (type)) 976 return false; 977 978 switch (TREE_CODE (type)) 979 { 980 case RECORD_TYPE: 981 for (tree fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld)) 982 if (TREE_CODE (fld) == FIELD_DECL) 983 { 984 tree ft = TREE_TYPE (fld); 985 986 if (DECL_BIT_FIELD (fld)) 987 return false; 988 989 if (!is_gimple_reg_type (ft) 990 && !scalarizable_type_p (ft, const_decl)) 991 return false; 992 } 993 994 return true; 995 996 case ARRAY_TYPE: 997 { 998 HOST_WIDE_INT min_elem_size; 999 if (const_decl) 1000 min_elem_size = 0; 1001 else 1002 min_elem_size = BITS_PER_UNIT; 1003 1004 if (TYPE_DOMAIN (type) == NULL_TREE 1005 || !tree_fits_shwi_p (TYPE_SIZE (type)) 1006 || !tree_fits_shwi_p (TYPE_SIZE (TREE_TYPE (type))) 1007 || (tree_to_shwi (TYPE_SIZE (TREE_TYPE (type))) <= min_elem_size) 1008 || !tree_fits_shwi_p (TYPE_MIN_VALUE (TYPE_DOMAIN (type)))) 1009 return false; 1010 if (tree_to_shwi (TYPE_SIZE (type)) == 0 1011 && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL_TREE) 1012 /* Zero-element array, should not prevent scalarization. */ 1013 ; 1014 else if ((tree_to_shwi (TYPE_SIZE (type)) <= 0) 1015 || !tree_fits_shwi_p (TYPE_MAX_VALUE (TYPE_DOMAIN (type)))) 1016 /* Variable-length array, do not allow scalarization. */ 1017 return false; 1018 1019 tree elem = TREE_TYPE (type); 1020 if (!is_gimple_reg_type (elem) 1021 && !scalarizable_type_p (elem, const_decl)) 1022 return false; 1023 return true; 1024 } 1025 default: 1026 return false; 1027 } 1028 } 1029 1030 static void scalarize_elem (tree, HOST_WIDE_INT, HOST_WIDE_INT, bool, tree, tree); 1031 1032 /* Create total_scalarization accesses for all scalar fields of a member 1033 of type DECL_TYPE conforming to scalarizable_type_p. BASE 1034 must be the top-most VAR_DECL representing the variable; within that, 1035 OFFSET locates the member and REF must be the memory reference expression for 1036 the member. */ 1037 1038 static void 1039 completely_scalarize (tree base, tree decl_type, HOST_WIDE_INT offset, tree ref) 1040 { 1041 switch (TREE_CODE (decl_type)) 1042 { 1043 case RECORD_TYPE: 1044 for (tree fld = TYPE_FIELDS (decl_type); fld; fld = DECL_CHAIN (fld)) 1045 if (TREE_CODE (fld) == FIELD_DECL) 1046 { 1047 HOST_WIDE_INT pos = offset + int_bit_position (fld); 1048 tree ft = TREE_TYPE (fld); 1049 tree nref = build3 (COMPONENT_REF, ft, ref, fld, NULL_TREE); 1050 1051 scalarize_elem (base, pos, tree_to_uhwi (DECL_SIZE (fld)), 1052 TYPE_REVERSE_STORAGE_ORDER (decl_type), 1053 nref, ft); 1054 } 1055 break; 1056 case ARRAY_TYPE: 1057 { 1058 tree elemtype = TREE_TYPE (decl_type); 1059 tree elem_size = TYPE_SIZE (elemtype); 1060 gcc_assert (elem_size && tree_fits_shwi_p (elem_size)); 1061 HOST_WIDE_INT el_size = tree_to_shwi (elem_size); 1062 gcc_assert (el_size > 0); 1063 1064 tree minidx = TYPE_MIN_VALUE (TYPE_DOMAIN (decl_type)); 1065 gcc_assert (TREE_CODE (minidx) == INTEGER_CST); 1066 tree maxidx = TYPE_MAX_VALUE (TYPE_DOMAIN (decl_type)); 1067 /* Skip (some) zero-length arrays; others have MAXIDX == MINIDX - 1. */ 1068 if (maxidx) 1069 { 1070 gcc_assert (TREE_CODE (maxidx) == INTEGER_CST); 1071 tree domain = TYPE_DOMAIN (decl_type); 1072 /* MINIDX and MAXIDX are inclusive, and must be interpreted in 1073 DOMAIN (e.g. signed int, whereas min/max may be size_int). */ 1074 offset_int idx = wi::to_offset (minidx); 1075 offset_int max = wi::to_offset (maxidx); 1076 if (!TYPE_UNSIGNED (domain)) 1077 { 1078 idx = wi::sext (idx, TYPE_PRECISION (domain)); 1079 max = wi::sext (max, TYPE_PRECISION (domain)); 1080 } 1081 for (int el_off = offset; idx <= max; ++idx) 1082 { 1083 tree nref = build4 (ARRAY_REF, elemtype, 1084 ref, 1085 wide_int_to_tree (domain, idx), 1086 NULL_TREE, NULL_TREE); 1087 scalarize_elem (base, el_off, el_size, 1088 TYPE_REVERSE_STORAGE_ORDER (decl_type), 1089 nref, elemtype); 1090 el_off += el_size; 1091 } 1092 } 1093 } 1094 break; 1095 default: 1096 gcc_unreachable (); 1097 } 1098 } 1099 1100 /* Create total_scalarization accesses for a member of type TYPE, which must 1101 satisfy either is_gimple_reg_type or scalarizable_type_p. BASE must be the 1102 top-most VAR_DECL representing the variable; within that, POS and SIZE locate 1103 the member, REVERSE gives its torage order. and REF must be the reference 1104 expression for it. */ 1105 1106 static void 1107 scalarize_elem (tree base, HOST_WIDE_INT pos, HOST_WIDE_INT size, bool reverse, 1108 tree ref, tree type) 1109 { 1110 if (is_gimple_reg_type (type)) 1111 { 1112 struct access *access = create_access_1 (base, pos, size); 1113 access->expr = ref; 1114 access->type = type; 1115 access->grp_total_scalarization = 1; 1116 access->reverse = reverse; 1117 /* Accesses for intraprocedural SRA can have their stmt NULL. */ 1118 } 1119 else 1120 completely_scalarize (base, type, pos, ref); 1121 } 1122 1123 /* Create a total_scalarization access for VAR as a whole. VAR must be of a 1124 RECORD_TYPE or ARRAY_TYPE conforming to scalarizable_type_p. */ 1125 1126 static void 1127 create_total_scalarization_access (tree var) 1128 { 1129 HOST_WIDE_INT size = tree_to_uhwi (DECL_SIZE (var)); 1130 struct access *access; 1131 1132 access = create_access_1 (var, 0, size); 1133 access->expr = var; 1134 access->type = TREE_TYPE (var); 1135 access->grp_total_scalarization = 1; 1136 } 1137 1138 /* Return true if REF has an VIEW_CONVERT_EXPR somewhere in it. */ 1139 1140 static inline bool 1141 contains_view_convert_expr_p (const_tree ref) 1142 { 1143 while (handled_component_p (ref)) 1144 { 1145 if (TREE_CODE (ref) == VIEW_CONVERT_EXPR) 1146 return true; 1147 ref = TREE_OPERAND (ref, 0); 1148 } 1149 1150 return false; 1151 } 1152 1153 /* Return true if REF contains a VIEW_CONVERT_EXPR or a COMPONENT_REF with a 1154 bit-field field declaration. If TYPE_CHANGING_P is non-NULL, set the bool 1155 it points to will be set if REF contains any of the above or a MEM_REF 1156 expression that effectively performs type conversion. */ 1157 1158 static bool 1159 contains_vce_or_bfcref_p (const_tree ref, bool *type_changing_p = NULL) 1160 { 1161 while (handled_component_p (ref)) 1162 { 1163 if (TREE_CODE (ref) == VIEW_CONVERT_EXPR 1164 || (TREE_CODE (ref) == COMPONENT_REF 1165 && DECL_BIT_FIELD (TREE_OPERAND (ref, 1)))) 1166 { 1167 if (type_changing_p) 1168 *type_changing_p = true; 1169 return true; 1170 } 1171 ref = TREE_OPERAND (ref, 0); 1172 } 1173 1174 if (!type_changing_p 1175 || TREE_CODE (ref) != MEM_REF 1176 || TREE_CODE (TREE_OPERAND (ref, 0)) != ADDR_EXPR) 1177 return false; 1178 1179 tree mem = TREE_OPERAND (TREE_OPERAND (ref, 0), 0); 1180 if (TYPE_MAIN_VARIANT (TREE_TYPE (ref)) 1181 != TYPE_MAIN_VARIANT (TREE_TYPE (mem))) 1182 *type_changing_p = true; 1183 1184 return false; 1185 } 1186 1187 /* Search the given tree for a declaration by skipping handled components and 1188 exclude it from the candidates. */ 1189 1190 static void 1191 disqualify_base_of_expr (tree t, const char *reason) 1192 { 1193 t = get_base_address (t); 1194 if (sra_mode == SRA_MODE_EARLY_IPA 1195 && TREE_CODE (t) == MEM_REF) 1196 t = get_ssa_base_param (TREE_OPERAND (t, 0)); 1197 1198 if (t && DECL_P (t)) 1199 disqualify_candidate (t, reason); 1200 } 1201 1202 /* Scan expression EXPR and create access structures for all accesses to 1203 candidates for scalarization. Return the created access or NULL if none is 1204 created. */ 1205 1206 static struct access * 1207 build_access_from_expr_1 (tree expr, gimple *stmt, bool write) 1208 { 1209 struct access *ret = NULL; 1210 bool partial_ref; 1211 1212 if (TREE_CODE (expr) == BIT_FIELD_REF 1213 || TREE_CODE (expr) == IMAGPART_EXPR 1214 || TREE_CODE (expr) == REALPART_EXPR) 1215 { 1216 expr = TREE_OPERAND (expr, 0); 1217 partial_ref = true; 1218 } 1219 else 1220 partial_ref = false; 1221 1222 if (storage_order_barrier_p (expr)) 1223 { 1224 disqualify_base_of_expr (expr, "storage order barrier."); 1225 return NULL; 1226 } 1227 1228 /* We need to dive through V_C_Es in order to get the size of its parameter 1229 and not the result type. Ada produces such statements. We are also 1230 capable of handling the topmost V_C_E but not any of those buried in other 1231 handled components. */ 1232 if (TREE_CODE (expr) == VIEW_CONVERT_EXPR) 1233 expr = TREE_OPERAND (expr, 0); 1234 1235 if (contains_view_convert_expr_p (expr)) 1236 { 1237 disqualify_base_of_expr (expr, "V_C_E under a different handled " 1238 "component."); 1239 return NULL; 1240 } 1241 if (TREE_THIS_VOLATILE (expr)) 1242 { 1243 disqualify_base_of_expr (expr, "part of a volatile reference."); 1244 return NULL; 1245 } 1246 1247 switch (TREE_CODE (expr)) 1248 { 1249 case MEM_REF: 1250 if (TREE_CODE (TREE_OPERAND (expr, 0)) != ADDR_EXPR 1251 && sra_mode != SRA_MODE_EARLY_IPA) 1252 return NULL; 1253 /* fall through */ 1254 case VAR_DECL: 1255 case PARM_DECL: 1256 case RESULT_DECL: 1257 case COMPONENT_REF: 1258 case ARRAY_REF: 1259 case ARRAY_RANGE_REF: 1260 ret = create_access (expr, stmt, write); 1261 break; 1262 1263 default: 1264 break; 1265 } 1266 1267 if (write && partial_ref && ret) 1268 ret->grp_partial_lhs = 1; 1269 1270 return ret; 1271 } 1272 1273 /* Scan expression EXPR and create access structures for all accesses to 1274 candidates for scalarization. Return true if any access has been inserted. 1275 STMT must be the statement from which the expression is taken, WRITE must be 1276 true if the expression is a store and false otherwise. */ 1277 1278 static bool 1279 build_access_from_expr (tree expr, gimple *stmt, bool write) 1280 { 1281 struct access *access; 1282 1283 access = build_access_from_expr_1 (expr, stmt, write); 1284 if (access) 1285 { 1286 /* This means the aggregate is accesses as a whole in a way other than an 1287 assign statement and thus cannot be removed even if we had a scalar 1288 replacement for everything. */ 1289 if (cannot_scalarize_away_bitmap) 1290 bitmap_set_bit (cannot_scalarize_away_bitmap, DECL_UID (access->base)); 1291 return true; 1292 } 1293 return false; 1294 } 1295 1296 /* Return the single non-EH successor edge of BB or NULL if there is none or 1297 more than one. */ 1298 1299 static edge 1300 single_non_eh_succ (basic_block bb) 1301 { 1302 edge e, res = NULL; 1303 edge_iterator ei; 1304 1305 FOR_EACH_EDGE (e, ei, bb->succs) 1306 if (!(e->flags & EDGE_EH)) 1307 { 1308 if (res) 1309 return NULL; 1310 res = e; 1311 } 1312 1313 return res; 1314 } 1315 1316 /* Disqualify LHS and RHS for scalarization if STMT has to terminate its BB and 1317 there is no alternative spot where to put statements SRA might need to 1318 generate after it. The spot we are looking for is an edge leading to a 1319 single non-EH successor, if it exists and is indeed single. RHS may be 1320 NULL, in that case ignore it. */ 1321 1322 static bool 1323 disqualify_if_bad_bb_terminating_stmt (gimple *stmt, tree lhs, tree rhs) 1324 { 1325 if ((sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA) 1326 && stmt_ends_bb_p (stmt)) 1327 { 1328 if (single_non_eh_succ (gimple_bb (stmt))) 1329 return false; 1330 1331 disqualify_base_of_expr (lhs, "LHS of a throwing stmt."); 1332 if (rhs) 1333 disqualify_base_of_expr (rhs, "RHS of a throwing stmt."); 1334 return true; 1335 } 1336 return false; 1337 } 1338 1339 /* Return true if the nature of BASE is such that it contains data even if 1340 there is no write to it in the function. */ 1341 1342 static bool 1343 comes_initialized_p (tree base) 1344 { 1345 return TREE_CODE (base) == PARM_DECL || constant_decl_p (base); 1346 } 1347 1348 /* Scan expressions occurring in STMT, create access structures for all accesses 1349 to candidates for scalarization and remove those candidates which occur in 1350 statements or expressions that prevent them from being split apart. Return 1351 true if any access has been inserted. */ 1352 1353 static bool 1354 build_accesses_from_assign (gimple *stmt) 1355 { 1356 tree lhs, rhs; 1357 struct access *lacc, *racc; 1358 1359 if (!gimple_assign_single_p (stmt) 1360 /* Scope clobbers don't influence scalarization. */ 1361 || gimple_clobber_p (stmt)) 1362 return false; 1363 1364 lhs = gimple_assign_lhs (stmt); 1365 rhs = gimple_assign_rhs1 (stmt); 1366 1367 if (disqualify_if_bad_bb_terminating_stmt (stmt, lhs, rhs)) 1368 return false; 1369 1370 racc = build_access_from_expr_1 (rhs, stmt, false); 1371 lacc = build_access_from_expr_1 (lhs, stmt, true); 1372 1373 if (lacc) 1374 { 1375 lacc->grp_assignment_write = 1; 1376 if (storage_order_barrier_p (rhs)) 1377 lacc->grp_unscalarizable_region = 1; 1378 1379 if (should_scalarize_away_bitmap && !is_gimple_reg_type (lacc->type)) 1380 { 1381 bool type_changing_p = false; 1382 contains_vce_or_bfcref_p (lhs, &type_changing_p); 1383 if (type_changing_p) 1384 bitmap_set_bit (cannot_scalarize_away_bitmap, 1385 DECL_UID (lacc->base)); 1386 } 1387 } 1388 1389 if (racc) 1390 { 1391 racc->grp_assignment_read = 1; 1392 if (should_scalarize_away_bitmap && !is_gimple_reg_type (racc->type)) 1393 { 1394 bool type_changing_p = false; 1395 contains_vce_or_bfcref_p (rhs, &type_changing_p); 1396 1397 if (type_changing_p || gimple_has_volatile_ops (stmt)) 1398 bitmap_set_bit (cannot_scalarize_away_bitmap, 1399 DECL_UID (racc->base)); 1400 else 1401 bitmap_set_bit (should_scalarize_away_bitmap, 1402 DECL_UID (racc->base)); 1403 } 1404 if (storage_order_barrier_p (lhs)) 1405 racc->grp_unscalarizable_region = 1; 1406 } 1407 1408 if (lacc && racc 1409 && (sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA) 1410 && !lacc->grp_unscalarizable_region 1411 && !racc->grp_unscalarizable_region 1412 && AGGREGATE_TYPE_P (TREE_TYPE (lhs)) 1413 && lacc->size == racc->size 1414 && useless_type_conversion_p (lacc->type, racc->type)) 1415 { 1416 struct assign_link *link; 1417 1418 link = assign_link_pool.allocate (); 1419 memset (link, 0, sizeof (struct assign_link)); 1420 1421 link->lacc = lacc; 1422 link->racc = racc; 1423 add_link_to_rhs (racc, link); 1424 add_access_to_work_queue (racc); 1425 1426 /* Let's delay marking the areas as written until propagation of accesses 1427 across link, unless the nature of rhs tells us that its data comes 1428 from elsewhere. */ 1429 if (!comes_initialized_p (racc->base)) 1430 lacc->write = false; 1431 } 1432 1433 return lacc || racc; 1434 } 1435 1436 /* Callback of walk_stmt_load_store_addr_ops visit_addr used to determine 1437 GIMPLE_ASM operands with memory constrains which cannot be scalarized. */ 1438 1439 static bool 1440 asm_visit_addr (gimple *, tree op, tree, void *) 1441 { 1442 op = get_base_address (op); 1443 if (op 1444 && DECL_P (op)) 1445 disqualify_candidate (op, "Non-scalarizable GIMPLE_ASM operand."); 1446 1447 return false; 1448 } 1449 1450 /* Return true iff callsite CALL has at least as many actual arguments as there 1451 are formal parameters of the function currently processed by IPA-SRA and 1452 that their types match. */ 1453 1454 static inline bool 1455 callsite_arguments_match_p (gimple *call) 1456 { 1457 if (gimple_call_num_args (call) < (unsigned) func_param_count) 1458 return false; 1459 1460 tree parm; 1461 int i; 1462 for (parm = DECL_ARGUMENTS (current_function_decl), i = 0; 1463 parm; 1464 parm = DECL_CHAIN (parm), i++) 1465 { 1466 tree arg = gimple_call_arg (call, i); 1467 if (!useless_type_conversion_p (TREE_TYPE (parm), TREE_TYPE (arg))) 1468 return false; 1469 } 1470 return true; 1471 } 1472 1473 /* Scan function and look for interesting expressions and create access 1474 structures for them. Return true iff any access is created. */ 1475 1476 static bool 1477 scan_function (void) 1478 { 1479 basic_block bb; 1480 bool ret = false; 1481 1482 FOR_EACH_BB_FN (bb, cfun) 1483 { 1484 gimple_stmt_iterator gsi; 1485 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) 1486 { 1487 gimple *stmt = gsi_stmt (gsi); 1488 tree t; 1489 unsigned i; 1490 1491 if (final_bbs && stmt_can_throw_external (stmt)) 1492 bitmap_set_bit (final_bbs, bb->index); 1493 switch (gimple_code (stmt)) 1494 { 1495 case GIMPLE_RETURN: 1496 t = gimple_return_retval (as_a <greturn *> (stmt)); 1497 if (t != NULL_TREE) 1498 ret |= build_access_from_expr (t, stmt, false); 1499 if (final_bbs) 1500 bitmap_set_bit (final_bbs, bb->index); 1501 break; 1502 1503 case GIMPLE_ASSIGN: 1504 ret |= build_accesses_from_assign (stmt); 1505 break; 1506 1507 case GIMPLE_CALL: 1508 for (i = 0; i < gimple_call_num_args (stmt); i++) 1509 ret |= build_access_from_expr (gimple_call_arg (stmt, i), 1510 stmt, false); 1511 1512 if (sra_mode == SRA_MODE_EARLY_IPA) 1513 { 1514 tree dest = gimple_call_fndecl (stmt); 1515 int flags = gimple_call_flags (stmt); 1516 1517 if (dest) 1518 { 1519 if (DECL_BUILT_IN_CLASS (dest) == BUILT_IN_NORMAL 1520 && DECL_FUNCTION_CODE (dest) == BUILT_IN_APPLY_ARGS) 1521 encountered_apply_args = true; 1522 if (recursive_call_p (current_function_decl, dest)) 1523 { 1524 encountered_recursive_call = true; 1525 if (!callsite_arguments_match_p (stmt)) 1526 encountered_unchangable_recursive_call = true; 1527 } 1528 } 1529 1530 if (final_bbs 1531 && (flags & (ECF_CONST | ECF_PURE)) == 0) 1532 bitmap_set_bit (final_bbs, bb->index); 1533 } 1534 1535 t = gimple_call_lhs (stmt); 1536 if (t && !disqualify_if_bad_bb_terminating_stmt (stmt, t, NULL)) 1537 ret |= build_access_from_expr (t, stmt, true); 1538 break; 1539 1540 case GIMPLE_ASM: 1541 { 1542 gasm *asm_stmt = as_a <gasm *> (stmt); 1543 walk_stmt_load_store_addr_ops (asm_stmt, NULL, NULL, NULL, 1544 asm_visit_addr); 1545 if (final_bbs) 1546 bitmap_set_bit (final_bbs, bb->index); 1547 1548 for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++) 1549 { 1550 t = TREE_VALUE (gimple_asm_input_op (asm_stmt, i)); 1551 ret |= build_access_from_expr (t, asm_stmt, false); 1552 } 1553 for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++) 1554 { 1555 t = TREE_VALUE (gimple_asm_output_op (asm_stmt, i)); 1556 ret |= build_access_from_expr (t, asm_stmt, true); 1557 } 1558 } 1559 break; 1560 1561 default: 1562 break; 1563 } 1564 } 1565 } 1566 1567 return ret; 1568 } 1569 1570 /* Helper of QSORT function. There are pointers to accesses in the array. An 1571 access is considered smaller than another if it has smaller offset or if the 1572 offsets are the same but is size is bigger. */ 1573 1574 static int 1575 compare_access_positions (const void *a, const void *b) 1576 { 1577 const access_p *fp1 = (const access_p *) a; 1578 const access_p *fp2 = (const access_p *) b; 1579 const access_p f1 = *fp1; 1580 const access_p f2 = *fp2; 1581 1582 if (f1->offset != f2->offset) 1583 return f1->offset < f2->offset ? -1 : 1; 1584 1585 if (f1->size == f2->size) 1586 { 1587 if (f1->type == f2->type) 1588 return 0; 1589 /* Put any non-aggregate type before any aggregate type. */ 1590 else if (!is_gimple_reg_type (f1->type) 1591 && is_gimple_reg_type (f2->type)) 1592 return 1; 1593 else if (is_gimple_reg_type (f1->type) 1594 && !is_gimple_reg_type (f2->type)) 1595 return -1; 1596 /* Put any complex or vector type before any other scalar type. */ 1597 else if (TREE_CODE (f1->type) != COMPLEX_TYPE 1598 && TREE_CODE (f1->type) != VECTOR_TYPE 1599 && (TREE_CODE (f2->type) == COMPLEX_TYPE 1600 || TREE_CODE (f2->type) == VECTOR_TYPE)) 1601 return 1; 1602 else if ((TREE_CODE (f1->type) == COMPLEX_TYPE 1603 || TREE_CODE (f1->type) == VECTOR_TYPE) 1604 && TREE_CODE (f2->type) != COMPLEX_TYPE 1605 && TREE_CODE (f2->type) != VECTOR_TYPE) 1606 return -1; 1607 /* Put any integral type before any non-integral type. When splicing, we 1608 make sure that those with insufficient precision and occupying the 1609 same space are not scalarized. */ 1610 else if (INTEGRAL_TYPE_P (f1->type) 1611 && !INTEGRAL_TYPE_P (f2->type)) 1612 return -1; 1613 else if (!INTEGRAL_TYPE_P (f1->type) 1614 && INTEGRAL_TYPE_P (f2->type)) 1615 return 1; 1616 /* Put the integral type with the bigger precision first. */ 1617 else if (INTEGRAL_TYPE_P (f1->type) 1618 && INTEGRAL_TYPE_P (f2->type) 1619 && (TYPE_PRECISION (f2->type) != TYPE_PRECISION (f1->type))) 1620 return TYPE_PRECISION (f2->type) - TYPE_PRECISION (f1->type); 1621 /* Stabilize the sort. */ 1622 return TYPE_UID (f1->type) - TYPE_UID (f2->type); 1623 } 1624 1625 /* We want the bigger accesses first, thus the opposite operator in the next 1626 line: */ 1627 return f1->size > f2->size ? -1 : 1; 1628 } 1629 1630 1631 /* Append a name of the declaration to the name obstack. A helper function for 1632 make_fancy_name. */ 1633 1634 static void 1635 make_fancy_decl_name (tree decl) 1636 { 1637 char buffer[32]; 1638 1639 tree name = DECL_NAME (decl); 1640 if (name) 1641 obstack_grow (&name_obstack, IDENTIFIER_POINTER (name), 1642 IDENTIFIER_LENGTH (name)); 1643 else 1644 { 1645 sprintf (buffer, "D%u", DECL_UID (decl)); 1646 obstack_grow (&name_obstack, buffer, strlen (buffer)); 1647 } 1648 } 1649 1650 /* Helper for make_fancy_name. */ 1651 1652 static void 1653 make_fancy_name_1 (tree expr) 1654 { 1655 char buffer[32]; 1656 tree index; 1657 1658 if (DECL_P (expr)) 1659 { 1660 make_fancy_decl_name (expr); 1661 return; 1662 } 1663 1664 switch (TREE_CODE (expr)) 1665 { 1666 case COMPONENT_REF: 1667 make_fancy_name_1 (TREE_OPERAND (expr, 0)); 1668 obstack_1grow (&name_obstack, '$'); 1669 make_fancy_decl_name (TREE_OPERAND (expr, 1)); 1670 break; 1671 1672 case ARRAY_REF: 1673 make_fancy_name_1 (TREE_OPERAND (expr, 0)); 1674 obstack_1grow (&name_obstack, '$'); 1675 /* Arrays with only one element may not have a constant as their 1676 index. */ 1677 index = TREE_OPERAND (expr, 1); 1678 if (TREE_CODE (index) != INTEGER_CST) 1679 break; 1680 sprintf (buffer, HOST_WIDE_INT_PRINT_DEC, TREE_INT_CST_LOW (index)); 1681 obstack_grow (&name_obstack, buffer, strlen (buffer)); 1682 break; 1683 1684 case ADDR_EXPR: 1685 make_fancy_name_1 (TREE_OPERAND (expr, 0)); 1686 break; 1687 1688 case MEM_REF: 1689 make_fancy_name_1 (TREE_OPERAND (expr, 0)); 1690 if (!integer_zerop (TREE_OPERAND (expr, 1))) 1691 { 1692 obstack_1grow (&name_obstack, '$'); 1693 sprintf (buffer, HOST_WIDE_INT_PRINT_DEC, 1694 TREE_INT_CST_LOW (TREE_OPERAND (expr, 1))); 1695 obstack_grow (&name_obstack, buffer, strlen (buffer)); 1696 } 1697 break; 1698 1699 case BIT_FIELD_REF: 1700 case REALPART_EXPR: 1701 case IMAGPART_EXPR: 1702 gcc_unreachable (); /* we treat these as scalars. */ 1703 break; 1704 default: 1705 break; 1706 } 1707 } 1708 1709 /* Create a human readable name for replacement variable of ACCESS. */ 1710 1711 static char * 1712 make_fancy_name (tree expr) 1713 { 1714 make_fancy_name_1 (expr); 1715 obstack_1grow (&name_obstack, '\0'); 1716 return XOBFINISH (&name_obstack, char *); 1717 } 1718 1719 /* Construct a MEM_REF that would reference a part of aggregate BASE of type 1720 EXP_TYPE at the given OFFSET and with storage order REVERSE. If BASE is 1721 something for which get_addr_base_and_unit_offset returns NULL, gsi must 1722 be non-NULL and is used to insert new statements either before or below 1723 the current one as specified by INSERT_AFTER. This function is not capable 1724 of handling bitfields. */ 1725 1726 tree 1727 build_ref_for_offset (location_t loc, tree base, poly_int64 offset, 1728 bool reverse, tree exp_type, gimple_stmt_iterator *gsi, 1729 bool insert_after) 1730 { 1731 tree prev_base = base; 1732 tree off; 1733 tree mem_ref; 1734 poly_int64 base_offset; 1735 unsigned HOST_WIDE_INT misalign; 1736 unsigned int align; 1737 1738 /* Preserve address-space information. */ 1739 addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (base)); 1740 if (as != TYPE_ADDR_SPACE (exp_type)) 1741 exp_type = build_qualified_type (exp_type, 1742 TYPE_QUALS (exp_type) 1743 | ENCODE_QUAL_ADDR_SPACE (as)); 1744 1745 poly_int64 byte_offset = exact_div (offset, BITS_PER_UNIT); 1746 get_object_alignment_1 (base, &align, &misalign); 1747 base = get_addr_base_and_unit_offset (base, &base_offset); 1748 1749 /* get_addr_base_and_unit_offset returns NULL for references with a variable 1750 offset such as array[var_index]. */ 1751 if (!base) 1752 { 1753 gassign *stmt; 1754 tree tmp, addr; 1755 1756 gcc_checking_assert (gsi); 1757 tmp = make_ssa_name (build_pointer_type (TREE_TYPE (prev_base))); 1758 addr = build_fold_addr_expr (unshare_expr (prev_base)); 1759 STRIP_USELESS_TYPE_CONVERSION (addr); 1760 stmt = gimple_build_assign (tmp, addr); 1761 gimple_set_location (stmt, loc); 1762 if (insert_after) 1763 gsi_insert_after (gsi, stmt, GSI_NEW_STMT); 1764 else 1765 gsi_insert_before (gsi, stmt, GSI_SAME_STMT); 1766 1767 off = build_int_cst (reference_alias_ptr_type (prev_base), byte_offset); 1768 base = tmp; 1769 } 1770 else if (TREE_CODE (base) == MEM_REF) 1771 { 1772 off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)), 1773 base_offset + byte_offset); 1774 off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1), off); 1775 base = unshare_expr (TREE_OPERAND (base, 0)); 1776 } 1777 else 1778 { 1779 off = build_int_cst (reference_alias_ptr_type (prev_base), 1780 base_offset + byte_offset); 1781 base = build_fold_addr_expr (unshare_expr (base)); 1782 } 1783 1784 unsigned int align_bound = known_alignment (misalign + offset); 1785 if (align_bound != 0) 1786 align = MIN (align, align_bound); 1787 if (align != TYPE_ALIGN (exp_type)) 1788 exp_type = build_aligned_type (exp_type, align); 1789 1790 mem_ref = fold_build2_loc (loc, MEM_REF, exp_type, base, off); 1791 REF_REVERSE_STORAGE_ORDER (mem_ref) = reverse; 1792 if (TREE_THIS_VOLATILE (prev_base)) 1793 TREE_THIS_VOLATILE (mem_ref) = 1; 1794 if (TREE_SIDE_EFFECTS (prev_base)) 1795 TREE_SIDE_EFFECTS (mem_ref) = 1; 1796 return mem_ref; 1797 } 1798 1799 /* Construct a memory reference to a part of an aggregate BASE at the given 1800 OFFSET and of the same type as MODEL. In case this is a reference to a 1801 bit-field, the function will replicate the last component_ref of model's 1802 expr to access it. GSI and INSERT_AFTER have the same meaning as in 1803 build_ref_for_offset. */ 1804 1805 static tree 1806 build_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset, 1807 struct access *model, gimple_stmt_iterator *gsi, 1808 bool insert_after) 1809 { 1810 if (TREE_CODE (model->expr) == COMPONENT_REF 1811 && DECL_BIT_FIELD (TREE_OPERAND (model->expr, 1))) 1812 { 1813 /* This access represents a bit-field. */ 1814 tree t, exp_type, fld = TREE_OPERAND (model->expr, 1); 1815 1816 offset -= int_bit_position (fld); 1817 exp_type = TREE_TYPE (TREE_OPERAND (model->expr, 0)); 1818 t = build_ref_for_offset (loc, base, offset, model->reverse, exp_type, 1819 gsi, insert_after); 1820 /* The flag will be set on the record type. */ 1821 REF_REVERSE_STORAGE_ORDER (t) = 0; 1822 return fold_build3_loc (loc, COMPONENT_REF, TREE_TYPE (fld), t, fld, 1823 NULL_TREE); 1824 } 1825 else 1826 return 1827 build_ref_for_offset (loc, base, offset, model->reverse, model->type, 1828 gsi, insert_after); 1829 } 1830 1831 /* Attempt to build a memory reference that we could but into a gimple 1832 debug_bind statement. Similar to build_ref_for_model but punts if it has to 1833 create statements and return s NULL instead. This function also ignores 1834 alignment issues and so its results should never end up in non-debug 1835 statements. */ 1836 1837 static tree 1838 build_debug_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset, 1839 struct access *model) 1840 { 1841 poly_int64 base_offset; 1842 tree off; 1843 1844 if (TREE_CODE (model->expr) == COMPONENT_REF 1845 && DECL_BIT_FIELD (TREE_OPERAND (model->expr, 1))) 1846 return NULL_TREE; 1847 1848 base = get_addr_base_and_unit_offset (base, &base_offset); 1849 if (!base) 1850 return NULL_TREE; 1851 if (TREE_CODE (base) == MEM_REF) 1852 { 1853 off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)), 1854 base_offset + offset / BITS_PER_UNIT); 1855 off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1), off); 1856 base = unshare_expr (TREE_OPERAND (base, 0)); 1857 } 1858 else 1859 { 1860 off = build_int_cst (reference_alias_ptr_type (base), 1861 base_offset + offset / BITS_PER_UNIT); 1862 base = build_fold_addr_expr (unshare_expr (base)); 1863 } 1864 1865 return fold_build2_loc (loc, MEM_REF, model->type, base, off); 1866 } 1867 1868 /* Construct a memory reference consisting of component_refs and array_refs to 1869 a part of an aggregate *RES (which is of type TYPE). The requested part 1870 should have type EXP_TYPE at be the given OFFSET. This function might not 1871 succeed, it returns true when it does and only then *RES points to something 1872 meaningful. This function should be used only to build expressions that we 1873 might need to present to user (e.g. in warnings). In all other situations, 1874 build_ref_for_model or build_ref_for_offset should be used instead. */ 1875 1876 static bool 1877 build_user_friendly_ref_for_offset (tree *res, tree type, HOST_WIDE_INT offset, 1878 tree exp_type) 1879 { 1880 while (1) 1881 { 1882 tree fld; 1883 tree tr_size, index, minidx; 1884 HOST_WIDE_INT el_size; 1885 1886 if (offset == 0 && exp_type 1887 && types_compatible_p (exp_type, type)) 1888 return true; 1889 1890 switch (TREE_CODE (type)) 1891 { 1892 case UNION_TYPE: 1893 case QUAL_UNION_TYPE: 1894 case RECORD_TYPE: 1895 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld)) 1896 { 1897 HOST_WIDE_INT pos, size; 1898 tree tr_pos, expr, *expr_ptr; 1899 1900 if (TREE_CODE (fld) != FIELD_DECL) 1901 continue; 1902 1903 tr_pos = bit_position (fld); 1904 if (!tr_pos || !tree_fits_uhwi_p (tr_pos)) 1905 continue; 1906 pos = tree_to_uhwi (tr_pos); 1907 gcc_assert (TREE_CODE (type) == RECORD_TYPE || pos == 0); 1908 tr_size = DECL_SIZE (fld); 1909 if (!tr_size || !tree_fits_uhwi_p (tr_size)) 1910 continue; 1911 size = tree_to_uhwi (tr_size); 1912 if (size == 0) 1913 { 1914 if (pos != offset) 1915 continue; 1916 } 1917 else if (pos > offset || (pos + size) <= offset) 1918 continue; 1919 1920 expr = build3 (COMPONENT_REF, TREE_TYPE (fld), *res, fld, 1921 NULL_TREE); 1922 expr_ptr = &expr; 1923 if (build_user_friendly_ref_for_offset (expr_ptr, TREE_TYPE (fld), 1924 offset - pos, exp_type)) 1925 { 1926 *res = expr; 1927 return true; 1928 } 1929 } 1930 return false; 1931 1932 case ARRAY_TYPE: 1933 tr_size = TYPE_SIZE (TREE_TYPE (type)); 1934 if (!tr_size || !tree_fits_uhwi_p (tr_size)) 1935 return false; 1936 el_size = tree_to_uhwi (tr_size); 1937 1938 minidx = TYPE_MIN_VALUE (TYPE_DOMAIN (type)); 1939 if (TREE_CODE (minidx) != INTEGER_CST || el_size == 0) 1940 return false; 1941 index = build_int_cst (TYPE_DOMAIN (type), offset / el_size); 1942 if (!integer_zerop (minidx)) 1943 index = int_const_binop (PLUS_EXPR, index, minidx); 1944 *res = build4 (ARRAY_REF, TREE_TYPE (type), *res, index, 1945 NULL_TREE, NULL_TREE); 1946 offset = offset % el_size; 1947 type = TREE_TYPE (type); 1948 break; 1949 1950 default: 1951 if (offset != 0) 1952 return false; 1953 1954 if (exp_type) 1955 return false; 1956 else 1957 return true; 1958 } 1959 } 1960 } 1961 1962 /* Return true iff TYPE is stdarg va_list type. */ 1963 1964 static inline bool 1965 is_va_list_type (tree type) 1966 { 1967 return TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (va_list_type_node); 1968 } 1969 1970 /* Print message to dump file why a variable was rejected. */ 1971 1972 static void 1973 reject (tree var, const char *msg) 1974 { 1975 if (dump_file && (dump_flags & TDF_DETAILS)) 1976 { 1977 fprintf (dump_file, "Rejected (%d): %s: ", DECL_UID (var), msg); 1978 print_generic_expr (dump_file, var); 1979 fprintf (dump_file, "\n"); 1980 } 1981 } 1982 1983 /* Return true if VAR is a candidate for SRA. */ 1984 1985 static bool 1986 maybe_add_sra_candidate (tree var) 1987 { 1988 tree type = TREE_TYPE (var); 1989 const char *msg; 1990 tree_node **slot; 1991 1992 if (!AGGREGATE_TYPE_P (type)) 1993 { 1994 reject (var, "not aggregate"); 1995 return false; 1996 } 1997 /* Allow constant-pool entries (that "need to live in memory") 1998 unless we are doing IPA SRA. */ 1999 if (needs_to_live_in_memory (var) 2000 && (sra_mode == SRA_MODE_EARLY_IPA || !constant_decl_p (var))) 2001 { 2002 reject (var, "needs to live in memory"); 2003 return false; 2004 } 2005 if (TREE_THIS_VOLATILE (var)) 2006 { 2007 reject (var, "is volatile"); 2008 return false; 2009 } 2010 if (!COMPLETE_TYPE_P (type)) 2011 { 2012 reject (var, "has incomplete type"); 2013 return false; 2014 } 2015 if (!tree_fits_uhwi_p (TYPE_SIZE (type))) 2016 { 2017 reject (var, "type size not fixed"); 2018 return false; 2019 } 2020 if (tree_to_uhwi (TYPE_SIZE (type)) == 0) 2021 { 2022 reject (var, "type size is zero"); 2023 return false; 2024 } 2025 if (type_internals_preclude_sra_p (type, &msg)) 2026 { 2027 reject (var, msg); 2028 return false; 2029 } 2030 if (/* Fix for PR 41089. tree-stdarg.c needs to have va_lists intact but 2031 we also want to schedule it rather late. Thus we ignore it in 2032 the early pass. */ 2033 (sra_mode == SRA_MODE_EARLY_INTRA 2034 && is_va_list_type (type))) 2035 { 2036 reject (var, "is va_list"); 2037 return false; 2038 } 2039 2040 bitmap_set_bit (candidate_bitmap, DECL_UID (var)); 2041 slot = candidates->find_slot_with_hash (var, DECL_UID (var), INSERT); 2042 *slot = var; 2043 2044 if (dump_file && (dump_flags & TDF_DETAILS)) 2045 { 2046 fprintf (dump_file, "Candidate (%d): ", DECL_UID (var)); 2047 print_generic_expr (dump_file, var); 2048 fprintf (dump_file, "\n"); 2049 } 2050 2051 return true; 2052 } 2053 2054 /* The very first phase of intraprocedural SRA. It marks in candidate_bitmap 2055 those with type which is suitable for scalarization. */ 2056 2057 static bool 2058 find_var_candidates (void) 2059 { 2060 tree var, parm; 2061 unsigned int i; 2062 bool ret = false; 2063 2064 for (parm = DECL_ARGUMENTS (current_function_decl); 2065 parm; 2066 parm = DECL_CHAIN (parm)) 2067 ret |= maybe_add_sra_candidate (parm); 2068 2069 FOR_EACH_LOCAL_DECL (cfun, i, var) 2070 { 2071 if (!VAR_P (var)) 2072 continue; 2073 2074 ret |= maybe_add_sra_candidate (var); 2075 } 2076 2077 return ret; 2078 } 2079 2080 /* Sort all accesses for the given variable, check for partial overlaps and 2081 return NULL if there are any. If there are none, pick a representative for 2082 each combination of offset and size and create a linked list out of them. 2083 Return the pointer to the first representative and make sure it is the first 2084 one in the vector of accesses. */ 2085 2086 static struct access * 2087 sort_and_splice_var_accesses (tree var) 2088 { 2089 int i, j, access_count; 2090 struct access *res, **prev_acc_ptr = &res; 2091 vec<access_p> *access_vec; 2092 bool first = true; 2093 HOST_WIDE_INT low = -1, high = 0; 2094 2095 access_vec = get_base_access_vector (var); 2096 if (!access_vec) 2097 return NULL; 2098 access_count = access_vec->length (); 2099 2100 /* Sort by <OFFSET, SIZE>. */ 2101 access_vec->qsort (compare_access_positions); 2102 2103 i = 0; 2104 while (i < access_count) 2105 { 2106 struct access *access = (*access_vec)[i]; 2107 bool grp_write = access->write; 2108 bool grp_read = !access->write; 2109 bool grp_scalar_write = access->write 2110 && is_gimple_reg_type (access->type); 2111 bool grp_scalar_read = !access->write 2112 && is_gimple_reg_type (access->type); 2113 bool grp_assignment_read = access->grp_assignment_read; 2114 bool grp_assignment_write = access->grp_assignment_write; 2115 bool multiple_scalar_reads = false; 2116 bool total_scalarization = access->grp_total_scalarization; 2117 bool grp_partial_lhs = access->grp_partial_lhs; 2118 bool first_scalar = is_gimple_reg_type (access->type); 2119 bool unscalarizable_region = access->grp_unscalarizable_region; 2120 bool bf_non_full_precision 2121 = (INTEGRAL_TYPE_P (access->type) 2122 && TYPE_PRECISION (access->type) != access->size 2123 && TREE_CODE (access->expr) == COMPONENT_REF 2124 && DECL_BIT_FIELD (TREE_OPERAND (access->expr, 1))); 2125 2126 if (first || access->offset >= high) 2127 { 2128 first = false; 2129 low = access->offset; 2130 high = access->offset + access->size; 2131 } 2132 else if (access->offset > low && access->offset + access->size > high) 2133 return NULL; 2134 else 2135 gcc_assert (access->offset >= low 2136 && access->offset + access->size <= high); 2137 2138 j = i + 1; 2139 while (j < access_count) 2140 { 2141 struct access *ac2 = (*access_vec)[j]; 2142 if (ac2->offset != access->offset || ac2->size != access->size) 2143 break; 2144 if (ac2->write) 2145 { 2146 grp_write = true; 2147 grp_scalar_write = (grp_scalar_write 2148 || is_gimple_reg_type (ac2->type)); 2149 } 2150 else 2151 { 2152 grp_read = true; 2153 if (is_gimple_reg_type (ac2->type)) 2154 { 2155 if (grp_scalar_read) 2156 multiple_scalar_reads = true; 2157 else 2158 grp_scalar_read = true; 2159 } 2160 } 2161 grp_assignment_read |= ac2->grp_assignment_read; 2162 grp_assignment_write |= ac2->grp_assignment_write; 2163 grp_partial_lhs |= ac2->grp_partial_lhs; 2164 unscalarizable_region |= ac2->grp_unscalarizable_region; 2165 total_scalarization |= ac2->grp_total_scalarization; 2166 relink_to_new_repr (access, ac2); 2167 2168 /* If there are both aggregate-type and scalar-type accesses with 2169 this combination of size and offset, the comparison function 2170 should have put the scalars first. */ 2171 gcc_assert (first_scalar || !is_gimple_reg_type (ac2->type)); 2172 /* It also prefers integral types to non-integral. However, when the 2173 precision of the selected type does not span the entire area and 2174 should also be used for a non-integer (i.e. float), we must not 2175 let that happen. Normally analyze_access_subtree expands the type 2176 to cover the entire area but for bit-fields it doesn't. */ 2177 if (bf_non_full_precision && !INTEGRAL_TYPE_P (ac2->type)) 2178 { 2179 if (dump_file && (dump_flags & TDF_DETAILS)) 2180 { 2181 fprintf (dump_file, "Cannot scalarize the following access " 2182 "because insufficient precision integer type was " 2183 "selected.\n "); 2184 dump_access (dump_file, access, false); 2185 } 2186 unscalarizable_region = true; 2187 } 2188 ac2->group_representative = access; 2189 j++; 2190 } 2191 2192 i = j; 2193 2194 access->group_representative = access; 2195 access->grp_write = grp_write; 2196 access->grp_read = grp_read; 2197 access->grp_scalar_read = grp_scalar_read; 2198 access->grp_scalar_write = grp_scalar_write; 2199 access->grp_assignment_read = grp_assignment_read; 2200 access->grp_assignment_write = grp_assignment_write; 2201 access->grp_hint = total_scalarization 2202 || (multiple_scalar_reads && !constant_decl_p (var)); 2203 access->grp_total_scalarization = total_scalarization; 2204 access->grp_partial_lhs = grp_partial_lhs; 2205 access->grp_unscalarizable_region = unscalarizable_region; 2206 2207 *prev_acc_ptr = access; 2208 prev_acc_ptr = &access->next_grp; 2209 } 2210 2211 gcc_assert (res == (*access_vec)[0]); 2212 return res; 2213 } 2214 2215 /* Create a variable for the given ACCESS which determines the type, name and a 2216 few other properties. Return the variable declaration and store it also to 2217 ACCESS->replacement. */ 2218 2219 static tree 2220 create_access_replacement (struct access *access) 2221 { 2222 tree repl; 2223 2224 if (access->grp_to_be_debug_replaced) 2225 { 2226 repl = create_tmp_var_raw (access->type); 2227 DECL_CONTEXT (repl) = current_function_decl; 2228 } 2229 else 2230 /* Drop any special alignment on the type if it's not on the main 2231 variant. This avoids issues with weirdo ABIs like AAPCS. */ 2232 repl = create_tmp_var (build_qualified_type 2233 (TYPE_MAIN_VARIANT (access->type), 2234 TYPE_QUALS (access->type)), "SR"); 2235 if (TREE_CODE (access->type) == COMPLEX_TYPE 2236 || TREE_CODE (access->type) == VECTOR_TYPE) 2237 { 2238 if (!access->grp_partial_lhs) 2239 DECL_GIMPLE_REG_P (repl) = 1; 2240 } 2241 else if (access->grp_partial_lhs 2242 && is_gimple_reg_type (access->type)) 2243 TREE_ADDRESSABLE (repl) = 1; 2244 2245 DECL_SOURCE_LOCATION (repl) = DECL_SOURCE_LOCATION (access->base); 2246 DECL_ARTIFICIAL (repl) = 1; 2247 DECL_IGNORED_P (repl) = DECL_IGNORED_P (access->base); 2248 2249 if (DECL_NAME (access->base) 2250 && !DECL_IGNORED_P (access->base) 2251 && !DECL_ARTIFICIAL (access->base)) 2252 { 2253 char *pretty_name = make_fancy_name (access->expr); 2254 tree debug_expr = unshare_expr_without_location (access->expr), d; 2255 bool fail = false; 2256 2257 DECL_NAME (repl) = get_identifier (pretty_name); 2258 DECL_NAMELESS (repl) = 1; 2259 obstack_free (&name_obstack, pretty_name); 2260 2261 /* Get rid of any SSA_NAMEs embedded in debug_expr, 2262 as DECL_DEBUG_EXPR isn't considered when looking for still 2263 used SSA_NAMEs and thus they could be freed. All debug info 2264 generation cares is whether something is constant or variable 2265 and that get_ref_base_and_extent works properly on the 2266 expression. It cannot handle accesses at a non-constant offset 2267 though, so just give up in those cases. */ 2268 for (d = debug_expr; 2269 !fail && (handled_component_p (d) || TREE_CODE (d) == MEM_REF); 2270 d = TREE_OPERAND (d, 0)) 2271 switch (TREE_CODE (d)) 2272 { 2273 case ARRAY_REF: 2274 case ARRAY_RANGE_REF: 2275 if (TREE_OPERAND (d, 1) 2276 && TREE_CODE (TREE_OPERAND (d, 1)) != INTEGER_CST) 2277 fail = true; 2278 if (TREE_OPERAND (d, 3) 2279 && TREE_CODE (TREE_OPERAND (d, 3)) != INTEGER_CST) 2280 fail = true; 2281 /* FALLTHRU */ 2282 case COMPONENT_REF: 2283 if (TREE_OPERAND (d, 2) 2284 && TREE_CODE (TREE_OPERAND (d, 2)) != INTEGER_CST) 2285 fail = true; 2286 break; 2287 case MEM_REF: 2288 if (TREE_CODE (TREE_OPERAND (d, 0)) != ADDR_EXPR) 2289 fail = true; 2290 else 2291 d = TREE_OPERAND (d, 0); 2292 break; 2293 default: 2294 break; 2295 } 2296 if (!fail) 2297 { 2298 SET_DECL_DEBUG_EXPR (repl, debug_expr); 2299 DECL_HAS_DEBUG_EXPR_P (repl) = 1; 2300 } 2301 if (access->grp_no_warning) 2302 TREE_NO_WARNING (repl) = 1; 2303 else 2304 TREE_NO_WARNING (repl) = TREE_NO_WARNING (access->base); 2305 } 2306 else 2307 TREE_NO_WARNING (repl) = 1; 2308 2309 if (dump_file) 2310 { 2311 if (access->grp_to_be_debug_replaced) 2312 { 2313 fprintf (dump_file, "Created a debug-only replacement for "); 2314 print_generic_expr (dump_file, access->base); 2315 fprintf (dump_file, " offset: %u, size: %u\n", 2316 (unsigned) access->offset, (unsigned) access->size); 2317 } 2318 else 2319 { 2320 fprintf (dump_file, "Created a replacement for "); 2321 print_generic_expr (dump_file, access->base); 2322 fprintf (dump_file, " offset: %u, size: %u: ", 2323 (unsigned) access->offset, (unsigned) access->size); 2324 print_generic_expr (dump_file, repl); 2325 fprintf (dump_file, "\n"); 2326 } 2327 } 2328 sra_stats.replacements++; 2329 2330 return repl; 2331 } 2332 2333 /* Return ACCESS scalar replacement, which must exist. */ 2334 2335 static inline tree 2336 get_access_replacement (struct access *access) 2337 { 2338 gcc_checking_assert (access->replacement_decl); 2339 return access->replacement_decl; 2340 } 2341 2342 2343 /* Build a subtree of accesses rooted in *ACCESS, and move the pointer in the 2344 linked list along the way. Stop when *ACCESS is NULL or the access pointed 2345 to it is not "within" the root. Return false iff some accesses partially 2346 overlap. */ 2347 2348 static bool 2349 build_access_subtree (struct access **access) 2350 { 2351 struct access *root = *access, *last_child = NULL; 2352 HOST_WIDE_INT limit = root->offset + root->size; 2353 2354 *access = (*access)->next_grp; 2355 while (*access && (*access)->offset + (*access)->size <= limit) 2356 { 2357 if (!last_child) 2358 root->first_child = *access; 2359 else 2360 last_child->next_sibling = *access; 2361 last_child = *access; 2362 (*access)->parent = root; 2363 (*access)->grp_write |= root->grp_write; 2364 2365 if (!build_access_subtree (access)) 2366 return false; 2367 } 2368 2369 if (*access && (*access)->offset < limit) 2370 return false; 2371 2372 return true; 2373 } 2374 2375 /* Build a tree of access representatives, ACCESS is the pointer to the first 2376 one, others are linked in a list by the next_grp field. Return false iff 2377 some accesses partially overlap. */ 2378 2379 static bool 2380 build_access_trees (struct access *access) 2381 { 2382 while (access) 2383 { 2384 struct access *root = access; 2385 2386 if (!build_access_subtree (&access)) 2387 return false; 2388 root->next_grp = access; 2389 } 2390 return true; 2391 } 2392 2393 /* Return true if expr contains some ARRAY_REFs into a variable bounded 2394 array. */ 2395 2396 static bool 2397 expr_with_var_bounded_array_refs_p (tree expr) 2398 { 2399 while (handled_component_p (expr)) 2400 { 2401 if (TREE_CODE (expr) == ARRAY_REF 2402 && !tree_fits_shwi_p (array_ref_low_bound (expr))) 2403 return true; 2404 expr = TREE_OPERAND (expr, 0); 2405 } 2406 return false; 2407 } 2408 2409 /* Analyze the subtree of accesses rooted in ROOT, scheduling replacements when 2410 both seeming beneficial and when ALLOW_REPLACEMENTS allows it. Also set all 2411 sorts of access flags appropriately along the way, notably always set 2412 grp_read and grp_assign_read according to MARK_READ and grp_write when 2413 MARK_WRITE is true. 2414 2415 Creating a replacement for a scalar access is considered beneficial if its 2416 grp_hint is set (this means we are either attempting total scalarization or 2417 there is more than one direct read access) or according to the following 2418 table: 2419 2420 Access written to through a scalar type (once or more times) 2421 | 2422 | Written to in an assignment statement 2423 | | 2424 | | Access read as scalar _once_ 2425 | | | 2426 | | | Read in an assignment statement 2427 | | | | 2428 | | | | Scalarize Comment 2429 ----------------------------------------------------------------------------- 2430 0 0 0 0 No access for the scalar 2431 0 0 0 1 No access for the scalar 2432 0 0 1 0 No Single read - won't help 2433 0 0 1 1 No The same case 2434 0 1 0 0 No access for the scalar 2435 0 1 0 1 No access for the scalar 2436 0 1 1 0 Yes s = *g; return s.i; 2437 0 1 1 1 Yes The same case as above 2438 1 0 0 0 No Won't help 2439 1 0 0 1 Yes s.i = 1; *g = s; 2440 1 0 1 0 Yes s.i = 5; g = s.i; 2441 1 0 1 1 Yes The same case as above 2442 1 1 0 0 No Won't help. 2443 1 1 0 1 Yes s.i = 1; *g = s; 2444 1 1 1 0 Yes s = *g; return s.i; 2445 1 1 1 1 Yes Any of the above yeses */ 2446 2447 static bool 2448 analyze_access_subtree (struct access *root, struct access *parent, 2449 bool allow_replacements) 2450 { 2451 struct access *child; 2452 HOST_WIDE_INT limit = root->offset + root->size; 2453 HOST_WIDE_INT covered_to = root->offset; 2454 bool scalar = is_gimple_reg_type (root->type); 2455 bool hole = false, sth_created = false; 2456 2457 if (parent) 2458 { 2459 if (parent->grp_read) 2460 root->grp_read = 1; 2461 if (parent->grp_assignment_read) 2462 root->grp_assignment_read = 1; 2463 if (parent->grp_write) 2464 root->grp_write = 1; 2465 if (parent->grp_assignment_write) 2466 root->grp_assignment_write = 1; 2467 if (parent->grp_total_scalarization) 2468 root->grp_total_scalarization = 1; 2469 } 2470 2471 if (root->grp_unscalarizable_region) 2472 allow_replacements = false; 2473 2474 if (allow_replacements && expr_with_var_bounded_array_refs_p (root->expr)) 2475 allow_replacements = false; 2476 2477 for (child = root->first_child; child; child = child->next_sibling) 2478 { 2479 hole |= covered_to < child->offset; 2480 sth_created |= analyze_access_subtree (child, root, 2481 allow_replacements && !scalar); 2482 2483 root->grp_unscalarized_data |= child->grp_unscalarized_data; 2484 root->grp_total_scalarization &= child->grp_total_scalarization; 2485 if (child->grp_covered) 2486 covered_to += child->size; 2487 else 2488 hole = true; 2489 } 2490 2491 if (allow_replacements && scalar && !root->first_child 2492 && (root->grp_hint 2493 || ((root->grp_scalar_read || root->grp_assignment_read) 2494 && (root->grp_scalar_write || root->grp_assignment_write)))) 2495 { 2496 /* Always create access replacements that cover the whole access. 2497 For integral types this means the precision has to match. 2498 Avoid assumptions based on the integral type kind, too. */ 2499 if (INTEGRAL_TYPE_P (root->type) 2500 && (TREE_CODE (root->type) != INTEGER_TYPE 2501 || TYPE_PRECISION (root->type) != root->size) 2502 /* But leave bitfield accesses alone. */ 2503 && (TREE_CODE (root->expr) != COMPONENT_REF 2504 || !DECL_BIT_FIELD (TREE_OPERAND (root->expr, 1)))) 2505 { 2506 tree rt = root->type; 2507 gcc_assert ((root->offset % BITS_PER_UNIT) == 0 2508 && (root->size % BITS_PER_UNIT) == 0); 2509 root->type = build_nonstandard_integer_type (root->size, 2510 TYPE_UNSIGNED (rt)); 2511 root->expr = build_ref_for_offset (UNKNOWN_LOCATION, root->base, 2512 root->offset, root->reverse, 2513 root->type, NULL, false); 2514 2515 if (dump_file && (dump_flags & TDF_DETAILS)) 2516 { 2517 fprintf (dump_file, "Changing the type of a replacement for "); 2518 print_generic_expr (dump_file, root->base); 2519 fprintf (dump_file, " offset: %u, size: %u ", 2520 (unsigned) root->offset, (unsigned) root->size); 2521 fprintf (dump_file, " to an integer.\n"); 2522 } 2523 } 2524 2525 root->grp_to_be_replaced = 1; 2526 root->replacement_decl = create_access_replacement (root); 2527 sth_created = true; 2528 hole = false; 2529 } 2530 else 2531 { 2532 if (allow_replacements 2533 && scalar && !root->first_child 2534 && (root->grp_scalar_write || root->grp_assignment_write) 2535 && !bitmap_bit_p (cannot_scalarize_away_bitmap, 2536 DECL_UID (root->base))) 2537 { 2538 gcc_checking_assert (!root->grp_scalar_read 2539 && !root->grp_assignment_read); 2540 sth_created = true; 2541 if (MAY_HAVE_DEBUG_BIND_STMTS) 2542 { 2543 root->grp_to_be_debug_replaced = 1; 2544 root->replacement_decl = create_access_replacement (root); 2545 } 2546 } 2547 2548 if (covered_to < limit) 2549 hole = true; 2550 if (scalar || !allow_replacements) 2551 root->grp_total_scalarization = 0; 2552 } 2553 2554 if (!hole || root->grp_total_scalarization) 2555 root->grp_covered = 1; 2556 else if (root->grp_write || comes_initialized_p (root->base)) 2557 root->grp_unscalarized_data = 1; /* not covered and written to */ 2558 return sth_created; 2559 } 2560 2561 /* Analyze all access trees linked by next_grp by the means of 2562 analyze_access_subtree. */ 2563 static bool 2564 analyze_access_trees (struct access *access) 2565 { 2566 bool ret = false; 2567 2568 while (access) 2569 { 2570 if (analyze_access_subtree (access, NULL, true)) 2571 ret = true; 2572 access = access->next_grp; 2573 } 2574 2575 return ret; 2576 } 2577 2578 /* Return true iff a potential new child of LACC at offset OFFSET and with size 2579 SIZE would conflict with an already existing one. If exactly such a child 2580 already exists in LACC, store a pointer to it in EXACT_MATCH. */ 2581 2582 static bool 2583 child_would_conflict_in_lacc (struct access *lacc, HOST_WIDE_INT norm_offset, 2584 HOST_WIDE_INT size, struct access **exact_match) 2585 { 2586 struct access *child; 2587 2588 for (child = lacc->first_child; child; child = child->next_sibling) 2589 { 2590 if (child->offset == norm_offset && child->size == size) 2591 { 2592 *exact_match = child; 2593 return true; 2594 } 2595 2596 if (child->offset < norm_offset + size 2597 && child->offset + child->size > norm_offset) 2598 return true; 2599 } 2600 2601 return false; 2602 } 2603 2604 /* Create a new child access of PARENT, with all properties just like MODEL 2605 except for its offset and with its grp_write false and grp_read true. 2606 Return the new access or NULL if it cannot be created. Note that this 2607 access is created long after all splicing and sorting, it's not located in 2608 any access vector and is automatically a representative of its group. Set 2609 the gpr_write flag of the new accesss if SET_GRP_WRITE is true. */ 2610 2611 static struct access * 2612 create_artificial_child_access (struct access *parent, struct access *model, 2613 HOST_WIDE_INT new_offset, 2614 bool set_grp_write) 2615 { 2616 struct access **child; 2617 tree expr = parent->base; 2618 2619 gcc_assert (!model->grp_unscalarizable_region); 2620 2621 struct access *access = access_pool.allocate (); 2622 memset (access, 0, sizeof (struct access)); 2623 if (!build_user_friendly_ref_for_offset (&expr, TREE_TYPE (expr), new_offset, 2624 model->type)) 2625 { 2626 access->grp_no_warning = true; 2627 expr = build_ref_for_model (EXPR_LOCATION (parent->base), parent->base, 2628 new_offset, model, NULL, false); 2629 } 2630 2631 access->base = parent->base; 2632 access->expr = expr; 2633 access->offset = new_offset; 2634 access->size = model->size; 2635 access->type = model->type; 2636 access->grp_write = set_grp_write; 2637 access->grp_read = false; 2638 access->reverse = model->reverse; 2639 2640 child = &parent->first_child; 2641 while (*child && (*child)->offset < new_offset) 2642 child = &(*child)->next_sibling; 2643 2644 access->next_sibling = *child; 2645 *child = access; 2646 2647 return access; 2648 } 2649 2650 2651 /* Beginning with ACCESS, traverse its whole access subtree and mark all 2652 sub-trees as written to. If any of them has not been marked so previously 2653 and has assignment links leading from it, re-enqueue it. */ 2654 2655 static void 2656 subtree_mark_written_and_enqueue (struct access *access) 2657 { 2658 if (access->grp_write) 2659 return; 2660 access->grp_write = true; 2661 add_access_to_work_queue (access); 2662 2663 struct access *child; 2664 for (child = access->first_child; child; child = child->next_sibling) 2665 subtree_mark_written_and_enqueue (child); 2666 } 2667 2668 /* Propagate subaccesses and grp_write flags of RACC across an assignment link 2669 to LACC. Enqueue sub-accesses as necessary so that the write flag is 2670 propagated transitively. Return true if anything changed. Additionally, if 2671 RACC is a scalar access but LACC is not, change the type of the latter, if 2672 possible. */ 2673 2674 static bool 2675 propagate_subaccesses_across_link (struct access *lacc, struct access *racc) 2676 { 2677 struct access *rchild; 2678 HOST_WIDE_INT norm_delta = lacc->offset - racc->offset; 2679 bool ret = false; 2680 2681 /* IF the LHS is still not marked as being written to, we only need to do so 2682 if the RHS at this level actually was. */ 2683 if (!lacc->grp_write) 2684 { 2685 gcc_checking_assert (!comes_initialized_p (racc->base)); 2686 if (racc->grp_write) 2687 { 2688 subtree_mark_written_and_enqueue (lacc); 2689 ret = true; 2690 } 2691 } 2692 2693 if (is_gimple_reg_type (lacc->type) 2694 || lacc->grp_unscalarizable_region 2695 || racc->grp_unscalarizable_region) 2696 { 2697 if (!lacc->grp_write) 2698 { 2699 ret = true; 2700 subtree_mark_written_and_enqueue (lacc); 2701 } 2702 return ret; 2703 } 2704 2705 if (is_gimple_reg_type (racc->type)) 2706 { 2707 if (!lacc->grp_write) 2708 { 2709 ret = true; 2710 subtree_mark_written_and_enqueue (lacc); 2711 } 2712 if (!lacc->first_child && !racc->first_child) 2713 { 2714 tree t = lacc->base; 2715 2716 lacc->type = racc->type; 2717 if (build_user_friendly_ref_for_offset (&t, TREE_TYPE (t), 2718 lacc->offset, racc->type)) 2719 lacc->expr = t; 2720 else 2721 { 2722 lacc->expr = build_ref_for_model (EXPR_LOCATION (lacc->base), 2723 lacc->base, lacc->offset, 2724 racc, NULL, false); 2725 lacc->grp_no_warning = true; 2726 } 2727 } 2728 return ret; 2729 } 2730 2731 for (rchild = racc->first_child; rchild; rchild = rchild->next_sibling) 2732 { 2733 struct access *new_acc = NULL; 2734 HOST_WIDE_INT norm_offset = rchild->offset + norm_delta; 2735 2736 if (child_would_conflict_in_lacc (lacc, norm_offset, rchild->size, 2737 &new_acc)) 2738 { 2739 if (new_acc) 2740 { 2741 if (!new_acc->grp_write && rchild->grp_write) 2742 { 2743 gcc_assert (!lacc->grp_write); 2744 subtree_mark_written_and_enqueue (new_acc); 2745 ret = true; 2746 } 2747 2748 rchild->grp_hint = 1; 2749 new_acc->grp_hint |= new_acc->grp_read; 2750 if (rchild->first_child 2751 && propagate_subaccesses_across_link (new_acc, rchild)) 2752 { 2753 ret = 1; 2754 add_access_to_work_queue (new_acc); 2755 } 2756 } 2757 else 2758 { 2759 if (!lacc->grp_write) 2760 { 2761 ret = true; 2762 subtree_mark_written_and_enqueue (lacc); 2763 } 2764 } 2765 continue; 2766 } 2767 2768 if (rchild->grp_unscalarizable_region) 2769 { 2770 if (rchild->grp_write && !lacc->grp_write) 2771 { 2772 ret = true; 2773 subtree_mark_written_and_enqueue (lacc); 2774 } 2775 continue; 2776 } 2777 2778 rchild->grp_hint = 1; 2779 new_acc = create_artificial_child_access (lacc, rchild, norm_offset, 2780 lacc->grp_write 2781 || rchild->grp_write); 2782 gcc_checking_assert (new_acc); 2783 if (racc->first_child) 2784 propagate_subaccesses_across_link (new_acc, rchild); 2785 2786 add_access_to_work_queue (lacc); 2787 ret = true; 2788 } 2789 2790 return ret; 2791 } 2792 2793 /* Propagate all subaccesses across assignment links. */ 2794 2795 static void 2796 propagate_all_subaccesses (void) 2797 { 2798 while (work_queue_head) 2799 { 2800 struct access *racc = pop_access_from_work_queue (); 2801 struct assign_link *link; 2802 2803 if (racc->group_representative) 2804 racc= racc->group_representative; 2805 gcc_assert (racc->first_link); 2806 2807 for (link = racc->first_link; link; link = link->next) 2808 { 2809 struct access *lacc = link->lacc; 2810 2811 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (lacc->base))) 2812 continue; 2813 lacc = lacc->group_representative; 2814 2815 bool reque_parents = false; 2816 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (racc->base))) 2817 { 2818 if (!lacc->grp_write) 2819 { 2820 subtree_mark_written_and_enqueue (lacc); 2821 reque_parents = true; 2822 } 2823 } 2824 else if (propagate_subaccesses_across_link (lacc, racc)) 2825 reque_parents = true; 2826 2827 if (reque_parents) 2828 do 2829 { 2830 add_access_to_work_queue (lacc); 2831 lacc = lacc->parent; 2832 } 2833 while (lacc); 2834 } 2835 } 2836 } 2837 2838 /* Go through all accesses collected throughout the (intraprocedural) analysis 2839 stage, exclude overlapping ones, identify representatives and build trees 2840 out of them, making decisions about scalarization on the way. Return true 2841 iff there are any to-be-scalarized variables after this stage. */ 2842 2843 static bool 2844 analyze_all_variable_accesses (void) 2845 { 2846 int res = 0; 2847 bitmap tmp = BITMAP_ALLOC (NULL); 2848 bitmap_iterator bi; 2849 unsigned i; 2850 bool optimize_speed_p = !optimize_function_for_size_p (cfun); 2851 2852 enum compiler_param param = optimize_speed_p 2853 ? PARAM_SRA_MAX_SCALARIZATION_SIZE_SPEED 2854 : PARAM_SRA_MAX_SCALARIZATION_SIZE_SIZE; 2855 2856 /* If the user didn't set PARAM_SRA_MAX_SCALARIZATION_SIZE_<...>, 2857 fall back to a target default. */ 2858 unsigned HOST_WIDE_INT max_scalarization_size 2859 = global_options_set.x_param_values[param] 2860 ? PARAM_VALUE (param) 2861 : get_move_ratio (optimize_speed_p) * UNITS_PER_WORD; 2862 2863 max_scalarization_size *= BITS_PER_UNIT; 2864 2865 EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap, 0, i, bi) 2866 if (bitmap_bit_p (should_scalarize_away_bitmap, i) 2867 && !bitmap_bit_p (cannot_scalarize_away_bitmap, i)) 2868 { 2869 tree var = candidate (i); 2870 2871 if (VAR_P (var) && scalarizable_type_p (TREE_TYPE (var), 2872 constant_decl_p (var))) 2873 { 2874 if (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (var))) 2875 <= max_scalarization_size) 2876 { 2877 create_total_scalarization_access (var); 2878 completely_scalarize (var, TREE_TYPE (var), 0, var); 2879 statistics_counter_event (cfun, 2880 "Totally-scalarized aggregates", 1); 2881 if (dump_file && (dump_flags & TDF_DETAILS)) 2882 { 2883 fprintf (dump_file, "Will attempt to totally scalarize "); 2884 print_generic_expr (dump_file, var); 2885 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var)); 2886 } 2887 } 2888 else if (dump_file && (dump_flags & TDF_DETAILS)) 2889 { 2890 fprintf (dump_file, "Too big to totally scalarize: "); 2891 print_generic_expr (dump_file, var); 2892 fprintf (dump_file, " (UID: %u)\n", DECL_UID (var)); 2893 } 2894 } 2895 } 2896 2897 bitmap_copy (tmp, candidate_bitmap); 2898 EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi) 2899 { 2900 tree var = candidate (i); 2901 struct access *access; 2902 2903 access = sort_and_splice_var_accesses (var); 2904 if (!access || !build_access_trees (access)) 2905 disqualify_candidate (var, 2906 "No or inhibitingly overlapping accesses."); 2907 } 2908 2909 propagate_all_subaccesses (); 2910 2911 bitmap_copy (tmp, candidate_bitmap); 2912 EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi) 2913 { 2914 tree var = candidate (i); 2915 struct access *access = get_first_repr_for_decl (var); 2916 2917 if (analyze_access_trees (access)) 2918 { 2919 res++; 2920 if (dump_file && (dump_flags & TDF_DETAILS)) 2921 { 2922 fprintf (dump_file, "\nAccess trees for "); 2923 print_generic_expr (dump_file, var); 2924 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var)); 2925 dump_access_tree (dump_file, access); 2926 fprintf (dump_file, "\n"); 2927 } 2928 } 2929 else 2930 disqualify_candidate (var, "No scalar replacements to be created."); 2931 } 2932 2933 BITMAP_FREE (tmp); 2934 2935 if (res) 2936 { 2937 statistics_counter_event (cfun, "Scalarized aggregates", res); 2938 return true; 2939 } 2940 else 2941 return false; 2942 } 2943 2944 /* Generate statements copying scalar replacements of accesses within a subtree 2945 into or out of AGG. ACCESS, all its children, siblings and their children 2946 are to be processed. AGG is an aggregate type expression (can be a 2947 declaration but does not have to be, it can for example also be a mem_ref or 2948 a series of handled components). TOP_OFFSET is the offset of the processed 2949 subtree which has to be subtracted from offsets of individual accesses to 2950 get corresponding offsets for AGG. If CHUNK_SIZE is non-null, copy only 2951 replacements in the interval <start_offset, start_offset + chunk_size>, 2952 otherwise copy all. GSI is a statement iterator used to place the new 2953 statements. WRITE should be true when the statements should write from AGG 2954 to the replacement and false if vice versa. if INSERT_AFTER is true, new 2955 statements will be added after the current statement in GSI, they will be 2956 added before the statement otherwise. */ 2957 2958 static void 2959 generate_subtree_copies (struct access *access, tree agg, 2960 HOST_WIDE_INT top_offset, 2961 HOST_WIDE_INT start_offset, HOST_WIDE_INT chunk_size, 2962 gimple_stmt_iterator *gsi, bool write, 2963 bool insert_after, location_t loc) 2964 { 2965 /* Never write anything into constant pool decls. See PR70602. */ 2966 if (!write && constant_decl_p (agg)) 2967 return; 2968 do 2969 { 2970 if (chunk_size && access->offset >= start_offset + chunk_size) 2971 return; 2972 2973 if (access->grp_to_be_replaced 2974 && (chunk_size == 0 2975 || access->offset + access->size > start_offset)) 2976 { 2977 tree expr, repl = get_access_replacement (access); 2978 gassign *stmt; 2979 2980 expr = build_ref_for_model (loc, agg, access->offset - top_offset, 2981 access, gsi, insert_after); 2982 2983 if (write) 2984 { 2985 if (access->grp_partial_lhs) 2986 expr = force_gimple_operand_gsi (gsi, expr, true, NULL_TREE, 2987 !insert_after, 2988 insert_after ? GSI_NEW_STMT 2989 : GSI_SAME_STMT); 2990 stmt = gimple_build_assign (repl, expr); 2991 } 2992 else 2993 { 2994 TREE_NO_WARNING (repl) = 1; 2995 if (access->grp_partial_lhs) 2996 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE, 2997 !insert_after, 2998 insert_after ? GSI_NEW_STMT 2999 : GSI_SAME_STMT); 3000 stmt = gimple_build_assign (expr, repl); 3001 } 3002 gimple_set_location (stmt, loc); 3003 3004 if (insert_after) 3005 gsi_insert_after (gsi, stmt, GSI_NEW_STMT); 3006 else 3007 gsi_insert_before (gsi, stmt, GSI_SAME_STMT); 3008 update_stmt (stmt); 3009 sra_stats.subtree_copies++; 3010 } 3011 else if (write 3012 && access->grp_to_be_debug_replaced 3013 && (chunk_size == 0 3014 || access->offset + access->size > start_offset)) 3015 { 3016 gdebug *ds; 3017 tree drhs = build_debug_ref_for_model (loc, agg, 3018 access->offset - top_offset, 3019 access); 3020 ds = gimple_build_debug_bind (get_access_replacement (access), 3021 drhs, gsi_stmt (*gsi)); 3022 if (insert_after) 3023 gsi_insert_after (gsi, ds, GSI_NEW_STMT); 3024 else 3025 gsi_insert_before (gsi, ds, GSI_SAME_STMT); 3026 } 3027 3028 if (access->first_child) 3029 generate_subtree_copies (access->first_child, agg, top_offset, 3030 start_offset, chunk_size, gsi, 3031 write, insert_after, loc); 3032 3033 access = access->next_sibling; 3034 } 3035 while (access); 3036 } 3037 3038 /* Assign zero to all scalar replacements in an access subtree. ACCESS is the 3039 root of the subtree to be processed. GSI is the statement iterator used 3040 for inserting statements which are added after the current statement if 3041 INSERT_AFTER is true or before it otherwise. */ 3042 3043 static void 3044 init_subtree_with_zero (struct access *access, gimple_stmt_iterator *gsi, 3045 bool insert_after, location_t loc) 3046 3047 { 3048 struct access *child; 3049 3050 if (access->grp_to_be_replaced) 3051 { 3052 gassign *stmt; 3053 3054 stmt = gimple_build_assign (get_access_replacement (access), 3055 build_zero_cst (access->type)); 3056 if (insert_after) 3057 gsi_insert_after (gsi, stmt, GSI_NEW_STMT); 3058 else 3059 gsi_insert_before (gsi, stmt, GSI_SAME_STMT); 3060 update_stmt (stmt); 3061 gimple_set_location (stmt, loc); 3062 } 3063 else if (access->grp_to_be_debug_replaced) 3064 { 3065 gdebug *ds 3066 = gimple_build_debug_bind (get_access_replacement (access), 3067 build_zero_cst (access->type), 3068 gsi_stmt (*gsi)); 3069 if (insert_after) 3070 gsi_insert_after (gsi, ds, GSI_NEW_STMT); 3071 else 3072 gsi_insert_before (gsi, ds, GSI_SAME_STMT); 3073 } 3074 3075 for (child = access->first_child; child; child = child->next_sibling) 3076 init_subtree_with_zero (child, gsi, insert_after, loc); 3077 } 3078 3079 /* Clobber all scalar replacements in an access subtree. ACCESS is the 3080 root of the subtree to be processed. GSI is the statement iterator used 3081 for inserting statements which are added after the current statement if 3082 INSERT_AFTER is true or before it otherwise. */ 3083 3084 static void 3085 clobber_subtree (struct access *access, gimple_stmt_iterator *gsi, 3086 bool insert_after, location_t loc) 3087 3088 { 3089 struct access *child; 3090 3091 if (access->grp_to_be_replaced) 3092 { 3093 tree rep = get_access_replacement (access); 3094 tree clobber = build_constructor (access->type, NULL); 3095 TREE_THIS_VOLATILE (clobber) = 1; 3096 gimple *stmt = gimple_build_assign (rep, clobber); 3097 3098 if (insert_after) 3099 gsi_insert_after (gsi, stmt, GSI_NEW_STMT); 3100 else 3101 gsi_insert_before (gsi, stmt, GSI_SAME_STMT); 3102 update_stmt (stmt); 3103 gimple_set_location (stmt, loc); 3104 } 3105 3106 for (child = access->first_child; child; child = child->next_sibling) 3107 clobber_subtree (child, gsi, insert_after, loc); 3108 } 3109 3110 /* Search for an access representative for the given expression EXPR and 3111 return it or NULL if it cannot be found. */ 3112 3113 static struct access * 3114 get_access_for_expr (tree expr) 3115 { 3116 poly_int64 poffset, psize, pmax_size; 3117 HOST_WIDE_INT offset, max_size; 3118 tree base; 3119 bool reverse; 3120 3121 /* FIXME: This should not be necessary but Ada produces V_C_Es with a type of 3122 a different size than the size of its argument and we need the latter 3123 one. */ 3124 if (TREE_CODE (expr) == VIEW_CONVERT_EXPR) 3125 expr = TREE_OPERAND (expr, 0); 3126 3127 base = get_ref_base_and_extent (expr, &poffset, &psize, &pmax_size, 3128 &reverse); 3129 if (!known_size_p (pmax_size) 3130 || !pmax_size.is_constant (&max_size) 3131 || !poffset.is_constant (&offset) 3132 || !DECL_P (base)) 3133 return NULL; 3134 3135 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (base))) 3136 return NULL; 3137 3138 return get_var_base_offset_size_access (base, offset, max_size); 3139 } 3140 3141 /* Replace the expression EXPR with a scalar replacement if there is one and 3142 generate other statements to do type conversion or subtree copying if 3143 necessary. GSI is used to place newly created statements, WRITE is true if 3144 the expression is being written to (it is on a LHS of a statement or output 3145 in an assembly statement). */ 3146 3147 static bool 3148 sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write) 3149 { 3150 location_t loc; 3151 struct access *access; 3152 tree type, bfr, orig_expr; 3153 3154 if (TREE_CODE (*expr) == BIT_FIELD_REF) 3155 { 3156 bfr = *expr; 3157 expr = &TREE_OPERAND (*expr, 0); 3158 } 3159 else 3160 bfr = NULL_TREE; 3161 3162 if (TREE_CODE (*expr) == REALPART_EXPR || TREE_CODE (*expr) == IMAGPART_EXPR) 3163 expr = &TREE_OPERAND (*expr, 0); 3164 access = get_access_for_expr (*expr); 3165 if (!access) 3166 return false; 3167 type = TREE_TYPE (*expr); 3168 orig_expr = *expr; 3169 3170 loc = gimple_location (gsi_stmt (*gsi)); 3171 gimple_stmt_iterator alt_gsi = gsi_none (); 3172 if (write && stmt_ends_bb_p (gsi_stmt (*gsi))) 3173 { 3174 alt_gsi = gsi_start_edge (single_non_eh_succ (gsi_bb (*gsi))); 3175 gsi = &alt_gsi; 3176 } 3177 3178 if (access->grp_to_be_replaced) 3179 { 3180 tree repl = get_access_replacement (access); 3181 /* If we replace a non-register typed access simply use the original 3182 access expression to extract the scalar component afterwards. 3183 This happens if scalarizing a function return value or parameter 3184 like in gcc.c-torture/execute/20041124-1.c, 20050316-1.c and 3185 gcc.c-torture/compile/20011217-1.c. 3186 3187 We also want to use this when accessing a complex or vector which can 3188 be accessed as a different type too, potentially creating a need for 3189 type conversion (see PR42196) and when scalarized unions are involved 3190 in assembler statements (see PR42398). */ 3191 if (!useless_type_conversion_p (type, access->type)) 3192 { 3193 tree ref; 3194 3195 ref = build_ref_for_model (loc, orig_expr, 0, access, gsi, false); 3196 3197 if (write) 3198 { 3199 gassign *stmt; 3200 3201 if (access->grp_partial_lhs) 3202 ref = force_gimple_operand_gsi (gsi, ref, true, NULL_TREE, 3203 false, GSI_NEW_STMT); 3204 stmt = gimple_build_assign (repl, ref); 3205 gimple_set_location (stmt, loc); 3206 gsi_insert_after (gsi, stmt, GSI_NEW_STMT); 3207 } 3208 else 3209 { 3210 gassign *stmt; 3211 3212 if (access->grp_partial_lhs) 3213 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE, 3214 true, GSI_SAME_STMT); 3215 stmt = gimple_build_assign (ref, repl); 3216 gimple_set_location (stmt, loc); 3217 gsi_insert_before (gsi, stmt, GSI_SAME_STMT); 3218 } 3219 } 3220 else 3221 *expr = repl; 3222 sra_stats.exprs++; 3223 } 3224 else if (write && access->grp_to_be_debug_replaced) 3225 { 3226 gdebug *ds = gimple_build_debug_bind (get_access_replacement (access), 3227 NULL_TREE, 3228 gsi_stmt (*gsi)); 3229 gsi_insert_after (gsi, ds, GSI_NEW_STMT); 3230 } 3231 3232 if (access->first_child) 3233 { 3234 HOST_WIDE_INT start_offset, chunk_size; 3235 if (bfr 3236 && tree_fits_uhwi_p (TREE_OPERAND (bfr, 1)) 3237 && tree_fits_uhwi_p (TREE_OPERAND (bfr, 2))) 3238 { 3239 chunk_size = tree_to_uhwi (TREE_OPERAND (bfr, 1)); 3240 start_offset = access->offset 3241 + tree_to_uhwi (TREE_OPERAND (bfr, 2)); 3242 } 3243 else 3244 start_offset = chunk_size = 0; 3245 3246 generate_subtree_copies (access->first_child, orig_expr, access->offset, 3247 start_offset, chunk_size, gsi, write, write, 3248 loc); 3249 } 3250 return true; 3251 } 3252 3253 /* Where scalar replacements of the RHS have been written to when a replacement 3254 of a LHS of an assigments cannot be direclty loaded from a replacement of 3255 the RHS. */ 3256 enum unscalarized_data_handling { SRA_UDH_NONE, /* Nothing done so far. */ 3257 SRA_UDH_RIGHT, /* Data flushed to the RHS. */ 3258 SRA_UDH_LEFT }; /* Data flushed to the LHS. */ 3259 3260 struct subreplacement_assignment_data 3261 { 3262 /* Offset of the access representing the lhs of the assignment. */ 3263 HOST_WIDE_INT left_offset; 3264 3265 /* LHS and RHS of the original assignment. */ 3266 tree assignment_lhs, assignment_rhs; 3267 3268 /* Access representing the rhs of the whole assignment. */ 3269 struct access *top_racc; 3270 3271 /* Stmt iterator used for statement insertions after the original assignment. 3272 It points to the main GSI used to traverse a BB during function body 3273 modification. */ 3274 gimple_stmt_iterator *new_gsi; 3275 3276 /* Stmt iterator used for statement insertions before the original 3277 assignment. Keeps on pointing to the original statement. */ 3278 gimple_stmt_iterator old_gsi; 3279 3280 /* Location of the assignment. */ 3281 location_t loc; 3282 3283 /* Keeps the information whether we have needed to refresh replacements of 3284 the LHS and from which side of the assignments this takes place. */ 3285 enum unscalarized_data_handling refreshed; 3286 }; 3287 3288 /* Store all replacements in the access tree rooted in TOP_RACC either to their 3289 base aggregate if there are unscalarized data or directly to LHS of the 3290 statement that is pointed to by GSI otherwise. */ 3291 3292 static void 3293 handle_unscalarized_data_in_subtree (struct subreplacement_assignment_data *sad) 3294 { 3295 tree src; 3296 if (sad->top_racc->grp_unscalarized_data) 3297 { 3298 src = sad->assignment_rhs; 3299 sad->refreshed = SRA_UDH_RIGHT; 3300 } 3301 else 3302 { 3303 src = sad->assignment_lhs; 3304 sad->refreshed = SRA_UDH_LEFT; 3305 } 3306 generate_subtree_copies (sad->top_racc->first_child, src, 3307 sad->top_racc->offset, 0, 0, 3308 &sad->old_gsi, false, false, sad->loc); 3309 } 3310 3311 /* Try to generate statements to load all sub-replacements in an access subtree 3312 formed by children of LACC from scalar replacements in the SAD->top_racc 3313 subtree. If that is not possible, refresh the SAD->top_racc base aggregate 3314 and load the accesses from it. */ 3315 3316 static void 3317 load_assign_lhs_subreplacements (struct access *lacc, 3318 struct subreplacement_assignment_data *sad) 3319 { 3320 for (lacc = lacc->first_child; lacc; lacc = lacc->next_sibling) 3321 { 3322 HOST_WIDE_INT offset; 3323 offset = lacc->offset - sad->left_offset + sad->top_racc->offset; 3324 3325 if (lacc->grp_to_be_replaced) 3326 { 3327 struct access *racc; 3328 gassign *stmt; 3329 tree rhs; 3330 3331 racc = find_access_in_subtree (sad->top_racc, offset, lacc->size); 3332 if (racc && racc->grp_to_be_replaced) 3333 { 3334 rhs = get_access_replacement (racc); 3335 if (!useless_type_conversion_p (lacc->type, racc->type)) 3336 rhs = fold_build1_loc (sad->loc, VIEW_CONVERT_EXPR, 3337 lacc->type, rhs); 3338 3339 if (racc->grp_partial_lhs && lacc->grp_partial_lhs) 3340 rhs = force_gimple_operand_gsi (&sad->old_gsi, rhs, true, 3341 NULL_TREE, true, GSI_SAME_STMT); 3342 } 3343 else 3344 { 3345 /* No suitable access on the right hand side, need to load from 3346 the aggregate. See if we have to update it first... */ 3347 if (sad->refreshed == SRA_UDH_NONE) 3348 handle_unscalarized_data_in_subtree (sad); 3349 3350 if (sad->refreshed == SRA_UDH_LEFT) 3351 rhs = build_ref_for_model (sad->loc, sad->assignment_lhs, 3352 lacc->offset - sad->left_offset, 3353 lacc, sad->new_gsi, true); 3354 else 3355 rhs = build_ref_for_model (sad->loc, sad->assignment_rhs, 3356 lacc->offset - sad->left_offset, 3357 lacc, sad->new_gsi, true); 3358 if (lacc->grp_partial_lhs) 3359 rhs = force_gimple_operand_gsi (sad->new_gsi, 3360 rhs, true, NULL_TREE, 3361 false, GSI_NEW_STMT); 3362 } 3363 3364 stmt = gimple_build_assign (get_access_replacement (lacc), rhs); 3365 gsi_insert_after (sad->new_gsi, stmt, GSI_NEW_STMT); 3366 gimple_set_location (stmt, sad->loc); 3367 update_stmt (stmt); 3368 sra_stats.subreplacements++; 3369 } 3370 else 3371 { 3372 if (sad->refreshed == SRA_UDH_NONE 3373 && lacc->grp_read && !lacc->grp_covered) 3374 handle_unscalarized_data_in_subtree (sad); 3375 3376 if (lacc && lacc->grp_to_be_debug_replaced) 3377 { 3378 gdebug *ds; 3379 tree drhs; 3380 struct access *racc = find_access_in_subtree (sad->top_racc, 3381 offset, 3382 lacc->size); 3383 3384 if (racc && racc->grp_to_be_replaced) 3385 { 3386 if (racc->grp_write || constant_decl_p (racc->base)) 3387 drhs = get_access_replacement (racc); 3388 else 3389 drhs = NULL; 3390 } 3391 else if (sad->refreshed == SRA_UDH_LEFT) 3392 drhs = build_debug_ref_for_model (sad->loc, lacc->base, 3393 lacc->offset, lacc); 3394 else if (sad->refreshed == SRA_UDH_RIGHT) 3395 drhs = build_debug_ref_for_model (sad->loc, sad->top_racc->base, 3396 offset, lacc); 3397 else 3398 drhs = NULL_TREE; 3399 if (drhs 3400 && !useless_type_conversion_p (lacc->type, TREE_TYPE (drhs))) 3401 drhs = fold_build1_loc (sad->loc, VIEW_CONVERT_EXPR, 3402 lacc->type, drhs); 3403 ds = gimple_build_debug_bind (get_access_replacement (lacc), 3404 drhs, gsi_stmt (sad->old_gsi)); 3405 gsi_insert_after (sad->new_gsi, ds, GSI_NEW_STMT); 3406 } 3407 } 3408 3409 if (lacc->first_child) 3410 load_assign_lhs_subreplacements (lacc, sad); 3411 } 3412 } 3413 3414 /* Result code for SRA assignment modification. */ 3415 enum assignment_mod_result { SRA_AM_NONE, /* nothing done for the stmt */ 3416 SRA_AM_MODIFIED, /* stmt changed but not 3417 removed */ 3418 SRA_AM_REMOVED }; /* stmt eliminated */ 3419 3420 /* Modify assignments with a CONSTRUCTOR on their RHS. STMT contains a pointer 3421 to the assignment and GSI is the statement iterator pointing at it. Returns 3422 the same values as sra_modify_assign. */ 3423 3424 static enum assignment_mod_result 3425 sra_modify_constructor_assign (gimple *stmt, gimple_stmt_iterator *gsi) 3426 { 3427 tree lhs = gimple_assign_lhs (stmt); 3428 struct access *acc = get_access_for_expr (lhs); 3429 if (!acc) 3430 return SRA_AM_NONE; 3431 location_t loc = gimple_location (stmt); 3432 3433 if (gimple_clobber_p (stmt)) 3434 { 3435 /* Clobber the replacement variable. */ 3436 clobber_subtree (acc, gsi, !acc->grp_covered, loc); 3437 /* Remove clobbers of fully scalarized variables, they are dead. */ 3438 if (acc->grp_covered) 3439 { 3440 unlink_stmt_vdef (stmt); 3441 gsi_remove (gsi, true); 3442 release_defs (stmt); 3443 return SRA_AM_REMOVED; 3444 } 3445 else 3446 return SRA_AM_MODIFIED; 3447 } 3448 3449 if (CONSTRUCTOR_NELTS (gimple_assign_rhs1 (stmt)) > 0) 3450 { 3451 /* I have never seen this code path trigger but if it can happen the 3452 following should handle it gracefully. */ 3453 if (access_has_children_p (acc)) 3454 generate_subtree_copies (acc->first_child, lhs, acc->offset, 0, 0, gsi, 3455 true, true, loc); 3456 return SRA_AM_MODIFIED; 3457 } 3458 3459 if (acc->grp_covered) 3460 { 3461 init_subtree_with_zero (acc, gsi, false, loc); 3462 unlink_stmt_vdef (stmt); 3463 gsi_remove (gsi, true); 3464 release_defs (stmt); 3465 return SRA_AM_REMOVED; 3466 } 3467 else 3468 { 3469 init_subtree_with_zero (acc, gsi, true, loc); 3470 return SRA_AM_MODIFIED; 3471 } 3472 } 3473 3474 /* Create and return a new suitable default definition SSA_NAME for RACC which 3475 is an access describing an uninitialized part of an aggregate that is being 3476 loaded. */ 3477 3478 static tree 3479 get_repl_default_def_ssa_name (struct access *racc) 3480 { 3481 gcc_checking_assert (!racc->grp_to_be_replaced 3482 && !racc->grp_to_be_debug_replaced); 3483 if (!racc->replacement_decl) 3484 racc->replacement_decl = create_access_replacement (racc); 3485 return get_or_create_ssa_default_def (cfun, racc->replacement_decl); 3486 } 3487 3488 /* Examine both sides of the assignment statement pointed to by STMT, replace 3489 them with a scalare replacement if there is one and generate copying of 3490 replacements if scalarized aggregates have been used in the assignment. GSI 3491 is used to hold generated statements for type conversions and subtree 3492 copying. */ 3493 3494 static enum assignment_mod_result 3495 sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi) 3496 { 3497 struct access *lacc, *racc; 3498 tree lhs, rhs; 3499 bool modify_this_stmt = false; 3500 bool force_gimple_rhs = false; 3501 location_t loc; 3502 gimple_stmt_iterator orig_gsi = *gsi; 3503 3504 if (!gimple_assign_single_p (stmt)) 3505 return SRA_AM_NONE; 3506 lhs = gimple_assign_lhs (stmt); 3507 rhs = gimple_assign_rhs1 (stmt); 3508 3509 if (TREE_CODE (rhs) == CONSTRUCTOR) 3510 return sra_modify_constructor_assign (stmt, gsi); 3511 3512 if (TREE_CODE (rhs) == REALPART_EXPR || TREE_CODE (lhs) == REALPART_EXPR 3513 || TREE_CODE (rhs) == IMAGPART_EXPR || TREE_CODE (lhs) == IMAGPART_EXPR 3514 || TREE_CODE (rhs) == BIT_FIELD_REF || TREE_CODE (lhs) == BIT_FIELD_REF) 3515 { 3516 modify_this_stmt = sra_modify_expr (gimple_assign_rhs1_ptr (stmt), 3517 gsi, false); 3518 modify_this_stmt |= sra_modify_expr (gimple_assign_lhs_ptr (stmt), 3519 gsi, true); 3520 return modify_this_stmt ? SRA_AM_MODIFIED : SRA_AM_NONE; 3521 } 3522 3523 lacc = get_access_for_expr (lhs); 3524 racc = get_access_for_expr (rhs); 3525 if (!lacc && !racc) 3526 return SRA_AM_NONE; 3527 /* Avoid modifying initializations of constant-pool replacements. */ 3528 if (racc && (racc->replacement_decl == lhs)) 3529 return SRA_AM_NONE; 3530 3531 loc = gimple_location (stmt); 3532 if (lacc && lacc->grp_to_be_replaced) 3533 { 3534 lhs = get_access_replacement (lacc); 3535 gimple_assign_set_lhs (stmt, lhs); 3536 modify_this_stmt = true; 3537 if (lacc->grp_partial_lhs) 3538 force_gimple_rhs = true; 3539 sra_stats.exprs++; 3540 } 3541 3542 if (racc && racc->grp_to_be_replaced) 3543 { 3544 rhs = get_access_replacement (racc); 3545 modify_this_stmt = true; 3546 if (racc->grp_partial_lhs) 3547 force_gimple_rhs = true; 3548 sra_stats.exprs++; 3549 } 3550 else if (racc 3551 && !racc->grp_unscalarized_data 3552 && !racc->grp_unscalarizable_region 3553 && TREE_CODE (lhs) == SSA_NAME 3554 && !access_has_replacements_p (racc)) 3555 { 3556 rhs = get_repl_default_def_ssa_name (racc); 3557 modify_this_stmt = true; 3558 sra_stats.exprs++; 3559 } 3560 3561 if (modify_this_stmt) 3562 { 3563 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs))) 3564 { 3565 /* If we can avoid creating a VIEW_CONVERT_EXPR do so. 3566 ??? This should move to fold_stmt which we simply should 3567 call after building a VIEW_CONVERT_EXPR here. */ 3568 if (AGGREGATE_TYPE_P (TREE_TYPE (lhs)) 3569 && !contains_bitfld_component_ref_p (lhs)) 3570 { 3571 lhs = build_ref_for_model (loc, lhs, 0, racc, gsi, false); 3572 gimple_assign_set_lhs (stmt, lhs); 3573 } 3574 else if (AGGREGATE_TYPE_P (TREE_TYPE (rhs)) 3575 && !contains_vce_or_bfcref_p (rhs)) 3576 rhs = build_ref_for_model (loc, rhs, 0, lacc, gsi, false); 3577 3578 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs))) 3579 { 3580 rhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (lhs), 3581 rhs); 3582 if (is_gimple_reg_type (TREE_TYPE (lhs)) 3583 && TREE_CODE (lhs) != SSA_NAME) 3584 force_gimple_rhs = true; 3585 } 3586 } 3587 } 3588 3589 if (lacc && lacc->grp_to_be_debug_replaced) 3590 { 3591 tree dlhs = get_access_replacement (lacc); 3592 tree drhs = unshare_expr (rhs); 3593 if (!useless_type_conversion_p (TREE_TYPE (dlhs), TREE_TYPE (drhs))) 3594 { 3595 if (AGGREGATE_TYPE_P (TREE_TYPE (drhs)) 3596 && !contains_vce_or_bfcref_p (drhs)) 3597 drhs = build_debug_ref_for_model (loc, drhs, 0, lacc); 3598 if (drhs 3599 && !useless_type_conversion_p (TREE_TYPE (dlhs), 3600 TREE_TYPE (drhs))) 3601 drhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR, 3602 TREE_TYPE (dlhs), drhs); 3603 } 3604 gdebug *ds = gimple_build_debug_bind (dlhs, drhs, stmt); 3605 gsi_insert_before (gsi, ds, GSI_SAME_STMT); 3606 } 3607 3608 /* From this point on, the function deals with assignments in between 3609 aggregates when at least one has scalar reductions of some of its 3610 components. There are three possible scenarios: Both the LHS and RHS have 3611 to-be-scalarized components, 2) only the RHS has or 3) only the LHS has. 3612 3613 In the first case, we would like to load the LHS components from RHS 3614 components whenever possible. If that is not possible, we would like to 3615 read it directly from the RHS (after updating it by storing in it its own 3616 components). If there are some necessary unscalarized data in the LHS, 3617 those will be loaded by the original assignment too. If neither of these 3618 cases happen, the original statement can be removed. Most of this is done 3619 by load_assign_lhs_subreplacements. 3620 3621 In the second case, we would like to store all RHS scalarized components 3622 directly into LHS and if they cover the aggregate completely, remove the 3623 statement too. In the third case, we want the LHS components to be loaded 3624 directly from the RHS (DSE will remove the original statement if it 3625 becomes redundant). 3626 3627 This is a bit complex but manageable when types match and when unions do 3628 not cause confusion in a way that we cannot really load a component of LHS 3629 from the RHS or vice versa (the access representing this level can have 3630 subaccesses that are accessible only through a different union field at a 3631 higher level - different from the one used in the examined expression). 3632 Unions are fun. 3633 3634 Therefore, I specially handle a fourth case, happening when there is a 3635 specific type cast or it is impossible to locate a scalarized subaccess on 3636 the other side of the expression. If that happens, I simply "refresh" the 3637 RHS by storing in it is scalarized components leave the original statement 3638 there to do the copying and then load the scalar replacements of the LHS. 3639 This is what the first branch does. */ 3640 3641 if (modify_this_stmt 3642 || gimple_has_volatile_ops (stmt) 3643 || contains_vce_or_bfcref_p (rhs) 3644 || contains_vce_or_bfcref_p (lhs) 3645 || stmt_ends_bb_p (stmt)) 3646 { 3647 /* No need to copy into a constant-pool, it comes pre-initialized. */ 3648 if (access_has_children_p (racc) && !constant_decl_p (racc->base)) 3649 generate_subtree_copies (racc->first_child, rhs, racc->offset, 0, 0, 3650 gsi, false, false, loc); 3651 if (access_has_children_p (lacc)) 3652 { 3653 gimple_stmt_iterator alt_gsi = gsi_none (); 3654 if (stmt_ends_bb_p (stmt)) 3655 { 3656 alt_gsi = gsi_start_edge (single_non_eh_succ (gsi_bb (*gsi))); 3657 gsi = &alt_gsi; 3658 } 3659 generate_subtree_copies (lacc->first_child, lhs, lacc->offset, 0, 0, 3660 gsi, true, true, loc); 3661 } 3662 sra_stats.separate_lhs_rhs_handling++; 3663 3664 /* This gimplification must be done after generate_subtree_copies, 3665 lest we insert the subtree copies in the middle of the gimplified 3666 sequence. */ 3667 if (force_gimple_rhs) 3668 rhs = force_gimple_operand_gsi (&orig_gsi, rhs, true, NULL_TREE, 3669 true, GSI_SAME_STMT); 3670 if (gimple_assign_rhs1 (stmt) != rhs) 3671 { 3672 modify_this_stmt = true; 3673 gimple_assign_set_rhs_from_tree (&orig_gsi, rhs); 3674 gcc_assert (stmt == gsi_stmt (orig_gsi)); 3675 } 3676 3677 return modify_this_stmt ? SRA_AM_MODIFIED : SRA_AM_NONE; 3678 } 3679 else 3680 { 3681 if (access_has_children_p (lacc) 3682 && access_has_children_p (racc) 3683 /* When an access represents an unscalarizable region, it usually 3684 represents accesses with variable offset and thus must not be used 3685 to generate new memory accesses. */ 3686 && !lacc->grp_unscalarizable_region 3687 && !racc->grp_unscalarizable_region) 3688 { 3689 struct subreplacement_assignment_data sad; 3690 3691 sad.left_offset = lacc->offset; 3692 sad.assignment_lhs = lhs; 3693 sad.assignment_rhs = rhs; 3694 sad.top_racc = racc; 3695 sad.old_gsi = *gsi; 3696 sad.new_gsi = gsi; 3697 sad.loc = gimple_location (stmt); 3698 sad.refreshed = SRA_UDH_NONE; 3699 3700 if (lacc->grp_read && !lacc->grp_covered) 3701 handle_unscalarized_data_in_subtree (&sad); 3702 3703 load_assign_lhs_subreplacements (lacc, &sad); 3704 if (sad.refreshed != SRA_UDH_RIGHT) 3705 { 3706 gsi_next (gsi); 3707 unlink_stmt_vdef (stmt); 3708 gsi_remove (&sad.old_gsi, true); 3709 release_defs (stmt); 3710 sra_stats.deleted++; 3711 return SRA_AM_REMOVED; 3712 } 3713 } 3714 else 3715 { 3716 if (access_has_children_p (racc) 3717 && !racc->grp_unscalarized_data 3718 && TREE_CODE (lhs) != SSA_NAME) 3719 { 3720 if (dump_file) 3721 { 3722 fprintf (dump_file, "Removing load: "); 3723 print_gimple_stmt (dump_file, stmt, 0); 3724 } 3725 generate_subtree_copies (racc->first_child, lhs, 3726 racc->offset, 0, 0, gsi, 3727 false, false, loc); 3728 gcc_assert (stmt == gsi_stmt (*gsi)); 3729 unlink_stmt_vdef (stmt); 3730 gsi_remove (gsi, true); 3731 release_defs (stmt); 3732 sra_stats.deleted++; 3733 return SRA_AM_REMOVED; 3734 } 3735 /* Restore the aggregate RHS from its components so the 3736 prevailing aggregate copy does the right thing. */ 3737 if (access_has_children_p (racc)) 3738 generate_subtree_copies (racc->first_child, rhs, racc->offset, 0, 0, 3739 gsi, false, false, loc); 3740 /* Re-load the components of the aggregate copy destination. 3741 But use the RHS aggregate to load from to expose more 3742 optimization opportunities. */ 3743 if (access_has_children_p (lacc)) 3744 generate_subtree_copies (lacc->first_child, rhs, lacc->offset, 3745 0, 0, gsi, true, true, loc); 3746 } 3747 3748 return SRA_AM_NONE; 3749 } 3750 } 3751 3752 /* Set any scalar replacements of values in the constant pool to the initial 3753 value of the constant. (Constant-pool decls like *.LC0 have effectively 3754 been initialized before the program starts, we must do the same for their 3755 replacements.) Thus, we output statements like 'SR.1 = *.LC0[0];' into 3756 the function's entry block. */ 3757 3758 static void 3759 initialize_constant_pool_replacements (void) 3760 { 3761 gimple_seq seq = NULL; 3762 gimple_stmt_iterator gsi = gsi_start (seq); 3763 bitmap_iterator bi; 3764 unsigned i; 3765 3766 EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap, 0, i, bi) 3767 { 3768 tree var = candidate (i); 3769 if (!constant_decl_p (var)) 3770 continue; 3771 vec<access_p> *access_vec = get_base_access_vector (var); 3772 if (!access_vec) 3773 continue; 3774 for (unsigned i = 0; i < access_vec->length (); i++) 3775 { 3776 struct access *access = (*access_vec)[i]; 3777 if (!access->replacement_decl) 3778 continue; 3779 gassign *stmt 3780 = gimple_build_assign (get_access_replacement (access), 3781 unshare_expr (access->expr)); 3782 if (dump_file && (dump_flags & TDF_DETAILS)) 3783 { 3784 fprintf (dump_file, "Generating constant initializer: "); 3785 print_gimple_stmt (dump_file, stmt, 0); 3786 fprintf (dump_file, "\n"); 3787 } 3788 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT); 3789 update_stmt (stmt); 3790 } 3791 } 3792 3793 seq = gsi_seq (gsi); 3794 if (seq) 3795 gsi_insert_seq_on_edge_immediate ( 3796 single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)), seq); 3797 } 3798 3799 /* Traverse the function body and all modifications as decided in 3800 analyze_all_variable_accesses. Return true iff the CFG has been 3801 changed. */ 3802 3803 static bool 3804 sra_modify_function_body (void) 3805 { 3806 bool cfg_changed = false; 3807 basic_block bb; 3808 3809 initialize_constant_pool_replacements (); 3810 3811 FOR_EACH_BB_FN (bb, cfun) 3812 { 3813 gimple_stmt_iterator gsi = gsi_start_bb (bb); 3814 while (!gsi_end_p (gsi)) 3815 { 3816 gimple *stmt = gsi_stmt (gsi); 3817 enum assignment_mod_result assign_result; 3818 bool modified = false, deleted = false; 3819 tree *t; 3820 unsigned i; 3821 3822 switch (gimple_code (stmt)) 3823 { 3824 case GIMPLE_RETURN: 3825 t = gimple_return_retval_ptr (as_a <greturn *> (stmt)); 3826 if (*t != NULL_TREE) 3827 modified |= sra_modify_expr (t, &gsi, false); 3828 break; 3829 3830 case GIMPLE_ASSIGN: 3831 assign_result = sra_modify_assign (stmt, &gsi); 3832 modified |= assign_result == SRA_AM_MODIFIED; 3833 deleted = assign_result == SRA_AM_REMOVED; 3834 break; 3835 3836 case GIMPLE_CALL: 3837 /* Operands must be processed before the lhs. */ 3838 for (i = 0; i < gimple_call_num_args (stmt); i++) 3839 { 3840 t = gimple_call_arg_ptr (stmt, i); 3841 modified |= sra_modify_expr (t, &gsi, false); 3842 } 3843 3844 if (gimple_call_lhs (stmt)) 3845 { 3846 t = gimple_call_lhs_ptr (stmt); 3847 modified |= sra_modify_expr (t, &gsi, true); 3848 } 3849 break; 3850 3851 case GIMPLE_ASM: 3852 { 3853 gasm *asm_stmt = as_a <gasm *> (stmt); 3854 for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++) 3855 { 3856 t = &TREE_VALUE (gimple_asm_input_op (asm_stmt, i)); 3857 modified |= sra_modify_expr (t, &gsi, false); 3858 } 3859 for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++) 3860 { 3861 t = &TREE_VALUE (gimple_asm_output_op (asm_stmt, i)); 3862 modified |= sra_modify_expr (t, &gsi, true); 3863 } 3864 } 3865 break; 3866 3867 default: 3868 break; 3869 } 3870 3871 if (modified) 3872 { 3873 update_stmt (stmt); 3874 if (maybe_clean_eh_stmt (stmt) 3875 && gimple_purge_dead_eh_edges (gimple_bb (stmt))) 3876 cfg_changed = true; 3877 } 3878 if (!deleted) 3879 gsi_next (&gsi); 3880 } 3881 } 3882 3883 gsi_commit_edge_inserts (); 3884 return cfg_changed; 3885 } 3886 3887 /* Generate statements initializing scalar replacements of parts of function 3888 parameters. */ 3889 3890 static void 3891 initialize_parameter_reductions (void) 3892 { 3893 gimple_stmt_iterator gsi; 3894 gimple_seq seq = NULL; 3895 tree parm; 3896 3897 gsi = gsi_start (seq); 3898 for (parm = DECL_ARGUMENTS (current_function_decl); 3899 parm; 3900 parm = DECL_CHAIN (parm)) 3901 { 3902 vec<access_p> *access_vec; 3903 struct access *access; 3904 3905 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (parm))) 3906 continue; 3907 access_vec = get_base_access_vector (parm); 3908 if (!access_vec) 3909 continue; 3910 3911 for (access = (*access_vec)[0]; 3912 access; 3913 access = access->next_grp) 3914 generate_subtree_copies (access, parm, 0, 0, 0, &gsi, true, true, 3915 EXPR_LOCATION (parm)); 3916 } 3917 3918 seq = gsi_seq (gsi); 3919 if (seq) 3920 gsi_insert_seq_on_edge_immediate (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)), seq); 3921 } 3922 3923 /* The "main" function of intraprocedural SRA passes. Runs the analysis and if 3924 it reveals there are components of some aggregates to be scalarized, it runs 3925 the required transformations. */ 3926 static unsigned int 3927 perform_intra_sra (void) 3928 { 3929 int ret = 0; 3930 sra_initialize (); 3931 3932 if (!find_var_candidates ()) 3933 goto out; 3934 3935 if (!scan_function ()) 3936 goto out; 3937 3938 if (!analyze_all_variable_accesses ()) 3939 goto out; 3940 3941 if (sra_modify_function_body ()) 3942 ret = TODO_update_ssa | TODO_cleanup_cfg; 3943 else 3944 ret = TODO_update_ssa; 3945 initialize_parameter_reductions (); 3946 3947 statistics_counter_event (cfun, "Scalar replacements created", 3948 sra_stats.replacements); 3949 statistics_counter_event (cfun, "Modified expressions", sra_stats.exprs); 3950 statistics_counter_event (cfun, "Subtree copy stmts", 3951 sra_stats.subtree_copies); 3952 statistics_counter_event (cfun, "Subreplacement stmts", 3953 sra_stats.subreplacements); 3954 statistics_counter_event (cfun, "Deleted stmts", sra_stats.deleted); 3955 statistics_counter_event (cfun, "Separate LHS and RHS handling", 3956 sra_stats.separate_lhs_rhs_handling); 3957 3958 out: 3959 sra_deinitialize (); 3960 return ret; 3961 } 3962 3963 /* Perform early intraprocedural SRA. */ 3964 static unsigned int 3965 early_intra_sra (void) 3966 { 3967 sra_mode = SRA_MODE_EARLY_INTRA; 3968 return perform_intra_sra (); 3969 } 3970 3971 /* Perform "late" intraprocedural SRA. */ 3972 static unsigned int 3973 late_intra_sra (void) 3974 { 3975 sra_mode = SRA_MODE_INTRA; 3976 return perform_intra_sra (); 3977 } 3978 3979 3980 static bool 3981 gate_intra_sra (void) 3982 { 3983 return flag_tree_sra != 0 && dbg_cnt (tree_sra); 3984 } 3985 3986 3987 namespace { 3988 3989 const pass_data pass_data_sra_early = 3990 { 3991 GIMPLE_PASS, /* type */ 3992 "esra", /* name */ 3993 OPTGROUP_NONE, /* optinfo_flags */ 3994 TV_TREE_SRA, /* tv_id */ 3995 ( PROP_cfg | PROP_ssa ), /* properties_required */ 3996 0, /* properties_provided */ 3997 0, /* properties_destroyed */ 3998 0, /* todo_flags_start */ 3999 TODO_update_ssa, /* todo_flags_finish */ 4000 }; 4001 4002 class pass_sra_early : public gimple_opt_pass 4003 { 4004 public: 4005 pass_sra_early (gcc::context *ctxt) 4006 : gimple_opt_pass (pass_data_sra_early, ctxt) 4007 {} 4008 4009 /* opt_pass methods: */ 4010 virtual bool gate (function *) { return gate_intra_sra (); } 4011 virtual unsigned int execute (function *) { return early_intra_sra (); } 4012 4013 }; // class pass_sra_early 4014 4015 } // anon namespace 4016 4017 gimple_opt_pass * 4018 make_pass_sra_early (gcc::context *ctxt) 4019 { 4020 return new pass_sra_early (ctxt); 4021 } 4022 4023 namespace { 4024 4025 const pass_data pass_data_sra = 4026 { 4027 GIMPLE_PASS, /* type */ 4028 "sra", /* name */ 4029 OPTGROUP_NONE, /* optinfo_flags */ 4030 TV_TREE_SRA, /* tv_id */ 4031 ( PROP_cfg | PROP_ssa ), /* properties_required */ 4032 0, /* properties_provided */ 4033 0, /* properties_destroyed */ 4034 TODO_update_address_taken, /* todo_flags_start */ 4035 TODO_update_ssa, /* todo_flags_finish */ 4036 }; 4037 4038 class pass_sra : public gimple_opt_pass 4039 { 4040 public: 4041 pass_sra (gcc::context *ctxt) 4042 : gimple_opt_pass (pass_data_sra, ctxt) 4043 {} 4044 4045 /* opt_pass methods: */ 4046 virtual bool gate (function *) { return gate_intra_sra (); } 4047 virtual unsigned int execute (function *) { return late_intra_sra (); } 4048 4049 }; // class pass_sra 4050 4051 } // anon namespace 4052 4053 gimple_opt_pass * 4054 make_pass_sra (gcc::context *ctxt) 4055 { 4056 return new pass_sra (ctxt); 4057 } 4058 4059 4060 /* Return true iff PARM (which must be a parm_decl) is an unused scalar 4061 parameter. */ 4062 4063 static bool 4064 is_unused_scalar_param (tree parm) 4065 { 4066 tree name; 4067 return (is_gimple_reg (parm) 4068 && (!(name = ssa_default_def (cfun, parm)) 4069 || has_zero_uses (name))); 4070 } 4071 4072 /* Scan immediate uses of a default definition SSA name of a parameter PARM and 4073 examine whether there are any direct or otherwise infeasible ones. If so, 4074 return true, otherwise return false. PARM must be a gimple register with a 4075 non-NULL default definition. */ 4076 4077 static bool 4078 ptr_parm_has_direct_uses (tree parm) 4079 { 4080 imm_use_iterator ui; 4081 gimple *stmt; 4082 tree name = ssa_default_def (cfun, parm); 4083 bool ret = false; 4084 4085 FOR_EACH_IMM_USE_STMT (stmt, ui, name) 4086 { 4087 int uses_ok = 0; 4088 use_operand_p use_p; 4089 4090 if (is_gimple_debug (stmt)) 4091 continue; 4092 4093 /* Valid uses include dereferences on the lhs and the rhs. */ 4094 if (gimple_has_lhs (stmt)) 4095 { 4096 tree lhs = gimple_get_lhs (stmt); 4097 while (handled_component_p (lhs)) 4098 lhs = TREE_OPERAND (lhs, 0); 4099 if (TREE_CODE (lhs) == MEM_REF 4100 && TREE_OPERAND (lhs, 0) == name 4101 && integer_zerop (TREE_OPERAND (lhs, 1)) 4102 && types_compatible_p (TREE_TYPE (lhs), 4103 TREE_TYPE (TREE_TYPE (name))) 4104 && !TREE_THIS_VOLATILE (lhs)) 4105 uses_ok++; 4106 } 4107 if (gimple_assign_single_p (stmt)) 4108 { 4109 tree rhs = gimple_assign_rhs1 (stmt); 4110 while (handled_component_p (rhs)) 4111 rhs = TREE_OPERAND (rhs, 0); 4112 if (TREE_CODE (rhs) == MEM_REF 4113 && TREE_OPERAND (rhs, 0) == name 4114 && integer_zerop (TREE_OPERAND (rhs, 1)) 4115 && types_compatible_p (TREE_TYPE (rhs), 4116 TREE_TYPE (TREE_TYPE (name))) 4117 && !TREE_THIS_VOLATILE (rhs)) 4118 uses_ok++; 4119 } 4120 else if (is_gimple_call (stmt)) 4121 { 4122 unsigned i; 4123 for (i = 0; i < gimple_call_num_args (stmt); ++i) 4124 { 4125 tree arg = gimple_call_arg (stmt, i); 4126 while (handled_component_p (arg)) 4127 arg = TREE_OPERAND (arg, 0); 4128 if (TREE_CODE (arg) == MEM_REF 4129 && TREE_OPERAND (arg, 0) == name 4130 && integer_zerop (TREE_OPERAND (arg, 1)) 4131 && types_compatible_p (TREE_TYPE (arg), 4132 TREE_TYPE (TREE_TYPE (name))) 4133 && !TREE_THIS_VOLATILE (arg)) 4134 uses_ok++; 4135 } 4136 } 4137 4138 /* If the number of valid uses does not match the number of 4139 uses in this stmt there is an unhandled use. */ 4140 FOR_EACH_IMM_USE_ON_STMT (use_p, ui) 4141 --uses_ok; 4142 4143 if (uses_ok != 0) 4144 ret = true; 4145 4146 if (ret) 4147 BREAK_FROM_IMM_USE_STMT (ui); 4148 } 4149 4150 return ret; 4151 } 4152 4153 /* Identify candidates for reduction for IPA-SRA based on their type and mark 4154 them in candidate_bitmap. Note that these do not necessarily include 4155 parameter which are unused and thus can be removed. Return true iff any 4156 such candidate has been found. */ 4157 4158 static bool 4159 find_param_candidates (void) 4160 { 4161 tree parm; 4162 int count = 0; 4163 bool ret = false; 4164 const char *msg; 4165 4166 for (parm = DECL_ARGUMENTS (current_function_decl); 4167 parm; 4168 parm = DECL_CHAIN (parm)) 4169 { 4170 tree type = TREE_TYPE (parm); 4171 tree_node **slot; 4172 4173 count++; 4174 4175 if (TREE_THIS_VOLATILE (parm) 4176 || TREE_ADDRESSABLE (parm) 4177 || (!is_gimple_reg_type (type) && is_va_list_type (type))) 4178 continue; 4179 4180 if (is_unused_scalar_param (parm)) 4181 { 4182 ret = true; 4183 continue; 4184 } 4185 4186 if (POINTER_TYPE_P (type)) 4187 { 4188 type = TREE_TYPE (type); 4189 4190 if (TREE_CODE (type) == FUNCTION_TYPE 4191 || TYPE_VOLATILE (type) 4192 || (TREE_CODE (type) == ARRAY_TYPE 4193 && TYPE_NONALIASED_COMPONENT (type)) 4194 || !is_gimple_reg (parm) 4195 || is_va_list_type (type) 4196 || ptr_parm_has_direct_uses (parm)) 4197 continue; 4198 } 4199 else if (!AGGREGATE_TYPE_P (type)) 4200 continue; 4201 4202 if (!COMPLETE_TYPE_P (type) 4203 || !tree_fits_uhwi_p (TYPE_SIZE (type)) 4204 || tree_to_uhwi (TYPE_SIZE (type)) == 0 4205 || (AGGREGATE_TYPE_P (type) 4206 && type_internals_preclude_sra_p (type, &msg))) 4207 continue; 4208 4209 bitmap_set_bit (candidate_bitmap, DECL_UID (parm)); 4210 slot = candidates->find_slot_with_hash (parm, DECL_UID (parm), INSERT); 4211 *slot = parm; 4212 4213 ret = true; 4214 if (dump_file && (dump_flags & TDF_DETAILS)) 4215 { 4216 fprintf (dump_file, "Candidate (%d): ", DECL_UID (parm)); 4217 print_generic_expr (dump_file, parm); 4218 fprintf (dump_file, "\n"); 4219 } 4220 } 4221 4222 func_param_count = count; 4223 return ret; 4224 } 4225 4226 /* Callback of walk_aliased_vdefs, marks the access passed as DATA as 4227 maybe_modified. */ 4228 4229 static bool 4230 mark_maybe_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED, 4231 void *data) 4232 { 4233 struct access *repr = (struct access *) data; 4234 4235 repr->grp_maybe_modified = 1; 4236 return true; 4237 } 4238 4239 /* Analyze what representatives (in linked lists accessible from 4240 REPRESENTATIVES) can be modified by side effects of statements in the 4241 current function. */ 4242 4243 static void 4244 analyze_modified_params (vec<access_p> representatives) 4245 { 4246 int i; 4247 4248 for (i = 0; i < func_param_count; i++) 4249 { 4250 struct access *repr; 4251 4252 for (repr = representatives[i]; 4253 repr; 4254 repr = repr->next_grp) 4255 { 4256 struct access *access; 4257 bitmap visited; 4258 ao_ref ar; 4259 4260 if (no_accesses_p (repr)) 4261 continue; 4262 if (!POINTER_TYPE_P (TREE_TYPE (repr->base)) 4263 || repr->grp_maybe_modified) 4264 continue; 4265 4266 ao_ref_init (&ar, repr->expr); 4267 visited = BITMAP_ALLOC (NULL); 4268 for (access = repr; access; access = access->next_sibling) 4269 { 4270 /* All accesses are read ones, otherwise grp_maybe_modified would 4271 be trivially set. */ 4272 walk_aliased_vdefs (&ar, gimple_vuse (access->stmt), 4273 mark_maybe_modified, repr, &visited); 4274 if (repr->grp_maybe_modified) 4275 break; 4276 } 4277 BITMAP_FREE (visited); 4278 } 4279 } 4280 } 4281 4282 /* Propagate distances in bb_dereferences in the opposite direction than the 4283 control flow edges, in each step storing the maximum of the current value 4284 and the minimum of all successors. These steps are repeated until the table 4285 stabilizes. Note that BBs which might terminate the functions (according to 4286 final_bbs bitmap) never updated in this way. */ 4287 4288 static void 4289 propagate_dereference_distances (void) 4290 { 4291 basic_block bb; 4292 4293 auto_vec<basic_block> queue (last_basic_block_for_fn (cfun)); 4294 queue.quick_push (ENTRY_BLOCK_PTR_FOR_FN (cfun)); 4295 FOR_EACH_BB_FN (bb, cfun) 4296 { 4297 queue.quick_push (bb); 4298 bb->aux = bb; 4299 } 4300 4301 while (!queue.is_empty ()) 4302 { 4303 edge_iterator ei; 4304 edge e; 4305 bool change = false; 4306 int i; 4307 4308 bb = queue.pop (); 4309 bb->aux = NULL; 4310 4311 if (bitmap_bit_p (final_bbs, bb->index)) 4312 continue; 4313 4314 for (i = 0; i < func_param_count; i++) 4315 { 4316 int idx = bb->index * func_param_count + i; 4317 bool first = true; 4318 HOST_WIDE_INT inh = 0; 4319 4320 FOR_EACH_EDGE (e, ei, bb->succs) 4321 { 4322 int succ_idx = e->dest->index * func_param_count + i; 4323 4324 if (e->src == EXIT_BLOCK_PTR_FOR_FN (cfun)) 4325 continue; 4326 4327 if (first) 4328 { 4329 first = false; 4330 inh = bb_dereferences [succ_idx]; 4331 } 4332 else if (bb_dereferences [succ_idx] < inh) 4333 inh = bb_dereferences [succ_idx]; 4334 } 4335 4336 if (!first && bb_dereferences[idx] < inh) 4337 { 4338 bb_dereferences[idx] = inh; 4339 change = true; 4340 } 4341 } 4342 4343 if (change && !bitmap_bit_p (final_bbs, bb->index)) 4344 FOR_EACH_EDGE (e, ei, bb->preds) 4345 { 4346 if (e->src->aux) 4347 continue; 4348 4349 e->src->aux = e->src; 4350 queue.quick_push (e->src); 4351 } 4352 } 4353 } 4354 4355 /* Dump a dereferences TABLE with heading STR to file F. */ 4356 4357 static void 4358 dump_dereferences_table (FILE *f, const char *str, HOST_WIDE_INT *table) 4359 { 4360 basic_block bb; 4361 4362 fprintf (dump_file, "%s", str); 4363 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), 4364 EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb) 4365 { 4366 fprintf (f, "%4i %i ", bb->index, bitmap_bit_p (final_bbs, bb->index)); 4367 if (bb != EXIT_BLOCK_PTR_FOR_FN (cfun)) 4368 { 4369 int i; 4370 for (i = 0; i < func_param_count; i++) 4371 { 4372 int idx = bb->index * func_param_count + i; 4373 fprintf (f, " %4" HOST_WIDE_INT_PRINT "d", table[idx]); 4374 } 4375 } 4376 fprintf (f, "\n"); 4377 } 4378 fprintf (dump_file, "\n"); 4379 } 4380 4381 /* Determine what (parts of) parameters passed by reference that are not 4382 assigned to are not certainly dereferenced in this function and thus the 4383 dereferencing cannot be safely moved to the caller without potentially 4384 introducing a segfault. Mark such REPRESENTATIVES as 4385 grp_not_necessarilly_dereferenced. 4386 4387 The dereferenced maximum "distance," i.e. the offset + size of the accessed 4388 part is calculated rather than simple booleans are calculated for each 4389 pointer parameter to handle cases when only a fraction of the whole 4390 aggregate is allocated (see testsuite/gcc.c-torture/execute/ipa-sra-2.c for 4391 an example). 4392 4393 The maximum dereference distances for each pointer parameter and BB are 4394 already stored in bb_dereference. This routine simply propagates these 4395 values upwards by propagate_dereference_distances and then compares the 4396 distances of individual parameters in the ENTRY BB to the equivalent 4397 distances of each representative of a (fraction of a) parameter. */ 4398 4399 static void 4400 analyze_caller_dereference_legality (vec<access_p> representatives) 4401 { 4402 int i; 4403 4404 if (dump_file && (dump_flags & TDF_DETAILS)) 4405 dump_dereferences_table (dump_file, 4406 "Dereference table before propagation:\n", 4407 bb_dereferences); 4408 4409 propagate_dereference_distances (); 4410 4411 if (dump_file && (dump_flags & TDF_DETAILS)) 4412 dump_dereferences_table (dump_file, 4413 "Dereference table after propagation:\n", 4414 bb_dereferences); 4415 4416 for (i = 0; i < func_param_count; i++) 4417 { 4418 struct access *repr = representatives[i]; 4419 int idx = ENTRY_BLOCK_PTR_FOR_FN (cfun)->index * func_param_count + i; 4420 4421 if (!repr || no_accesses_p (repr)) 4422 continue; 4423 4424 do 4425 { 4426 if ((repr->offset + repr->size) > bb_dereferences[idx]) 4427 repr->grp_not_necessarilly_dereferenced = 1; 4428 repr = repr->next_grp; 4429 } 4430 while (repr); 4431 } 4432 } 4433 4434 /* Return the representative access for the parameter declaration PARM if it is 4435 a scalar passed by reference which is not written to and the pointer value 4436 is not used directly. Thus, if it is legal to dereference it in the caller 4437 and we can rule out modifications through aliases, such parameter should be 4438 turned into one passed by value. Return NULL otherwise. */ 4439 4440 static struct access * 4441 unmodified_by_ref_scalar_representative (tree parm) 4442 { 4443 int i, access_count; 4444 struct access *repr; 4445 vec<access_p> *access_vec; 4446 4447 access_vec = get_base_access_vector (parm); 4448 gcc_assert (access_vec); 4449 repr = (*access_vec)[0]; 4450 if (repr->write) 4451 return NULL; 4452 repr->group_representative = repr; 4453 4454 access_count = access_vec->length (); 4455 for (i = 1; i < access_count; i++) 4456 { 4457 struct access *access = (*access_vec)[i]; 4458 if (access->write) 4459 return NULL; 4460 access->group_representative = repr; 4461 access->next_sibling = repr->next_sibling; 4462 repr->next_sibling = access; 4463 } 4464 4465 repr->grp_read = 1; 4466 repr->grp_scalar_ptr = 1; 4467 return repr; 4468 } 4469 4470 /* Return true iff this ACCESS precludes IPA-SRA of the parameter it is 4471 associated with. REQ_ALIGN is the minimum required alignment. */ 4472 4473 static bool 4474 access_precludes_ipa_sra_p (struct access *access, unsigned int req_align) 4475 { 4476 unsigned int exp_align; 4477 /* Avoid issues such as the second simple testcase in PR 42025. The problem 4478 is incompatible assign in a call statement (and possibly even in asm 4479 statements). This can be relaxed by using a new temporary but only for 4480 non-TREE_ADDRESSABLE types and is probably not worth the complexity. (In 4481 intraprocedural SRA we deal with this by keeping the old aggregate around, 4482 something we cannot do in IPA-SRA.) */ 4483 if (access->write 4484 && (is_gimple_call (access->stmt) 4485 || gimple_code (access->stmt) == GIMPLE_ASM)) 4486 return true; 4487 4488 exp_align = get_object_alignment (access->expr); 4489 if (exp_align < req_align) 4490 return true; 4491 4492 return false; 4493 } 4494 4495 4496 /* Sort collected accesses for parameter PARM, identify representatives for 4497 each accessed region and link them together. Return NULL if there are 4498 different but overlapping accesses, return the special ptr value meaning 4499 there are no accesses for this parameter if that is the case and return the 4500 first representative otherwise. Set *RO_GRP if there is a group of accesses 4501 with only read (i.e. no write) accesses. */ 4502 4503 static struct access * 4504 splice_param_accesses (tree parm, bool *ro_grp) 4505 { 4506 int i, j, access_count, group_count; 4507 int total_size = 0; 4508 struct access *access, *res, **prev_acc_ptr = &res; 4509 vec<access_p> *access_vec; 4510 4511 access_vec = get_base_access_vector (parm); 4512 if (!access_vec) 4513 return &no_accesses_representant; 4514 access_count = access_vec->length (); 4515 4516 access_vec->qsort (compare_access_positions); 4517 4518 i = 0; 4519 total_size = 0; 4520 group_count = 0; 4521 while (i < access_count) 4522 { 4523 bool modification; 4524 tree a1_alias_type; 4525 access = (*access_vec)[i]; 4526 modification = access->write; 4527 if (access_precludes_ipa_sra_p (access, TYPE_ALIGN (access->type))) 4528 return NULL; 4529 a1_alias_type = reference_alias_ptr_type (access->expr); 4530 4531 /* Access is about to become group representative unless we find some 4532 nasty overlap which would preclude us from breaking this parameter 4533 apart. */ 4534 4535 j = i + 1; 4536 while (j < access_count) 4537 { 4538 struct access *ac2 = (*access_vec)[j]; 4539 if (ac2->offset != access->offset) 4540 { 4541 /* All or nothing law for parameters. */ 4542 if (access->offset + access->size > ac2->offset) 4543 return NULL; 4544 else 4545 break; 4546 } 4547 else if (ac2->size != access->size) 4548 return NULL; 4549 4550 if (access_precludes_ipa_sra_p (ac2, TYPE_ALIGN (access->type)) 4551 || (ac2->type != access->type 4552 && (TREE_ADDRESSABLE (ac2->type) 4553 || TREE_ADDRESSABLE (access->type))) 4554 || (reference_alias_ptr_type (ac2->expr) != a1_alias_type)) 4555 return NULL; 4556 4557 modification |= ac2->write; 4558 ac2->group_representative = access; 4559 ac2->next_sibling = access->next_sibling; 4560 access->next_sibling = ac2; 4561 j++; 4562 } 4563 4564 group_count++; 4565 access->grp_maybe_modified = modification; 4566 if (!modification) 4567 *ro_grp = true; 4568 *prev_acc_ptr = access; 4569 prev_acc_ptr = &access->next_grp; 4570 total_size += access->size; 4571 i = j; 4572 } 4573 4574 gcc_assert (group_count > 0); 4575 return res; 4576 } 4577 4578 /* Decide whether parameters with representative accesses given by REPR should 4579 be reduced into components. */ 4580 4581 static int 4582 decide_one_param_reduction (struct access *repr) 4583 { 4584 HOST_WIDE_INT total_size, cur_parm_size; 4585 bool by_ref; 4586 tree parm; 4587 4588 parm = repr->base; 4589 cur_parm_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm))); 4590 gcc_assert (cur_parm_size > 0); 4591 4592 if (POINTER_TYPE_P (TREE_TYPE (parm))) 4593 by_ref = true; 4594 else 4595 by_ref = false; 4596 4597 if (dump_file) 4598 { 4599 struct access *acc; 4600 fprintf (dump_file, "Evaluating PARAM group sizes for "); 4601 print_generic_expr (dump_file, parm); 4602 fprintf (dump_file, " (UID: %u): \n", DECL_UID (parm)); 4603 for (acc = repr; acc; acc = acc->next_grp) 4604 dump_access (dump_file, acc, true); 4605 } 4606 4607 total_size = 0; 4608 int new_param_count = 0; 4609 4610 for (; repr; repr = repr->next_grp) 4611 { 4612 gcc_assert (parm == repr->base); 4613 4614 /* Taking the address of a non-addressable field is verboten. */ 4615 if (by_ref && repr->non_addressable) 4616 return 0; 4617 4618 /* Do not decompose a non-BLKmode param in a way that would 4619 create BLKmode params. Especially for by-reference passing 4620 (thus, pointer-type param) this is hardly worthwhile. */ 4621 if (DECL_MODE (parm) != BLKmode 4622 && TYPE_MODE (repr->type) == BLKmode) 4623 return 0; 4624 4625 if (!by_ref || (!repr->grp_maybe_modified 4626 && !repr->grp_not_necessarilly_dereferenced)) 4627 total_size += repr->size; 4628 else 4629 total_size += cur_parm_size; 4630 4631 new_param_count++; 4632 } 4633 4634 gcc_assert (new_param_count > 0); 4635 4636 if (!by_ref) 4637 { 4638 if (total_size >= cur_parm_size) 4639 return 0; 4640 } 4641 else 4642 { 4643 int parm_num_limit; 4644 if (optimize_function_for_size_p (cfun)) 4645 parm_num_limit = 1; 4646 else 4647 parm_num_limit = PARAM_VALUE (PARAM_IPA_SRA_PTR_GROWTH_FACTOR); 4648 4649 if (new_param_count > parm_num_limit 4650 || total_size > (parm_num_limit * cur_parm_size)) 4651 return 0; 4652 } 4653 4654 if (dump_file) 4655 fprintf (dump_file, " ....will be split into %i components\n", 4656 new_param_count); 4657 return new_param_count; 4658 } 4659 4660 /* The order of the following enums is important, we need to do extra work for 4661 UNUSED_PARAMS, BY_VAL_ACCESSES and UNMODIF_BY_REF_ACCESSES. */ 4662 enum ipa_splicing_result { NO_GOOD_ACCESS, UNUSED_PARAMS, BY_VAL_ACCESSES, 4663 MODIF_BY_REF_ACCESSES, UNMODIF_BY_REF_ACCESSES }; 4664 4665 /* Identify representatives of all accesses to all candidate parameters for 4666 IPA-SRA. Return result based on what representatives have been found. */ 4667 4668 static enum ipa_splicing_result 4669 splice_all_param_accesses (vec<access_p> &representatives) 4670 { 4671 enum ipa_splicing_result result = NO_GOOD_ACCESS; 4672 tree parm; 4673 struct access *repr; 4674 4675 representatives.create (func_param_count); 4676 4677 for (parm = DECL_ARGUMENTS (current_function_decl); 4678 parm; 4679 parm = DECL_CHAIN (parm)) 4680 { 4681 if (is_unused_scalar_param (parm)) 4682 { 4683 representatives.quick_push (&no_accesses_representant); 4684 if (result == NO_GOOD_ACCESS) 4685 result = UNUSED_PARAMS; 4686 } 4687 else if (POINTER_TYPE_P (TREE_TYPE (parm)) 4688 && is_gimple_reg_type (TREE_TYPE (TREE_TYPE (parm))) 4689 && bitmap_bit_p (candidate_bitmap, DECL_UID (parm))) 4690 { 4691 repr = unmodified_by_ref_scalar_representative (parm); 4692 representatives.quick_push (repr); 4693 if (repr) 4694 result = UNMODIF_BY_REF_ACCESSES; 4695 } 4696 else if (bitmap_bit_p (candidate_bitmap, DECL_UID (parm))) 4697 { 4698 bool ro_grp = false; 4699 repr = splice_param_accesses (parm, &ro_grp); 4700 representatives.quick_push (repr); 4701 4702 if (repr && !no_accesses_p (repr)) 4703 { 4704 if (POINTER_TYPE_P (TREE_TYPE (parm))) 4705 { 4706 if (ro_grp) 4707 result = UNMODIF_BY_REF_ACCESSES; 4708 else if (result < MODIF_BY_REF_ACCESSES) 4709 result = MODIF_BY_REF_ACCESSES; 4710 } 4711 else if (result < BY_VAL_ACCESSES) 4712 result = BY_VAL_ACCESSES; 4713 } 4714 else if (no_accesses_p (repr) && (result == NO_GOOD_ACCESS)) 4715 result = UNUSED_PARAMS; 4716 } 4717 else 4718 representatives.quick_push (NULL); 4719 } 4720 4721 if (result == NO_GOOD_ACCESS) 4722 { 4723 representatives.release (); 4724 return NO_GOOD_ACCESS; 4725 } 4726 4727 return result; 4728 } 4729 4730 /* Return the index of BASE in PARMS. Abort if it is not found. */ 4731 4732 static inline int 4733 get_param_index (tree base, vec<tree> parms) 4734 { 4735 int i, len; 4736 4737 len = parms.length (); 4738 for (i = 0; i < len; i++) 4739 if (parms[i] == base) 4740 return i; 4741 gcc_unreachable (); 4742 } 4743 4744 /* Convert the decisions made at the representative level into compact 4745 parameter adjustments. REPRESENTATIVES are pointers to first 4746 representatives of each param accesses, ADJUSTMENTS_COUNT is the expected 4747 final number of adjustments. */ 4748 4749 static ipa_parm_adjustment_vec 4750 turn_representatives_into_adjustments (vec<access_p> representatives, 4751 int adjustments_count) 4752 { 4753 vec<tree> parms; 4754 ipa_parm_adjustment_vec adjustments; 4755 tree parm; 4756 int i; 4757 4758 gcc_assert (adjustments_count > 0); 4759 parms = ipa_get_vector_of_formal_parms (current_function_decl); 4760 adjustments.create (adjustments_count); 4761 parm = DECL_ARGUMENTS (current_function_decl); 4762 for (i = 0; i < func_param_count; i++, parm = DECL_CHAIN (parm)) 4763 { 4764 struct access *repr = representatives[i]; 4765 4766 if (!repr || no_accesses_p (repr)) 4767 { 4768 struct ipa_parm_adjustment adj; 4769 4770 memset (&adj, 0, sizeof (adj)); 4771 adj.base_index = get_param_index (parm, parms); 4772 adj.base = parm; 4773 if (!repr) 4774 adj.op = IPA_PARM_OP_COPY; 4775 else 4776 adj.op = IPA_PARM_OP_REMOVE; 4777 adj.arg_prefix = "ISRA"; 4778 adjustments.quick_push (adj); 4779 } 4780 else 4781 { 4782 struct ipa_parm_adjustment adj; 4783 int index = get_param_index (parm, parms); 4784 4785 for (; repr; repr = repr->next_grp) 4786 { 4787 memset (&adj, 0, sizeof (adj)); 4788 gcc_assert (repr->base == parm); 4789 adj.base_index = index; 4790 adj.base = repr->base; 4791 adj.type = repr->type; 4792 adj.alias_ptr_type = reference_alias_ptr_type (repr->expr); 4793 adj.offset = repr->offset; 4794 adj.reverse = repr->reverse; 4795 adj.by_ref = (POINTER_TYPE_P (TREE_TYPE (repr->base)) 4796 && (repr->grp_maybe_modified 4797 || repr->grp_not_necessarilly_dereferenced)); 4798 adj.arg_prefix = "ISRA"; 4799 adjustments.quick_push (adj); 4800 } 4801 } 4802 } 4803 parms.release (); 4804 return adjustments; 4805 } 4806 4807 /* Analyze the collected accesses and produce a plan what to do with the 4808 parameters in the form of adjustments, NULL meaning nothing. */ 4809 4810 static ipa_parm_adjustment_vec 4811 analyze_all_param_acesses (void) 4812 { 4813 enum ipa_splicing_result repr_state; 4814 bool proceed = false; 4815 int i, adjustments_count = 0; 4816 vec<access_p> representatives; 4817 ipa_parm_adjustment_vec adjustments; 4818 4819 repr_state = splice_all_param_accesses (representatives); 4820 if (repr_state == NO_GOOD_ACCESS) 4821 return ipa_parm_adjustment_vec (); 4822 4823 /* If there are any parameters passed by reference which are not modified 4824 directly, we need to check whether they can be modified indirectly. */ 4825 if (repr_state == UNMODIF_BY_REF_ACCESSES) 4826 { 4827 analyze_caller_dereference_legality (representatives); 4828 analyze_modified_params (representatives); 4829 } 4830 4831 for (i = 0; i < func_param_count; i++) 4832 { 4833 struct access *repr = representatives[i]; 4834 4835 if (repr && !no_accesses_p (repr)) 4836 { 4837 if (repr->grp_scalar_ptr) 4838 { 4839 adjustments_count++; 4840 if (repr->grp_not_necessarilly_dereferenced 4841 || repr->grp_maybe_modified) 4842 representatives[i] = NULL; 4843 else 4844 { 4845 proceed = true; 4846 sra_stats.scalar_by_ref_to_by_val++; 4847 } 4848 } 4849 else 4850 { 4851 int new_components = decide_one_param_reduction (repr); 4852 4853 if (new_components == 0) 4854 { 4855 representatives[i] = NULL; 4856 adjustments_count++; 4857 } 4858 else 4859 { 4860 adjustments_count += new_components; 4861 sra_stats.aggregate_params_reduced++; 4862 sra_stats.param_reductions_created += new_components; 4863 proceed = true; 4864 } 4865 } 4866 } 4867 else 4868 { 4869 if (no_accesses_p (repr)) 4870 { 4871 proceed = true; 4872 sra_stats.deleted_unused_parameters++; 4873 } 4874 adjustments_count++; 4875 } 4876 } 4877 4878 if (!proceed && dump_file) 4879 fprintf (dump_file, "NOT proceeding to change params.\n"); 4880 4881 if (proceed) 4882 adjustments = turn_representatives_into_adjustments (representatives, 4883 adjustments_count); 4884 else 4885 adjustments = ipa_parm_adjustment_vec (); 4886 4887 representatives.release (); 4888 return adjustments; 4889 } 4890 4891 /* If a parameter replacement identified by ADJ does not yet exist in the form 4892 of declaration, create it and record it, otherwise return the previously 4893 created one. */ 4894 4895 static tree 4896 get_replaced_param_substitute (struct ipa_parm_adjustment *adj) 4897 { 4898 tree repl; 4899 if (!adj->new_ssa_base) 4900 { 4901 char *pretty_name = make_fancy_name (adj->base); 4902 4903 repl = create_tmp_reg (TREE_TYPE (adj->base), "ISR"); 4904 DECL_NAME (repl) = get_identifier (pretty_name); 4905 DECL_NAMELESS (repl) = 1; 4906 obstack_free (&name_obstack, pretty_name); 4907 4908 adj->new_ssa_base = repl; 4909 } 4910 else 4911 repl = adj->new_ssa_base; 4912 return repl; 4913 } 4914 4915 /* Find the first adjustment for a particular parameter BASE in a vector of 4916 ADJUSTMENTS which is not a copy_param. Return NULL if there is no such 4917 adjustment. */ 4918 4919 static struct ipa_parm_adjustment * 4920 get_adjustment_for_base (ipa_parm_adjustment_vec adjustments, tree base) 4921 { 4922 int i, len; 4923 4924 len = adjustments.length (); 4925 for (i = 0; i < len; i++) 4926 { 4927 struct ipa_parm_adjustment *adj; 4928 4929 adj = &adjustments[i]; 4930 if (adj->op != IPA_PARM_OP_COPY && adj->base == base) 4931 return adj; 4932 } 4933 4934 return NULL; 4935 } 4936 4937 /* If OLD_NAME, which is being defined by statement STMT, is an SSA_NAME of a 4938 parameter which is to be removed because its value is not used, create a new 4939 SSA_NAME relating to a replacement VAR_DECL, replace all uses of the 4940 original with it and return it. If there is no need to re-map, return NULL. 4941 ADJUSTMENTS is a pointer to a vector of IPA-SRA adjustments. */ 4942 4943 static tree 4944 replace_removed_params_ssa_names (tree old_name, gimple *stmt, 4945 ipa_parm_adjustment_vec adjustments) 4946 { 4947 struct ipa_parm_adjustment *adj; 4948 tree decl, repl, new_name; 4949 4950 if (TREE_CODE (old_name) != SSA_NAME) 4951 return NULL; 4952 4953 decl = SSA_NAME_VAR (old_name); 4954 if (decl == NULL_TREE 4955 || TREE_CODE (decl) != PARM_DECL) 4956 return NULL; 4957 4958 adj = get_adjustment_for_base (adjustments, decl); 4959 if (!adj) 4960 return NULL; 4961 4962 repl = get_replaced_param_substitute (adj); 4963 new_name = make_ssa_name (repl, stmt); 4964 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new_name) 4965 = SSA_NAME_OCCURS_IN_ABNORMAL_PHI (old_name); 4966 4967 if (dump_file) 4968 { 4969 fprintf (dump_file, "replacing an SSA name of a removed param "); 4970 print_generic_expr (dump_file, old_name); 4971 fprintf (dump_file, " with "); 4972 print_generic_expr (dump_file, new_name); 4973 fprintf (dump_file, "\n"); 4974 } 4975 4976 replace_uses_by (old_name, new_name); 4977 return new_name; 4978 } 4979 4980 /* If the statement STMT contains any expressions that need to replaced with a 4981 different one as noted by ADJUSTMENTS, do so. Handle any potential type 4982 incompatibilities (GSI is used to accommodate conversion statements and must 4983 point to the statement). Return true iff the statement was modified. */ 4984 4985 static bool 4986 sra_ipa_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi, 4987 ipa_parm_adjustment_vec adjustments) 4988 { 4989 tree *lhs_p, *rhs_p; 4990 bool any; 4991 4992 if (!gimple_assign_single_p (stmt)) 4993 return false; 4994 4995 rhs_p = gimple_assign_rhs1_ptr (stmt); 4996 lhs_p = gimple_assign_lhs_ptr (stmt); 4997 4998 any = ipa_modify_expr (rhs_p, false, adjustments); 4999 any |= ipa_modify_expr (lhs_p, false, adjustments); 5000 if (any) 5001 { 5002 tree new_rhs = NULL_TREE; 5003 5004 if (!useless_type_conversion_p (TREE_TYPE (*lhs_p), TREE_TYPE (*rhs_p))) 5005 { 5006 if (TREE_CODE (*rhs_p) == CONSTRUCTOR) 5007 { 5008 /* V_C_Es of constructors can cause trouble (PR 42714). */ 5009 if (is_gimple_reg_type (TREE_TYPE (*lhs_p))) 5010 *rhs_p = build_zero_cst (TREE_TYPE (*lhs_p)); 5011 else 5012 *rhs_p = build_constructor (TREE_TYPE (*lhs_p), 5013 NULL); 5014 } 5015 else 5016 new_rhs = fold_build1_loc (gimple_location (stmt), 5017 VIEW_CONVERT_EXPR, TREE_TYPE (*lhs_p), 5018 *rhs_p); 5019 } 5020 else if (REFERENCE_CLASS_P (*rhs_p) 5021 && is_gimple_reg_type (TREE_TYPE (*lhs_p)) 5022 && !is_gimple_reg (*lhs_p)) 5023 /* This can happen when an assignment in between two single field 5024 structures is turned into an assignment in between two pointers to 5025 scalars (PR 42237). */ 5026 new_rhs = *rhs_p; 5027 5028 if (new_rhs) 5029 { 5030 tree tmp = force_gimple_operand_gsi (gsi, new_rhs, true, NULL_TREE, 5031 true, GSI_SAME_STMT); 5032 5033 gimple_assign_set_rhs_from_tree (gsi, tmp); 5034 } 5035 5036 return true; 5037 } 5038 5039 return false; 5040 } 5041 5042 /* Traverse the function body and all modifications as described in 5043 ADJUSTMENTS. Return true iff the CFG has been changed. */ 5044 5045 bool 5046 ipa_sra_modify_function_body (ipa_parm_adjustment_vec adjustments) 5047 { 5048 bool cfg_changed = false; 5049 basic_block bb; 5050 5051 FOR_EACH_BB_FN (bb, cfun) 5052 { 5053 gimple_stmt_iterator gsi; 5054 5055 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) 5056 { 5057 gphi *phi = as_a <gphi *> (gsi_stmt (gsi)); 5058 tree new_lhs, old_lhs = gimple_phi_result (phi); 5059 new_lhs = replace_removed_params_ssa_names (old_lhs, phi, adjustments); 5060 if (new_lhs) 5061 { 5062 gimple_phi_set_result (phi, new_lhs); 5063 release_ssa_name (old_lhs); 5064 } 5065 } 5066 5067 gsi = gsi_start_bb (bb); 5068 while (!gsi_end_p (gsi)) 5069 { 5070 gimple *stmt = gsi_stmt (gsi); 5071 bool modified = false; 5072 tree *t; 5073 unsigned i; 5074 5075 switch (gimple_code (stmt)) 5076 { 5077 case GIMPLE_RETURN: 5078 t = gimple_return_retval_ptr (as_a <greturn *> (stmt)); 5079 if (*t != NULL_TREE) 5080 modified |= ipa_modify_expr (t, true, adjustments); 5081 break; 5082 5083 case GIMPLE_ASSIGN: 5084 modified |= sra_ipa_modify_assign (stmt, &gsi, adjustments); 5085 break; 5086 5087 case GIMPLE_CALL: 5088 /* Operands must be processed before the lhs. */ 5089 for (i = 0; i < gimple_call_num_args (stmt); i++) 5090 { 5091 t = gimple_call_arg_ptr (stmt, i); 5092 modified |= ipa_modify_expr (t, true, adjustments); 5093 } 5094 5095 if (gimple_call_lhs (stmt)) 5096 { 5097 t = gimple_call_lhs_ptr (stmt); 5098 modified |= ipa_modify_expr (t, false, adjustments); 5099 } 5100 break; 5101 5102 case GIMPLE_ASM: 5103 { 5104 gasm *asm_stmt = as_a <gasm *> (stmt); 5105 for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++) 5106 { 5107 t = &TREE_VALUE (gimple_asm_input_op (asm_stmt, i)); 5108 modified |= ipa_modify_expr (t, true, adjustments); 5109 } 5110 for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++) 5111 { 5112 t = &TREE_VALUE (gimple_asm_output_op (asm_stmt, i)); 5113 modified |= ipa_modify_expr (t, false, adjustments); 5114 } 5115 } 5116 break; 5117 5118 default: 5119 break; 5120 } 5121 5122 def_operand_p defp; 5123 ssa_op_iter iter; 5124 FOR_EACH_SSA_DEF_OPERAND (defp, stmt, iter, SSA_OP_DEF) 5125 { 5126 tree old_def = DEF_FROM_PTR (defp); 5127 if (tree new_def = replace_removed_params_ssa_names (old_def, stmt, 5128 adjustments)) 5129 { 5130 SET_DEF (defp, new_def); 5131 release_ssa_name (old_def); 5132 modified = true; 5133 } 5134 } 5135 5136 if (modified) 5137 { 5138 update_stmt (stmt); 5139 if (maybe_clean_eh_stmt (stmt) 5140 && gimple_purge_dead_eh_edges (gimple_bb (stmt))) 5141 cfg_changed = true; 5142 } 5143 gsi_next (&gsi); 5144 } 5145 } 5146 5147 return cfg_changed; 5148 } 5149 5150 /* Call gimple_debug_bind_reset_value on all debug statements describing 5151 gimple register parameters that are being removed or replaced. */ 5152 5153 static void 5154 sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments) 5155 { 5156 int i, len; 5157 gimple_stmt_iterator *gsip = NULL, gsi; 5158 5159 if (MAY_HAVE_DEBUG_STMTS && single_succ_p (ENTRY_BLOCK_PTR_FOR_FN (cfun))) 5160 { 5161 gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun))); 5162 gsip = &gsi; 5163 } 5164 len = adjustments.length (); 5165 for (i = 0; i < len; i++) 5166 { 5167 struct ipa_parm_adjustment *adj; 5168 imm_use_iterator ui; 5169 gimple *stmt; 5170 gdebug *def_temp; 5171 tree name, vexpr, copy = NULL_TREE; 5172 use_operand_p use_p; 5173 5174 adj = &adjustments[i]; 5175 if (adj->op == IPA_PARM_OP_COPY || !is_gimple_reg (adj->base)) 5176 continue; 5177 name = ssa_default_def (cfun, adj->base); 5178 vexpr = NULL; 5179 if (name) 5180 FOR_EACH_IMM_USE_STMT (stmt, ui, name) 5181 { 5182 if (gimple_clobber_p (stmt)) 5183 { 5184 gimple_stmt_iterator cgsi = gsi_for_stmt (stmt); 5185 unlink_stmt_vdef (stmt); 5186 gsi_remove (&cgsi, true); 5187 release_defs (stmt); 5188 continue; 5189 } 5190 /* All other users must have been removed by 5191 ipa_sra_modify_function_body. */ 5192 gcc_assert (is_gimple_debug (stmt)); 5193 if (vexpr == NULL && gsip != NULL) 5194 { 5195 gcc_assert (TREE_CODE (adj->base) == PARM_DECL); 5196 vexpr = make_node (DEBUG_EXPR_DECL); 5197 def_temp = gimple_build_debug_source_bind (vexpr, adj->base, 5198 NULL); 5199 DECL_ARTIFICIAL (vexpr) = 1; 5200 TREE_TYPE (vexpr) = TREE_TYPE (name); 5201 SET_DECL_MODE (vexpr, DECL_MODE (adj->base)); 5202 gsi_insert_before (gsip, def_temp, GSI_SAME_STMT); 5203 } 5204 if (vexpr) 5205 { 5206 FOR_EACH_IMM_USE_ON_STMT (use_p, ui) 5207 SET_USE (use_p, vexpr); 5208 } 5209 else 5210 gimple_debug_bind_reset_value (stmt); 5211 update_stmt (stmt); 5212 } 5213 /* Create a VAR_DECL for debug info purposes. */ 5214 if (!DECL_IGNORED_P (adj->base)) 5215 { 5216 copy = build_decl (DECL_SOURCE_LOCATION (current_function_decl), 5217 VAR_DECL, DECL_NAME (adj->base), 5218 TREE_TYPE (adj->base)); 5219 if (DECL_PT_UID_SET_P (adj->base)) 5220 SET_DECL_PT_UID (copy, DECL_PT_UID (adj->base)); 5221 TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (adj->base); 5222 TREE_READONLY (copy) = TREE_READONLY (adj->base); 5223 TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (adj->base); 5224 DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (adj->base); 5225 DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (adj->base); 5226 DECL_IGNORED_P (copy) = DECL_IGNORED_P (adj->base); 5227 DECL_ABSTRACT_ORIGIN (copy) = DECL_ORIGIN (adj->base); 5228 DECL_SEEN_IN_BIND_EXPR_P (copy) = 1; 5229 SET_DECL_RTL (copy, 0); 5230 TREE_USED (copy) = 1; 5231 DECL_CONTEXT (copy) = current_function_decl; 5232 add_local_decl (cfun, copy); 5233 DECL_CHAIN (copy) = 5234 BLOCK_VARS (DECL_INITIAL (current_function_decl)); 5235 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = copy; 5236 } 5237 if (gsip != NULL && copy && target_for_debug_bind (adj->base)) 5238 { 5239 gcc_assert (TREE_CODE (adj->base) == PARM_DECL); 5240 if (vexpr) 5241 def_temp = gimple_build_debug_bind (copy, vexpr, NULL); 5242 else 5243 def_temp = gimple_build_debug_source_bind (copy, adj->base, 5244 NULL); 5245 gsi_insert_before (gsip, def_temp, GSI_SAME_STMT); 5246 } 5247 } 5248 } 5249 5250 /* Return false if all callers have at least as many actual arguments as there 5251 are formal parameters in the current function and that their types 5252 match. */ 5253 5254 static bool 5255 some_callers_have_mismatched_arguments_p (struct cgraph_node *node, 5256 void *data ATTRIBUTE_UNUSED) 5257 { 5258 struct cgraph_edge *cs; 5259 for (cs = node->callers; cs; cs = cs->next_caller) 5260 if (!cs->call_stmt || !callsite_arguments_match_p (cs->call_stmt)) 5261 return true; 5262 5263 return false; 5264 } 5265 5266 /* Return false if all callers have vuse attached to a call statement. */ 5267 5268 static bool 5269 some_callers_have_no_vuse_p (struct cgraph_node *node, 5270 void *data ATTRIBUTE_UNUSED) 5271 { 5272 struct cgraph_edge *cs; 5273 for (cs = node->callers; cs; cs = cs->next_caller) 5274 if (!cs->call_stmt || !gimple_vuse (cs->call_stmt)) 5275 return true; 5276 5277 return false; 5278 } 5279 5280 /* Convert all callers of NODE. */ 5281 5282 static bool 5283 convert_callers_for_node (struct cgraph_node *node, 5284 void *data) 5285 { 5286 ipa_parm_adjustment_vec *adjustments = (ipa_parm_adjustment_vec *) data; 5287 bitmap recomputed_callers = BITMAP_ALLOC (NULL); 5288 struct cgraph_edge *cs; 5289 5290 for (cs = node->callers; cs; cs = cs->next_caller) 5291 { 5292 push_cfun (DECL_STRUCT_FUNCTION (cs->caller->decl)); 5293 5294 if (dump_file) 5295 fprintf (dump_file, "Adjusting call %s -> %s\n", 5296 cs->caller->dump_name (), cs->callee->dump_name ()); 5297 5298 ipa_modify_call_arguments (cs, cs->call_stmt, *adjustments); 5299 5300 pop_cfun (); 5301 } 5302 5303 for (cs = node->callers; cs; cs = cs->next_caller) 5304 if (bitmap_set_bit (recomputed_callers, cs->caller->uid) 5305 && gimple_in_ssa_p (DECL_STRUCT_FUNCTION (cs->caller->decl))) 5306 compute_fn_summary (cs->caller, true); 5307 BITMAP_FREE (recomputed_callers); 5308 5309 return true; 5310 } 5311 5312 /* Convert all callers of NODE to pass parameters as given in ADJUSTMENTS. */ 5313 5314 static void 5315 convert_callers (struct cgraph_node *node, tree old_decl, 5316 ipa_parm_adjustment_vec adjustments) 5317 { 5318 basic_block this_block; 5319 5320 node->call_for_symbol_and_aliases (convert_callers_for_node, 5321 &adjustments, false); 5322 5323 if (!encountered_recursive_call) 5324 return; 5325 5326 FOR_EACH_BB_FN (this_block, cfun) 5327 { 5328 gimple_stmt_iterator gsi; 5329 5330 for (gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi)) 5331 { 5332 gcall *stmt; 5333 tree call_fndecl; 5334 stmt = dyn_cast <gcall *> (gsi_stmt (gsi)); 5335 if (!stmt) 5336 continue; 5337 call_fndecl = gimple_call_fndecl (stmt); 5338 if (call_fndecl == old_decl) 5339 { 5340 if (dump_file) 5341 fprintf (dump_file, "Adjusting recursive call"); 5342 gimple_call_set_fndecl (stmt, node->decl); 5343 ipa_modify_call_arguments (NULL, stmt, adjustments); 5344 } 5345 } 5346 } 5347 5348 return; 5349 } 5350 5351 /* Perform all the modification required in IPA-SRA for NODE to have parameters 5352 as given in ADJUSTMENTS. Return true iff the CFG has been changed. */ 5353 5354 static bool 5355 modify_function (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments) 5356 { 5357 struct cgraph_node *new_node; 5358 bool cfg_changed; 5359 5360 cgraph_edge::rebuild_edges (); 5361 free_dominance_info (CDI_DOMINATORS); 5362 pop_cfun (); 5363 5364 /* This must be done after rebuilding cgraph edges for node above. 5365 Otherwise any recursive calls to node that are recorded in 5366 redirect_callers will be corrupted. */ 5367 vec<cgraph_edge *> redirect_callers = node->collect_callers (); 5368 new_node = node->create_version_clone_with_body (redirect_callers, NULL, 5369 NULL, false, NULL, NULL, 5370 "isra"); 5371 redirect_callers.release (); 5372 5373 push_cfun (DECL_STRUCT_FUNCTION (new_node->decl)); 5374 ipa_modify_formal_parameters (current_function_decl, adjustments); 5375 cfg_changed = ipa_sra_modify_function_body (adjustments); 5376 sra_ipa_reset_debug_stmts (adjustments); 5377 convert_callers (new_node, node->decl, adjustments); 5378 new_node->make_local (); 5379 return cfg_changed; 5380 } 5381 5382 /* Means of communication between ipa_sra_check_caller and 5383 ipa_sra_preliminary_function_checks. */ 5384 5385 struct ipa_sra_check_caller_data 5386 { 5387 bool has_callers; 5388 bool bad_arg_alignment; 5389 bool has_thunk; 5390 }; 5391 5392 /* If NODE has a caller, mark that fact in DATA which is pointer to 5393 ipa_sra_check_caller_data. Also check all aggregate arguments in all known 5394 calls if they are unit aligned and if not, set the appropriate flag in DATA 5395 too. */ 5396 5397 static bool 5398 ipa_sra_check_caller (struct cgraph_node *node, void *data) 5399 { 5400 if (!node->callers) 5401 return false; 5402 5403 struct ipa_sra_check_caller_data *iscc; 5404 iscc = (struct ipa_sra_check_caller_data *) data; 5405 iscc->has_callers = true; 5406 5407 for (cgraph_edge *cs = node->callers; cs; cs = cs->next_caller) 5408 { 5409 if (cs->caller->thunk.thunk_p) 5410 { 5411 iscc->has_thunk = true; 5412 return true; 5413 } 5414 gimple *call_stmt = cs->call_stmt; 5415 unsigned count = gimple_call_num_args (call_stmt); 5416 for (unsigned i = 0; i < count; i++) 5417 { 5418 tree arg = gimple_call_arg (call_stmt, i); 5419 if (is_gimple_reg (arg)) 5420 continue; 5421 5422 tree offset; 5423 poly_int64 bitsize, bitpos; 5424 machine_mode mode; 5425 int unsignedp, reversep, volatilep = 0; 5426 get_inner_reference (arg, &bitsize, &bitpos, &offset, &mode, 5427 &unsignedp, &reversep, &volatilep); 5428 if (!multiple_p (bitpos, BITS_PER_UNIT)) 5429 { 5430 iscc->bad_arg_alignment = true; 5431 return true; 5432 } 5433 } 5434 } 5435 5436 return false; 5437 } 5438 5439 /* Return false the function is apparently unsuitable for IPA-SRA based on it's 5440 attributes, return true otherwise. NODE is the cgraph node of the current 5441 function. */ 5442 5443 static bool 5444 ipa_sra_preliminary_function_checks (struct cgraph_node *node) 5445 { 5446 if (!node->can_be_local_p ()) 5447 { 5448 if (dump_file) 5449 fprintf (dump_file, "Function not local to this compilation unit.\n"); 5450 return false; 5451 } 5452 5453 if (!node->local.can_change_signature) 5454 { 5455 if (dump_file) 5456 fprintf (dump_file, "Function can not change signature.\n"); 5457 return false; 5458 } 5459 5460 if (!tree_versionable_function_p (node->decl)) 5461 { 5462 if (dump_file) 5463 fprintf (dump_file, "Function is not versionable.\n"); 5464 return false; 5465 } 5466 5467 if (!opt_for_fn (node->decl, optimize) 5468 || !opt_for_fn (node->decl, flag_ipa_sra)) 5469 { 5470 if (dump_file) 5471 fprintf (dump_file, "Function not optimized.\n"); 5472 return false; 5473 } 5474 5475 if (DECL_VIRTUAL_P (current_function_decl)) 5476 { 5477 if (dump_file) 5478 fprintf (dump_file, "Function is a virtual method.\n"); 5479 return false; 5480 } 5481 5482 if ((DECL_ONE_ONLY (node->decl) || DECL_EXTERNAL (node->decl)) 5483 && ipa_fn_summaries->get (node)->size >= MAX_INLINE_INSNS_AUTO) 5484 { 5485 if (dump_file) 5486 fprintf (dump_file, "Function too big to be made truly local.\n"); 5487 return false; 5488 } 5489 5490 if (cfun->stdarg) 5491 { 5492 if (dump_file) 5493 fprintf (dump_file, "Function uses stdarg. \n"); 5494 return false; 5495 } 5496 5497 if (TYPE_ATTRIBUTES (TREE_TYPE (node->decl))) 5498 return false; 5499 5500 if (DECL_DISREGARD_INLINE_LIMITS (node->decl)) 5501 { 5502 if (dump_file) 5503 fprintf (dump_file, "Always inline function will be inlined " 5504 "anyway. \n"); 5505 return false; 5506 } 5507 5508 struct ipa_sra_check_caller_data iscc; 5509 memset (&iscc, 0, sizeof(iscc)); 5510 node->call_for_symbol_and_aliases (ipa_sra_check_caller, &iscc, true); 5511 if (!iscc.has_callers) 5512 { 5513 if (dump_file) 5514 fprintf (dump_file, 5515 "Function has no callers in this compilation unit.\n"); 5516 return false; 5517 } 5518 5519 if (iscc.bad_arg_alignment) 5520 { 5521 if (dump_file) 5522 fprintf (dump_file, 5523 "A function call has an argument with non-unit alignment.\n"); 5524 return false; 5525 } 5526 5527 if (iscc.has_thunk) 5528 { 5529 if (dump_file) 5530 fprintf (dump_file, 5531 "A has thunk.\n"); 5532 return false; 5533 } 5534 5535 return true; 5536 } 5537 5538 /* Perform early interprocedural SRA. */ 5539 5540 static unsigned int 5541 ipa_early_sra (void) 5542 { 5543 struct cgraph_node *node = cgraph_node::get (current_function_decl); 5544 ipa_parm_adjustment_vec adjustments; 5545 int ret = 0; 5546 5547 if (!ipa_sra_preliminary_function_checks (node)) 5548 return 0; 5549 5550 sra_initialize (); 5551 sra_mode = SRA_MODE_EARLY_IPA; 5552 5553 if (!find_param_candidates ()) 5554 { 5555 if (dump_file) 5556 fprintf (dump_file, "Function has no IPA-SRA candidates.\n"); 5557 goto simple_out; 5558 } 5559 5560 if (node->call_for_symbol_and_aliases 5561 (some_callers_have_mismatched_arguments_p, NULL, true)) 5562 { 5563 if (dump_file) 5564 fprintf (dump_file, "There are callers with insufficient number of " 5565 "arguments or arguments with type mismatches.\n"); 5566 goto simple_out; 5567 } 5568 5569 if (node->call_for_symbol_and_aliases 5570 (some_callers_have_no_vuse_p, NULL, true)) 5571 { 5572 if (dump_file) 5573 fprintf (dump_file, "There are callers with no VUSE attached " 5574 "to a call stmt.\n"); 5575 goto simple_out; 5576 } 5577 5578 bb_dereferences = XCNEWVEC (HOST_WIDE_INT, 5579 func_param_count 5580 * last_basic_block_for_fn (cfun)); 5581 final_bbs = BITMAP_ALLOC (NULL); 5582 5583 scan_function (); 5584 if (encountered_apply_args) 5585 { 5586 if (dump_file) 5587 fprintf (dump_file, "Function calls __builtin_apply_args().\n"); 5588 goto out; 5589 } 5590 5591 if (encountered_unchangable_recursive_call) 5592 { 5593 if (dump_file) 5594 fprintf (dump_file, "Function calls itself with insufficient " 5595 "number of arguments.\n"); 5596 goto out; 5597 } 5598 5599 adjustments = analyze_all_param_acesses (); 5600 if (!adjustments.exists ()) 5601 goto out; 5602 if (dump_file) 5603 ipa_dump_param_adjustments (dump_file, adjustments, current_function_decl); 5604 5605 if (modify_function (node, adjustments)) 5606 ret = TODO_update_ssa | TODO_cleanup_cfg; 5607 else 5608 ret = TODO_update_ssa; 5609 adjustments.release (); 5610 5611 statistics_counter_event (cfun, "Unused parameters deleted", 5612 sra_stats.deleted_unused_parameters); 5613 statistics_counter_event (cfun, "Scalar parameters converted to by-value", 5614 sra_stats.scalar_by_ref_to_by_val); 5615 statistics_counter_event (cfun, "Aggregate parameters broken up", 5616 sra_stats.aggregate_params_reduced); 5617 statistics_counter_event (cfun, "Aggregate parameter components created", 5618 sra_stats.param_reductions_created); 5619 5620 out: 5621 BITMAP_FREE (final_bbs); 5622 free (bb_dereferences); 5623 simple_out: 5624 sra_deinitialize (); 5625 return ret; 5626 } 5627 5628 namespace { 5629 5630 const pass_data pass_data_early_ipa_sra = 5631 { 5632 GIMPLE_PASS, /* type */ 5633 "eipa_sra", /* name */ 5634 OPTGROUP_NONE, /* optinfo_flags */ 5635 TV_IPA_SRA, /* tv_id */ 5636 0, /* properties_required */ 5637 0, /* properties_provided */ 5638 0, /* properties_destroyed */ 5639 0, /* todo_flags_start */ 5640 TODO_dump_symtab, /* todo_flags_finish */ 5641 }; 5642 5643 class pass_early_ipa_sra : public gimple_opt_pass 5644 { 5645 public: 5646 pass_early_ipa_sra (gcc::context *ctxt) 5647 : gimple_opt_pass (pass_data_early_ipa_sra, ctxt) 5648 {} 5649 5650 /* opt_pass methods: */ 5651 virtual bool gate (function *) { return flag_ipa_sra && dbg_cnt (eipa_sra); } 5652 virtual unsigned int execute (function *) { return ipa_early_sra (); } 5653 5654 }; // class pass_early_ipa_sra 5655 5656 } // anon namespace 5657 5658 gimple_opt_pass * 5659 make_pass_early_ipa_sra (gcc::context *ctxt) 5660 { 5661 return new pass_early_ipa_sra (ctxt); 5662 } 5663