mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-25 00:24:26 +00:00
Cache the fairly expensive last split point computation and provide a fast
inlined path for the common case. Most basic blocks don't contain a call that may throw, so the last split point os simply the first terminator. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@128874 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -305,6 +305,10 @@ public:
|
|||||||
/// it returns end()
|
/// it returns end()
|
||||||
iterator getFirstTerminator();
|
iterator getFirstTerminator();
|
||||||
|
|
||||||
|
const_iterator getFirstTerminator() const {
|
||||||
|
return const_cast<MachineBasicBlock*>(this)->getFirstTerminator();
|
||||||
|
}
|
||||||
|
|
||||||
/// getLastNonDebugInstr - returns an iterator to the last non-debug
|
/// getLastNonDebugInstr - returns an iterator to the last non-debug
|
||||||
/// instruction in the basic block, or end()
|
/// instruction in the basic block, or end()
|
||||||
iterator getLastNonDebugInstr();
|
iterator getLastNonDebugInstr();
|
||||||
|
@ -48,7 +48,8 @@ SplitAnalysis::SplitAnalysis(const VirtRegMap &vrm,
|
|||||||
LIS(lis),
|
LIS(lis),
|
||||||
Loops(mli),
|
Loops(mli),
|
||||||
TII(*MF.getTarget().getInstrInfo()),
|
TII(*MF.getTarget().getInstrInfo()),
|
||||||
CurLI(0) {}
|
CurLI(0),
|
||||||
|
LastSplitPoint(MF.getNumBlockIDs()) {}
|
||||||
|
|
||||||
void SplitAnalysis::clear() {
|
void SplitAnalysis::clear() {
|
||||||
UseSlots.clear();
|
UseSlots.clear();
|
||||||
@ -58,10 +59,39 @@ void SplitAnalysis::clear() {
|
|||||||
CurLI = 0;
|
CurLI = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SplitAnalysis::canAnalyzeBranch(const MachineBasicBlock *MBB) {
|
SlotIndex SplitAnalysis::computeLastSplitPoint(unsigned Num) {
|
||||||
MachineBasicBlock *T, *F;
|
const MachineBasicBlock *MBB = MF.getBlockNumbered(Num);
|
||||||
SmallVector<MachineOperand, 4> Cond;
|
const MachineBasicBlock *LPad = MBB->getLandingPadSuccessor();
|
||||||
return !TII.AnalyzeBranch(const_cast<MachineBasicBlock&>(*MBB), T, F, Cond);
|
std::pair<SlotIndex, SlotIndex> &LSP = LastSplitPoint[Num];
|
||||||
|
|
||||||
|
// 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 = LIS.getMBBEndIdx(MBB);
|
||||||
|
else
|
||||||
|
LSP.first = LIS.getInstructionIndex(FirstTerm);
|
||||||
|
|
||||||
|
// If there is a landing pad successor, also find the call instruction.
|
||||||
|
if (!LPad)
|
||||||
|
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 = FirstTerm, E = MBB->begin();
|
||||||
|
I != E; --I)
|
||||||
|
if (I->getDesc().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 (LPad && LSP.second.isValid() && !LIS.isLiveInToMBB(*CurLI, LPad))
|
||||||
|
return LSP.second;
|
||||||
|
else
|
||||||
|
return LSP.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// analyzeUses - Count instructions, basic blocks, and loops using CurLI.
|
/// analyzeUses - Count instructions, basic blocks, and loops using CurLI.
|
||||||
@ -125,11 +155,7 @@ bool SplitAnalysis::calcLiveBlockInfo() {
|
|||||||
// all successor blocks. If interference reaches LastSplitPoint, it is not
|
// all successor blocks. If interference reaches LastSplitPoint, it is not
|
||||||
// possible to insert a split or reload that makes CurLI live in the
|
// possible to insert a split or reload that makes CurLI live in the
|
||||||
// outgoing bundle.
|
// outgoing bundle.
|
||||||
MachineBasicBlock::iterator LSP = LIS.getLastSplitPoint(*CurLI, BI.MBB);
|
BI.LastSplitPoint = getLastSplitPoint(BI.MBB->getNumber());
|
||||||
if (LSP == BI.MBB->end())
|
|
||||||
BI.LastSplitPoint = Stop;
|
|
||||||
else
|
|
||||||
BI.LastSplitPoint = LIS.getInstructionIndex(LSP);
|
|
||||||
|
|
||||||
// LVI is the first live segment overlapping MBB.
|
// LVI is the first live segment overlapping MBB.
|
||||||
BI.LiveIn = LVI->start <= Start;
|
BI.LiveIn = LVI->start <= Start;
|
||||||
|
@ -93,16 +93,20 @@ private:
|
|||||||
// Current live interval.
|
// Current live interval.
|
||||||
const LiveInterval *CurLI;
|
const LiveInterval *CurLI;
|
||||||
|
|
||||||
|
/// 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;
|
||||||
|
|
||||||
|
SlotIndex computeLastSplitPoint(unsigned Num);
|
||||||
|
|
||||||
// Sumarize statistics by counting instructions using CurLI.
|
// Sumarize statistics by counting instructions using CurLI.
|
||||||
void analyzeUses();
|
void analyzeUses();
|
||||||
|
|
||||||
/// calcLiveBlockInfo - Compute per-block information about CurLI.
|
/// calcLiveBlockInfo - Compute per-block information about CurLI.
|
||||||
bool calcLiveBlockInfo();
|
bool calcLiveBlockInfo();
|
||||||
|
|
||||||
/// canAnalyzeBranch - Return true if MBB ends in a branch that can be
|
|
||||||
/// analyzed.
|
|
||||||
bool canAnalyzeBranch(const MachineBasicBlock *MBB);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SplitAnalysis(const VirtRegMap &vrm, const LiveIntervals &lis,
|
SplitAnalysis(const VirtRegMap &vrm, const LiveIntervals &lis,
|
||||||
const MachineLoopInfo &mli);
|
const MachineLoopInfo &mli);
|
||||||
@ -118,6 +122,16 @@ public:
|
|||||||
/// getParent - Return the last analyzed interval.
|
/// getParent - Return the last analyzed interval.
|
||||||
const LiveInterval &getParent() const { return *CurLI; }
|
const LiveInterval &getParent() const { return *CurLI; }
|
||||||
|
|
||||||
|
/// getLastSplitPoint - Return that 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);
|
||||||
|
}
|
||||||
|
|
||||||
/// hasUses - Return true if MBB has any uses of CurLI.
|
/// hasUses - Return true if MBB has any uses of CurLI.
|
||||||
bool hasUses(const MachineBasicBlock *MBB) const {
|
bool hasUses(const MachineBasicBlock *MBB) const {
|
||||||
return UsingBlocks.lookup(MBB);
|
return UsingBlocks.lookup(MBB);
|
||||||
|
Reference in New Issue
Block a user