If the first definition of a virtual register is a partial redef, add an

<imp-def> operand for the full register. This ensures that the full physical
register is marked live after register allocation.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@104320 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jakob Stoklund Olesen 2010-05-21 16:32:16 +00:00
parent d8a33ddcfe
commit 63e6a488cb
3 changed files with 24 additions and 7 deletions

View File

@ -338,7 +338,7 @@ public:
/// addRegisterDefined - We have determined MI defines a register. Make sure /// addRegisterDefined - We have determined MI defines a register. Make sure
/// there is an operand defining Reg. /// there is an operand defining Reg.
void addRegisterDefined(unsigned IncomingReg, void addRegisterDefined(unsigned IncomingReg,
const TargetRegisterInfo *RegInfo); const TargetRegisterInfo *RegInfo = 0);
/// isSafeToMove - Return true if it is safe to move this instruction. If /// isSafeToMove - Return true if it is safe to move this instruction. If
/// SawStore is set to true, it means that there is a store (or call) between /// SawStore is set to true, it means that there is a store (or call) between

View File

@ -320,6 +320,12 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
// of inputs. // of inputs.
if (MO.isEarlyClobber()) if (MO.isEarlyClobber())
defIndex = MIIdx.getUseIndex(); defIndex = MIIdx.getUseIndex();
// Make sure the first definition is not a partial redefinition. Add an
// <imp-def> of the full register.
if (MO.getSubReg())
mi->addRegisterDefined(interval.reg);
MachineInstr *CopyMI = NULL; MachineInstr *CopyMI = NULL;
unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
if (mi->isExtractSubreg() || mi->isInsertSubreg() || mi->isSubregToReg() || if (mi->isExtractSubreg() || mi->isInsertSubreg() || mi->isSubregToReg() ||
@ -1371,7 +1377,8 @@ rewriteInstructionsForSpills(const LiveInterval &li, bool TrySplit,
MI->eraseFromParent(); MI->eraseFromParent();
continue; continue;
} }
assert(!O.isImplicit() && "Spilling register that's used as implicit use?"); assert(!(O.isImplicit() && O.isUse()) &&
"Spilling register that's used as implicit use?");
SlotIndex index = getInstructionIndex(MI); SlotIndex index = getInstructionIndex(MI);
if (index < start || index >= end) if (index < start || index >= end)
continue; continue;

View File

@ -1388,8 +1388,18 @@ bool MachineInstr::addRegisterDead(unsigned IncomingReg,
void MachineInstr::addRegisterDefined(unsigned IncomingReg, void MachineInstr::addRegisterDefined(unsigned IncomingReg,
const TargetRegisterInfo *RegInfo) { const TargetRegisterInfo *RegInfo) {
if (TargetRegisterInfo::isPhysicalRegister(IncomingReg)) {
MachineOperand *MO = findRegisterDefOperand(IncomingReg, false, RegInfo); MachineOperand *MO = findRegisterDefOperand(IncomingReg, false, RegInfo);
if (!MO || MO->getSubReg()) if (MO)
return;
} else {
for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
const MachineOperand &MO = getOperand(i);
if (MO.isReg() && MO.getReg() == IncomingReg && MO.isDef() &&
MO.getSubReg() == 0)
return;
}
}
addOperand(MachineOperand::CreateReg(IncomingReg, addOperand(MachineOperand::CreateReg(IncomingReg,
true /*IsDef*/, true /*IsDef*/,
true /*IsImp*/)); true /*IsImp*/));