From c1988f384c9d792da7289fc3ef450b5156d47ff3 Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Wed, 21 Jan 2015 22:55:13 +0000 Subject: [PATCH] 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 --- llvm/include/llvm/CodeGen/MachineInstr.h | 5 +++++ llvm/lib/CodeGen/LiveIntervalAnalysis.cpp | 21 ++++++++++++++++----- llvm/lib/CodeGen/MachineInstr.cpp | 8 ++++++++ 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/llvm/include/llvm/CodeGen/MachineInstr.h b/llvm/include/llvm/CodeGen/MachineInstr.h index bcf1f5c..945ee0f 100644 --- a/llvm/include/llvm/CodeGen/MachineInstr.h +++ b/llvm/include/llvm/CodeGen/MachineInstr.h @@ -1048,6 +1048,11 @@ public: bool addRegisterDead(unsigned Reg, const TargetRegisterInfo *RegInfo, 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 /// there is an operand defining Reg. void addRegisterDefined(unsigned Reg, diff --git a/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp b/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp index c03773f..16b30ff 100644 --- a/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -448,23 +448,34 @@ bool LiveIntervals::computeDeadValues(LiveInterval &LI, for (auto VNI : LI.valnos) { if (VNI->isUnused()) 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"); - 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; if (VNI->isPHIDef()) { // This is a dead PHI. Remove it. VNI->markUnused(); 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; } else { // 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"); MI->addRegisterDead(LI.reg, TRI); 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); } } diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp index 968ec2c..470d6cb 100644 --- a/llvm/lib/CodeGen/MachineInstr.cpp +++ b/llvm/lib/CodeGen/MachineInstr.cpp @@ -1889,6 +1889,14 @@ bool MachineInstr::addRegisterDead(unsigned Reg, 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, const TargetRegisterInfo *RegInfo) { if (TargetRegisterInfo::isPhysicalRegister(Reg)) { -- 2.7.4