Skip to content

Commit

Permalink
Move the search for the appropriate AND instruction
Browse files Browse the repository at this point in the history
into OptimizeCompareInstr.
This necessitates the passing of CmpValue around,
so widen the virtual functions to accomodate.

No functionality changes.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@114428 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
ggreif committed Sep 21, 2010
1 parent b4c7a12 commit 04ac81d
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 26 deletions.
6 changes: 3 additions & 3 deletions include/llvm/Target/TargetInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -581,16 +581,16 @@ class TargetInstrInfo {
/// in SrcReg and the value it compares against in CmpValue. Return true if
/// the comparison instruction can be analyzed.
virtual bool AnalyzeCompare(const MachineInstr *MI,
unsigned &SrcReg, int &CmpValue) const {
unsigned &SrcReg, int &Mask, int &Value) const {
return false;
}

/// OptimizeCompareInstr - See if the comparison instruction can be converted
/// into something more efficient. E.g., on ARM most instructions can set the
/// flags register, obviating the need for a separate CMP. Update the iterator
/// *only* if a transformation took place.
virtual bool OptimizeCompareInstr(MachineInstr * /*CmpInstr*/,
unsigned /*SrcReg*/, int /*CmpValue*/,
virtual bool OptimizeCompareInstr(MachineInstr *CmpInstr,
unsigned SrcReg, int Mask, int Value,
MachineBasicBlock::iterator &) const {
return false;
}
Expand Down
6 changes: 3 additions & 3 deletions lib/CodeGen/PeepholeOptimizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,13 +238,13 @@ bool PeepholeOptimizer::OptimizeCmpInstr(MachineInstr *MI,
// If this instruction is a comparison against zero and isn't comparing a
// physical register, we can try to optimize it.
unsigned SrcReg;
int CmpValue;
if (!TII->AnalyzeCompare(MI, SrcReg, CmpValue) ||
int CmpMask, CmpValue;
if (!TII->AnalyzeCompare(MI, SrcReg, CmpMask, CmpValue) ||
TargetRegisterInfo::isPhysicalRegister(SrcReg))
return false;

// Attempt to optimize the comparison instruction.
if (TII->OptimizeCompareInstr(MI, SrcReg, CmpValue, NextIter)) {
if (TII->OptimizeCompareInstr(MI, SrcReg, CmpMask, CmpValue, NextIter)) {
++NumEliminated;
return true;
}
Expand Down
60 changes: 42 additions & 18 deletions lib/Target/ARM/ARMBaseInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1376,31 +1376,37 @@ bool llvm::rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
}

bool ARMBaseInstrInfo::
AnalyzeCompare(const MachineInstr *MI, unsigned &SrcReg, int &CmpValue) const {
AnalyzeCompare(const MachineInstr *MI, unsigned &SrcReg, int &CmpMask, int &CmpValue) const {
switch (MI->getOpcode()) {
default: break;
case ARM::CMPri:
case ARM::CMPzri:
case ARM::t2CMPri:
case ARM::t2CMPzri:
SrcReg = MI->getOperand(0).getReg();
CmpMask = ~0;
CmpValue = MI->getOperand(1).getImm();
return true;
case ARM::TSTri: {
MachineBasicBlock::const_iterator MII(MI);
if (MI->getParent()->begin() == MII)
return false;
const MachineInstr *AND = llvm::prior(MII);
if (AND->getOpcode() != ARM::ANDri)
return false;
if (MI->getOperand(0).getReg() == AND->getOperand(1).getReg() &&
MI->getOperand(1).getImm() == AND->getOperand(2).getImm()) {
SrcReg = AND->getOperand(0).getReg();
CmpValue = 0;
return true;
}
}
break;
case ARM::TSTri:
case ARM::t2TSTri:
SrcReg = MI->getOperand(0).getReg();
CmpMask = MI->getOperand(1).getImm();
CmpValue = 0;
return true;
}

return false;
}

static bool isSuitableForMask(const MachineInstr &MI, unsigned SrcReg,
int CmpMask) {
switch (MI.getOpcode()) {
case ARM::ANDri:
case ARM::t2ANDri:
if (SrcReg == MI.getOperand(1).getReg() &&
CmpMask == MI.getOperand(2).getImm())
return true;
break;
}

return false;
Expand All @@ -1410,8 +1416,8 @@ AnalyzeCompare(const MachineInstr *MI, unsigned &SrcReg, int &CmpValue) const {
/// comparison into one that sets the zero bit in the flags register. Update the
/// iterator *only* if a transformation took place.
bool ARMBaseInstrInfo::
OptimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, int CmpValue,
MachineBasicBlock::iterator &MII) const {
OptimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, int CmpMask,
int CmpValue, MachineBasicBlock::iterator &MII) const {
if (CmpValue != 0)
return false;

Expand All @@ -1423,6 +1429,24 @@ OptimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, int CmpValue,

MachineInstr *MI = &*DI;

// Masked compares sometimes use the same register as the corresponding 'and'.
if (CmpMask != ~0) {
if (!isSuitableForMask(*MI, SrcReg, CmpMask)) {
MI = 0;
for (MachineRegisterInfo::use_iterator UI = MRI.use_begin(SrcReg),
UE = MRI.use_end(); UI != UE; ++UI) {
if (UI->getParent() != CmpInstr->getParent()) continue;
MachineInstr &PotentialAND = *UI;
if (!isSuitableForMask(PotentialAND, SrcReg, CmpMask))
continue;
SrcReg = PotentialAND.getOperand(0).getReg();
MI = &PotentialAND;
break;
}
if (!MI) return false;
}
}

// Conservatively refuse to convert an instruction which isn't in the same BB
// as the comparison.
if (MI->getParent() != CmpInstr->getParent())
Expand Down
4 changes: 2 additions & 2 deletions lib/Target/ARM/ARMBaseInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -326,12 +326,12 @@ class ARMBaseInstrInfo : public TargetInstrInfoImpl {
/// in SrcReg and the value it compares against in CmpValue. Return true if
/// the comparison instruction can be analyzed.
virtual bool AnalyzeCompare(const MachineInstr *MI, unsigned &SrcReg,
int &CmpValue) const;
int &CmpMask, int &CmpValue) const;

/// OptimizeCompareInstr - Convert the instruction to set the zero flag so
/// that we can remove a "comparison with zero".
virtual bool OptimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg,
int CmpValue,
int CmpMask, int CmpValue,
MachineBasicBlock::iterator &MII) const;

virtual unsigned getNumMicroOps(const MachineInstr *MI,
Expand Down

0 comments on commit 04ac81d

Please sign in to comment.