Commit cdc1afa3 by James Greenhalgh Committed by James Greenhalgh

[Patch 2/2 ARM/AArch64] Add a new Cortex-A53 scheduling model

	* config/arm/aarch-common-protos.h
	(aarch_accumulator_forwarding): New.
	(aarch_forward_to_shift_is_not_shifted_reg): Likewise.
	* config/arm/aarch-common.c (aarch_accumulator_forwarding): New.
	(aarch_forward_to_shift_is_not_shifted_reg): Liekwise.
	* config/arm/cortex-a53.md: Rewrite.

From-SVN: r228324
parent 34050b6b
2015-10-01 James Greenhalgh <james.greenhalgh@arm.com>
* config/arm/aarch-common-protos.h
(aarch_accumulator_forwarding): New.
(aarch_forward_to_shift_is_not_shifted_reg): Likewise.
* config/arm/aarch-common.c (aarch_accumulator_forwarding): New.
(aarch_forward_to_shift_is_not_shifted_reg): Liekwise.
* config/arm/cortex-a53.md: Rewrite.
2015-10-01 Richard Biener <rguenther@suse.de> 2015-10-01 Richard Biener <rguenther@suse.de>
* gimple-match.h (mprts_hook): Declare. * gimple-match.h (mprts_hook): Declare.
...@@ -23,7 +23,9 @@ ...@@ -23,7 +23,9 @@
#ifndef GCC_AARCH_COMMON_PROTOS_H #ifndef GCC_AARCH_COMMON_PROTOS_H
#define GCC_AARCH_COMMON_PROTOS_H #define GCC_AARCH_COMMON_PROTOS_H
extern int aarch_accumulator_forwarding (rtx_insn *, rtx_insn *);
extern int aarch_crypto_can_dual_issue (rtx_insn *, rtx_insn *); extern int aarch_crypto_can_dual_issue (rtx_insn *, rtx_insn *);
extern int aarch_forward_to_shift_is_not_shifted_reg (rtx_insn *, rtx_insn *);
extern bool aarch_rev16_p (rtx); extern bool aarch_rev16_p (rtx);
extern bool aarch_rev16_shleft_mask_imm_p (rtx, machine_mode); extern bool aarch_rev16_shleft_mask_imm_p (rtx, machine_mode);
extern bool aarch_rev16_shright_mask_imm_p (rtx, machine_mode); extern bool aarch_rev16_shright_mask_imm_p (rtx, machine_mode);
......
...@@ -394,6 +394,112 @@ arm_mac_accumulator_is_result (rtx producer, rtx consumer) ...@@ -394,6 +394,112 @@ arm_mac_accumulator_is_result (rtx producer, rtx consumer)
&& !reg_overlap_mentioned_p (result, op1)); && !reg_overlap_mentioned_p (result, op1));
} }
/* Return non-zero if the destination of PRODUCER feeds the accumulator
operand of an MLA-like operation. */
int
aarch_accumulator_forwarding (rtx_insn *producer, rtx_insn *consumer)
{
rtx producer_set = single_set (producer);
rtx consumer_set = single_set (consumer);
/* We are looking for a SET feeding a SET. */
if (!producer_set || !consumer_set)
return 0;
rtx dest = SET_DEST (producer_set);
rtx mla = SET_SRC (consumer_set);
/* We're looking for a register SET. */
if (!REG_P (dest))
return 0;
rtx accumulator;
/* Strip a zero_extend. */
if (GET_CODE (mla) == ZERO_EXTEND)
mla = XEXP (mla, 0);
switch (GET_CODE (mla))
{
case PLUS:
/* Possibly an MADD. */
if (GET_CODE (XEXP (mla, 0)) == MULT)
accumulator = XEXP (mla, 1);
else
return 0;
break;
case MINUS:
/* Possibly an MSUB. */
if (GET_CODE (XEXP (mla, 1)) == MULT)
accumulator = XEXP (mla, 0);
else
return 0;
break;
case FMA:
{
/* Possibly an FMADD/FMSUB/FNMADD/FNMSUB. */
if (REG_P (XEXP (mla, 1))
&& REG_P (XEXP (mla, 2))
&& (REG_P (XEXP (mla, 0))
|| GET_CODE (XEXP (mla, 0)) == NEG))
{
/* FMADD/FMSUB. */
accumulator = XEXP (mla, 2);
}
else if (REG_P (XEXP (mla, 1))
&& GET_CODE (XEXP (mla, 2)) == NEG
&& (REG_P (XEXP (mla, 0))
|| GET_CODE (XEXP (mla, 0)) == NEG))
{
/* FNMADD/FNMSUB. */
accumulator = XEXP (XEXP (mla, 2), 0);
}
else
return 0;
break;
}
default:
/* Not an MLA-like operation. */
return 0;
}
return (REGNO (dest) == REGNO (accumulator));
}
/* Return nonzero if the CONSUMER instruction is some sort of
arithmetic or logic + shift operation, and the register we are
writing in PRODUCER is not used in a register shift by register
operation. */
int
aarch_forward_to_shift_is_not_shifted_reg (rtx_insn *producer,
rtx_insn *consumer)
{
rtx value, op;
rtx early_op;
if (!arm_get_set_operands (producer, consumer, &value, &op))
return 0;
if ((early_op = arm_find_shift_sub_rtx (op)))
{
if (REG_P (early_op))
early_op = op;
/* Any other canonicalisation of a shift is a shift-by-constant
so we don't care. */
if (GET_CODE (early_op) == ASHIFT)
return (!REG_P (XEXP (early_op, 0))
|| !REG_P (XEXP (early_op, 1)));
else
return 1;
}
return 0;
}
/* Return non-zero if the consumer (a multiply-accumulate instruction) /* Return non-zero if the consumer (a multiply-accumulate instruction)
has an accumulator dependency on the result of the producer (a has an accumulator dependency on the result of the producer (a
multiplication instruction) and no other dependency on that result. */ multiplication instruction) and no other dependency on that result. */
......
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