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