Added MachineInstr::isRegTiedToDefOperand to check for two-addressness.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@67335 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng
2009-03-19 20:30:06 +00:00
parent 817046e1f1
commit a24752ff43
6 changed files with 42 additions and 24 deletions

View File

@@ -245,6 +245,11 @@ public:
/// check if the register def is a re-definition due to two addr elimination. /// check if the register def is a re-definition due to two addr elimination.
bool isRegReDefinedByTwoAddr(unsigned DefIdx) const; bool isRegReDefinedByTwoAddr(unsigned DefIdx) const;
/// isRegTiedToDefOperand - Return true if the use operand of the specified
/// index is tied to an def operand. It also returns the def operand index by
/// reference if DefOpIdx is not null.
bool isRegTiedToDefOperand(unsigned UseOpIdx, unsigned *DefOpIdx = 0);
/// copyKillDeadInfo - Copies kill / dead operand properties from MI. /// copyKillDeadInfo - Copies kill / dead operand properties from MI.
/// ///
void copyKillDeadInfo(const MachineInstr *MI); void copyKillDeadInfo(const MachineInstr *MI);

View File

@@ -1062,8 +1062,6 @@ static bool FilterFoldedOps(MachineInstr *MI,
SmallVector<unsigned, 2> &Ops, SmallVector<unsigned, 2> &Ops,
unsigned &MRInfo, unsigned &MRInfo,
SmallVector<unsigned, 2> &FoldOps) { SmallVector<unsigned, 2> &FoldOps) {
const TargetInstrDesc &TID = MI->getDesc();
MRInfo = 0; MRInfo = 0;
for (unsigned i = 0, e = Ops.size(); i != e; ++i) { for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
unsigned OpIdx = Ops[i]; unsigned OpIdx = Ops[i];
@@ -1075,8 +1073,7 @@ static bool FilterFoldedOps(MachineInstr *MI,
MRInfo |= (unsigned)VirtRegMap::isMod; MRInfo |= (unsigned)VirtRegMap::isMod;
else { else {
// Filter out two-address use operand(s). // Filter out two-address use operand(s).
if (!MO.isImplicit() && if (MI->isRegTiedToDefOperand(OpIdx)) {
TID.getOperandConstraint(OpIdx, TOI::TIED_TO) != -1) {
MRInfo = VirtRegMap::isModRef; MRInfo = VirtRegMap::isModRef;
continue; continue;
} }
@@ -2160,8 +2157,7 @@ addIntervalsForSpills(const LiveInterval &li,
MachineInstr *LastUse = getInstructionFromIndex(LastUseIdx); MachineInstr *LastUse = getInstructionFromIndex(LastUseIdx);
int UseIdx = LastUse->findRegisterUseOperandIdx(LI->reg, false); int UseIdx = LastUse->findRegisterUseOperandIdx(LI->reg, false);
assert(UseIdx != -1); assert(UseIdx != -1);
if (LastUse->getOperand(UseIdx).isImplicit() || if (!LastUse->isRegTiedToDefOperand(UseIdx)) {
LastUse->getDesc().getOperandConstraint(UseIdx,TOI::TIED_TO) == -1){
LastUse->getOperand(UseIdx).setIsKill(); LastUse->getOperand(UseIdx).setIsKill();
vrm.addKillPoint(LI->reg, LastUseIdx); vrm.addKillPoint(LI->reg, LastUseIdx);
} }

View File

@@ -689,7 +689,7 @@ int MachineInstr::findFirstPredOperandIdx() const {
return -1; return -1;
} }
/// isRegReDefinedByTwoAddr - Given the index of a register def operand, /// isRegReDefinedByTwoAddr - Given the index of a register operand,
/// check if the register def is a re-definition due to two addr elimination. /// check if the register def is a re-definition due to two addr elimination.
bool MachineInstr::isRegReDefinedByTwoAddr(unsigned DefIdx) const{ bool MachineInstr::isRegReDefinedByTwoAddr(unsigned DefIdx) const{
assert(getOperand(DefIdx).isDef() && "DefIdx is not a def!"); assert(getOperand(DefIdx).isDef() && "DefIdx is not a def!");
@@ -703,6 +703,24 @@ bool MachineInstr::isRegReDefinedByTwoAddr(unsigned DefIdx) const{
return false; return false;
} }
/// isRegTiedToDefOperand - Return true if the operand of the specified index
/// is a register use and it is tied to an def operand. It also returns the def
/// operand index by reference.
bool MachineInstr::isRegTiedToDefOperand(unsigned UseOpIdx, unsigned *DefOpIdx){
const TargetInstrDesc &TID = getDesc();
if (UseOpIdx >= TID.getNumOperands())
return false;
const MachineOperand &MO = getOperand(UseOpIdx);
if (!MO.isReg() || !MO.isUse())
return false;
int DefIdx = TID.getOperandConstraint(UseOpIdx, TOI::TIED_TO);
if (DefIdx == -1)
return false;
if (DefOpIdx)
*DefOpIdx = (unsigned)DefIdx;
return true;
}
/// copyKillDeadInfo - Copies kill / dead operand properties from MI. /// copyKillDeadInfo - Copies kill / dead operand properties from MI.
/// ///
void MachineInstr::copyKillDeadInfo(const MachineInstr *MI) { void MachineInstr::copyKillDeadInfo(const MachineInstr *MI) {

View File

@@ -695,7 +695,7 @@ void RALocal::ComputeLocalLiveness(MachineBasicBlock& MBB) {
if (isPhysReg || !usedOutsideBlock) { if (isPhysReg || !usedOutsideBlock) {
if (MO.isUse()) { if (MO.isUse()) {
// Don't mark uses that are tied to defs as kills. // Don't mark uses that are tied to defs as kills.
if (MI->getDesc().getOperandConstraint(idx, TOI::TIED_TO) == -1) if (!MI->isRegTiedToDefOperand(idx))
MO.setIsKill(true); MO.setIsKill(true);
} else } else
MO.setIsDead(true); MO.setIsDead(true);

View File

@@ -233,8 +233,7 @@ static void UpdateKills(MachineInstr &MI, BitVector &RegKills,
KillOps[Reg]->setIsKill(false); KillOps[Reg]->setIsKill(false);
KillOps[Reg] = NULL; KillOps[Reg] = NULL;
RegKills.reset(Reg); RegKills.reset(Reg);
if (i < TID.getNumOperands() && if (!MI.isRegTiedToDefOperand(i))
TID.getOperandConstraint(i, TOI::TIED_TO) == -1)
// Unless it's a two-address operand, this is the new kill. // Unless it's a two-address operand, this is the new kill.
MO.setIsKill(); MO.setIsKill();
} }
@@ -748,8 +747,8 @@ bool LocalSpiller::CommuteToFoldReload(MachineBasicBlock &MBB,
int UseIdx = DefMI->findRegisterUseOperandIdx(DestReg, false); int UseIdx = DefMI->findRegisterUseOperandIdx(DestReg, false);
if (UseIdx == -1) if (UseIdx == -1)
return false; return false;
int DefIdx = TID.getOperandConstraint(UseIdx, TOI::TIED_TO); unsigned DefIdx;
if (DefIdx == -1) if (!MI.isRegTiedToDefOperand(UseIdx, &DefIdx))
return false; return false;
assert(DefMI->getOperand(DefIdx).isReg() && assert(DefMI->getOperand(DefIdx).isReg() &&
DefMI->getOperand(DefIdx).getReg() == SrcReg); DefMI->getOperand(DefIdx).getReg() == SrcReg);
@@ -890,7 +889,7 @@ void LocalSpiller::TransferDeadness(MachineBasicBlock *MBB, unsigned CurDist,
continue; continue;
if (!LastUD || (LastUD->isUse() && MO.isDef())) if (!LastUD || (LastUD->isUse() && MO.isDef()))
LastUD = &MO; LastUD = &MO;
if (TID.getOperandConstraint(i, TOI::TIED_TO) != -1) if (LastUDMI->isRegTiedToDefOperand(i))
return; return;
} }
if (LastUD->isDef()) if (LastUD->isDef())
@@ -1168,8 +1167,8 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM,
// aren't allowed to modify the reused register. If none of these cases // aren't allowed to modify the reused register. If none of these cases
// apply, reuse it. // apply, reuse it.
bool CanReuse = true; bool CanReuse = true;
int ti = TID.getOperandConstraint(i, TOI::TIED_TO); bool isTied = MI.isRegTiedToDefOperand(i);
if (ti != -1) { if (isTied) {
// Okay, we have a two address operand. We can reuse this physreg as // Okay, we have a two address operand. We can reuse this physreg as
// long as we are allowed to clobber the value and there isn't an // long as we are allowed to clobber the value and there isn't an
// earlier def that has already clobbered the physreg. // earlier def that has already clobbered the physreg.
@@ -1206,7 +1205,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM,
// we can get at R0 or its alias. // we can get at R0 or its alias.
ReusedOperands.addReuse(i, ReuseSlot, PhysReg, ReusedOperands.addReuse(i, ReuseSlot, PhysReg,
VRM.getPhys(VirtReg), VirtReg); VRM.getPhys(VirtReg), VirtReg);
if (ti != -1) if (isTied)
// Only mark it clobbered if this is a use&def operand. // Only mark it clobbered if this is a use&def operand.
ReusedOperands.markClobbered(PhysReg); ReusedOperands.markClobbered(PhysReg);
++NumReused; ++NumReused;
@@ -1226,7 +1225,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM,
// Mark is isKill if it's there no other uses of the same virtual // Mark is isKill if it's there no other uses of the same virtual
// register and it's not a two-address operand. IsKill will be // register and it's not a two-address operand. IsKill will be
// unset if reg is reused. // unset if reg is reused.
if (ti == -1 && KilledMIRegs.count(VirtReg) == 0) { if (!isTied && KilledMIRegs.count(VirtReg) == 0) {
MI.getOperand(i).setIsKill(); MI.getOperand(i).setIsKill();
KilledMIRegs.insert(VirtReg); KilledMIRegs.insert(VirtReg);
} }
@@ -1325,7 +1324,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM,
Spills.addAvailable(SSorRMId, PhysReg); Spills.addAvailable(SSorRMId, PhysReg);
// Assumes this is the last use. IsKill will be unset if reg is reused // Assumes this is the last use. IsKill will be unset if reg is reused
// unless it's a two-address operand. // unless it's a two-address operand.
if (TID.getOperandConstraint(i, TOI::TIED_TO) == -1 && if (!MI.isRegTiedToDefOperand(i) &&
KilledMIRegs.count(VirtReg) == 0) { KilledMIRegs.count(VirtReg) == 0) {
MI.getOperand(i).setIsKill(); MI.getOperand(i).setIsKill();
KilledMIRegs.insert(VirtReg); KilledMIRegs.insert(VirtReg);

View File

@@ -234,7 +234,7 @@ static bool isTwoAddrUse(MachineInstr *UseMI, unsigned Reg) {
for (unsigned i = 0, e = TID.getNumOperands(); i != e; ++i) { for (unsigned i = 0, e = TID.getNumOperands(); i != e; ++i) {
MachineOperand &MO = UseMI->getOperand(i); MachineOperand &MO = UseMI->getOperand(i);
if (MO.isReg() && MO.getReg() == Reg && if (MO.isReg() && MO.getReg() == Reg &&
(MO.isDef() || TID.getOperandConstraint(i, TOI::TIED_TO) != -1)) (MO.isDef() || UseMI->isRegTiedToDefOperand(i)))
// Earlier use is a two-address one. // Earlier use is a two-address one.
return true; return true;
} }
@@ -338,8 +338,8 @@ static bool isTwoAddrUse(MachineInstr &MI, unsigned Reg, unsigned &DstReg) {
const MachineOperand &MO = MI.getOperand(i); const MachineOperand &MO = MI.getOperand(i);
if (!MO.isReg() || !MO.isUse() || MO.getReg() != Reg) if (!MO.isReg() || !MO.isUse() || MO.getReg() != Reg)
continue; continue;
int ti = TID.getOperandConstraint(i, TOI::TIED_TO); unsigned ti;
if (ti != -1) { if (MI.isRegTiedToDefOperand(i, &ti)) {
DstReg = MI.getOperand(ti).getReg(); DstReg = MI.getOperand(ti).getReg();
return true; return true;
} }
@@ -635,8 +635,8 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) {
ProcessCopy(&*mi, &*mbbi, Processed); ProcessCopy(&*mi, &*mbbi, Processed);
for (unsigned si = 1, e = TID.getNumOperands(); si < e; ++si) { for (unsigned si = 1, e = TID.getNumOperands(); si < e; ++si) {
int ti = TID.getOperandConstraint(si, TOI::TIED_TO); unsigned ti = 0;
if (ti == -1) if (!mi->isRegTiedToDefOperand(si, &ti))
continue; continue;
if (FirstTied) { if (FirstTied) {
@@ -669,7 +669,7 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) {
// b + a for example) because our transformation will not work. This // b + a for example) because our transformation will not work. This
// should never occur because we are in SSA form. // should never occur because we are in SSA form.
for (unsigned i = 0; i != mi->getNumOperands(); ++i) for (unsigned i = 0; i != mi->getNumOperands(); ++i)
assert((int)i == ti || assert(i == ti ||
!mi->getOperand(i).isReg() || !mi->getOperand(i).isReg() ||
mi->getOperand(i).getReg() != regA); mi->getOperand(i).getReg() != regA);
#endif #endif