forked from OSchip/llvm-project
LiveIntervalAnalysis: Mark subregister defs as undef when we determined they are only reading a dead superregister value
This was not necessary before as this case can only be detected when the liveness analysis is at subregister level. llvm-svn: 226733
This commit is contained in:
parent
4b6a7e355b
commit
c1988f384c
|
@ -1048,6 +1048,11 @@ public:
|
||||||
bool addRegisterDead(unsigned Reg, const TargetRegisterInfo *RegInfo,
|
bool addRegisterDead(unsigned Reg, const TargetRegisterInfo *RegInfo,
|
||||||
bool AddIfNotFound = false);
|
bool AddIfNotFound = false);
|
||||||
|
|
||||||
|
/// Mark all subregister defs of register @p Reg with the undef flag.
|
||||||
|
/// This function is used when we determined to have a subregister def in an
|
||||||
|
/// otherwise undefined super register.
|
||||||
|
void addRegisterDefReadUndef(unsigned Reg);
|
||||||
|
|
||||||
/// addRegisterDefined - We have determined MI defines a register. Make sure
|
/// addRegisterDefined - We have determined MI defines a register. Make sure
|
||||||
/// there is an operand defining Reg.
|
/// there is an operand defining Reg.
|
||||||
void addRegisterDefined(unsigned Reg,
|
void addRegisterDefined(unsigned Reg,
|
||||||
|
|
|
@ -448,23 +448,34 @@ bool LiveIntervals::computeDeadValues(LiveInterval &LI,
|
||||||
for (auto VNI : LI.valnos) {
|
for (auto VNI : LI.valnos) {
|
||||||
if (VNI->isUnused())
|
if (VNI->isUnused())
|
||||||
continue;
|
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");
|
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->tracksSubRegLiveness()) {
|
||||||
|
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;
|
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();
|
||||||
LI.removeSegment(I);
|
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;
|
PHIRemoved = 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(Def);
|
||||||
assert(MI && "No instruction defining live value");
|
assert(MI && "No instruction defining live value");
|
||||||
MI->addRegisterDead(LI.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: " << Def << '\t' << *MI);
|
||||||
dead->push_back(MI);
|
dead->push_back(MI);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1889,6 +1889,14 @@ bool MachineInstr::addRegisterDead(unsigned Reg,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MachineInstr::addRegisterDefReadUndef(unsigned Reg) {
|
||||||
|
for (MachineOperand &MO : operands()) {
|
||||||
|
if (!MO.isReg() || !MO.isDef() || MO.getReg() != Reg || MO.getSubReg() == 0)
|
||||||
|
continue;
|
||||||
|
MO.setIsUndef();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MachineInstr::addRegisterDefined(unsigned Reg,
|
void MachineInstr::addRegisterDefined(unsigned Reg,
|
||||||
const TargetRegisterInfo *RegInfo) {
|
const TargetRegisterInfo *RegInfo) {
|
||||||
if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
|
if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
|
||||||
|
|
Loading…
Reference in New Issue