[llvm-commits] [llvm] r71606 - in /llvm/trunk: lib/CodeGen/RegAllocLinearScan.cpp lib/CodeGen/VirtRegRewriter.cpp test/CodeGen/X86/2007-03-01-SpillerCrash.ll
Evan Cheng
evan.cheng at apple.com
Tue May 12 16:07:01 PDT 2009
Author: evancheng
Date: Tue May 12 18:07:00 2009
New Revision: 71606
URL: http://llvm.org/viewvc/llvm-project?rev=71606&view=rev
Log:
Teach TransferDeadness to delete truly dead instructions if they do not produce side effects.
Modified:
llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp
llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp
llvm/trunk/test/CodeGen/X86/2007-03-01-SpillerCrash.ll
Modified: llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp?rev=71606&r1=71605&r2=71606&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp (original)
+++ llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp Tue May 12 18:07:00 2009
@@ -350,29 +350,44 @@
if (!vni->def || vni->def == ~1U || vni->def == ~0U)
return Reg;
MachineInstr *CopyMI = li_->getInstructionFromIndex(vni->def);
- unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
+ unsigned SrcReg, DstReg, SrcSubReg, DstSubReg, PhysReg;
if (!CopyMI ||
!tii_->isMoveInstr(*CopyMI, SrcReg, DstReg, SrcSubReg, DstSubReg))
return Reg;
+ PhysReg = SrcReg;
if (TargetRegisterInfo::isVirtualRegister(SrcReg)) {
if (!vrm_->isAssignedReg(SrcReg))
return Reg;
- else
- SrcReg = vrm_->getPhys(SrcReg);
+ PhysReg = vrm_->getPhys(SrcReg);
}
- if (Reg == SrcReg)
+ if (Reg == PhysReg)
return Reg;
const TargetRegisterClass *RC = mri_->getRegClass(cur.reg);
- if (!RC->contains(SrcReg))
+ if (!RC->contains(PhysReg))
return Reg;
// Try to coalesce.
- if (!li_->conflictsWithPhysRegDef(cur, *vrm_, SrcReg)) {
- DOUT << "Coalescing: " << cur << " -> " << tri_->getName(SrcReg)
+ if (!li_->conflictsWithPhysRegDef(cur, *vrm_, PhysReg)) {
+ DOUT << "Coalescing: " << cur << " -> " << tri_->getName(PhysReg)
<< '\n';
vrm_->clearVirt(cur.reg);
- vrm_->assignVirt2Phys(cur.reg, SrcReg);
+ vrm_->assignVirt2Phys(cur.reg, PhysReg);
+
+ // Remove unnecessary kills since a copy does not clobber the register.
+ if (li_->hasInterval(SrcReg)) {
+ LiveInterval &SrcLI = li_->getInterval(SrcReg);
+ for (MachineRegisterInfo::reg_iterator I = mri_->reg_begin(cur.reg),
+ E = mri_->reg_end(); I != E; ++I) {
+ MachineOperand &O = I.getOperand();
+ if (!O.isUse() || !O.isKill())
+ continue;
+ MachineInstr *MI = &*I;
+ if (SrcLI.liveAt(li_->getDefIndex(li_->getInstructionIndex(MI))))
+ O.setIsKill(false);
+ }
+ }
+
++NumCoalesce;
return SrcReg;
}
Modified: llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp?rev=71606&r1=71605&r2=71606&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp (original)
+++ llvm/trunk/lib/CodeGen/VirtRegRewriter.cpp Tue May 12 18:07:00 2009
@@ -851,6 +851,14 @@
}
}
+namespace {
+ struct RefSorter {
+ bool operator()(const std::pair<MachineInstr*, int> &A,
+ const std::pair<MachineInstr*, int> &B) {
+ return A.second < B.second;
+ }
+ };
+}
// ***************************** //
// Local Spiller Implementation //
@@ -1313,9 +1321,10 @@
/// removed. Find the last def or use and mark it as dead / kill.
void TransferDeadness(MachineBasicBlock *MBB, unsigned CurDist,
unsigned Reg, BitVector &RegKills,
- std::vector<MachineOperand*> &KillOps) {
- int LastUDDist = -1;
- MachineInstr *LastUDMI = NULL;
+ std::vector<MachineOperand*> &KillOps,
+ VirtRegMap &VRM) {
+ SmallPtrSet<MachineInstr*, 4> Seens;
+ SmallVector<std::pair<MachineInstr*, int>,8> Refs;
for (MachineRegisterInfo::reg_iterator RI = RegInfo->reg_begin(Reg),
RE = RegInfo->reg_end(); RI != RE; ++RI) {
MachineInstr *UDMI = &*RI;
@@ -1324,13 +1333,18 @@
DenseMap<MachineInstr*, unsigned>::iterator DI = DistanceMap.find(UDMI);
if (DI == DistanceMap.end() || DI->second > CurDist)
continue;
- if ((int)DI->second < LastUDDist)
- continue;
- LastUDDist = DI->second;
- LastUDMI = UDMI;
+ if (Seens.insert(UDMI))
+ Refs.push_back(std::make_pair(UDMI, DI->second));
}
- if (LastUDMI) {
+ if (Refs.empty())
+ return;
+ std::sort(Refs.begin(), Refs.end(), RefSorter());
+
+ while (!Refs.empty()) {
+ MachineInstr *LastUDMI = Refs.back().first;
+ Refs.pop_back();
+
MachineOperand *LastUD = NULL;
for (unsigned i = 0, e = LastUDMI->getNumOperands(); i != e; ++i) {
MachineOperand &MO = LastUDMI->getOperand(i);
@@ -1339,14 +1353,24 @@
if (!LastUD || (LastUD->isUse() && MO.isDef()))
LastUD = &MO;
if (LastUDMI->isRegTiedToDefOperand(i))
- return;
+ break;
}
- if (LastUD->isDef())
- LastUD->setIsDead();
- else {
+ if (LastUD->isDef()) {
+ // If the instruction has no side effect, delete it and propagate
+ // backward further. Otherwise, mark is dead and we are done.
+ const TargetInstrDesc &TID = LastUDMI->getDesc();
+ if (TID.mayStore() || TID.isCall() || TID.isTerminator() ||
+ TID.hasUnmodeledSideEffects()) {
+ LastUD->setIsDead();
+ break;
+ }
+ VRM.RemoveMachineInstrFromMaps(LastUDMI);
+ MBB->erase(LastUDMI);
+ } else {
LastUD->setIsKill();
RegKills.set(Reg);
KillOps[Reg] = LastUD;
+ break;
}
}
}
@@ -2027,7 +2051,7 @@
TRI->isSubRegister(KillRegs[0], Dst) ||
TRI->isSuperRegister(KillRegs[0], Dst));
// Last def is now dead.
- TransferDeadness(&MBB, Dist, Src, RegKills, KillOps);
+ TransferDeadness(&MBB, Dist, Src, RegKills, KillOps, VRM);
}
VRM.RemoveMachineInstrFromMaps(&MI);
MBB.erase(&MI);
Modified: llvm/trunk/test/CodeGen/X86/2007-03-01-SpillerCrash.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2007-03-01-SpillerCrash.ll?rev=71606&r1=71605&r2=71606&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/2007-03-01-SpillerCrash.ll (original)
+++ llvm/trunk/test/CodeGen/X86/2007-03-01-SpillerCrash.ll Tue May 12 18:07:00 2009
@@ -1,4 +1,5 @@
; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin8 -mattr=+sse2
+; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin8 -mattr=+sse2 | not grep movhlps
define void @test() nounwind {
test.exit:
More information about the llvm-commits
mailing list