mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
Add SrcReg2 to analyzeCompare and optimizeCompareInstr to handle Compare
instructions with two register operands. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@159465 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
8ccaad526a
commit
de7266c611
@ -623,19 +623,22 @@ public:
|
|||||||
CreateTargetPostRAHazardRecognizer(const InstrItineraryData*,
|
CreateTargetPostRAHazardRecognizer(const InstrItineraryData*,
|
||||||
const ScheduleDAG *DAG) const = 0;
|
const ScheduleDAG *DAG) const = 0;
|
||||||
|
|
||||||
/// AnalyzeCompare - For a comparison instruction, return the source register
|
/// analyzeCompare - For a comparison instruction, return the source registers
|
||||||
/// in SrcReg and the value it compares against in CmpValue. Return true if
|
/// in SrcReg and SrcReg2 if having two register operands, and the value it
|
||||||
/// the comparison instruction can be analyzed.
|
/// compares against in CmpValue. Return true if the comparison instruction
|
||||||
virtual bool AnalyzeCompare(const MachineInstr *MI,
|
/// can be analyzed.
|
||||||
unsigned &SrcReg, int &Mask, int &Value) const {
|
virtual bool analyzeCompare(const MachineInstr *MI,
|
||||||
|
unsigned &SrcReg, unsigned &SrcReg2,
|
||||||
|
int &Mask, int &Value) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// OptimizeCompareInstr - See if the comparison instruction can be converted
|
/// optimizeCompareInstr - See if the comparison instruction can be converted
|
||||||
/// into something more efficient. E.g., on ARM most instructions can set the
|
/// into something more efficient. E.g., on ARM most instructions can set the
|
||||||
/// flags register, obviating the need for a separate CMP.
|
/// flags register, obviating the need for a separate CMP.
|
||||||
virtual bool OptimizeCompareInstr(MachineInstr *CmpInstr,
|
virtual bool optimizeCompareInstr(MachineInstr *CmpInstr,
|
||||||
unsigned SrcReg, int Mask, int Value,
|
unsigned SrcReg, unsigned SrcReg2,
|
||||||
|
int Mask, int Value,
|
||||||
const MachineRegisterInfo *MRI) const {
|
const MachineRegisterInfo *MRI) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -368,14 +368,15 @@ bool PeepholeOptimizer::optimizeCmpInstr(MachineInstr *MI,
|
|||||||
MachineBasicBlock *MBB) {
|
MachineBasicBlock *MBB) {
|
||||||
// If this instruction is a comparison against zero and isn't comparing a
|
// If this instruction is a comparison against zero and isn't comparing a
|
||||||
// physical register, we can try to optimize it.
|
// physical register, we can try to optimize it.
|
||||||
unsigned SrcReg;
|
unsigned SrcReg, SrcReg2;
|
||||||
int CmpMask, CmpValue;
|
int CmpMask, CmpValue;
|
||||||
if (!TII->AnalyzeCompare(MI, SrcReg, CmpMask, CmpValue) ||
|
if (!TII->analyzeCompare(MI, SrcReg, SrcReg2, CmpMask, CmpValue) ||
|
||||||
TargetRegisterInfo::isPhysicalRegister(SrcReg))
|
TargetRegisterInfo::isPhysicalRegister(SrcReg) ||
|
||||||
|
(SrcReg2 != 0 && TargetRegisterInfo::isPhysicalRegister(SrcReg2)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Attempt to optimize the comparison instruction.
|
// Attempt to optimize the comparison instruction.
|
||||||
if (TII->OptimizeCompareInstr(MI, SrcReg, CmpMask, CmpValue, MRI)) {
|
if (TII->optimizeCompareInstr(MI, SrcReg, SrcReg2, CmpMask, CmpValue, MRI)) {
|
||||||
++NumCmps;
|
++NumCmps;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1737,26 +1737,33 @@ bool llvm::rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
|
|||||||
return Offset == 0;
|
return Offset == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// analyzeCompare - For a comparison instruction, return the source registers
|
||||||
|
/// in SrcReg and SrcReg2 if having two register operands, and the value it
|
||||||
|
/// compares against in CmpValue. Return true if the comparison instruction
|
||||||
|
/// can be analyzed.
|
||||||
bool ARMBaseInstrInfo::
|
bool ARMBaseInstrInfo::
|
||||||
AnalyzeCompare(const MachineInstr *MI, unsigned &SrcReg, int &CmpMask,
|
analyzeCompare(const MachineInstr *MI, unsigned &SrcReg, unsigned &SrcReg2,
|
||||||
int &CmpValue) const {
|
int &CmpMask, int &CmpValue) const {
|
||||||
switch (MI->getOpcode()) {
|
switch (MI->getOpcode()) {
|
||||||
default: break;
|
default: break;
|
||||||
case ARM::CMPri:
|
case ARM::CMPri:
|
||||||
case ARM::t2CMPri:
|
case ARM::t2CMPri:
|
||||||
SrcReg = MI->getOperand(0).getReg();
|
SrcReg = MI->getOperand(0).getReg();
|
||||||
|
SrcReg2 = 0;
|
||||||
CmpMask = ~0;
|
CmpMask = ~0;
|
||||||
CmpValue = MI->getOperand(1).getImm();
|
CmpValue = MI->getOperand(1).getImm();
|
||||||
return true;
|
return true;
|
||||||
case ARM::CMPrr:
|
case ARM::CMPrr:
|
||||||
case ARM::t2CMPrr:
|
case ARM::t2CMPrr:
|
||||||
SrcReg = MI->getOperand(0).getReg();
|
SrcReg = MI->getOperand(0).getReg();
|
||||||
|
SrcReg2 = MI->getOperand(1).getReg();
|
||||||
CmpMask = ~0;
|
CmpMask = ~0;
|
||||||
CmpValue = 0;
|
CmpValue = 0;
|
||||||
return true;
|
return true;
|
||||||
case ARM::TSTri:
|
case ARM::TSTri:
|
||||||
case ARM::t2TSTri:
|
case ARM::t2TSTri:
|
||||||
SrcReg = MI->getOperand(0).getReg();
|
SrcReg = MI->getOperand(0).getReg();
|
||||||
|
SrcReg2 = 0;
|
||||||
CmpMask = MI->getOperand(1).getImm();
|
CmpMask = MI->getOperand(1).getImm();
|
||||||
CmpValue = 0;
|
CmpValue = 0;
|
||||||
return true;
|
return true;
|
||||||
@ -1794,14 +1801,17 @@ static bool isSuitableForMask(MachineInstr *&MI, unsigned SrcReg,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// OptimizeCompareInstr - Convert the instruction supplying the argument to the
|
/// optimizeCompareInstr - Convert the instruction supplying the argument to the
|
||||||
/// comparison into one that sets the zero bit in the flags register. Convert
|
/// comparison into one that sets the zero bit in the flags register;
|
||||||
/// the SUBrr(r1,r2)|Subri(r1,CmpValue) instruction into one that sets the flags
|
/// Remove a redundant Compare instruction if an earlier instruction can set the
|
||||||
/// register and remove the CMPrr(r1,r2)|CMPrr(r2,r1)|CMPri(r1,CmpValue)
|
/// flags in the same way as Compare.
|
||||||
/// instruction.
|
/// E.g. SUBrr(r1,r2) and CMPrr(r1,r2). We also handle the case where two
|
||||||
|
/// operands are swapped: SUBrr(r1,r2) and CMPrr(r2,r1), by updating the
|
||||||
|
/// condition code of instructions which use the flags.
|
||||||
bool ARMBaseInstrInfo::
|
bool ARMBaseInstrInfo::
|
||||||
OptimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, int CmpMask,
|
optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, unsigned SrcReg2,
|
||||||
int CmpValue, const MachineRegisterInfo *MRI) const {
|
int CmpMask, int CmpValue,
|
||||||
|
const MachineRegisterInfo *MRI) const {
|
||||||
if (MRI->def_empty(SrcReg))
|
if (MRI->def_empty(SrcReg))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -1841,13 +1851,10 @@ OptimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, int CmpMask,
|
|||||||
// For CMPrr(r1,r2), we are looking for SUB(r1,r2) or SUB(r2,r1).
|
// For CMPrr(r1,r2), we are looking for SUB(r1,r2) or SUB(r2,r1).
|
||||||
// For CMPri(r1, CmpValue), we are looking for SUBri(r1, CmpValue).
|
// For CMPri(r1, CmpValue), we are looking for SUBri(r1, CmpValue).
|
||||||
MachineInstr *Sub = NULL;
|
MachineInstr *Sub = NULL;
|
||||||
unsigned SrcReg2 = 0;
|
if (SrcReg2 != 0)
|
||||||
if (CmpInstr->getOpcode() == ARM::CMPrr ||
|
|
||||||
CmpInstr->getOpcode() == ARM::t2CMPrr) {
|
|
||||||
SrcReg2 = CmpInstr->getOperand(1).getReg();
|
|
||||||
// MI is not a candidate for CMPrr.
|
// MI is not a candidate for CMPrr.
|
||||||
MI = NULL;
|
MI = NULL;
|
||||||
} else if (MI->getParent() != CmpInstr->getParent() || CmpValue != 0) {
|
else if (MI->getParent() != CmpInstr->getParent() || CmpValue != 0) {
|
||||||
// Conservatively refuse to convert an instruction which isn't in the same
|
// Conservatively refuse to convert an instruction which isn't in the same
|
||||||
// BB as the comparison.
|
// BB as the comparison.
|
||||||
// For CMPri, we need to check Sub, thus we can't return here.
|
// For CMPri, we need to check Sub, thus we can't return here.
|
||||||
|
@ -186,16 +186,20 @@ public:
|
|||||||
return NumCycles == 1;
|
return NumCycles == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// AnalyzeCompare - For a comparison instruction, return the source register
|
/// analyzeCompare - For a comparison instruction, return the source registers
|
||||||
/// in SrcReg and the value it compares against in CmpValue. Return true if
|
/// in SrcReg and SrcReg2 if having two register operands, and the value it
|
||||||
/// the comparison instruction can be analyzed.
|
/// compares against in CmpValue. Return true if the comparison instruction
|
||||||
virtual bool AnalyzeCompare(const MachineInstr *MI, unsigned &SrcReg,
|
/// can be analyzed.
|
||||||
int &CmpMask, int &CmpValue) const;
|
virtual bool analyzeCompare(const MachineInstr *MI, unsigned &SrcReg,
|
||||||
|
unsigned &SrcReg2, int &CmpMask,
|
||||||
|
int &CmpValue) const;
|
||||||
|
|
||||||
/// OptimizeCompareInstr - Convert the instruction to set the zero flag so
|
/// optimizeCompareInstr - Convert the instruction to set the zero flag so
|
||||||
/// that we can remove a "comparison with zero".
|
/// that we can remove a "comparison with zero"; Remove a redundant CMP
|
||||||
virtual bool OptimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg,
|
/// instruction if the flags can be updated in the same way by an earlier
|
||||||
int CmpMask, int CmpValue,
|
/// instruction such as SUB.
|
||||||
|
virtual bool optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg,
|
||||||
|
unsigned SrcReg2, int CmpMask, int CmpValue,
|
||||||
const MachineRegisterInfo *MRI) const;
|
const MachineRegisterInfo *MRI) const;
|
||||||
|
|
||||||
/// FoldImmediate - 'Reg' is known to be defined by a move immediate
|
/// FoldImmediate - 'Reg' is known to be defined by a move immediate
|
||||||
|
Loading…
Reference in New Issue
Block a user