mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-05-22 03:39:03 +00:00
Dead code elimination may separate the live interval into multiple connected components.
I have convinced myself that it can only happen when a phi value dies. When it happens, allocate new virtual registers for the components. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@127827 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c74513d1b6
commit
6a3dbd3b25
@ -160,7 +160,9 @@ namespace llvm {
|
|||||||
/// defs for new uses, and it doesn't remove dead defs.
|
/// defs for new uses, and it doesn't remove dead defs.
|
||||||
/// Dead PHIDef values are marked as unused.
|
/// Dead PHIDef values are marked as unused.
|
||||||
/// New dead machine instructions are added to the dead vector.
|
/// New dead machine instructions are added to the dead vector.
|
||||||
void shrinkToUses(LiveInterval *li,
|
/// Return true if the interval may have been separated into multiple
|
||||||
|
/// connected components.
|
||||||
|
bool shrinkToUses(LiveInterval *li,
|
||||||
SmallVectorImpl<MachineInstr*> *dead = 0);
|
SmallVectorImpl<MachineInstr*> *dead = 0);
|
||||||
|
|
||||||
// Interval removal
|
// Interval removal
|
||||||
|
@ -460,7 +460,7 @@ bool InlineSpiller::reMaterializeFor(MachineBasicBlock::iterator MI) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Alocate a new register for the remat.
|
// Alocate a new register for the remat.
|
||||||
LiveInterval &NewLI = Edit->create(MRI, LIS, VRM);
|
LiveInterval &NewLI = Edit->create(LIS, VRM);
|
||||||
NewLI.markNotSpillable();
|
NewLI.markNotSpillable();
|
||||||
|
|
||||||
// Rematting for a copy: Set allocation hint to be the destination register.
|
// Rematting for a copy: Set allocation hint to be the destination register.
|
||||||
@ -685,7 +685,7 @@ void InlineSpiller::spillAroundUses(unsigned Reg) {
|
|||||||
|
|
||||||
// Allocate interval around instruction.
|
// Allocate interval around instruction.
|
||||||
// FIXME: Infer regclass from instruction alone.
|
// FIXME: Infer regclass from instruction alone.
|
||||||
LiveInterval &NewLI = Edit->create(MRI, LIS, VRM);
|
LiveInterval &NewLI = Edit->create(LIS, VRM);
|
||||||
NewLI.markNotSpillable();
|
NewLI.markNotSpillable();
|
||||||
|
|
||||||
if (Reads)
|
if (Reads)
|
||||||
|
@ -746,7 +746,7 @@ LiveInterval* LiveIntervals::dupInterval(LiveInterval *li) {
|
|||||||
/// shrinkToUses - After removing some uses of a register, shrink its live
|
/// shrinkToUses - After removing some uses of a register, shrink its live
|
||||||
/// range to just the remaining uses. This method does not compute reaching
|
/// range to just the remaining uses. This method does not compute reaching
|
||||||
/// defs for new uses, and it doesn't remove dead defs.
|
/// defs for new uses, and it doesn't remove dead defs.
|
||||||
void LiveIntervals::shrinkToUses(LiveInterval *li,
|
bool LiveIntervals::shrinkToUses(LiveInterval *li,
|
||||||
SmallVectorImpl<MachineInstr*> *dead) {
|
SmallVectorImpl<MachineInstr*> *dead) {
|
||||||
DEBUG(dbgs() << "Shrink: " << *li << '\n');
|
DEBUG(dbgs() << "Shrink: " << *li << '\n');
|
||||||
assert(TargetRegisterInfo::isVirtualRegister(li->reg)
|
assert(TargetRegisterInfo::isVirtualRegister(li->reg)
|
||||||
@ -835,6 +835,7 @@ void LiveIntervals::shrinkToUses(LiveInterval *li,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle dead values.
|
// Handle dead values.
|
||||||
|
bool CanSeparate = false;
|
||||||
for (LiveInterval::vni_iterator I = li->vni_begin(), E = li->vni_end();
|
for (LiveInterval::vni_iterator I = li->vni_begin(), E = li->vni_end();
|
||||||
I != E; ++I) {
|
I != E; ++I) {
|
||||||
VNInfo *VNI = *I;
|
VNInfo *VNI = *I;
|
||||||
@ -848,6 +849,8 @@ void LiveIntervals::shrinkToUses(LiveInterval *li,
|
|||||||
// This is a dead PHI. Remove it.
|
// This is a dead PHI. Remove it.
|
||||||
VNI->setIsUnused(true);
|
VNI->setIsUnused(true);
|
||||||
NewLI.removeRange(*LII);
|
NewLI.removeRange(*LII);
|
||||||
|
DEBUG(dbgs() << "Dead PHI at " << VNI->def << " may separate interval\n");
|
||||||
|
CanSeparate = true;
|
||||||
} else {
|
} 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);
|
||||||
@ -863,6 +866,7 @@ void LiveIntervals::shrinkToUses(LiveInterval *li,
|
|||||||
// Move the trimmed ranges back.
|
// Move the trimmed ranges back.
|
||||||
li->ranges.swap(NewLI.ranges);
|
li->ranges.swap(NewLI.ranges);
|
||||||
DEBUG(dbgs() << "Shrunk: " << *li << '\n');
|
DEBUG(dbgs() << "Shrunk: " << *li << '\n');
|
||||||
|
return CanSeparate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,16 +22,16 @@
|
|||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
LiveInterval &LiveRangeEdit::create(MachineRegisterInfo &mri,
|
LiveInterval &LiveRangeEdit::createFrom(unsigned OldReg,
|
||||||
LiveIntervals &lis,
|
LiveIntervals &LIS,
|
||||||
VirtRegMap &vrm) {
|
VirtRegMap &VRM) {
|
||||||
const TargetRegisterClass *RC = mri.getRegClass(getReg());
|
MachineRegisterInfo &MRI = VRM.getRegInfo();
|
||||||
unsigned VReg = mri.createVirtualRegister(RC);
|
unsigned VReg = MRI.createVirtualRegister(MRI.getRegClass(OldReg));
|
||||||
vrm.grow();
|
VRM.grow();
|
||||||
vrm.setIsSplitFromReg(VReg, vrm.getOriginal(getReg()));
|
VRM.setIsSplitFromReg(VReg, VRM.getOriginal(OldReg));
|
||||||
LiveInterval &li = lis.getOrCreateInterval(VReg);
|
LiveInterval &LI = LIS.getOrCreateInterval(VReg);
|
||||||
newRegs_.push_back(&li);
|
newRegs_.push_back(&LI);
|
||||||
return li;
|
return LI;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LiveRangeEdit::scanRemattable(LiveIntervals &lis,
|
void LiveRangeEdit::scanRemattable(LiveIntervals &lis,
|
||||||
@ -137,7 +137,7 @@ void LiveRangeEdit::eraseVirtReg(unsigned Reg, LiveIntervals &LIS) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead,
|
void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead,
|
||||||
LiveIntervals &LIS,
|
LiveIntervals &LIS, VirtRegMap &VRM,
|
||||||
const TargetInstrInfo &TII) {
|
const TargetInstrInfo &TII) {
|
||||||
SetVector<LiveInterval*,
|
SetVector<LiveInterval*,
|
||||||
SmallVector<LiveInterval*, 8>,
|
SmallVector<LiveInterval*, 8>,
|
||||||
@ -205,7 +205,20 @@ void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead,
|
|||||||
ToShrink.pop_back();
|
ToShrink.pop_back();
|
||||||
if (delegate_)
|
if (delegate_)
|
||||||
delegate_->LRE_WillShrinkVirtReg(LI->reg);
|
delegate_->LRE_WillShrinkVirtReg(LI->reg);
|
||||||
LIS.shrinkToUses(LI, &Dead);
|
if (!LIS.shrinkToUses(LI, &Dead))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// LI may have been separated, create new intervals.
|
||||||
|
LI->RenumberValues(LIS);
|
||||||
|
ConnectedVNInfoEqClasses ConEQ(LIS);
|
||||||
|
unsigned NumComp = ConEQ.Classify(LI);
|
||||||
|
if (NumComp <= 1)
|
||||||
|
continue;
|
||||||
|
DEBUG(dbgs() << NumComp << " components: " << *LI << '\n');
|
||||||
|
SmallVector<LiveInterval*, 8> Dups(1, LI);
|
||||||
|
for (unsigned i = 1; i != NumComp; ++i)
|
||||||
|
Dups.push_back(&createFrom(LI->reg, LIS, VRM));
|
||||||
|
ConEQ.Distribute(&Dups[0], VRM.getRegInfo());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,6 +65,9 @@ private:
|
|||||||
/// live range trimmed or entirely removed.
|
/// live range trimmed or entirely removed.
|
||||||
SmallPtrSet<const VNInfo*,4> rematted_;
|
SmallPtrSet<const VNInfo*,4> rematted_;
|
||||||
|
|
||||||
|
/// createFrom - Create a new virtual register based on OldReg.
|
||||||
|
LiveInterval &createFrom(unsigned, LiveIntervals&, VirtRegMap &);
|
||||||
|
|
||||||
/// scanRemattable - Identify the parent_ values that may rematerialize.
|
/// scanRemattable - Identify the parent_ values that may rematerialize.
|
||||||
void scanRemattable(LiveIntervals &lis,
|
void scanRemattable(LiveIntervals &lis,
|
||||||
const TargetInstrInfo &tii,
|
const TargetInstrInfo &tii,
|
||||||
@ -110,9 +113,11 @@ public:
|
|||||||
return uselessRegs_;
|
return uselessRegs_;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// create - Create a new register with the same class and stack slot as
|
/// create - Create a new register with the same class and original slot as
|
||||||
/// parent.
|
/// parent.
|
||||||
LiveInterval &create(MachineRegisterInfo&, LiveIntervals&, VirtRegMap&);
|
LiveInterval &create(LiveIntervals &LIS, VirtRegMap &VRM) {
|
||||||
|
return createFrom(getReg(), LIS, VRM);
|
||||||
|
}
|
||||||
|
|
||||||
/// anyRematerializable - Return true if any parent values may be
|
/// anyRematerializable - Return true if any parent values may be
|
||||||
/// rematerializable.
|
/// rematerializable.
|
||||||
@ -166,7 +171,7 @@ public:
|
|||||||
/// (allDefsAreDead returns true). This may cause live intervals to be trimmed
|
/// (allDefsAreDead returns true). This may cause live intervals to be trimmed
|
||||||
/// and further dead efs to be eliminated.
|
/// and further dead efs to be eliminated.
|
||||||
void eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead,
|
void eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead,
|
||||||
LiveIntervals&,
|
LiveIntervals&, VirtRegMap&,
|
||||||
const TargetInstrInfo&);
|
const TargetInstrInfo&);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -538,11 +538,11 @@ void SplitEditor::openIntv() {
|
|||||||
|
|
||||||
// Create the complement as index 0.
|
// Create the complement as index 0.
|
||||||
if (Edit->empty())
|
if (Edit->empty())
|
||||||
Edit->create(MRI, LIS, VRM);
|
Edit->create(LIS, VRM);
|
||||||
|
|
||||||
// Create the open interval.
|
// Create the open interval.
|
||||||
OpenIdx = Edit->size();
|
OpenIdx = Edit->size();
|
||||||
Edit->create(MRI, LIS, VRM);
|
Edit->create(LIS, VRM);
|
||||||
}
|
}
|
||||||
|
|
||||||
SlotIndex SplitEditor::enterIntvBefore(SlotIndex Idx) {
|
SlotIndex SplitEditor::enterIntvBefore(SlotIndex Idx) {
|
||||||
@ -802,7 +802,7 @@ void SplitEditor::deleteRematVictims() {
|
|||||||
if (Dead.empty())
|
if (Dead.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Edit->eliminateDeadDefs(Dead, LIS, TII);
|
Edit->eliminateDeadDefs(Dead, LIS, VRM, TII);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SplitEditor::finish() {
|
void SplitEditor::finish() {
|
||||||
@ -866,7 +866,7 @@ void SplitEditor::finish() {
|
|||||||
SmallVector<LiveInterval*, 8> dups;
|
SmallVector<LiveInterval*, 8> dups;
|
||||||
dups.push_back(li);
|
dups.push_back(li);
|
||||||
for (unsigned i = 1; i != NumComp; ++i)
|
for (unsigned i = 1; i != NumComp; ++i)
|
||||||
dups.push_back(&Edit->create(MRI, LIS, VRM));
|
dups.push_back(&Edit->create(LIS, VRM));
|
||||||
ConEQ.Distribute(&dups[0], MRI);
|
ConEQ.Distribute(&dups[0], MRI);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user