VNInfo cleanup.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73634 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Lang Hames 2009-06-17 21:01:20 +00:00
parent 559254b697
commit 857c4e01f8
10 changed files with 270 additions and 142 deletions

View File

@ -33,26 +33,106 @@ namespace llvm {
class TargetRegisterInfo;
struct LiveInterval;
/// VNInfo - If the value number definition is undefined (e.g. phi
/// merge point), it contains ~0u,x. If the value number is not in use, it
/// contains ~1u,x to indicate that the value # is not used.
/// def - Instruction # of the definition.
/// - or reg # of the definition if it's a stack slot liveinterval.
/// copy - Copy iff val# is defined by a copy; zero otherwise.
/// hasPHIKill - One or more of the kills are PHI nodes.
/// redefByEC - Re-defined by early clobber somewhere during the live range.
/// kills - Instruction # of the kills.
struct VNInfo {
/// VNInfo - Value Number Information.
/// This class holds information about a machine level values, including
/// definition and use points.
///
/// Care must be taken in interpreting the def index of the value. The
/// following rules apply:
///
/// If the isDefAccurate() method returns false then the def index does not
/// actually point to the defining MachineInstr, or even (necessarily) a
/// valid MachineInstr at all. In general such a def index should not be
/// used as an index to obtain a MachineInstr. The exception is Values
/// defined by PHI instructions, after PHI elimination has occured. In this
/// case the def should point to the start of the block in which the PHI
/// existed. This fact can be used to insert code dealing with the PHI value
/// at the merge point (e.g. to spill or split it).
class VNInfo {
private:
static const uint8_t HAS_PHI_KILL = 1,
REDEF_BY_EC = 1 << 1,
IS_PHI_DEF = 1 << 2,
IS_UNUSED = 1 << 3,
IS_DEF_ACCURATE = 1 << 4;
uint8_t flags;
public:
/// The ID number of this value.
unsigned id;
/// The index of the defining instruction (if isDefAccurate() returns true).
unsigned def;
MachineInstr *copy;
bool hasPHIKill : 1;
bool redefByEC : 1;
SmallVector<unsigned, 4> kills;
VNInfo()
: id(~1U), def(~1U), copy(0), hasPHIKill(false), redefByEC(false) {}
: flags(IS_UNUSED), id(~1U), def(0), copy(0) {}
/// VNInfo constructor.
/// d is presumed to point to the actual defining instr. If it doesn't
/// setIsDefAccurate(false) should be called after construction.
VNInfo(unsigned i, unsigned d, MachineInstr *c)
: id(i), def(d), copy(c), hasPHIKill(false), redefByEC(false) {}
: flags(IS_DEF_ACCURATE), id(i), def(d), copy(c) {}
/// VNInfo construtor, copies values from orig, except for the value number.
VNInfo(unsigned i, const VNInfo &orig)
: flags(orig.flags), id(i), def(orig.def), copy(orig.copy),
kills(orig.kills) {}
/// Used for copying value number info.
unsigned getFlags() const { return flags; }
void setFlags(unsigned flags) { this->flags = flags; }
/// Returns true if one or more kills are PHI nodes.
bool hasPHIKill() const { return flags & HAS_PHI_KILL; }
void setHasPHIKill(bool hasKill) {
if (hasKill)
flags |= HAS_PHI_KILL;
else
flags &= ~HAS_PHI_KILL;
}
/// Returns true if this value is re-defined by an early clobber somewhere
/// during the live range.
bool hasRedefByEC() const { return flags & REDEF_BY_EC; }
void setHasRedefByEC(bool hasRedef) {
if (hasRedef)
flags |= REDEF_BY_EC;
else
flags &= ~REDEF_BY_EC;
}
/// Returns true if this value is defined by a PHI instruction (or was,
/// PHI instrucions may have been eliminated).
bool isPHIDef() const { return flags & IS_PHI_DEF; }
void setIsPHIDef(bool phiDef) {
if (phiDef)
flags |= IS_PHI_DEF;
else
flags &= ~IS_PHI_DEF;
}
/// Returns true if this value is unused.
bool isUnused() const { return flags & IS_UNUSED; }
void setIsUnused(bool unused) {
if (unused)
flags |= IS_UNUSED;
else
flags &= ~IS_UNUSED;
}
/// Returns true if the def is accurate.
bool isDefAccurate() const { return flags & IS_DEF_ACCURATE; }
void setIsDefAccurate(bool defAccurate) {
if (defAccurate)
flags |= IS_DEF_ACCURATE;
else
flags &= ~IS_DEF_ACCURATE;
}
};
/// LiveRange structure - This represents a simple register range in the
@ -210,15 +290,17 @@ namespace llvm {
void copyValNumInfo(VNInfo *DstValNo, const VNInfo *SrcValNo) {
DstValNo->def = SrcValNo->def;
DstValNo->copy = SrcValNo->copy;
DstValNo->hasPHIKill = SrcValNo->hasPHIKill;
DstValNo->redefByEC = SrcValNo->redefByEC;
DstValNo->setFlags(SrcValNo->getFlags());
DstValNo->kills = SrcValNo->kills;
}
/// getNextValue - Create a new value number and return it. MIIdx specifies
/// the instruction that defines the value number.
VNInfo *getNextValue(unsigned MIIdx, MachineInstr *CopyMI,
BumpPtrAllocator &VNInfoAllocator) {
bool isDefAccurate, BumpPtrAllocator &VNInfoAllocator) {
assert(MIIdx != ~0u && MIIdx != ~1u &&
"PHI def / unused flags should now be passed explicitly.");
#ifdef __GNUC__
unsigned Alignment = (unsigned)__alignof__(VNInfo);
#else
@ -229,6 +311,26 @@ namespace llvm {
static_cast<VNInfo*>(VNInfoAllocator.Allocate((unsigned)sizeof(VNInfo),
Alignment));
new (VNI) VNInfo((unsigned)valnos.size(), MIIdx, CopyMI);
VNI->setIsDefAccurate(isDefAccurate);
valnos.push_back(VNI);
return VNI;
}
/// Create a copy of the given value. The new value will be identical except
/// for the Value number.
VNInfo *createValueCopy(const VNInfo *orig, BumpPtrAllocator &VNInfoAllocator) {
#ifdef __GNUC__
unsigned Alignment = (unsigned)__alignof__(VNInfo);
#else
// FIXME: ugly.
unsigned Alignment = 8;
#endif
VNInfo *VNI =
static_cast<VNInfo*>(VNInfoAllocator.Allocate((unsigned)sizeof(VNInfo),
Alignment));
new (VNI) VNInfo((unsigned)valnos.size(), *orig);
valnos.push_back(VNI);
return VNI;
}

View File

@ -306,9 +306,9 @@ void LiveInterval::removeRange(unsigned Start, unsigned End,
VNInfo *VNI = valnos.back();
valnos.pop_back();
VNI->~VNInfo();
} while (!valnos.empty() && valnos.back()->def == ~1U);
} while (!valnos.empty() && valnos.back()->isUnused());
} else {
ValNo->def = ~1U;
ValNo->setIsUnused(true);
}
}
}
@ -354,9 +354,9 @@ void LiveInterval::removeValNo(VNInfo *ValNo) {
VNInfo *VNI = valnos.back();
valnos.pop_back();
VNI->~VNInfo();
} while (!valnos.empty() && valnos.back()->def == ~1U);
} while (!valnos.empty() && valnos.back()->isUnused());
} else {
ValNo->def = ~1U;
ValNo->setIsUnused(true);
}
}
@ -372,9 +372,8 @@ void LiveInterval::scaleNumbering(unsigned factor) {
// Scale VNI info.
for (vni_iterator VNI = vni_begin(), VNIE = vni_end(); VNI != VNIE; ++VNI) {
VNInfo *vni = *VNI;
if (vni->def != ~0U && vni->def != ~1U) {
vni->def = InstrSlots::scale(vni->def, factor);
}
vni->def = InstrSlots::scale(vni->def, factor);
for (unsigned i = 0; i < vni->kills.size(); ++i) {
if (vni->kills[i] != 0)
@ -593,9 +592,9 @@ void LiveInterval::MergeValueInAsValue(const LiveInterval &RHS,
VNInfo *VNI = valnos.back();
valnos.pop_back();
VNI->~VNInfo();
} while (!valnos.empty() && valnos.back()->def == ~1U);
} while (!valnos.empty() && valnos.back()->isUnused());
} else {
V1->def = ~1U;
V1->setIsUnused(true);
}
}
}
@ -622,7 +621,7 @@ void LiveInterval::MergeInClobberRanges(const LiveInterval &Clobbers,
else if (UnusedValNo)
ClobberValNo = UnusedValNo;
else {
UnusedValNo = ClobberValNo = getNextValue(~0U, 0, VNInfoAllocator);
UnusedValNo = ClobberValNo = getNextValue(0, 0, false, VNInfoAllocator);
ValNoMaps.insert(std::make_pair(I->valno, ClobberValNo));
}
@ -675,7 +674,7 @@ void LiveInterval::MergeInClobberRange(unsigned Start, unsigned End,
BumpPtrAllocator &VNInfoAllocator) {
// Find a value # to use for the clobber ranges. If there is already a value#
// for unknown values, use it.
VNInfo *ClobberValNo = getNextValue(~0U, 0, VNInfoAllocator);
VNInfo *ClobberValNo = getNextValue(0, 0, false, VNInfoAllocator);
iterator IP = begin();
IP = std::upper_bound(IP, end(), Start);
@ -758,9 +757,9 @@ VNInfo* LiveInterval::MergeValueNumberInto(VNInfo *V1, VNInfo *V2) {
VNInfo *VNI = valnos.back();
valnos.pop_back();
VNI->~VNInfo();
} while (valnos.back()->def == ~1U);
} while (valnos.back()->isUnused());
} else {
V1->def = ~1U;
V1->setIsUnused(true);
}
return V2;
@ -777,8 +776,7 @@ void LiveInterval::Copy(const LiveInterval &RHS,
weight = RHS.weight;
for (unsigned i = 0, e = RHS.getNumValNums(); i != e; ++i) {
const VNInfo *VNI = RHS.getValNumInfo(i);
VNInfo *NewVNI = getNextValue(~0U, 0, VNInfoAllocator);
copyValNumInfo(NewVNI, VNI);
createValueCopy(VNI, VNInfoAllocator);
}
for (unsigned i = 0, e = RHS.ranges.size(); i != e; ++i) {
const LiveRange &LR = RHS.ranges[i];
@ -830,22 +828,22 @@ void LiveInterval::print(std::ostream &OS,
const VNInfo *vni = *i;
if (vnum) OS << " ";
OS << vnum << "@";
if (vni->def == ~1U) {
if (vni->isUnused()) {
OS << "x";
} else {
if (vni->def == ~0U)
if (!vni->isDefAccurate())
OS << "?";
else
OS << vni->def;
unsigned ee = vni->kills.size();
if (ee || vni->hasPHIKill) {
if (ee || vni->hasPHIKill()) {
OS << "-(";
for (unsigned j = 0; j != ee; ++j) {
OS << vni->kills[j];
if (j != ee-1)
OS << " ";
}
if (vni->hasPHIKill) {
if (vni->hasPHIKill()) {
if (ee)
OS << " ";
OS << "phi";

View File

@ -199,7 +199,7 @@ void LiveIntervals::computeNumbering() {
// Remap the VNInfo def index, which works the same as the
// start indices above. VN's with special sentinel defs
// don't need to be remapped.
if (vni->def != ~0U && vni->def != ~1U) {
if (vni->isDefAccurate() && !vni->isUnused()) {
unsigned index = vni->def / InstrSlots::NUM;
unsigned offset = vni->def % InstrSlots::NUM;
if (offset == InstrSlots::LOAD) {
@ -447,7 +447,7 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
tii_->isMoveInstr(*mi, SrcReg, DstReg, SrcSubReg, DstSubReg))
CopyMI = mi;
// Earlyclobbers move back one.
ValNo = interval.getNextValue(defIndex, CopyMI, VNInfoAllocator);
ValNo = interval.getNextValue(defIndex, CopyMI, true, VNInfoAllocator);
assert(ValNo->id == 0 && "First value in interval is not 0?");
@ -539,13 +539,15 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
// The new value number (#1) is defined by the instruction we claimed
// defined value #0.
VNInfo *ValNo = interval.getNextValue(OldValNo->def, OldValNo->copy,
false, // update at *
VNInfoAllocator);
ValNo->setFlags(OldValNo->getFlags()); // * <- updating here
// Value#0 is now defined by the 2-addr instruction.
OldValNo->def = RedefIndex;
OldValNo->copy = 0;
if (MO.isEarlyClobber())
OldValNo->redefByEC = true;
OldValNo->setHasRedefByEC(true);
// Add the new live interval which replaces the range for the input copy.
LiveRange LR(DefIndex, RedefIndex, ValNo);
@ -577,12 +579,13 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
DOUT << " Removing [" << Start << "," << End << "] from: ";
interval.print(DOUT, tri_); DOUT << "\n";
interval.removeRange(Start, End);
VNI->hasPHIKill = true;
VNI->setHasPHIKill(true);
DOUT << " RESULT: "; interval.print(DOUT, tri_);
// Replace the interval with one of a NEW value number. Note that this
// value number isn't actually defined by an instruction, weird huh? :)
LiveRange LR(Start, End, interval.getNextValue(~0, 0, VNInfoAllocator));
LiveRange LR(Start, End, interval.getNextValue(0, 0, false, VNInfoAllocator));
LR.valno->setIsPHIDef(true);
DOUT << " replace range with " << LR;
interval.addRange(LR);
interval.addKill(LR.valno, End);
@ -604,13 +607,13 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
mi->getOpcode() == TargetInstrInfo::SUBREG_TO_REG ||
tii_->isMoveInstr(*mi, SrcReg, DstReg, SrcSubReg, DstSubReg))
CopyMI = mi;
ValNo = interval.getNextValue(defIndex, CopyMI, VNInfoAllocator);
ValNo = interval.getNextValue(defIndex, CopyMI, true, VNInfoAllocator);
unsigned killIndex = getMBBEndIdx(mbb) + 1;
LiveRange LR(defIndex, killIndex, ValNo);
interval.addRange(LR);
interval.addKill(ValNo, killIndex);
ValNo->hasPHIKill = true;
ValNo->setHasPHIKill(true);
DOUT << " +" << LR;
}
}
@ -692,9 +695,9 @@ exit:
LiveInterval::iterator OldLR = interval.FindLiveRangeContaining(start);
bool Extend = OldLR != interval.end();
VNInfo *ValNo = Extend
? OldLR->valno : interval.getNextValue(start, CopyMI, VNInfoAllocator);
? OldLR->valno : interval.getNextValue(start, CopyMI, true, VNInfoAllocator);
if (MO.isEarlyClobber() && Extend)
ValNo->redefByEC = true;
ValNo->setHasRedefByEC(true);
LiveRange LR(start, end, ValNo);
interval.addRange(LR);
interval.addKill(LR.valno, end);
@ -783,7 +786,7 @@ exit:
}
}
LiveRange LR(start, end, interval.getNextValue(~0U, 0, VNInfoAllocator));
LiveRange LR(start, end, interval.getNextValue(0, 0, false, VNInfoAllocator));
interval.addRange(LR);
interval.addKill(LR.valno, end);
DOUT << " +" << LR << '\n';
@ -1099,13 +1102,12 @@ bool LiveIntervals::isReMaterializable(const LiveInterval &li,
for (LiveInterval::const_vni_iterator i = li.vni_begin(), e = li.vni_end();
i != e; ++i) {
const VNInfo *VNI = *i;
unsigned DefIdx = VNI->def;
if (DefIdx == ~1U)
if (VNI->isUnused())
continue; // Dead val#.
// Is the def for the val# rematerializable?
if (DefIdx == ~0u)
if (!VNI->isDefAccurate())
return false;
MachineInstr *ReMatDefMI = getInstructionFromIndex(DefIdx);
MachineInstr *ReMatDefMI = getInstructionFromIndex(VNI->def);
bool DefIsLoad = false;
if (!ReMatDefMI ||
!isReMaterializable(li, VNI, ReMatDefMI, SpillIs, DefIsLoad))
@ -1450,7 +1452,7 @@ rewriteInstructionForSpills(const LiveInterval &li, const VNInfo *VNI,
if (HasUse) {
if (CreatedNewVReg) {
LiveRange LR(getLoadIndex(index), getUseIndex(index)+1,
nI.getNextValue(~0U, 0, VNInfoAllocator));
nI.getNextValue(0, 0, false, VNInfoAllocator));
DOUT << " +" << LR;
nI.addRange(LR);
} else {
@ -1464,7 +1466,7 @@ rewriteInstructionForSpills(const LiveInterval &li, const VNInfo *VNI,
}
if (HasDef) {
LiveRange LR(getDefIndex(index), getStoreIndex(index),
nI.getNextValue(~0U, 0, VNInfoAllocator));
nI.getNextValue(0, 0, false, VNInfoAllocator));
DOUT << " +" << LR;
nI.addRange(LR);
}
@ -1840,14 +1842,14 @@ addIntervalsForSpillsFast(const LiveInterval &li,
unsigned index = getInstructionIndex(MI);
if (HasUse) {
LiveRange LR(getLoadIndex(index), getUseIndex(index),
nI.getNextValue(~0U, 0, getVNInfoAllocator()));
nI.getNextValue(0, 0, false, getVNInfoAllocator()));
DOUT << " +" << LR;
nI.addRange(LR);
vrm.addRestorePoint(NewVReg, MI);
}
if (HasDef) {
LiveRange LR(getDefIndex(index), getStoreIndex(index),
nI.getNextValue(~0U, 0, getVNInfoAllocator()));
nI.getNextValue(0, 0, false, getVNInfoAllocator()));
DOUT << " +" << LR;
nI.addRange(LR);
vrm.addSpillPoint(NewVReg, true, MI);
@ -1961,12 +1963,11 @@ addIntervalsForSpills(const LiveInterval &li,
i != e; ++i) {
const VNInfo *VNI = *i;
unsigned VN = VNI->id;
unsigned DefIdx = VNI->def;
if (DefIdx == ~1U)
if (VNI->isUnused())
continue; // Dead val#.
// Is the def for the val# rematerializable?
MachineInstr *ReMatDefMI = (DefIdx == ~0u)
? 0 : getInstructionFromIndex(DefIdx);
MachineInstr *ReMatDefMI = VNI->isDefAccurate()
? getInstructionFromIndex(VNI->def) : 0;
bool dummy;
if (ReMatDefMI && isReMaterializable(li, VNI, ReMatDefMI, SpillIs, dummy)) {
// Remember how to remat the def of this val#.
@ -1977,7 +1978,7 @@ addIntervalsForSpills(const LiveInterval &li,
ReMatDefs[VN] = Clone;
bool CanDelete = true;
if (VNI->hasPHIKill) {
if (VNI->hasPHIKill()) {
// A kill is a phi node, not all of its uses can be rematerialized.
// It must not be deleted.
CanDelete = false;
@ -2287,8 +2288,8 @@ LiveRange LiveIntervals::addLiveRangeToEndOfBlock(unsigned reg,
LiveInterval& Interval = getOrCreateInterval(reg);
VNInfo* VN = Interval.getNextValue(
getInstructionIndex(startInst) + InstrSlots::DEF,
startInst, getVNInfoAllocator());
VN->hasPHIKill = true;
startInst, true, getVNInfoAllocator());
VN->setHasPHIKill(true);
VN->kills.push_back(getMBBEndIdx(startInst->getParent()));
LiveRange LR(getInstructionIndex(startInst) + InstrSlots::DEF,
getMBBEndIdx(startInst->getParent()) + 1, VN);

View File

@ -343,7 +343,7 @@ int PreAllocSplitting::CreateSpillStackSlot(unsigned Reg,
if (CurrSLI->hasAtLeastOneValue())
CurrSValNo = CurrSLI->getValNumInfo(0);
else
CurrSValNo = CurrSLI->getNextValue(~0U, 0, LSs->getVNInfoAllocator());
CurrSValNo = CurrSLI->getNextValue(0, 0, false, LSs->getVNInfoAllocator());
return SS;
}
@ -637,8 +637,9 @@ PreAllocSplitting::PerformPHIConstructionFallBack(MachineBasicBlock::iterator Us
if (Phis.count(MBB)) return Phis[MBB];
unsigned StartIndex = LIs->getMBBStartIdx(MBB);
VNInfo *RetVNI = Phis[MBB] = LI->getNextValue(~0U, /*FIXME*/ 0,
LIs->getVNInfoAllocator());
VNInfo *RetVNI = Phis[MBB] =
LI->getNextValue(0, /*FIXME*/ 0, false, LIs->getVNInfoAllocator());
if (!IsIntraBlock) LiveOut[MBB] = RetVNI;
// If there are no uses or defs between our starting point and the
@ -654,7 +655,7 @@ PreAllocSplitting::PerformPHIConstructionFallBack(MachineBasicBlock::iterator Us
IncomingVNs[*PI] = Incoming;
}
if (MBB->pred_size() == 1 && !RetVNI->hasPHIKill) {
if (MBB->pred_size() == 1 && !RetVNI->hasPHIKill()) {
VNInfo* OldVN = RetVNI;
VNInfo* NewVN = IncomingVNs.begin()->second;
VNInfo* MergedVN = LI->MergeValueNumberInto(OldVN, NewVN);
@ -678,7 +679,7 @@ PreAllocSplitting::PerformPHIConstructionFallBack(MachineBasicBlock::iterator Us
// VNInfo to represent the joined value.
for (DenseMap<MachineBasicBlock*, VNInfo*>::iterator I =
IncomingVNs.begin(), E = IncomingVNs.end(); I != E; ++I) {
I->second->hasPHIKill = true;
I->second->setHasPHIKill(true);
unsigned KillIndex = LIs->getMBBEndIdx(I->first);
if (!LiveInterval::isKill(I->second, KillIndex))
LI->addKill(I->second, KillIndex);
@ -730,7 +731,9 @@ void PreAllocSplitting::ReconstructLiveInterval(LiveInterval* LI) {
unsigned DefIdx = LIs->getInstructionIndex(&*DI);
DefIdx = LiveIntervals::getDefIndex(DefIdx);
VNInfo* NewVN = LI->getNextValue(DefIdx, 0, Alloc);
assert(DI->getOpcode() != TargetInstrInfo::PHI &&
"Following NewVN isPHIDef flag incorrect. Fix me!");
VNInfo* NewVN = LI->getNextValue(DefIdx, 0, true, Alloc);
// If the def is a move, set the copy field.
unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
@ -793,7 +796,7 @@ void PreAllocSplitting::RenumberValno(VNInfo* VN) {
// Bail out if we ever encounter a valno that has a PHI kill. We can't
// renumber these.
if (OldVN->hasPHIKill) return;
if (OldVN->hasPHIKill()) return;
VNsToCopy.push_back(OldVN);
@ -823,9 +826,7 @@ void PreAllocSplitting::RenumberValno(VNInfo* VN) {
VNInfo* OldVN = *OI;
// Copy the valno over
VNInfo* NewVN = NewLI.getNextValue(OldVN->def, OldVN->copy,
LIs->getVNInfoAllocator());
NewLI.copyValNumInfo(NewVN, OldVN);
VNInfo* NewVN = NewLI.createValueCopy(OldVN, LIs->getVNInfoAllocator());
NewLI.MergeValueInAsValue(*CurrLI, OldVN, NewVN);
// Remove the valno from the old interval
@ -873,7 +874,7 @@ bool PreAllocSplitting::Rematerialize(unsigned vreg, VNInfo* ValNo,
MachineBasicBlock::iterator KillPt = BarrierMBB->end();
unsigned KillIdx = 0;
if (ValNo->def == ~0U || DefMI->getParent() == BarrierMBB)
if (!ValNo->isDefAccurate() || DefMI->getParent() == BarrierMBB)
KillPt = findSpillPoint(BarrierMBB, Barrier, NULL, RefsInMBB, KillIdx);
else
KillPt = findNextEmptySlot(DefMI->getParent(), DefMI, KillIdx);
@ -942,7 +943,7 @@ MachineInstr* PreAllocSplitting::FoldSpill(unsigned vreg,
if (CurrSLI->hasAtLeastOneValue())
CurrSValNo = CurrSLI->getValNumInfo(0);
else
CurrSValNo = CurrSLI->getNextValue(~0U, 0, LSs->getVNInfoAllocator());
CurrSValNo = CurrSLI->getNextValue(0, 0, false, LSs->getVNInfoAllocator());
}
return FMI;
@ -1032,13 +1033,13 @@ bool PreAllocSplitting::SplitRegLiveInterval(LiveInterval *LI) {
CurrLI->FindLiveRangeContaining(LIs->getUseIndex(BarrierIdx));
VNInfo *ValNo = LR->valno;
if (ValNo->def == ~1U) {
if (ValNo->isUnused()) {
// Defined by a dead def? How can this be?
assert(0 && "Val# is defined by a dead def?");
abort();
}
MachineInstr *DefMI = (ValNo->def != ~0U)
MachineInstr *DefMI = ValNo->isDefAccurate()
? LIs->getInstructionFromIndex(ValNo->def) : NULL;
// If this would create a new join point, do not split.
@ -1072,8 +1073,8 @@ bool PreAllocSplitting::SplitRegLiveInterval(LiveInterval *LI) {
unsigned SpillIndex = 0;
MachineInstr *SpillMI = NULL;
int SS = -1;
if (ValNo->def == ~0U) {
// If it's defined by a phi, we must split just before the barrier.
if (!ValNo->isDefAccurate()) {
// If we don't know where the def is we must split just before the barrier.
if ((SpillMI = FoldSpill(LI->reg, RC, 0, Barrier,
BarrierMBB, SS, RefsInMBB))) {
SpillIndex = LIs->getInstructionIndex(SpillMI);
@ -1254,17 +1255,16 @@ bool PreAllocSplitting::removeDeadSpills(SmallPtrSet<LiveInterval*, 8>& split) {
// We don't currently try to handle definitions with PHI kills, because
// it would involve processing more than one VNInfo at once.
if (CurrVN->hasPHIKill) continue;
if (CurrVN->hasPHIKill()) continue;
// We also don't try to handle the results of PHI joins, since there's
// no defining instruction to analyze.
unsigned DefIdx = CurrVN->def;
if (DefIdx == ~0U || DefIdx == ~1U) continue;
if (!CurrVN->isDefAccurate() || CurrVN->isUnused()) continue;
// We're only interested in eliminating cruft introduced by the splitter,
// is of the form load-use or load-use-store. First, check that the
// definition is a load, and remember what stack slot we loaded it from.
MachineInstr* DefMI = LIs->getInstructionFromIndex(DefIdx);
MachineInstr* DefMI = LIs->getInstructionFromIndex(CurrVN->def);
int FrameIndex;
if (!TII->isLoadFromStackSlot(DefMI, FrameIndex)) continue;
@ -1383,7 +1383,7 @@ bool PreAllocSplitting::createsNewJoin(LiveRange* LR,
if (DefMBB == BarrierMBB)
return false;
if (LR->valno->hasPHIKill)
if (LR->valno->hasPHIKill())
return false;
unsigned MBBEnd = LIs->getMBBEndIdx(BarrierMBB);

View File

@ -358,7 +358,7 @@ unsigned RALinScan::attemptTrivialCoalescing(LiveInterval &cur, unsigned Reg) {
return Reg;
VNInfo *vni = cur.begin()->valno;
if (!vni->def || vni->def == ~1U || vni->def == ~0U)
if (!vni->def || vni->isUnused() || !vni->isDefAccurate())
return Reg;
MachineInstr *CopyMI = li_->getInstructionFromIndex(vni->def);
unsigned SrcReg, DstReg, SrcSubReg, DstSubReg, PhysReg;
@ -745,7 +745,7 @@ static void addStackInterval(LiveInterval *cur, LiveStacks *ls_,
if (SI.hasAtLeastOneValue())
VNI = SI.getValNumInfo(0);
else
VNI = SI.getNextValue(~0U, 0, ls_->getVNInfoAllocator());
VNI = SI.getNextValue(0, 0, false, ls_->getVNInfoAllocator());
LiveInterval &RI = li_->getInterval(cur->reg);
// FIXME: This may be overly conservative.
@ -921,7 +921,7 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur)
// one, e.g. X86::mov32to32_. These move instructions are not coalescable.
if (!vrm_->getRegAllocPref(cur->reg) && cur->hasAtLeastOneValue()) {
VNInfo *vni = cur->begin()->valno;
if (vni->def && vni->def != ~1U && vni->def != ~0U) {
if (vni->def && !vni->isUnused() && vni->isDefAccurate()) {
MachineInstr *CopyMI = li_->getInstructionFromIndex(vni->def);
unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
if (CopyMI &&

View File

@ -651,7 +651,7 @@ void PBQPRegAlloc::addStackInterval(const LiveInterval *spilled,
if (stackInterval.getNumValNums() != 0)
vni = stackInterval.getValNumInfo(0);
else
vni = stackInterval.getNextValue(-0U, 0, lss->getVNInfoAllocator());
vni = stackInterval.getNextValue(0, 0, false, lss->getVNInfoAllocator());
LiveInterval &rhsInterval = lis->getInterval(spilled->reg);
stackInterval.MergeRangesInAsValue(rhsInterval, vni);

View File

@ -141,7 +141,7 @@ bool SimpleRegisterCoalescing::AdjustCopiesBackFrom(LiveInterval &IntA,
// The live interval of ECX is represented as this:
// %reg20,inf = [46,47:1)[174,230:0) 0@174-(230) 1@46-(47)
// The coalescer has no idea there was a def in the middle of [174,230].
if (AValNo->redefByEC)
if (AValNo->hasRedefByEC())
return false;
// If AValNo is defined as a copy from IntB, we can potentially process this.
@ -203,7 +203,8 @@ bool SimpleRegisterCoalescing::AdjustCopiesBackFrom(LiveInterval &IntA,
for (const unsigned *SR = tri_->getSubRegisters(IntB.reg); *SR; ++SR) {
LiveInterval &SRLI = li_->getInterval(*SR);
SRLI.addRange(LiveRange(FillerStart, FillerEnd,
SRLI.getNextValue(FillerStart, 0, li_->getVNInfoAllocator())));
SRLI.getNextValue(FillerStart, 0, true,
li_->getVNInfoAllocator())));
}
}
@ -304,8 +305,10 @@ bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(LiveInterval &IntA,
assert(ALR != IntA.end() && "Live range not found!");
VNInfo *AValNo = ALR->valno;
// If other defs can reach uses of this def, then it's not safe to perform
// the optimization.
if (AValNo->def == ~0U || AValNo->def == ~1U || AValNo->hasPHIKill)
// the optimization. FIXME: Do isPHIDef and isDefAccurate both need to be
// tested?
if (AValNo->isPHIDef() || !AValNo->isDefAccurate() ||
AValNo->isUnused() || AValNo->hasPHIKill())
return false;
MachineInstr *DefMI = li_->getInstructionFromIndex(AValNo->def);
const TargetInstrDesc &TID = DefMI->getDesc();
@ -351,7 +354,7 @@ bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(LiveInterval &IntA,
unsigned OpIdx = NewMI->findRegisterUseOperandIdx(IntA.reg, false);
NewMI->getOperand(OpIdx).setIsKill();
bool BHasPHIKill = BValNo->hasPHIKill;
bool BHasPHIKill = BValNo->hasPHIKill();
SmallVector<VNInfo*, 4> BDeadValNos;
SmallVector<unsigned, 4> BKills;
std::map<unsigned, unsigned> BExtend;
@ -403,7 +406,7 @@ bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(LiveInterval &IntA,
// extended to the end of the existing live range defined by the copy.
unsigned DefIdx = li_->getDefIndex(UseIdx);
const LiveRange *DLR = IntB.getLiveRangeContaining(DefIdx);
BHasPHIKill |= DLR->valno->hasPHIKill;
BHasPHIKill |= DLR->valno->hasPHIKill();
assert(DLR->valno->def == DefIdx);
BDeadValNos.push_back(DLR->valno);
BExtend[DLR->start] = DLR->end;
@ -462,7 +465,7 @@ bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(LiveInterval &IntA,
}
}
IntB.addKills(ValNo, BKills);
ValNo->hasPHIKill = BHasPHIKill;
ValNo->setHasPHIKill(BHasPHIKill);
DOUT << " result = "; IntB.print(DOUT, tri_);
DOUT << "\n";
@ -578,8 +581,10 @@ bool SimpleRegisterCoalescing::ReMaterializeTrivialDef(LiveInterval &SrcInt,
assert(SrcLR != SrcInt.end() && "Live range not found!");
VNInfo *ValNo = SrcLR->valno;
// If other defs can reach uses of this def, then it's not safe to perform
// the optimization.
if (ValNo->def == ~0U || ValNo->def == ~1U || ValNo->hasPHIKill)
// the optimization. FIXME: Do isPHIDef and isDefAccurate both need to be
// tested?
if (ValNo->isPHIDef() || !ValNo->isDefAccurate() ||
ValNo->isUnused() || ValNo->hasPHIKill())
return false;
MachineInstr *DefMI = li_->getInstructionFromIndex(ValNo->def);
const TargetInstrDesc &TID = DefMI->getDesc();
@ -671,7 +676,7 @@ bool SimpleRegisterCoalescing::isBackEdgeCopy(MachineInstr *CopyMI,
return false;
unsigned KillIdx = li_->getMBBEndIdx(MBB) + 1;
if (DstLR->valno->kills.size() == 1 &&
DstLR->valno->kills[0] == KillIdx && DstLR->valno->hasPHIKill)
DstLR->valno->kills[0] == KillIdx && DstLR->valno->hasPHIKill())
return true;
return false;
}
@ -935,7 +940,7 @@ bool SimpleRegisterCoalescing::CanCoalesceWithImpDef(MachineInstr *CopyMI,
LiveInterval::iterator LR = li.FindLiveRangeContaining(CopyIdx);
if (LR == li.end())
return false;
if (LR->valno->hasPHIKill)
if (LR->valno->hasPHIKill())
return false;
if (LR->valno->def != CopyIdx)
return false;
@ -1682,9 +1687,9 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
E = SavedLI->vni_end(); I != E; ++I) {
const VNInfo *ValNo = *I;
VNInfo *NewValNo = RealInt.getNextValue(ValNo->def, ValNo->copy,
false, // updated at *
li_->getVNInfoAllocator());
NewValNo->hasPHIKill = ValNo->hasPHIKill;
NewValNo->redefByEC = ValNo->redefByEC;
NewValNo->setFlags(ValNo->getFlags()); // * updated here.
RealInt.addKills(NewValNo, ValNo->kills);
RealInt.MergeValueInAsValue(*SavedLI, ValNo, NewValNo);
}
@ -1723,7 +1728,8 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
for (LiveInterval::const_vni_iterator i = ResSrcInt->vni_begin(),
e = ResSrcInt->vni_end(); i != e; ++i) {
const VNInfo *vni = *i;
if (!vni->def || vni->def == ~1U || vni->def == ~0U)
// FIXME: Do isPHIDef and isDefAccurate both need to be tested?
if (!vni->def || vni->isUnused() || vni->isPHIDef() || !vni->isDefAccurate())
continue;
MachineInstr *CopyMI = li_->getInstructionFromIndex(vni->def);
unsigned NewSrcReg, NewDstReg, NewSrcSubIdx, NewDstSubIdx;
@ -1870,7 +1876,8 @@ bool SimpleRegisterCoalescing::RangeIsDefinedByCopyFromReg(LiveInterval &li,
unsigned SrcReg = li_->getVNInfoSourceReg(LR->valno);
if (SrcReg == Reg)
return true;
if (LR->valno->def == ~0U &&
// FIXME: Do isPHIDef and isDefAccurate both need to be tested?
if ((LR->valno->isPHIDef() || !LR->valno->isDefAccurate()) &&
TargetRegisterInfo::isPhysicalRegister(li.reg) &&
*tri_->getSuperRegisters(li.reg)) {
// It's a sub-register live interval, we may not have precise information.
@ -2039,7 +2046,8 @@ bool SimpleRegisterCoalescing::SimpleJoin(LiveInterval &LHS, LiveInterval &RHS){
// Okay, the final step is to loop over the RHS live intervals, adding them to
// the LHS.
LHSValNo->hasPHIKill |= VNI->hasPHIKill;
if (VNI->hasPHIKill())
LHSValNo->setHasPHIKill(true);
LHS.addKills(LHSValNo, VNI->kills);
LHS.MergeRangesInAsValue(RHS, LHSValNo);
LHS.weight += RHS.weight;
@ -2206,7 +2214,7 @@ SimpleRegisterCoalescing::JoinIntervals(LiveInterval &LHS, LiveInterval &RHS,
for (LiveInterval::vni_iterator i = LHS.vni_begin(), e = LHS.vni_end();
i != e; ++i) {
VNInfo *VNI = *i;
if (VNI->def == ~1U || VNI->copy == 0) // Src not defined by a copy?
if (VNI->isUnused() || VNI->copy == 0) // Src not defined by a copy?
continue;
// DstReg is known to be a register in the LHS interval. If the src is
@ -2223,7 +2231,7 @@ SimpleRegisterCoalescing::JoinIntervals(LiveInterval &LHS, LiveInterval &RHS,
for (LiveInterval::vni_iterator i = RHS.vni_begin(), e = RHS.vni_end();
i != e; ++i) {
VNInfo *VNI = *i;
if (VNI->def == ~1U || VNI->copy == 0) // Src not defined by a copy?
if (VNI->isUnused() || VNI->copy == 0) // Src not defined by a copy?
continue;
// DstReg is known to be a register in the RHS interval. If the src is
@ -2243,7 +2251,7 @@ SimpleRegisterCoalescing::JoinIntervals(LiveInterval &LHS, LiveInterval &RHS,
i != e; ++i) {
VNInfo *VNI = *i;
unsigned VN = VNI->id;
if (LHSValNoAssignments[VN] >= 0 || VNI->def == ~1U)
if (LHSValNoAssignments[VN] >= 0 || VNI->isUnused())
continue;
ComputeUltimateVN(VNI, NewVNInfo,
LHSValsDefinedFromRHS, RHSValsDefinedFromLHS,
@ -2253,7 +2261,7 @@ SimpleRegisterCoalescing::JoinIntervals(LiveInterval &LHS, LiveInterval &RHS,
i != e; ++i) {
VNInfo *VNI = *i;
unsigned VN = VNI->id;
if (RHSValNoAssignments[VN] >= 0 || VNI->def == ~1U)
if (RHSValNoAssignments[VN] >= 0 || VNI->isUnused())
continue;
// If this value number isn't a copy from the LHS, it's a new number.
if (RHSValsDefinedFromLHS.find(VNI) == RHSValsDefinedFromLHS.end()) {
@ -2317,7 +2325,8 @@ SimpleRegisterCoalescing::JoinIntervals(LiveInterval &LHS, LiveInterval &RHS,
VNInfo *VNI = I->first;
unsigned LHSValID = LHSValNoAssignments[VNI->id];
LiveInterval::removeKill(NewVNInfo[LHSValID], VNI->def);
NewVNInfo[LHSValID]->hasPHIKill |= VNI->hasPHIKill;
if (VNI->hasPHIKill())
NewVNInfo[LHSValID]->setHasPHIKill(true);
RHS.addKills(NewVNInfo[LHSValID], VNI->kills);
}
@ -2327,7 +2336,8 @@ SimpleRegisterCoalescing::JoinIntervals(LiveInterval &LHS, LiveInterval &RHS,
VNInfo *VNI = I->first;
unsigned RHSValID = RHSValNoAssignments[VNI->id];
LiveInterval::removeKill(NewVNInfo[RHSValID], VNI->def);
NewVNInfo[RHSValID]->hasPHIKill |= VNI->hasPHIKill;
if (VNI->hasPHIKill())
NewVNInfo[RHSValID]->setHasPHIKill(true);
LHS.addKills(NewVNInfo[RHSValID], VNI->kills);
}

View File

@ -47,16 +47,24 @@ protected:
tii = mf->getTarget().getInstrInfo();
}
/// Insert a store of the given vreg to the given stack slot immediately
/// after the given instruction. Returns the base index of the inserted
/// instruction. The caller is responsible for adding an appropriate
/// LiveInterval to the LiveIntervals analysis.
unsigned insertStoreFor(MachineInstr *mi, unsigned ss,
unsigned newVReg,
const TargetRegisterClass *trc) {
MachineBasicBlock::iterator nextInstItr(mi);
++nextInstItr;
/// Ensures there is space before the given machine instruction, returns the
/// instruction's new number.
unsigned makeSpaceBefore(MachineInstr *mi) {
if (!lis->hasGapBeforeInstr(lis->getInstructionIndex(mi))) {
lis->scaleNumbering(2);
ls->scaleNumbering(2);
}
unsigned miIdx = lis->getInstructionIndex(mi);
assert(lis->hasGapBeforeInstr(miIdx));
return miIdx;
}
/// Ensure there is space after the given machine instruction, returns the
/// instruction's new number.
unsigned makeSpaceAfter(MachineInstr *mi) {
if (!lis->hasGapAfterInstr(lis->getInstructionIndex(mi))) {
lis->scaleNumbering(2);
ls->scaleNumbering(2);
@ -66,7 +74,23 @@ protected:
assert(lis->hasGapAfterInstr(miIdx));
tii->storeRegToStackSlot(*mi->getParent(), nextInstItr, newVReg,
return miIdx;
}
/// Insert a store of the given vreg to the given stack slot immediately
/// after the given instruction. Returns the base index of the inserted
/// instruction. The caller is responsible for adding an appropriate
/// LiveInterval to the LiveIntervals analysis.
unsigned insertStoreFor(MachineInstr *mi, unsigned ss,
unsigned vreg,
const TargetRegisterClass *trc) {
MachineBasicBlock::iterator nextInstItr(mi);
++nextInstItr;
unsigned miIdx = makeSpaceAfter(mi);
tii->storeRegToStackSlot(*mi->getParent(), nextInstItr, vreg,
true, ss, trc);
MachineBasicBlock::iterator storeInstItr(mi);
++storeInstItr;
@ -86,20 +110,13 @@ protected:
/// instruction. The caller is responsible for adding an appropriate
/// LiveInterval to the LiveIntervals analysis.
unsigned insertLoadFor(MachineInstr *mi, unsigned ss,
unsigned newVReg,
unsigned vreg,
const TargetRegisterClass *trc) {
MachineBasicBlock::iterator useInstItr(mi);
if (!lis->hasGapBeforeInstr(lis->getInstructionIndex(mi))) {
lis->scaleNumbering(2);
ls->scaleNumbering(2);
}
unsigned miIdx = lis->getInstructionIndex(mi);
assert(lis->hasGapBeforeInstr(miIdx));
tii->loadRegFromStackSlot(*mi->getParent(), useInstItr, newVReg, ss, trc);
unsigned miIdx = makeSpaceBefore(mi);
tii->loadRegFromStackSlot(*mi->getParent(), useInstItr, vreg, ss, trc);
MachineBasicBlock::iterator loadInstItr(mi);
--loadInstItr;
MachineInstr *loadInst = &*loadInstItr;
@ -113,7 +130,6 @@ protected:
return loadInstIdx;
}
/// Add spill ranges for every use/def of the live interval, inserting loads
/// immediately before each use, and stores after each def. No folding is
/// attempted.
@ -178,7 +194,7 @@ protected:
end = lis->getUseIndex(lis->getInstructionIndex(mi));
VNInfo *vni =
newLI->getNextValue(loadInstIdx, 0, lis->getVNInfoAllocator());
newLI->getNextValue(loadInstIdx, 0, true, lis->getVNInfoAllocator());
vni->kills.push_back(lis->getInstructionIndex(mi));
LiveRange lr(start, end, vni);
@ -191,7 +207,7 @@ protected:
end = lis->getUseIndex(storeInstIdx);
VNInfo *vni =
newLI->getNextValue(storeInstIdx, 0, lis->getVNInfoAllocator());
newLI->getNextValue(storeInstIdx, 0, true, lis->getVNInfoAllocator());
vni->kills.push_back(storeInstIdx);
LiveRange lr(start, end, vni);
@ -201,7 +217,6 @@ protected:
added.push_back(newLI);
}
return added;
}

View File

@ -18,6 +18,7 @@ namespace llvm {
class LiveStacks;
class MachineFunction;
class VirtRegMap;
class MachineInstr;
/// Spiller interface.
///
@ -26,7 +27,11 @@ namespace llvm {
class Spiller {
public:
virtual ~Spiller() = 0;
/// Spill the given live range. The method used will depend on the Spiller
/// implementation selected.
virtual std::vector<LiveInterval*> spill(LiveInterval *li) = 0;
};
/// Create and return a spiller object, as specified on the command line.

View File

@ -827,7 +827,7 @@ void StrongPHIElimination::InsertCopies(MachineDomTreeNode* MDTN,
// Add a live range for the new vreg
LiveInterval& Int = LI.getInterval(I->getOperand(i).getReg());
VNInfo* FirstVN = *Int.vni_begin();
FirstVN->hasPHIKill = false;
FirstVN->setHasPHIKill(false);
if (I->getOperand(i).isKill())
FirstVN->kills.push_back(
LiveIntervals::getUseIndex(LI.getInstructionIndex(I)));
@ -886,10 +886,7 @@ bool StrongPHIElimination::mergeLiveIntervals(unsigned primary,
VNInfo* OldVN = R.valno;
VNInfo*& NewVN = VNMap[OldVN];
if (!NewVN) {
NewVN = LHS.getNextValue(OldVN->def,
OldVN->copy,
LI.getVNInfoAllocator());
NewVN->kills = OldVN->kills;
NewVN = LHS.createValueCopy(OldVN, LI.getVNInfoAllocator());
}
LiveRange LR (R.start, R.end, NewVN);
@ -987,7 +984,7 @@ bool StrongPHIElimination::runOnMachineFunction(MachineFunction &Fn) {
LiveInterval& Int = LI.getOrCreateInterval(I->first);
const LiveRange* LR =
Int.getLiveRangeContaining(LI.getMBBEndIdx(SI->second));
LR->valno->hasPHIKill = true;
LR->valno->setHasPHIKill(true);
I->second.erase(SI->first);
}
@ -1037,7 +1034,7 @@ bool StrongPHIElimination::runOnMachineFunction(MachineFunction &Fn) {
// now has an unknown def.
unsigned idx = LI.getDefIndex(LI.getInstructionIndex(PInstr));
const LiveRange* PLR = PI.getLiveRangeContaining(idx);
PLR->valno->def = ~0U;
PLR->valno->setIsPHIDef(true);
LiveRange R (LI.getMBBStartIdx(PInstr->getParent()),
PLR->start, PLR->valno);
PI.addRange(R);