mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-24 08:33:39 +00:00
Use the LiveVariables information to efficiently get local kills. This
removes the largest scaling problem in the test cases from PR13225 when ASan is switched to insert basic blocks in the natural CFG order. It may also solve some scaling problems for more normal code with large numbers of basic blocks and variables. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@160194 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
b76fb96cd6
commit
5583415909
@ -483,32 +483,6 @@ static bool isTwoAddrUse(MachineInstr &MI, unsigned Reg, unsigned &DstReg) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// findLocalKill - Look for an instruction below MI in the MBB that kills the
|
|
||||||
/// specified register. Returns null if there are any other Reg use between the
|
|
||||||
/// instructions.
|
|
||||||
static
|
|
||||||
MachineInstr *findLocalKill(unsigned Reg, MachineBasicBlock *MBB,
|
|
||||||
MachineInstr *MI, MachineRegisterInfo *MRI,
|
|
||||||
DenseMap<MachineInstr*, unsigned> &DistanceMap) {
|
|
||||||
MachineInstr *KillMI = 0;
|
|
||||||
for (MachineRegisterInfo::use_nodbg_iterator
|
|
||||||
UI = MRI->use_nodbg_begin(Reg),
|
|
||||||
UE = MRI->use_nodbg_end(); UI != UE; ++UI) {
|
|
||||||
MachineInstr *UseMI = &*UI;
|
|
||||||
if (UseMI == MI || UseMI->getParent() != MBB)
|
|
||||||
continue;
|
|
||||||
if (DistanceMap.count(UseMI))
|
|
||||||
continue;
|
|
||||||
if (!UI.getOperand().isKill())
|
|
||||||
return 0;
|
|
||||||
if (KillMI)
|
|
||||||
return 0; // -O0 kill markers cannot be trusted?
|
|
||||||
KillMI = UseMI;
|
|
||||||
}
|
|
||||||
|
|
||||||
return KillMI;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// findOnlyInterestingUse - Given a register, if has a single in-basic block
|
/// findOnlyInterestingUse - Given a register, if has a single in-basic block
|
||||||
/// use, return the use instruction if it's a copy or a two-address use.
|
/// use, return the use instruction if it's a copy or a two-address use.
|
||||||
static
|
static
|
||||||
@ -905,13 +879,18 @@ TwoAddressInstructionPass::RescheduleMIBelowKill(MachineBasicBlock *MBB,
|
|||||||
MachineBasicBlock::iterator &mi,
|
MachineBasicBlock::iterator &mi,
|
||||||
MachineBasicBlock::iterator &nmi,
|
MachineBasicBlock::iterator &nmi,
|
||||||
unsigned Reg) {
|
unsigned Reg) {
|
||||||
|
// Bail immediately if we don't have LV available. We use it to find kills
|
||||||
|
// efficiently.
|
||||||
|
if (!LV)
|
||||||
|
return false;
|
||||||
|
|
||||||
MachineInstr *MI = &*mi;
|
MachineInstr *MI = &*mi;
|
||||||
DenseMap<MachineInstr*, unsigned>::iterator DI = DistanceMap.find(MI);
|
DenseMap<MachineInstr*, unsigned>::iterator DI = DistanceMap.find(MI);
|
||||||
if (DI == DistanceMap.end())
|
if (DI == DistanceMap.end())
|
||||||
// Must be created from unfolded load. Don't waste time trying this.
|
// Must be created from unfolded load. Don't waste time trying this.
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
MachineInstr *KillMI = findLocalKill(Reg, MBB, mi, MRI, DistanceMap);
|
MachineInstr *KillMI = LV->getVarInfo(Reg).findKill(MBB);
|
||||||
if (!KillMI || KillMI->isCopy() || KillMI->isCopyLike())
|
if (!KillMI || KillMI->isCopy() || KillMI->isCopyLike())
|
||||||
// Don't mess with copies, they may be coalesced later.
|
// Don't mess with copies, they may be coalesced later.
|
||||||
return false;
|
return false;
|
||||||
@ -1012,19 +991,9 @@ TwoAddressInstructionPass::RescheduleMIBelowKill(MachineBasicBlock *MBB,
|
|||||||
MBB->splice(KillPos, MBB, From, To);
|
MBB->splice(KillPos, MBB, From, To);
|
||||||
DistanceMap.erase(DI);
|
DistanceMap.erase(DI);
|
||||||
|
|
||||||
if (LV) {
|
|
||||||
// Update live variables
|
// Update live variables
|
||||||
LV->removeVirtualRegisterKilled(Reg, KillMI);
|
LV->removeVirtualRegisterKilled(Reg, KillMI);
|
||||||
LV->addVirtualRegisterKilled(Reg, MI);
|
LV->addVirtualRegisterKilled(Reg, MI);
|
||||||
} else {
|
|
||||||
for (unsigned i = 0, e = KillMI->getNumOperands(); i != e; ++i) {
|
|
||||||
MachineOperand &MO = KillMI->getOperand(i);
|
|
||||||
if (!MO.isReg() || !MO.isUse() || MO.getReg() != Reg)
|
|
||||||
continue;
|
|
||||||
MO.setIsKill(false);
|
|
||||||
}
|
|
||||||
MI->addRegisterKilled(Reg, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1061,13 +1030,18 @@ TwoAddressInstructionPass::RescheduleKillAboveMI(MachineBasicBlock *MBB,
|
|||||||
MachineBasicBlock::iterator &mi,
|
MachineBasicBlock::iterator &mi,
|
||||||
MachineBasicBlock::iterator &nmi,
|
MachineBasicBlock::iterator &nmi,
|
||||||
unsigned Reg) {
|
unsigned Reg) {
|
||||||
|
// Bail immediately if we don't have LV available. We use it to find kills
|
||||||
|
// efficiently.
|
||||||
|
if (!LV)
|
||||||
|
return false;
|
||||||
|
|
||||||
MachineInstr *MI = &*mi;
|
MachineInstr *MI = &*mi;
|
||||||
DenseMap<MachineInstr*, unsigned>::iterator DI = DistanceMap.find(MI);
|
DenseMap<MachineInstr*, unsigned>::iterator DI = DistanceMap.find(MI);
|
||||||
if (DI == DistanceMap.end())
|
if (DI == DistanceMap.end())
|
||||||
// Must be created from unfolded load. Don't waste time trying this.
|
// Must be created from unfolded load. Don't waste time trying this.
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
MachineInstr *KillMI = findLocalKill(Reg, MBB, mi, MRI, DistanceMap);
|
MachineInstr *KillMI = LV->getVarInfo(Reg).findKill(MBB);
|
||||||
if (!KillMI || KillMI->isCopy() || KillMI->isCopyLike())
|
if (!KillMI || KillMI->isCopy() || KillMI->isCopyLike())
|
||||||
// Don't mess with copies, they may be coalesced later.
|
// Don't mess with copies, they may be coalesced later.
|
||||||
return false;
|
return false;
|
||||||
@ -1165,19 +1139,10 @@ TwoAddressInstructionPass::RescheduleKillAboveMI(MachineBasicBlock *MBB,
|
|||||||
nmi = llvm::prior(InsertPos); // Backtrack so we process the moved instr.
|
nmi = llvm::prior(InsertPos); // Backtrack so we process the moved instr.
|
||||||
DistanceMap.erase(DI);
|
DistanceMap.erase(DI);
|
||||||
|
|
||||||
if (LV) {
|
|
||||||
// Update live variables
|
// Update live variables
|
||||||
LV->removeVirtualRegisterKilled(Reg, KillMI);
|
LV->removeVirtualRegisterKilled(Reg, KillMI);
|
||||||
LV->addVirtualRegisterKilled(Reg, MI);
|
LV->addVirtualRegisterKilled(Reg, MI);
|
||||||
} else {
|
|
||||||
for (unsigned i = 0, e = KillMI->getNumOperands(); i != e; ++i) {
|
|
||||||
MachineOperand &MO = KillMI->getOperand(i);
|
|
||||||
if (!MO.isReg() || !MO.isUse() || MO.getReg() != Reg)
|
|
||||||
continue;
|
|
||||||
MO.setIsKill(false);
|
|
||||||
}
|
|
||||||
MI->addRegisterKilled(Reg, 0);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user