Remove TargetInstrInfo::CommuteChangesDestination and added findCommutedOpIndices which returns the operand indices which are swapped (when applicable). This allows for some code clean up and future enhancements.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75264 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2009-07-10 19:15:51 +00:00
parent fd12da4d61
commit 261ce1d5f8
4 changed files with 67 additions and 31 deletions

View File

@ -194,13 +194,11 @@ public:
virtual MachineInstr *commuteInstruction(MachineInstr *MI,
bool NewMI = false) const = 0;
/// CommuteChangesDestination - Return true if commuting the specified
/// instruction will also changes the destination operand. Also return the
/// current operand index of the would be new destination register by
/// reference. This can happen when the commutable instruction is also a
/// two-address instruction.
virtual bool CommuteChangesDestination(MachineInstr *MI,
unsigned &OpIdx) const = 0;
/// findCommutedOpIndices - If specified MI is commutable, return the two
/// operand indices that would swap value. Return true if the instruction
/// is not in a form which this routine understands.
virtual bool findCommutedOpIndices(MachineInstr *MI, unsigned &SrcOpIdx1,
unsigned &SrcOpIdx2) const = 0;
/// AnalyzeBranch - Analyze the branching code at the end of MBB, returning
/// true if it cannot be understood (e.g. it's a switch dispatch or isn't
@ -495,8 +493,8 @@ protected:
public:
virtual MachineInstr *commuteInstruction(MachineInstr *MI,
bool NewMI = false) const;
virtual bool CommuteChangesDestination(MachineInstr *MI,
unsigned &OpIdx) const;
virtual bool findCommutedOpIndices(MachineInstr *MI, unsigned &SrcOpIdx1,
unsigned &SrcOpIdx2) const;
virtual bool PredicateInstruction(MachineInstr *MI,
const SmallVectorImpl<MachineOperand> &Pred) const;
virtual void reMaterialize(MachineBasicBlock &MBB,

View File

@ -312,9 +312,23 @@ bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(LiveInterval &IntA,
return false;
MachineInstr *DefMI = li_->getInstructionFromIndex(AValNo->def);
const TargetInstrDesc &TID = DefMI->getDesc();
unsigned NewDstIdx;
if (!TID.isCommutable() ||
!tii_->CommuteChangesDestination(DefMI, NewDstIdx))
if (!TID.isCommutable())
return false;
// If DefMI is a two-address instruction then commuting it will change the
// destination register.
int DefIdx = DefMI->findRegisterDefOperandIdx(IntA.reg);
assert(DefIdx != -1);
unsigned UseOpIdx;
if (!DefMI->isRegTiedToUseOperand(DefIdx, &UseOpIdx))
return false;
unsigned Op1, Op2, NewDstIdx;
if (!tii_->findCommutedOpIndices(DefMI, Op1, Op2))
return false;
if (Op1 == UseOpIdx)
NewDstIdx = Op2;
else if (Op2 == UseOpIdx)
NewDstIdx = Op1;
else
return false;
MachineOperand &NewDstMO = DefMI->getOperand(NewDstIdx);

View File

@ -70,26 +70,24 @@ MachineInstr *TargetInstrInfoImpl::commuteInstruction(MachineInstr *MI,
return MI;
}
/// CommuteChangesDestination - Return true if commuting the specified
/// instruction will also changes the destination operand. Also return the
/// current operand index of the would be new destination register by
/// reference. This can happen when the commutable instruction is also a
/// two-address instruction.
bool TargetInstrInfoImpl::CommuteChangesDestination(MachineInstr *MI,
unsigned &OpIdx) const{
/// findCommutedOpIndices - If specified MI is commutable, return the two
/// operand indices that would swap value. Return true if the instruction
/// is not in a form which this routine understands.
bool TargetInstrInfoImpl::findCommutedOpIndices(MachineInstr *MI,
unsigned &SrcOpIdx1,
unsigned &SrcOpIdx2) const {
const TargetInstrDesc &TID = MI->getDesc();
if (!TID.getNumDefs())
if (!TID.isCommutable())
return false;
assert(MI->getOperand(1).isReg() && MI->getOperand(2).isReg() &&
"This only knows how to commute register operands so far");
if (MI->getOperand(0).getReg() == MI->getOperand(1).getReg()) {
// Must be two address instruction!
assert(MI->getDesc().getOperandConstraint(0, TOI::TIED_TO) &&
"Expecting a two-address instruction!");
OpIdx = 2;
return true;
}
return false;
// This assumes v0 = op v1, v2 and commuting would swap v1 and v2. If this
// is not true, then the target must implement this.
SrcOpIdx1 = TID.getNumDefs();
SrcOpIdx2 = SrcOpIdx1 + 1;
if (!MI->getOperand(SrcOpIdx1).isReg() ||
!MI->getOperand(SrcOpIdx2).isReg())
// No idea.
return false;
return true;
}

View File

@ -1157,6 +1157,32 @@ private:
return false;
}
/// CommuteChangesDestination - We are looking for r0 = op r1, r2 and
/// where SrcReg is r1 and it is tied to r0. Return true if after
/// commuting this instruction it will be r0 = op r2, r1.
static bool CommuteChangesDestination(MachineInstr *DefMI,
const TargetInstrDesc &TID,
unsigned SrcReg,
const TargetInstrInfo *TII,
unsigned &DstIdx) {
if (TID.getNumDefs() != 1 && TID.getNumOperands() != 3)
return false;
if (!DefMI->getOperand(1).isReg() ||
DefMI->getOperand(1).getReg() != SrcReg)
return false;
unsigned DefIdx;
if (!DefMI->isRegTiedToDefOperand(1, &DefIdx) || DefIdx != 0)
return false;
unsigned SrcIdx1, SrcIdx2;
if (!TII->findCommutedOpIndices(DefMI, SrcIdx1, SrcIdx2))
return false;
if (SrcIdx1 == 1 && SrcIdx2 == 2) {
DstIdx = 2;
return true;
}
return false;
}
/// CommuteToFoldReload -
/// Look for
/// r1 = load fi#1
@ -1185,7 +1211,7 @@ private:
unsigned NewDstIdx;
if (DefMII != MBB.begin() &&
TID.isCommutable() &&
TII->CommuteChangesDestination(DefMI, NewDstIdx)) {
CommuteChangesDestination(DefMI, TID, SrcReg, TII, NewDstIdx)) {
MachineOperand &NewDstMO = DefMI->getOperand(NewDstIdx);
unsigned NewReg = NewDstMO.getReg();
if (!NewDstMO.isKill() || TRI->regsOverlap(NewReg, SrcReg))