1 /* Memory address lowering and addressing mode selection.
2 Copyright (C) 2004-2014 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"
28 #include "stor-layout.h"
35 #include "hard-reg-set.h"
38 #include "basic-block.h"
39 #include "tree-pretty-print.h"
40 #include "tree-ssa-alias.h"
41 #include "internal-fn.h"
42 #include "gimple-expr.h"
45 #include "gimple-iterator.h"
46 #include "gimplify-me.h"
47 #include "stringpool.h"
48 #include "tree-ssanames.h"
49 #include "tree-ssa-loop-ivopts.h"
54 #include "tree-inline.h"
55 #include "tree-affine.h"
57 /* FIXME: We compute address costs using RTL. */
58 #include "insn-config.h"
64 #include "tree-ssa-address.h"
66 /* TODO -- handling of symbols (according to Richard Hendersons
67 comments, http://gcc.gnu.org/ml/gcc-patches/2005-04/msg00949.html):
69 There are at least 5 different kinds of symbols that we can run up against:
71 (1) binds_local_p, small data area.
72 (2) binds_local_p, eg local statics
73 (3) !binds_local_p, eg global variables
74 (4) thread local, local_exec
75 (5) thread local, !local_exec
77 Now, (1) won't appear often in an array context, but it certainly can.
78 All you have to do is set -GN high enough, or explicitly mark any
79 random object __attribute__((section (".sdata"))).
81 All of these affect whether or not a symbol is in fact a valid address.
82 The only one tested here is (3). And that result may very well
83 be incorrect for (4) or (5).
85 An incorrect result here does not cause incorrect results out the
86 back end, because the expander in expr.c validizes the address. However
87 it would be nice to improve the handling here in order to produce more
90 /* A "template" for memory address, used to determine whether the address is
93 typedef struct GTY (()) mem_addr_template
{
94 rtx ref
; /* The template. */
95 rtx
* GTY ((skip
)) step_p
; /* The point in template where the step should be
97 rtx
* GTY ((skip
)) off_p
; /* The point in template where the offset should
102 /* The templates. Each of the low five bits of the index corresponds to one
103 component of TARGET_MEM_REF being present, while the high bits identify
104 the address space. See TEMPL_IDX. */
106 static GTY(()) vec
<mem_addr_template
, va_gc
> *mem_addr_template_list
;
108 #define TEMPL_IDX(AS, SYMBOL, BASE, INDEX, STEP, OFFSET) \
110 | ((SYMBOL != 0) << 4) \
111 | ((BASE != 0) << 3) \
112 | ((INDEX != 0) << 2) \
113 | ((STEP != 0) << 1) \
116 /* Stores address for memory reference with parameters SYMBOL, BASE, INDEX,
117 STEP and OFFSET to *ADDR using address mode ADDRESS_MODE. Stores pointers
118 to where step is placed to *STEP_P and offset to *OFFSET_P. */
121 gen_addr_rtx (machine_mode address_mode
,
122 rtx symbol
, rtx base
, rtx index
, rtx step
, rtx offset
,
123 rtx
*addr
, rtx
**step_p
, rtx
**offset_p
)
138 act_elem
= gen_rtx_MULT (address_mode
, act_elem
, step
);
141 *step_p
= &XEXP (act_elem
, 1);
147 if (base
&& base
!= const0_rtx
)
150 *addr
= simplify_gen_binary (PLUS
, address_mode
, base
, *addr
);
160 act_elem
= gen_rtx_PLUS (address_mode
, act_elem
, offset
);
163 *offset_p
= &XEXP (act_elem
, 1);
165 if (GET_CODE (symbol
) == SYMBOL_REF
166 || GET_CODE (symbol
) == LABEL_REF
167 || GET_CODE (symbol
) == CONST
)
168 act_elem
= gen_rtx_CONST (address_mode
, act_elem
);
172 *addr
= gen_rtx_PLUS (address_mode
, *addr
, act_elem
);
180 *addr
= gen_rtx_PLUS (address_mode
, *addr
, offset
);
182 *offset_p
= &XEXP (*addr
, 1);
196 /* Description of a memory address. */
200 tree symbol
, base
, index
, step
, offset
;
203 /* Returns address for TARGET_MEM_REF with parameters given by ADDR
205 If REALLY_EXPAND is false, just make fake registers instead
206 of really expanding the operands, and perform the expansion in-place
207 by using one of the "templates". */
210 addr_for_mem_ref (struct mem_address
*addr
, addr_space_t as
,
213 machine_mode address_mode
= targetm
.addr_space
.address_mode (as
);
214 machine_mode pointer_mode
= targetm
.addr_space
.pointer_mode (as
);
215 rtx address
, sym
, bse
, idx
, st
, off
;
216 struct mem_addr_template
*templ
;
218 if (addr
->step
&& !integer_onep (addr
->step
))
219 st
= immed_wide_int_const (addr
->step
, pointer_mode
);
223 if (addr
->offset
&& !integer_zerop (addr
->offset
))
225 offset_int dc
= offset_int::from (addr
->offset
, SIGNED
);
226 off
= immed_wide_int_const (dc
, pointer_mode
);
233 unsigned int templ_index
234 = TEMPL_IDX (as
, addr
->symbol
, addr
->base
, addr
->index
, st
, off
);
236 if (templ_index
>= vec_safe_length (mem_addr_template_list
))
237 vec_safe_grow_cleared (mem_addr_template_list
, templ_index
+ 1);
239 /* Reuse the templates for addresses, so that we do not waste memory. */
240 templ
= &(*mem_addr_template_list
)[templ_index
];
243 sym
= (addr
->symbol
?
244 gen_rtx_SYMBOL_REF (pointer_mode
, ggc_strdup ("test_symbol"))
247 gen_raw_REG (pointer_mode
, LAST_VIRTUAL_REGISTER
+ 1)
250 gen_raw_REG (pointer_mode
, LAST_VIRTUAL_REGISTER
+ 2)
253 gen_addr_rtx (pointer_mode
, sym
, bse
, idx
,
254 st
? const0_rtx
: NULL_RTX
,
255 off
? const0_rtx
: NULL_RTX
,
269 /* Otherwise really expand the expressions. */
271 ? expand_expr (addr
->symbol
, NULL_RTX
, pointer_mode
, EXPAND_NORMAL
)
274 ? expand_expr (addr
->base
, NULL_RTX
, pointer_mode
, EXPAND_NORMAL
)
277 ? expand_expr (addr
->index
, NULL_RTX
, pointer_mode
, EXPAND_NORMAL
)
280 gen_addr_rtx (pointer_mode
, sym
, bse
, idx
, st
, off
, &address
, NULL
, NULL
);
281 if (pointer_mode
!= address_mode
)
282 address
= convert_memory_address (address_mode
, address
);
286 /* implement addr_for_mem_ref() directly from a tree, which avoids exporting
287 the mem_address structure. */
290 addr_for_mem_ref (tree exp
, addr_space_t as
, bool really_expand
)
292 struct mem_address addr
;
293 get_address_description (exp
, &addr
);
294 return addr_for_mem_ref (&addr
, as
, really_expand
);
297 /* Returns address of MEM_REF in TYPE. */
300 tree_mem_ref_addr (tree type
, tree mem_ref
)
304 tree step
= TMR_STEP (mem_ref
), offset
= TMR_OFFSET (mem_ref
);
305 tree addr_base
= NULL_TREE
, addr_off
= NULL_TREE
;
307 addr_base
= fold_convert (type
, TMR_BASE (mem_ref
));
309 act_elem
= TMR_INDEX (mem_ref
);
313 act_elem
= fold_build2 (MULT_EXPR
, TREE_TYPE (act_elem
),
318 act_elem
= TMR_INDEX2 (mem_ref
);
322 addr_off
= fold_build2 (PLUS_EXPR
, TREE_TYPE (addr_off
),
328 if (offset
&& !integer_zerop (offset
))
331 addr_off
= fold_build2 (PLUS_EXPR
, TREE_TYPE (addr_off
), addr_off
,
332 fold_convert (TREE_TYPE (addr_off
), offset
));
338 addr
= fold_build_pointer_plus (addr_base
, addr_off
);
345 /* Returns true if a memory reference in MODE and with parameters given by
346 ADDR is valid on the current target. */
349 valid_mem_ref_p (machine_mode mode
, addr_space_t as
,
350 struct mem_address
*addr
)
354 address
= addr_for_mem_ref (addr
, as
, false);
358 return memory_address_addr_space_p (mode
, address
, as
);
361 /* Checks whether a TARGET_MEM_REF with type TYPE and parameters given by ADDR
362 is valid on the current target and if so, creates and returns the
363 TARGET_MEM_REF. If VERIFY is false omit the verification step. */
366 create_mem_ref_raw (tree type
, tree alias_ptr_type
, struct mem_address
*addr
,
372 && !valid_mem_ref_p (TYPE_MODE (type
), TYPE_ADDR_SPACE (type
), addr
))
375 if (addr
->step
&& integer_onep (addr
->step
))
376 addr
->step
= NULL_TREE
;
379 addr
->offset
= fold_convert (alias_ptr_type
, addr
->offset
);
381 addr
->offset
= build_int_cst (alias_ptr_type
, 0);
389 && POINTER_TYPE_P (TREE_TYPE (addr
->base
)))
396 base
= build_int_cst (ptr_type_node
, 0);
400 /* If possible use a plain MEM_REF instead of a TARGET_MEM_REF.
401 ??? As IVOPTs does not follow restrictions to where the base
402 pointer may point to create a MEM_REF only if we know that
404 if ((TREE_CODE (base
) == ADDR_EXPR
|| TREE_CODE (base
) == INTEGER_CST
)
405 && (!index2
|| integer_zerop (index2
))
406 && (!addr
->index
|| integer_zerop (addr
->index
)))
407 return fold_build2 (MEM_REF
, type
, base
, addr
->offset
);
409 return build5 (TARGET_MEM_REF
, type
,
410 base
, addr
->offset
, addr
->index
, addr
->step
, index2
);
413 /* Returns true if OBJ is an object whose address is a link time constant. */
416 fixed_address_object_p (tree obj
)
418 return (TREE_CODE (obj
) == VAR_DECL
419 && (TREE_STATIC (obj
)
420 || DECL_EXTERNAL (obj
))
421 && ! DECL_DLLIMPORT_P (obj
));
424 /* If ADDR contains an address of object that is a link time constant,
425 move it to PARTS->symbol. */
428 move_fixed_address_to_symbol (struct mem_address
*parts
, aff_tree
*addr
)
431 tree val
= NULL_TREE
;
433 for (i
= 0; i
< addr
->n
; i
++)
435 if (addr
->elts
[i
].coef
!= 1)
438 val
= addr
->elts
[i
].val
;
439 if (TREE_CODE (val
) == ADDR_EXPR
440 && fixed_address_object_p (TREE_OPERAND (val
, 0)))
448 aff_combination_remove_elt (addr
, i
);
451 /* If ADDR contains an instance of BASE_HINT, move it to PARTS->base. */
454 move_hint_to_base (tree type
, struct mem_address
*parts
, tree base_hint
,
458 tree val
= NULL_TREE
;
461 for (i
= 0; i
< addr
->n
; i
++)
463 if (addr
->elts
[i
].coef
!= 1)
466 val
= addr
->elts
[i
].val
;
467 if (operand_equal_p (val
, base_hint
, 0))
474 /* Cast value to appropriate pointer type. We cannot use a pointer
475 to TYPE directly, as the back-end will assume registers of pointer
476 type are aligned, and just the base itself may not actually be.
477 We use void pointer to the type's address space instead. */
478 qual
= ENCODE_QUAL_ADDR_SPACE (TYPE_ADDR_SPACE (type
));
479 type
= build_qualified_type (void_type_node
, qual
);
480 parts
->base
= fold_convert (build_pointer_type (type
), val
);
481 aff_combination_remove_elt (addr
, i
);
484 /* If ADDR contains an address of a dereferenced pointer, move it to
488 move_pointer_to_base (struct mem_address
*parts
, aff_tree
*addr
)
491 tree val
= NULL_TREE
;
493 for (i
= 0; i
< addr
->n
; i
++)
495 if (addr
->elts
[i
].coef
!= 1)
498 val
= addr
->elts
[i
].val
;
499 if (POINTER_TYPE_P (TREE_TYPE (val
)))
507 aff_combination_remove_elt (addr
, i
);
510 /* Moves the loop variant part V in linear address ADDR to be the index
514 move_variant_to_index (struct mem_address
*parts
, aff_tree
*addr
, tree v
)
517 tree val
= NULL_TREE
;
519 gcc_assert (!parts
->index
);
520 for (i
= 0; i
< addr
->n
; i
++)
522 val
= addr
->elts
[i
].val
;
523 if (operand_equal_p (val
, v
, 0))
530 parts
->index
= fold_convert (sizetype
, val
);
531 parts
->step
= wide_int_to_tree (sizetype
, addr
->elts
[i
].coef
);
532 aff_combination_remove_elt (addr
, i
);
535 /* Adds ELT to PARTS. */
538 add_to_parts (struct mem_address
*parts
, tree elt
)
544 parts
->index
= fold_convert (sizetype
, elt
);
554 /* Add ELT to base. */
555 type
= TREE_TYPE (parts
->base
);
556 if (POINTER_TYPE_P (type
))
557 parts
->base
= fold_build_pointer_plus (parts
->base
, elt
);
559 parts
->base
= fold_build2 (PLUS_EXPR
, type
,
563 /* Finds the most expensive multiplication in ADDR that can be
564 expressed in an addressing mode and move the corresponding
565 element(s) to PARTS. */
568 most_expensive_mult_to_index (tree type
, struct mem_address
*parts
,
569 aff_tree
*addr
, bool speed
)
571 addr_space_t as
= TYPE_ADDR_SPACE (type
);
572 machine_mode address_mode
= targetm
.addr_space
.address_mode (as
);
574 unsigned best_mult_cost
= 0, acost
;
575 tree mult_elt
= NULL_TREE
, elt
;
577 enum tree_code op_code
;
579 offset_int best_mult
= 0;
580 for (i
= 0; i
< addr
->n
; i
++)
582 if (!wi::fits_shwi_p (addr
->elts
[i
].coef
))
585 coef
= addr
->elts
[i
].coef
.to_shwi ();
587 || !multiplier_allowed_in_address_p (coef
, TYPE_MODE (type
), as
))
590 acost
= mult_by_coeff_cost (coef
, address_mode
, speed
);
592 if (acost
> best_mult_cost
)
594 best_mult_cost
= acost
;
595 best_mult
= offset_int::from (addr
->elts
[i
].coef
, SIGNED
);
602 /* Collect elements multiplied by best_mult. */
603 for (i
= j
= 0; i
< addr
->n
; i
++)
605 offset_int amult
= offset_int::from (addr
->elts
[i
].coef
, SIGNED
);
606 offset_int amult_neg
= -wi::sext (amult
, TYPE_PRECISION (addr
->type
));
608 if (amult
== best_mult
)
610 else if (amult_neg
== best_mult
)
611 op_code
= MINUS_EXPR
;
614 addr
->elts
[j
] = addr
->elts
[i
];
619 elt
= fold_convert (sizetype
, addr
->elts
[i
].val
);
621 mult_elt
= fold_build2 (op_code
, sizetype
, mult_elt
, elt
);
622 else if (op_code
== PLUS_EXPR
)
625 mult_elt
= fold_build1 (NEGATE_EXPR
, sizetype
, elt
);
629 parts
->index
= mult_elt
;
630 parts
->step
= wide_int_to_tree (sizetype
, best_mult
);
633 /* Splits address ADDR for a memory access of type TYPE into PARTS.
634 If BASE_HINT is non-NULL, it specifies an SSA name to be used
635 preferentially as base of the reference, and IV_CAND is the selected
636 iv candidate used in ADDR.
638 TODO -- be more clever about the distribution of the elements of ADDR
639 to PARTS. Some architectures do not support anything but single
640 register in address, possibly with a small integer offset; while
641 create_mem_ref will simplify the address to an acceptable shape
642 later, it would be more efficient to know that asking for complicated
643 addressing modes is useless. */
646 addr_to_parts (tree type
, aff_tree
*addr
, tree iv_cand
,
647 tree base_hint
, struct mem_address
*parts
,
653 parts
->symbol
= NULL_TREE
;
654 parts
->base
= NULL_TREE
;
655 parts
->index
= NULL_TREE
;
656 parts
->step
= NULL_TREE
;
658 if (addr
->offset
!= 0)
659 parts
->offset
= wide_int_to_tree (sizetype
, addr
->offset
);
661 parts
->offset
= NULL_TREE
;
663 /* Try to find a symbol. */
664 move_fixed_address_to_symbol (parts
, addr
);
666 /* No need to do address parts reassociation if the number of parts
667 is <= 2 -- in that case, no loop invariant code motion can be
670 if (!base_hint
&& (addr
->n
> 2))
671 move_variant_to_index (parts
, addr
, iv_cand
);
673 /* First move the most expensive feasible multiplication
676 most_expensive_mult_to_index (type
, parts
, addr
, speed
);
678 /* Try to find a base of the reference. Since at the moment
679 there is no reliable way how to distinguish between pointer and its
680 offset, this is just a guess. */
681 if (!parts
->symbol
&& base_hint
)
682 move_hint_to_base (type
, parts
, base_hint
, addr
);
683 if (!parts
->symbol
&& !parts
->base
)
684 move_pointer_to_base (parts
, addr
);
686 /* Then try to process the remaining elements. */
687 for (i
= 0; i
< addr
->n
; i
++)
689 part
= fold_convert (sizetype
, addr
->elts
[i
].val
);
690 if (addr
->elts
[i
].coef
!= 1)
691 part
= fold_build2 (MULT_EXPR
, sizetype
, part
,
692 wide_int_to_tree (sizetype
, addr
->elts
[i
].coef
));
693 add_to_parts (parts
, part
);
696 add_to_parts (parts
, fold_convert (sizetype
, addr
->rest
));
699 /* Force the PARTS to register. */
702 gimplify_mem_ref_parts (gimple_stmt_iterator
*gsi
, struct mem_address
*parts
)
705 parts
->base
= force_gimple_operand_gsi_1 (gsi
, parts
->base
,
706 is_gimple_mem_ref_addr
, NULL_TREE
,
707 true, GSI_SAME_STMT
);
709 parts
->index
= force_gimple_operand_gsi (gsi
, parts
->index
,
711 true, GSI_SAME_STMT
);
714 /* Creates and returns a TARGET_MEM_REF for address ADDR. If necessary
715 computations are emitted in front of GSI. TYPE is the mode
716 of created memory reference. IV_CAND is the selected iv candidate in ADDR,
717 and BASE_HINT is non NULL if IV_CAND comes from a base address
721 create_mem_ref (gimple_stmt_iterator
*gsi
, tree type
, aff_tree
*addr
,
722 tree alias_ptr_type
, tree iv_cand
, tree base_hint
, bool speed
)
725 struct mem_address parts
;
727 addr_to_parts (type
, addr
, iv_cand
, base_hint
, &parts
, speed
);
728 gimplify_mem_ref_parts (gsi
, &parts
);
729 mem_ref
= create_mem_ref_raw (type
, alias_ptr_type
, &parts
, true);
733 /* The expression is too complicated. Try making it simpler. */
735 if (parts
.step
&& !integer_onep (parts
.step
))
737 /* Move the multiplication to index. */
738 gcc_assert (parts
.index
);
739 parts
.index
= force_gimple_operand_gsi (gsi
,
740 fold_build2 (MULT_EXPR
, sizetype
,
741 parts
.index
, parts
.step
),
742 true, NULL_TREE
, true, GSI_SAME_STMT
);
743 parts
.step
= NULL_TREE
;
745 mem_ref
= create_mem_ref_raw (type
, alias_ptr_type
, &parts
, true);
753 gcc_assert (is_gimple_val (tmp
));
755 /* Add the symbol to base, eventually forcing it to register. */
758 gcc_assert (useless_type_conversion_p
759 (sizetype
, TREE_TYPE (parts
.base
)));
763 parts
.base
= force_gimple_operand_gsi_1 (gsi
,
764 fold_build_pointer_plus (tmp
, parts
.base
),
765 is_gimple_mem_ref_addr
, NULL_TREE
, true, GSI_SAME_STMT
);
769 parts
.index
= parts
.base
;
775 parts
.symbol
= NULL_TREE
;
777 mem_ref
= create_mem_ref_raw (type
, alias_ptr_type
, &parts
, true);
784 /* Add index to base. */
787 parts
.base
= force_gimple_operand_gsi_1 (gsi
,
788 fold_build_pointer_plus (parts
.base
, parts
.index
),
789 is_gimple_mem_ref_addr
, NULL_TREE
, true, GSI_SAME_STMT
);
792 parts
.base
= parts
.index
;
793 parts
.index
= NULL_TREE
;
795 mem_ref
= create_mem_ref_raw (type
, alias_ptr_type
, &parts
, true);
800 if (parts
.offset
&& !integer_zerop (parts
.offset
))
802 /* Try adding offset to base. */
805 parts
.base
= force_gimple_operand_gsi_1 (gsi
,
806 fold_build_pointer_plus (parts
.base
, parts
.offset
),
807 is_gimple_mem_ref_addr
, NULL_TREE
, true, GSI_SAME_STMT
);
810 parts
.base
= parts
.offset
;
812 parts
.offset
= NULL_TREE
;
814 mem_ref
= create_mem_ref_raw (type
, alias_ptr_type
, &parts
, true);
819 /* Verify that the address is in the simplest possible shape
820 (only a register). If we cannot create such a memory reference,
821 something is really wrong. */
822 gcc_assert (parts
.symbol
== NULL_TREE
);
823 gcc_assert (parts
.index
== NULL_TREE
);
824 gcc_assert (!parts
.step
|| integer_onep (parts
.step
));
825 gcc_assert (!parts
.offset
|| integer_zerop (parts
.offset
));
829 /* Copies components of the address from OP to ADDR. */
832 get_address_description (tree op
, struct mem_address
*addr
)
834 if (TREE_CODE (TMR_BASE (op
)) == ADDR_EXPR
)
836 addr
->symbol
= TMR_BASE (op
);
837 addr
->base
= TMR_INDEX2 (op
);
841 addr
->symbol
= NULL_TREE
;
844 gcc_assert (integer_zerop (TMR_BASE (op
)));
845 addr
->base
= TMR_INDEX2 (op
);
848 addr
->base
= TMR_BASE (op
);
850 addr
->index
= TMR_INDEX (op
);
851 addr
->step
= TMR_STEP (op
);
852 addr
->offset
= TMR_OFFSET (op
);
855 /* Copies the reference information from OLD_REF to NEW_REF, where
856 NEW_REF should be either a MEM_REF or a TARGET_MEM_REF. */
859 copy_ref_info (tree new_ref
, tree old_ref
)
861 tree new_ptr_base
= NULL_TREE
;
863 gcc_assert (TREE_CODE (new_ref
) == MEM_REF
864 || TREE_CODE (new_ref
) == TARGET_MEM_REF
);
866 TREE_SIDE_EFFECTS (new_ref
) = TREE_SIDE_EFFECTS (old_ref
);
867 TREE_THIS_VOLATILE (new_ref
) = TREE_THIS_VOLATILE (old_ref
);
869 new_ptr_base
= TREE_OPERAND (new_ref
, 0);
871 /* We can transfer points-to information from an old pointer
872 or decl base to the new one. */
874 && TREE_CODE (new_ptr_base
) == SSA_NAME
875 && !SSA_NAME_PTR_INFO (new_ptr_base
))
877 tree base
= get_base_address (old_ref
);
880 else if ((TREE_CODE (base
) == MEM_REF
881 || TREE_CODE (base
) == TARGET_MEM_REF
)
882 && TREE_CODE (TREE_OPERAND (base
, 0)) == SSA_NAME
883 && SSA_NAME_PTR_INFO (TREE_OPERAND (base
, 0)))
885 struct ptr_info_def
*new_pi
;
886 unsigned int align
, misalign
;
888 duplicate_ssa_name_ptr_info
889 (new_ptr_base
, SSA_NAME_PTR_INFO (TREE_OPERAND (base
, 0)));
890 new_pi
= SSA_NAME_PTR_INFO (new_ptr_base
);
891 /* We have to be careful about transferring alignment information. */
892 if (get_ptr_info_alignment (new_pi
, &align
, &misalign
)
893 && TREE_CODE (old_ref
) == MEM_REF
894 && !(TREE_CODE (new_ref
) == TARGET_MEM_REF
895 && (TMR_INDEX2 (new_ref
)
896 || (TMR_STEP (new_ref
)
897 && (TREE_INT_CST_LOW (TMR_STEP (new_ref
))
900 unsigned int inc
= (mem_ref_offset (old_ref
).to_short_addr ()
901 - mem_ref_offset (new_ref
).to_short_addr ());
902 adjust_ptr_info_misalignment (new_pi
, inc
);
905 mark_ptr_info_alignment_unknown (new_pi
);
907 else if (TREE_CODE (base
) == VAR_DECL
908 || TREE_CODE (base
) == PARM_DECL
909 || TREE_CODE (base
) == RESULT_DECL
)
911 struct ptr_info_def
*pi
= get_ptr_info (new_ptr_base
);
912 pt_solution_set_var (&pi
->pt
, base
);
917 /* Move constants in target_mem_ref REF to offset. Returns the new target
918 mem ref if anything changes, NULL_TREE otherwise. */
921 maybe_fold_tmr (tree ref
)
923 struct mem_address addr
;
924 bool changed
= false;
927 get_address_description (ref
, &addr
);
930 && TREE_CODE (addr
.base
) == INTEGER_CST
931 && !integer_zerop (addr
.base
))
933 addr
.offset
= fold_binary_to_constant (PLUS_EXPR
,
934 TREE_TYPE (addr
.offset
),
935 addr
.offset
, addr
.base
);
936 addr
.base
= NULL_TREE
;
941 && TREE_CODE (TREE_OPERAND (addr
.symbol
, 0)) == MEM_REF
)
943 addr
.offset
= fold_binary_to_constant
944 (PLUS_EXPR
, TREE_TYPE (addr
.offset
),
946 TREE_OPERAND (TREE_OPERAND (addr
.symbol
, 0), 1));
947 addr
.symbol
= TREE_OPERAND (TREE_OPERAND (addr
.symbol
, 0), 0);
951 && handled_component_p (TREE_OPERAND (addr
.symbol
, 0)))
953 HOST_WIDE_INT offset
;
954 addr
.symbol
= build_fold_addr_expr
955 (get_addr_base_and_unit_offset
956 (TREE_OPERAND (addr
.symbol
, 0), &offset
));
957 addr
.offset
= int_const_binop (PLUS_EXPR
,
958 addr
.offset
, size_int (offset
));
962 if (addr
.index
&& TREE_CODE (addr
.index
) == INTEGER_CST
)
967 off
= fold_binary_to_constant (MULT_EXPR
, sizetype
,
969 addr
.step
= NULL_TREE
;
972 addr
.offset
= fold_binary_to_constant (PLUS_EXPR
,
973 TREE_TYPE (addr
.offset
),
975 addr
.index
= NULL_TREE
;
982 /* If we have propagated something into this TARGET_MEM_REF and thus
983 ended up folding it, always create a new TARGET_MEM_REF regardless
984 if it is valid in this for on the target - the propagation result
985 wouldn't be anyway. */
986 new_ref
= create_mem_ref_raw (TREE_TYPE (ref
),
987 TREE_TYPE (addr
.offset
), &addr
, false);
988 TREE_SIDE_EFFECTS (new_ref
) = TREE_SIDE_EFFECTS (ref
);
989 TREE_THIS_VOLATILE (new_ref
) = TREE_THIS_VOLATILE (ref
);
993 /* Dump PARTS to FILE. */
995 extern void dump_mem_address (FILE *, struct mem_address
*);
997 dump_mem_address (FILE *file
, struct mem_address
*parts
)
1001 fprintf (file
, "symbol: ");
1002 print_generic_expr (file
, TREE_OPERAND (parts
->symbol
, 0), TDF_SLIM
);
1003 fprintf (file
, "\n");
1007 fprintf (file
, "base: ");
1008 print_generic_expr (file
, parts
->base
, TDF_SLIM
);
1009 fprintf (file
, "\n");
1013 fprintf (file
, "index: ");
1014 print_generic_expr (file
, parts
->index
, TDF_SLIM
);
1015 fprintf (file
, "\n");
1019 fprintf (file
, "step: ");
1020 print_generic_expr (file
, parts
->step
, TDF_SLIM
);
1021 fprintf (file
, "\n");
1025 fprintf (file
, "offset: ");
1026 print_generic_expr (file
, parts
->offset
, TDF_SLIM
);
1027 fprintf (file
, "\n");
1031 #include "gt-tree-ssa-address.h"