forked from OSchip/llvm-project
[LiveVariables] Improve isLiveOut runtime performances. NFC.
On large goto table based interpreters, where phi nodes can have (very) large fan-ins, isLiveOut exhibited poor performances: about 40% of the full codegen time was spent in PHIElim, sorting MachineBasicBlock addresses. This patch improve the performances for such cases, and does not show compile time regressions on the LNT, at bootstrap (llvm+clang+lldb) or any other benchmarks we have in-house. llvm-svn: 239510
This commit is contained in:
parent
5965680d53
commit
af37ad19a9
|
@ -738,45 +738,22 @@ bool LiveVariables::VarInfo::isLiveIn(const MachineBasicBlock &MBB,
|
||||||
bool LiveVariables::isLiveOut(unsigned Reg, const MachineBasicBlock &MBB) {
|
bool LiveVariables::isLiveOut(unsigned Reg, const MachineBasicBlock &MBB) {
|
||||||
LiveVariables::VarInfo &VI = getVarInfo(Reg);
|
LiveVariables::VarInfo &VI = getVarInfo(Reg);
|
||||||
|
|
||||||
|
SmallPtrSet<const MachineBasicBlock *, 8> Kills;
|
||||||
|
for (unsigned i = 0, e = VI.Kills.size(); i != e; ++i)
|
||||||
|
Kills.insert(VI.Kills[i]->getParent());
|
||||||
|
|
||||||
// Loop over all of the successors of the basic block, checking to see if
|
// Loop over all of the successors of the basic block, checking to see if
|
||||||
// the value is either live in the block, or if it is killed in the block.
|
// the value is either live in the block, or if it is killed in the block.
|
||||||
SmallVector<MachineBasicBlock*, 8> OpSuccBlocks;
|
for (const MachineBasicBlock *SuccMBB : MBB.successors()) {
|
||||||
for (MachineBasicBlock::const_succ_iterator SI = MBB.succ_begin(),
|
|
||||||
E = MBB.succ_end(); SI != E; ++SI) {
|
|
||||||
MachineBasicBlock *SuccMBB = *SI;
|
|
||||||
|
|
||||||
// Is it alive in this successor?
|
// Is it alive in this successor?
|
||||||
unsigned SuccIdx = SuccMBB->getNumber();
|
unsigned SuccIdx = SuccMBB->getNumber();
|
||||||
if (VI.AliveBlocks.test(SuccIdx))
|
if (VI.AliveBlocks.test(SuccIdx))
|
||||||
return true;
|
return true;
|
||||||
OpSuccBlocks.push_back(SuccMBB);
|
// Or is it live because there is a use in a successor that kills it?
|
||||||
|
if (Kills.count(SuccMBB))
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check to see if this value is live because there is a use in a successor
|
|
||||||
// that kills it.
|
|
||||||
switch (OpSuccBlocks.size()) {
|
|
||||||
case 1: {
|
|
||||||
MachineBasicBlock *SuccMBB = OpSuccBlocks[0];
|
|
||||||
for (unsigned i = 0, e = VI.Kills.size(); i != e; ++i)
|
|
||||||
if (VI.Kills[i]->getParent() == SuccMBB)
|
|
||||||
return true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 2: {
|
|
||||||
MachineBasicBlock *SuccMBB1 = OpSuccBlocks[0], *SuccMBB2 = OpSuccBlocks[1];
|
|
||||||
for (unsigned i = 0, e = VI.Kills.size(); i != e; ++i)
|
|
||||||
if (VI.Kills[i]->getParent() == SuccMBB1 ||
|
|
||||||
VI.Kills[i]->getParent() == SuccMBB2)
|
|
||||||
return true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
std::sort(OpSuccBlocks.begin(), OpSuccBlocks.end());
|
|
||||||
for (unsigned i = 0, e = VI.Kills.size(); i != e; ++i)
|
|
||||||
if (std::binary_search(OpSuccBlocks.begin(), OpSuccBlocks.end(),
|
|
||||||
VI.Kills[i]->getParent()))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue