1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 11:02:59 +02:00

[NFC] Extract LastSplitPoint computation from SplitAnalysis to a new class

InsertPointAnalysis.

Because both split and spill hoisting want to use LastSplitPoint computation
result, extract the LastSplitPoint computation from SplitAnalysis class which
also contains a bunch of other analysises only related to split.

Differential Revision: http://reviews.llvm.org/D20027.

llvm-svn: 269248
This commit is contained in:
Wei Mi 2016-05-11 22:28:29 +00:00
parent b8461809ec
commit ee383d9f9c
2 changed files with 128 additions and 91 deletions

View File

@ -37,6 +37,85 @@ STATISTIC(NumCopies, "Number of copies inserted for splitting");
STATISTIC(NumRemats, "Number of rematerialized defs for splitting");
STATISTIC(NumRepairs, "Number of invalid live ranges repaired");
//===----------------------------------------------------------------------===//
// Last Insert Point Analysis
//===----------------------------------------------------------------------===//
InsertPointAnalysis::InsertPointAnalysis(const LiveIntervals &lis,
unsigned BBNum)
: LIS(lis), CurLI(nullptr), LastInsertPoint(BBNum) {}
SlotIndex
InsertPointAnalysis::computeLastInsertPoint(const MachineBasicBlock &MBB) {
unsigned Num = MBB.getNumber();
std::pair<SlotIndex, SlotIndex> &LIP = LastInsertPoint[Num];
SlotIndex MBBEnd = LIS.getMBBEndIdx(&MBB);
SmallVector<const MachineBasicBlock *, 1> EHPadSucessors;
for (const MachineBasicBlock *SMBB : MBB.successors())
if (SMBB->isEHPad())
EHPadSucessors.push_back(SMBB);
// Compute insert points on the first call. The pair is independent of the
// current live interval.
if (!LIP.first.isValid()) {
MachineBasicBlock::const_iterator FirstTerm = MBB.getFirstTerminator();
if (FirstTerm == MBB.end())
LIP.first = MBBEnd;
else
LIP.first = LIS.getInstructionIndex(*FirstTerm);
// If there is a landing pad successor, also find the call instruction.
if (EHPadSucessors.empty())
return LIP.first;
// There may not be a call instruction (?) in which case we ignore LPad.
LIP.second = LIP.first;
for (MachineBasicBlock::const_iterator I = MBB.end(), E = MBB.begin();
I != E;) {
--I;
if (I->isCall()) {
LIP.second = LIS.getInstructionIndex(*I);
break;
}
}
}
// If CurLI is live into a landing pad successor, move the last insert point
// back to the call that may throw.
if (!LIP.second)
return LIP.first;
assert(CurLI && "CurLI not being set");
if (none_of(EHPadSucessors, [&](const MachineBasicBlock *EHPad) {
return LIS.isLiveInToMBB(*CurLI, EHPad);
}))
return LIP.first;
// Find the value leaving MBB.
const VNInfo *VNI = CurLI->getVNInfoBefore(MBBEnd);
if (!VNI)
return LIP.first;
// If the value leaving MBB was defined after the call in MBB, it can't
// really be live-in to the landing pad. This can happen if the landing pad
// has a PHI, and this register is undef on the exceptional edge.
// <rdar://problem/10664933>
if (!SlotIndex::isEarlierInstr(VNI->def, LIP.second) && VNI->def < MBBEnd)
return LIP.first;
// Value is properly live-in to the landing pad.
// Only allow inserts before the call.
return LIP.second;
}
MachineBasicBlock::iterator
InsertPointAnalysis::getLastInsertPointIter(MachineBasicBlock &MBB) {
SlotIndex LIP = getLastInsertPoint(MBB);
if (LIP == LIS.getMBBEndIdx(&MBB))
return MBB.end();
return LIS.getInstructionFromIndex(LIP);
}
//===----------------------------------------------------------------------===//
// Split Analysis
//===----------------------------------------------------------------------===//
@ -45,7 +124,7 @@ SplitAnalysis::SplitAnalysis(const VirtRegMap &vrm, const LiveIntervals &lis,
const MachineLoopInfo &mli)
: MF(vrm.getMachineFunction()), VRM(vrm), LIS(lis), Loops(mli),
TII(*MF.getSubtarget().getInstrInfo()), CurLI(nullptr),
LastSplitPoint(MF.getNumBlockIDs()) {}
IPA(lis, MF.getNumBlockIDs()) {}
void SplitAnalysis::clear() {
UseSlots.clear();
@ -55,75 +134,6 @@ void SplitAnalysis::clear() {
DidRepairRange = false;
}
SlotIndex SplitAnalysis::computeLastSplitPoint(unsigned Num) {
const MachineBasicBlock *MBB = MF.getBlockNumbered(Num);
std::pair<SlotIndex, SlotIndex> &LSP = LastSplitPoint[Num];
SlotIndex MBBEnd = LIS.getMBBEndIdx(MBB);
SmallVector<const MachineBasicBlock *, 1> EHPadSucessors;
for (const MachineBasicBlock *SMBB : MBB->successors())
if (SMBB->isEHPad())
EHPadSucessors.push_back(SMBB);
// Compute split points on the first call. The pair is independent of the
// current live interval.
if (!LSP.first.isValid()) {
MachineBasicBlock::const_iterator FirstTerm = MBB->getFirstTerminator();
if (FirstTerm == MBB->end())
LSP.first = MBBEnd;
else
LSP.first = LIS.getInstructionIndex(*FirstTerm);
// If there is a landing pad successor, also find the call instruction.
if (EHPadSucessors.empty())
return LSP.first;
// There may not be a call instruction (?) in which case we ignore LPad.
LSP.second = LSP.first;
for (MachineBasicBlock::const_iterator I = MBB->end(), E = MBB->begin();
I != E;) {
--I;
if (I->isCall()) {
LSP.second = LIS.getInstructionIndex(*I);
break;
}
}
}
// If CurLI is live into a landing pad successor, move the last split point
// back to the call that may throw.
if (!LSP.second)
return LSP.first;
if (none_of(EHPadSucessors, [&](const MachineBasicBlock *EHPad) {
return LIS.isLiveInToMBB(*CurLI, EHPad);
}))
return LSP.first;
// Find the value leaving MBB.
const VNInfo *VNI = CurLI->getVNInfoBefore(MBBEnd);
if (!VNI)
return LSP.first;
// If the value leaving MBB was defined after the call in MBB, it can't
// really be live-in to the landing pad. This can happen if the landing pad
// has a PHI, and this register is undef on the exceptional edge.
// <rdar://problem/10664933>
if (!SlotIndex::isEarlierInstr(VNI->def, LSP.second) && VNI->def < MBBEnd)
return LSP.first;
// Value is properly live-in to the landing pad.
// Only allow splits before the call.
return LSP.second;
}
MachineBasicBlock::iterator
SplitAnalysis::getLastSplitPointIter(MachineBasicBlock *MBB) {
SlotIndex LSP = getLastSplitPoint(MBB->getNumber());
if (LSP == LIS.getMBBEndIdx(MBB))
return MBB->end();
return LIS.getInstructionFromIndex(LSP);
}
/// analyzeUses - Count instructions, basic blocks, and loops using CurLI.
void SplitAnalysis::analyzeUses() {
assert(UseSlots.empty() && "Call clear first");
@ -318,6 +328,7 @@ bool SplitAnalysis::isOriginalEndpoint(SlotIndex Idx) const {
void SplitAnalysis::analyze(const LiveInterval *li) {
clear();
CurLI = li;
IPA.setInterval(li);
analyzeUses();
}

View File

@ -38,6 +38,42 @@ class VirtRegMap;
class VNInfo;
class raw_ostream;
/// Determines the latest safe point in a block in which we can insert a split,
/// spill or other instruction related with CurLI.
class LLVM_LIBRARY_VISIBILITY InsertPointAnalysis {
private:
const LiveIntervals &LIS;
/// Current LiveInterval for which to insert split or spill.
const LiveInterval *CurLI;
/// Last legal insert point in each basic block in the current function.
/// The first entry is the first terminator, the second entry is the
/// last valid point to insert a split or spill for a variable that is
/// live into a landing pad successor.
SmallVector<std::pair<SlotIndex, SlotIndex>, 8> LastInsertPoint;
SlotIndex computeLastInsertPoint(const MachineBasicBlock &MBB);
public:
InsertPointAnalysis(const LiveIntervals &lis, unsigned BBNum);
void setInterval(const LiveInterval *LI) { CurLI = LI; }
/// Return the base index of the last valid insert point in \pMBB.
SlotIndex getLastInsertPoint(const MachineBasicBlock &MBB) {
unsigned Num = MBB.getNumber();
// Inline the common simple case.
if (LastInsertPoint[Num].first.isValid() &&
!LastInsertPoint[Num].second.isValid())
return LastInsertPoint[Num].first;
return computeLastInsertPoint(MBB);
}
/// Returns the last insert point as an iterator.
MachineBasicBlock::iterator getLastInsertPointIter(MachineBasicBlock &);
};
/// SplitAnalysis - Analyze a LiveInterval, looking for live range splitting
/// opportunities.
class LLVM_LIBRARY_VISIBILITY SplitAnalysis {
@ -84,15 +120,12 @@ private:
// Current live interval.
const LiveInterval *CurLI;
/// Insert Point Analysis.
InsertPointAnalysis IPA;
// Sorted slot indexes of using instructions.
SmallVector<SlotIndex, 8> UseSlots;
/// LastSplitPoint - Last legal split point in each basic block in the current
/// function. The first entry is the first terminator, the second entry is the
/// last valid split point for a variable that is live in to a landing pad
/// successor.
SmallVector<std::pair<SlotIndex, SlotIndex>, 8> LastSplitPoint;
/// UseBlocks - Blocks where CurLI has uses.
SmallVector<BlockInfo, 8> UseBlocks;
@ -109,8 +142,6 @@ private:
/// DidRepairRange - analyze was forced to shrinkToUses().
bool DidRepairRange;
SlotIndex computeLastSplitPoint(unsigned Num);
// Sumarize statistics by counting instructions using CurLI.
void analyzeUses();
@ -137,19 +168,6 @@ public:
/// getParent - Return the last analyzed interval.
const LiveInterval &getParent() const { return *CurLI; }
/// getLastSplitPoint - Return the base index of the last valid split point
/// in the basic block numbered Num.
SlotIndex getLastSplitPoint(unsigned Num) {
// Inline the common simple case.
if (LastSplitPoint[Num].first.isValid() &&
!LastSplitPoint[Num].second.isValid())
return LastSplitPoint[Num].first;
return computeLastSplitPoint(Num);
}
/// getLastSplitPointIter - Returns the last split point as an iterator.
MachineBasicBlock::iterator getLastSplitPointIter(MachineBasicBlock*);
/// isOriginalEndpoint - Return true if the original live range was killed or
/// (re-)defined at Idx. Idx should be the 'def' slot for a normal kill/def,
/// and 'use' for an early-clobber def.
@ -195,6 +213,14 @@ public:
/// @param BI The block to be isolated.
/// @param SingleInstrs True when single instructions should be isolated.
bool shouldSplitSingleBlock(const BlockInfo &BI, bool SingleInstrs) const;
SlotIndex getLastSplitPoint(unsigned Num) {
return IPA.getLastInsertPoint(*MF.getBlockNumbered(Num));
}
MachineBasicBlock::iterator getLastSplitPointIter(MachineBasicBlock *BB) {
return IPA.getLastInsertPointIter(*BB);
}
};