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