mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 20:32:21 +00:00
Implement AArch64 TTI interface isAsCheapAsAMove.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@214159 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
f3224d0617
commit
a3b8caf8a7
@ -1636,7 +1636,7 @@ class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype,
|
||||
|
||||
multiclass AddSub<bit isSub, string mnemonic,
|
||||
SDPatternOperator OpNode = null_frag> {
|
||||
let hasSideEffects = 0 in {
|
||||
let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in {
|
||||
// Add/Subtract immediate
|
||||
def Wri : BaseAddSubImm<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32,
|
||||
mnemonic, OpNode> {
|
||||
@ -1961,14 +1961,14 @@ class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype>
|
||||
|
||||
multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode,
|
||||
string Alias> {
|
||||
let AddedComplexity = 6 in
|
||||
let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
|
||||
def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic,
|
||||
[(set GPR32sp:$Rd, (OpNode GPR32:$Rn,
|
||||
logical_imm32:$imm))]> {
|
||||
let Inst{31} = 0;
|
||||
let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
|
||||
}
|
||||
let AddedComplexity = 6 in
|
||||
let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
|
||||
def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic,
|
||||
[(set GPR64sp:$Rd, (OpNode GPR64:$Rn,
|
||||
logical_imm64:$imm))]> {
|
||||
@ -2013,8 +2013,10 @@ class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode>
|
||||
// Split from LogicalImm as not all instructions have both.
|
||||
multiclass LogicalReg<bits<2> opc, bit N, string mnemonic,
|
||||
SDPatternOperator OpNode> {
|
||||
let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
|
||||
def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
|
||||
def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
|
||||
}
|
||||
|
||||
def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
|
||||
[(set GPR32:$Rd, (OpNode GPR32:$Rn,
|
||||
|
@ -541,6 +541,51 @@ void AArch64InstrInfo::insertSelect(MachineBasicBlock &MBB,
|
||||
CC);
|
||||
}
|
||||
|
||||
// FIXME: this implementation should be micro-architecture dependent, so a
|
||||
// micro-architecture target hook should be introduced here in future.
|
||||
bool AArch64InstrInfo::isAsCheapAsAMove(const MachineInstr *MI) const {
|
||||
if (!Subtarget.isCortexA57() && !Subtarget.isCortexA53())
|
||||
return MI->isAsCheapAsAMove();
|
||||
|
||||
switch (MI->getOpcode()) {
|
||||
default:
|
||||
return false;
|
||||
|
||||
// add/sub on register without shift
|
||||
case AArch64::ADDWri:
|
||||
case AArch64::ADDXri:
|
||||
case AArch64::SUBWri:
|
||||
case AArch64::SUBXri:
|
||||
return (MI->getOperand(3).getImm() == 0);
|
||||
|
||||
// logical ops on immediate
|
||||
case AArch64::ANDWri:
|
||||
case AArch64::ANDXri:
|
||||
case AArch64::EORWri:
|
||||
case AArch64::EORXri:
|
||||
case AArch64::ORRWri:
|
||||
case AArch64::ORRXri:
|
||||
return true;
|
||||
|
||||
// logical ops on register without shift
|
||||
case AArch64::ANDWrr:
|
||||
case AArch64::ANDXrr:
|
||||
case AArch64::BICWrr:
|
||||
case AArch64::BICXrr:
|
||||
case AArch64::EONWrr:
|
||||
case AArch64::EONXrr:
|
||||
case AArch64::EORWrr:
|
||||
case AArch64::EORXrr:
|
||||
case AArch64::ORNWrr:
|
||||
case AArch64::ORNXrr:
|
||||
case AArch64::ORRWrr:
|
||||
case AArch64::ORRXrr:
|
||||
return true;
|
||||
}
|
||||
|
||||
llvm_unreachable("Unknown opcode to check as cheap as a move!");
|
||||
}
|
||||
|
||||
bool AArch64InstrInfo::isCoalescableExtInstr(const MachineInstr &MI,
|
||||
unsigned &SrcReg, unsigned &DstReg,
|
||||
unsigned &SubIdx) const {
|
||||
|
@ -46,6 +46,8 @@ public:
|
||||
|
||||
unsigned GetInstSizeInBytes(const MachineInstr *MI) const;
|
||||
|
||||
bool isAsCheapAsAMove(const MachineInstr *MI) const override;
|
||||
|
||||
bool isCoalescableExtInstr(const MachineInstr &MI, unsigned &SrcReg,
|
||||
unsigned &DstReg, unsigned &SubIdx) const override;
|
||||
|
||||
|
@ -100,6 +100,8 @@ public:
|
||||
bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); }
|
||||
|
||||
bool isCyclone() const { return CPUString == "cyclone"; }
|
||||
bool isCortexA57() const { return CPUString == "cortex-a57"; }
|
||||
bool isCortexA53() const { return CPUString == "cortex-a53"; }
|
||||
|
||||
/// getMaxInlineSizeThreshold - Returns the maximum memset / memcpy size
|
||||
/// that still makes it profitable to inline the call.
|
||||
|
16
test/CodeGen/AArch64/remat.ll
Normal file
16
test/CodeGen/AArch64/remat.ll
Normal file
@ -0,0 +1,16 @@
|
||||
; RUN: llc -mtriple=aarch64-linux-gnuabi -mcpu=cortex-a57 -o - %s | FileCheck %s
|
||||
; RUN: llc -mtriple=aarch64-linux-gnuabi -mcpu=cortex-a53 -o - %s | FileCheck %s
|
||||
|
||||
%X = type { i64, i64, i64 }
|
||||
declare void @f(%X*)
|
||||
define void @t() {
|
||||
entry:
|
||||
%tmp = alloca %X
|
||||
call void @f(%X* %tmp)
|
||||
; CHECK: add x0, sp, #8
|
||||
; CHECK-NEXT-NOT: mov
|
||||
call void @f(%X* %tmp)
|
||||
; CHECK: add x0, sp, #8
|
||||
; CHECK-NEXT-NOT: mov
|
||||
ret void
|
||||
}
|
Loading…
Reference in New Issue
Block a user