mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01: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:
parent
b8461809ec
commit
ee383d9f9c
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user