summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/CodeGen/LiveIntervalAnalysis.cpp24
-rw-r--r--llvm/lib/CodeGen/VirtRegMap.cpp14
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.
OpenPOWER on IntegriCloud