mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-18 09:27:27 +00:00
VNInfo cleanup.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73634 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
559254b697
commit
857c4e01f8
@ -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;
|
||||
}
|
||||
|
@ -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";
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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 &&
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user