mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-14 16:33:28 +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.
|
||||
/// Dead PHIDef values are marked as unused.
|
||||
/// 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);
|
||||
|
||||
// Interval removal
|
||||
|
@ -460,7 +460,7 @@ bool InlineSpiller::reMaterializeFor(MachineBasicBlock::iterator MI) {
|
||||
}
|
||||
|
||||
// Alocate a new register for the remat.
|
||||
LiveInterval &NewLI = Edit->create(MRI, LIS, VRM);
|
||||
LiveInterval &NewLI = Edit->create(LIS, VRM);
|
||||
NewLI.markNotSpillable();
|
||||
|
||||
// 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.
|
||||
// FIXME: Infer regclass from instruction alone.
|
||||
LiveInterval &NewLI = Edit->create(MRI, LIS, VRM);
|
||||
LiveInterval &NewLI = Edit->create(LIS, VRM);
|
||||
NewLI.markNotSpillable();
|
||||
|
||||
if (Reads)
|
||||
|
@ -746,7 +746,7 @@ LiveInterval* LiveIntervals::dupInterval(LiveInterval *li) {
|
||||
/// shrinkToUses - After removing some uses of a register, shrink its live
|
||||
/// range to just the remaining uses. This method does not compute reaching
|
||||
/// defs for new uses, and it doesn't remove dead defs.
|
||||
void LiveIntervals::shrinkToUses(LiveInterval *li,
|
||||
bool LiveIntervals::shrinkToUses(LiveInterval *li,
|
||||
SmallVectorImpl<MachineInstr*> *dead) {
|
||||
DEBUG(dbgs() << "Shrink: " << *li << '\n');
|
||||
assert(TargetRegisterInfo::isVirtualRegister(li->reg)
|
||||
@ -835,6 +835,7 @@ void LiveIntervals::shrinkToUses(LiveInterval *li,
|
||||
}
|
||||
|
||||
// Handle dead values.
|
||||
bool CanSeparate = false;
|
||||
for (LiveInterval::vni_iterator I = li->vni_begin(), E = li->vni_end();
|
||||
I != E; ++I) {
|
||||
VNInfo *VNI = *I;
|
||||
@ -848,6 +849,8 @@ void LiveIntervals::shrinkToUses(LiveInterval *li,
|
||||
// This is a dead PHI. Remove it.
|
||||
VNI->setIsUnused(true);
|
||||
NewLI.removeRange(*LII);
|
||||
DEBUG(dbgs() << "Dead PHI at " << VNI->def << " may separate interval\n");
|
||||
CanSeparate = true;
|
||||
} else {
|
||||
// This is a dead def. Make sure the instruction knows.
|
||||
MachineInstr *MI = getInstructionFromIndex(VNI->def);
|
||||
@ -863,6 +866,7 @@ void LiveIntervals::shrinkToUses(LiveInterval *li,
|
||||
// Move the trimmed ranges back.
|
||||
li->ranges.swap(NewLI.ranges);
|
||||
DEBUG(dbgs() << "Shrunk: " << *li << '\n');
|
||||
return CanSeparate;
|
||||
}
|
||||
|
||||
|
||||
|
@ -22,16 +22,16 @@
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
LiveInterval &LiveRangeEdit::create(MachineRegisterInfo &mri,
|
||||
LiveIntervals &lis,
|
||||
VirtRegMap &vrm) {
|
||||
const TargetRegisterClass *RC = mri.getRegClass(getReg());
|
||||
unsigned VReg = mri.createVirtualRegister(RC);
|
||||
vrm.grow();
|
||||
vrm.setIsSplitFromReg(VReg, vrm.getOriginal(getReg()));
|
||||
LiveInterval &li = lis.getOrCreateInterval(VReg);
|
||||
newRegs_.push_back(&li);
|
||||
return li;
|
||||
LiveInterval &LiveRangeEdit::createFrom(unsigned OldReg,
|
||||
LiveIntervals &LIS,
|
||||
VirtRegMap &VRM) {
|
||||
MachineRegisterInfo &MRI = VRM.getRegInfo();
|
||||
unsigned VReg = MRI.createVirtualRegister(MRI.getRegClass(OldReg));
|
||||
VRM.grow();
|
||||
VRM.setIsSplitFromReg(VReg, VRM.getOriginal(OldReg));
|
||||
LiveInterval &LI = LIS.getOrCreateInterval(VReg);
|
||||
newRegs_.push_back(&LI);
|
||||
return LI;
|
||||
}
|
||||
|
||||
void LiveRangeEdit::scanRemattable(LiveIntervals &lis,
|
||||
@ -137,7 +137,7 @@ void LiveRangeEdit::eraseVirtReg(unsigned Reg, LiveIntervals &LIS) {
|
||||
}
|
||||
|
||||
void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead,
|
||||
LiveIntervals &LIS,
|
||||
LiveIntervals &LIS, VirtRegMap &VRM,
|
||||
const TargetInstrInfo &TII) {
|
||||
SetVector<LiveInterval*,
|
||||
SmallVector<LiveInterval*, 8>,
|
||||
@ -205,7 +205,20 @@ void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead,
|
||||
ToShrink.pop_back();
|
||||
if (delegate_)
|
||||
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.
|
||||
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.
|
||||
void scanRemattable(LiveIntervals &lis,
|
||||
const TargetInstrInfo &tii,
|
||||
@ -110,9 +113,11 @@ public:
|
||||
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.
|
||||
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
|
||||
/// rematerializable.
|
||||
@ -166,7 +171,7 @@ public:
|
||||
/// (allDefsAreDead returns true). This may cause live intervals to be trimmed
|
||||
/// and further dead efs to be eliminated.
|
||||
void eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead,
|
||||
LiveIntervals&,
|
||||
LiveIntervals&, VirtRegMap&,
|
||||
const TargetInstrInfo&);
|
||||
|
||||
};
|
||||
|
@ -538,11 +538,11 @@ void SplitEditor::openIntv() {
|
||||
|
||||
// Create the complement as index 0.
|
||||
if (Edit->empty())
|
||||
Edit->create(MRI, LIS, VRM);
|
||||
Edit->create(LIS, VRM);
|
||||
|
||||
// Create the open interval.
|
||||
OpenIdx = Edit->size();
|
||||
Edit->create(MRI, LIS, VRM);
|
||||
Edit->create(LIS, VRM);
|
||||
}
|
||||
|
||||
SlotIndex SplitEditor::enterIntvBefore(SlotIndex Idx) {
|
||||
@ -802,7 +802,7 @@ void SplitEditor::deleteRematVictims() {
|
||||
if (Dead.empty())
|
||||
return;
|
||||
|
||||
Edit->eliminateDeadDefs(Dead, LIS, TII);
|
||||
Edit->eliminateDeadDefs(Dead, LIS, VRM, TII);
|
||||
}
|
||||
|
||||
void SplitEditor::finish() {
|
||||
@ -866,7 +866,7 @@ void SplitEditor::finish() {
|
||||
SmallVector<LiveInterval*, 8> dups;
|
||||
dups.push_back(li);
|
||||
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);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user