mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-02 07:11:49 +00:00
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:
parent
221d5de013
commit
a2e79ef908
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
|
||||||
|
|
||||||
// Look for gaps in the live range.
|
// LVI is the first live segment overlapping MBB.
|
||||||
bool hasGap = false;
|
BI.LiveIn = LVI->start <= Start;
|
||||||
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.
|
// Look for gaps in the live range.
|
||||||
BI.LiveThrough = !hasGap && BI.LiveIn && BI.LiveOut;
|
BI.LiveOut = true;
|
||||||
if (Uses)
|
while (LVI->end < Stop) {
|
||||||
|
SlotIndex LastStop = LVI->end;
|
||||||
|
if (++LVI == LVE || LVI->start >= Stop) {
|
||||||
|
BI.LiveOut = false;
|
||||||
|
BI.LastUse = LastStop;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't set LiveThrough when the block has a gap.
|
||||||
|
BI.LiveThrough = BI.LiveIn && BI.LiveOut;
|
||||||
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)
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user