"enable-subreg-liveness", cl::Hidden, cl::init(true),
cl::desc("Enable subregister liveness tracking."));
+namespace llvm {
+cl::opt<bool> UseSegmentSetForPhysRegs(
+ "use-segment-set-for-physregs", cl::Hidden, cl::init(true),
+ cl::desc(
+ "Use segment set for the computation of the live ranges of physregs."));
+}
+
void LiveIntervals::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesCFG();
AU.addRequired<AliasAnalysis>();
assert(LRCalc && "LRCalc not initialized.");
assert(LI.empty() && "Should only compute empty intervals.");
LRCalc->reset(MF, getSlotIndexes(), DomTree, &getVNInfoAllocator());
- LRCalc->calculate(LI);
+ LRCalc->calculate(LI, MRI->shouldTrackSubRegLiveness(LI.reg));
computeDeadValues(LI, nullptr);
}
LRCalc->extendToUses(LR, Reg);
}
}
+
+ // Flush the segment set to the segment vector.
+ if (UseSegmentSetForPhysRegs)
+ LR.flushSegmentSet();
}
unsigned Unit = *Units;
LiveRange *LR = RegUnitRanges[Unit];
if (!LR) {
- LR = RegUnitRanges[Unit] = new LiveRange();
+ // Use segment set to speed-up initial computation of the live range.
+ LR = RegUnitRanges[Unit] = new LiveRange(UseSegmentSetForPhysRegs);
NewRanges.push_back(Unit);
}
VNInfo *VNI = LR->createDeadDef(Begin, getVNInfoAllocator());
for (auto VNI : LI.valnos) {
if (VNI->isUnused())
continue;
- LiveRange::iterator I = LI.FindSegmentContaining(VNI->def);
+ SlotIndex Def = VNI->def;
+ LiveRange::iterator I = LI.FindSegmentContaining(Def);
assert(I != LI.end() && "Missing segment for VNI");
- if (I->end != VNI->def.getDeadSlot())
+
+ // Is the register live before? Otherwise we may have to add a read-undef
+ // flag for subregister defs.
+ if (MRI->shouldTrackSubRegLiveness(LI.reg)) {
+ if ((I == LI.begin() || std::prev(I)->end < Def) && !VNI->isPHIDef()) {
+ MachineInstr *MI = getInstructionFromIndex(Def);
+ MI->addRegisterDefReadUndef(LI.reg);
+ }
+ }
+
+ if (I->end != Def.getDeadSlot())
continue;
if (VNI->isPHIDef()) {
// This is a dead PHI. Remove it.
VNI->markUnused();
LI.removeSegment(I);
- DEBUG(dbgs() << "Dead PHI at " << VNI->def << " may separate interval\n");
+ DEBUG(dbgs() << "Dead PHI at " << Def << " may separate interval\n");
PHIRemoved = true;
} else {
// This is a dead def. Make sure the instruction knows.
- MachineInstr *MI = getInstructionFromIndex(VNI->def);
+ MachineInstr *MI = getInstructionFromIndex(Def);
assert(MI && "No instruction defining live value");
MI->addRegisterDead(LI.reg, TRI);
if (dead && MI->allDefsAreDead()) {
- DEBUG(dbgs() << "All defs dead: " << VNI->def << '\t' << *MI);
+ DEBUG(dbgs() << "All defs dead: " << Def << '\t' << *MI);
dead->push_back(MI);
}
}
}
}
-void LiveIntervals::pruneValue(LiveInterval &LI, SlotIndex Kill,
- SmallVectorImpl<SlotIndex> *EndPoints) {
- pruneValue((LiveRange&)LI, Kill, EndPoints);
-
- for (LiveInterval::SubRange &SR : LI.subranges()) {
- pruneValue(SR, Kill, nullptr);
- }
-}
-
//===----------------------------------------------------------------------===//
// Register allocator hooks.
//
RU.push_back(std::make_pair(&RURange, RURange.find(LI.begin()->end)));
}
- if (MRI->tracksSubRegLiveness()) {
+ if (MRI->subRegLivenessEnabled()) {
SRs.clear();
for (const LiveInterval::SubRange &SR : LI.subranges()) {
SRs.push_back(std::make_pair(&SR, SR.find(LI.begin()->end)));
// There should be no kill flag on FOO when %vreg5 is rewritten as %EAX.
for (auto &RUP : RU) {
const LiveRange &RURange = *RUP.first;
- LiveRange::const_iterator I = RUP.second;
+ LiveRange::const_iterator &I = RUP.second;
if (I == RURange.end())
continue;
I = RURange.advanceTo(I, RI->end);
goto CancelKill;
}
- if (MRI->tracksSubRegLiveness()) {
+ if (MRI->subRegLivenessEnabled()) {
// When reading a partial undefined value we must not add a kill flag.
// The regalloc might have used the undef lane for something else.
// Example:
DefinedLanesMask = 0;
for (auto &SRP : SRs) {
const LiveInterval::SubRange &SR = *SRP.first;
- LiveRange::const_iterator I = SRP.second;
+ LiveRange::const_iterator &I = SRP.second;
if (I == SR.end())
continue;
I = SR.advanceTo(I, RI->end);
repairOldRegInRange(Begin, End, endIdx, LI, Reg);
}
}
+
+void LiveIntervals::removePhysRegDefAt(unsigned Reg, SlotIndex Pos) {
+ for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units) {
+ if (LiveRange *LR = getCachedRegUnit(*Units))
+ if (VNInfo *VNI = LR->getVNInfoAt(Pos))
+ LR->removeValNo(VNI);
+ }
+}
+
+void LiveIntervals::removeVRegDefAt(LiveInterval &LI, SlotIndex Pos) {
+ VNInfo *VNI = LI.getVNInfoAt(Pos);
+ if (VNI == nullptr)
+ return;
+ LI.removeValNo(VNI);
+
+ // Also remove the value in subranges.
+ for (LiveInterval::SubRange &S : LI.subranges()) {
+ if (VNInfo *SVNI = S.getVNInfoAt(Pos))
+ S.removeValNo(SVNI);
+ }
+ LI.removeEmptySubRanges();
+}