Do not consider subreg defs as reads when computing subrange liveness
Subregister definitions are considered uses for the purpose of tracking
liveness of the whole register. At the same time, when calculating live
interval subranges, subregister defs should not be treated as uses.
Differential Revision: https://reviews.llvm.org/D24190
llvm-svn: 280532
diff --git a/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp b/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp
index a312276..4195f00 100644
--- a/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp
+++ b/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -506,20 +506,19 @@
// Visit all instructions reading Reg.
SlotIndex LastIdx;
- for (MachineOperand &MO : MRI->reg_operands(Reg)) {
- MachineInstr *UseMI = MO.getParent();
- if (UseMI->isDebugValue() || !MO.readsReg())
+ for (MachineOperand &MO : MRI->use_nodbg_operands(Reg)) {
+ // Skip "undef" uses.
+ if (!MO.readsReg())
continue;
// Maybe the operand is for a subregister we don't care about.
unsigned SubReg = MO.getSubReg();
if (SubReg != 0) {
LaneBitmask LaneMask = TRI->getSubRegIndexLaneMask(SubReg);
- if (MO.isDef())
- LaneMask = ~LaneMask & MRI->getMaxLaneMaskForVReg(Reg);
if ((LaneMask & SR.LaneMask) == 0)
continue;
}
// We only need to visit each instruction once.
+ MachineInstr *UseMI = MO.getParent();
SlotIndex Idx = getInstructionIndex(*UseMI).getRegSlot();
if (Idx == LastIdx)
continue;
diff --git a/llvm/lib/CodeGen/LiveRangeCalc.cpp b/llvm/lib/CodeGen/LiveRangeCalc.cpp
index 25d22a02..98022d9 100644
--- a/llvm/lib/CodeGen/LiveRangeCalc.cpp
+++ b/llvm/lib/CodeGen/LiveRangeCalc.cpp
@@ -163,13 +163,18 @@
LI->computeSubRangeUndefs(Undefs, Mask, *MRI, *Indexes);
// Visit all operands that read Reg. This may include partial defs.
+ bool IsSubRange = (Mask != ~0U);
const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo();
for (MachineOperand &MO : MRI->reg_nodbg_operands(Reg)) {
// Clear all kill flags. They will be reinserted after register allocation
// by LiveIntervalAnalysis::addKillFlags().
if (MO.isUse())
MO.setIsKill(false);
- if (!MO.readsReg())
+ // MO::readsReg returns "true" for subregister defs. This is for keeping
+ // liveness of the entire register (i.e. for the main range of the live
+ // interval). For subranges, definitions of non-overlapping subregisters
+ // do not count as uses.
+ if (!MO.readsReg() || (IsSubRange && MO.isDef()))
continue;
unsigned SubReg = MO.getSubReg();
diff --git a/llvm/lib/CodeGen/LiveRangeCalc.h b/llvm/lib/CodeGen/LiveRangeCalc.h
index 84cc1cb..892f535 100644
--- a/llvm/lib/CodeGen/LiveRangeCalc.h
+++ b/llvm/lib/CodeGen/LiveRangeCalc.h
@@ -160,6 +160,7 @@
/// all uses must be jointly dominated by the definitions from @p LR
/// together with definitions of other lanes where @p LR becomes undefined
/// (via <def,read-undef> operands).
+ /// If @p LR is a main range, the @p LaneMask should be set to ~0.
void extendToUses(LiveRange &LR, unsigned Reg, LaneBitmask LaneMask,
LiveInterval *LI = nullptr);
diff --git a/llvm/lib/CodeGen/SplitKit.cpp b/llvm/lib/CodeGen/SplitKit.cpp
index 6d59f85..e06bc4a 100644
--- a/llvm/lib/CodeGen/SplitKit.cpp
+++ b/llvm/lib/CodeGen/SplitKit.cpp
@@ -1206,7 +1206,8 @@
// defining the register. This is because a <def,read-undef> operand
// will create an "undef" point, and we cannot extend any subranges
// until all of them have been accounted for.
- ExtPoints.push_back(ExtPoint(MO, RegIdx, Next));
+ if (MO.isUse())
+ ExtPoints.push_back(ExtPoint(MO, RegIdx, Next));
} else {
LiveRangeCalc &LRC = getLRCalc(RegIdx);
LRC.extend(LI, Next, 0, ArrayRef<SlotIndex>());
@@ -1221,10 +1222,6 @@
unsigned Reg = EP.MO.getReg(), Sub = EP.MO.getSubReg();
LaneBitmask LM = Sub != 0 ? TRI.getSubRegIndexLaneMask(Sub)
: MRI.getMaxLaneMaskForVReg(Reg);
- // If this is a non-read-undef definition of a sub-register, extend
- // subranges for everything except that sub-register.
- if (Sub != 0 && EP.MO.isDef())
- LM = MRI.getMaxLaneMaskForVReg(Reg) & ~LM;
for (LiveInterval::SubRange &S : LI.subranges()) {
if (!(S.LaneMask & LM))
continue;