summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/RegAllocGreedy.cpp20
-rw-r--r--lib/CodeGen/SplitKit.cpp85
-rw-r--r--lib/CodeGen/SplitKit.h21
3 files changed, 55 insertions, 71 deletions
diff --git a/lib/CodeGen/RegAllocGreedy.cpp b/lib/CodeGen/RegAllocGreedy.cpp
index 15d8cbac01..2d03760fc7 100644
--- a/lib/CodeGen/RegAllocGreedy.cpp
+++ b/lib/CodeGen/RegAllocGreedy.cpp
@@ -552,7 +552,7 @@ bool RAGreedy::addSplitConstraints(InterferenceCache::Cursor Intf,
BC.Entry = SpillPlacement::MustSpill, ++Ins;
else if (Intf.first() < BI.FirstUse)
BC.Entry = SpillPlacement::PrefSpill, ++Ins;
- else if (Intf.first() < BI.LastUse)
+ else if (Intf.first() < (BI.LiveThrough ? BI.LastUse : BI.Kill))
++Ins;
}
@@ -562,7 +562,7 @@ bool RAGreedy::addSplitConstraints(InterferenceCache::Cursor Intf,
BC.Exit = SpillPlacement::MustSpill, ++Ins;
else if (Intf.last() > BI.LastUse)
BC.Exit = SpillPlacement::PrefSpill, ++Ins;
- else if (Intf.last() > BI.FirstUse)
+ else if (Intf.last() > (BI.LiveThrough ? BI.FirstUse : BI.Def))
++Ins;
}
@@ -811,7 +811,7 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg,
DEBUG(dbgs() << ", no interference");
if (!BI.LiveThrough) {
DEBUG(dbgs() << ", not live-through.\n");
- SE->useIntv(SE->enterIntvBefore(BI.FirstUse), Stop);
+ SE->useIntv(SE->enterIntvBefore(BI.Def), Stop);
continue;
}
if (!RegIn) {
@@ -828,10 +828,10 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg,
// Block has interference.
DEBUG(dbgs() << ", interference to " << Intf.last());
- if (!BI.LiveThrough && Intf.last() <= BI.FirstUse) {
+ if (!BI.LiveThrough && Intf.last() <= BI.Def) {
// The interference doesn't reach the outgoing segment.
- DEBUG(dbgs() << " doesn't affect def from " << BI.FirstUse << '\n');
- SE->useIntv(BI.FirstUse, Stop);
+ DEBUG(dbgs() << " doesn't affect def from " << BI.Def << '\n');
+ SE->useIntv(BI.Def, Stop);
continue;
}
@@ -887,7 +887,7 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg,
DEBUG(dbgs() << ", no interference");
if (!BI.LiveThrough) {
DEBUG(dbgs() << ", killed in block.\n");
- SE->useIntv(Start, SE->leaveIntvAfter(BI.LastUse));
+ SE->useIntv(Start, SE->leaveIntvAfter(BI.Kill));
continue;
}
if (!RegOut) {
@@ -920,10 +920,10 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg,
// Block has interference.
DEBUG(dbgs() << ", interference from " << Intf.first());
- if (!BI.LiveThrough && Intf.first() >= BI.LastUse) {
+ if (!BI.LiveThrough && Intf.first() >= BI.Kill) {
// The interference doesn't reach the outgoing segment.
- DEBUG(dbgs() << " doesn't affect kill at " << BI.LastUse << '\n');
- SE->useIntv(Start, BI.LastUse);
+ DEBUG(dbgs() << " doesn't affect kill at " << BI.Kill << '\n');
+ SE->useIntv(Start, BI.Kill);
continue;
}
diff --git a/lib/CodeGen/SplitKit.cpp b/lib/CodeGen/SplitKit.cpp
index ef5650c861..53141b54c9 100644
--- a/lib/CodeGen/SplitKit.cpp
+++ b/lib/CodeGen/SplitKit.cpp
@@ -145,7 +145,7 @@ void SplitAnalysis::analyzeUses() {
/// where CurLI is live.
bool SplitAnalysis::calcLiveBlockInfo() {
ThroughBlocks.resize(MF.getNumBlockIDs());
- NumThroughBlocks = NumGapBlocks = 0;
+ NumThroughBlocks = 0;
if (CurLI->empty())
return true;
@@ -164,62 +164,55 @@ bool SplitAnalysis::calcLiveBlockInfo() {
SlotIndex Start, Stop;
tie(Start, Stop) = LIS.getSlotIndexes()->getMBBRange(BI.MBB);
- // If the block contains no uses, the range must be live through. At one
- // point, SimpleRegisterCoalescing could create dangling ranges that ended
- // mid-block.
- if (UseI == UseE || *UseI >= Stop) {
- ++NumThroughBlocks;
- ThroughBlocks.set(BI.MBB->getNumber());
- // The range shouldn't end mid-block if there are no uses. This shouldn't
- // happen.
- if (LVI->end < Stop)
- return false;
- } else {
- // This block has uses. Find the first and last uses in the block.
+ // LVI is the first live segment overlapping MBB.
+ BI.LiveIn = LVI->start <= Start;
+ if (!BI.LiveIn)
+ BI.Def = LVI->start;
+
+ // Find the first and last uses in the block.
+ bool Uses = UseI != UseE && *UseI < Stop;
+ if (Uses) {
BI.FirstUse = *UseI;
assert(BI.FirstUse >= Start);
do ++UseI;
while (UseI != UseE && *UseI < Stop);
BI.LastUse = UseI[-1];
assert(BI.LastUse < Stop);
+ }
- // LVI is the first live segment overlapping MBB.
- BI.LiveIn = LVI->start <= Start;
-
- // Look for gaps in the live range.
- BI.LiveOut = true;
- while (LVI->end < Stop) {
- SlotIndex LastStop = LVI->end;
- if (++LVI == LVE || LVI->start >= Stop) {
- BI.LiveOut = false;
- break;
- }
- if (LastStop < LVI->start) {
- // There is a gap in the live range. Create duplicate entries for the
- // live-in snippet and the live-out snippet.
- ++NumGapBlocks;
-
- // Push the Live-in part.
- BI.LiveThrough = false;
- BI.LiveOut = false;
- UseBlocks.push_back(BI);
- UseBlocks.back().LastUse = LastStop;
-
- // Set up BI for the live-out part.
- BI.LiveIn = false;
- BI.LiveOut = true;
- BI.FirstUse = LVI->start;
- }
+ // Look for gaps in the live range.
+ bool hasGap = false;
+ BI.LiveOut = true;
+ while (LVI->end < Stop) {
+ SlotIndex LastStop = LVI->end;
+ if (++LVI == LVE || LVI->start >= Stop) {
+ BI.Kill = LastStop;
+ BI.LiveOut = false;
+ break;
+ }
+ if (LastStop < LVI->start) {
+ hasGap = true;
+ BI.Kill = LastStop;
+ BI.Def = LVI->start;
}
+ }
- // Don't set LiveThrough when the block has a gap.
- BI.LiveThrough = BI.LiveIn && BI.LiveOut;
+ // Don't set LiveThrough when the block has a gap.
+ BI.LiveThrough = !hasGap && BI.LiveIn && BI.LiveOut;
+ if (Uses)
UseBlocks.push_back(BI);
-
- // LVI is now at LVE or LVI->end >= Stop.
- if (LVI == LVE)
- break;
+ else {
+ ++NumThroughBlocks;
+ ThroughBlocks.set(BI.MBB->getNumber());
}
+ // FIXME: This should never happen. The live range stops or starts without a
+ // corresponding use. An earlier pass did something wrong.
+ if (!BI.LiveThrough && !Uses)
+ return false;
+
+ // LVI is now at LVE or LVI->end >= Stop.
+ if (LVI == LVE)
+ break;
// Live segment ends exactly at Stop. Move to the next segment.
if (LVI->end == Stop && ++LVI == LVE)
diff --git a/lib/CodeGen/SplitKit.h b/lib/CodeGen/SplitKit.h
index 7174c0b55f..dc27486e73 100644
--- a/lib/CodeGen/SplitKit.h
+++ b/lib/CodeGen/SplitKit.h
@@ -63,22 +63,17 @@ public:
/// 1. | o---x | Internal to block. Variable is only live in this block.
/// 2. |---x | Live-in, kill.
/// 3. | o---| Def, live-out.
- /// 4. |---x o---| Live-in, kill, def, live-out. Counted by NumGapBlocks.
+ /// 4. |---x o---| Live-in, kill, def, live-out.
/// 5. |---o---o---| Live-through with uses or defs.
- /// 6. |-----------| Live-through without uses. Counted by NumThroughBlocks.
- ///
- /// Two BlockInfo entries are created for template 4. One for the live-in
- /// segment, and one for the live-out segment. These entries look as if the
- /// block were split in the middle where the live range isn't live.
- ///
- /// Live-through blocks without any uses don't get BlockInfo entries. They
- /// are simply listed in ThroughBlocks instead.
+ /// 6. |-----------| Live-through without uses. Transparent.
///
struct BlockInfo {
MachineBasicBlock *MBB;
SlotIndex FirstUse; ///< First instr using current reg.
SlotIndex LastUse; ///< Last instr using current reg.
- bool LiveThrough; ///< Live in whole block (Templ 5. above).
+ SlotIndex Kill; ///< Interval end point inside block.
+ SlotIndex Def; ///< Interval start point inside block.
+ bool LiveThrough; ///< Live in whole block (Templ 5. or 6. above).
bool LiveIn; ///< Current reg is live in.
bool LiveOut; ///< Current reg is live out.
};
@@ -96,10 +91,6 @@ private:
/// UseBlocks - Blocks where CurLI has uses.
SmallVector<BlockInfo, 8> UseBlocks;
- /// NumGapBlocks - Number of duplicate entries in UseBlocks for blocks where
- /// the live range has a gap.
- unsigned NumGapBlocks;
-
/// ThroughBlocks - Block numbers where CurLI is live through without uses.
BitVector ThroughBlocks;
@@ -169,7 +160,7 @@ public:
/// getNumLiveBlocks - Return the number of blocks where CurLI is live.
unsigned getNumLiveBlocks() const {
- return getUseBlocks().size() - NumGapBlocks + getNumThroughBlocks();
+ return getUseBlocks().size() + getNumThroughBlocks();
}
/// countLiveBlocks - Return the number of blocks where li is live. This is