mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-07 12:28:24 +00:00
Use the LiveBLocks array for SplitEditor::splitSingleBlocks() as well.
This fixes a bug where splitSingleBlocks() could split a live range after a terminator instruction. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@125237 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -954,6 +954,25 @@ SlotIndex SplitEditor::leaveIntvAfter(SlotIndex Idx) {
|
|||||||
return VNI->def;
|
return VNI->def;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SlotIndex SplitEditor::leaveIntvBefore(SlotIndex Idx) {
|
||||||
|
assert(OpenIdx && "openIntv not called before leaveIntvBefore");
|
||||||
|
DEBUG(dbgs() << " leaveIntvBefore " << Idx);
|
||||||
|
|
||||||
|
// The interval must be live into the instruction at Idx.
|
||||||
|
Idx = Idx.getBoundaryIndex();
|
||||||
|
VNInfo *ParentVNI = Edit.getParent().getVNInfoAt(Idx);
|
||||||
|
if (!ParentVNI) {
|
||||||
|
DEBUG(dbgs() << ": not live\n");
|
||||||
|
return Idx.getNextSlot();
|
||||||
|
}
|
||||||
|
DEBUG(dbgs() << ": valno " << ParentVNI->id << '\n');
|
||||||
|
|
||||||
|
MachineInstr *MI = LIS.getInstructionFromIndex(Idx);
|
||||||
|
assert(MI && "No instruction at index");
|
||||||
|
VNInfo *VNI = defFromParent(0, ParentVNI, Idx, *MI->getParent(), MI);
|
||||||
|
return VNI->def;
|
||||||
|
}
|
||||||
|
|
||||||
SlotIndex SplitEditor::leaveIntvAtTop(MachineBasicBlock &MBB) {
|
SlotIndex SplitEditor::leaveIntvAtTop(MachineBasicBlock &MBB) {
|
||||||
assert(OpenIdx && "openIntv not called before leaveIntvAtTop");
|
assert(OpenIdx && "openIntv not called before leaveIntvAtTop");
|
||||||
SlotIndex Start = LIS.getMBBStartIdx(&MBB);
|
SlotIndex Start = LIS.getMBBStartIdx(&MBB);
|
||||||
@@ -1211,28 +1230,20 @@ void SplitEditor::splitAroundLoop(const MachineLoop *Loop) {
|
|||||||
/// may be an advantage to split CurLI for the duration of the block.
|
/// may be an advantage to split CurLI for the duration of the block.
|
||||||
bool SplitAnalysis::getMultiUseBlocks(BlockPtrSet &Blocks) {
|
bool SplitAnalysis::getMultiUseBlocks(BlockPtrSet &Blocks) {
|
||||||
// If CurLI is local to one block, there is no point to splitting it.
|
// If CurLI is local to one block, there is no point to splitting it.
|
||||||
if (UsingBlocks.size() <= 1)
|
if (LiveBlocks.size() <= 1)
|
||||||
return false;
|
return false;
|
||||||
// Add blocks with multiple uses.
|
// Add blocks with multiple uses.
|
||||||
for (BlockCountMap::iterator I = UsingBlocks.begin(), E = UsingBlocks.end();
|
for (unsigned i = 0, e = LiveBlocks.size(); i != e; ++i) {
|
||||||
I != E; ++I)
|
const BlockInfo &BI = LiveBlocks[i];
|
||||||
switch (I->second) {
|
if (!BI.Uses)
|
||||||
case 0:
|
|
||||||
case 1:
|
|
||||||
continue;
|
continue;
|
||||||
case 2: {
|
unsigned Instrs = UsingBlocks.lookup(BI.MBB);
|
||||||
// When there are only two uses and CurLI is both live in and live out,
|
if (Instrs <= 1)
|
||||||
// we don't really win anything by isolating the block since we would be
|
continue;
|
||||||
// inserting two copies.
|
if (Instrs == 2 && BI.LiveIn && BI.LiveOut && !BI.LiveThrough)
|
||||||
// The remaing register would still have two uses in the block. (Unless it
|
continue;
|
||||||
// separates into disconnected components).
|
Blocks.insert(BI.MBB);
|
||||||
if (LIS.isLiveInToMBB(*CurLI, I->first) &&
|
}
|
||||||
LIS.isLiveOutOfMBB(*CurLI, I->first))
|
|
||||||
continue;
|
|
||||||
} // Fall through.
|
|
||||||
default:
|
|
||||||
Blocks.insert(I->first);
|
|
||||||
}
|
|
||||||
return !Blocks.empty();
|
return !Blocks.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1240,34 +1251,22 @@ bool SplitAnalysis::getMultiUseBlocks(BlockPtrSet &Blocks) {
|
|||||||
/// basic block in Blocks.
|
/// basic block in Blocks.
|
||||||
void SplitEditor::splitSingleBlocks(const SplitAnalysis::BlockPtrSet &Blocks) {
|
void SplitEditor::splitSingleBlocks(const SplitAnalysis::BlockPtrSet &Blocks) {
|
||||||
DEBUG(dbgs() << " splitSingleBlocks for " << Blocks.size() << " blocks.\n");
|
DEBUG(dbgs() << " splitSingleBlocks for " << Blocks.size() << " blocks.\n");
|
||||||
// Determine the first and last instruction using CurLI in each block.
|
|
||||||
typedef std::pair<SlotIndex,SlotIndex> IndexPair;
|
|
||||||
typedef DenseMap<const MachineBasicBlock*,IndexPair> IndexPairMap;
|
|
||||||
IndexPairMap MBBRange;
|
|
||||||
for (SplitAnalysis::InstrPtrSet::const_iterator I = sa_.UsingInstrs.begin(),
|
|
||||||
E = sa_.UsingInstrs.end(); I != E; ++I) {
|
|
||||||
const MachineBasicBlock *MBB = (*I)->getParent();
|
|
||||||
if (!Blocks.count(MBB))
|
|
||||||
continue;
|
|
||||||
SlotIndex Idx = LIS.getInstructionIndex(*I);
|
|
||||||
DEBUG(dbgs() << " BB#" << MBB->getNumber() << '\t' << Idx << '\t' << **I);
|
|
||||||
IndexPair &IP = MBBRange[MBB];
|
|
||||||
if (!IP.first.isValid() || Idx < IP.first)
|
|
||||||
IP.first = Idx;
|
|
||||||
if (!IP.second.isValid() || Idx > IP.second)
|
|
||||||
IP.second = Idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a new interval for each block.
|
for (unsigned i = 0, e = sa_.LiveBlocks.size(); i != e; ++i) {
|
||||||
for (SplitAnalysis::BlockPtrSet::const_iterator I = Blocks.begin(),
|
const SplitAnalysis::BlockInfo &BI = sa_.LiveBlocks[i];
|
||||||
E = Blocks.end(); I != E; ++I) {
|
if (!BI.Uses || !Blocks.count(BI.MBB))
|
||||||
IndexPair &IP = MBBRange[*I];
|
continue;
|
||||||
DEBUG(dbgs() << " splitting for BB#" << (*I)->getNumber() << ": ["
|
|
||||||
<< IP.first << ';' << IP.second << ")\n");
|
|
||||||
assert(IP.first.isValid() && IP.second.isValid());
|
|
||||||
|
|
||||||
openIntv();
|
openIntv();
|
||||||
useIntv(enterIntvBefore(IP.first), leaveIntvAfter(IP.second));
|
SlotIndex SegStart = enterIntvBefore(BI.FirstUse);
|
||||||
|
if (BI.LastUse < BI.LastSplitPoint) {
|
||||||
|
useIntv(SegStart, leaveIntvAfter(BI.LastUse));
|
||||||
|
} else {
|
||||||
|
// THe last use os after tha last valid split point.
|
||||||
|
SlotIndex SegStop = leaveIntvBefore(BI.LastSplitPoint);
|
||||||
|
useIntv(SegStart, SegStop);
|
||||||
|
overlapIntv(SegStop, BI.LastUse);
|
||||||
|
}
|
||||||
closeIntv();
|
closeIntv();
|
||||||
}
|
}
|
||||||
finish();
|
finish();
|
||||||
|
@@ -407,6 +407,10 @@ public:
|
|||||||
/// Return the end of the live range.
|
/// Return the end of the live range.
|
||||||
SlotIndex leaveIntvAfter(SlotIndex Idx);
|
SlotIndex leaveIntvAfter(SlotIndex Idx);
|
||||||
|
|
||||||
|
/// leaveIntvBefore - Leave the open interval before the instruction at Idx.
|
||||||
|
/// Return the end of the live range.
|
||||||
|
SlotIndex leaveIntvBefore(SlotIndex Idx);
|
||||||
|
|
||||||
/// leaveIntvAtTop - Leave the interval at the top of MBB.
|
/// leaveIntvAtTop - Leave the interval at the top of MBB.
|
||||||
/// Add liveness from the MBB top to the copy.
|
/// Add liveness from the MBB top to the copy.
|
||||||
/// Return the end of the live range.
|
/// Return the end of the live range.
|
||||||
|
Reference in New Issue
Block a user