LiveIntervalAnalysis: Cleanup computeDeadValues

- This also fixes a bug introduced in r223880 where values were not
  correctly marked as Dead anymore.
- Cleanup computeDeadValues(): split up SubRange code variant, simplify
  arguments.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@224538 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Matthias Braun
2014-12-18 19:58:52 +00:00
parent a75626b56b
commit b82636bb80
3 changed files with 48 additions and 35 deletions

View File

@@ -472,6 +472,12 @@ namespace llvm {
removeSegment(S.start, S.end, RemoveDeadValNo); removeSegment(S.start, S.end, RemoveDeadValNo);
} }
/// Remove segment pointed to by iterator @p I from this range. This does
/// not remove dead value numbers.
iterator removeSegment(iterator I) {
return segments.erase(I);
}
/// Query Liveness at Idx. /// Query Liveness at Idx.
/// The sub-instruction slot of Idx doesn't matter, only the instruction /// The sub-instruction slot of Idx doesn't matter, only the instruction
/// it refers to is considered. /// it refers to is considered.

View File

@@ -158,7 +158,7 @@ namespace llvm {
/// shrinkToUses(LiveInterval *li, SmallVectorImpl<MachineInstr*> *dead) /// shrinkToUses(LiveInterval *li, SmallVectorImpl<MachineInstr*> *dead)
/// that works on a subregister live range and only looks at uses matching /// that works on a subregister live range and only looks at uses matching
/// the lane mask of the subregister range. /// the lane mask of the subregister range.
bool shrinkToUses(LiveInterval::SubRange &SR, unsigned Reg); void shrinkToUses(LiveInterval::SubRange &SR, unsigned Reg);
/// extendToIndices - Extend the live range of LI to reach all points in /// extendToIndices - Extend the live range of LI to reach all points in
/// Indices. The points in the Indices array must be jointly dominated by /// Indices. The points in the Indices array must be jointly dominated by
@@ -406,17 +406,15 @@ namespace llvm {
/// Compute RegMaskSlots and RegMaskBits. /// Compute RegMaskSlots and RegMaskBits.
void computeRegMasks(); void computeRegMasks();
/// \brief Walk the values in the @p LR live range and compute which ones /// Walk the values in @p LI and check for dead values:
/// are dead in live range @p Segments. Dead values are not deleted,
/// however:
/// - Dead PHIDef values are marked as unused. /// - Dead PHIDef values are marked as unused.
/// - if @p dead != nullptr then dead operands are marked as such and /// - Dead operands are marked as such.
/// completely dead machine instructions are added to the @p dead vector. /// - Completely dead machine instructions are added to the @p dead vector
/// - CanSeparate is set to true if the interval may have been separated /// if it is not nullptr.
/// into multiple connected components. /// Returns true if any PHI value numbers have been removed which may
void computeDeadValues(LiveRange &Segments, LiveRange &LR, /// have separated the interval into multiple connected components.
bool *CanSeparate = nullptr, unsigned Reg = 0, bool computeDeadValues(LiveInterval &LI,
SmallVectorImpl<MachineInstr*> *dead = nullptr); SmallVectorImpl<MachineInstr*> *dead);
static LiveInterval* createInterval(unsigned Reg); static LiveInterval* createInterval(unsigned Reg);

View File

@@ -193,7 +193,7 @@ void LiveIntervals::computeVirtRegInterval(LiveInterval &LI) {
assert(LI.empty() && "Should only compute empty intervals."); assert(LI.empty() && "Should only compute empty intervals.");
LRCalc->reset(MF, getSlotIndexes(), DomTree, &getVNInfoAllocator()); LRCalc->reset(MF, getSlotIndexes(), DomTree, &getVNInfoAllocator());
LRCalc->calculate(LI); LRCalc->calculate(LI);
computeDeadValues(LI, LI); computeDeadValues(LI, nullptr);
} }
void LiveIntervals::computeVirtRegs() { void LiveIntervals::computeVirtRegs() {
@@ -433,49 +433,46 @@ bool LiveIntervals::shrinkToUses(LiveInterval *li,
createSegmentsForValues(NewLR, make_range(li->vni_begin(), li->vni_end())); createSegmentsForValues(NewLR, make_range(li->vni_begin(), li->vni_end()));
extendSegmentsToUses(NewLR, *Indexes, WorkList, *li); extendSegmentsToUses(NewLR, *Indexes, WorkList, *li);
// Handle dead values.
bool CanSeparate;
computeDeadValues(NewLR, *li, &CanSeparate, li->reg, dead);
// Move the trimmed segments back. // Move the trimmed segments back.
li->segments.swap(NewLR.segments); li->segments.swap(NewLR.segments);
// Handle dead values.
bool CanSeparate = computeDeadValues(*li, dead);
DEBUG(dbgs() << "Shrunk: " << *li << '\n'); DEBUG(dbgs() << "Shrunk: " << *li << '\n');
return CanSeparate; return CanSeparate;
} }
void LiveIntervals::computeDeadValues(LiveRange &Segments, LiveRange &LR, bool LiveIntervals::computeDeadValues(LiveInterval &LI,
bool *CanSeparateRes, unsigned Reg,
SmallVectorImpl<MachineInstr*> *dead) { SmallVectorImpl<MachineInstr*> *dead) {
bool CanSeparate = false; bool PHIRemoved = false;
for (auto VNI : LR.valnos) { for (auto VNI : LI.valnos) {
if (VNI->isUnused()) if (VNI->isUnused())
continue; continue;
LiveRange::iterator LRI = Segments.FindSegmentContaining(VNI->def); LiveRange::iterator I = LI.FindSegmentContaining(VNI->def);
assert(LRI != Segments.end() && "Missing segment for PHI"); assert(I != LI.end() && "Missing segment for VNI");
if (LRI->end != VNI->def.getDeadSlot()) if (I->end != VNI->def.getDeadSlot())
continue; continue;
if (VNI->isPHIDef()) { if (VNI->isPHIDef()) {
// This is a dead PHI. Remove it. // This is a dead PHI. Remove it.
VNI->markUnused(); VNI->markUnused();
Segments.removeSegment(LRI->start, LRI->end); LI.removeSegment(I);
DEBUG(dbgs() << "Dead PHI at " << VNI->def << " may separate interval\n"); DEBUG(dbgs() << "Dead PHI at " << VNI->def << " may separate interval\n");
CanSeparate = true; PHIRemoved = true;
} else if (dead != nullptr) { } else {
// This is a dead def. Make sure the instruction knows. // This is a dead def. Make sure the instruction knows.
MachineInstr *MI = getInstructionFromIndex(VNI->def); MachineInstr *MI = getInstructionFromIndex(VNI->def);
assert(MI && "No instruction defining live value"); assert(MI && "No instruction defining live value");
MI->addRegisterDead(Reg, TRI); MI->addRegisterDead(LI.reg, TRI);
if (dead && MI->allDefsAreDead()) { if (dead && MI->allDefsAreDead()) {
DEBUG(dbgs() << "All defs dead: " << VNI->def << '\t' << *MI); DEBUG(dbgs() << "All defs dead: " << VNI->def << '\t' << *MI);
dead->push_back(MI); dead->push_back(MI);
} }
} }
} }
if (CanSeparateRes != nullptr) return PHIRemoved;
*CanSeparateRes = CanSeparate;
} }
bool LiveIntervals::shrinkToUses(LiveInterval::SubRange &SR, unsigned Reg) void LiveIntervals::shrinkToUses(LiveInterval::SubRange &SR, unsigned Reg)
{ {
DEBUG(dbgs() << "Shrink: " << SR << '\n'); DEBUG(dbgs() << "Shrink: " << SR << '\n');
assert(TargetRegisterInfo::isVirtualRegister(Reg) assert(TargetRegisterInfo::isVirtualRegister(Reg)
@@ -522,14 +519,26 @@ bool LiveIntervals::shrinkToUses(LiveInterval::SubRange &SR, unsigned Reg)
createSegmentsForValues(NewLR, make_range(SR.vni_begin(), SR.vni_end())); createSegmentsForValues(NewLR, make_range(SR.vni_begin(), SR.vni_end()));
extendSegmentsToUses(NewLR, *Indexes, WorkList, SR); extendSegmentsToUses(NewLR, *Indexes, WorkList, SR);
// Handle dead values.
bool CanSeparate;
computeDeadValues(NewLR, SR, &CanSeparate);
// Move the trimmed ranges back. // Move the trimmed ranges back.
SR.segments.swap(NewLR.segments); SR.segments.swap(NewLR.segments);
// Remove dead PHI value numbers
for (auto VNI : SR.valnos) {
if (VNI->isUnused())
continue;
const LiveRange::Segment *Segment = SR.getSegmentContaining(VNI->def);
assert(Segment != nullptr && "Missing segment for VNI");
if (Segment->end != VNI->def.getDeadSlot())
continue;
if (VNI->isPHIDef()) {
// This is a dead PHI. Remove it.
VNI->markUnused();
SR.removeSegment(*Segment);
DEBUG(dbgs() << "Dead PHI at " << VNI->def << " may separate interval\n");
}
}
DEBUG(dbgs() << "Shrunk: " << SR << '\n'); DEBUG(dbgs() << "Shrunk: " << SR << '\n');
return CanSeparate;
} }
void LiveIntervals::extendToIndices(LiveRange &LR, void LiveIntervals::extendToIndices(LiveRange &LR,