[AArch64 costs 1/18] Refactor aarch64_address_costs.
gcc/ * config/aarch64/aarch64-protos.h (scale_addr_mode_cost): New. (cpu_addrcost_table): Use it. * config/aarch64/aarch64.c (generic_addrcost_table): Initialize it. (aarch64_address_cost): Rewrite using aarch64_classify_address, move it. From-SVN: r210493
This commit is contained in:
parent
a764d66099
commit
677473677a
|
@ -1,3 +1,11 @@
|
|||
2014-05-16 James Greenhalgh <james.greenhalgh@arm.com>
|
||||
|
||||
* config/aarch64/aarch64-protos.h (scale_addr_mode_cost): New.
|
||||
(cpu_addrcost_table): Use it.
|
||||
* config/aarch64/aarch64.c (generic_addrcost_table): Initialize it.
|
||||
(aarch64_address_cost): Rewrite using aarch64_classify_address,
|
||||
move it.
|
||||
|
||||
2014-05-16 Richard Biener <rguenther@suse.de>
|
||||
|
||||
* tree-ssa-sccvn.c: Include tree-cfg.h and domwalk.h.
|
||||
|
|
|
@ -108,9 +108,22 @@ enum aarch64_symbol_type
|
|||
cost models and vectors for address cost calculations, register
|
||||
move costs and memory move costs. */
|
||||
|
||||
/* Scaled addressing modes can vary cost depending on the mode of the
|
||||
value to be loaded/stored. QImode values cannot use scaled
|
||||
addressing modes. */
|
||||
|
||||
struct scale_addr_mode_cost
|
||||
{
|
||||
const int hi;
|
||||
const int si;
|
||||
const int di;
|
||||
const int ti;
|
||||
};
|
||||
|
||||
/* Additional cost for addresses. */
|
||||
struct cpu_addrcost_table
|
||||
{
|
||||
const struct scale_addr_mode_cost addr_scale_costs;
|
||||
const int pre_modify;
|
||||
const int post_modify;
|
||||
const int register_offset;
|
||||
|
|
|
@ -171,6 +171,15 @@ __extension__
|
|||
#endif
|
||||
static const struct cpu_addrcost_table generic_addrcost_table =
|
||||
{
|
||||
#if HAVE_DESIGNATED_INITIALIZERS
|
||||
.addr_scale_costs =
|
||||
#endif
|
||||
{
|
||||
NAMED_PARAM (qi, 0),
|
||||
NAMED_PARAM (hi, 0),
|
||||
NAMED_PARAM (si, 0),
|
||||
NAMED_PARAM (ti, 0),
|
||||
},
|
||||
NAMED_PARAM (pre_modify, 0),
|
||||
NAMED_PARAM (post_modify, 0),
|
||||
NAMED_PARAM (register_offset, 0),
|
||||
|
@ -4550,6 +4559,101 @@ aarch64_strip_shift_or_extend (rtx x)
|
|||
return aarch64_strip_shift (x);
|
||||
}
|
||||
|
||||
static int
|
||||
aarch64_address_cost (rtx x,
|
||||
enum machine_mode mode,
|
||||
addr_space_t as ATTRIBUTE_UNUSED,
|
||||
bool speed)
|
||||
{
|
||||
enum rtx_code c = GET_CODE (x);
|
||||
const struct cpu_addrcost_table *addr_cost = aarch64_tune_params->addr_cost;
|
||||
struct aarch64_address_info info;
|
||||
int cost = 0;
|
||||
info.shift = 0;
|
||||
|
||||
if (!aarch64_classify_address (&info, x, mode, c, false))
|
||||
{
|
||||
if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF)
|
||||
{
|
||||
/* This is a CONST or SYMBOL ref which will be split
|
||||
in a different way depending on the code model in use.
|
||||
Cost it through the generic infrastructure. */
|
||||
int cost_symbol_ref = rtx_cost (x, MEM, 1, speed);
|
||||
/* Divide through by the cost of one instruction to
|
||||
bring it to the same units as the address costs. */
|
||||
cost_symbol_ref /= COSTS_N_INSNS (1);
|
||||
/* The cost is then the cost of preparing the address,
|
||||
followed by an immediate (possibly 0) offset. */
|
||||
return cost_symbol_ref + addr_cost->imm_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is most likely a jump table from a case
|
||||
statement. */
|
||||
return addr_cost->register_offset;
|
||||
}
|
||||
}
|
||||
|
||||
switch (info.type)
|
||||
{
|
||||
case ADDRESS_LO_SUM:
|
||||
case ADDRESS_SYMBOLIC:
|
||||
case ADDRESS_REG_IMM:
|
||||
cost += addr_cost->imm_offset;
|
||||
break;
|
||||
|
||||
case ADDRESS_REG_WB:
|
||||
if (c == PRE_INC || c == PRE_DEC || c == PRE_MODIFY)
|
||||
cost += addr_cost->pre_modify;
|
||||
else if (c == POST_INC || c == POST_DEC || c == POST_MODIFY)
|
||||
cost += addr_cost->post_modify;
|
||||
else
|
||||
gcc_unreachable ();
|
||||
|
||||
break;
|
||||
|
||||
case ADDRESS_REG_REG:
|
||||
cost += addr_cost->register_offset;
|
||||
break;
|
||||
|
||||
case ADDRESS_REG_UXTW:
|
||||
case ADDRESS_REG_SXTW:
|
||||
cost += addr_cost->register_extend;
|
||||
break;
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
|
||||
if (info.shift > 0)
|
||||
{
|
||||
/* For the sake of calculating the cost of the shifted register
|
||||
component, we can treat same sized modes in the same way. */
|
||||
switch (GET_MODE_BITSIZE (mode))
|
||||
{
|
||||
case 16:
|
||||
cost += addr_cost->addr_scale_costs.hi;
|
||||
break;
|
||||
|
||||
case 32:
|
||||
cost += addr_cost->addr_scale_costs.si;
|
||||
break;
|
||||
|
||||
case 64:
|
||||
cost += addr_cost->addr_scale_costs.di;
|
||||
break;
|
||||
|
||||
/* We can't tell, or this is a 128-bit vector. */
|
||||
default:
|
||||
cost += addr_cost->addr_scale_costs.ti;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return cost;
|
||||
}
|
||||
|
||||
/* Calculate the cost of calculating X, storing it in *COST. Result
|
||||
is true if the total cost of the operation has now been calculated. */
|
||||
static bool
|
||||
|
@ -4886,37 +4990,6 @@ aarch64_rtx_costs (rtx x, int code, int outer ATTRIBUTE_UNUSED,
|
|||
return false;
|
||||
}
|
||||
|
||||
static int
|
||||
aarch64_address_cost (rtx x ATTRIBUTE_UNUSED,
|
||||
enum machine_mode mode ATTRIBUTE_UNUSED,
|
||||
addr_space_t as ATTRIBUTE_UNUSED, bool speed ATTRIBUTE_UNUSED)
|
||||
{
|
||||
enum rtx_code c = GET_CODE (x);
|
||||
const struct cpu_addrcost_table *addr_cost = aarch64_tune_params->addr_cost;
|
||||
|
||||
if (c == PRE_INC || c == PRE_DEC || c == PRE_MODIFY)
|
||||
return addr_cost->pre_modify;
|
||||
|
||||
if (c == POST_INC || c == POST_DEC || c == POST_MODIFY)
|
||||
return addr_cost->post_modify;
|
||||
|
||||
if (c == PLUS)
|
||||
{
|
||||
if (GET_CODE (XEXP (x, 1)) == CONST_INT)
|
||||
return addr_cost->imm_offset;
|
||||
else if (GET_CODE (XEXP (x, 0)) == MULT
|
||||
|| GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
|
||||
|| GET_CODE (XEXP (x, 0)) == SIGN_EXTEND)
|
||||
return addr_cost->register_extend;
|
||||
|
||||
return addr_cost->register_offset;
|
||||
}
|
||||
else if (c == MEM || c == LABEL_REF || c == SYMBOL_REF)
|
||||
return addr_cost->imm_offset;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
aarch64_register_move_cost (enum machine_mode mode,
|
||||
reg_class_t from_i, reg_class_t to_i)
|
||||
|
|
Loading…
Reference in New Issue