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