Add a LiveRangeEdit::Delegate protocol.

This will we used for keeping register allocator data structures up to date
while LiveRangeEdit is trimming live intervals.

llvm-svn: 127300
This commit is contained in:
Jakob Stoklund Olesen 2011-03-09 00:57:29 +00:00
parent d1e9ff0d6c
commit eec325fc2f
4 changed files with 38 additions and 7 deletions

View File

@ -333,7 +333,7 @@ void InlineSpiller::insertSpill(LiveInterval &NewLI,
void InlineSpiller::spill(LiveInterval *li,
SmallVectorImpl<LiveInterval*> &newIntervals,
const SmallVectorImpl<LiveInterval*> &spillIs) {
LiveRangeEdit edit(*li, newIntervals, &spillIs);
LiveRangeEdit edit(*li, newIntervals, 0, &spillIs);
spill(edit);
if (VerifySpills)
mf_.verify(&pass_, "After inline spill");

View File

@ -174,6 +174,8 @@ void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead,
ToShrink.insert(&LI);
}
if (delegate_)
delegate_->LRE_WillEraseInstruction(MI);
LIS.RemoveMachineInstrFromMaps(MI);
MI->eraseFromParent();
}

View File

@ -29,8 +29,17 @@ class MachineRegisterInfo;
class VirtRegMap;
class LiveRangeEdit {
public:
/// Callback methods for LiveRangeEdit owners.
struct Delegate {
/// Called immediately before erasing a dead machine instruction.
virtual void LRE_WillEraseInstruction(MachineInstr *MI) {}
};
private:
LiveInterval &parent_;
SmallVectorImpl<LiveInterval*> &newRegs_;
Delegate *const delegate_;
const SmallVectorImpl<LiveInterval*> *uselessRegs_;
/// firstNew_ - Index of the first register added to newRegs_.
@ -66,9 +75,13 @@ public:
/// rematerializing values because they are about to be removed.
LiveRangeEdit(LiveInterval &parent,
SmallVectorImpl<LiveInterval*> &newRegs,
Delegate *delegate,
const SmallVectorImpl<LiveInterval*> *uselessRegs = 0)
: parent_(parent), newRegs_(newRegs), uselessRegs_(uselessRegs),
firstNew_(newRegs.size()), scannedRemattable_(false) {}
: parent_(parent), newRegs_(newRegs),
delegate_(delegate),
uselessRegs_(uselessRegs),
firstNew_(newRegs.size()),
scannedRemattable_(false) {}
LiveInterval &getParent() const { return parent_; }
unsigned getReg() const { return parent_.reg; }

View File

@ -56,7 +56,10 @@ static RegisterRegAlloc greedyRegAlloc("greedy", "greedy register allocator",
createGreedyRegisterAllocator);
namespace {
class RAGreedy : public MachineFunctionPass, public RegAllocBase {
class RAGreedy : public MachineFunctionPass,
public RegAllocBase,
private LiveRangeEdit::Delegate {
// context
MachineFunction *MF;
BitVector ReservedRegs;
@ -157,6 +160,8 @@ public:
static char ID;
private:
void LRE_WillEraseInstruction(MachineInstr*);
bool checkUncachedInterference(LiveInterval&, unsigned);
LiveInterval *getSingleInterference(LiveInterval&, unsigned);
bool reassignVReg(LiveInterval &InterferingVReg, unsigned OldPhysReg);
@ -234,6 +239,17 @@ void RAGreedy::getAnalysisUsage(AnalysisUsage &AU) const {
MachineFunctionPass::getAnalysisUsage(AU);
}
//===----------------------------------------------------------------------===//
// LiveRangeEdit delegate methods
//===----------------------------------------------------------------------===//
void RAGreedy::LRE_WillEraseInstruction(MachineInstr *MI) {
// LRE itself will remove from SlotIndexes and parent basic block.
VRM->RemoveMachineInstrFromMaps(MI);
}
void RAGreedy::releaseMemory() {
SpillerInstance.reset(0);
LRStage.clear();
@ -601,7 +617,7 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg,
SmallVector<IndexPair, 8> InterferenceRanges;
mapGlobalInterference(PhysReg, InterferenceRanges);
LiveRangeEdit LREdit(VirtReg, NewVRegs);
LiveRangeEdit LREdit(VirtReg, NewVRegs, this);
SE->reset(LREdit);
// Create the main cross-block interval.
@ -1129,7 +1145,7 @@ unsigned RAGreedy::tryLocalSplit(LiveInterval &VirtReg, AllocationOrder &Order,
<< '-' << Uses[BestAfter] << ", " << BestDiff
<< ", " << (BestAfter - BestBefore + 1) << " instrs\n");
LiveRangeEdit LREdit(VirtReg, NewVRegs);
LiveRangeEdit LREdit(VirtReg, NewVRegs, this);
SE->reset(LREdit);
SE->openIntv();
@ -1181,7 +1197,7 @@ unsigned RAGreedy::trySplit(LiveInterval &VirtReg, AllocationOrder &Order,
if (Stage < RS_Block) {
SplitAnalysis::BlockPtrSet Blocks;
if (SA->getMultiUseBlocks(Blocks)) {
LiveRangeEdit LREdit(VirtReg, NewVRegs);
LiveRangeEdit LREdit(VirtReg, NewVRegs, this);
SE->reset(LREdit);
SE->splitSingleBlocks(Blocks);
setStage(NewVRegs.begin(), NewVRegs.end(), RS_Block);