Reapply r132245 with a fix for the bug that broke the darwin9/i386 build.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132309 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jakob Stoklund Olesen 2011-05-30 01:33:26 +00:00
parent 221d5de013
commit a2e79ef908
3 changed files with 73 additions and 56 deletions

View File

@ -552,7 +552,7 @@ bool RAGreedy::addSplitConstraints(InterferenceCache::Cursor Intf,
BC.Entry = SpillPlacement::MustSpill, ++Ins; BC.Entry = SpillPlacement::MustSpill, ++Ins;
else if (Intf.first() < BI.FirstUse) else if (Intf.first() < BI.FirstUse)
BC.Entry = SpillPlacement::PrefSpill, ++Ins; BC.Entry = SpillPlacement::PrefSpill, ++Ins;
else if (Intf.first() < (BI.LiveThrough ? BI.LastUse : BI.Kill)) else if (Intf.first() < BI.LastUse)
++Ins; ++Ins;
} }
@ -562,7 +562,7 @@ bool RAGreedy::addSplitConstraints(InterferenceCache::Cursor Intf,
BC.Exit = SpillPlacement::MustSpill, ++Ins; BC.Exit = SpillPlacement::MustSpill, ++Ins;
else if (Intf.last() > BI.LastUse) else if (Intf.last() > BI.LastUse)
BC.Exit = SpillPlacement::PrefSpill, ++Ins; BC.Exit = SpillPlacement::PrefSpill, ++Ins;
else if (Intf.last() > (BI.LiveThrough ? BI.FirstUse : BI.Def)) else if (Intf.last() > BI.FirstUse)
++Ins; ++Ins;
} }
@ -811,7 +811,7 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg,
DEBUG(dbgs() << ", no interference"); DEBUG(dbgs() << ", no interference");
if (!BI.LiveThrough) { if (!BI.LiveThrough) {
DEBUG(dbgs() << ", not live-through.\n"); DEBUG(dbgs() << ", not live-through.\n");
SE->useIntv(SE->enterIntvBefore(BI.Def), Stop); SE->useIntv(SE->enterIntvBefore(BI.FirstUse), Stop);
continue; continue;
} }
if (!RegIn) { if (!RegIn) {
@ -828,10 +828,10 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg,
// Block has interference. // Block has interference.
DEBUG(dbgs() << ", interference to " << Intf.last()); DEBUG(dbgs() << ", interference to " << Intf.last());
if (!BI.LiveThrough && Intf.last() <= BI.Def) { if (!BI.LiveThrough && Intf.last() <= BI.FirstUse) {
// The interference doesn't reach the outgoing segment. // The interference doesn't reach the outgoing segment.
DEBUG(dbgs() << " doesn't affect def from " << BI.Def << '\n'); DEBUG(dbgs() << " doesn't affect def from " << BI.FirstUse << '\n');
SE->useIntv(BI.Def, Stop); SE->useIntv(BI.FirstUse, Stop);
continue; continue;
} }
@ -887,7 +887,7 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg,
DEBUG(dbgs() << ", no interference"); DEBUG(dbgs() << ", no interference");
if (!BI.LiveThrough) { if (!BI.LiveThrough) {
DEBUG(dbgs() << ", killed in block.\n"); DEBUG(dbgs() << ", killed in block.\n");
SE->useIntv(Start, SE->leaveIntvAfter(BI.Kill)); SE->useIntv(Start, SE->leaveIntvAfter(BI.LastUse));
continue; continue;
} }
if (!RegOut) { if (!RegOut) {
@ -920,10 +920,10 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg,
// Block has interference. // Block has interference.
DEBUG(dbgs() << ", interference from " << Intf.first()); DEBUG(dbgs() << ", interference from " << Intf.first());
if (!BI.LiveThrough && Intf.first() >= BI.Kill) { if (!BI.LiveThrough && Intf.first() >= BI.LastUse) {
// The interference doesn't reach the outgoing segment. // The interference doesn't reach the outgoing segment.
DEBUG(dbgs() << " doesn't affect kill at " << BI.Kill << '\n'); DEBUG(dbgs() << " doesn't affect kill at " << BI.LastUse << '\n');
SE->useIntv(Start, BI.Kill); SE->useIntv(Start, BI.LastUse);
continue; continue;
} }

View File

@ -145,7 +145,7 @@ void SplitAnalysis::analyzeUses() {
/// where CurLI is live. /// where CurLI is live.
bool SplitAnalysis::calcLiveBlockInfo() { bool SplitAnalysis::calcLiveBlockInfo() {
ThroughBlocks.resize(MF.getNumBlockIDs()); ThroughBlocks.resize(MF.getNumBlockIDs());
NumThroughBlocks = 0; NumThroughBlocks = NumGapBlocks = 0;
if (CurLI->empty()) if (CurLI->empty())
return true; return true;
@ -164,55 +164,63 @@ bool SplitAnalysis::calcLiveBlockInfo() {
SlotIndex Start, Stop; SlotIndex Start, Stop;
tie(Start, Stop) = LIS.getSlotIndexes()->getMBBRange(BI.MBB); tie(Start, Stop) = LIS.getSlotIndexes()->getMBBRange(BI.MBB);
// LVI is the first live segment overlapping MBB. // If the block contains no uses, the range must be live through. At one
BI.LiveIn = LVI->start <= Start; // point, SimpleRegisterCoalescing could create dangling ranges that ended
if (!BI.LiveIn) // mid-block.
BI.Def = LVI->start; if (UseI == UseE || *UseI >= Stop) {
++NumThroughBlocks;
// Find the first and last uses in the block. ThroughBlocks.set(BI.MBB->getNumber());
bool Uses = UseI != UseE && *UseI < Stop; // The range shouldn't end mid-block if there are no uses. This shouldn't
if (Uses) { // happen.
if (LVI->end < Stop)
return false;
} else {
// This block has uses. Find the first and last uses in the block.
BI.FirstUse = *UseI; BI.FirstUse = *UseI;
assert(BI.FirstUse >= Start); assert(BI.FirstUse >= Start);
do ++UseI; do ++UseI;
while (UseI != UseE && *UseI < Stop); while (UseI != UseE && *UseI < Stop);
BI.LastUse = UseI[-1]; BI.LastUse = UseI[-1];
assert(BI.LastUse < Stop); assert(BI.LastUse < Stop);
}
// LVI is the first live segment overlapping MBB.
BI.LiveIn = LVI->start <= Start;
// Look for gaps in the live range. // Look for gaps in the live range.
bool hasGap = false;
BI.LiveOut = true; BI.LiveOut = true;
while (LVI->end < Stop) { while (LVI->end < Stop) {
SlotIndex LastStop = LVI->end; SlotIndex LastStop = LVI->end;
if (++LVI == LVE || LVI->start >= Stop) { if (++LVI == LVE || LVI->start >= Stop) {
BI.Kill = LastStop;
BI.LiveOut = false; BI.LiveOut = false;
BI.LastUse = LastStop;
break; break;
} }
if (LastStop < LVI->start) { if (LastStop < LVI->start) {
hasGap = true; // There is a gap in the live range. Create duplicate entries for the
BI.Kill = LastStop; // live-in snippet and the live-out snippet.
BI.Def = LVI->start; ++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;
} }
} }
// Don't set LiveThrough when the block has a gap. // Don't set LiveThrough when the block has a gap.
BI.LiveThrough = !hasGap && BI.LiveIn && BI.LiveOut; BI.LiveThrough = BI.LiveIn && BI.LiveOut;
if (Uses)
UseBlocks.push_back(BI); UseBlocks.push_back(BI);
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. // LVI is now at LVE or LVI->end >= Stop.
if (LVI == LVE) if (LVI == LVE)
break; break;
}
// Live segment ends exactly at Stop. Move to the next segment. // Live segment ends exactly at Stop. Move to the next segment.
if (LVI->end == Stop && ++LVI == LVE) if (LVI->end == Stop && ++LVI == LVE)

View File

@ -63,17 +63,22 @@ public:
/// 1. | o---x | Internal to block. Variable is only live in this block. /// 1. | o---x | Internal to block. Variable is only live in this block.
/// 2. |---x | Live-in, kill. /// 2. |---x | Live-in, kill.
/// 3. | o---| Def, live-out. /// 3. | o---| Def, live-out.
/// 4. |---x o---| Live-in, kill, def, live-out. /// 4. |---x o---| Live-in, kill, def, live-out. Counted by NumGapBlocks.
/// 5. |---o---o---| Live-through with uses or defs. /// 5. |---o---o---| Live-through with uses or defs.
/// 6. |-----------| Live-through without uses. Transparent. /// 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.
/// ///
struct BlockInfo { struct BlockInfo {
MachineBasicBlock *MBB; MachineBasicBlock *MBB;
SlotIndex FirstUse; ///< First instr using current reg. SlotIndex FirstUse; ///< First instr using current reg.
SlotIndex LastUse; ///< Last instr using current reg. SlotIndex LastUse; ///< Last instr using current reg.
SlotIndex Kill; ///< Interval end point inside block. bool LiveThrough; ///< Live in whole block (Templ 5. above).
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 LiveIn; ///< Current reg is live in.
bool LiveOut; ///< Current reg is live out. bool LiveOut; ///< Current reg is live out.
}; };
@ -91,6 +96,10 @@ private:
/// UseBlocks - Blocks where CurLI has uses. /// UseBlocks - Blocks where CurLI has uses.
SmallVector<BlockInfo, 8> UseBlocks; 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. /// ThroughBlocks - Block numbers where CurLI is live through without uses.
BitVector ThroughBlocks; BitVector ThroughBlocks;
@ -160,7 +169,7 @@ public:
/// getNumLiveBlocks - Return the number of blocks where CurLI is live. /// getNumLiveBlocks - Return the number of blocks where CurLI is live.
unsigned getNumLiveBlocks() const { unsigned getNumLiveBlocks() const {
return getUseBlocks().size() + getNumThroughBlocks(); return getUseBlocks().size() - NumGapBlocks + getNumThroughBlocks();
} }
/// countLiveBlocks - Return the number of blocks where li is live. This is /// countLiveBlocks - Return the number of blocks where li is live. This is