mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-26 07:24:25 +00:00
Teach TransferDeadness to delete truly dead instructions if they do not produce side effects.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@71606 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -350,29 +350,44 @@ unsigned RALinScan::attemptTrivialCoalescing(LiveInterval &cur, unsigned Reg) {
|
|||||||
if (!vni->def || vni->def == ~1U || vni->def == ~0U)
|
if (!vni->def || vni->def == ~1U || vni->def == ~0U)
|
||||||
return Reg;
|
return Reg;
|
||||||
MachineInstr *CopyMI = li_->getInstructionFromIndex(vni->def);
|
MachineInstr *CopyMI = li_->getInstructionFromIndex(vni->def);
|
||||||
unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
|
unsigned SrcReg, DstReg, SrcSubReg, DstSubReg, PhysReg;
|
||||||
if (!CopyMI ||
|
if (!CopyMI ||
|
||||||
!tii_->isMoveInstr(*CopyMI, SrcReg, DstReg, SrcSubReg, DstSubReg))
|
!tii_->isMoveInstr(*CopyMI, SrcReg, DstReg, SrcSubReg, DstSubReg))
|
||||||
return Reg;
|
return Reg;
|
||||||
|
PhysReg = SrcReg;
|
||||||
if (TargetRegisterInfo::isVirtualRegister(SrcReg)) {
|
if (TargetRegisterInfo::isVirtualRegister(SrcReg)) {
|
||||||
if (!vrm_->isAssignedReg(SrcReg))
|
if (!vrm_->isAssignedReg(SrcReg))
|
||||||
return Reg;
|
return Reg;
|
||||||
else
|
PhysReg = vrm_->getPhys(SrcReg);
|
||||||
SrcReg = vrm_->getPhys(SrcReg);
|
|
||||||
}
|
}
|
||||||
if (Reg == SrcReg)
|
if (Reg == PhysReg)
|
||||||
return Reg;
|
return Reg;
|
||||||
|
|
||||||
const TargetRegisterClass *RC = mri_->getRegClass(cur.reg);
|
const TargetRegisterClass *RC = mri_->getRegClass(cur.reg);
|
||||||
if (!RC->contains(SrcReg))
|
if (!RC->contains(PhysReg))
|
||||||
return Reg;
|
return Reg;
|
||||||
|
|
||||||
// Try to coalesce.
|
// Try to coalesce.
|
||||||
if (!li_->conflictsWithPhysRegDef(cur, *vrm_, SrcReg)) {
|
if (!li_->conflictsWithPhysRegDef(cur, *vrm_, PhysReg)) {
|
||||||
DOUT << "Coalescing: " << cur << " -> " << tri_->getName(SrcReg)
|
DOUT << "Coalescing: " << cur << " -> " << tri_->getName(PhysReg)
|
||||||
<< '\n';
|
<< '\n';
|
||||||
vrm_->clearVirt(cur.reg);
|
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;
|
++NumCoalesce;
|
||||||
return SrcReg;
|
return SrcReg;
|
||||||
}
|
}
|
||||||
|
@ -851,6 +851,14 @@ void AssignPhysToVirtReg(MachineInstr *MI, unsigned VirtReg, unsigned PhysReg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 //
|
// Local Spiller Implementation //
|
||||||
@ -1313,9 +1321,10 @@ private:
|
|||||||
/// removed. Find the last def or use and mark it as dead / kill.
|
/// removed. Find the last def or use and mark it as dead / kill.
|
||||||
void TransferDeadness(MachineBasicBlock *MBB, unsigned CurDist,
|
void TransferDeadness(MachineBasicBlock *MBB, unsigned CurDist,
|
||||||
unsigned Reg, BitVector &RegKills,
|
unsigned Reg, BitVector &RegKills,
|
||||||
std::vector<MachineOperand*> &KillOps) {
|
std::vector<MachineOperand*> &KillOps,
|
||||||
int LastUDDist = -1;
|
VirtRegMap &VRM) {
|
||||||
MachineInstr *LastUDMI = NULL;
|
SmallPtrSet<MachineInstr*, 4> Seens;
|
||||||
|
SmallVector<std::pair<MachineInstr*, int>,8> Refs;
|
||||||
for (MachineRegisterInfo::reg_iterator RI = RegInfo->reg_begin(Reg),
|
for (MachineRegisterInfo::reg_iterator RI = RegInfo->reg_begin(Reg),
|
||||||
RE = RegInfo->reg_end(); RI != RE; ++RI) {
|
RE = RegInfo->reg_end(); RI != RE; ++RI) {
|
||||||
MachineInstr *UDMI = &*RI;
|
MachineInstr *UDMI = &*RI;
|
||||||
@ -1324,13 +1333,18 @@ private:
|
|||||||
DenseMap<MachineInstr*, unsigned>::iterator DI = DistanceMap.find(UDMI);
|
DenseMap<MachineInstr*, unsigned>::iterator DI = DistanceMap.find(UDMI);
|
||||||
if (DI == DistanceMap.end() || DI->second > CurDist)
|
if (DI == DistanceMap.end() || DI->second > CurDist)
|
||||||
continue;
|
continue;
|
||||||
if ((int)DI->second < LastUDDist)
|
if (Seens.insert(UDMI))
|
||||||
continue;
|
Refs.push_back(std::make_pair(UDMI, DI->second));
|
||||||
LastUDDist = DI->second;
|
|
||||||
LastUDMI = UDMI;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
MachineOperand *LastUD = NULL;
|
||||||
for (unsigned i = 0, e = LastUDMI->getNumOperands(); i != e; ++i) {
|
for (unsigned i = 0, e = LastUDMI->getNumOperands(); i != e; ++i) {
|
||||||
MachineOperand &MO = LastUDMI->getOperand(i);
|
MachineOperand &MO = LastUDMI->getOperand(i);
|
||||||
@ -1339,14 +1353,24 @@ private:
|
|||||||
if (!LastUD || (LastUD->isUse() && MO.isDef()))
|
if (!LastUD || (LastUD->isUse() && MO.isDef()))
|
||||||
LastUD = &MO;
|
LastUD = &MO;
|
||||||
if (LastUDMI->isRegTiedToDefOperand(i))
|
if (LastUDMI->isRegTiedToDefOperand(i))
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
if (LastUD->isDef())
|
if (LastUD->isDef()) {
|
||||||
LastUD->setIsDead();
|
// If the instruction has no side effect, delete it and propagate
|
||||||
else {
|
// 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();
|
LastUD->setIsKill();
|
||||||
RegKills.set(Reg);
|
RegKills.set(Reg);
|
||||||
KillOps[Reg] = LastUD;
|
KillOps[Reg] = LastUD;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2027,7 +2051,7 @@ private:
|
|||||||
TRI->isSubRegister(KillRegs[0], Dst) ||
|
TRI->isSubRegister(KillRegs[0], Dst) ||
|
||||||
TRI->isSuperRegister(KillRegs[0], Dst));
|
TRI->isSuperRegister(KillRegs[0], Dst));
|
||||||
// Last def is now dead.
|
// Last def is now dead.
|
||||||
TransferDeadness(&MBB, Dist, Src, RegKills, KillOps);
|
TransferDeadness(&MBB, Dist, Src, RegKills, KillOps, VRM);
|
||||||
}
|
}
|
||||||
VRM.RemoveMachineInstrFromMaps(&MI);
|
VRM.RemoveMachineInstrFromMaps(&MI);
|
||||||
MBB.erase(&MI);
|
MBB.erase(&MI);
|
||||||
|
@ -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
|
||||||
|
; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin8 -mattr=+sse2 | not grep movhlps
|
||||||
|
|
||||||
define void @test() nounwind {
|
define void @test() nounwind {
|
||||||
test.exit:
|
test.exit:
|
||||||
|
Reference in New Issue
Block a user