1 /* Memory address lowering and addressing mode selection.
2 Copyright (C) 2004, 2006, 2007, 2008, 2009 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 3, or (at your option) any
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
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 /* Utility functions for manipulation with TARGET_MEM_REFs -- tree expressions
21 that directly map to addressing modes of the target. */
25 #include "coretypes.h"
30 #include "hard-reg-set.h"
31 #include "basic-block.h"
33 #include "diagnostic.h"
34 #include "tree-flow.h"
35 #include "tree-dump.h"
36 #include "tree-pass.h"
39 #include "tree-inline.h"
40 #include "insn-config.h"
44 #include "tree-affine.h"
46 /* TODO -- handling of symbols (according to Richard Hendersons
47 comments, http://gcc.gnu.org/ml/gcc-patches/2005-04/msg00949.html):
49 There are at least 5 different kinds of symbols that we can run up against:
51 (1) binds_local_p, small data area.
52 (2) binds_local_p, eg local statics
53 (3) !binds_local_p, eg global variables
54 (4) thread local, local_exec
55 (5) thread local, !local_exec
57 Now, (1) won't appear often in an array context, but it certainly can.
58 All you have to do is set -GN high enough, or explicitly mark any
59 random object __attribute__((section (".sdata"))).
61 All of these affect whether or not a symbol is in fact a valid address.
62 The only one tested here is (3). And that result may very well
63 be incorrect for (4) or (5).
65 An incorrect result here does not cause incorrect results out the
66 back end, because the expander in expr.c validizes the address. However
67 it would be nice to improve the handling here in order to produce more
70 /* A "template" for memory address, used to determine whether the address is
73 struct GTY (()) mem_addr_template
{
74 rtx ref
; /* The template. */
75 rtx
* GTY ((skip
)) step_p
; /* The point in template where the step should be
77 rtx
* GTY ((skip
)) off_p
; /* The point in template where the offset should
81 /* The templates. Each of the five bits of the index corresponds to one
82 component of TARGET_MEM_REF being present, see TEMPL_IDX. */
84 static GTY (()) struct mem_addr_template templates
[32];
86 #define TEMPL_IDX(SYMBOL, BASE, INDEX, STEP, OFFSET) \
87 (((SYMBOL != 0) << 4) \
88 | ((BASE != 0) << 3) \
89 | ((INDEX != 0) << 2) \
90 | ((STEP != 0) << 1) \
93 /* Stores address for memory reference with parameters SYMBOL, BASE, INDEX,
94 STEP and OFFSET to *ADDR. Stores pointers to where step is placed to
95 *STEP_P and offset to *OFFSET_P. */
98 gen_addr_rtx (rtx symbol
, rtx base
, rtx index
, rtx step
, rtx offset
,
99 rtx
*addr
, rtx
**step_p
, rtx
**offset_p
)
114 act_elem
= gen_rtx_MULT (Pmode
, act_elem
, step
);
117 *step_p
= &XEXP (act_elem
, 1);
126 *addr
= simplify_gen_binary (PLUS
, Pmode
, base
, *addr
);
136 act_elem
= gen_rtx_PLUS (Pmode
, act_elem
, offset
);
139 *offset_p
= &XEXP (act_elem
, 1);
141 if (GET_CODE (symbol
) == SYMBOL_REF
142 || GET_CODE (symbol
) == LABEL_REF
143 || GET_CODE (symbol
) == CONST
)
144 act_elem
= gen_rtx_CONST (Pmode
, act_elem
);
148 *addr
= gen_rtx_PLUS (Pmode
, *addr
, act_elem
);
156 *addr
= gen_rtx_PLUS (Pmode
, *addr
, offset
);
158 *offset_p
= &XEXP (*addr
, 1);
172 /* Returns address for TARGET_MEM_REF with parameters given by ADDR.
173 If REALLY_EXPAND is false, just make fake registers instead
174 of really expanding the operands, and perform the expansion in-place
175 by using one of the "templates". */
178 addr_for_mem_ref (struct mem_address
*addr
, bool really_expand
)
180 rtx address
, sym
, bse
, idx
, st
, off
;
181 static bool templates_initialized
= false;
182 struct mem_addr_template
*templ
;
184 if (addr
->step
&& !integer_onep (addr
->step
))
185 st
= immed_double_const (TREE_INT_CST_LOW (addr
->step
),
186 TREE_INT_CST_HIGH (addr
->step
), Pmode
);
190 if (addr
->offset
&& !integer_zerop (addr
->offset
))
191 off
= immed_double_const (TREE_INT_CST_LOW (addr
->offset
),
192 TREE_INT_CST_HIGH (addr
->offset
), Pmode
);
198 /* Reuse the templates for addresses, so that we do not waste memory. */
199 if (!templates_initialized
)
203 templates_initialized
= true;
204 sym
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup ("test_symbol"));
205 bse
= gen_raw_REG (Pmode
, LAST_VIRTUAL_REGISTER
+ 1);
206 idx
= gen_raw_REG (Pmode
, LAST_VIRTUAL_REGISTER
+ 2);
208 for (i
= 0; i
< 32; i
++)
209 gen_addr_rtx ((i
& 16 ? sym
: NULL_RTX
),
210 (i
& 8 ? bse
: NULL_RTX
),
211 (i
& 4 ? idx
: NULL_RTX
),
212 (i
& 2 ? const0_rtx
: NULL_RTX
),
213 (i
& 1 ? const0_rtx
: NULL_RTX
),
215 &templates
[i
].step_p
,
216 &templates
[i
].off_p
);
219 templ
= templates
+ TEMPL_IDX (addr
->symbol
, addr
->base
, addr
->index
,
229 /* Otherwise really expand the expressions. */
231 ? expand_expr (build_addr (addr
->symbol
, current_function_decl
),
232 NULL_RTX
, Pmode
, EXPAND_NORMAL
)
235 ? expand_expr (addr
->base
, NULL_RTX
, Pmode
, EXPAND_NORMAL
)
238 ? expand_expr (addr
->index
, NULL_RTX
, Pmode
, EXPAND_NORMAL
)
241 gen_addr_rtx (sym
, bse
, idx
, st
, off
, &address
, NULL
, NULL
);
245 /* Returns address of MEM_REF in TYPE. */
248 tree_mem_ref_addr (tree type
, tree mem_ref
)
252 tree step
= TMR_STEP (mem_ref
), offset
= TMR_OFFSET (mem_ref
);
253 tree sym
= TMR_SYMBOL (mem_ref
), base
= TMR_BASE (mem_ref
);
254 tree addr_base
= NULL_TREE
, addr_off
= NULL_TREE
;
257 addr_base
= fold_convert (type
, build_addr (sym
, current_function_decl
));
258 else if (base
&& POINTER_TYPE_P (TREE_TYPE (base
)))
260 addr_base
= fold_convert (type
, base
);
264 act_elem
= TMR_INDEX (mem_ref
);
268 act_elem
= fold_build2 (MULT_EXPR
, sizetype
, act_elem
, step
);
276 addr_off
= fold_build2 (PLUS_EXPR
, sizetype
, addr_off
, act_elem
);
281 if (offset
&& !integer_zerop (offset
))
284 addr_off
= fold_build2 (PLUS_EXPR
, sizetype
, addr_off
, offset
);
292 addr
= fold_build2 (POINTER_PLUS_EXPR
, type
, addr_base
, addr_off
);
294 addr
= fold_convert (type
, addr_off
);
299 addr
= build_int_cst (type
, 0);
304 /* Returns true if a memory reference in MODE and with parameters given by
305 ADDR is valid on the current target. */
308 valid_mem_ref_p (enum machine_mode mode
, struct mem_address
*addr
)
312 address
= addr_for_mem_ref (addr
, false);
316 return memory_address_p (mode
, address
);
319 /* Checks whether a TARGET_MEM_REF with type TYPE and parameters given by ADDR
320 is valid on the current target and if so, creates and returns the
324 create_mem_ref_raw (tree type
, struct mem_address
*addr
)
326 if (!valid_mem_ref_p (TYPE_MODE (type
), addr
))
329 if (addr
->step
&& integer_onep (addr
->step
))
330 addr
->step
= NULL_TREE
;
332 if (addr
->offset
&& integer_zerop (addr
->offset
))
333 addr
->offset
= NULL_TREE
;
335 return build6 (TARGET_MEM_REF
, type
,
336 addr
->symbol
, addr
->base
, addr
->index
,
337 addr
->step
, addr
->offset
, NULL
);
340 /* Returns true if OBJ is an object whose address is a link time constant. */
343 fixed_address_object_p (tree obj
)
345 return (TREE_CODE (obj
) == VAR_DECL
346 && (TREE_STATIC (obj
)
347 || DECL_EXTERNAL (obj
))
348 && ! DECL_DLLIMPORT_P (obj
));
351 /* If ADDR contains an address of object that is a link time constant,
352 move it to PARTS->symbol. */
355 move_fixed_address_to_symbol (struct mem_address
*parts
, aff_tree
*addr
)
358 tree val
= NULL_TREE
;
360 for (i
= 0; i
< addr
->n
; i
++)
362 if (!double_int_one_p (addr
->elts
[i
].coef
))
365 val
= addr
->elts
[i
].val
;
366 if (TREE_CODE (val
) == ADDR_EXPR
367 && fixed_address_object_p (TREE_OPERAND (val
, 0)))
374 parts
->symbol
= TREE_OPERAND (val
, 0);
375 aff_combination_remove_elt (addr
, i
);
378 /* If ADDR contains an address of a dereferenced pointer, move it to
382 move_pointer_to_base (struct mem_address
*parts
, aff_tree
*addr
)
385 tree val
= NULL_TREE
;
387 for (i
= 0; i
< addr
->n
; i
++)
389 if (!double_int_one_p (addr
->elts
[i
].coef
))
392 val
= addr
->elts
[i
].val
;
393 if (POINTER_TYPE_P (TREE_TYPE (val
)))
401 aff_combination_remove_elt (addr
, i
);
404 /* Adds ELT to PARTS. */
407 add_to_parts (struct mem_address
*parts
, tree elt
)
413 parts
->index
= fold_convert (sizetype
, elt
);
423 /* Add ELT to base. */
424 type
= TREE_TYPE (parts
->base
);
425 if (POINTER_TYPE_P (type
))
426 parts
->base
= fold_build2 (POINTER_PLUS_EXPR
, type
,
428 fold_convert (sizetype
, elt
));
430 parts
->base
= fold_build2 (PLUS_EXPR
, type
,
434 /* Finds the most expensive multiplication in ADDR that can be
435 expressed in an addressing mode and move the corresponding
436 element(s) to PARTS. */
439 most_expensive_mult_to_index (struct mem_address
*parts
, aff_tree
*addr
,
443 double_int best_mult
, amult
, amult_neg
;
444 unsigned best_mult_cost
= 0, acost
;
445 tree mult_elt
= NULL_TREE
, elt
;
447 enum tree_code op_code
;
449 best_mult
= double_int_zero
;
450 for (i
= 0; i
< addr
->n
; i
++)
452 if (!double_int_fits_in_shwi_p (addr
->elts
[i
].coef
))
455 /* FIXME: Should use the correct memory mode rather than Pmode. */
457 coef
= double_int_to_shwi (addr
->elts
[i
].coef
);
459 || !multiplier_allowed_in_address_p (coef
, Pmode
))
462 acost
= multiply_by_cost (coef
, Pmode
, speed
);
464 if (acost
> best_mult_cost
)
466 best_mult_cost
= acost
;
467 best_mult
= addr
->elts
[i
].coef
;
474 /* Collect elements multiplied by best_mult. */
475 for (i
= j
= 0; i
< addr
->n
; i
++)
477 amult
= addr
->elts
[i
].coef
;
478 amult_neg
= double_int_ext_for_comb (double_int_neg (amult
), addr
);
480 if (double_int_equal_p (amult
, best_mult
))
482 else if (double_int_equal_p (amult_neg
, best_mult
))
483 op_code
= MINUS_EXPR
;
486 addr
->elts
[j
] = addr
->elts
[i
];
491 elt
= fold_convert (sizetype
, addr
->elts
[i
].val
);
493 mult_elt
= fold_build2 (op_code
, sizetype
, mult_elt
, elt
);
494 else if (op_code
== PLUS_EXPR
)
497 mult_elt
= fold_build1 (NEGATE_EXPR
, sizetype
, elt
);
501 parts
->index
= mult_elt
;
502 parts
->step
= double_int_to_tree (sizetype
, best_mult
);
505 /* Splits address ADDR into PARTS.
507 TODO -- be more clever about the distribution of the elements of ADDR
508 to PARTS. Some architectures do not support anything but single
509 register in address, possibly with a small integer offset; while
510 create_mem_ref will simplify the address to an acceptable shape
511 later, it would be more efficient to know that asking for complicated
512 addressing modes is useless. */
515 addr_to_parts (aff_tree
*addr
, struct mem_address
*parts
, bool speed
)
520 parts
->symbol
= NULL_TREE
;
521 parts
->base
= NULL_TREE
;
522 parts
->index
= NULL_TREE
;
523 parts
->step
= NULL_TREE
;
525 if (!double_int_zero_p (addr
->offset
))
526 parts
->offset
= double_int_to_tree (sizetype
, addr
->offset
);
528 parts
->offset
= NULL_TREE
;
530 /* Try to find a symbol. */
531 move_fixed_address_to_symbol (parts
, addr
);
533 /* First move the most expensive feasible multiplication
535 most_expensive_mult_to_index (parts
, addr
, speed
);
537 /* Try to find a base of the reference. Since at the moment
538 there is no reliable way how to distinguish between pointer and its
539 offset, this is just a guess. */
541 move_pointer_to_base (parts
, addr
);
543 /* Then try to process the remaining elements. */
544 for (i
= 0; i
< addr
->n
; i
++)
546 part
= fold_convert (sizetype
, addr
->elts
[i
].val
);
547 if (!double_int_one_p (addr
->elts
[i
].coef
))
548 part
= fold_build2 (MULT_EXPR
, sizetype
, part
,
549 double_int_to_tree (sizetype
, addr
->elts
[i
].coef
));
550 add_to_parts (parts
, part
);
553 add_to_parts (parts
, fold_convert (sizetype
, addr
->rest
));
556 /* Force the PARTS to register. */
559 gimplify_mem_ref_parts (gimple_stmt_iterator
*gsi
, struct mem_address
*parts
)
562 parts
->base
= force_gimple_operand_gsi (gsi
, parts
->base
,
564 true, GSI_SAME_STMT
);
566 parts
->index
= force_gimple_operand_gsi (gsi
, parts
->index
,
568 true, GSI_SAME_STMT
);
571 /* Creates and returns a TARGET_MEM_REF for address ADDR. If necessary
572 computations are emitted in front of GSI. TYPE is the mode
573 of created memory reference. */
576 create_mem_ref (gimple_stmt_iterator
*gsi
, tree type
, aff_tree
*addr
,
581 struct mem_address parts
;
583 addr_to_parts (addr
, &parts
, speed
);
584 gimplify_mem_ref_parts (gsi
, &parts
);
585 mem_ref
= create_mem_ref_raw (type
, &parts
);
589 /* The expression is too complicated. Try making it simpler. */
591 if (parts
.step
&& !integer_onep (parts
.step
))
593 /* Move the multiplication to index. */
594 gcc_assert (parts
.index
);
595 parts
.index
= force_gimple_operand_gsi (gsi
,
596 fold_build2 (MULT_EXPR
, sizetype
,
597 parts
.index
, parts
.step
),
598 true, NULL_TREE
, true, GSI_SAME_STMT
);
599 parts
.step
= NULL_TREE
;
601 mem_ref
= create_mem_ref_raw (type
, &parts
);
608 tmp
= build_addr (parts
.symbol
, current_function_decl
);
609 gcc_assert (is_gimple_val (tmp
));
611 /* Add the symbol to base, eventually forcing it to register. */
614 gcc_assert (useless_type_conversion_p
615 (sizetype
, TREE_TYPE (parts
.base
)));
619 atype
= TREE_TYPE (tmp
);
620 parts
.base
= force_gimple_operand_gsi (gsi
,
621 fold_build2 (POINTER_PLUS_EXPR
, atype
,
623 fold_convert (sizetype
, parts
.base
)),
624 true, NULL_TREE
, true, GSI_SAME_STMT
);
628 parts
.index
= parts
.base
;
634 parts
.symbol
= NULL_TREE
;
636 mem_ref
= create_mem_ref_raw (type
, &parts
);
643 /* Add index to base. */
646 atype
= TREE_TYPE (parts
.base
);
647 parts
.base
= force_gimple_operand_gsi (gsi
,
648 fold_build2 (POINTER_PLUS_EXPR
, atype
,
651 true, NULL_TREE
, true, GSI_SAME_STMT
);
654 parts
.base
= parts
.index
;
655 parts
.index
= NULL_TREE
;
657 mem_ref
= create_mem_ref_raw (type
, &parts
);
662 if (parts
.offset
&& !integer_zerop (parts
.offset
))
664 /* Try adding offset to base. */
667 atype
= TREE_TYPE (parts
.base
);
668 parts
.base
= force_gimple_operand_gsi (gsi
,
669 fold_build2 (POINTER_PLUS_EXPR
, atype
,
671 fold_convert (sizetype
, parts
.offset
)),
672 true, NULL_TREE
, true, GSI_SAME_STMT
);
675 parts
.base
= parts
.offset
;
677 parts
.offset
= NULL_TREE
;
679 mem_ref
= create_mem_ref_raw (type
, &parts
);
684 /* Verify that the address is in the simplest possible shape
685 (only a register). If we cannot create such a memory reference,
686 something is really wrong. */
687 gcc_assert (parts
.symbol
== NULL_TREE
);
688 gcc_assert (parts
.index
== NULL_TREE
);
689 gcc_assert (!parts
.step
|| integer_onep (parts
.step
));
690 gcc_assert (!parts
.offset
|| integer_zerop (parts
.offset
));
694 /* Copies components of the address from OP to ADDR. */
697 get_address_description (tree op
, struct mem_address
*addr
)
699 addr
->symbol
= TMR_SYMBOL (op
);
700 addr
->base
= TMR_BASE (op
);
701 addr
->index
= TMR_INDEX (op
);
702 addr
->step
= TMR_STEP (op
);
703 addr
->offset
= TMR_OFFSET (op
);
706 /* Copies the additional information attached to target_mem_ref FROM to TO. */
709 copy_mem_ref_info (tree to
, tree from
)
711 /* And the info about the original reference. */
712 TMR_ORIGINAL (to
) = TMR_ORIGINAL (from
);
715 /* Move constants in target_mem_ref REF to offset. Returns the new target
716 mem ref if anything changes, NULL_TREE otherwise. */
719 maybe_fold_tmr (tree ref
)
721 struct mem_address addr
;
722 bool changed
= false;
725 get_address_description (ref
, &addr
);
727 if (addr
.base
&& TREE_CODE (addr
.base
) == INTEGER_CST
)
730 addr
.offset
= fold_binary_to_constant (PLUS_EXPR
, sizetype
,
732 fold_convert (sizetype
, addr
.base
));
734 addr
.offset
= addr
.base
;
736 addr
.base
= NULL_TREE
;
740 if (addr
.index
&& TREE_CODE (addr
.index
) == INTEGER_CST
)
745 off
= fold_binary_to_constant (MULT_EXPR
, sizetype
,
747 addr
.step
= NULL_TREE
;
752 addr
.offset
= fold_binary_to_constant (PLUS_EXPR
, sizetype
,
758 addr
.index
= NULL_TREE
;
765 ret
= create_mem_ref_raw (TREE_TYPE (ref
), &addr
);
769 copy_mem_ref_info (ret
, ref
);
773 /* Dump PARTS to FILE. */
775 extern void dump_mem_address (FILE *, struct mem_address
*);
777 dump_mem_address (FILE *file
, struct mem_address
*parts
)
781 fprintf (file
, "symbol: ");
782 print_generic_expr (file
, parts
->symbol
, TDF_SLIM
);
783 fprintf (file
, "\n");
787 fprintf (file
, "base: ");
788 print_generic_expr (file
, parts
->base
, TDF_SLIM
);
789 fprintf (file
, "\n");
793 fprintf (file
, "index: ");
794 print_generic_expr (file
, parts
->index
, TDF_SLIM
);
795 fprintf (file
, "\n");
799 fprintf (file
, "step: ");
800 print_generic_expr (file
, parts
->step
, TDF_SLIM
);
801 fprintf (file
, "\n");
805 fprintf (file
, "offset: ");
806 print_generic_expr (file
, parts
->offset
, TDF_SLIM
);
807 fprintf (file
, "\n");
811 #include "gt-tree-ssa-address.h"