* tree-data-ref.c (conflict_fn): Assert that the number of affine
[official-gcc.git] / gcc / tree-ssa-address.c
blob69a41a48edf64b84338262b01941cdc33941a761
1 /* Memory address lowering and addressing mode selection.
2 Copyright (C) 2004 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING. If not, write to the Free
18 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301, USA. */
21 /* Utility functions for manipulation with TARGET_MEM_REFs -- tree expressions
22 that directly map to addressing modes of the target. */
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tm.h"
28 #include "tree.h"
29 #include "rtl.h"
30 #include "tm_p.h"
31 #include "hard-reg-set.h"
32 #include "basic-block.h"
33 #include "output.h"
34 #include "diagnostic.h"
35 #include "tree-flow.h"
36 #include "tree-dump.h"
37 #include "tree-pass.h"
38 #include "timevar.h"
39 #include "flags.h"
40 #include "tree-inline.h"
41 #include "insn-config.h"
42 #include "recog.h"
43 #include "expr.h"
44 #include "ggc.h"
45 #include "tree-affine.h"
47 /* TODO -- handling of symbols (according to Richard Hendersons
48 comments, http://gcc.gnu.org/ml/gcc-patches/2005-04/msg00949.html):
50 There are at least 5 different kinds of symbols that we can run up against:
52 (1) binds_local_p, small data area.
53 (2) binds_local_p, eg local statics
54 (3) !binds_local_p, eg global variables
55 (4) thread local, local_exec
56 (5) thread local, !local_exec
58 Now, (1) won't appear often in an array context, but it certainly can.
59 All you have to do is set -GN high enough, or explicitly mark any
60 random object __attribute__((section (".sdata"))).
62 All of these affect whether or not a symbol is in fact a valid address.
63 The only one tested here is (3). And that result may very well
64 be incorrect for (4) or (5).
66 An incorrect result here does not cause incorrect results out the
67 back end, because the expander in expr.c validizes the address. However
68 it would be nice to improve the handling here in order to produce more
69 precise results. */
71 /* A "template" for memory address, used to determine whether the address is
72 valid for mode. */
74 struct mem_addr_template GTY (())
76 rtx ref; /* The template. */
77 rtx * GTY ((skip)) step_p; /* The point in template where the step should be
78 filled in. */
79 rtx * GTY ((skip)) off_p; /* The point in template where the offset should
80 be filled in. */
83 /* The templates. Each of the five bits of the index corresponds to one
84 component of TARGET_MEM_REF being present, see TEMPL_IDX. */
86 static GTY (()) struct mem_addr_template templates[32];
88 #define TEMPL_IDX(SYMBOL, BASE, INDEX, STEP, OFFSET) \
89 (((SYMBOL != 0) << 4) \
90 | ((BASE != 0) << 3) \
91 | ((INDEX != 0) << 2) \
92 | ((STEP != 0) << 1) \
93 | (OFFSET != 0))
95 /* Stores address for memory reference with parameters SYMBOL, BASE, INDEX,
96 STEP and OFFSET to *ADDR. Stores pointers to where step is placed to
97 *STEP_P and offset to *OFFSET_P. */
99 static void
100 gen_addr_rtx (rtx symbol, rtx base, rtx index, rtx step, rtx offset,
101 rtx *addr, rtx **step_p, rtx **offset_p)
103 rtx act_elem;
105 *addr = NULL_RTX;
106 if (step_p)
107 *step_p = NULL;
108 if (offset_p)
109 *offset_p = NULL;
111 if (index)
113 act_elem = index;
114 if (step)
116 act_elem = gen_rtx_MULT (Pmode, act_elem, step);
118 if (step_p)
119 *step_p = &XEXP (act_elem, 1);
122 *addr = act_elem;
125 if (base)
127 if (*addr)
128 *addr = gen_rtx_PLUS (Pmode, *addr, base);
129 else
130 *addr = base;
133 if (symbol)
135 act_elem = symbol;
136 if (offset)
138 act_elem = gen_rtx_CONST (Pmode,
139 gen_rtx_PLUS (Pmode, act_elem, offset));
140 if (offset_p)
141 *offset_p = &XEXP (XEXP (act_elem, 0), 1);
144 if (*addr)
145 *addr = gen_rtx_PLUS (Pmode, *addr, act_elem);
146 else
147 *addr = act_elem;
149 else if (offset)
151 if (*addr)
153 *addr = gen_rtx_PLUS (Pmode, *addr, offset);
154 if (offset_p)
155 *offset_p = &XEXP (*addr, 1);
157 else
159 *addr = offset;
160 if (offset_p)
161 *offset_p = addr;
165 if (!*addr)
166 *addr = const0_rtx;
169 /* Returns address for TARGET_MEM_REF with parameters given by ADDR.
170 If REALLY_EXPAND is false, just make fake registers instead
171 of really expanding the operands, and perform the expansion in-place
172 by using one of the "templates". */
175 addr_for_mem_ref (struct mem_address *addr, bool really_expand)
177 rtx address, sym, bse, idx, st, off;
178 static bool templates_initialized = false;
179 struct mem_addr_template *templ;
181 if (addr->step && !integer_onep (addr->step))
182 st = immed_double_const (TREE_INT_CST_LOW (addr->step),
183 TREE_INT_CST_HIGH (addr->step), Pmode);
184 else
185 st = NULL_RTX;
187 if (addr->offset && !integer_zerop (addr->offset))
188 off = immed_double_const (TREE_INT_CST_LOW (addr->offset),
189 TREE_INT_CST_HIGH (addr->offset), Pmode);
190 else
191 off = NULL_RTX;
193 if (!really_expand)
195 /* Reuse the templates for addresses, so that we do not waste memory. */
196 if (!templates_initialized)
198 unsigned i;
200 templates_initialized = true;
201 sym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup ("test_symbol"));
202 bse = gen_raw_REG (Pmode, LAST_VIRTUAL_REGISTER + 1);
203 idx = gen_raw_REG (Pmode, LAST_VIRTUAL_REGISTER + 2);
205 for (i = 0; i < 32; i++)
206 gen_addr_rtx ((i & 16 ? sym : NULL_RTX),
207 (i & 8 ? bse : NULL_RTX),
208 (i & 4 ? idx : NULL_RTX),
209 (i & 2 ? const0_rtx : NULL_RTX),
210 (i & 1 ? const0_rtx : NULL_RTX),
211 &templates[i].ref,
212 &templates[i].step_p,
213 &templates[i].off_p);
216 templ = templates + TEMPL_IDX (addr->symbol, addr->base, addr->index,
217 st, off);
218 if (st)
219 *templ->step_p = st;
220 if (off)
221 *templ->off_p = off;
223 return templ->ref;
226 /* Otherwise really expand the expressions. */
227 sym = (addr->symbol
228 ? expand_expr (build_addr (addr->symbol, current_function_decl),
229 NULL_RTX, Pmode, EXPAND_NORMAL)
230 : NULL_RTX);
231 bse = (addr->base
232 ? expand_expr (addr->base, NULL_RTX, Pmode, EXPAND_NORMAL)
233 : NULL_RTX);
234 idx = (addr->index
235 ? expand_expr (addr->index, NULL_RTX, Pmode, EXPAND_NORMAL)
236 : NULL_RTX);
238 gen_addr_rtx (sym, bse, idx, st, off, &address, NULL, NULL);
239 return address;
242 /* Returns address of MEM_REF in TYPE. */
244 tree
245 tree_mem_ref_addr (tree type, tree mem_ref)
247 tree addr;
248 tree act_elem;
249 tree step = TMR_STEP (mem_ref), offset = TMR_OFFSET (mem_ref);
250 tree sym = TMR_SYMBOL (mem_ref), base = TMR_BASE (mem_ref);
251 tree addr_base = NULL_TREE, addr_off = NULL_TREE;
253 if (sym)
254 addr_base = fold_convert (type, build_addr (sym, current_function_decl));
255 else if (base && POINTER_TYPE_P (TREE_TYPE (base)))
257 addr_base = fold_convert (type, base);
258 base = NULL_TREE;
261 act_elem = TMR_INDEX (mem_ref);
262 if (act_elem)
264 if (step)
265 act_elem = fold_build2 (MULT_EXPR, sizetype, act_elem, step);
266 addr_off = act_elem;
269 act_elem = base;
270 if (act_elem)
272 if (addr_off)
273 addr_off = fold_build2 (PLUS_EXPR, sizetype, addr_off, act_elem);
274 else
275 addr_off = act_elem;
278 if (offset && !integer_zerop (offset))
280 if (addr_off)
281 addr_off = fold_build2 (PLUS_EXPR, sizetype, addr_off, offset);
282 else
283 addr_off = offset;
286 if (addr_off)
288 addr = fold_convert (type, addr_off);
289 if (addr_base)
290 addr = fold_build2 (PLUS_EXPR, type, addr_base, addr);
292 else if (addr_base)
293 addr = addr_base;
294 else
295 addr = build_int_cst (type, 0);
297 return addr;
300 /* Returns true if a memory reference in MODE and with parameters given by
301 ADDR is valid on the current target. */
303 static bool
304 valid_mem_ref_p (enum machine_mode mode, struct mem_address *addr)
306 rtx address;
308 address = addr_for_mem_ref (addr, false);
309 if (!address)
310 return false;
312 return memory_address_p (mode, address);
315 /* Checks whether a TARGET_MEM_REF with type TYPE and parameters given by ADDR
316 is valid on the current target and if so, creates and returns the
317 TARGET_MEM_REF. */
319 static tree
320 create_mem_ref_raw (tree type, struct mem_address *addr)
322 if (!valid_mem_ref_p (TYPE_MODE (type), addr))
323 return NULL_TREE;
325 if (addr->step && integer_onep (addr->step))
326 addr->step = NULL_TREE;
328 if (addr->offset && integer_zerop (addr->offset))
329 addr->offset = NULL_TREE;
331 return build7 (TARGET_MEM_REF, type,
332 addr->symbol, addr->base, addr->index,
333 addr->step, addr->offset, NULL, NULL);
336 /* Returns true if OBJ is an object whose address is a link time constant. */
338 static bool
339 fixed_address_object_p (tree obj)
341 return (TREE_CODE (obj) == VAR_DECL
342 && (TREE_STATIC (obj)
343 || DECL_EXTERNAL (obj)));
346 /* If ADDR contains an address of object that is a link time constant,
347 move it to PARTS->symbol. */
349 static void
350 move_fixed_address_to_symbol (struct mem_address *parts, aff_tree *addr)
352 unsigned i;
353 tree val = NULL_TREE;
355 for (i = 0; i < addr->n; i++)
357 if (!double_int_one_p (addr->elts[i].coef))
358 continue;
360 val = addr->elts[i].val;
361 if (TREE_CODE (val) == ADDR_EXPR
362 && fixed_address_object_p (TREE_OPERAND (val, 0)))
363 break;
366 if (i == addr->n)
367 return;
369 parts->symbol = TREE_OPERAND (val, 0);
370 aff_combination_remove_elt (addr, i);
373 /* If ADDR contains an address of a dereferenced pointer, move it to
374 PARTS->base. */
376 static void
377 move_pointer_to_base (struct mem_address *parts, aff_tree *addr)
379 unsigned i;
380 tree val = NULL_TREE;
382 for (i = 0; i < addr->n; i++)
384 if (!double_int_one_p (addr->elts[i].coef))
385 continue;
387 val = addr->elts[i].val;
388 if (POINTER_TYPE_P (TREE_TYPE (val)))
389 break;
392 if (i == addr->n)
393 return;
395 parts->base = val;
396 aff_combination_remove_elt (addr, i);
399 /* Adds ELT to PARTS. */
401 static void
402 add_to_parts (struct mem_address *parts, tree elt)
404 tree type;
406 if (!parts->index)
408 parts->index = elt;
409 return;
412 if (!parts->base)
414 parts->base = elt;
415 return;
418 /* Add ELT to base. */
419 type = TREE_TYPE (parts->base);
420 parts->base = fold_build2 (PLUS_EXPR, type,
421 parts->base,
422 fold_convert (type, elt));
425 /* Finds the most expensive multiplication in ADDR that can be
426 expressed in an addressing mode and move the corresponding
427 element(s) to PARTS. */
429 static void
430 most_expensive_mult_to_index (struct mem_address *parts, aff_tree *addr)
432 HOST_WIDE_INT coef;
433 double_int best_mult, amult, amult_neg;
434 unsigned best_mult_cost = 0, acost;
435 tree mult_elt = NULL_TREE, elt;
436 unsigned i, j;
437 enum tree_code op_code;
439 best_mult = double_int_zero;
440 for (i = 0; i < addr->n; i++)
442 if (!double_int_fits_in_shwi_p (addr->elts[i].coef))
443 continue;
445 /* FIXME: Should use the correct memory mode rather than Pmode. */
447 coef = double_int_to_shwi (addr->elts[i].coef);
448 if (coef == 1
449 || !multiplier_allowed_in_address_p (coef, Pmode))
450 continue;
452 acost = multiply_by_cost (coef, Pmode);
454 if (acost > best_mult_cost)
456 best_mult_cost = acost;
457 best_mult = addr->elts[i].coef;
461 if (!best_mult_cost)
462 return;
464 /* Collect elements multiplied by best_mult. */
465 for (i = j = 0; i < addr->n; i++)
467 amult = addr->elts[i].coef;
468 amult_neg = double_int_ext_for_comb (double_int_neg (amult), addr);
470 if (double_int_equal_p (amult, best_mult))
471 op_code = PLUS_EXPR;
472 else if (double_int_equal_p (amult_neg, best_mult))
473 op_code = MINUS_EXPR;
474 else
476 addr->elts[j] = addr->elts[i];
477 j++;
478 continue;
481 elt = fold_convert (sizetype, addr->elts[i].val);
482 if (mult_elt)
483 mult_elt = fold_build2 (op_code, sizetype, mult_elt, elt);
484 else if (op_code == PLUS_EXPR)
485 mult_elt = elt;
486 else
487 mult_elt = fold_build1 (NEGATE_EXPR, sizetype, elt);
489 addr->n = j;
491 parts->index = mult_elt;
492 parts->step = double_int_to_tree (sizetype, best_mult);
495 /* Splits address ADDR into PARTS.
497 TODO -- be more clever about the distribution of the elements of ADDR
498 to PARTS. Some architectures do not support anything but single
499 register in address, possibly with a small integer offset; while
500 create_mem_ref will simplify the address to an acceptable shape
501 later, it would be more efficient to know that asking for complicated
502 addressing modes is useless. */
504 static void
505 addr_to_parts (aff_tree *addr, struct mem_address *parts)
507 tree part;
508 unsigned i;
510 parts->symbol = NULL_TREE;
511 parts->base = NULL_TREE;
512 parts->index = NULL_TREE;
513 parts->step = NULL_TREE;
515 if (!double_int_zero_p (addr->offset))
516 parts->offset = double_int_to_tree (sizetype, addr->offset);
517 else
518 parts->offset = NULL_TREE;
520 /* Try to find a symbol. */
521 move_fixed_address_to_symbol (parts, addr);
523 /* First move the most expensive feasible multiplication
524 to index. */
525 most_expensive_mult_to_index (parts, addr);
527 /* Try to find a base of the reference. Since at the moment
528 there is no reliable way how to distinguish between pointer and its
529 offset, this is just a guess. */
530 if (!parts->symbol)
531 move_pointer_to_base (parts, addr);
533 /* Then try to process the remaining elements. */
534 for (i = 0; i < addr->n; i++)
536 part = fold_convert (sizetype, addr->elts[i].val);
537 if (!double_int_one_p (addr->elts[i].coef))
538 part = fold_build2 (MULT_EXPR, sizetype, part,
539 double_int_to_tree (sizetype, addr->elts[i].coef));
540 add_to_parts (parts, part);
542 if (addr->rest)
543 add_to_parts (parts, fold_convert (sizetype, addr->rest));
546 /* Force the PARTS to register. */
548 static void
549 gimplify_mem_ref_parts (block_stmt_iterator *bsi, struct mem_address *parts)
551 if (parts->base)
552 parts->base = force_gimple_operand_bsi (bsi, parts->base,
553 true, NULL_TREE);
554 if (parts->index)
555 parts->index = force_gimple_operand_bsi (bsi, parts->index,
556 true, NULL_TREE);
559 /* Creates and returns a TARGET_MEM_REF for address ADDR. If necessary
560 computations are emitted in front of BSI. TYPE is the mode
561 of created memory reference. */
563 tree
564 create_mem_ref (block_stmt_iterator *bsi, tree type, aff_tree *addr)
566 tree mem_ref, tmp;
567 tree addr_type = build_pointer_type (type), atype;
568 struct mem_address parts;
570 addr_to_parts (addr, &parts);
571 gimplify_mem_ref_parts (bsi, &parts);
572 mem_ref = create_mem_ref_raw (type, &parts);
573 if (mem_ref)
574 return mem_ref;
576 /* The expression is too complicated. Try making it simpler. */
578 if (parts.step && !integer_onep (parts.step))
580 /* Move the multiplication to index. */
581 gcc_assert (parts.index);
582 parts.index = force_gimple_operand_bsi (bsi,
583 fold_build2 (MULT_EXPR, sizetype,
584 parts.index, parts.step),
585 true, NULL_TREE);
586 parts.step = NULL_TREE;
588 mem_ref = create_mem_ref_raw (type, &parts);
589 if (mem_ref)
590 return mem_ref;
593 if (parts.symbol)
595 tmp = fold_convert (addr_type,
596 build_addr (parts.symbol, current_function_decl));
598 /* Add the symbol to base, eventually forcing it to register. */
599 if (parts.base)
601 if (parts.index)
602 parts.base = force_gimple_operand_bsi (bsi,
603 fold_build2 (PLUS_EXPR, addr_type,
604 fold_convert (addr_type, parts.base),
605 tmp),
606 true, NULL_TREE);
607 else
609 parts.index = parts.base;
610 parts.base = tmp;
613 else
614 parts.base = tmp;
615 parts.symbol = NULL_TREE;
617 mem_ref = create_mem_ref_raw (type, &parts);
618 if (mem_ref)
619 return mem_ref;
622 if (parts.index)
624 /* Add index to base. */
625 if (parts.base)
627 atype = TREE_TYPE (parts.base);
628 parts.base = force_gimple_operand_bsi (bsi,
629 fold_build2 (PLUS_EXPR, atype,
630 parts.base,
631 fold_convert (atype, parts.index)),
632 true, NULL_TREE);
634 else
635 parts.base = parts.index;
636 parts.index = NULL_TREE;
638 mem_ref = create_mem_ref_raw (type, &parts);
639 if (mem_ref)
640 return mem_ref;
643 if (parts.offset && !integer_zerop (parts.offset))
645 /* Try adding offset to base. */
646 if (parts.base)
648 atype = TREE_TYPE (parts.base);
649 parts.base = force_gimple_operand_bsi (bsi,
650 fold_build2 (PLUS_EXPR, atype,
651 parts.base,
652 fold_convert (atype, parts.offset)),
653 true, NULL_TREE);
655 else
656 parts.base = parts.offset;
658 parts.offset = NULL_TREE;
660 mem_ref = create_mem_ref_raw (type, &parts);
661 if (mem_ref)
662 return mem_ref;
665 /* Verify that the address is in the simplest possible shape
666 (only a register). If we cannot create such a memory reference,
667 something is really wrong. */
668 gcc_assert (parts.symbol == NULL_TREE);
669 gcc_assert (parts.index == NULL_TREE);
670 gcc_assert (!parts.step || integer_onep (parts.step));
671 gcc_assert (!parts.offset || integer_zerop (parts.offset));
672 gcc_unreachable ();
675 /* Copies components of the address from OP to ADDR. */
677 void
678 get_address_description (tree op, struct mem_address *addr)
680 addr->symbol = TMR_SYMBOL (op);
681 addr->base = TMR_BASE (op);
682 addr->index = TMR_INDEX (op);
683 addr->step = TMR_STEP (op);
684 addr->offset = TMR_OFFSET (op);
687 /* Copies the additional information attached to target_mem_ref FROM to TO. */
689 void
690 copy_mem_ref_info (tree to, tree from)
692 /* Copy the annotation, to preserve the aliasing information. */
693 TMR_TAG (to) = TMR_TAG (from);
695 /* And the info about the original reference. */
696 TMR_ORIGINAL (to) = TMR_ORIGINAL (from);
699 /* Move constants in target_mem_ref REF to offset. Returns the new target
700 mem ref if anything changes, NULL_TREE otherwise. */
702 tree
703 maybe_fold_tmr (tree ref)
705 struct mem_address addr;
706 bool changed = false;
707 tree ret, off;
709 get_address_description (ref, &addr);
711 if (addr.base && TREE_CODE (addr.base) == INTEGER_CST)
713 if (addr.offset)
714 addr.offset = fold_binary_to_constant (PLUS_EXPR, sizetype,
715 addr.offset,
716 fold_convert (sizetype, addr.base));
717 else
718 addr.offset = addr.base;
720 addr.base = NULL_TREE;
721 changed = true;
724 if (addr.index && TREE_CODE (addr.index) == INTEGER_CST)
726 off = addr.index;
727 if (addr.step)
729 off = fold_binary_to_constant (MULT_EXPR, sizetype,
730 off, addr.step);
731 addr.step = NULL_TREE;
734 if (addr.offset)
736 addr.offset = fold_binary_to_constant (PLUS_EXPR, sizetype,
737 addr.offset, off);
739 else
740 addr.offset = off;
742 addr.index = NULL_TREE;
743 changed = true;
746 if (!changed)
747 return NULL_TREE;
749 ret = create_mem_ref_raw (TREE_TYPE (ref), &addr);
750 if (!ret)
751 return NULL_TREE;
753 copy_mem_ref_info (ret, ref);
754 return ret;
757 /* Dump PARTS to FILE. */
759 extern void dump_mem_address (FILE *, struct mem_address *);
760 void
761 dump_mem_address (FILE *file, struct mem_address *parts)
763 if (parts->symbol)
765 fprintf (file, "symbol: ");
766 print_generic_expr (file, parts->symbol, TDF_SLIM);
767 fprintf (file, "\n");
769 if (parts->base)
771 fprintf (file, "base: ");
772 print_generic_expr (file, parts->base, TDF_SLIM);
773 fprintf (file, "\n");
775 if (parts->index)
777 fprintf (file, "index: ");
778 print_generic_expr (file, parts->index, TDF_SLIM);
779 fprintf (file, "\n");
781 if (parts->step)
783 fprintf (file, "step: ");
784 print_generic_expr (file, parts->step, TDF_SLIM);
785 fprintf (file, "\n");
787 if (parts->offset)
789 fprintf (file, "offset: ");
790 print_generic_expr (file, parts->offset, TDF_SLIM);
791 fprintf (file, "\n");
795 #include "gt-tree-ssa-address.h"