Skip to content

Commit

Permalink
Refactored the LiveRangeEdit interface so that MachineFunction, Targe…
Browse files Browse the repository at this point in the history
…tInstrInfo, MachineRegisterInfo, LiveIntervals, and VirtRegMap are all passed into the constructor and stored as members instead of passed in to each method.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153903 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
cooperp committed Apr 2, 2012
1 parent 3197b44 commit 8a06af9
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 93 deletions.
22 changes: 11 additions & 11 deletions lib/CodeGen/InlineSpiller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -655,7 +655,7 @@ void InlineSpiller::analyzeSiblingValues() {
if (OrigVNI->def != VNI->def)
DefMI = traceSiblingValue(Reg, VNI, OrigVNI);
}
if (DefMI && Edit->checkRematerializable(VNI, DefMI, TII, AA)) {
if (DefMI && Edit->checkRematerializable(VNI, DefMI, AA)) {
DEBUG(dbgs() << "Value " << PrintReg(Reg) << ':' << VNI->id << '@'
<< VNI->def << " may remat from " << *DefMI);
}
Expand Down Expand Up @@ -856,7 +856,7 @@ bool InlineSpiller::reMaterializeFor(LiveInterval &VirtReg,
SibValueMap::const_iterator SibI = SibValues.find(ParentVNI);
if (SibI != SibValues.end())
RM.OrigMI = SibI->second.DefMI;
if (!Edit->canRematerializeAt(RM, UseIdx, false, LIS)) {
if (!Edit->canRematerializeAt(RM, UseIdx, false)) {
markValueUsed(&VirtReg, ParentVNI);
DEBUG(dbgs() << "\tcannot remat for " << UseIdx << '\t' << *MI);
return false;
Expand All @@ -883,12 +883,12 @@ bool InlineSpiller::reMaterializeFor(LiveInterval &VirtReg,
}

// Alocate a new register for the remat.
LiveInterval &NewLI = Edit->createFrom(Original, LIS, VRM);
LiveInterval &NewLI = Edit->createFrom(Original);
NewLI.markNotSpillable();

// Finally we can rematerialize OrigMI before MI.
SlotIndex DefIdx = Edit->rematerializeAt(*MI->getParent(), MI, NewLI.reg, RM,
LIS, TII, TRI);
TRI);
DEBUG(dbgs() << "\tremat: " << DefIdx << '\t'
<< *LIS.getInstructionFromIndex(DefIdx));

Expand All @@ -913,7 +913,7 @@ bool InlineSpiller::reMaterializeFor(LiveInterval &VirtReg,
/// and trim the live ranges after.
void InlineSpiller::reMaterializeAll() {
// analyzeSiblingValues has already tested all relevant defining instructions.
if (!Edit->anyRematerializable(LIS, TII, AA))
if (!Edit->anyRematerializable(AA))
return;

UsedValues.clear();
Expand Down Expand Up @@ -954,7 +954,7 @@ void InlineSpiller::reMaterializeAll() {
if (DeadDefs.empty())
return;
DEBUG(dbgs() << "Remat created " << DeadDefs.size() << " dead defs.\n");
Edit->eliminateDeadDefs(DeadDefs, LIS, VRM, TII, RegsToSpill);
Edit->eliminateDeadDefs(DeadDefs, RegsToSpill);

// Get rid of deleted and empty intervals.
for (unsigned i = RegsToSpill.size(); i != 0; --i) {
Expand All @@ -966,7 +966,7 @@ void InlineSpiller::reMaterializeAll() {
LiveInterval &LI = LIS.getInterval(Reg);
if (!LI.empty())
continue;
Edit->eraseVirtReg(Reg, LIS);
Edit->eraseVirtReg(Reg);
RegsToSpill.erase(RegsToSpill.begin() + (i - 1));
}
DEBUG(dbgs() << RegsToSpill.size() << " registers to spill after remat.\n");
Expand Down Expand Up @@ -1181,7 +1181,7 @@ void InlineSpiller::spillAroundUses(unsigned Reg) {

// Allocate interval around instruction.
// FIXME: Infer regclass from instruction alone.
LiveInterval &NewLI = Edit->createFrom(Reg, LIS, VRM);
LiveInterval &NewLI = Edit->createFrom(Reg);
NewLI.markNotSpillable();

if (RI.Reads)
Expand Down Expand Up @@ -1244,7 +1244,7 @@ void InlineSpiller::spillAll() {
// Hoisted spills may cause dead code.
if (!DeadDefs.empty()) {
DEBUG(dbgs() << "Eliminating " << DeadDefs.size() << " dead defs\n");
Edit->eliminateDeadDefs(DeadDefs, LIS, VRM, TII, RegsToSpill);
Edit->eliminateDeadDefs(DeadDefs, RegsToSpill);
}

// Finally delete the SnippetCopies.
Expand All @@ -1260,7 +1260,7 @@ void InlineSpiller::spillAll() {

// Delete all spilled registers.
for (unsigned i = 0, e = RegsToSpill.size(); i != e; ++i)
Edit->eraseVirtReg(RegsToSpill[i], LIS);
Edit->eraseVirtReg(RegsToSpill[i]);
}

void InlineSpiller::spill(LiveRangeEdit &edit) {
Expand Down Expand Up @@ -1289,5 +1289,5 @@ void InlineSpiller::spill(LiveRangeEdit &edit) {
if (!RegsToSpill.empty())
spillAll();

Edit->calculateRegClassAndHint(MF, LIS, Loops);
Edit->calculateRegClassAndHint(MF, Loops);
}
74 changes: 28 additions & 46 deletions lib/CodeGen/LiveRangeEdit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,71 +31,62 @@ STATISTIC(NumFracRanges, "Number of live ranges fractured by DCE");

void LiveRangeEdit::Delegate::anchor() { }

LiveInterval &LiveRangeEdit::createFrom(unsigned OldReg,
LiveIntervals &LIS,
VirtRegMap &VRM) {
MachineRegisterInfo &MRI = VRM.getRegInfo();
LiveInterval &LiveRangeEdit::createFrom(unsigned OldReg) {
unsigned VReg = MRI.createVirtualRegister(MRI.getRegClass(OldReg));
VRM.grow();
VRM.setIsSplitFromReg(VReg, VRM.getOriginal(OldReg));
VRM->grow();
VRM->setIsSplitFromReg(VReg, VRM->getOriginal(OldReg));
LiveInterval &LI = LIS.getOrCreateInterval(VReg);
newRegs_.push_back(&LI);
return LI;
}

bool LiveRangeEdit::checkRematerializable(VNInfo *VNI,
const MachineInstr *DefMI,
const TargetInstrInfo &tii,
AliasAnalysis *aa) {
assert(DefMI && "Missing instruction");
scannedRemattable_ = true;
if (!tii.isTriviallyReMaterializable(DefMI, aa))
if (!TII.isTriviallyReMaterializable(DefMI, aa))
return false;
remattable_.insert(VNI);
return true;
}

void LiveRangeEdit::scanRemattable(LiveIntervals &lis,
const TargetInstrInfo &tii,
AliasAnalysis *aa) {
void LiveRangeEdit::scanRemattable(AliasAnalysis *aa) {
for (LiveInterval::vni_iterator I = parent_.vni_begin(),
E = parent_.vni_end(); I != E; ++I) {
VNInfo *VNI = *I;
if (VNI->isUnused())
continue;
MachineInstr *DefMI = lis.getInstructionFromIndex(VNI->def);
MachineInstr *DefMI = LIS.getInstructionFromIndex(VNI->def);
if (!DefMI)
continue;
checkRematerializable(VNI, DefMI, tii, aa);
checkRematerializable(VNI, DefMI, aa);
}
scannedRemattable_ = true;
}

bool LiveRangeEdit::anyRematerializable(LiveIntervals &lis,
const TargetInstrInfo &tii,
AliasAnalysis *aa) {
bool LiveRangeEdit::anyRematerializable(AliasAnalysis *aa) {
if (!scannedRemattable_)
scanRemattable(lis, tii, aa);
scanRemattable(aa);
return !remattable_.empty();
}

/// allUsesAvailableAt - Return true if all registers used by OrigMI at
/// OrigIdx are also available with the same value at UseIdx.
bool LiveRangeEdit::allUsesAvailableAt(const MachineInstr *OrigMI,
SlotIndex OrigIdx,
SlotIndex UseIdx,
LiveIntervals &lis) {
SlotIndex UseIdx) {
OrigIdx = OrigIdx.getRegSlot(true);
UseIdx = UseIdx.getRegSlot(true);
for (unsigned i = 0, e = OrigMI->getNumOperands(); i != e; ++i) {
const MachineOperand &MO = OrigMI->getOperand(i);
if (!MO.isReg() || !MO.getReg() || MO.isDef())
continue;
// Reserved registers are OK.
if (MO.isUndef() || !lis.hasInterval(MO.getReg()))
if (MO.isUndef() || !LIS.hasInterval(MO.getReg()))
continue;

LiveInterval &li = lis.getInterval(MO.getReg());
LiveInterval &li = LIS.getInterval(MO.getReg());
const VNInfo *OVNI = li.getVNInfoAt(OrigIdx);
if (!OVNI)
continue;
Expand All @@ -107,8 +98,7 @@ bool LiveRangeEdit::allUsesAvailableAt(const MachineInstr *OrigMI,

bool LiveRangeEdit::canRematerializeAt(Remat &RM,
SlotIndex UseIdx,
bool cheapAsAMove,
LiveIntervals &lis) {
bool cheapAsAMove) {
assert(scannedRemattable_ && "Call anyRematerializable first");

// Use scanRemattable info.
Expand All @@ -118,10 +108,10 @@ bool LiveRangeEdit::canRematerializeAt(Remat &RM,
// No defining instruction provided.
SlotIndex DefIdx;
if (RM.OrigMI)
DefIdx = lis.getInstructionIndex(RM.OrigMI);
DefIdx = LIS.getInstructionIndex(RM.OrigMI);
else {
DefIdx = RM.ParentVNI->def;
RM.OrigMI = lis.getInstructionFromIndex(DefIdx);
RM.OrigMI = LIS.getInstructionFromIndex(DefIdx);
assert(RM.OrigMI && "No defining instruction for remattable value");
}

Expand All @@ -130,7 +120,7 @@ bool LiveRangeEdit::canRematerializeAt(Remat &RM,
return false;

// Verify that all used registers are available with the same values.
if (!allUsesAvailableAt(RM.OrigMI, DefIdx, UseIdx, lis))
if (!allUsesAvailableAt(RM.OrigMI, DefIdx, UseIdx))
return false;

return true;
Expand All @@ -140,27 +130,22 @@ SlotIndex LiveRangeEdit::rematerializeAt(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
unsigned DestReg,
const Remat &RM,
LiveIntervals &lis,
const TargetInstrInfo &tii,
const TargetRegisterInfo &tri,
bool Late) {
assert(RM.OrigMI && "Invalid remat");
tii.reMaterialize(MBB, MI, DestReg, 0, RM.OrigMI, tri);
TII.reMaterialize(MBB, MI, DestReg, 0, RM.OrigMI, tri);
rematted_.insert(RM.ParentVNI);
return lis.getSlotIndexes()->insertMachineInstrInMaps(--MI, Late)
return LIS.getSlotIndexes()->insertMachineInstrInMaps(--MI, Late)
.getRegSlot();
}

void LiveRangeEdit::eraseVirtReg(unsigned Reg, LiveIntervals &LIS) {
void LiveRangeEdit::eraseVirtReg(unsigned Reg) {
if (delegate_ && delegate_->LRE_CanEraseVirtReg(Reg))
LIS.removeInterval(Reg);
}

bool LiveRangeEdit::foldAsLoad(LiveInterval *LI,
SmallVectorImpl<MachineInstr*> &Dead,
MachineRegisterInfo &MRI,
LiveIntervals &LIS,
const TargetInstrInfo &TII) {
SmallVectorImpl<MachineInstr*> &Dead) {
MachineInstr *DefMI = 0, *UseMI = 0;

// Check that there is a single def and a single use.
Expand Down Expand Up @@ -206,13 +191,10 @@ bool LiveRangeEdit::foldAsLoad(LiveInterval *LI,
}

void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead,
LiveIntervals &LIS, VirtRegMap &VRM,
const TargetInstrInfo &TII,
ArrayRef<unsigned> RegsBeingSpilled) {
SetVector<LiveInterval*,
SmallVector<LiveInterval*, 8>,
SmallPtrSet<LiveInterval*, 8> > ToShrink;
MachineRegisterInfo &MRI = VRM.getRegInfo();

for (;;) {
// Erase all dead defs.
Expand Down Expand Up @@ -263,7 +245,7 @@ void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead,
LI.removeValNo(VNI);
if (LI.empty()) {
ToShrink.remove(&LI);
eraseVirtReg(Reg, LIS);
eraseVirtReg(Reg);
}
}
}
Expand All @@ -282,12 +264,14 @@ void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead,
// Shrink just one live interval. Then delete new dead defs.
LiveInterval *LI = ToShrink.back();
ToShrink.pop_back();
if (foldAsLoad(LI, Dead, MRI, LIS, TII))
if (foldAsLoad(LI, Dead))
continue;
if (delegate_)
delegate_->LRE_WillShrinkVirtReg(LI->reg);
if (!LIS.shrinkToUses(LI, &Dead))
continue;
if (!VRM)
continue;

// Don't create new intervals for a register being spilled.
// The new intervals would have to be spilled anyway so its not worth it.
Expand All @@ -302,7 +286,7 @@ void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead,
}

if (BeingSpilled) continue;

if (!VRM) continue;

// LI may have been separated, create new intervals.
LI->RenumberValues(LIS);
Expand All @@ -311,16 +295,16 @@ void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead,
if (NumComp <= 1)
continue;
++NumFracRanges;
bool IsOriginal = VRM.getOriginal(LI->reg) == LI->reg;
bool IsOriginal = VRM->getOriginal(LI->reg) == LI->reg;
DEBUG(dbgs() << NumComp << " components: " << *LI << '\n');
SmallVector<LiveInterval*, 8> Dups(1, LI);
for (unsigned i = 1; i != NumComp; ++i) {
Dups.push_back(&createFrom(LI->reg, LIS, VRM));
Dups.push_back(&createFrom(LI->reg));
// If LI is an original interval that hasn't been split yet, make the new
// intervals their own originals instead of referring to LI. The original
// interval must contain all the split products, and LI doesn't.
if (IsOriginal)
VRM.setIsSplitFromReg(Dups.back()->reg, 0);
VRM->setIsSplitFromReg(Dups.back()->reg, 0);
if (delegate_)
delegate_->LRE_DidCloneVirtReg(Dups.back()->reg, LI->reg);
}
Expand All @@ -329,10 +313,8 @@ void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead,
}

void LiveRangeEdit::calculateRegClassAndHint(MachineFunction &MF,
LiveIntervals &LIS,
const MachineLoopInfo &Loops) {
VirtRegAuxInfo VRAI(MF, LIS, Loops);
MachineRegisterInfo &MRI = MF.getRegInfo();
for (iterator I = begin(), E = end(); I != E; ++I) {
LiveInterval &LI = **I;
if (MRI.recomputeRegClass(LI.reg, MF.getTarget()))
Expand Down
Loading

0 comments on commit 8a06af9

Please sign in to comment.