1 /* Memory address lowering and addressing mode selection.
2 Copyright (C) 2004, 2006, 2007, 2008, 2009, 2010
3 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3, or (at your option) any
12 GCC is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 /* Utility functions for manipulation with TARGET_MEM_REFs -- tree expressions
22 that directly map to addressing modes of the target. */
26 #include "coretypes.h"
31 #include "hard-reg-set.h"
32 #include "basic-block.h"
34 #include "diagnostic.h"
35 #include "tree-flow.h"
36 #include "tree-dump.h"
37 #include "tree-pass.h"
40 #include "tree-inline.h"
41 #include "insn-config.h"
45 #include "tree-affine.h"
48 /* TODO -- handling of symbols (according to Richard Hendersons
49 comments, http://gcc.gnu.org/ml/gcc-patches/2005-04/msg00949.html):
51 There are at least 5 different kinds of symbols that we can run up against:
53 (1) binds_local_p, small data area.
54 (2) binds_local_p, eg local statics
55 (3) !binds_local_p, eg global variables
56 (4) thread local, local_exec
57 (5) thread local, !local_exec
59 Now, (1) won't appear often in an array context, but it certainly can.
60 All you have to do is set -GN high enough, or explicitly mark any
61 random object __attribute__((section (".sdata"))).
63 All of these affect whether or not a symbol is in fact a valid address.
64 The only one tested here is (3). And that result may very well
65 be incorrect for (4) or (5).
67 An incorrect result here does not cause incorrect results out the
68 back end, because the expander in expr.c validizes the address. However
69 it would be nice to improve the handling here in order to produce more
72 /* A "template" for memory address, used to determine whether the address is
75 typedef struct GTY (()) mem_addr_template
{
76 rtx ref
; /* The template. */
77 rtx
* GTY ((skip
)) step_p
; /* The point in template where the step should be
79 rtx
* GTY ((skip
)) off_p
; /* The point in template where the offset should
83 DEF_VEC_O (mem_addr_template
);
84 DEF_VEC_ALLOC_O (mem_addr_template
, gc
);
86 /* The templates. Each of the low five bits of the index corresponds to one
87 component of TARGET_MEM_REF being present, while the high bits identify
88 the address space. See TEMPL_IDX. */
90 static GTY(()) VEC (mem_addr_template
, gc
) *mem_addr_template_list
;
92 #define TEMPL_IDX(AS, SYMBOL, BASE, INDEX, STEP, OFFSET) \
94 | ((SYMBOL != 0) << 4) \
95 | ((BASE != 0) << 3) \
96 | ((INDEX != 0) << 2) \
97 | ((STEP != 0) << 1) \
100 /* Stores address for memory reference with parameters SYMBOL, BASE, INDEX,
101 STEP and OFFSET to *ADDR using address mode ADDRESS_MODE. Stores pointers
102 to where step is placed to *STEP_P and offset to *OFFSET_P. */
105 gen_addr_rtx (enum machine_mode address_mode
,
106 rtx symbol
, rtx base
, rtx index
, rtx step
, rtx offset
,
107 rtx
*addr
, rtx
**step_p
, rtx
**offset_p
)
122 act_elem
= gen_rtx_MULT (address_mode
, act_elem
, step
);
125 *step_p
= &XEXP (act_elem
, 1);
134 *addr
= simplify_gen_binary (PLUS
, address_mode
, base
, *addr
);
144 act_elem
= gen_rtx_PLUS (address_mode
, act_elem
, offset
);
147 *offset_p
= &XEXP (act_elem
, 1);
149 if (GET_CODE (symbol
) == SYMBOL_REF
150 || GET_CODE (symbol
) == LABEL_REF
151 || GET_CODE (symbol
) == CONST
)
152 act_elem
= gen_rtx_CONST (address_mode
, act_elem
);
156 *addr
= gen_rtx_PLUS (address_mode
, *addr
, act_elem
);
164 *addr
= gen_rtx_PLUS (address_mode
, *addr
, offset
);
166 *offset_p
= &XEXP (*addr
, 1);
180 /* Returns address for TARGET_MEM_REF with parameters given by ADDR
182 If REALLY_EXPAND is false, just make fake registers instead
183 of really expanding the operands, and perform the expansion in-place
184 by using one of the "templates". */
187 addr_for_mem_ref (struct mem_address
*addr
, addr_space_t as
,
190 enum machine_mode address_mode
= targetm
.addr_space
.address_mode (as
);
191 rtx address
, sym
, bse
, idx
, st
, off
;
192 struct mem_addr_template
*templ
;
194 if (addr
->step
&& !integer_onep (addr
->step
))
195 st
= immed_double_int_const (tree_to_double_int (addr
->step
), address_mode
);
199 if (addr
->offset
&& !integer_zerop (addr
->offset
))
200 off
= immed_double_int_const (tree_to_double_int (addr
->offset
), address_mode
);
206 unsigned int templ_index
207 = TEMPL_IDX (as
, addr
->symbol
, addr
->base
, addr
->index
, st
, off
);
210 >= VEC_length (mem_addr_template
, mem_addr_template_list
))
211 VEC_safe_grow_cleared (mem_addr_template
, gc
, mem_addr_template_list
,
214 /* Reuse the templates for addresses, so that we do not waste memory. */
215 templ
= VEC_index (mem_addr_template
, mem_addr_template_list
, templ_index
);
218 sym
= (addr
->symbol
?
219 gen_rtx_SYMBOL_REF (address_mode
, ggc_strdup ("test_symbol"))
222 gen_raw_REG (address_mode
, LAST_VIRTUAL_REGISTER
+ 1)
225 gen_raw_REG (address_mode
, LAST_VIRTUAL_REGISTER
+ 2)
228 gen_addr_rtx (address_mode
, sym
, bse
, idx
,
229 st
? const0_rtx
: NULL_RTX
,
230 off
? const0_rtx
: NULL_RTX
,
244 /* Otherwise really expand the expressions. */
246 ? expand_expr (build_addr (addr
->symbol
, current_function_decl
),
247 NULL_RTX
, address_mode
, EXPAND_NORMAL
)
250 ? expand_expr (addr
->base
, NULL_RTX
, address_mode
, EXPAND_NORMAL
)
253 ? expand_expr (addr
->index
, NULL_RTX
, address_mode
, EXPAND_NORMAL
)
256 gen_addr_rtx (address_mode
, sym
, bse
, idx
, st
, off
, &address
, NULL
, NULL
);
260 /* Returns address of MEM_REF in TYPE. */
263 tree_mem_ref_addr (tree type
, tree mem_ref
)
267 tree step
= TMR_STEP (mem_ref
), offset
= TMR_OFFSET (mem_ref
);
268 tree sym
= TMR_SYMBOL (mem_ref
), base
= TMR_BASE (mem_ref
);
269 tree addr_base
= NULL_TREE
, addr_off
= NULL_TREE
;
272 addr_base
= fold_convert (type
, build_addr (sym
, current_function_decl
));
273 else if (base
&& POINTER_TYPE_P (TREE_TYPE (base
)))
275 addr_base
= fold_convert (type
, base
);
279 act_elem
= TMR_INDEX (mem_ref
);
283 act_elem
= fold_build2 (MULT_EXPR
, sizetype
, act_elem
, step
);
291 addr_off
= fold_build2 (PLUS_EXPR
, sizetype
, addr_off
, act_elem
);
296 if (offset
&& !integer_zerop (offset
))
299 addr_off
= fold_build2 (PLUS_EXPR
, sizetype
, addr_off
, offset
);
307 addr
= fold_build2 (POINTER_PLUS_EXPR
, type
, addr_base
, addr_off
);
309 addr
= fold_convert (type
, addr_off
);
314 addr
= build_int_cst (type
, 0);
319 /* Returns true if a memory reference in MODE and with parameters given by
320 ADDR is valid on the current target. */
323 valid_mem_ref_p (enum machine_mode mode
, addr_space_t as
,
324 struct mem_address
*addr
)
328 address
= addr_for_mem_ref (addr
, as
, false);
332 return memory_address_addr_space_p (mode
, address
, as
);
335 /* Checks whether a TARGET_MEM_REF with type TYPE and parameters given by ADDR
336 is valid on the current target and if so, creates and returns the
340 create_mem_ref_raw (tree type
, struct mem_address
*addr
)
342 if (!valid_mem_ref_p (TYPE_MODE (type
), TYPE_ADDR_SPACE (type
), addr
))
345 if (addr
->step
&& integer_onep (addr
->step
))
346 addr
->step
= NULL_TREE
;
348 if (addr
->offset
&& integer_zerop (addr
->offset
))
349 addr
->offset
= NULL_TREE
;
351 return build6 (TARGET_MEM_REF
, type
,
352 addr
->symbol
, addr
->base
, addr
->index
,
353 addr
->step
, addr
->offset
, NULL
);
356 /* Returns true if OBJ is an object whose address is a link time constant. */
359 fixed_address_object_p (tree obj
)
361 return (TREE_CODE (obj
) == VAR_DECL
362 && (TREE_STATIC (obj
)
363 || DECL_EXTERNAL (obj
))
364 && ! DECL_DLLIMPORT_P (obj
));
367 /* If ADDR contains an address of object that is a link time constant,
368 move it to PARTS->symbol. */
371 move_fixed_address_to_symbol (struct mem_address
*parts
, aff_tree
*addr
)
374 tree val
= NULL_TREE
;
376 for (i
= 0; i
< addr
->n
; i
++)
378 if (!double_int_one_p (addr
->elts
[i
].coef
))
381 val
= addr
->elts
[i
].val
;
382 if (TREE_CODE (val
) == ADDR_EXPR
383 && fixed_address_object_p (TREE_OPERAND (val
, 0)))
390 parts
->symbol
= TREE_OPERAND (val
, 0);
391 aff_combination_remove_elt (addr
, i
);
394 /* If ADDR contains an instance of BASE_HINT, move it to PARTS->base. */
397 move_hint_to_base (tree type
, struct mem_address
*parts
, tree base_hint
,
401 tree val
= NULL_TREE
;
404 for (i
= 0; i
< addr
->n
; i
++)
406 if (!double_int_one_p (addr
->elts
[i
].coef
))
409 val
= addr
->elts
[i
].val
;
410 if (operand_equal_p (val
, base_hint
, 0))
417 /* Cast value to appropriate pointer type. We cannot use a pointer
418 to TYPE directly, as the back-end will assume registers of pointer
419 type are aligned, and just the base itself may not actually be.
420 We use void pointer to the type's address space instead. */
421 qual
= ENCODE_QUAL_ADDR_SPACE (TYPE_ADDR_SPACE (type
));
422 type
= build_qualified_type (void_type_node
, qual
);
423 parts
->base
= fold_convert (build_pointer_type (type
), val
);
424 aff_combination_remove_elt (addr
, i
);
427 /* If ADDR contains an address of a dereferenced pointer, move it to
431 move_pointer_to_base (struct mem_address
*parts
, aff_tree
*addr
)
434 tree val
= NULL_TREE
;
436 for (i
= 0; i
< addr
->n
; i
++)
438 if (!double_int_one_p (addr
->elts
[i
].coef
))
441 val
= addr
->elts
[i
].val
;
442 if (POINTER_TYPE_P (TREE_TYPE (val
)))
450 aff_combination_remove_elt (addr
, i
);
453 /* Adds ELT to PARTS. */
456 add_to_parts (struct mem_address
*parts
, tree elt
)
462 parts
->index
= fold_convert (sizetype
, elt
);
472 /* Add ELT to base. */
473 type
= TREE_TYPE (parts
->base
);
474 if (POINTER_TYPE_P (type
))
475 parts
->base
= fold_build2 (POINTER_PLUS_EXPR
, type
,
477 fold_convert (sizetype
, elt
));
479 parts
->base
= fold_build2 (PLUS_EXPR
, type
,
483 /* Finds the most expensive multiplication in ADDR that can be
484 expressed in an addressing mode and move the corresponding
485 element(s) to PARTS. */
488 most_expensive_mult_to_index (tree type
, struct mem_address
*parts
,
489 aff_tree
*addr
, bool speed
)
491 addr_space_t as
= TYPE_ADDR_SPACE (type
);
492 enum machine_mode address_mode
= targetm
.addr_space
.address_mode (as
);
494 double_int best_mult
, amult
, amult_neg
;
495 unsigned best_mult_cost
= 0, acost
;
496 tree mult_elt
= NULL_TREE
, elt
;
498 enum tree_code op_code
;
500 best_mult
= double_int_zero
;
501 for (i
= 0; i
< addr
->n
; i
++)
503 if (!double_int_fits_in_shwi_p (addr
->elts
[i
].coef
))
506 coef
= double_int_to_shwi (addr
->elts
[i
].coef
);
508 || !multiplier_allowed_in_address_p (coef
, TYPE_MODE (type
), as
))
511 acost
= multiply_by_cost (coef
, address_mode
, speed
);
513 if (acost
> best_mult_cost
)
515 best_mult_cost
= acost
;
516 best_mult
= addr
->elts
[i
].coef
;
523 /* Collect elements multiplied by best_mult. */
524 for (i
= j
= 0; i
< addr
->n
; i
++)
526 amult
= addr
->elts
[i
].coef
;
527 amult_neg
= double_int_ext_for_comb (double_int_neg (amult
), addr
);
529 if (double_int_equal_p (amult
, best_mult
))
531 else if (double_int_equal_p (amult_neg
, best_mult
))
532 op_code
= MINUS_EXPR
;
535 addr
->elts
[j
] = addr
->elts
[i
];
540 elt
= fold_convert (sizetype
, addr
->elts
[i
].val
);
542 mult_elt
= fold_build2 (op_code
, sizetype
, mult_elt
, elt
);
543 else if (op_code
== PLUS_EXPR
)
546 mult_elt
= fold_build1 (NEGATE_EXPR
, sizetype
, elt
);
550 parts
->index
= mult_elt
;
551 parts
->step
= double_int_to_tree (sizetype
, best_mult
);
554 /* Splits address ADDR for a memory access of type TYPE into PARTS.
555 If BASE_HINT is non-NULL, it specifies an SSA name to be used
556 preferentially as base of the reference.
558 TODO -- be more clever about the distribution of the elements of ADDR
559 to PARTS. Some architectures do not support anything but single
560 register in address, possibly with a small integer offset; while
561 create_mem_ref will simplify the address to an acceptable shape
562 later, it would be more efficient to know that asking for complicated
563 addressing modes is useless. */
566 addr_to_parts (tree type
, aff_tree
*addr
, tree base_hint
,
567 struct mem_address
*parts
, bool speed
)
572 parts
->symbol
= NULL_TREE
;
573 parts
->base
= NULL_TREE
;
574 parts
->index
= NULL_TREE
;
575 parts
->step
= NULL_TREE
;
577 if (!double_int_zero_p (addr
->offset
))
578 parts
->offset
= double_int_to_tree (sizetype
, addr
->offset
);
580 parts
->offset
= NULL_TREE
;
582 /* Try to find a symbol. */
583 move_fixed_address_to_symbol (parts
, addr
);
585 /* First move the most expensive feasible multiplication
587 most_expensive_mult_to_index (type
, parts
, addr
, speed
);
589 /* Try to find a base of the reference. Since at the moment
590 there is no reliable way how to distinguish between pointer and its
591 offset, this is just a guess. */
592 if (!parts
->symbol
&& base_hint
)
593 move_hint_to_base (type
, parts
, base_hint
, addr
);
594 if (!parts
->symbol
&& !parts
->base
)
595 move_pointer_to_base (parts
, addr
);
597 /* Then try to process the remaining elements. */
598 for (i
= 0; i
< addr
->n
; i
++)
600 part
= fold_convert (sizetype
, addr
->elts
[i
].val
);
601 if (!double_int_one_p (addr
->elts
[i
].coef
))
602 part
= fold_build2 (MULT_EXPR
, sizetype
, part
,
603 double_int_to_tree (sizetype
, addr
->elts
[i
].coef
));
604 add_to_parts (parts
, part
);
607 add_to_parts (parts
, fold_convert (sizetype
, addr
->rest
));
610 /* Force the PARTS to register. */
613 gimplify_mem_ref_parts (gimple_stmt_iterator
*gsi
, struct mem_address
*parts
)
616 parts
->base
= force_gimple_operand_gsi (gsi
, parts
->base
,
618 true, GSI_SAME_STMT
);
620 parts
->index
= force_gimple_operand_gsi (gsi
, parts
->index
,
622 true, GSI_SAME_STMT
);
625 /* Creates and returns a TARGET_MEM_REF for address ADDR. If necessary
626 computations are emitted in front of GSI. TYPE is the mode
627 of created memory reference. */
630 create_mem_ref (gimple_stmt_iterator
*gsi
, tree type
, aff_tree
*addr
,
631 tree base_hint
, bool speed
)
635 struct mem_address parts
;
637 addr_to_parts (type
, addr
, base_hint
, &parts
, speed
);
638 gimplify_mem_ref_parts (gsi
, &parts
);
639 mem_ref
= create_mem_ref_raw (type
, &parts
);
643 /* The expression is too complicated. Try making it simpler. */
645 if (parts
.step
&& !integer_onep (parts
.step
))
647 /* Move the multiplication to index. */
648 gcc_assert (parts
.index
);
649 parts
.index
= force_gimple_operand_gsi (gsi
,
650 fold_build2 (MULT_EXPR
, sizetype
,
651 parts
.index
, parts
.step
),
652 true, NULL_TREE
, true, GSI_SAME_STMT
);
653 parts
.step
= NULL_TREE
;
655 mem_ref
= create_mem_ref_raw (type
, &parts
);
662 tmp
= build_addr (parts
.symbol
, current_function_decl
);
663 gcc_assert (is_gimple_val (tmp
));
665 /* Add the symbol to base, eventually forcing it to register. */
668 gcc_assert (useless_type_conversion_p
669 (sizetype
, TREE_TYPE (parts
.base
)));
673 atype
= TREE_TYPE (tmp
);
674 parts
.base
= force_gimple_operand_gsi (gsi
,
675 fold_build2 (POINTER_PLUS_EXPR
, atype
,
677 fold_convert (sizetype
, parts
.base
)),
678 true, NULL_TREE
, true, GSI_SAME_STMT
);
682 parts
.index
= parts
.base
;
688 parts
.symbol
= NULL_TREE
;
690 mem_ref
= create_mem_ref_raw (type
, &parts
);
697 /* Add index to base. */
700 atype
= TREE_TYPE (parts
.base
);
701 parts
.base
= force_gimple_operand_gsi (gsi
,
702 fold_build2 (POINTER_PLUS_EXPR
, atype
,
705 true, NULL_TREE
, true, GSI_SAME_STMT
);
708 parts
.base
= parts
.index
;
709 parts
.index
= NULL_TREE
;
711 mem_ref
= create_mem_ref_raw (type
, &parts
);
716 if (parts
.offset
&& !integer_zerop (parts
.offset
))
718 /* Try adding offset to base. */
721 atype
= TREE_TYPE (parts
.base
);
722 parts
.base
= force_gimple_operand_gsi (gsi
,
723 fold_build2 (POINTER_PLUS_EXPR
, atype
,
725 fold_convert (sizetype
, parts
.offset
)),
726 true, NULL_TREE
, true, GSI_SAME_STMT
);
729 parts
.base
= parts
.offset
;
731 parts
.offset
= NULL_TREE
;
733 mem_ref
= create_mem_ref_raw (type
, &parts
);
738 /* Verify that the address is in the simplest possible shape
739 (only a register). If we cannot create such a memory reference,
740 something is really wrong. */
741 gcc_assert (parts
.symbol
== NULL_TREE
);
742 gcc_assert (parts
.index
== NULL_TREE
);
743 gcc_assert (!parts
.step
|| integer_onep (parts
.step
));
744 gcc_assert (!parts
.offset
|| integer_zerop (parts
.offset
));
748 /* Copies components of the address from OP to ADDR. */
751 get_address_description (tree op
, struct mem_address
*addr
)
753 addr
->symbol
= TMR_SYMBOL (op
);
754 addr
->base
= TMR_BASE (op
);
755 addr
->index
= TMR_INDEX (op
);
756 addr
->step
= TMR_STEP (op
);
757 addr
->offset
= TMR_OFFSET (op
);
760 /* Copies the additional information attached to target_mem_ref FROM to TO. */
763 copy_mem_ref_info (tree to
, tree from
)
765 /* And the info about the original reference. */
766 TMR_ORIGINAL (to
) = TMR_ORIGINAL (from
);
767 TREE_SIDE_EFFECTS (to
) = TREE_SIDE_EFFECTS (from
);
768 TREE_THIS_VOLATILE (to
) = TREE_THIS_VOLATILE (from
);
771 /* Move constants in target_mem_ref REF to offset. Returns the new target
772 mem ref if anything changes, NULL_TREE otherwise. */
775 maybe_fold_tmr (tree ref
)
777 struct mem_address addr
;
778 bool changed
= false;
781 get_address_description (ref
, &addr
);
783 if (addr
.base
&& TREE_CODE (addr
.base
) == INTEGER_CST
)
786 addr
.offset
= fold_binary_to_constant (PLUS_EXPR
, sizetype
,
788 fold_convert (sizetype
, addr
.base
));
790 addr
.offset
= addr
.base
;
792 addr
.base
= NULL_TREE
;
796 if (addr
.index
&& TREE_CODE (addr
.index
) == INTEGER_CST
)
801 off
= fold_binary_to_constant (MULT_EXPR
, sizetype
,
803 addr
.step
= NULL_TREE
;
808 addr
.offset
= fold_binary_to_constant (PLUS_EXPR
, sizetype
,
814 addr
.index
= NULL_TREE
;
821 ret
= create_mem_ref_raw (TREE_TYPE (ref
), &addr
);
825 copy_mem_ref_info (ret
, ref
);
829 /* Dump PARTS to FILE. */
831 extern void dump_mem_address (FILE *, struct mem_address
*);
833 dump_mem_address (FILE *file
, struct mem_address
*parts
)
837 fprintf (file
, "symbol: ");
838 print_generic_expr (file
, parts
->symbol
, TDF_SLIM
);
839 fprintf (file
, "\n");
843 fprintf (file
, "base: ");
844 print_generic_expr (file
, parts
->base
, TDF_SLIM
);
845 fprintf (file
, "\n");
849 fprintf (file
, "index: ");
850 print_generic_expr (file
, parts
->index
, TDF_SLIM
);
851 fprintf (file
, "\n");
855 fprintf (file
, "step: ");
856 print_generic_expr (file
, parts
->step
, TDF_SLIM
);
857 fprintf (file
, "\n");
861 fprintf (file
, "offset: ");
862 print_generic_expr (file
, parts
->offset
, TDF_SLIM
);
863 fprintf (file
, "\n");
867 #include "gt-tree-ssa-address.h"