mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-12 01:25:49 +00:00
Reapply r63025 and r63026, with fixes for the failing testcases.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@63049 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -139,26 +139,11 @@ namespace {
|
|||||||
|
|
||||||
void UpdateSpillSlotInterval(VNInfo*, unsigned, unsigned);
|
void UpdateSpillSlotInterval(VNInfo*, unsigned, unsigned);
|
||||||
|
|
||||||
VNInfo* UpdateRegisterInterval(VNInfo*, unsigned, unsigned);
|
|
||||||
|
|
||||||
bool ShrinkWrapToLastUse(MachineBasicBlock*, VNInfo*,
|
|
||||||
SmallVector<MachineOperand*, 4>&,
|
|
||||||
SmallPtrSet<MachineInstr*, 4>&);
|
|
||||||
|
|
||||||
void ShrinkWrapLiveInterval(VNInfo*, MachineBasicBlock*, MachineBasicBlock*,
|
|
||||||
MachineBasicBlock*, SmallPtrSet<MachineBasicBlock*, 8>&,
|
|
||||||
DenseMap<MachineBasicBlock*, SmallVector<MachineOperand*, 4> >&,
|
|
||||||
DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 4> >&,
|
|
||||||
SmallVector<MachineBasicBlock*, 4>&);
|
|
||||||
|
|
||||||
bool SplitRegLiveInterval(LiveInterval*);
|
bool SplitRegLiveInterval(LiveInterval*);
|
||||||
|
|
||||||
bool SplitRegLiveIntervals(const TargetRegisterClass **,
|
bool SplitRegLiveIntervals(const TargetRegisterClass **,
|
||||||
SmallPtrSet<LiveInterval*, 8>&);
|
SmallPtrSet<LiveInterval*, 8>&);
|
||||||
|
|
||||||
void RepairLiveInterval(LiveInterval* CurrLI, VNInfo* ValNo,
|
|
||||||
MachineInstr* DefMI, unsigned RestoreIdx);
|
|
||||||
|
|
||||||
bool createsNewJoin(LiveRange* LR, MachineBasicBlock* DefMBB,
|
bool createsNewJoin(LiveRange* LR, MachineBasicBlock* DefMBB,
|
||||||
MachineBasicBlock* BarrierMBB);
|
MachineBasicBlock* BarrierMBB);
|
||||||
bool Rematerialize(unsigned vreg, VNInfo* ValNo,
|
bool Rematerialize(unsigned vreg, VNInfo* ValNo,
|
||||||
@@ -423,176 +408,6 @@ PreAllocSplitting::UpdateSpillSlotInterval(VNInfo *ValNo, unsigned SpillIndex,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// UpdateRegisterInterval - Given the specified val# of the current live
|
|
||||||
/// interval is being split, and the spill and restore indices, update the live
|
|
||||||
/// interval accordingly.
|
|
||||||
VNInfo*
|
|
||||||
PreAllocSplitting::UpdateRegisterInterval(VNInfo *ValNo, unsigned SpillIndex,
|
|
||||||
unsigned RestoreIndex) {
|
|
||||||
assert(LIs->getMBBFromIndex(RestoreIndex) == BarrierMBB &&
|
|
||||||
"Expect restore in the barrier mbb");
|
|
||||||
|
|
||||||
SmallVector<std::pair<unsigned,unsigned>, 4> Before;
|
|
||||||
SmallVector<std::pair<unsigned,unsigned>, 4> After;
|
|
||||||
SmallVector<unsigned, 4> BeforeKills;
|
|
||||||
SmallVector<unsigned, 4> AfterKills;
|
|
||||||
SmallPtrSet<const LiveRange*, 4> Processed;
|
|
||||||
|
|
||||||
// First, let's figure out which parts of the live interval is now defined
|
|
||||||
// by the restore, which are defined by the original definition.
|
|
||||||
const LiveRange *LR = CurrLI->getLiveRangeContaining(RestoreIndex);
|
|
||||||
After.push_back(std::make_pair(RestoreIndex, LR->end));
|
|
||||||
if (CurrLI->isKill(ValNo, LR->end))
|
|
||||||
AfterKills.push_back(LR->end);
|
|
||||||
|
|
||||||
assert(LR->contains(SpillIndex));
|
|
||||||
if (SpillIndex > LR->start) {
|
|
||||||
Before.push_back(std::make_pair(LR->start, SpillIndex));
|
|
||||||
BeforeKills.push_back(SpillIndex);
|
|
||||||
}
|
|
||||||
Processed.insert(LR);
|
|
||||||
|
|
||||||
// Start from the restore mbb, figure out what part of the live interval
|
|
||||||
// are defined by the restore.
|
|
||||||
SmallVector<MachineBasicBlock*, 4> WorkList;
|
|
||||||
MachineBasicBlock *MBB = BarrierMBB;
|
|
||||||
for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(),
|
|
||||||
SE = MBB->succ_end(); SI != SE; ++SI)
|
|
||||||
WorkList.push_back(*SI);
|
|
||||||
|
|
||||||
SmallPtrSet<MachineBasicBlock*, 4> ProcessedBlocks;
|
|
||||||
ProcessedBlocks.insert(MBB);
|
|
||||||
|
|
||||||
while (!WorkList.empty()) {
|
|
||||||
MBB = WorkList.back();
|
|
||||||
WorkList.pop_back();
|
|
||||||
unsigned Idx = LIs->getMBBStartIdx(MBB);
|
|
||||||
LR = CurrLI->getLiveRangeContaining(Idx);
|
|
||||||
if (LR && LR->valno == ValNo && !Processed.count(LR)) {
|
|
||||||
After.push_back(std::make_pair(LR->start, LR->end));
|
|
||||||
if (CurrLI->isKill(ValNo, LR->end))
|
|
||||||
AfterKills.push_back(LR->end);
|
|
||||||
Idx = LIs->getMBBEndIdx(MBB);
|
|
||||||
if (LR->end > Idx) {
|
|
||||||
// Live range extend beyond at least one mbb. Let's see what other
|
|
||||||
// mbbs it reaches.
|
|
||||||
LIs->findReachableMBBs(LR->start, LR->end, WorkList);
|
|
||||||
}
|
|
||||||
Processed.insert(LR);
|
|
||||||
}
|
|
||||||
|
|
||||||
ProcessedBlocks.insert(MBB);
|
|
||||||
if (LR)
|
|
||||||
for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(),
|
|
||||||
SE = MBB->succ_end(); SI != SE; ++SI)
|
|
||||||
if (!ProcessedBlocks.count(*SI))
|
|
||||||
WorkList.push_back(*SI);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (LiveInterval::iterator I = CurrLI->begin(), E = CurrLI->end();
|
|
||||||
I != E; ++I) {
|
|
||||||
LiveRange *LR = I;
|
|
||||||
if (LR->valno == ValNo && !Processed.count(LR)) {
|
|
||||||
Before.push_back(std::make_pair(LR->start, LR->end));
|
|
||||||
if (CurrLI->isKill(ValNo, LR->end))
|
|
||||||
BeforeKills.push_back(LR->end);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now create new val#s to represent the live ranges defined by the old def
|
|
||||||
// those defined by the restore.
|
|
||||||
unsigned AfterDef = ValNo->def;
|
|
||||||
MachineInstr *AfterCopy = ValNo->copy;
|
|
||||||
bool HasPHIKill = ValNo->hasPHIKill;
|
|
||||||
CurrLI->removeValNo(ValNo);
|
|
||||||
VNInfo *BValNo = (Before.empty())
|
|
||||||
? NULL
|
|
||||||
: CurrLI->getNextValue(AfterDef, AfterCopy, LIs->getVNInfoAllocator());
|
|
||||||
if (BValNo)
|
|
||||||
CurrLI->addKills(BValNo, BeforeKills);
|
|
||||||
|
|
||||||
VNInfo *AValNo = (After.empty())
|
|
||||||
? NULL
|
|
||||||
: CurrLI->getNextValue(RestoreIndex, 0, LIs->getVNInfoAllocator());
|
|
||||||
if (AValNo) {
|
|
||||||
AValNo->hasPHIKill = HasPHIKill;
|
|
||||||
CurrLI->addKills(AValNo, AfterKills);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned i = 0, e = Before.size(); i != e; ++i) {
|
|
||||||
unsigned Start = Before[i].first;
|
|
||||||
unsigned End = Before[i].second;
|
|
||||||
CurrLI->addRange(LiveRange(Start, End, BValNo));
|
|
||||||
}
|
|
||||||
for (unsigned i = 0, e = After.size(); i != e; ++i) {
|
|
||||||
unsigned Start = After[i].first;
|
|
||||||
unsigned End = After[i].second;
|
|
||||||
CurrLI->addRange(LiveRange(Start, End, AValNo));
|
|
||||||
}
|
|
||||||
|
|
||||||
return AValNo;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ShrinkWrapToLastUse - There are uses of the current live interval in the
|
|
||||||
/// given block, shrink wrap the live interval to the last use (i.e. remove
|
|
||||||
/// from last use to the end of the mbb). In case mbb is the where the barrier
|
|
||||||
/// is, remove from the last use to the barrier.
|
|
||||||
bool
|
|
||||||
PreAllocSplitting::ShrinkWrapToLastUse(MachineBasicBlock *MBB, VNInfo *ValNo,
|
|
||||||
SmallVector<MachineOperand*, 4> &Uses,
|
|
||||||
SmallPtrSet<MachineInstr*, 4> &UseMIs) {
|
|
||||||
MachineOperand *LastMO = 0;
|
|
||||||
MachineInstr *LastMI = 0;
|
|
||||||
if (MBB != BarrierMBB && Uses.size() == 1) {
|
|
||||||
// Single use, no need to traverse the block. We can't assume this for the
|
|
||||||
// barrier bb though since the use is probably below the barrier.
|
|
||||||
LastMO = Uses[0];
|
|
||||||
LastMI = LastMO->getParent();
|
|
||||||
} else {
|
|
||||||
MachineBasicBlock::iterator MEE = MBB->begin();
|
|
||||||
MachineBasicBlock::iterator MII;
|
|
||||||
if (MBB == BarrierMBB)
|
|
||||||
MII = Barrier;
|
|
||||||
else
|
|
||||||
MII = MBB->end();
|
|
||||||
while (MII != MEE) {
|
|
||||||
--MII;
|
|
||||||
MachineInstr *UseMI = &*MII;
|
|
||||||
if (!UseMIs.count(UseMI))
|
|
||||||
continue;
|
|
||||||
for (unsigned i = 0, e = UseMI->getNumOperands(); i != e; ++i) {
|
|
||||||
MachineOperand &MO = UseMI->getOperand(i);
|
|
||||||
if (MO.isReg() && MO.getReg() == CurrLI->reg) {
|
|
||||||
LastMO = &MO;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LastMI = UseMI;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cut off live range from last use (or beginning of the mbb if there
|
|
||||||
// are no uses in it) to the end of the mbb.
|
|
||||||
unsigned RangeStart, RangeEnd = LIs->getMBBEndIdx(MBB)+1;
|
|
||||||
if (LastMI) {
|
|
||||||
RangeStart = LIs->getUseIndex(LIs->getInstructionIndex(LastMI))+1;
|
|
||||||
assert(!LastMO->isKill() && "Last use already terminates the interval?");
|
|
||||||
LastMO->setIsKill();
|
|
||||||
} else {
|
|
||||||
assert(MBB == BarrierMBB);
|
|
||||||
RangeStart = LIs->getMBBStartIdx(MBB);
|
|
||||||
}
|
|
||||||
if (MBB == BarrierMBB)
|
|
||||||
RangeEnd = LIs->getUseIndex(BarrierIdx)+1;
|
|
||||||
CurrLI->removeRange(RangeStart, RangeEnd);
|
|
||||||
if (LastMI)
|
|
||||||
CurrLI->addKill(ValNo, RangeStart);
|
|
||||||
|
|
||||||
// Return true if the last use becomes a new kill.
|
|
||||||
return LastMI;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// PerformPHIConstruction - From properly set up use and def lists, use a PHI
|
/// PerformPHIConstruction - From properly set up use and def lists, use a PHI
|
||||||
/// construction algorithm to compute the ranges and valnos for an interval.
|
/// construction algorithm to compute the ranges and valnos for an interval.
|
||||||
VNInfo* PreAllocSplitting::PerformPHIConstruction(
|
VNInfo* PreAllocSplitting::PerformPHIConstruction(
|
||||||
@@ -748,12 +563,12 @@ VNInfo* PreAllocSplitting::PerformPHIConstruction(
|
|||||||
ret = PerformPHIConstruction(walker, MBB, LI, Visited, Defs, Uses,
|
ret = PerformPHIConstruction(walker, MBB, LI, Visited, Defs, Uses,
|
||||||
NewVNs, LiveOut, Phis, false, true);
|
NewVNs, LiveOut, Phis, false, true);
|
||||||
|
|
||||||
|
LI->addRange(LiveRange(UseIndex, EndIndex+1, ret));
|
||||||
|
|
||||||
// FIXME: Need to set kills properly for inter-block stuff.
|
// FIXME: Need to set kills properly for inter-block stuff.
|
||||||
if (LI->isKill(ret, UseIndex)) LI->removeKill(ret, UseIndex);
|
if (LI->isKill(ret, UseIndex)) LI->removeKill(ret, UseIndex);
|
||||||
if (intrablock)
|
if (intrablock)
|
||||||
LI->addKill(ret, EndIndex);
|
LI->addKill(ret, EndIndex);
|
||||||
|
|
||||||
LI->addRange(LiveRange(UseIndex, EndIndex+1, ret));
|
|
||||||
} else if (ContainsDefs && ContainsUses){
|
} else if (ContainsDefs && ContainsUses){
|
||||||
SmallPtrSet<MachineInstr*, 2>& BlockDefs = Defs[MBB];
|
SmallPtrSet<MachineInstr*, 2>& BlockDefs = Defs[MBB];
|
||||||
SmallPtrSet<MachineInstr*, 2>& BlockUses = Uses[MBB];
|
SmallPtrSet<MachineInstr*, 2>& BlockUses = Uses[MBB];
|
||||||
@@ -805,13 +620,13 @@ VNInfo* PreAllocSplitting::PerformPHIConstruction(
|
|||||||
ret = PerformPHIConstruction(walker, MBB, LI, Visited, Defs, Uses,
|
ret = PerformPHIConstruction(walker, MBB, LI, Visited, Defs, Uses,
|
||||||
NewVNs, LiveOut, Phis, false, true);
|
NewVNs, LiveOut, Phis, false, true);
|
||||||
|
|
||||||
|
LI->addRange(LiveRange(StartIndex, EndIndex+1, ret));
|
||||||
|
|
||||||
if (foundUse && LI->isKill(ret, StartIndex))
|
if (foundUse && LI->isKill(ret, StartIndex))
|
||||||
LI->removeKill(ret, StartIndex);
|
LI->removeKill(ret, StartIndex);
|
||||||
if (intrablock) {
|
if (intrablock) {
|
||||||
LI->addKill(ret, EndIndex);
|
LI->addKill(ret, EndIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
LI->addRange(LiveRange(StartIndex, EndIndex+1, ret));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Memoize results so we don't have to recompute them.
|
// Memoize results so we don't have to recompute them.
|
||||||
@@ -890,142 +705,6 @@ void PreAllocSplitting::ReconstructLiveInterval(LiveInterval* LI) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ShrinkWrapLiveInterval - Recursively traverse the predecessor
|
|
||||||
/// chain to find the new 'kills' and shrink wrap the live interval to the
|
|
||||||
/// new kill indices.
|
|
||||||
void
|
|
||||||
PreAllocSplitting::ShrinkWrapLiveInterval(VNInfo *ValNo, MachineBasicBlock *MBB,
|
|
||||||
MachineBasicBlock *SuccMBB, MachineBasicBlock *DefMBB,
|
|
||||||
SmallPtrSet<MachineBasicBlock*, 8> &Visited,
|
|
||||||
DenseMap<MachineBasicBlock*, SmallVector<MachineOperand*, 4> > &Uses,
|
|
||||||
DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 4> > &UseMIs,
|
|
||||||
SmallVector<MachineBasicBlock*, 4> &UseMBBs) {
|
|
||||||
if (Visited.count(MBB))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// If live interval is live in another successor path, then we can't process
|
|
||||||
// this block. But we may able to do so after all the successors have been
|
|
||||||
// processed.
|
|
||||||
if (MBB != BarrierMBB) {
|
|
||||||
for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(),
|
|
||||||
SE = MBB->succ_end(); SI != SE; ++SI) {
|
|
||||||
MachineBasicBlock *SMBB = *SI;
|
|
||||||
if (SMBB == SuccMBB)
|
|
||||||
continue;
|
|
||||||
if (CurrLI->liveAt(LIs->getMBBStartIdx(SMBB)))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Visited.insert(MBB);
|
|
||||||
|
|
||||||
DenseMap<MachineBasicBlock*, SmallVector<MachineOperand*, 4> >::iterator
|
|
||||||
UMII = Uses.find(MBB);
|
|
||||||
if (UMII != Uses.end()) {
|
|
||||||
// At least one use in this mbb, lets look for the kill.
|
|
||||||
DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 4> >::iterator
|
|
||||||
UMII2 = UseMIs.find(MBB);
|
|
||||||
if (ShrinkWrapToLastUse(MBB, ValNo, UMII->second, UMII2->second))
|
|
||||||
// Found a kill, shrink wrapping of this path ends here.
|
|
||||||
return;
|
|
||||||
} else if (MBB == DefMBB) {
|
|
||||||
// There are no uses after the def.
|
|
||||||
MachineInstr *DefMI = LIs->getInstructionFromIndex(ValNo->def);
|
|
||||||
if (UseMBBs.empty()) {
|
|
||||||
// The only use must be below barrier in the barrier block. It's safe to
|
|
||||||
// remove the def.
|
|
||||||
LIs->RemoveMachineInstrFromMaps(DefMI);
|
|
||||||
DefMI->eraseFromParent();
|
|
||||||
CurrLI->removeRange(ValNo->def, LIs->getMBBEndIdx(MBB)+1);
|
|
||||||
}
|
|
||||||
} else if (MBB == BarrierMBB) {
|
|
||||||
// Remove entire live range from start of mbb to barrier.
|
|
||||||
CurrLI->removeRange(LIs->getMBBStartIdx(MBB),
|
|
||||||
LIs->getUseIndex(BarrierIdx)+1);
|
|
||||||
} else {
|
|
||||||
// Remove entire live range of the mbb out of the live interval.
|
|
||||||
CurrLI->removeRange(LIs->getMBBStartIdx(MBB), LIs->getMBBEndIdx(MBB)+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (MBB == DefMBB)
|
|
||||||
// Reached the def mbb, stop traversing this path further.
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Traverse the pathes up the predecessor chains further.
|
|
||||||
for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(),
|
|
||||||
PE = MBB->pred_end(); PI != PE; ++PI) {
|
|
||||||
MachineBasicBlock *Pred = *PI;
|
|
||||||
if (Pred == MBB)
|
|
||||||
continue;
|
|
||||||
if (Pred == DefMBB && ValNo->hasPHIKill)
|
|
||||||
// Pred is the def bb and the def reaches other val#s, we must
|
|
||||||
// allow the value to be live out of the bb.
|
|
||||||
continue;
|
|
||||||
if (!CurrLI->liveAt(LIs->getMBBEndIdx(Pred)-1))
|
|
||||||
return;
|
|
||||||
ShrinkWrapLiveInterval(ValNo, Pred, MBB, DefMBB, Visited,
|
|
||||||
Uses, UseMIs, UseMBBs);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void PreAllocSplitting::RepairLiveInterval(LiveInterval* CurrLI,
|
|
||||||
VNInfo* ValNo,
|
|
||||||
MachineInstr* DefMI,
|
|
||||||
unsigned RestoreIdx) {
|
|
||||||
// Shrink wrap the live interval by walking up the CFG and find the
|
|
||||||
// new kills.
|
|
||||||
// Now let's find all the uses of the val#.
|
|
||||||
DenseMap<MachineBasicBlock*, SmallVector<MachineOperand*, 4> > Uses;
|
|
||||||
DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 4> > UseMIs;
|
|
||||||
SmallPtrSet<MachineBasicBlock*, 4> Seen;
|
|
||||||
SmallVector<MachineBasicBlock*, 4> UseMBBs;
|
|
||||||
for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(CurrLI->reg),
|
|
||||||
UE = MRI->use_end(); UI != UE; ++UI) {
|
|
||||||
MachineOperand &UseMO = UI.getOperand();
|
|
||||||
MachineInstr *UseMI = UseMO.getParent();
|
|
||||||
unsigned UseIdx = LIs->getInstructionIndex(UseMI);
|
|
||||||
LiveInterval::iterator ULR = CurrLI->FindLiveRangeContaining(UseIdx);
|
|
||||||
if (ULR->valno != ValNo)
|
|
||||||
continue;
|
|
||||||
MachineBasicBlock *UseMBB = UseMI->getParent();
|
|
||||||
// Remember which other mbb's use this val#.
|
|
||||||
if (Seen.insert(UseMBB) && UseMBB != BarrierMBB)
|
|
||||||
UseMBBs.push_back(UseMBB);
|
|
||||||
DenseMap<MachineBasicBlock*, SmallVector<MachineOperand*, 4> >::iterator
|
|
||||||
UMII = Uses.find(UseMBB);
|
|
||||||
if (UMII != Uses.end()) {
|
|
||||||
DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 4> >::iterator
|
|
||||||
UMII2 = UseMIs.find(UseMBB);
|
|
||||||
UMII->second.push_back(&UseMO);
|
|
||||||
UMII2->second.insert(UseMI);
|
|
||||||
} else {
|
|
||||||
SmallVector<MachineOperand*, 4> Ops;
|
|
||||||
Ops.push_back(&UseMO);
|
|
||||||
Uses.insert(std::make_pair(UseMBB, Ops));
|
|
||||||
SmallPtrSet<MachineInstr*, 4> MIs;
|
|
||||||
MIs.insert(UseMI);
|
|
||||||
UseMIs.insert(std::make_pair(UseMBB, MIs));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Walk up the predecessor chains.
|
|
||||||
SmallPtrSet<MachineBasicBlock*, 8> Visited;
|
|
||||||
ShrinkWrapLiveInterval(ValNo, BarrierMBB, NULL, DefMI->getParent(), Visited,
|
|
||||||
Uses, UseMIs, UseMBBs);
|
|
||||||
|
|
||||||
// Remove live range from barrier to the restore. FIXME: Find a better
|
|
||||||
// point to re-start the live interval.
|
|
||||||
VNInfo* AfterValNo = UpdateRegisterInterval(ValNo,
|
|
||||||
LIs->getUseIndex(BarrierIdx)+1,
|
|
||||||
LIs->getDefIndex(RestoreIdx));
|
|
||||||
|
|
||||||
// Attempt to renumber the new valno into a new vreg.
|
|
||||||
RenumberValno(AfterValNo);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// RenumberValno - Split the given valno out into a new vreg, allowing it to
|
/// RenumberValno - Split the given valno out into a new vreg, allowing it to
|
||||||
/// be allocated to a different register. This function creates a new vreg,
|
/// be allocated to a different register. This function creates a new vreg,
|
||||||
/// copies the valno and its live ranges over to the new vreg's interval,
|
/// copies the valno and its live ranges over to the new vreg's interval,
|
||||||
@@ -1055,12 +734,12 @@ void PreAllocSplitting::RenumberValno(VNInfo* VN) {
|
|||||||
for (SmallVector<unsigned, 4>::iterator KI = OldVN->kills.begin(),
|
for (SmallVector<unsigned, 4>::iterator KI = OldVN->kills.begin(),
|
||||||
KE = OldVN->kills.end(); KI != KE; ++KI) {
|
KE = OldVN->kills.end(); KI != KE; ++KI) {
|
||||||
MachineInstr* MI = LIs->getInstructionFromIndex(*KI);
|
MachineInstr* MI = LIs->getInstructionFromIndex(*KI);
|
||||||
//if (!MI) continue;
|
|
||||||
unsigned DefIdx = MI->findRegisterDefOperandIdx(CurrLI->reg);
|
unsigned DefIdx = MI->findRegisterDefOperandIdx(CurrLI->reg);
|
||||||
if (DefIdx == ~0U) continue;
|
if (DefIdx == ~0U) continue;
|
||||||
if (MI->isRegReDefinedByTwoAddr(DefIdx)) {
|
if (MI->isRegReDefinedByTwoAddr(DefIdx)) {
|
||||||
VNInfo* NextVN =
|
VNInfo* NextVN =
|
||||||
CurrLI->findDefinedVNInfo(LiveIntervals::getDefIndex(*KI));
|
CurrLI->findDefinedVNInfo(LiveIntervals::getDefIndex(*KI));
|
||||||
|
if (NextVN == OldVN) continue;
|
||||||
Stack.push_back(NextVN);
|
Stack.push_back(NextVN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1131,18 +810,10 @@ bool PreAllocSplitting::Rematerialize(unsigned vreg, VNInfo* ValNo,
|
|||||||
TII->reMaterialize(MBB, RestorePt, vreg, DefMI);
|
TII->reMaterialize(MBB, RestorePt, vreg, DefMI);
|
||||||
LIs->InsertMachineInstrInMaps(prior(RestorePt), RestoreIdx);
|
LIs->InsertMachineInstrInMaps(prior(RestorePt), RestoreIdx);
|
||||||
|
|
||||||
if (KillPt->getParent() == BarrierMBB) {
|
ReconstructLiveInterval(CurrLI);
|
||||||
VNInfo* After = UpdateRegisterInterval(ValNo, LIs->getUseIndex(KillIdx)+1,
|
unsigned RematIdx = LIs->getInstructionIndex(prior(RestorePt));
|
||||||
LIs->getDefIndex(RestoreIdx));
|
RematIdx = LiveIntervals::getDefIndex(RematIdx);
|
||||||
|
RenumberValno(CurrLI->findDefinedVNInfo(RematIdx));
|
||||||
RenumberValno(After);
|
|
||||||
|
|
||||||
++NumSplits;
|
|
||||||
++NumRemats;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
RepairLiveInterval(CurrLI, ValNo, DefMI, RestoreIdx);
|
|
||||||
|
|
||||||
++NumSplits;
|
++NumSplits;
|
||||||
++NumRemats;
|
++NumRemats;
|
||||||
@@ -1315,28 +986,14 @@ bool PreAllocSplitting::SplitRegLiveInterval(LiveInterval *LI) {
|
|||||||
MachineInstr *LoadMI = prior(RestorePt);
|
MachineInstr *LoadMI = prior(RestorePt);
|
||||||
LIs->InsertMachineInstrInMaps(LoadMI, RestoreIndex);
|
LIs->InsertMachineInstrInMaps(LoadMI, RestoreIndex);
|
||||||
|
|
||||||
// If live interval is spilled in the same block as the barrier, just
|
|
||||||
// create a hole in the interval.
|
|
||||||
if (!DefMBB ||
|
|
||||||
(SpillMI && SpillMI->getParent() == BarrierMBB)) {
|
|
||||||
// Update spill stack slot live interval.
|
|
||||||
UpdateSpillSlotInterval(ValNo, LIs->getUseIndex(SpillIndex)+1,
|
|
||||||
LIs->getDefIndex(RestoreIndex));
|
|
||||||
|
|
||||||
VNInfo* After = UpdateRegisterInterval(ValNo,
|
|
||||||
LIs->getUseIndex(SpillIndex)+1,
|
|
||||||
LIs->getDefIndex(RestoreIndex));
|
|
||||||
RenumberValno(After);
|
|
||||||
|
|
||||||
++NumSplits;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update spill stack slot live interval.
|
// Update spill stack slot live interval.
|
||||||
UpdateSpillSlotInterval(ValNo, LIs->getUseIndex(SpillIndex)+1,
|
UpdateSpillSlotInterval(ValNo, LIs->getUseIndex(SpillIndex)+1,
|
||||||
LIs->getDefIndex(RestoreIndex));
|
LIs->getDefIndex(RestoreIndex));
|
||||||
|
|
||||||
RepairLiveInterval(CurrLI, ValNo, DefMI, RestoreIndex);
|
ReconstructLiveInterval(CurrLI);
|
||||||
|
unsigned RestoreIdx = LIs->getInstructionIndex(prior(RestorePt));
|
||||||
|
RestoreIdx = LiveIntervals::getDefIndex(RestoreIdx);
|
||||||
|
RenumberValno(CurrLI->findDefinedVNInfo(RestoreIdx));
|
||||||
|
|
||||||
++NumSplits;
|
++NumSplits;
|
||||||
return true;
|
return true;
|
||||||
|
Reference in New Issue
Block a user