From a24752ff43dc1ad8c18c5d9e78549c45f62b980e Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Thu, 19 Mar 2009 20:30:06 +0000 Subject: [PATCH] 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 --- include/llvm/CodeGen/MachineInstr.h | 5 +++++ lib/CodeGen/LiveIntervalAnalysis.cpp | 8 ++------ lib/CodeGen/MachineInstr.cpp | 20 +++++++++++++++++++- lib/CodeGen/RegAllocLocal.cpp | 2 +- lib/CodeGen/Spiller.cpp | 19 +++++++++---------- lib/CodeGen/TwoAddressInstructionPass.cpp | 12 ++++++------ 6 files changed, 42 insertions(+), 24 deletions(-) diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index 668c4b3635e..5c646c6874a 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -245,6 +245,11 @@ public: /// check if the register def is a re-definition due to two addr elimination. 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. /// void copyKillDeadInfo(const MachineInstr *MI); diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp index c70cbb48783..3a8f40faec5 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -1062,8 +1062,6 @@ static bool FilterFoldedOps(MachineInstr *MI, SmallVector &Ops, unsigned &MRInfo, SmallVector &FoldOps) { - const TargetInstrDesc &TID = MI->getDesc(); - MRInfo = 0; for (unsigned i = 0, e = Ops.size(); i != e; ++i) { unsigned OpIdx = Ops[i]; @@ -1075,8 +1073,7 @@ static bool FilterFoldedOps(MachineInstr *MI, MRInfo |= (unsigned)VirtRegMap::isMod; else { // Filter out two-address use operand(s). - if (!MO.isImplicit() && - TID.getOperandConstraint(OpIdx, TOI::TIED_TO) != -1) { + if (MI->isRegTiedToDefOperand(OpIdx)) { MRInfo = VirtRegMap::isModRef; continue; } @@ -2160,8 +2157,7 @@ addIntervalsForSpills(const LiveInterval &li, MachineInstr *LastUse = getInstructionFromIndex(LastUseIdx); int UseIdx = LastUse->findRegisterUseOperandIdx(LI->reg, false); assert(UseIdx != -1); - if (LastUse->getOperand(UseIdx).isImplicit() || - LastUse->getDesc().getOperandConstraint(UseIdx,TOI::TIED_TO) == -1){ + if (!LastUse->isRegTiedToDefOperand(UseIdx)) { LastUse->getOperand(UseIdx).setIsKill(); vrm.addKillPoint(LI->reg, LastUseIdx); } diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp index 7bb616468c1..cc85b80a178 100644 --- a/lib/CodeGen/MachineInstr.cpp +++ b/lib/CodeGen/MachineInstr.cpp @@ -689,7 +689,7 @@ int MachineInstr::findFirstPredOperandIdx() const { 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. bool MachineInstr::isRegReDefinedByTwoAddr(unsigned DefIdx) const{ assert(getOperand(DefIdx).isDef() && "DefIdx is not a def!"); @@ -703,6 +703,24 @@ bool MachineInstr::isRegReDefinedByTwoAddr(unsigned DefIdx) const{ 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. /// void MachineInstr::copyKillDeadInfo(const MachineInstr *MI) { diff --git a/lib/CodeGen/RegAllocLocal.cpp b/lib/CodeGen/RegAllocLocal.cpp index a8c69008c24..b965dc9f0f6 100644 --- a/lib/CodeGen/RegAllocLocal.cpp +++ b/lib/CodeGen/RegAllocLocal.cpp @@ -695,7 +695,7 @@ void RALocal::ComputeLocalLiveness(MachineBasicBlock& MBB) { if (isPhysReg || !usedOutsideBlock) { if (MO.isUse()) { // 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); } else MO.setIsDead(true); diff --git a/lib/CodeGen/Spiller.cpp b/lib/CodeGen/Spiller.cpp index d47e1fd35a6..2c96ddc2b96 100644 --- a/lib/CodeGen/Spiller.cpp +++ b/lib/CodeGen/Spiller.cpp @@ -233,8 +233,7 @@ static void UpdateKills(MachineInstr &MI, BitVector &RegKills, KillOps[Reg]->setIsKill(false); KillOps[Reg] = NULL; RegKills.reset(Reg); - if (i < TID.getNumOperands() && - TID.getOperandConstraint(i, TOI::TIED_TO) == -1) + if (!MI.isRegTiedToDefOperand(i)) // Unless it's a two-address operand, this is the new kill. MO.setIsKill(); } @@ -748,8 +747,8 @@ bool LocalSpiller::CommuteToFoldReload(MachineBasicBlock &MBB, int UseIdx = DefMI->findRegisterUseOperandIdx(DestReg, false); if (UseIdx == -1) return false; - int DefIdx = TID.getOperandConstraint(UseIdx, TOI::TIED_TO); - if (DefIdx == -1) + unsigned DefIdx; + if (!MI.isRegTiedToDefOperand(UseIdx, &DefIdx)) return false; assert(DefMI->getOperand(DefIdx).isReg() && DefMI->getOperand(DefIdx).getReg() == SrcReg); @@ -890,7 +889,7 @@ void LocalSpiller::TransferDeadness(MachineBasicBlock *MBB, unsigned CurDist, continue; if (!LastUD || (LastUD->isUse() && MO.isDef())) LastUD = &MO; - if (TID.getOperandConstraint(i, TOI::TIED_TO) != -1) + if (LastUDMI->isRegTiedToDefOperand(i)) return; } 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 // apply, reuse it. bool CanReuse = true; - int ti = TID.getOperandConstraint(i, TOI::TIED_TO); - if (ti != -1) { + bool isTied = MI.isRegTiedToDefOperand(i); + if (isTied) { // 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 // 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. ReusedOperands.addReuse(i, ReuseSlot, PhysReg, VRM.getPhys(VirtReg), VirtReg); - if (ti != -1) + if (isTied) // Only mark it clobbered if this is a use&def operand. ReusedOperands.markClobbered(PhysReg); ++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 // register and it's not a two-address operand. IsKill will be // unset if reg is reused. - if (ti == -1 && KilledMIRegs.count(VirtReg) == 0) { + if (!isTied && KilledMIRegs.count(VirtReg) == 0) { MI.getOperand(i).setIsKill(); KilledMIRegs.insert(VirtReg); } @@ -1325,7 +1324,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM, Spills.addAvailable(SSorRMId, PhysReg); // Assumes this is the last use. IsKill will be unset if reg is reused // unless it's a two-address operand. - if (TID.getOperandConstraint(i, TOI::TIED_TO) == -1 && + if (!MI.isRegTiedToDefOperand(i) && KilledMIRegs.count(VirtReg) == 0) { MI.getOperand(i).setIsKill(); KilledMIRegs.insert(VirtReg); diff --git a/lib/CodeGen/TwoAddressInstructionPass.cpp b/lib/CodeGen/TwoAddressInstructionPass.cpp index 35c069a672a..3b923ef8db5 100644 --- a/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -234,7 +234,7 @@ static bool isTwoAddrUse(MachineInstr *UseMI, unsigned Reg) { for (unsigned i = 0, e = TID.getNumOperands(); i != e; ++i) { MachineOperand &MO = UseMI->getOperand(i); 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. return true; } @@ -338,8 +338,8 @@ static bool isTwoAddrUse(MachineInstr &MI, unsigned Reg, unsigned &DstReg) { const MachineOperand &MO = MI.getOperand(i); if (!MO.isReg() || !MO.isUse() || MO.getReg() != Reg) continue; - int ti = TID.getOperandConstraint(i, TOI::TIED_TO); - if (ti != -1) { + unsigned ti; + if (MI.isRegTiedToDefOperand(i, &ti)) { DstReg = MI.getOperand(ti).getReg(); return true; } @@ -635,8 +635,8 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) { ProcessCopy(&*mi, &*mbbi, Processed); for (unsigned si = 1, e = TID.getNumOperands(); si < e; ++si) { - int ti = TID.getOperandConstraint(si, TOI::TIED_TO); - if (ti == -1) + unsigned ti = 0; + if (!mi->isRegTiedToDefOperand(si, &ti)) continue; if (FirstTied) { @@ -669,7 +669,7 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) { // b + a for example) because our transformation will not work. This // should never occur because we are in SSA form. for (unsigned i = 0; i != mi->getNumOperands(); ++i) - assert((int)i == ti || + assert(i == ti || !mi->getOperand(i).isReg() || mi->getOperand(i).getReg() != regA); #endif -- 2.34.1