diff options
| -rw-r--r-- | llvm/lib/CodeGen/LiveIntervalAnalysis.cpp | 24 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/VirtRegMap.cpp | 14 |
2 files changed, 33 insertions, 5 deletions
diff --git a/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp b/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp index dde55f9dd48..1e78259731b 100644 --- a/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -671,6 +671,30 @@ void LiveIntervals::addKillFlags(const VirtRegMap *VRM) { CancelKill = true; break; } + + // If an instruction writes to a subregister, a new segment starts in the + // LiveInterval. In this case adding Kill-Flags is incorrect if no + // super registers defs/uses are appended to the instruction which is + // what we do when subregister liveness tracking is enabled. + if (MRI->tracksSubRegLiveness()) { + // Next segment has to be adjacent in the subregister write case. + LiveRange::iterator N = std::next(RI); + if (N != LI->end() && N->start == RI->end) { + // See if we have a partial write operand + bool IsFullWrite = false; + for (MachineInstr::const_mop_iterator MOp = MI->operands_begin(), + MOpE = MI->operands_end(); MOp != MOpE; ++MOp) { + if (MOp->isReg() && !MOp->isDef() && MOp->getReg() == Reg + && MOp->getSubReg() == 0) { + IsFullWrite = true; + break; + } + } + if (!IsFullWrite) + CancelKill = true; + } + } + if (CancelKill) MI->clearRegisterKills(Reg, nullptr); else diff --git a/llvm/lib/CodeGen/VirtRegMap.cpp b/llvm/lib/CodeGen/VirtRegMap.cpp index 0d17d43d972..3d72d204ac4 100644 --- a/llvm/lib/CodeGen/VirtRegMap.cpp +++ b/llvm/lib/CodeGen/VirtRegMap.cpp @@ -266,6 +266,7 @@ void VirtRegRewriter::addMBBLiveIns() { } void VirtRegRewriter::rewrite() { + bool NoSubRegLiveness = !MRI->tracksSubRegLiveness(); SmallVector<unsigned, 8> SuperDeads; SmallVector<unsigned, 8> SuperDefs; SmallVector<unsigned, 8> SuperKills; @@ -347,7 +348,8 @@ void VirtRegRewriter::rewrite() { // A virtual register kill refers to the whole register, so we may // have to add <imp-use,kill> operands for the super-register. A // partial redef always kills and redefines the super-register. - if (MO.readsReg() && (MO.isDef() || MO.isKill())) + if (NoSubRegLiveness && MO.readsReg() + && (MO.isDef() || MO.isKill())) SuperKills.push_back(PhysReg); if (MO.isDef()) { @@ -358,10 +360,12 @@ void VirtRegRewriter::rewrite() { MO.setIsUndef(false); // Also add implicit defs for the super-register. - if (MO.isDead()) - SuperDeads.push_back(PhysReg); - else - SuperDefs.push_back(PhysReg); + if (NoSubRegLiveness) { + if (MO.isDead()) + SuperDeads.push_back(PhysReg); + else + SuperDefs.push_back(PhysReg); + } } // PhysReg operands cannot have subregister indexes. |

