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