RegCoalescer: Making sure re-materialization defines all subranges

The register coalescer can rematerialize constants that define
more of a register than the copy it is going to replace was going
to do.
This is valid in the case the register was undef before the
copy happened.
This patch makes sure that all the subranges defined by the new
rematerialization instructions have at least a dead def.

Review: http://reviews.llvm.org/D16693
llvm-svn: 259614
This commit is contained in:
Marcello Maggioni 2016-02-03 00:22:32 +00:00
parent 512c61df1c
commit bfe87568aa
1 changed files with 30 additions and 0 deletions

View File

@ -1001,6 +1001,36 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP,
updateRegDefsUses(DstReg, DstReg, DstIdx);
NewMI->getOperand(0).setSubReg(NewIdx);
// Add dead subregister definitions if we are defining the whole register
// but only part of it is live.
// This could happen if the rematerialization instruction is rematerializing
// more than actually is used in the register.
// An example would be:
// vreg1 = LOAD CONSTANTS 5, 8 ; Loading both 5 and 8 in different subregs
// ; Copying only part of the register here, but the rest is undef.
// vreg2:sub_16bit<def, read-undef> = COPY vreg1:sub_16bit
// ==>
// ; Materialize all the constants but only using one
// vreg2 = LOAD_CONSTANTS 5, 8
//
// at this point for the part that wasn't defined before we could have
// subranges missing the definition.
LiveInterval &DstInt = LIS->getInterval(DstReg);
if (NewIdx == 0 && DstInt.hasSubRanges()) {
SlotIndex CurrIdx = LIS->getInstructionIndex(NewMI);
SlotIndex DefIndex = CurrIdx.getRegSlot(NewMI->getOperand(0).isEarlyClobber());
LaneBitmask MaxMask = MRI->getMaxLaneMaskForVReg(DstReg);
VNInfo::Allocator& Alloc = LIS->getVNInfoAllocator();
for (LiveInterval::SubRange &SR : DstInt.subranges()) {
if (!SR.liveAt(DefIndex))
SR.createDeadDef(DefIndex, Alloc);
MaxMask &= ~SR.LaneMask;
}
if (MaxMask != 0) {
LiveInterval::SubRange *SR = DstInt.createSubRange(Alloc, MaxMask);
SR->createDeadDef(DefIndex, Alloc);
}
}
} else if (NewMI->getOperand(0).getReg() != CopyDstReg) {
// The New instruction may be defining a sub-register of what's actually
// been asked for. If so it must implicitly define the whole thing.