mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-15 07:59:57 +00:00
[MachineSink] Improve runtime performance. NFC.
This patch fixes a compilation time issue, when MachineSink faces PHIs with a huge number of operands. This can happen for example in goto table based interpreters, where some basic blocks can have several of those PHIs, each one with several hundreds operands. MachineSink was spending a significant time re-building and re-sorting the list of successors of the current MachineBasicBlock. The computing and sorting of the current MachineBasicBlock successors is now cached. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239720 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
7a1e93493d
commit
981ffd1bc4
@ -73,6 +73,11 @@ namespace {
|
||||
|
||||
SparseBitVector<> RegsToClearKillFlags;
|
||||
|
||||
// Cache all successors to a MachineBasicBlock, sorted by frequency info and
|
||||
// loop depth. AllSuccessors is lazily populated.
|
||||
std::map<MachineBasicBlock *, SmallVector<MachineBasicBlock *, 4>>
|
||||
AllSuccessors;
|
||||
|
||||
public:
|
||||
static char ID; // Pass identification
|
||||
MachineSinking() : MachineFunctionPass(ID) {
|
||||
@ -132,6 +137,9 @@ namespace {
|
||||
|
||||
bool PerformTrivialForwardCoalescing(MachineInstr *MI,
|
||||
MachineBasicBlock *MBB);
|
||||
|
||||
SmallVector<MachineBasicBlock *, 4> &
|
||||
GetAllSortedSuccessors(MachineInstr *MI, MachineBasicBlock *MBB);
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
@ -269,9 +277,8 @@ bool MachineSinking::runOnMachineFunction(MachineFunction &MF) {
|
||||
// Process all basic blocks.
|
||||
CEBCandidates.clear();
|
||||
ToSplit.clear();
|
||||
for (MachineFunction::iterator I = MF.begin(), E = MF.end();
|
||||
I != E; ++I)
|
||||
MadeChange |= ProcessBlock(*I);
|
||||
for (auto &MBB: MF)
|
||||
MadeChange |= ProcessBlock(MBB);
|
||||
|
||||
// If we have anything we marked as toSplit, split it now.
|
||||
for (auto &Pair : ToSplit) {
|
||||
@ -310,6 +317,9 @@ bool MachineSinking::ProcessBlock(MachineBasicBlock &MBB) {
|
||||
|
||||
bool MadeChange = false;
|
||||
|
||||
// MBB changed, reset all cached information.
|
||||
AllSuccessors.clear();
|
||||
|
||||
// Walk the basic block bottom-up. Remember if we saw a store.
|
||||
MachineBasicBlock::iterator I = MBB.end();
|
||||
--I;
|
||||
@ -522,6 +532,51 @@ bool MachineSinking::isProfitableToSinkTo(unsigned Reg, MachineInstr *MI,
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Get the sorted sequence of successors for this MachineBasicBlock, possibly
|
||||
/// computing it if it was not already cached.
|
||||
SmallVector<MachineBasicBlock *, 4> &
|
||||
MachineSinking::GetAllSortedSuccessors(MachineInstr *MI, MachineBasicBlock *MBB) {
|
||||
|
||||
// Do we have the sorted successors in cache ?
|
||||
auto Succs = AllSuccessors.find(MBB);
|
||||
if (Succs != AllSuccessors.end())
|
||||
return Succs->second;
|
||||
|
||||
SmallVector<MachineBasicBlock *, 4> AllSuccs(MBB->succ_begin(),
|
||||
MBB->succ_end());
|
||||
|
||||
// Handle cases where sinking can happen but where the sink point isn't a
|
||||
// successor. For example:
|
||||
//
|
||||
// x = computation
|
||||
// if () {} else {}
|
||||
// use x
|
||||
//
|
||||
const std::vector<MachineDomTreeNode *> &Children =
|
||||
DT->getNode(MBB)->getChildren();
|
||||
for (const auto &DTChild : Children)
|
||||
// DomTree children of MBB that have MBB as immediate dominator are added.
|
||||
if (DTChild->getIDom()->getBlock() == MI->getParent() &&
|
||||
// Skip MBBs already added to the AllSuccs vector above.
|
||||
!MBB->isSuccessor(DTChild->getBlock()))
|
||||
AllSuccs.push_back(DTChild->getBlock());
|
||||
|
||||
// Sort Successors according to their loop depth or block frequency info.
|
||||
std::stable_sort(
|
||||
AllSuccs.begin(), AllSuccs.end(),
|
||||
[this](const MachineBasicBlock *L, const MachineBasicBlock *R) {
|
||||
uint64_t LHSFreq = MBFI ? MBFI->getBlockFreq(L).getFrequency() : 0;
|
||||
uint64_t RHSFreq = MBFI ? MBFI->getBlockFreq(R).getFrequency() : 0;
|
||||
bool HasBlockFreq = LHSFreq != 0 && RHSFreq != 0;
|
||||
return HasBlockFreq ? LHSFreq < RHSFreq
|
||||
: LI->getLoopDepth(L) < LI->getLoopDepth(R);
|
||||
});
|
||||
|
||||
auto it = AllSuccessors.insert(std::make_pair(MBB, AllSuccs));
|
||||
|
||||
return it.first->second;
|
||||
}
|
||||
|
||||
/// FindSuccToSinkTo - Find a successor to sink this instruction to.
|
||||
MachineBasicBlock *MachineSinking::FindSuccToSinkTo(MachineInstr *MI,
|
||||
MachineBasicBlock *MBB,
|
||||
@ -579,38 +634,7 @@ MachineBasicBlock *MachineSinking::FindSuccToSinkTo(MachineInstr *MI,
|
||||
// we should sink to. If we have reliable block frequency information
|
||||
// (frequency != 0) available, give successors with smaller frequencies
|
||||
// higher priority, otherwise prioritize smaller loop depths.
|
||||
SmallVector<MachineBasicBlock*, 4> Succs(MBB->succ_begin(),
|
||||
MBB->succ_end());
|
||||
|
||||
// Handle cases where sinking can happen but where the sink point isn't a
|
||||
// successor. For example:
|
||||
//
|
||||
// x = computation
|
||||
// if () {} else {}
|
||||
// use x
|
||||
//
|
||||
const std::vector<MachineDomTreeNode *> &Children =
|
||||
DT->getNode(MBB)->getChildren();
|
||||
for (const auto &DTChild : Children)
|
||||
// DomTree children of MBB that have MBB as immediate dominator are added.
|
||||
if (DTChild->getIDom()->getBlock() == MI->getParent() &&
|
||||
// Skip MBBs already added to the Succs vector above.
|
||||
!MBB->isSuccessor(DTChild->getBlock()))
|
||||
Succs.push_back(DTChild->getBlock());
|
||||
|
||||
// Sort Successors according to their loop depth or block frequency info.
|
||||
std::stable_sort(
|
||||
Succs.begin(), Succs.end(),
|
||||
[this](const MachineBasicBlock *L, const MachineBasicBlock *R) {
|
||||
uint64_t LHSFreq = MBFI ? MBFI->getBlockFreq(L).getFrequency() : 0;
|
||||
uint64_t RHSFreq = MBFI ? MBFI->getBlockFreq(R).getFrequency() : 0;
|
||||
bool HasBlockFreq = LHSFreq != 0 && RHSFreq != 0;
|
||||
return HasBlockFreq ? LHSFreq < RHSFreq
|
||||
: LI->getLoopDepth(L) < LI->getLoopDepth(R);
|
||||
});
|
||||
for (SmallVectorImpl<MachineBasicBlock *>::iterator SI = Succs.begin(),
|
||||
E = Succs.end(); SI != E; ++SI) {
|
||||
MachineBasicBlock *SuccBlock = *SI;
|
||||
for (MachineBasicBlock *SuccBlock : GetAllSortedSuccessors(MI, MBB)) {
|
||||
bool LocalUse = false;
|
||||
if (AllUsesDominatedByBlock(Reg, SuccBlock, MBB,
|
||||
BreakPHIEdge, LocalUse)) {
|
||||
|
Loading…
Reference in New Issue
Block a user