Commit e8426e0a by Bin Cheng Committed by Bin Cheng

aarch64.c (aarch64_legitimize_address): legitimize address expressions like Ra +…

aarch64.c (aarch64_legitimize_address): legitimize address expressions like Ra + Rb + CONST and Ra + Rb<<SCALE + CONST.


	* config/aarch64/aarch64.c (aarch64_legitimize_address): legitimize
	address expressions like Ra + Rb + CONST and Ra + Rb<<SCALE + CONST.


Co-Authored-By: Jiong Wang <jiong.wang@arm.com>

From-SVN: r231244
parent 72cc0e58
2015-12-04 Bin Cheng <bin.cheng@arm.com>
Jiong Wang <jiong.wang@arm.com>
* config/aarch64/aarch64.c (aarch64_legitimize_address): legitimize
address expressions like Ra + Rb + CONST and Ra + Rb<<SCALE + CONST.
2015-12-03 Jan Hubicka <hubicka@ucw.cz>
* alias.c (alias_set_subset_of, alias_sets_must_conflict_p)
......@@ -4823,13 +4823,75 @@ aarch64_legitimize_address (rtx x, rtx /* orig_x */, machine_mode mode)
We try to pick as large a range for the offset as possible to
maximize the chance of a CSE. However, for aligned addresses
we limit the range to 4k so that structures with different sized
elements are likely to use the same base. */
elements are likely to use the same base. We need to be careful
not to split a CONST for some forms of address expression, otherwise
it will generate sub-optimal code. */
if (GET_CODE (x) == PLUS && CONST_INT_P (XEXP (x, 1)))
{
HOST_WIDE_INT offset = INTVAL (XEXP (x, 1));
HOST_WIDE_INT base_offset;
if (GET_CODE (XEXP (x, 0)) == PLUS)
{
rtx op0 = XEXP (XEXP (x, 0), 0);
rtx op1 = XEXP (XEXP (x, 0), 1);
/* Address expressions of the form Ra + Rb + CONST.
If CONST is within the range supported by the addressing
mode "reg+offset", do not split CONST and use the
sequence
Rt = Ra + Rb;
addr = Rt + CONST. */
if (REG_P (op0) && REG_P (op1))
{
machine_mode addr_mode = GET_MODE (x);
rtx base = gen_reg_rtx (addr_mode);
rtx addr = plus_constant (addr_mode, base, offset);
if (aarch64_legitimate_address_hook_p (mode, addr, false))
{
emit_insn (gen_adddi3 (base, op0, op1));
return addr;
}
}
/* Address expressions of the form Ra + Rb<<SCALE + CONST.
If Reg + Rb<<SCALE is a valid address expression, do not
split CONST and use the sequence
Rc = CONST;
Rt = Ra + Rc;
addr = Rt + Rb<<SCALE.
Here we split CONST out of memory referece because:
a) We depend on GIMPLE optimizers to pick up common sub
expression involving the scaling operation.
b) The index Rb is likely a loop iv, it's better to split
the CONST so that computation of new base Rt is a loop
invariant and can be moved out of loop. This is more
important when the original base Ra is sfp related. */
else if (REG_P (op0) || REG_P (op1))
{
machine_mode addr_mode = GET_MODE (x);
rtx base = gen_reg_rtx (addr_mode);
/* Switch to make sure that register is in op0. */
if (REG_P (op1))
std::swap (op0, op1);
rtx addr = gen_rtx_PLUS (addr_mode, op1, base);
if (aarch64_legitimate_address_hook_p (mode, addr, false))
{
base = force_operand (plus_constant (addr_mode,
op0, offset),
NULL_RTX);
return gen_rtx_PLUS (addr_mode, op1, base);
}
}
}
/* Does it look like we'll need a load/store-pair operation? */
if (GET_MODE_SIZE (mode) > 16
|| mode == TImode)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment