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