1 /* Memory address lowering and addressing mode selection. 2 Copyright (C) 2004-2019 Free Software Foundation, Inc. 3 4 This file is part of GCC. 5 6 GCC is free software; you can redistribute it and/or modify it 7 under the terms of the GNU General Public License as published by the 8 Free Software Foundation; either version 3, or (at your option) any 9 later version. 10 11 GCC is distributed in the hope that it will be useful, but WITHOUT 12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GCC; see the file COPYING3. If not see 18 <http://www.gnu.org/licenses/>. */ 19 20 /* Utility functions for manipulation with TARGET_MEM_REFs -- tree expressions 21 that directly map to addressing modes of the target. */ 22 23 #include "config.h" 24 #include "system.h" 25 #include "coretypes.h" 26 #include "backend.h" 27 #include "target.h" 28 #include "rtl.h" 29 #include "tree.h" 30 #include "gimple.h" 31 #include "memmodel.h" 32 #include "stringpool.h" 33 #include "tree-vrp.h" 34 #include "tree-ssanames.h" 35 #include "expmed.h" 36 #include "insn-config.h" 37 #include "emit-rtl.h" 38 #include "recog.h" 39 #include "tree-pretty-print.h" 40 #include "fold-const.h" 41 #include "stor-layout.h" 42 #include "gimple-iterator.h" 43 #include "gimplify-me.h" 44 #include "tree-ssa-loop-ivopts.h" 45 #include "expr.h" 46 #include "tree-dfa.h" 47 #include "dumpfile.h" 48 #include "tree-affine.h" 49 #include "gimplify.h" 50 51 /* FIXME: We compute address costs using RTL. */ 52 #include "tree-ssa-address.h" 53 54 /* TODO -- handling of symbols (according to Richard Hendersons 55 comments, http://gcc.gnu.org/ml/gcc-patches/2005-04/msg00949.html): 56 57 There are at least 5 different kinds of symbols that we can run up against: 58 59 (1) binds_local_p, small data area. 60 (2) binds_local_p, eg local statics 61 (3) !binds_local_p, eg global variables 62 (4) thread local, local_exec 63 (5) thread local, !local_exec 64 65 Now, (1) won't appear often in an array context, but it certainly can. 66 All you have to do is set -GN high enough, or explicitly mark any 67 random object __attribute__((section (".sdata"))). 68 69 All of these affect whether or not a symbol is in fact a valid address. 70 The only one tested here is (3). And that result may very well 71 be incorrect for (4) or (5). 72 73 An incorrect result here does not cause incorrect results out the 74 back end, because the expander in expr.c validizes the address. However 75 it would be nice to improve the handling here in order to produce more 76 precise results. */ 77 78 /* A "template" for memory address, used to determine whether the address is 79 valid for mode. */ 80 81 struct GTY (()) mem_addr_template { 82 rtx ref; /* The template. */ 83 rtx * GTY ((skip)) step_p; /* The point in template where the step should be 84 filled in. */ 85 rtx * GTY ((skip)) off_p; /* The point in template where the offset should 86 be filled in. */ 87 }; 88 89 90 /* The templates. Each of the low five bits of the index corresponds to one 91 component of TARGET_MEM_REF being present, while the high bits identify 92 the address space. See TEMPL_IDX. */ 93 94 static GTY(()) vec<mem_addr_template, va_gc> *mem_addr_template_list; 95 96 #define TEMPL_IDX(AS, SYMBOL, BASE, INDEX, STEP, OFFSET) \ 97 (((int) (AS) << 5) \ 98 | ((SYMBOL != 0) << 4) \ 99 | ((BASE != 0) << 3) \ 100 | ((INDEX != 0) << 2) \ 101 | ((STEP != 0) << 1) \ 102 | (OFFSET != 0)) 103 104 /* Stores address for memory reference with parameters SYMBOL, BASE, INDEX, 105 STEP and OFFSET to *ADDR using address mode ADDRESS_MODE. Stores pointers 106 to where step is placed to *STEP_P and offset to *OFFSET_P. */ 107 108 static void 109 gen_addr_rtx (machine_mode address_mode, 110 rtx symbol, rtx base, rtx index, rtx step, rtx offset, 111 rtx *addr, rtx **step_p, rtx **offset_p) 112 { 113 rtx act_elem; 114 115 *addr = NULL_RTX; 116 if (step_p) 117 *step_p = NULL; 118 if (offset_p) 119 *offset_p = NULL; 120 121 if (index && index != const0_rtx) 122 { 123 act_elem = index; 124 if (step) 125 { 126 act_elem = gen_rtx_MULT (address_mode, act_elem, step); 127 128 if (step_p) 129 *step_p = &XEXP (act_elem, 1); 130 } 131 132 *addr = act_elem; 133 } 134 135 if (base && base != const0_rtx) 136 { 137 if (*addr) 138 *addr = simplify_gen_binary (PLUS, address_mode, base, *addr); 139 else 140 *addr = base; 141 } 142 143 if (symbol) 144 { 145 act_elem = symbol; 146 if (offset) 147 { 148 act_elem = gen_rtx_PLUS (address_mode, act_elem, offset); 149 150 if (offset_p) 151 *offset_p = &XEXP (act_elem, 1); 152 153 if (GET_CODE (symbol) == SYMBOL_REF 154 || GET_CODE (symbol) == LABEL_REF 155 || GET_CODE (symbol) == CONST) 156 act_elem = gen_rtx_CONST (address_mode, act_elem); 157 } 158 159 if (*addr) 160 *addr = gen_rtx_PLUS (address_mode, *addr, act_elem); 161 else 162 *addr = act_elem; 163 } 164 else if (offset) 165 { 166 if (*addr) 167 { 168 *addr = gen_rtx_PLUS (address_mode, *addr, offset); 169 if (offset_p) 170 *offset_p = &XEXP (*addr, 1); 171 } 172 else 173 { 174 *addr = offset; 175 if (offset_p) 176 *offset_p = addr; 177 } 178 } 179 180 if (!*addr) 181 *addr = const0_rtx; 182 } 183 184 /* Returns address for TARGET_MEM_REF with parameters given by ADDR 185 in address space AS. 186 If REALLY_EXPAND is false, just make fake registers instead 187 of really expanding the operands, and perform the expansion in-place 188 by using one of the "templates". */ 189 190 rtx 191 addr_for_mem_ref (struct mem_address *addr, addr_space_t as, 192 bool really_expand) 193 { 194 scalar_int_mode address_mode = targetm.addr_space.address_mode (as); 195 scalar_int_mode pointer_mode = targetm.addr_space.pointer_mode (as); 196 rtx address, sym, bse, idx, st, off; 197 struct mem_addr_template *templ; 198 199 if (addr->step && !integer_onep (addr->step)) 200 st = immed_wide_int_const (wi::to_wide (addr->step), pointer_mode); 201 else 202 st = NULL_RTX; 203 204 if (addr->offset && !integer_zerop (addr->offset)) 205 { 206 poly_offset_int dc 207 = poly_offset_int::from (wi::to_poly_wide (addr->offset), SIGNED); 208 off = immed_wide_int_const (dc, pointer_mode); 209 } 210 else 211 off = NULL_RTX; 212 213 if (!really_expand) 214 { 215 unsigned int templ_index 216 = TEMPL_IDX (as, addr->symbol, addr->base, addr->index, st, off); 217 218 if (templ_index >= vec_safe_length (mem_addr_template_list)) 219 vec_safe_grow_cleared (mem_addr_template_list, templ_index + 1); 220 221 /* Reuse the templates for addresses, so that we do not waste memory. */ 222 templ = &(*mem_addr_template_list)[templ_index]; 223 if (!templ->ref) 224 { 225 sym = (addr->symbol ? 226 gen_rtx_SYMBOL_REF (pointer_mode, ggc_strdup ("test_symbol")) 227 : NULL_RTX); 228 bse = (addr->base ? 229 gen_raw_REG (pointer_mode, LAST_VIRTUAL_REGISTER + 1) 230 : NULL_RTX); 231 idx = (addr->index ? 232 gen_raw_REG (pointer_mode, LAST_VIRTUAL_REGISTER + 2) 233 : NULL_RTX); 234 235 gen_addr_rtx (pointer_mode, sym, bse, idx, 236 st? const0_rtx : NULL_RTX, 237 off? const0_rtx : NULL_RTX, 238 &templ->ref, 239 &templ->step_p, 240 &templ->off_p); 241 } 242 243 if (st) 244 *templ->step_p = st; 245 if (off) 246 *templ->off_p = off; 247 248 return templ->ref; 249 } 250 251 /* Otherwise really expand the expressions. */ 252 sym = (addr->symbol 253 ? expand_expr (addr->symbol, NULL_RTX, pointer_mode, EXPAND_NORMAL) 254 : NULL_RTX); 255 bse = (addr->base 256 ? expand_expr (addr->base, NULL_RTX, pointer_mode, EXPAND_NORMAL) 257 : NULL_RTX); 258 idx = (addr->index 259 ? expand_expr (addr->index, NULL_RTX, pointer_mode, EXPAND_NORMAL) 260 : NULL_RTX); 261 262 /* addr->base could be an SSA_NAME that was set to a constant value. The 263 call to expand_expr may expose that constant. If so, fold the value 264 into OFF and clear BSE. Otherwise we may later try to pull a mode from 265 BSE to generate a REG, which won't work with constants because they 266 are modeless. */ 267 if (bse && GET_CODE (bse) == CONST_INT) 268 { 269 if (off) 270 off = simplify_gen_binary (PLUS, pointer_mode, bse, off); 271 else 272 off = bse; 273 gcc_assert (GET_CODE (off) == CONST_INT); 274 bse = NULL_RTX; 275 } 276 gen_addr_rtx (pointer_mode, sym, bse, idx, st, off, &address, NULL, NULL); 277 if (pointer_mode != address_mode) 278 address = convert_memory_address (address_mode, address); 279 return address; 280 } 281 282 /* implement addr_for_mem_ref() directly from a tree, which avoids exporting 283 the mem_address structure. */ 284 285 rtx 286 addr_for_mem_ref (tree exp, addr_space_t as, bool really_expand) 287 { 288 struct mem_address addr; 289 get_address_description (exp, &addr); 290 return addr_for_mem_ref (&addr, as, really_expand); 291 } 292 293 /* Returns address of MEM_REF in TYPE. */ 294 295 tree 296 tree_mem_ref_addr (tree type, tree mem_ref) 297 { 298 tree addr; 299 tree act_elem; 300 tree step = TMR_STEP (mem_ref), offset = TMR_OFFSET (mem_ref); 301 tree addr_base = NULL_TREE, addr_off = NULL_TREE; 302 303 addr_base = fold_convert (type, TMR_BASE (mem_ref)); 304 305 act_elem = TMR_INDEX (mem_ref); 306 if (act_elem) 307 { 308 if (step) 309 act_elem = fold_build2 (MULT_EXPR, TREE_TYPE (act_elem), 310 act_elem, step); 311 addr_off = act_elem; 312 } 313 314 act_elem = TMR_INDEX2 (mem_ref); 315 if (act_elem) 316 { 317 if (addr_off) 318 addr_off = fold_build2 (PLUS_EXPR, TREE_TYPE (addr_off), 319 addr_off, act_elem); 320 else 321 addr_off = act_elem; 322 } 323 324 if (offset && !integer_zerop (offset)) 325 { 326 if (addr_off) 327 addr_off = fold_build2 (PLUS_EXPR, TREE_TYPE (addr_off), addr_off, 328 fold_convert (TREE_TYPE (addr_off), offset)); 329 else 330 addr_off = offset; 331 } 332 333 if (addr_off) 334 addr = fold_build_pointer_plus (addr_base, addr_off); 335 else 336 addr = addr_base; 337 338 return addr; 339 } 340 341 /* Returns true if a memory reference in MODE and with parameters given by 342 ADDR is valid on the current target. */ 343 344 bool 345 valid_mem_ref_p (machine_mode mode, addr_space_t as, 346 struct mem_address *addr) 347 { 348 rtx address; 349 350 address = addr_for_mem_ref (addr, as, false); 351 if (!address) 352 return false; 353 354 return memory_address_addr_space_p (mode, address, as); 355 } 356 357 /* Checks whether a TARGET_MEM_REF with type TYPE and parameters given by ADDR 358 is valid on the current target and if so, creates and returns the 359 TARGET_MEM_REF. If VERIFY is false omit the verification step. */ 360 361 static tree 362 create_mem_ref_raw (tree type, tree alias_ptr_type, struct mem_address *addr, 363 bool verify) 364 { 365 tree base, index2; 366 367 if (verify 368 && !valid_mem_ref_p (TYPE_MODE (type), TYPE_ADDR_SPACE (type), addr)) 369 return NULL_TREE; 370 371 if (addr->step && integer_onep (addr->step)) 372 addr->step = NULL_TREE; 373 374 if (addr->offset) 375 addr->offset = fold_convert (alias_ptr_type, addr->offset); 376 else 377 addr->offset = build_int_cst (alias_ptr_type, 0); 378 379 if (addr->symbol) 380 { 381 base = addr->symbol; 382 index2 = addr->base; 383 } 384 else if (addr->base 385 && POINTER_TYPE_P (TREE_TYPE (addr->base))) 386 { 387 base = addr->base; 388 index2 = NULL_TREE; 389 } 390 else 391 { 392 base = build_int_cst (build_pointer_type (type), 0); 393 index2 = addr->base; 394 } 395 396 /* If possible use a plain MEM_REF instead of a TARGET_MEM_REF. 397 ??? As IVOPTs does not follow restrictions to where the base 398 pointer may point to create a MEM_REF only if we know that 399 base is valid. */ 400 if ((TREE_CODE (base) == ADDR_EXPR || TREE_CODE (base) == INTEGER_CST) 401 && (!index2 || integer_zerop (index2)) 402 && (!addr->index || integer_zerop (addr->index))) 403 return fold_build2 (MEM_REF, type, base, addr->offset); 404 405 return build5 (TARGET_MEM_REF, type, 406 base, addr->offset, addr->index, addr->step, index2); 407 } 408 409 /* Returns true if OBJ is an object whose address is a link time constant. */ 410 411 static bool 412 fixed_address_object_p (tree obj) 413 { 414 return (VAR_P (obj) 415 && (TREE_STATIC (obj) || DECL_EXTERNAL (obj)) 416 && ! DECL_DLLIMPORT_P (obj)); 417 } 418 419 /* If ADDR contains an address of object that is a link time constant, 420 move it to PARTS->symbol. */ 421 422 void 423 move_fixed_address_to_symbol (struct mem_address *parts, aff_tree *addr) 424 { 425 unsigned i; 426 tree val = NULL_TREE; 427 428 for (i = 0; i < addr->n; i++) 429 { 430 if (addr->elts[i].coef != 1) 431 continue; 432 433 val = addr->elts[i].val; 434 if (TREE_CODE (val) == ADDR_EXPR 435 && fixed_address_object_p (TREE_OPERAND (val, 0))) 436 break; 437 } 438 439 if (i == addr->n) 440 return; 441 442 parts->symbol = val; 443 aff_combination_remove_elt (addr, i); 444 } 445 446 /* Return true if ADDR contains an instance of BASE_HINT and it's moved to 447 PARTS->base. */ 448 449 static bool 450 move_hint_to_base (tree type, struct mem_address *parts, tree base_hint, 451 aff_tree *addr) 452 { 453 unsigned i; 454 tree val = NULL_TREE; 455 int qual; 456 457 for (i = 0; i < addr->n; i++) 458 { 459 if (addr->elts[i].coef != 1) 460 continue; 461 462 val = addr->elts[i].val; 463 if (operand_equal_p (val, base_hint, 0)) 464 break; 465 } 466 467 if (i == addr->n) 468 return false; 469 470 /* Cast value to appropriate pointer type. We cannot use a pointer 471 to TYPE directly, as the back-end will assume registers of pointer 472 type are aligned, and just the base itself may not actually be. 473 We use void pointer to the type's address space instead. */ 474 qual = ENCODE_QUAL_ADDR_SPACE (TYPE_ADDR_SPACE (type)); 475 type = build_qualified_type (void_type_node, qual); 476 parts->base = fold_convert (build_pointer_type (type), val); 477 aff_combination_remove_elt (addr, i); 478 return true; 479 } 480 481 /* If ADDR contains an address of a dereferenced pointer, move it to 482 PARTS->base. */ 483 484 static void 485 move_pointer_to_base (struct mem_address *parts, aff_tree *addr) 486 { 487 unsigned i; 488 tree val = NULL_TREE; 489 490 for (i = 0; i < addr->n; i++) 491 { 492 if (addr->elts[i].coef != 1) 493 continue; 494 495 val = addr->elts[i].val; 496 if (POINTER_TYPE_P (TREE_TYPE (val))) 497 break; 498 } 499 500 if (i == addr->n) 501 return; 502 503 parts->base = val; 504 aff_combination_remove_elt (addr, i); 505 } 506 507 /* Moves the loop variant part V in linear address ADDR to be the index 508 of PARTS. */ 509 510 static void 511 move_variant_to_index (struct mem_address *parts, aff_tree *addr, tree v) 512 { 513 unsigned i; 514 tree val = NULL_TREE; 515 516 gcc_assert (!parts->index); 517 for (i = 0; i < addr->n; i++) 518 { 519 val = addr->elts[i].val; 520 if (operand_equal_p (val, v, 0)) 521 break; 522 } 523 524 if (i == addr->n) 525 return; 526 527 parts->index = fold_convert (sizetype, val); 528 parts->step = wide_int_to_tree (sizetype, addr->elts[i].coef); 529 aff_combination_remove_elt (addr, i); 530 } 531 532 /* Adds ELT to PARTS. */ 533 534 static void 535 add_to_parts (struct mem_address *parts, tree elt) 536 { 537 tree type; 538 539 if (!parts->index) 540 { 541 parts->index = fold_convert (sizetype, elt); 542 return; 543 } 544 545 if (!parts->base) 546 { 547 parts->base = elt; 548 return; 549 } 550 551 /* Add ELT to base. */ 552 type = TREE_TYPE (parts->base); 553 if (POINTER_TYPE_P (type)) 554 parts->base = fold_build_pointer_plus (parts->base, elt); 555 else 556 parts->base = fold_build2 (PLUS_EXPR, type, parts->base, elt); 557 } 558 559 /* Returns true if multiplying by RATIO is allowed in an address. Test the 560 validity for a memory reference accessing memory of mode MODE in address 561 space AS. */ 562 563 static bool 564 multiplier_allowed_in_address_p (HOST_WIDE_INT ratio, machine_mode mode, 565 addr_space_t as) 566 { 567 #define MAX_RATIO 128 568 unsigned int data_index = (int) as * MAX_MACHINE_MODE + (int) mode; 569 static vec<sbitmap> valid_mult_list; 570 sbitmap valid_mult; 571 572 if (data_index >= valid_mult_list.length ()) 573 valid_mult_list.safe_grow_cleared (data_index + 1); 574 575 valid_mult = valid_mult_list[data_index]; 576 if (!valid_mult) 577 { 578 machine_mode address_mode = targetm.addr_space.address_mode (as); 579 rtx reg1 = gen_raw_REG (address_mode, LAST_VIRTUAL_REGISTER + 1); 580 rtx reg2 = gen_raw_REG (address_mode, LAST_VIRTUAL_REGISTER + 2); 581 rtx addr, scaled; 582 HOST_WIDE_INT i; 583 584 valid_mult = sbitmap_alloc (2 * MAX_RATIO + 1); 585 bitmap_clear (valid_mult); 586 scaled = gen_rtx_fmt_ee (MULT, address_mode, reg1, NULL_RTX); 587 addr = gen_rtx_fmt_ee (PLUS, address_mode, scaled, reg2); 588 for (i = -MAX_RATIO; i <= MAX_RATIO; i++) 589 { 590 XEXP (scaled, 1) = gen_int_mode (i, address_mode); 591 if (memory_address_addr_space_p (mode, addr, as) 592 || memory_address_addr_space_p (mode, scaled, as)) 593 bitmap_set_bit (valid_mult, i + MAX_RATIO); 594 } 595 596 if (dump_file && (dump_flags & TDF_DETAILS)) 597 { 598 fprintf (dump_file, " allowed multipliers:"); 599 for (i = -MAX_RATIO; i <= MAX_RATIO; i++) 600 if (bitmap_bit_p (valid_mult, i + MAX_RATIO)) 601 fprintf (dump_file, " %d", (int) i); 602 fprintf (dump_file, "\n"); 603 fprintf (dump_file, "\n"); 604 } 605 606 valid_mult_list[data_index] = valid_mult; 607 } 608 609 if (ratio > MAX_RATIO || ratio < -MAX_RATIO) 610 return false; 611 612 return bitmap_bit_p (valid_mult, ratio + MAX_RATIO); 613 } 614 615 /* Finds the most expensive multiplication in ADDR that can be 616 expressed in an addressing mode and move the corresponding 617 element(s) to PARTS. */ 618 619 static void 620 most_expensive_mult_to_index (tree type, struct mem_address *parts, 621 aff_tree *addr, bool speed) 622 { 623 addr_space_t as = TYPE_ADDR_SPACE (type); 624 machine_mode address_mode = targetm.addr_space.address_mode (as); 625 HOST_WIDE_INT coef; 626 unsigned best_mult_cost = 0, acost; 627 tree mult_elt = NULL_TREE, elt; 628 unsigned i, j; 629 enum tree_code op_code; 630 631 offset_int best_mult = 0; 632 for (i = 0; i < addr->n; i++) 633 { 634 if (!wi::fits_shwi_p (addr->elts[i].coef)) 635 continue; 636 637 coef = addr->elts[i].coef.to_shwi (); 638 if (coef == 1 639 || !multiplier_allowed_in_address_p (coef, TYPE_MODE (type), as)) 640 continue; 641 642 acost = mult_by_coeff_cost (coef, address_mode, speed); 643 644 if (acost > best_mult_cost) 645 { 646 best_mult_cost = acost; 647 best_mult = offset_int::from (addr->elts[i].coef, SIGNED); 648 } 649 } 650 651 if (!best_mult_cost) 652 return; 653 654 /* Collect elements multiplied by best_mult. */ 655 for (i = j = 0; i < addr->n; i++) 656 { 657 offset_int amult = offset_int::from (addr->elts[i].coef, SIGNED); 658 offset_int amult_neg = -wi::sext (amult, TYPE_PRECISION (addr->type)); 659 660 if (amult == best_mult) 661 op_code = PLUS_EXPR; 662 else if (amult_neg == best_mult) 663 op_code = MINUS_EXPR; 664 else 665 { 666 addr->elts[j] = addr->elts[i]; 667 j++; 668 continue; 669 } 670 671 elt = fold_convert (sizetype, addr->elts[i].val); 672 if (mult_elt) 673 mult_elt = fold_build2 (op_code, sizetype, mult_elt, elt); 674 else if (op_code == PLUS_EXPR) 675 mult_elt = elt; 676 else 677 mult_elt = fold_build1 (NEGATE_EXPR, sizetype, elt); 678 } 679 addr->n = j; 680 681 parts->index = mult_elt; 682 parts->step = wide_int_to_tree (sizetype, best_mult); 683 } 684 685 /* Splits address ADDR for a memory access of type TYPE into PARTS. 686 If BASE_HINT is non-NULL, it specifies an SSA name to be used 687 preferentially as base of the reference, and IV_CAND is the selected 688 iv candidate used in ADDR. Store true to VAR_IN_BASE if variant 689 part of address is split to PARTS.base. 690 691 TODO -- be more clever about the distribution of the elements of ADDR 692 to PARTS. Some architectures do not support anything but single 693 register in address, possibly with a small integer offset; while 694 create_mem_ref will simplify the address to an acceptable shape 695 later, it would be more efficient to know that asking for complicated 696 addressing modes is useless. */ 697 698 static void 699 addr_to_parts (tree type, aff_tree *addr, tree iv_cand, tree base_hint, 700 struct mem_address *parts, bool *var_in_base, bool speed) 701 { 702 tree part; 703 unsigned i; 704 705 parts->symbol = NULL_TREE; 706 parts->base = NULL_TREE; 707 parts->index = NULL_TREE; 708 parts->step = NULL_TREE; 709 710 if (maybe_ne (addr->offset, 0)) 711 parts->offset = wide_int_to_tree (sizetype, addr->offset); 712 else 713 parts->offset = NULL_TREE; 714 715 /* Try to find a symbol. */ 716 move_fixed_address_to_symbol (parts, addr); 717 718 /* Since at the moment there is no reliable way to know how to 719 distinguish between pointer and its offset, we decide if var 720 part is the pointer based on guess. */ 721 *var_in_base = (base_hint != NULL && parts->symbol == NULL); 722 if (*var_in_base) 723 *var_in_base = move_hint_to_base (type, parts, base_hint, addr); 724 else 725 move_variant_to_index (parts, addr, iv_cand); 726 727 /* First move the most expensive feasible multiplication to index. */ 728 if (!parts->index) 729 most_expensive_mult_to_index (type, parts, addr, speed); 730 731 /* Move pointer into base. */ 732 if (!parts->symbol && !parts->base) 733 move_pointer_to_base (parts, addr); 734 735 /* Then try to process the remaining elements. */ 736 for (i = 0; i < addr->n; i++) 737 { 738 part = fold_convert (sizetype, addr->elts[i].val); 739 if (addr->elts[i].coef != 1) 740 part = fold_build2 (MULT_EXPR, sizetype, part, 741 wide_int_to_tree (sizetype, addr->elts[i].coef)); 742 add_to_parts (parts, part); 743 } 744 if (addr->rest) 745 add_to_parts (parts, fold_convert (sizetype, addr->rest)); 746 } 747 748 /* Force the PARTS to register. */ 749 750 static void 751 gimplify_mem_ref_parts (gimple_stmt_iterator *gsi, struct mem_address *parts) 752 { 753 if (parts->base) 754 parts->base = force_gimple_operand_gsi_1 (gsi, parts->base, 755 is_gimple_mem_ref_addr, NULL_TREE, 756 true, GSI_SAME_STMT); 757 if (parts->index) 758 parts->index = force_gimple_operand_gsi (gsi, parts->index, 759 true, NULL_TREE, 760 true, GSI_SAME_STMT); 761 } 762 763 /* Return true if the OFFSET in PARTS is the only thing that is making 764 it an invalid address for type TYPE. */ 765 766 static bool 767 mem_ref_valid_without_offset_p (tree type, mem_address parts) 768 { 769 if (!parts.base) 770 parts.base = parts.offset; 771 parts.offset = NULL_TREE; 772 return valid_mem_ref_p (TYPE_MODE (type), TYPE_ADDR_SPACE (type), &parts); 773 } 774 775 /* Fold PARTS->offset into PARTS->base, so that there is no longer 776 a separate offset. Emit any new instructions before GSI. */ 777 778 static void 779 add_offset_to_base (gimple_stmt_iterator *gsi, mem_address *parts) 780 { 781 tree tmp = parts->offset; 782 if (parts->base) 783 { 784 tmp = fold_build_pointer_plus (parts->base, tmp); 785 tmp = force_gimple_operand_gsi_1 (gsi, tmp, is_gimple_mem_ref_addr, 786 NULL_TREE, true, GSI_SAME_STMT); 787 } 788 parts->base = tmp; 789 parts->offset = NULL_TREE; 790 } 791 792 /* Creates and returns a TARGET_MEM_REF for address ADDR. If necessary 793 computations are emitted in front of GSI. TYPE is the mode 794 of created memory reference. IV_CAND is the selected iv candidate in ADDR, 795 and BASE_HINT is non NULL if IV_CAND comes from a base address 796 object. */ 797 798 tree 799 create_mem_ref (gimple_stmt_iterator *gsi, tree type, aff_tree *addr, 800 tree alias_ptr_type, tree iv_cand, tree base_hint, bool speed) 801 { 802 bool var_in_base; 803 tree mem_ref, tmp; 804 struct mem_address parts; 805 806 addr_to_parts (type, addr, iv_cand, base_hint, &parts, &var_in_base, speed); 807 gimplify_mem_ref_parts (gsi, &parts); 808 mem_ref = create_mem_ref_raw (type, alias_ptr_type, &parts, true); 809 if (mem_ref) 810 return mem_ref; 811 812 /* The expression is too complicated. Try making it simpler. */ 813 814 /* Merge symbol into other parts. */ 815 if (parts.symbol) 816 { 817 tmp = parts.symbol; 818 parts.symbol = NULL_TREE; 819 gcc_assert (is_gimple_val (tmp)); 820 821 if (parts.base) 822 { 823 gcc_assert (useless_type_conversion_p (sizetype, 824 TREE_TYPE (parts.base))); 825 826 if (parts.index) 827 { 828 /* Add the symbol to base, eventually forcing it to register. */ 829 tmp = fold_build_pointer_plus (tmp, parts.base); 830 tmp = force_gimple_operand_gsi_1 (gsi, tmp, 831 is_gimple_mem_ref_addr, 832 NULL_TREE, true, 833 GSI_SAME_STMT); 834 } 835 else 836 { 837 /* Move base to index, then move the symbol to base. */ 838 parts.index = parts.base; 839 } 840 parts.base = tmp; 841 } 842 else 843 parts.base = tmp; 844 845 mem_ref = create_mem_ref_raw (type, alias_ptr_type, &parts, true); 846 if (mem_ref) 847 return mem_ref; 848 } 849 850 /* Move multiplication to index by transforming address expression: 851 [... + index << step + ...] 852 into: 853 index' = index << step; 854 [... + index' + ,,,]. */ 855 if (parts.step && !integer_onep (parts.step)) 856 { 857 gcc_assert (parts.index); 858 if (parts.offset && mem_ref_valid_without_offset_p (type, parts)) 859 { 860 add_offset_to_base (gsi, &parts); 861 mem_ref = create_mem_ref_raw (type, alias_ptr_type, &parts, true); 862 gcc_assert (mem_ref); 863 return mem_ref; 864 } 865 866 parts.index = force_gimple_operand_gsi (gsi, 867 fold_build2 (MULT_EXPR, sizetype, 868 parts.index, parts.step), 869 true, NULL_TREE, true, GSI_SAME_STMT); 870 parts.step = NULL_TREE; 871 872 mem_ref = create_mem_ref_raw (type, alias_ptr_type, &parts, true); 873 if (mem_ref) 874 return mem_ref; 875 } 876 877 /* Add offset to invariant part by transforming address expression: 878 [base + index + offset] 879 into: 880 base' = base + offset; 881 [base' + index] 882 or: 883 index' = index + offset; 884 [base + index'] 885 depending on which one is invariant. */ 886 if (parts.offset && !integer_zerop (parts.offset)) 887 { 888 tree old_base = unshare_expr (parts.base); 889 tree old_index = unshare_expr (parts.index); 890 tree old_offset = unshare_expr (parts.offset); 891 892 tmp = parts.offset; 893 parts.offset = NULL_TREE; 894 /* Add offset to invariant part. */ 895 if (!var_in_base) 896 { 897 if (parts.base) 898 { 899 tmp = fold_build_pointer_plus (parts.base, tmp); 900 tmp = force_gimple_operand_gsi_1 (gsi, tmp, 901 is_gimple_mem_ref_addr, 902 NULL_TREE, true, 903 GSI_SAME_STMT); 904 } 905 parts.base = tmp; 906 } 907 else 908 { 909 if (parts.index) 910 { 911 tmp = fold_build_pointer_plus (parts.index, tmp); 912 tmp = force_gimple_operand_gsi_1 (gsi, tmp, 913 is_gimple_mem_ref_addr, 914 NULL_TREE, true, 915 GSI_SAME_STMT); 916 } 917 parts.index = tmp; 918 } 919 920 mem_ref = create_mem_ref_raw (type, alias_ptr_type, &parts, true); 921 if (mem_ref) 922 return mem_ref; 923 924 /* Restore parts.base, index and offset so that we can check if 925 [base + offset] addressing mode is supported in next step. 926 This is necessary for targets only support [base + offset], 927 but not [base + index] addressing mode. */ 928 parts.base = old_base; 929 parts.index = old_index; 930 parts.offset = old_offset; 931 } 932 933 /* Transform [base + index + ...] into: 934 base' = base + index; 935 [base' + ...]. */ 936 if (parts.index) 937 { 938 tmp = parts.index; 939 parts.index = NULL_TREE; 940 /* Add index to base. */ 941 if (parts.base) 942 { 943 tmp = fold_build_pointer_plus (parts.base, tmp); 944 tmp = force_gimple_operand_gsi_1 (gsi, tmp, 945 is_gimple_mem_ref_addr, 946 NULL_TREE, true, GSI_SAME_STMT); 947 } 948 parts.base = tmp; 949 950 mem_ref = create_mem_ref_raw (type, alias_ptr_type, &parts, true); 951 if (mem_ref) 952 return mem_ref; 953 } 954 955 /* Transform [base + offset] into: 956 base' = base + offset; 957 [base']. */ 958 if (parts.offset && !integer_zerop (parts.offset)) 959 { 960 add_offset_to_base (gsi, &parts); 961 mem_ref = create_mem_ref_raw (type, alias_ptr_type, &parts, true); 962 if (mem_ref) 963 return mem_ref; 964 } 965 966 /* Verify that the address is in the simplest possible shape 967 (only a register). If we cannot create such a memory reference, 968 something is really wrong. */ 969 gcc_assert (parts.symbol == NULL_TREE); 970 gcc_assert (parts.index == NULL_TREE); 971 gcc_assert (!parts.step || integer_onep (parts.step)); 972 gcc_assert (!parts.offset || integer_zerop (parts.offset)); 973 gcc_unreachable (); 974 } 975 976 /* Copies components of the address from OP to ADDR. */ 977 978 void 979 get_address_description (tree op, struct mem_address *addr) 980 { 981 if (TREE_CODE (TMR_BASE (op)) == ADDR_EXPR) 982 { 983 addr->symbol = TMR_BASE (op); 984 addr->base = TMR_INDEX2 (op); 985 } 986 else 987 { 988 addr->symbol = NULL_TREE; 989 if (TMR_INDEX2 (op)) 990 { 991 gcc_assert (integer_zerop (TMR_BASE (op))); 992 addr->base = TMR_INDEX2 (op); 993 } 994 else 995 addr->base = TMR_BASE (op); 996 } 997 addr->index = TMR_INDEX (op); 998 addr->step = TMR_STEP (op); 999 addr->offset = TMR_OFFSET (op); 1000 } 1001 1002 /* Copies the reference information from OLD_REF to NEW_REF, where 1003 NEW_REF should be either a MEM_REF or a TARGET_MEM_REF. */ 1004 1005 void 1006 copy_ref_info (tree new_ref, tree old_ref) 1007 { 1008 tree new_ptr_base = NULL_TREE; 1009 1010 gcc_assert (TREE_CODE (new_ref) == MEM_REF 1011 || TREE_CODE (new_ref) == TARGET_MEM_REF); 1012 1013 TREE_SIDE_EFFECTS (new_ref) = TREE_SIDE_EFFECTS (old_ref); 1014 TREE_THIS_VOLATILE (new_ref) = TREE_THIS_VOLATILE (old_ref); 1015 1016 new_ptr_base = TREE_OPERAND (new_ref, 0); 1017 1018 /* We can transfer points-to information from an old pointer 1019 or decl base to the new one. */ 1020 if (new_ptr_base 1021 && TREE_CODE (new_ptr_base) == SSA_NAME 1022 && !SSA_NAME_PTR_INFO (new_ptr_base)) 1023 { 1024 tree base = get_base_address (old_ref); 1025 if (!base) 1026 ; 1027 else if ((TREE_CODE (base) == MEM_REF 1028 || TREE_CODE (base) == TARGET_MEM_REF) 1029 && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME 1030 && SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0))) 1031 { 1032 struct ptr_info_def *new_pi; 1033 unsigned int align, misalign; 1034 1035 duplicate_ssa_name_ptr_info 1036 (new_ptr_base, SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0))); 1037 new_pi = SSA_NAME_PTR_INFO (new_ptr_base); 1038 /* We have to be careful about transferring alignment information. */ 1039 if (get_ptr_info_alignment (new_pi, &align, &misalign) 1040 && TREE_CODE (old_ref) == MEM_REF 1041 && !(TREE_CODE (new_ref) == TARGET_MEM_REF 1042 && (TMR_INDEX2 (new_ref) 1043 /* TODO: Below conditions can be relaxed if TMR_INDEX 1044 is an indcution variable and its initial value and 1045 step are aligned. */ 1046 || (TMR_INDEX (new_ref) && !TMR_STEP (new_ref)) 1047 || (TMR_STEP (new_ref) 1048 && (TREE_INT_CST_LOW (TMR_STEP (new_ref)) 1049 < align))))) 1050 { 1051 poly_uint64 inc = (mem_ref_offset (old_ref) 1052 - mem_ref_offset (new_ref)).force_uhwi (); 1053 adjust_ptr_info_misalignment (new_pi, inc); 1054 } 1055 else 1056 mark_ptr_info_alignment_unknown (new_pi); 1057 } 1058 else if (VAR_P (base) 1059 || TREE_CODE (base) == PARM_DECL 1060 || TREE_CODE (base) == RESULT_DECL) 1061 { 1062 struct ptr_info_def *pi = get_ptr_info (new_ptr_base); 1063 pt_solution_set_var (&pi->pt, base); 1064 } 1065 } 1066 } 1067 1068 /* Move constants in target_mem_ref REF to offset. Returns the new target 1069 mem ref if anything changes, NULL_TREE otherwise. */ 1070 1071 tree 1072 maybe_fold_tmr (tree ref) 1073 { 1074 struct mem_address addr; 1075 bool changed = false; 1076 tree new_ref, off; 1077 1078 get_address_description (ref, &addr); 1079 1080 if (addr.base 1081 && TREE_CODE (addr.base) == INTEGER_CST 1082 && !integer_zerop (addr.base)) 1083 { 1084 addr.offset = fold_binary_to_constant (PLUS_EXPR, 1085 TREE_TYPE (addr.offset), 1086 addr.offset, addr.base); 1087 addr.base = NULL_TREE; 1088 changed = true; 1089 } 1090 1091 if (addr.symbol 1092 && TREE_CODE (TREE_OPERAND (addr.symbol, 0)) == MEM_REF) 1093 { 1094 addr.offset = fold_binary_to_constant 1095 (PLUS_EXPR, TREE_TYPE (addr.offset), 1096 addr.offset, 1097 TREE_OPERAND (TREE_OPERAND (addr.symbol, 0), 1)); 1098 addr.symbol = TREE_OPERAND (TREE_OPERAND (addr.symbol, 0), 0); 1099 changed = true; 1100 } 1101 else if (addr.symbol 1102 && handled_component_p (TREE_OPERAND (addr.symbol, 0))) 1103 { 1104 poly_int64 offset; 1105 addr.symbol = build_fold_addr_expr 1106 (get_addr_base_and_unit_offset 1107 (TREE_OPERAND (addr.symbol, 0), &offset)); 1108 addr.offset = int_const_binop (PLUS_EXPR, 1109 addr.offset, size_int (offset)); 1110 changed = true; 1111 } 1112 1113 if (addr.index && TREE_CODE (addr.index) == INTEGER_CST) 1114 { 1115 off = addr.index; 1116 if (addr.step) 1117 { 1118 off = fold_binary_to_constant (MULT_EXPR, sizetype, 1119 off, addr.step); 1120 addr.step = NULL_TREE; 1121 } 1122 1123 addr.offset = fold_binary_to_constant (PLUS_EXPR, 1124 TREE_TYPE (addr.offset), 1125 addr.offset, off); 1126 addr.index = NULL_TREE; 1127 changed = true; 1128 } 1129 1130 if (!changed) 1131 return NULL_TREE; 1132 1133 /* If we have propagated something into this TARGET_MEM_REF and thus 1134 ended up folding it, always create a new TARGET_MEM_REF regardless 1135 if it is valid in this for on the target - the propagation result 1136 wouldn't be anyway. */ 1137 new_ref = create_mem_ref_raw (TREE_TYPE (ref), 1138 TREE_TYPE (addr.offset), &addr, false); 1139 TREE_SIDE_EFFECTS (new_ref) = TREE_SIDE_EFFECTS (ref); 1140 TREE_THIS_VOLATILE (new_ref) = TREE_THIS_VOLATILE (ref); 1141 return new_ref; 1142 } 1143 1144 /* Dump PARTS to FILE. */ 1145 1146 extern void dump_mem_address (FILE *, struct mem_address *); 1147 void 1148 dump_mem_address (FILE *file, struct mem_address *parts) 1149 { 1150 if (parts->symbol) 1151 { 1152 fprintf (file, "symbol: "); 1153 print_generic_expr (file, TREE_OPERAND (parts->symbol, 0), TDF_SLIM); 1154 fprintf (file, "\n"); 1155 } 1156 if (parts->base) 1157 { 1158 fprintf (file, "base: "); 1159 print_generic_expr (file, parts->base, TDF_SLIM); 1160 fprintf (file, "\n"); 1161 } 1162 if (parts->index) 1163 { 1164 fprintf (file, "index: "); 1165 print_generic_expr (file, parts->index, TDF_SLIM); 1166 fprintf (file, "\n"); 1167 } 1168 if (parts->step) 1169 { 1170 fprintf (file, "step: "); 1171 print_generic_expr (file, parts->step, TDF_SLIM); 1172 fprintf (file, "\n"); 1173 } 1174 if (parts->offset) 1175 { 1176 fprintf (file, "offset: "); 1177 print_generic_expr (file, parts->offset, TDF_SLIM); 1178 fprintf (file, "\n"); 1179 } 1180 } 1181 1182 #include "gt-tree-ssa-address.h" 1183