aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2011-03-03 03:41:29 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2011-03-03 03:41:29 +0000
commit36d61863bc83bd2301e0224adc560098b35ec0dc (patch)
treef263712c35c5e76d30493c5b80e9bfe9175d2099 /lib/CodeGen
parentf27a40a9717c019fd07990483fb475b544bc895e (diff)
downloadexternal_llvm-36d61863bc83bd2301e0224adc560098b35ec0dc.zip
external_llvm-36d61863bc83bd2301e0224adc560098b35ec0dc.tar.gz
external_llvm-36d61863bc83bd2301e0224adc560098b35ec0dc.tar.bz2
Cache basic block bounds instead of asking SlotIndexes::getMBBRange all the time.
This speeds up the greedy register allocator by 15%. DenseMap is not as fast as one might hope. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@126921 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/RegAllocGreedy.cpp69
-rw-r--r--lib/CodeGen/SplitKit.cpp21
-rw-r--r--lib/CodeGen/SplitKit.h2
3 files changed, 42 insertions, 50 deletions
diff --git a/lib/CodeGen/RegAllocGreedy.cpp b/lib/CodeGen/RegAllocGreedy.cpp
index ea20ae0..cbecc4b 100644
--- a/lib/CodeGen/RegAllocGreedy.cpp
+++ b/lib/CodeGen/RegAllocGreedy.cpp
@@ -473,19 +473,17 @@ float RAGreedy::calcInterferenceInfo(LiveInterval &VirtReg, unsigned PhysReg) {
for (unsigned i = 0, e = SA->LiveBlocks.size(); i != e; ++i) {
SplitAnalysis::BlockInfo &BI = SA->LiveBlocks[i];
SpillPlacement::BlockConstraint &BC = SpillConstraints[i];
- SlotIndex Start, Stop;
- tie(Start, Stop) = Indexes->getMBBRange(BI.MBB);
// Skip interference-free blocks.
- if (IntI.start() >= Stop)
+ if (IntI.start() >= BI.Stop)
continue;
// Is the interference live-in?
if (BI.LiveIn) {
- IntI.advanceTo(Start);
+ IntI.advanceTo(BI.Start);
if (!IntI.valid())
break;
- if (IntI.start() <= Start)
+ if (IntI.start() <= BI.Start)
BC.Entry = SpillPlacement::MustSpill;
}
@@ -495,7 +493,7 @@ float RAGreedy::calcInterferenceInfo(LiveInterval &VirtReg, unsigned PhysReg) {
IntI.advanceTo(BI.LastSplitPoint.getPrevSlot());
if (!IntI.valid())
break;
- if (IntI.start() < Stop)
+ if (IntI.start() < BI.Stop)
BC.Exit = SpillPlacement::MustSpill;
}
}
@@ -505,20 +503,18 @@ float RAGreedy::calcInterferenceInfo(LiveInterval &VirtReg, unsigned PhysReg) {
for (unsigned i = 0, e = SA->LiveBlocks.size(); i != e; ++i) {
SplitAnalysis::BlockInfo &BI = SA->LiveBlocks[i];
SpillPlacement::BlockConstraint &BC = SpillConstraints[i];
- SlotIndex Start, Stop;
- tie(Start, Stop) = Indexes->getMBBRange(BI.MBB);
// Skip interference-free blocks.
- if (IntI.start() >= Stop)
+ if (IntI.start() >= BI.Stop)
continue;
// Handle transparent blocks with interference separately.
// Transparent blocks never incur any fixed cost.
if (BI.LiveThrough && !BI.Uses) {
- IntI.advanceTo(Start);
+ IntI.advanceTo(BI.Start);
if (!IntI.valid())
break;
- if (IntI.start() >= Stop)
+ if (IntI.start() >= BI.Stop)
continue;
if (BC.Entry != SpillPlacement::MustSpill)
@@ -534,7 +530,7 @@ float RAGreedy::calcInterferenceInfo(LiveInterval &VirtReg, unsigned PhysReg) {
// Check interference on entry.
if (BI.LiveIn && BC.Entry != SpillPlacement::MustSpill) {
- IntI.advanceTo(Start);
+ IntI.advanceTo(BI.Start);
if (!IntI.valid())
break;
// Not live in, but before the first use.
@@ -575,7 +571,7 @@ float RAGreedy::calcInterferenceInfo(LiveInterval &VirtReg, unsigned PhysReg) {
IntI.advanceTo(BI.LastUse);
if (!IntI.valid())
break;
- if (IntI.start() < Stop) {
+ if (IntI.start() < BI.Stop) {
BC.Exit = SpillPlacement::PrefSpill;
// Avoid splitting twice in the same block.
if (!BI.LiveThrough && !SA->isOriginalEndpoint(BI.Def))
@@ -668,18 +664,17 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg,
for (unsigned i = 0, e = SA->LiveBlocks.size(); i != e; ++i) {
const SplitAnalysis::BlockInfo &BI = SA->LiveBlocks[i];
IndexPair &IP = InterferenceRanges[i];
- SlotIndex Start, Stop;
- tie(Start, Stop) = Indexes->getMBBRange(BI.MBB);
+
// Skip interference-free blocks.
- if (IntI.start() >= Stop)
+ if (IntI.start() >= BI.Stop)
continue;
// First interference in block.
if (BI.LiveIn) {
- IntI.advanceTo(Start);
+ IntI.advanceTo(BI.Start);
if (!IntI.valid())
break;
- if (IntI.start() >= Stop)
+ if (IntI.start() >= BI.Stop)
continue;
if (!IP.first.isValid() || IntI.start() < IP.first)
IP.first = IntI.start();
@@ -687,10 +682,10 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg,
// Last interference in block.
if (BI.LiveOut) {
- IntI.advanceTo(Stop);
- if (!IntI.valid() || IntI.start() >= Stop)
+ IntI.advanceTo(BI.Stop);
+ if (!IntI.valid() || IntI.start() >= BI.Stop)
--IntI;
- if (IntI.stop() <= Start)
+ if (IntI.stop() <= BI.Start)
continue;
if (!IP.second.isValid() || IntI.stop() > IP.second)
IP.second = IntI.stop();
@@ -716,16 +711,14 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg,
continue;
IndexPair &IP = InterferenceRanges[i];
- SlotIndex Start, Stop;
- tie(Start, Stop) = Indexes->getMBBRange(BI.MBB);
-
DEBUG(dbgs() << "BB#" << BI.MBB->getNumber() << " -> EB#"
<< Bundles->getBundle(BI.MBB->getNumber(), 1)
<< " intf [" << IP.first << ';' << IP.second << ')');
// The interference interval should either be invalid or overlap MBB.
- assert((!IP.first.isValid() || IP.first < Stop) && "Bad interference");
- assert((!IP.second.isValid() || IP.second > Start) && "Bad interference");
+ assert((!IP.first.isValid() || IP.first < BI.Stop) && "Bad interference");
+ assert((!IP.second.isValid() || IP.second > BI.Start)
+ && "Bad interference");
// Check interference leaving the block.
if (!IP.second.isValid()) {
@@ -742,14 +735,14 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg,
}
if (!BI.LiveThrough) {
DEBUG(dbgs() << ", not live-through.\n");
- SE->useIntv(SE->enterIntvBefore(BI.Def), Stop);
+ SE->useIntv(SE->enterIntvBefore(BI.Def), BI.Stop);
continue;
}
if (!RegIn) {
// Block is live-through, but entry bundle is on the stack.
// Reload just before the first use.
DEBUG(dbgs() << ", not live-in, enter before first use.\n");
- SE->useIntv(SE->enterIntvBefore(BI.FirstUse), Stop);
+ SE->useIntv(SE->enterIntvBefore(BI.FirstUse), BI.Stop);
continue;
}
DEBUG(dbgs() << ", live-through.\n");
@@ -762,7 +755,7 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg,
if (!BI.LiveThrough && IP.second <= BI.Def) {
// The interference doesn't reach the outgoing segment.
DEBUG(dbgs() << " doesn't affect def from " << BI.Def << '\n');
- SE->useIntv(BI.Def, Stop);
+ SE->useIntv(BI.Def, BI.Stop);
continue;
}
@@ -790,7 +783,7 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg,
SlotIndex SegStart = SE->enterIntvBefore(Use);
assert(SegStart >= IP.second && "Couldn't avoid interference");
assert(SegStart < BI.LastSplitPoint && "Impossible split point");
- SE->useIntv(SegStart, Stop);
+ SE->useIntv(SegStart, BI.Stop);
continue;
}
}
@@ -813,8 +806,6 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg,
// We have an incoming register. Check for interference.
IndexPair &IP = InterferenceRanges[i];
- SlotIndex Start, Stop;
- tie(Start, Stop) = Indexes->getMBBRange(BI.MBB);
DEBUG(dbgs() << "EB#" << Bundles->getBundle(BI.MBB->getNumber(), 0)
<< " -> BB#" << BI.MBB->getNumber());
@@ -828,7 +819,7 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg,
// Block is live-through without interference.
if (RegOut) {
DEBUG(dbgs() << ", no uses, live-through.\n");
- SE->useIntv(Start, Stop);
+ SE->useIntv(BI.Start, BI.Stop);
} else {
DEBUG(dbgs() << ", no uses, stack-out.\n");
SE->leaveIntvAtTop(*BI.MBB);
@@ -837,7 +828,7 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg,
}
if (!BI.LiveThrough) {
DEBUG(dbgs() << ", killed in block.\n");
- SE->useIntv(Start, SE->leaveIntvAfter(BI.Kill));
+ SE->useIntv(BI.Start, SE->leaveIntvAfter(BI.Kill));
continue;
}
if (!RegOut) {
@@ -845,7 +836,7 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg,
// Spill immediately after the last use.
if (BI.LastUse < BI.LastSplitPoint) {
DEBUG(dbgs() << ", uses, stack-out.\n");
- SE->useIntv(Start, SE->leaveIntvAfter(BI.LastUse));
+ SE->useIntv(BI.Start, SE->leaveIntvAfter(BI.LastUse));
continue;
}
// The last use is after the last split point, it is probably an
@@ -853,7 +844,7 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg,
DEBUG(dbgs() << ", uses at " << BI.LastUse << " after split point "
<< BI.LastSplitPoint << ", stack-out.\n");
SlotIndex SegEnd = SE->leaveIntvBefore(BI.LastSplitPoint);
- SE->useIntv(Start, SegEnd);
+ SE->useIntv(BI.Start, SegEnd);
// Run a double interval from the split to the last use.
// This makes it possible to spill the complement without affecting the
// indirect branch.
@@ -862,7 +853,7 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg,
}
// Register is live-through.
DEBUG(dbgs() << ", uses, live-through.\n");
- SE->useIntv(Start, Stop);
+ SE->useIntv(BI.Start, BI.Stop);
continue;
}
@@ -872,7 +863,7 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg,
if (!BI.LiveThrough && IP.first >= BI.Kill) {
// The interference doesn't reach the outgoing segment.
DEBUG(dbgs() << " doesn't affect kill at " << BI.Kill << '\n');
- SE->useIntv(Start, BI.Kill);
+ SE->useIntv(BI.Start, BI.Kill);
continue;
}
@@ -894,7 +885,7 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg,
DEBUG(dbgs() << ", free use at " << *UI << ".\n");
SlotIndex SegEnd = SE->leaveIntvAfter(Use);
assert(SegEnd <= IP.first && "Couldn't avoid interference");
- SE->useIntv(Start, SegEnd);
+ SE->useIntv(BI.Start, SegEnd);
continue;
}
diff --git a/lib/CodeGen/SplitKit.cpp b/lib/CodeGen/SplitKit.cpp
index 017511e..3f08354 100644
--- a/lib/CodeGen/SplitKit.cpp
+++ b/lib/CodeGen/SplitKit.cpp
@@ -105,8 +105,7 @@ void SplitAnalysis::calcLiveBlockInfo() {
for (;;) {
BlockInfo BI;
BI.MBB = MFI;
- SlotIndex Start, Stop;
- tie(Start, Stop) = LIS.getSlotIndexes()->getMBBRange(BI.MBB);
+ tie(BI.Start, BI.Stop) = LIS.getSlotIndexes()->getMBBRange(BI.MBB);
// The last split point is the latest possible insertion point that dominates
// all successor blocks. If interference reaches LastSplitPoint, it is not
@@ -114,12 +113,12 @@ void SplitAnalysis::calcLiveBlockInfo() {
// outgoing bundle.
MachineBasicBlock::iterator LSP = LIS.getLastSplitPoint(*CurLI, BI.MBB);
if (LSP == BI.MBB->end())
- BI.LastSplitPoint = Stop;
+ BI.LastSplitPoint = BI.Stop;
else
BI.LastSplitPoint = LIS.getInstructionIndex(LSP);
// LVI is the first live segment overlapping MBB.
- BI.LiveIn = LVI->start <= Start;
+ BI.LiveIn = LVI->start <= BI.Start;
if (!BI.LiveIn)
BI.Def = LVI->start;
@@ -127,19 +126,19 @@ void SplitAnalysis::calcLiveBlockInfo() {
BI.Uses = hasUses(MFI);
if (BI.Uses && UseI != UseE) {
BI.FirstUse = *UseI;
- assert(BI.FirstUse >= Start);
+ assert(BI.FirstUse >= BI.Start);
do ++UseI;
- while (UseI != UseE && *UseI < Stop);
+ while (UseI != UseE && *UseI < BI.Stop);
BI.LastUse = UseI[-1];
- assert(BI.LastUse < Stop);
+ assert(BI.LastUse < BI.Stop);
}
// Look for gaps in the live range.
bool hasGap = false;
BI.LiveOut = true;
- while (LVI->end < Stop) {
+ while (LVI->end < BI.Stop) {
SlotIndex LastStop = LVI->end;
- if (++LVI == LVE || LVI->start >= Stop) {
+ if (++LVI == LVE || LVI->start >= BI.Stop) {
BI.Kill = LastStop;
BI.LiveOut = false;
break;
@@ -160,11 +159,11 @@ void SplitAnalysis::calcLiveBlockInfo() {
break;
// Live segment ends exactly at Stop. Move to the next segment.
- if (LVI->end == Stop && ++LVI == LVE)
+ if (LVI->end == BI.Stop && ++LVI == LVE)
break;
// Pick the next basic block.
- if (LVI->start < Stop)
+ if (LVI->start < BI.Stop)
++MFI;
else
MFI = LIS.getMBBFromIndex(LVI->start);
diff --git a/lib/CodeGen/SplitKit.h b/lib/CodeGen/SplitKit.h
index 28c5c60..240f1fe 100644
--- a/lib/CodeGen/SplitKit.h
+++ b/lib/CodeGen/SplitKit.h
@@ -71,6 +71,8 @@ public:
///
struct BlockInfo {
MachineBasicBlock *MBB;
+ SlotIndex Start; ///< Beginining of block.
+ SlotIndex Stop; ///< End of block.
SlotIndex FirstUse; ///< First instr using current reg.
SlotIndex LastUse; ///< Last instr using current reg.
SlotIndex Kill; ///< Interval end point inside block.