/// make sure to set it to the correct physical subregister.
void updateRegDefsUses(unsigned SrcReg, unsigned DstReg, unsigned SubIdx);
+ /// If the given machine operand reads only undefined lanes add an undef
+ /// flag.
+ /// This can happen when undef uses were previously concealed by a copy
+ /// which we coalesced. Example:
+ /// %vreg0:sub0<def,read-undef> = ...
+ /// %vreg1 = COPY %vreg0 <-- Coalescing COPY reveals undef
+ /// = use %vreg1:sub1 <-- hidden undef use
+ void addUndefFlag(const LiveInterval &Int, SlotIndex UseIdx,
+ MachineOperand &MO, unsigned SubRegIdx);
+
/// Handle copies of undef values.
/// Returns true if @p CopyMI was a copy of an undef value and eliminated.
bool eliminateUndefCopy(MachineInstr *CopyMI);
return true;
}
+void RegisterCoalescer::addUndefFlag(const LiveInterval &Int, SlotIndex UseIdx,
+ MachineOperand &MO, unsigned SubRegIdx) {
+ LaneBitmask Mask = TRI->getSubRegIndexLaneMask(SubRegIdx);
+ if (MO.isDef())
+ Mask = ~Mask;
+ bool IsUndef = true;
+ for (const LiveInterval::SubRange &S : Int.subranges()) {
+ if ((S.LaneMask & Mask) == 0)
+ continue;
+ if (S.liveAt(UseIdx)) {
+ IsUndef = false;
+ break;
+ }
+ }
+ if (IsUndef) {
+ MO.setIsUndef(true);
+ // We found out some subregister use is actually reading an undefined
+ // value. In some cases the whole vreg has become undefined at this
+ // point so we have to potentially shrink the main range if the
+ // use was ending a live segment there.
+ LiveQueryResult Q = Int.Query(UseIdx);
+ if (Q.valueOut() == nullptr)
+ ShrinkMainRange = true;
+ }
+}
+
void RegisterCoalescer::updateRegDefsUses(unsigned SrcReg,
unsigned DstReg,
unsigned SubIdx) {
bool DstIsPhys = TargetRegisterInfo::isPhysicalRegister(DstReg);
LiveInterval *DstInt = DstIsPhys ? nullptr : &LIS->getInterval(DstReg);
+ if (DstInt && DstInt->hasSubRanges() && DstReg != SrcReg) {
+ for (MachineOperand &MO : MRI->reg_operands(DstReg)) {
+ unsigned SubReg = MO.getSubReg();
+ if (SubReg == 0 || MO.isUndef())
+ continue;
+ MachineInstr &MI = *MO.getParent();
+ if (MI.isDebugValue())
+ continue;
+ SlotIndex UseIdx = LIS->getInstructionIndex(MI).getRegSlot(true);
+ addUndefFlag(*DstInt, UseIdx, MO, SubReg);
+ }
+ }
+
SmallPtrSet<MachineInstr*, 8> Visited;
for (MachineRegisterInfo::reg_instr_iterator
I = MRI->reg_instr_begin(SrcReg), E = MRI->reg_instr_end();
LaneBitmask Mask = MRI->getMaxLaneMaskForVReg(DstInt->reg);
DstInt->createSubRangeFrom(Allocator, Mask, *DstInt);
}
- LaneBitmask Mask = TRI->getSubRegIndexLaneMask(SubIdx);
- bool IsUndef = true;
SlotIndex MIIdx = UseMI->isDebugValue()
? LIS->getSlotIndexes()->getIndexBefore(*UseMI)
: LIS->getInstructionIndex(*UseMI);
SlotIndex UseIdx = MIIdx.getRegSlot(true);
- for (LiveInterval::SubRange &S : DstInt->subranges()) {
- if ((S.LaneMask & Mask) == 0)
- continue;
- if (S.liveAt(UseIdx)) {
- IsUndef = false;
- break;
- }
- }
- if (IsUndef) {
- MO.setIsUndef(true);
- // We found out some subregister use is actually reading an undefined
- // value. In some cases the whole vreg has become undefined at this
- // point so we have to potentially shrink the main range if the
- // use was ending a live segment there.
- LiveQueryResult Q = DstInt->Query(MIIdx);
- if (Q.valueOut() == nullptr)
- ShrinkMainRange = true;
- }
+ addUndefFlag(*DstInt, UseIdx, MO, SubIdx);
}
if (DstIsPhys)