mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-09-27 16:17:17 +00:00
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:
@@ -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.
|
||||||
|
@@ -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);
|
||||||
|
|
||||||
|
@@ -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,
|
||||||
|
Reference in New Issue
Block a user