1 /* Memory address lowering and addressing mode selection.
2 Copyright (C) 2004-2017 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"
32 #include "stringpool.h"
34 #include "tree-ssanames.h"
36 #include "insn-config.h"
39 #include "tree-pretty-print.h"
40 #include "fold-const.h"
41 #include "stor-layout.h"
42 #include "gimple-iterator.h"
43 #include "gimplify-me.h"
44 #include "tree-ssa-loop-ivopts.h"
48 #include "tree-affine.h"
50 /* FIXME: We compute address costs using RTL. */
51 #include "tree-ssa-address.h"
53 /* TODO -- handling of symbols (according to Richard Hendersons
54 comments, http://gcc.gnu.org/ml/gcc-patches/2005-04/msg00949.html):
56 There are at least 5 different kinds of symbols that we can run up against:
58 (1) binds_local_p, small data area.
59 (2) binds_local_p, eg local statics
60 (3) !binds_local_p, eg global variables
61 (4) thread local, local_exec
62 (5) thread local, !local_exec
64 Now, (1) won't appear often in an array context, but it certainly can.
65 All you have to do is set -GN high enough, or explicitly mark any
66 random object __attribute__((section (".sdata"))).
68 All of these affect whether or not a symbol is in fact a valid address.
69 The only one tested here is (3). And that result may very well
70 be incorrect for (4) or (5).
72 An incorrect result here does not cause incorrect results out the
73 back end, because the expander in expr.c validizes the address. However
74 it would be nice to improve the handling here in order to produce more
77 /* A "template" for memory address, used to determine whether the address is
80 struct GTY (()) mem_addr_template
{
81 rtx ref
; /* The template. */
82 rtx
* GTY ((skip
)) step_p
; /* The point in template where the step should be
84 rtx
* GTY ((skip
)) off_p
; /* The point in template where the offset should
89 /* The templates. Each of the low five bits of the index corresponds to one
90 component of TARGET_MEM_REF being present, while the high bits identify
91 the address space. See TEMPL_IDX. */
93 static GTY(()) vec
<mem_addr_template
, va_gc
> *mem_addr_template_list
;
95 #define TEMPL_IDX(AS, SYMBOL, BASE, INDEX, STEP, OFFSET) \
97 | ((SYMBOL != 0) << 4) \
98 | ((BASE != 0) << 3) \
99 | ((INDEX != 0) << 2) \
100 | ((STEP != 0) << 1) \
103 /* Stores address for memory reference with parameters SYMBOL, BASE, INDEX,
104 STEP and OFFSET to *ADDR using address mode ADDRESS_MODE. Stores pointers
105 to where step is placed to *STEP_P and offset to *OFFSET_P. */
108 gen_addr_rtx (machine_mode address_mode
,
109 rtx symbol
, rtx base
, rtx index
, rtx step
, rtx offset
,
110 rtx
*addr
, rtx
**step_p
, rtx
**offset_p
)
120 if (index
&& index
!= const0_rtx
)
125 act_elem
= gen_rtx_MULT (address_mode
, act_elem
, step
);
128 *step_p
= &XEXP (act_elem
, 1);
134 if (base
&& base
!= const0_rtx
)
137 *addr
= simplify_gen_binary (PLUS
, address_mode
, base
, *addr
);
147 act_elem
= gen_rtx_PLUS (address_mode
, act_elem
, offset
);
150 *offset_p
= &XEXP (act_elem
, 1);
152 if (GET_CODE (symbol
) == SYMBOL_REF
153 || GET_CODE (symbol
) == LABEL_REF
154 || GET_CODE (symbol
) == CONST
)
155 act_elem
= gen_rtx_CONST (address_mode
, act_elem
);
159 *addr
= gen_rtx_PLUS (address_mode
, *addr
, act_elem
);
167 *addr
= gen_rtx_PLUS (address_mode
, *addr
, offset
);
169 *offset_p
= &XEXP (*addr
, 1);
183 /* Returns address for TARGET_MEM_REF with parameters given by ADDR
185 If REALLY_EXPAND is false, just make fake registers instead
186 of really expanding the operands, and perform the expansion in-place
187 by using one of the "templates". */
190 addr_for_mem_ref (struct mem_address
*addr
, addr_space_t as
,
193 machine_mode address_mode
= targetm
.addr_space
.address_mode (as
);
194 machine_mode pointer_mode
= targetm
.addr_space
.pointer_mode (as
);
195 rtx address
, sym
, bse
, idx
, st
, off
;
196 struct mem_addr_template
*templ
;
198 if (addr
->step
&& !integer_onep (addr
->step
))
199 st
= immed_wide_int_const (addr
->step
, pointer_mode
);
203 if (addr
->offset
&& !integer_zerop (addr
->offset
))
205 offset_int dc
= offset_int::from (addr
->offset
, SIGNED
);
206 off
= immed_wide_int_const (dc
, pointer_mode
);
213 unsigned int templ_index
214 = TEMPL_IDX (as
, addr
->symbol
, addr
->base
, addr
->index
, st
, off
);
216 if (templ_index
>= vec_safe_length (mem_addr_template_list
))
217 vec_safe_grow_cleared (mem_addr_template_list
, templ_index
+ 1);
219 /* Reuse the templates for addresses, so that we do not waste memory. */
220 templ
= &(*mem_addr_template_list
)[templ_index
];
223 sym
= (addr
->symbol
?
224 gen_rtx_SYMBOL_REF (pointer_mode
, ggc_strdup ("test_symbol"))
227 gen_raw_REG (pointer_mode
, LAST_VIRTUAL_REGISTER
+ 1)
230 gen_raw_REG (pointer_mode
, LAST_VIRTUAL_REGISTER
+ 2)
233 gen_addr_rtx (pointer_mode
, sym
, bse
, idx
,
234 st
? const0_rtx
: NULL_RTX
,
235 off
? const0_rtx
: NULL_RTX
,
249 /* Otherwise really expand the expressions. */
251 ? expand_expr (addr
->symbol
, NULL_RTX
, pointer_mode
, EXPAND_NORMAL
)
254 ? expand_expr (addr
->base
, NULL_RTX
, pointer_mode
, EXPAND_NORMAL
)
257 ? expand_expr (addr
->index
, NULL_RTX
, pointer_mode
, EXPAND_NORMAL
)
260 gen_addr_rtx (pointer_mode
, sym
, bse
, idx
, st
, off
, &address
, NULL
, NULL
);
261 if (pointer_mode
!= address_mode
)
262 address
= convert_memory_address (address_mode
, address
);
266 /* implement addr_for_mem_ref() directly from a tree, which avoids exporting
267 the mem_address structure. */
270 addr_for_mem_ref (tree exp
, addr_space_t as
, bool really_expand
)
272 struct mem_address addr
;
273 get_address_description (exp
, &addr
);
274 return addr_for_mem_ref (&addr
, as
, really_expand
);
277 /* Returns address of MEM_REF in TYPE. */
280 tree_mem_ref_addr (tree type
, tree mem_ref
)
284 tree step
= TMR_STEP (mem_ref
), offset
= TMR_OFFSET (mem_ref
);
285 tree addr_base
= NULL_TREE
, addr_off
= NULL_TREE
;
287 addr_base
= fold_convert (type
, TMR_BASE (mem_ref
));
289 act_elem
= TMR_INDEX (mem_ref
);
293 act_elem
= fold_build2 (MULT_EXPR
, TREE_TYPE (act_elem
),
298 act_elem
= TMR_INDEX2 (mem_ref
);
302 addr_off
= fold_build2 (PLUS_EXPR
, TREE_TYPE (addr_off
),
308 if (offset
&& !integer_zerop (offset
))
311 addr_off
= fold_build2 (PLUS_EXPR
, TREE_TYPE (addr_off
), addr_off
,
312 fold_convert (TREE_TYPE (addr_off
), offset
));
318 addr
= fold_build_pointer_plus (addr_base
, addr_off
);
325 /* Returns true if a memory reference in MODE and with parameters given by
326 ADDR is valid on the current target. */
329 valid_mem_ref_p (machine_mode mode
, addr_space_t as
,
330 struct mem_address
*addr
)
334 address
= addr_for_mem_ref (addr
, as
, false);
338 return memory_address_addr_space_p (mode
, address
, as
);
341 /* Checks whether a TARGET_MEM_REF with type TYPE and parameters given by ADDR
342 is valid on the current target and if so, creates and returns the
343 TARGET_MEM_REF. If VERIFY is false omit the verification step. */
346 create_mem_ref_raw (tree type
, tree alias_ptr_type
, struct mem_address
*addr
,
352 && !valid_mem_ref_p (TYPE_MODE (type
), TYPE_ADDR_SPACE (type
), addr
))
355 if (addr
->step
&& integer_onep (addr
->step
))
356 addr
->step
= NULL_TREE
;
359 addr
->offset
= fold_convert (alias_ptr_type
, addr
->offset
);
361 addr
->offset
= build_int_cst (alias_ptr_type
, 0);
369 && POINTER_TYPE_P (TREE_TYPE (addr
->base
)))
376 base
= build_int_cst (build_pointer_type (type
), 0);
380 /* If possible use a plain MEM_REF instead of a TARGET_MEM_REF.
381 ??? As IVOPTs does not follow restrictions to where the base
382 pointer may point to create a MEM_REF only if we know that
384 if ((TREE_CODE (base
) == ADDR_EXPR
|| TREE_CODE (base
) == INTEGER_CST
)
385 && (!index2
|| integer_zerop (index2
))
386 && (!addr
->index
|| integer_zerop (addr
->index
)))
387 return fold_build2 (MEM_REF
, type
, base
, addr
->offset
);
389 return build5 (TARGET_MEM_REF
, type
,
390 base
, addr
->offset
, addr
->index
, addr
->step
, index2
);
393 /* Returns true if OBJ is an object whose address is a link time constant. */
396 fixed_address_object_p (tree obj
)
399 && (TREE_STATIC (obj
) || DECL_EXTERNAL (obj
))
400 && ! DECL_DLLIMPORT_P (obj
));
403 /* If ADDR contains an address of object that is a link time constant,
404 move it to PARTS->symbol. */
407 move_fixed_address_to_symbol (struct mem_address
*parts
, aff_tree
*addr
)
410 tree val
= NULL_TREE
;
412 for (i
= 0; i
< addr
->n
; i
++)
414 if (addr
->elts
[i
].coef
!= 1)
417 val
= addr
->elts
[i
].val
;
418 if (TREE_CODE (val
) == ADDR_EXPR
419 && fixed_address_object_p (TREE_OPERAND (val
, 0)))
427 aff_combination_remove_elt (addr
, i
);
430 /* If ADDR contains an instance of BASE_HINT, move it to PARTS->base. */
433 move_hint_to_base (tree type
, struct mem_address
*parts
, tree base_hint
,
437 tree val
= NULL_TREE
;
440 for (i
= 0; i
< addr
->n
; i
++)
442 if (addr
->elts
[i
].coef
!= 1)
445 val
= addr
->elts
[i
].val
;
446 if (operand_equal_p (val
, base_hint
, 0))
453 /* Cast value to appropriate pointer type. We cannot use a pointer
454 to TYPE directly, as the back-end will assume registers of pointer
455 type are aligned, and just the base itself may not actually be.
456 We use void pointer to the type's address space instead. */
457 qual
= ENCODE_QUAL_ADDR_SPACE (TYPE_ADDR_SPACE (type
));
458 type
= build_qualified_type (void_type_node
, qual
);
459 parts
->base
= fold_convert (build_pointer_type (type
), val
);
460 aff_combination_remove_elt (addr
, i
);
463 /* If ADDR contains an address of a dereferenced pointer, move it to
467 move_pointer_to_base (struct mem_address
*parts
, aff_tree
*addr
)
470 tree val
= NULL_TREE
;
472 for (i
= 0; i
< addr
->n
; i
++)
474 if (addr
->elts
[i
].coef
!= 1)
477 val
= addr
->elts
[i
].val
;
478 if (POINTER_TYPE_P (TREE_TYPE (val
)))
486 aff_combination_remove_elt (addr
, i
);
489 /* Moves the loop variant part V in linear address ADDR to be the index
493 move_variant_to_index (struct mem_address
*parts
, aff_tree
*addr
, tree v
)
496 tree val
= NULL_TREE
;
498 gcc_assert (!parts
->index
);
499 for (i
= 0; i
< addr
->n
; i
++)
501 val
= addr
->elts
[i
].val
;
502 if (operand_equal_p (val
, v
, 0))
509 parts
->index
= fold_convert (sizetype
, val
);
510 parts
->step
= wide_int_to_tree (sizetype
, addr
->elts
[i
].coef
);
511 aff_combination_remove_elt (addr
, i
);
514 /* Adds ELT to PARTS. */
517 add_to_parts (struct mem_address
*parts
, tree elt
)
523 parts
->index
= fold_convert (sizetype
, elt
);
533 /* Add ELT to base. */
534 type
= TREE_TYPE (parts
->base
);
535 if (POINTER_TYPE_P (type
))
536 parts
->base
= fold_build_pointer_plus (parts
->base
, elt
);
538 parts
->base
= fold_build2 (PLUS_EXPR
, type
,
542 /* Returns true if multiplying by RATIO is allowed in an address. Test the
543 validity for a memory reference accessing memory of mode MODE in address
547 multiplier_allowed_in_address_p (HOST_WIDE_INT ratio
, machine_mode mode
,
550 #define MAX_RATIO 128
551 unsigned int data_index
= (int) as
* MAX_MACHINE_MODE
+ (int) mode
;
552 static vec
<sbitmap
> valid_mult_list
;
555 if (data_index
>= valid_mult_list
.length ())
556 valid_mult_list
.safe_grow_cleared (data_index
+ 1);
558 valid_mult
= valid_mult_list
[data_index
];
561 machine_mode address_mode
= targetm
.addr_space
.address_mode (as
);
562 rtx reg1
= gen_raw_REG (address_mode
, LAST_VIRTUAL_REGISTER
+ 1);
563 rtx reg2
= gen_raw_REG (address_mode
, LAST_VIRTUAL_REGISTER
+ 2);
567 valid_mult
= sbitmap_alloc (2 * MAX_RATIO
+ 1);
568 bitmap_clear (valid_mult
);
569 scaled
= gen_rtx_fmt_ee (MULT
, address_mode
, reg1
, NULL_RTX
);
570 addr
= gen_rtx_fmt_ee (PLUS
, address_mode
, scaled
, reg2
);
571 for (i
= -MAX_RATIO
; i
<= MAX_RATIO
; i
++)
573 XEXP (scaled
, 1) = gen_int_mode (i
, address_mode
);
574 if (memory_address_addr_space_p (mode
, addr
, as
)
575 || memory_address_addr_space_p (mode
, scaled
, as
))
576 bitmap_set_bit (valid_mult
, i
+ MAX_RATIO
);
579 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
581 fprintf (dump_file
, " allowed multipliers:");
582 for (i
= -MAX_RATIO
; i
<= MAX_RATIO
; i
++)
583 if (bitmap_bit_p (valid_mult
, i
+ MAX_RATIO
))
584 fprintf (dump_file
, " %d", (int) i
);
585 fprintf (dump_file
, "\n");
586 fprintf (dump_file
, "\n");
589 valid_mult_list
[data_index
] = valid_mult
;
592 if (ratio
> MAX_RATIO
|| ratio
< -MAX_RATIO
)
595 return bitmap_bit_p (valid_mult
, ratio
+ MAX_RATIO
);
598 /* Finds the most expensive multiplication in ADDR that can be
599 expressed in an addressing mode and move the corresponding
600 element(s) to PARTS. */
603 most_expensive_mult_to_index (tree type
, struct mem_address
*parts
,
604 aff_tree
*addr
, bool speed
)
606 addr_space_t as
= TYPE_ADDR_SPACE (type
);
607 machine_mode address_mode
= targetm
.addr_space
.address_mode (as
);
609 unsigned best_mult_cost
= 0, acost
;
610 tree mult_elt
= NULL_TREE
, elt
;
612 enum tree_code op_code
;
614 offset_int best_mult
= 0;
615 for (i
= 0; i
< addr
->n
; i
++)
617 if (!wi::fits_shwi_p (addr
->elts
[i
].coef
))
620 coef
= addr
->elts
[i
].coef
.to_shwi ();
622 || !multiplier_allowed_in_address_p (coef
, TYPE_MODE (type
), as
))
625 acost
= mult_by_coeff_cost (coef
, address_mode
, speed
);
627 if (acost
> best_mult_cost
)
629 best_mult_cost
= acost
;
630 best_mult
= offset_int::from (addr
->elts
[i
].coef
, SIGNED
);
637 /* Collect elements multiplied by best_mult. */
638 for (i
= j
= 0; i
< addr
->n
; i
++)
640 offset_int amult
= offset_int::from (addr
->elts
[i
].coef
, SIGNED
);
641 offset_int amult_neg
= -wi::sext (amult
, TYPE_PRECISION (addr
->type
));
643 if (amult
== best_mult
)
645 else if (amult_neg
== best_mult
)
646 op_code
= MINUS_EXPR
;
649 addr
->elts
[j
] = addr
->elts
[i
];
654 elt
= fold_convert (sizetype
, addr
->elts
[i
].val
);
656 mult_elt
= fold_build2 (op_code
, sizetype
, mult_elt
, elt
);
657 else if (op_code
== PLUS_EXPR
)
660 mult_elt
= fold_build1 (NEGATE_EXPR
, sizetype
, elt
);
664 parts
->index
= mult_elt
;
665 parts
->step
= wide_int_to_tree (sizetype
, best_mult
);
668 /* Splits address ADDR for a memory access of type TYPE into PARTS.
669 If BASE_HINT is non-NULL, it specifies an SSA name to be used
670 preferentially as base of the reference, and IV_CAND is the selected
671 iv candidate used in ADDR.
673 TODO -- be more clever about the distribution of the elements of ADDR
674 to PARTS. Some architectures do not support anything but single
675 register in address, possibly with a small integer offset; while
676 create_mem_ref will simplify the address to an acceptable shape
677 later, it would be more efficient to know that asking for complicated
678 addressing modes is useless. */
681 addr_to_parts (tree type
, aff_tree
*addr
, tree iv_cand
,
682 tree base_hint
, struct mem_address
*parts
,
688 parts
->symbol
= NULL_TREE
;
689 parts
->base
= NULL_TREE
;
690 parts
->index
= NULL_TREE
;
691 parts
->step
= NULL_TREE
;
693 if (addr
->offset
!= 0)
694 parts
->offset
= wide_int_to_tree (sizetype
, addr
->offset
);
696 parts
->offset
= NULL_TREE
;
698 /* Try to find a symbol. */
699 move_fixed_address_to_symbol (parts
, addr
);
701 /* No need to do address parts reassociation if the number of parts
702 is <= 2 -- in that case, no loop invariant code motion can be
705 if (!base_hint
&& (addr
->n
> 2))
706 move_variant_to_index (parts
, addr
, iv_cand
);
708 /* First move the most expensive feasible multiplication
711 most_expensive_mult_to_index (type
, parts
, addr
, speed
);
713 /* Try to find a base of the reference. Since at the moment
714 there is no reliable way how to distinguish between pointer and its
715 offset, this is just a guess. */
716 if (!parts
->symbol
&& base_hint
)
717 move_hint_to_base (type
, parts
, base_hint
, addr
);
718 if (!parts
->symbol
&& !parts
->base
)
719 move_pointer_to_base (parts
, addr
);
721 /* Then try to process the remaining elements. */
722 for (i
= 0; i
< addr
->n
; i
++)
724 part
= fold_convert (sizetype
, addr
->elts
[i
].val
);
725 if (addr
->elts
[i
].coef
!= 1)
726 part
= fold_build2 (MULT_EXPR
, sizetype
, part
,
727 wide_int_to_tree (sizetype
, addr
->elts
[i
].coef
));
728 add_to_parts (parts
, part
);
731 add_to_parts (parts
, fold_convert (sizetype
, addr
->rest
));
734 /* Force the PARTS to register. */
737 gimplify_mem_ref_parts (gimple_stmt_iterator
*gsi
, struct mem_address
*parts
)
740 parts
->base
= force_gimple_operand_gsi_1 (gsi
, parts
->base
,
741 is_gimple_mem_ref_addr
, NULL_TREE
,
742 true, GSI_SAME_STMT
);
744 parts
->index
= force_gimple_operand_gsi (gsi
, parts
->index
,
746 true, GSI_SAME_STMT
);
749 /* Creates and returns a TARGET_MEM_REF for address ADDR. If necessary
750 computations are emitted in front of GSI. TYPE is the mode
751 of created memory reference. IV_CAND is the selected iv candidate in ADDR,
752 and BASE_HINT is non NULL if IV_CAND comes from a base address
756 create_mem_ref (gimple_stmt_iterator
*gsi
, tree type
, aff_tree
*addr
,
757 tree alias_ptr_type
, tree iv_cand
, tree base_hint
, bool speed
)
760 struct mem_address parts
;
762 addr_to_parts (type
, addr
, iv_cand
, base_hint
, &parts
, speed
);
763 gimplify_mem_ref_parts (gsi
, &parts
);
764 mem_ref
= create_mem_ref_raw (type
, alias_ptr_type
, &parts
, true);
768 /* The expression is too complicated. Try making it simpler. */
770 if (parts
.step
&& !integer_onep (parts
.step
))
772 /* Move the multiplication to index. */
773 gcc_assert (parts
.index
);
774 parts
.index
= force_gimple_operand_gsi (gsi
,
775 fold_build2 (MULT_EXPR
, sizetype
,
776 parts
.index
, parts
.step
),
777 true, NULL_TREE
, true, GSI_SAME_STMT
);
778 parts
.step
= NULL_TREE
;
780 mem_ref
= create_mem_ref_raw (type
, alias_ptr_type
, &parts
, true);
788 gcc_assert (is_gimple_val (tmp
));
790 /* Add the symbol to base, eventually forcing it to register. */
793 gcc_assert (useless_type_conversion_p
794 (sizetype
, TREE_TYPE (parts
.base
)));
798 parts
.base
= force_gimple_operand_gsi_1 (gsi
,
799 fold_build_pointer_plus (tmp
, parts
.base
),
800 is_gimple_mem_ref_addr
, NULL_TREE
, true, GSI_SAME_STMT
);
804 parts
.index
= parts
.base
;
810 parts
.symbol
= NULL_TREE
;
812 mem_ref
= create_mem_ref_raw (type
, alias_ptr_type
, &parts
, true);
819 /* Add index to base. */
822 parts
.base
= force_gimple_operand_gsi_1 (gsi
,
823 fold_build_pointer_plus (parts
.base
, parts
.index
),
824 is_gimple_mem_ref_addr
, NULL_TREE
, true, GSI_SAME_STMT
);
827 parts
.base
= parts
.index
;
828 parts
.index
= NULL_TREE
;
830 mem_ref
= create_mem_ref_raw (type
, alias_ptr_type
, &parts
, true);
835 if (parts
.offset
&& !integer_zerop (parts
.offset
))
837 /* Try adding offset to base. */
840 parts
.base
= force_gimple_operand_gsi_1 (gsi
,
841 fold_build_pointer_plus (parts
.base
, parts
.offset
),
842 is_gimple_mem_ref_addr
, NULL_TREE
, true, GSI_SAME_STMT
);
845 parts
.base
= parts
.offset
;
847 parts
.offset
= NULL_TREE
;
849 mem_ref
= create_mem_ref_raw (type
, alias_ptr_type
, &parts
, true);
854 /* Verify that the address is in the simplest possible shape
855 (only a register). If we cannot create such a memory reference,
856 something is really wrong. */
857 gcc_assert (parts
.symbol
== NULL_TREE
);
858 gcc_assert (parts
.index
== NULL_TREE
);
859 gcc_assert (!parts
.step
|| integer_onep (parts
.step
));
860 gcc_assert (!parts
.offset
|| integer_zerop (parts
.offset
));
864 /* Copies components of the address from OP to ADDR. */
867 get_address_description (tree op
, struct mem_address
*addr
)
869 if (TREE_CODE (TMR_BASE (op
)) == ADDR_EXPR
)
871 addr
->symbol
= TMR_BASE (op
);
872 addr
->base
= TMR_INDEX2 (op
);
876 addr
->symbol
= NULL_TREE
;
879 gcc_assert (integer_zerop (TMR_BASE (op
)));
880 addr
->base
= TMR_INDEX2 (op
);
883 addr
->base
= TMR_BASE (op
);
885 addr
->index
= TMR_INDEX (op
);
886 addr
->step
= TMR_STEP (op
);
887 addr
->offset
= TMR_OFFSET (op
);
890 /* Copies the reference information from OLD_REF to NEW_REF, where
891 NEW_REF should be either a MEM_REF or a TARGET_MEM_REF. */
894 copy_ref_info (tree new_ref
, tree old_ref
)
896 tree new_ptr_base
= NULL_TREE
;
898 gcc_assert (TREE_CODE (new_ref
) == MEM_REF
899 || TREE_CODE (new_ref
) == TARGET_MEM_REF
);
901 TREE_SIDE_EFFECTS (new_ref
) = TREE_SIDE_EFFECTS (old_ref
);
902 TREE_THIS_VOLATILE (new_ref
) = TREE_THIS_VOLATILE (old_ref
);
904 new_ptr_base
= TREE_OPERAND (new_ref
, 0);
906 /* We can transfer points-to information from an old pointer
907 or decl base to the new one. */
909 && TREE_CODE (new_ptr_base
) == SSA_NAME
910 && !SSA_NAME_PTR_INFO (new_ptr_base
))
912 tree base
= get_base_address (old_ref
);
915 else if ((TREE_CODE (base
) == MEM_REF
916 || TREE_CODE (base
) == TARGET_MEM_REF
)
917 && TREE_CODE (TREE_OPERAND (base
, 0)) == SSA_NAME
918 && SSA_NAME_PTR_INFO (TREE_OPERAND (base
, 0)))
920 struct ptr_info_def
*new_pi
;
921 unsigned int align
, misalign
;
923 duplicate_ssa_name_ptr_info
924 (new_ptr_base
, SSA_NAME_PTR_INFO (TREE_OPERAND (base
, 0)));
925 new_pi
= SSA_NAME_PTR_INFO (new_ptr_base
);
926 /* We have to be careful about transferring alignment information. */
927 if (get_ptr_info_alignment (new_pi
, &align
, &misalign
)
928 && TREE_CODE (old_ref
) == MEM_REF
929 && !(TREE_CODE (new_ref
) == TARGET_MEM_REF
930 && (TMR_INDEX2 (new_ref
)
931 /* TODO: Below conditions can be relaxed if TMR_INDEX
932 is an indcution variable and its initial value and
934 || (TMR_INDEX (new_ref
) && !TMR_STEP (new_ref
))
935 || (TMR_STEP (new_ref
)
936 && (TREE_INT_CST_LOW (TMR_STEP (new_ref
))
939 unsigned int inc
= (mem_ref_offset (old_ref
).to_short_addr ()
940 - mem_ref_offset (new_ref
).to_short_addr ());
941 adjust_ptr_info_misalignment (new_pi
, inc
);
944 mark_ptr_info_alignment_unknown (new_pi
);
946 else if (VAR_P (base
)
947 || TREE_CODE (base
) == PARM_DECL
948 || TREE_CODE (base
) == RESULT_DECL
)
950 struct ptr_info_def
*pi
= get_ptr_info (new_ptr_base
);
951 pt_solution_set_var (&pi
->pt
, base
);
956 /* Move constants in target_mem_ref REF to offset. Returns the new target
957 mem ref if anything changes, NULL_TREE otherwise. */
960 maybe_fold_tmr (tree ref
)
962 struct mem_address addr
;
963 bool changed
= false;
966 get_address_description (ref
, &addr
);
969 && TREE_CODE (addr
.base
) == INTEGER_CST
970 && !integer_zerop (addr
.base
))
972 addr
.offset
= fold_binary_to_constant (PLUS_EXPR
,
973 TREE_TYPE (addr
.offset
),
974 addr
.offset
, addr
.base
);
975 addr
.base
= NULL_TREE
;
980 && TREE_CODE (TREE_OPERAND (addr
.symbol
, 0)) == MEM_REF
)
982 addr
.offset
= fold_binary_to_constant
983 (PLUS_EXPR
, TREE_TYPE (addr
.offset
),
985 TREE_OPERAND (TREE_OPERAND (addr
.symbol
, 0), 1));
986 addr
.symbol
= TREE_OPERAND (TREE_OPERAND (addr
.symbol
, 0), 0);
990 && handled_component_p (TREE_OPERAND (addr
.symbol
, 0)))
992 HOST_WIDE_INT offset
;
993 addr
.symbol
= build_fold_addr_expr
994 (get_addr_base_and_unit_offset
995 (TREE_OPERAND (addr
.symbol
, 0), &offset
));
996 addr
.offset
= int_const_binop (PLUS_EXPR
,
997 addr
.offset
, size_int (offset
));
1001 if (addr
.index
&& TREE_CODE (addr
.index
) == INTEGER_CST
)
1006 off
= fold_binary_to_constant (MULT_EXPR
, sizetype
,
1008 addr
.step
= NULL_TREE
;
1011 addr
.offset
= fold_binary_to_constant (PLUS_EXPR
,
1012 TREE_TYPE (addr
.offset
),
1014 addr
.index
= NULL_TREE
;
1021 /* If we have propagated something into this TARGET_MEM_REF and thus
1022 ended up folding it, always create a new TARGET_MEM_REF regardless
1023 if it is valid in this for on the target - the propagation result
1024 wouldn't be anyway. */
1025 new_ref
= create_mem_ref_raw (TREE_TYPE (ref
),
1026 TREE_TYPE (addr
.offset
), &addr
, false);
1027 TREE_SIDE_EFFECTS (new_ref
) = TREE_SIDE_EFFECTS (ref
);
1028 TREE_THIS_VOLATILE (new_ref
) = TREE_THIS_VOLATILE (ref
);
1032 /* Dump PARTS to FILE. */
1034 extern void dump_mem_address (FILE *, struct mem_address
*);
1036 dump_mem_address (FILE *file
, struct mem_address
*parts
)
1040 fprintf (file
, "symbol: ");
1041 print_generic_expr (file
, TREE_OPERAND (parts
->symbol
, 0), TDF_SLIM
);
1042 fprintf (file
, "\n");
1046 fprintf (file
, "base: ");
1047 print_generic_expr (file
, parts
->base
, TDF_SLIM
);
1048 fprintf (file
, "\n");
1052 fprintf (file
, "index: ");
1053 print_generic_expr (file
, parts
->index
, TDF_SLIM
);
1054 fprintf (file
, "\n");
1058 fprintf (file
, "step: ");
1059 print_generic_expr (file
, parts
->step
, TDF_SLIM
);
1060 fprintf (file
, "\n");
1064 fprintf (file
, "offset: ");
1065 print_generic_expr (file
, parts
->offset
, TDF_SLIM
);
1066 fprintf (file
, "\n");
1070 #include "gt-tree-ssa-address.h"