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"
30 #include "basic-block.h"
32 #include "diagnostic.h"
33 #include "tree-pretty-print.h"
34 #include "tree-flow.h"
35 #include "tree-dump.h"
36 #include "tree-pass.h"
39 #include "tree-inline.h"
40 #include "tree-affine.h"
42 /* FIXME: We compute address costs using RTL. */
43 #include "insn-config.h"
50 /* TODO -- handling of symbols (according to Richard Hendersons
51 comments, http://gcc.gnu.org/ml/gcc-patches/2005-04/msg00949.html):
53 There are at least 5 different kinds of symbols that we can run up against:
55 (1) binds_local_p, small data area.
56 (2) binds_local_p, eg local statics
57 (3) !binds_local_p, eg global variables
58 (4) thread local, local_exec
59 (5) thread local, !local_exec
61 Now, (1) won't appear often in an array context, but it certainly can.
62 All you have to do is set -GN high enough, or explicitly mark any
63 random object __attribute__((section (".sdata"))).
65 All of these affect whether or not a symbol is in fact a valid address.
66 The only one tested here is (3). And that result may very well
67 be incorrect for (4) or (5).
69 An incorrect result here does not cause incorrect results out the
70 back end, because the expander in expr.c validizes the address. However
71 it would be nice to improve the handling here in order to produce more
74 /* A "template" for memory address, used to determine whether the address is
77 typedef struct GTY (()) mem_addr_template
{
78 rtx ref
; /* The template. */
79 rtx
* GTY ((skip
)) step_p
; /* The point in template where the step should be
81 rtx
* GTY ((skip
)) off_p
; /* The point in template where the offset should
85 DEF_VEC_O (mem_addr_template
);
86 DEF_VEC_ALLOC_O (mem_addr_template
, gc
);
88 /* The templates. Each of the low five bits of the index corresponds to one
89 component of TARGET_MEM_REF being present, while the high bits identify
90 the address space. See TEMPL_IDX. */
92 static GTY(()) VEC (mem_addr_template
, gc
) *mem_addr_template_list
;
94 #define TEMPL_IDX(AS, SYMBOL, BASE, INDEX, STEP, OFFSET) \
96 | ((SYMBOL != 0) << 4) \
97 | ((BASE != 0) << 3) \
98 | ((INDEX != 0) << 2) \
99 | ((STEP != 0) << 1) \
102 /* Stores address for memory reference with parameters SYMBOL, BASE, INDEX,
103 STEP and OFFSET to *ADDR using address mode ADDRESS_MODE. Stores pointers
104 to where step is placed to *STEP_P and offset to *OFFSET_P. */
107 gen_addr_rtx (enum machine_mode address_mode
,
108 rtx symbol
, rtx base
, rtx index
, rtx step
, rtx offset
,
109 rtx
*addr
, rtx
**step_p
, rtx
**offset_p
)
124 act_elem
= gen_rtx_MULT (address_mode
, act_elem
, step
);
127 *step_p
= &XEXP (act_elem
, 1);
136 *addr
= simplify_gen_binary (PLUS
, address_mode
, base
, *addr
);
146 act_elem
= gen_rtx_PLUS (address_mode
, act_elem
, offset
);
149 *offset_p
= &XEXP (act_elem
, 1);
151 if (GET_CODE (symbol
) == SYMBOL_REF
152 || GET_CODE (symbol
) == LABEL_REF
153 || GET_CODE (symbol
) == CONST
)
154 act_elem
= gen_rtx_CONST (address_mode
, act_elem
);
158 *addr
= gen_rtx_PLUS (address_mode
, *addr
, act_elem
);
166 *addr
= gen_rtx_PLUS (address_mode
, *addr
, offset
);
168 *offset_p
= &XEXP (*addr
, 1);
182 /* Returns address for TARGET_MEM_REF with parameters given by ADDR
184 If REALLY_EXPAND is false, just make fake registers instead
185 of really expanding the operands, and perform the expansion in-place
186 by using one of the "templates". */
189 addr_for_mem_ref (struct mem_address
*addr
, addr_space_t as
,
192 enum machine_mode address_mode
= targetm
.addr_space
.address_mode (as
);
193 rtx address
, sym
, bse
, idx
, st
, off
;
194 struct mem_addr_template
*templ
;
196 if (addr
->step
&& !integer_onep (addr
->step
))
197 st
= immed_double_int_const (tree_to_double_int (addr
->step
), address_mode
);
201 if (addr
->offset
&& !integer_zerop (addr
->offset
))
202 off
= immed_double_int_const (tree_to_double_int (addr
->offset
), address_mode
);
208 unsigned int templ_index
209 = TEMPL_IDX (as
, addr
->symbol
, addr
->base
, addr
->index
, st
, off
);
212 >= VEC_length (mem_addr_template
, mem_addr_template_list
))
213 VEC_safe_grow_cleared (mem_addr_template
, gc
, mem_addr_template_list
,
216 /* Reuse the templates for addresses, so that we do not waste memory. */
217 templ
= VEC_index (mem_addr_template
, mem_addr_template_list
, templ_index
);
220 sym
= (addr
->symbol
?
221 gen_rtx_SYMBOL_REF (address_mode
, ggc_strdup ("test_symbol"))
224 gen_raw_REG (address_mode
, LAST_VIRTUAL_REGISTER
+ 1)
227 gen_raw_REG (address_mode
, LAST_VIRTUAL_REGISTER
+ 2)
230 gen_addr_rtx (address_mode
, sym
, bse
, idx
,
231 st
? const0_rtx
: NULL_RTX
,
232 off
? const0_rtx
: NULL_RTX
,
246 /* Otherwise really expand the expressions. */
248 ? expand_expr (build_addr (addr
->symbol
, current_function_decl
),
249 NULL_RTX
, address_mode
, EXPAND_NORMAL
)
252 ? expand_expr (addr
->base
, NULL_RTX
, address_mode
, EXPAND_NORMAL
)
255 ? expand_expr (addr
->index
, NULL_RTX
, address_mode
, EXPAND_NORMAL
)
258 gen_addr_rtx (address_mode
, sym
, bse
, idx
, st
, off
, &address
, NULL
, NULL
);
262 /* Returns address of MEM_REF in TYPE. */
265 tree_mem_ref_addr (tree type
, tree mem_ref
)
269 tree step
= TMR_STEP (mem_ref
), offset
= TMR_OFFSET (mem_ref
);
270 tree sym
= TMR_SYMBOL (mem_ref
), base
= TMR_BASE (mem_ref
);
271 tree addr_base
= NULL_TREE
, addr_off
= NULL_TREE
;
274 addr_base
= fold_convert (type
, build_addr (sym
, current_function_decl
));
275 else if (base
&& POINTER_TYPE_P (TREE_TYPE (base
)))
277 addr_base
= fold_convert (type
, base
);
281 act_elem
= TMR_INDEX (mem_ref
);
285 act_elem
= fold_build2 (MULT_EXPR
, sizetype
, act_elem
, step
);
293 addr_off
= fold_build2 (PLUS_EXPR
, sizetype
, addr_off
, act_elem
);
298 if (offset
&& !integer_zerop (offset
))
301 addr_off
= fold_build2 (PLUS_EXPR
, sizetype
, addr_off
, offset
);
309 addr
= fold_build2 (POINTER_PLUS_EXPR
, type
, addr_base
, addr_off
);
311 addr
= fold_convert (type
, addr_off
);
316 addr
= build_int_cst (type
, 0);
321 /* Returns true if a memory reference in MODE and with parameters given by
322 ADDR is valid on the current target. */
325 valid_mem_ref_p (enum machine_mode mode
, addr_space_t as
,
326 struct mem_address
*addr
)
330 address
= addr_for_mem_ref (addr
, as
, false);
334 return memory_address_addr_space_p (mode
, address
, as
);
337 /* Checks whether a TARGET_MEM_REF with type TYPE and parameters given by ADDR
338 is valid on the current target and if so, creates and returns the
342 create_mem_ref_raw (tree type
, struct mem_address
*addr
)
344 if (!valid_mem_ref_p (TYPE_MODE (type
), TYPE_ADDR_SPACE (type
), addr
))
347 if (addr
->step
&& integer_onep (addr
->step
))
348 addr
->step
= NULL_TREE
;
350 if (addr
->offset
&& integer_zerop (addr
->offset
))
351 addr
->offset
= NULL_TREE
;
353 return build6 (TARGET_MEM_REF
, type
,
354 addr
->symbol
, addr
->base
, addr
->index
,
355 addr
->step
, addr
->offset
, NULL
);
358 /* Returns true if OBJ is an object whose address is a link time constant. */
361 fixed_address_object_p (tree obj
)
363 return (TREE_CODE (obj
) == VAR_DECL
364 && (TREE_STATIC (obj
)
365 || DECL_EXTERNAL (obj
))
366 && ! DECL_DLLIMPORT_P (obj
));
369 /* If ADDR contains an address of object that is a link time constant,
370 move it to PARTS->symbol. */
373 move_fixed_address_to_symbol (struct mem_address
*parts
, aff_tree
*addr
)
376 tree val
= NULL_TREE
;
378 for (i
= 0; i
< addr
->n
; i
++)
380 if (!double_int_one_p (addr
->elts
[i
].coef
))
383 val
= addr
->elts
[i
].val
;
384 if (TREE_CODE (val
) == ADDR_EXPR
385 && fixed_address_object_p (TREE_OPERAND (val
, 0)))
392 parts
->symbol
= TREE_OPERAND (val
, 0);
393 aff_combination_remove_elt (addr
, i
);
396 /* If ADDR contains an instance of BASE_HINT, move it to PARTS->base. */
399 move_hint_to_base (tree type
, struct mem_address
*parts
, tree base_hint
,
403 tree val
= NULL_TREE
;
406 for (i
= 0; i
< addr
->n
; i
++)
408 if (!double_int_one_p (addr
->elts
[i
].coef
))
411 val
= addr
->elts
[i
].val
;
412 if (operand_equal_p (val
, base_hint
, 0))
419 /* Cast value to appropriate pointer type. We cannot use a pointer
420 to TYPE directly, as the back-end will assume registers of pointer
421 type are aligned, and just the base itself may not actually be.
422 We use void pointer to the type's address space instead. */
423 qual
= ENCODE_QUAL_ADDR_SPACE (TYPE_ADDR_SPACE (type
));
424 type
= build_qualified_type (void_type_node
, qual
);
425 parts
->base
= fold_convert (build_pointer_type (type
), val
);
426 aff_combination_remove_elt (addr
, i
);
429 /* If ADDR contains an address of a dereferenced pointer, move it to
433 move_pointer_to_base (struct mem_address
*parts
, aff_tree
*addr
)
436 tree val
= NULL_TREE
;
438 for (i
= 0; i
< addr
->n
; i
++)
440 if (!double_int_one_p (addr
->elts
[i
].coef
))
443 val
= addr
->elts
[i
].val
;
444 if (POINTER_TYPE_P (TREE_TYPE (val
)))
452 aff_combination_remove_elt (addr
, i
);
455 /* Adds ELT to PARTS. */
458 add_to_parts (struct mem_address
*parts
, tree elt
)
464 parts
->index
= fold_convert (sizetype
, elt
);
474 /* Add ELT to base. */
475 type
= TREE_TYPE (parts
->base
);
476 if (POINTER_TYPE_P (type
))
477 parts
->base
= fold_build2 (POINTER_PLUS_EXPR
, type
,
479 fold_convert (sizetype
, elt
));
481 parts
->base
= fold_build2 (PLUS_EXPR
, type
,
485 /* Finds the most expensive multiplication in ADDR that can be
486 expressed in an addressing mode and move the corresponding
487 element(s) to PARTS. */
490 most_expensive_mult_to_index (tree type
, struct mem_address
*parts
,
491 aff_tree
*addr
, bool speed
)
493 addr_space_t as
= TYPE_ADDR_SPACE (type
);
494 enum machine_mode address_mode
= targetm
.addr_space
.address_mode (as
);
496 double_int best_mult
, amult
, amult_neg
;
497 unsigned best_mult_cost
= 0, acost
;
498 tree mult_elt
= NULL_TREE
, elt
;
500 enum tree_code op_code
;
502 best_mult
= double_int_zero
;
503 for (i
= 0; i
< addr
->n
; i
++)
505 if (!double_int_fits_in_shwi_p (addr
->elts
[i
].coef
))
508 coef
= double_int_to_shwi (addr
->elts
[i
].coef
);
510 || !multiplier_allowed_in_address_p (coef
, TYPE_MODE (type
), as
))
513 acost
= multiply_by_cost (coef
, address_mode
, speed
);
515 if (acost
> best_mult_cost
)
517 best_mult_cost
= acost
;
518 best_mult
= addr
->elts
[i
].coef
;
525 /* Collect elements multiplied by best_mult. */
526 for (i
= j
= 0; i
< addr
->n
; i
++)
528 amult
= addr
->elts
[i
].coef
;
529 amult_neg
= double_int_ext_for_comb (double_int_neg (amult
), addr
);
531 if (double_int_equal_p (amult
, best_mult
))
533 else if (double_int_equal_p (amult_neg
, best_mult
))
534 op_code
= MINUS_EXPR
;
537 addr
->elts
[j
] = addr
->elts
[i
];
542 elt
= fold_convert (sizetype
, addr
->elts
[i
].val
);
544 mult_elt
= fold_build2 (op_code
, sizetype
, mult_elt
, elt
);
545 else if (op_code
== PLUS_EXPR
)
548 mult_elt
= fold_build1 (NEGATE_EXPR
, sizetype
, elt
);
552 parts
->index
= mult_elt
;
553 parts
->step
= double_int_to_tree (sizetype
, best_mult
);
556 /* Splits address ADDR for a memory access of type TYPE into PARTS.
557 If BASE_HINT is non-NULL, it specifies an SSA name to be used
558 preferentially as base of the reference.
560 TODO -- be more clever about the distribution of the elements of ADDR
561 to PARTS. Some architectures do not support anything but single
562 register in address, possibly with a small integer offset; while
563 create_mem_ref will simplify the address to an acceptable shape
564 later, it would be more efficient to know that asking for complicated
565 addressing modes is useless. */
568 addr_to_parts (tree type
, aff_tree
*addr
, tree base_hint
,
569 struct mem_address
*parts
, bool speed
)
574 parts
->symbol
= NULL_TREE
;
575 parts
->base
= NULL_TREE
;
576 parts
->index
= NULL_TREE
;
577 parts
->step
= NULL_TREE
;
579 if (!double_int_zero_p (addr
->offset
))
580 parts
->offset
= double_int_to_tree (sizetype
, addr
->offset
);
582 parts
->offset
= NULL_TREE
;
584 /* Try to find a symbol. */
585 move_fixed_address_to_symbol (parts
, addr
);
587 /* First move the most expensive feasible multiplication
589 most_expensive_mult_to_index (type
, parts
, addr
, speed
);
591 /* Try to find a base of the reference. Since at the moment
592 there is no reliable way how to distinguish between pointer and its
593 offset, this is just a guess. */
594 if (!parts
->symbol
&& base_hint
)
595 move_hint_to_base (type
, parts
, base_hint
, addr
);
596 if (!parts
->symbol
&& !parts
->base
)
597 move_pointer_to_base (parts
, addr
);
599 /* Then try to process the remaining elements. */
600 for (i
= 0; i
< addr
->n
; i
++)
602 part
= fold_convert (sizetype
, addr
->elts
[i
].val
);
603 if (!double_int_one_p (addr
->elts
[i
].coef
))
604 part
= fold_build2 (MULT_EXPR
, sizetype
, part
,
605 double_int_to_tree (sizetype
, addr
->elts
[i
].coef
));
606 add_to_parts (parts
, part
);
609 add_to_parts (parts
, fold_convert (sizetype
, addr
->rest
));
612 /* Force the PARTS to register. */
615 gimplify_mem_ref_parts (gimple_stmt_iterator
*gsi
, struct mem_address
*parts
)
618 parts
->base
= force_gimple_operand_gsi (gsi
, parts
->base
,
620 true, GSI_SAME_STMT
);
622 parts
->index
= force_gimple_operand_gsi (gsi
, parts
->index
,
624 true, GSI_SAME_STMT
);
627 /* Creates and returns a TARGET_MEM_REF for address ADDR. If necessary
628 computations are emitted in front of GSI. TYPE is the mode
629 of created memory reference. */
632 create_mem_ref (gimple_stmt_iterator
*gsi
, tree type
, aff_tree
*addr
,
633 tree base_hint
, bool speed
)
637 struct mem_address parts
;
639 addr_to_parts (type
, addr
, base_hint
, &parts
, speed
);
640 gimplify_mem_ref_parts (gsi
, &parts
);
641 mem_ref
= create_mem_ref_raw (type
, &parts
);
645 /* The expression is too complicated. Try making it simpler. */
647 if (parts
.step
&& !integer_onep (parts
.step
))
649 /* Move the multiplication to index. */
650 gcc_assert (parts
.index
);
651 parts
.index
= force_gimple_operand_gsi (gsi
,
652 fold_build2 (MULT_EXPR
, sizetype
,
653 parts
.index
, parts
.step
),
654 true, NULL_TREE
, true, GSI_SAME_STMT
);
655 parts
.step
= NULL_TREE
;
657 mem_ref
= create_mem_ref_raw (type
, &parts
);
664 tmp
= build_addr (parts
.symbol
, current_function_decl
);
665 gcc_assert (is_gimple_val (tmp
));
667 /* Add the symbol to base, eventually forcing it to register. */
670 gcc_assert (useless_type_conversion_p
671 (sizetype
, TREE_TYPE (parts
.base
)));
675 atype
= TREE_TYPE (tmp
);
676 parts
.base
= force_gimple_operand_gsi (gsi
,
677 fold_build2 (POINTER_PLUS_EXPR
, atype
,
679 fold_convert (sizetype
, parts
.base
)),
680 true, NULL_TREE
, true, GSI_SAME_STMT
);
684 parts
.index
= parts
.base
;
690 parts
.symbol
= NULL_TREE
;
692 mem_ref
= create_mem_ref_raw (type
, &parts
);
699 /* Add index to base. */
702 atype
= TREE_TYPE (parts
.base
);
703 parts
.base
= force_gimple_operand_gsi (gsi
,
704 fold_build2 (POINTER_PLUS_EXPR
, atype
,
707 true, NULL_TREE
, true, GSI_SAME_STMT
);
710 parts
.base
= parts
.index
;
711 parts
.index
= NULL_TREE
;
713 mem_ref
= create_mem_ref_raw (type
, &parts
);
718 if (parts
.offset
&& !integer_zerop (parts
.offset
))
720 /* Try adding offset to base. */
723 atype
= TREE_TYPE (parts
.base
);
724 parts
.base
= force_gimple_operand_gsi (gsi
,
725 fold_build2 (POINTER_PLUS_EXPR
, atype
,
727 fold_convert (sizetype
, parts
.offset
)),
728 true, NULL_TREE
, true, GSI_SAME_STMT
);
731 parts
.base
= parts
.offset
;
733 parts
.offset
= NULL_TREE
;
735 mem_ref
= create_mem_ref_raw (type
, &parts
);
740 /* Verify that the address is in the simplest possible shape
741 (only a register). If we cannot create such a memory reference,
742 something is really wrong. */
743 gcc_assert (parts
.symbol
== NULL_TREE
);
744 gcc_assert (parts
.index
== NULL_TREE
);
745 gcc_assert (!parts
.step
|| integer_onep (parts
.step
));
746 gcc_assert (!parts
.offset
|| integer_zerop (parts
.offset
));
750 /* Copies components of the address from OP to ADDR. */
753 get_address_description (tree op
, struct mem_address
*addr
)
755 addr
->symbol
= TMR_SYMBOL (op
);
756 addr
->base
= TMR_BASE (op
);
757 addr
->index
= TMR_INDEX (op
);
758 addr
->step
= TMR_STEP (op
);
759 addr
->offset
= TMR_OFFSET (op
);
762 /* Copies the additional information attached to target_mem_ref FROM to TO. */
765 copy_mem_ref_info (tree to
, tree from
)
767 /* And the info about the original reference. */
768 TMR_ORIGINAL (to
) = TMR_ORIGINAL (from
);
769 TREE_SIDE_EFFECTS (to
) = TREE_SIDE_EFFECTS (from
);
770 TREE_THIS_VOLATILE (to
) = TREE_THIS_VOLATILE (from
);
773 /* Move constants in target_mem_ref REF to offset. Returns the new target
774 mem ref if anything changes, NULL_TREE otherwise. */
777 maybe_fold_tmr (tree ref
)
779 struct mem_address addr
;
780 bool changed
= false;
783 get_address_description (ref
, &addr
);
785 if (addr
.base
&& TREE_CODE (addr
.base
) == INTEGER_CST
)
788 addr
.offset
= fold_binary_to_constant (PLUS_EXPR
, sizetype
,
790 fold_convert (sizetype
, addr
.base
));
792 addr
.offset
= addr
.base
;
794 addr
.base
= NULL_TREE
;
798 if (addr
.index
&& TREE_CODE (addr
.index
) == INTEGER_CST
)
803 off
= fold_binary_to_constant (MULT_EXPR
, sizetype
,
805 addr
.step
= NULL_TREE
;
810 addr
.offset
= fold_binary_to_constant (PLUS_EXPR
, sizetype
,
816 addr
.index
= NULL_TREE
;
823 ret
= create_mem_ref_raw (TREE_TYPE (ref
), &addr
);
827 copy_mem_ref_info (ret
, ref
);
831 /* Dump PARTS to FILE. */
833 extern void dump_mem_address (FILE *, struct mem_address
*);
835 dump_mem_address (FILE *file
, struct mem_address
*parts
)
839 fprintf (file
, "symbol: ");
840 print_generic_expr (file
, parts
->symbol
, TDF_SLIM
);
841 fprintf (file
, "\n");
845 fprintf (file
, "base: ");
846 print_generic_expr (file
, parts
->base
, TDF_SLIM
);
847 fprintf (file
, "\n");
851 fprintf (file
, "index: ");
852 print_generic_expr (file
, parts
->index
, TDF_SLIM
);
853 fprintf (file
, "\n");
857 fprintf (file
, "step: ");
858 print_generic_expr (file
, parts
->step
, TDF_SLIM
);
859 fprintf (file
, "\n");
863 fprintf (file
, "offset: ");
864 print_generic_expr (file
, parts
->offset
, TDF_SLIM
);
865 fprintf (file
, "\n");
869 #include "gt-tree-ssa-address.h"