Let callers decide the sub-register index on the def operand of rematerialized instructions.

Avoid remat'ing instructions whose def have sub-register indices for now. It's just really really hard to get all the cases right.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75900 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2009-07-16 09:20:10 +00:00
parent 6ef40b11f8
commit 378445303b
20 changed files with 277 additions and 49 deletions

View File

@ -151,7 +151,7 @@ public:
/// specific location targeting a new destination register. /// specific location targeting a new destination register.
virtual void reMaterialize(MachineBasicBlock &MBB, virtual void reMaterialize(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI, MachineBasicBlock::iterator MI,
unsigned DestReg, unsigned DestReg, unsigned SubIdx,
const MachineInstr *Orig) const = 0; const MachineInstr *Orig) const = 0;
/// isInvariantLoad - Return true if the specified instruction (which is /// isInvariantLoad - Return true if the specified instruction (which is
@ -499,7 +499,7 @@ public:
const SmallVectorImpl<MachineOperand> &Pred) const; const SmallVectorImpl<MachineOperand> &Pred) const;
virtual void reMaterialize(MachineBasicBlock &MBB, virtual void reMaterialize(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI, MachineBasicBlock::iterator MI,
unsigned DestReg, unsigned DestReg, unsigned SubReg,
const MachineInstr *Orig) const; const MachineInstr *Orig) const;
virtual unsigned GetFunctionSizeInBytes(const MachineFunction &MF) const; virtual unsigned GetFunctionSizeInBytes(const MachineFunction &MF) const;
}; };

View File

@ -1157,6 +1157,11 @@ bool LiveIntervals::isReMaterializable(const LiveInterval &li,
if (DisableReMat) if (DisableReMat)
return false; return false;
// FIXME: For now, avoid remating instructions whose definition has a subreg
// index. It's just incredibly difficult to get right.
if (MI->findRegisterDefOperand(li.reg)->getSubReg())
return false;
if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF) if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF)
return true; return true;
@ -1595,7 +1600,7 @@ rewriteInstructionForSpills(const LiveInterval &li, const VNInfo *VNI,
if (CreatedNewVReg) { if (CreatedNewVReg) {
if (DefIsReMat) { if (DefIsReMat) {
vrm.setVirtIsReMaterialized(NewVReg, ReMatDefMI/*, CanDelete*/); vrm.setVirtIsReMaterialized(NewVReg, ReMatDefMI);
if (ReMatIds[VNI->id] == VirtRegMap::MAX_STACK_SLOT) { if (ReMatIds[VNI->id] == VirtRegMap::MAX_STACK_SLOT) {
// Each valnum may have its own remat id. // Each valnum may have its own remat id.
ReMatIds[VNI->id] = vrm.assignVirtReMatId(NewVReg); ReMatIds[VNI->id] = vrm.assignVirtReMatId(NewVReg);

View File

@ -867,7 +867,7 @@ void PreAllocSplitting::RenumberValno(VNInfo* VN) {
NumRenumbers++; NumRenumbers++;
} }
bool PreAllocSplitting::Rematerialize(unsigned vreg, VNInfo* ValNo, bool PreAllocSplitting::Rematerialize(unsigned VReg, VNInfo* ValNo,
MachineInstr* DefMI, MachineInstr* DefMI,
MachineBasicBlock::iterator RestorePt, MachineBasicBlock::iterator RestorePt,
unsigned RestoreIdx, unsigned RestoreIdx,
@ -884,7 +884,7 @@ bool PreAllocSplitting::Rematerialize(unsigned vreg, VNInfo* ValNo,
if (KillPt == DefMI->getParent()->end()) if (KillPt == DefMI->getParent()->end())
return false; return false;
TII->reMaterialize(MBB, RestorePt, vreg, DefMI); TII->reMaterialize(MBB, RestorePt, VReg, 0, DefMI);
LIs->InsertMachineInstrInMaps(prior(RestorePt), RestoreIdx); LIs->InsertMachineInstrInMaps(prior(RestorePt), RestoreIdx);
ReconstructLiveInterval(CurrLI); ReconstructLiveInterval(CurrLI);

View File

@ -590,6 +590,7 @@ SimpleRegisterCoalescing::TrimLiveIntervalToLastUse(unsigned CopyIdx,
/// computation, replace the copy by rematerialize the definition. /// computation, replace the copy by rematerialize the definition.
bool SimpleRegisterCoalescing::ReMaterializeTrivialDef(LiveInterval &SrcInt, bool SimpleRegisterCoalescing::ReMaterializeTrivialDef(LiveInterval &SrcInt,
unsigned DstReg, unsigned DstReg,
unsigned DstSubIdx,
MachineInstr *CopyMI) { MachineInstr *CopyMI) {
unsigned CopyIdx = li_->getUseIndex(li_->getInstructionIndex(CopyMI)); unsigned CopyIdx = li_->getUseIndex(li_->getInstructionIndex(CopyMI));
LiveInterval::iterator SrcLR = SrcInt.FindLiveRangeContaining(CopyIdx); LiveInterval::iterator SrcLR = SrcInt.FindLiveRangeContaining(CopyIdx);
@ -647,7 +648,7 @@ bool SimpleRegisterCoalescing::ReMaterializeTrivialDef(LiveInterval &SrcInt,
} }
MachineBasicBlock::iterator MII = next(MachineBasicBlock::iterator(CopyMI)); MachineBasicBlock::iterator MII = next(MachineBasicBlock::iterator(CopyMI));
tii_->reMaterialize(*MBB, MII, DstReg, DefMI); tii_->reMaterialize(*MBB, MII, DstReg, DstSubIdx, DefMI);
MachineInstr *NewMI = prior(MII); MachineInstr *NewMI = prior(MII);
if (checkForDeadDef) { if (checkForDeadDef) {
@ -738,7 +739,8 @@ SimpleRegisterCoalescing::UpdateRegDefsUses(unsigned SrcReg, unsigned DstReg,
CopySrcReg == SrcReg && CopyDstReg != UseDstReg) { CopySrcReg == SrcReg && CopyDstReg != UseDstReg) {
// If the use is a copy and it won't be coalesced away, and its source // If the use is a copy and it won't be coalesced away, and its source
// is defined by a trivial computation, try to rematerialize it instead. // is defined by a trivial computation, try to rematerialize it instead.
if (ReMaterializeTrivialDef(li_->getInterval(SrcReg), CopyDstReg,UseMI)) if (ReMaterializeTrivialDef(li_->getInterval(SrcReg), CopyDstReg,
CopyDstSubIdx, UseMI))
continue; continue;
} }
@ -950,10 +952,9 @@ SimpleRegisterCoalescing::ShortenDeadCopySrcLiveRange(LiveInterval &li,
if (LR->valno->def == RemoveStart) { if (LR->valno->def == RemoveStart) {
// If the def MI defines the val# and this copy is the only kill of the // If the def MI defines the val# and this copy is the only kill of the
// val#, then propagate the dead marker. // val#, then propagate the dead marker.
if (li.isOnlyLROfValNo(LR)) { PropagateDeadness(li, CopyMI, RemoveStart, li_, tri_);
PropagateDeadness(li, CopyMI, RemoveStart, li_, tri_); ++numDeadValNo;
++numDeadValNo;
}
if (li.isKill(LR->valno, RemoveEnd)) if (li.isKill(LR->valno, RemoveEnd))
li.removeKill(LR->valno, RemoveEnd); li.removeKill(LR->valno, RemoveEnd);
} }
@ -1679,7 +1680,7 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
// If definition of source is defined by trivial computation, try // If definition of source is defined by trivial computation, try
// rematerializing it. // rematerializing it.
if (!isExtSubReg && !isInsSubReg && !isSubRegToReg && if (!isExtSubReg && !isInsSubReg && !isSubRegToReg &&
ReMaterializeTrivialDef(SrcInt, DstInt.reg, CopyMI)) ReMaterializeTrivialDef(SrcInt, DstReg, DstSubIdx, CopyMI))
return true; return true;
// If we can eliminate the copy without merging the live ranges, do so now. // If we can eliminate the copy without merging the live ranges, do so now.

View File

@ -206,7 +206,7 @@ namespace llvm {
/// ReMaterializeTrivialDef - If the source of a copy is defined by a trivial /// ReMaterializeTrivialDef - If the source of a copy is defined by a trivial
/// computation, replace the copy by rematerialize the definition. /// computation, replace the copy by rematerialize the definition.
bool ReMaterializeTrivialDef(LiveInterval &SrcInt, unsigned DstReg, bool ReMaterializeTrivialDef(LiveInterval &SrcInt, unsigned DstReg,
MachineInstr *CopyMI); unsigned DstSubIdx, MachineInstr *CopyMI);
/// TurnCopyIntoImpDef - If source of the specified copy is an implicit def, /// TurnCopyIntoImpDef - If source of the specified copy is an implicit def,
/// turn the copy into an implicit def. /// turn the copy into an implicit def.

View File

@ -130,9 +130,12 @@ bool TargetInstrInfoImpl::PredicateInstruction(MachineInstr *MI,
void TargetInstrInfoImpl::reMaterialize(MachineBasicBlock &MBB, void TargetInstrInfoImpl::reMaterialize(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I, MachineBasicBlock::iterator I,
unsigned DestReg, unsigned DestReg,
unsigned SubIdx,
const MachineInstr *Orig) const { const MachineInstr *Orig) const {
MachineInstr *MI = MBB.getParent()->CloneMachineInstr(Orig); MachineInstr *MI = MBB.getParent()->CloneMachineInstr(Orig);
MI->getOperand(0).setReg(DestReg); MachineOperand &MO = MI->getOperand(0);
MO.setReg(DestReg);
MO.setSubReg(SubIdx);
MBB.insert(I, MI); MBB.insert(I, MI);
} }

View File

@ -798,6 +798,7 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) {
// a = a op c // a = a op c
unsigned regA = mi->getOperand(ti).getReg(); unsigned regA = mi->getOperand(ti).getReg();
unsigned regB = mi->getOperand(si).getReg(); unsigned regB = mi->getOperand(si).getReg();
unsigned regASubIdx = mi->getOperand(ti).getSubReg();
assert(TargetRegisterInfo::isVirtualRegister(regB) && assert(TargetRegisterInfo::isVirtualRegister(regB) &&
"cannot update physical register live information"); "cannot update physical register live information");
@ -946,7 +947,7 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) {
DefMI->isSafeToReMat(TII, regB) && DefMI->isSafeToReMat(TII, regB) &&
isProfitableToReMat(regB, rc, mi, DefMI, mbbi, Dist)){ isProfitableToReMat(regB, rc, mi, DefMI, mbbi, Dist)){
DEBUG(cerr << "2addr: REMATTING : " << *DefMI << "\n"); DEBUG(cerr << "2addr: REMATTING : " << *DefMI << "\n");
TII->reMaterialize(*mbbi, mi, regA, DefMI); TII->reMaterialize(*mbbi, mi, regA, regASubIdx, DefMI);
ReMatRegs.set(regB); ReMatRegs.set(regB);
++NumReMats; ++NumReMats;
} else { } else {

View File

@ -490,7 +490,7 @@ static void ReMaterialize(MachineBasicBlock &MBB,
const TargetInstrInfo *TII, const TargetInstrInfo *TII,
const TargetRegisterInfo *TRI, const TargetRegisterInfo *TRI,
VirtRegMap &VRM) { VirtRegMap &VRM) {
TII->reMaterialize(MBB, MII, DestReg, VRM.getReMaterializedMI(Reg)); TII->reMaterialize(MBB, MII, DestReg, 0, VRM.getReMaterializedMI(Reg));
MachineInstr *NewMI = prior(MII); MachineInstr *NewMI = prior(MII);
for (unsigned i = 0, e = NewMI->getNumOperands(); i != e; ++i) { for (unsigned i = 0, e = NewMI->getNumOperands(); i != e; ++i) {
MachineOperand &MO = NewMI->getOperand(i); MachineOperand &MO = NewMI->getOperand(i);

View File

@ -887,7 +887,7 @@ void ARMBaseRegisterInfo::
emitLoadConstPool(MachineBasicBlock &MBB, emitLoadConstPool(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &MBBI, MachineBasicBlock::iterator &MBBI,
DebugLoc dl, DebugLoc dl,
unsigned DestReg, int Val, unsigned DestReg, unsigned SubIdx, int Val,
ARMCC::CondCodes Pred, ARMCC::CondCodes Pred,
unsigned PredReg) const { unsigned PredReg) const {
MachineFunction &MF = *MBB.getParent(); MachineFunction &MF = *MBB.getParent();
@ -896,7 +896,8 @@ emitLoadConstPool(MachineBasicBlock &MBB,
MF.getFunction()->getContext()->getConstantInt(Type::Int32Ty, Val); MF.getFunction()->getContext()->getConstantInt(Type::Int32Ty, Val);
unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4); unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
BuildMI(MBB, MBBI, dl, TII.get(ARM::LDRcp), DestReg) BuildMI(MBB, MBBI, dl, TII.get(ARM::LDRcp))
.addReg(DestReg, getDefRegState(true), SubIdx)
.addConstantPoolIndex(Idx) .addConstantPoolIndex(Idx)
.addReg(0).addImm(0).addImm(Pred).addReg(PredReg); .addReg(0).addImm(0).addImm(Pred).addReg(PredReg);
} }

View File

@ -112,7 +112,8 @@ public:
virtual void emitLoadConstPool(MachineBasicBlock &MBB, virtual void emitLoadConstPool(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &MBBI, MachineBasicBlock::iterator &MBBI,
DebugLoc dl, DebugLoc dl,
unsigned DestReg, int Val, unsigned DestReg, unsigned SubIdx,
int Val,
ARMCC::CondCodes Pred = ARMCC::AL, ARMCC::CondCodes Pred = ARMCC::AL,
unsigned PredReg = 0) const; unsigned PredReg = 0) const;

View File

@ -117,12 +117,12 @@ BlockHasNoFallThrough(const MachineBasicBlock &MBB) const {
void ARMInstrInfo:: void ARMInstrInfo::
reMaterialize(MachineBasicBlock &MBB, reMaterialize(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I, MachineBasicBlock::iterator I,
unsigned DestReg, unsigned DestReg, unsigned SubIdx,
const MachineInstr *Orig) const { const MachineInstr *Orig) const {
DebugLoc dl = Orig->getDebugLoc(); DebugLoc dl = Orig->getDebugLoc();
if (Orig->getOpcode() == ARM::MOVi2pieces) { if (Orig->getOpcode() == ARM::MOVi2pieces) {
RI.emitLoadConstPool(MBB, I, dl, RI.emitLoadConstPool(MBB, I, dl,
DestReg, DestReg, SubIdx,
Orig->getOperand(1).getImm(), Orig->getOperand(1).getImm(),
(ARMCC::CondCodes)Orig->getOperand(2).getImm(), (ARMCC::CondCodes)Orig->getOperand(2).getImm(),
Orig->getOperand(3).getReg()); Orig->getOperand(3).getReg());

View File

@ -45,7 +45,8 @@ public:
const ARMRegisterInfo &getRegisterInfo() const { return RI; } const ARMRegisterInfo &getRegisterInfo() const { return RI; }
void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
unsigned DestReg, const MachineInstr *Orig) const; unsigned DestReg, unsigned SubIdx,
const MachineInstr *Orig) const;
}; };
} }

View File

@ -62,7 +62,8 @@ const MachineInstrBuilder &AddDefaultCC(const MachineInstrBuilder &MIB) {
void Thumb1RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB, void Thumb1RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &MBBI, MachineBasicBlock::iterator &MBBI,
DebugLoc dl, DebugLoc dl,
unsigned DestReg, int Val, unsigned DestReg, unsigned SubIdx,
int Val,
ARMCC::CondCodes Pred, ARMCC::CondCodes Pred,
unsigned PredReg) const { unsigned PredReg) const {
MachineFunction &MF = *MBB.getParent(); MachineFunction &MF = *MBB.getParent();
@ -71,8 +72,9 @@ void Thumb1RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB,
MF.getFunction()->getContext()->getConstantInt(Type::Int32Ty, Val); MF.getFunction()->getContext()->getConstantInt(Type::Int32Ty, Val);
unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4); unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
BuildMI(MBB, MBBI, dl, TII.get(ARM::tLDRcp), DestReg) BuildMI(MBB, MBBI, dl, TII.get(ARM::tLDRcp))
.addConstantPoolIndex(Idx).addImm(Pred).addReg(PredReg); .addReg(DestReg, getDefRegState(true), SubIdx)
.addConstantPoolIndex(Idx).addImm(Pred).addReg(PredReg);
} }
const TargetRegisterClass* const TargetRegisterClass*
@ -149,7 +151,7 @@ void emitThumbRegPlusImmInReg(MachineBasicBlock &MBB,
AddDefaultCC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tRSB), LdReg)) AddDefaultCC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tRSB), LdReg))
.addReg(LdReg, RegState::Kill); .addReg(LdReg, RegState::Kill);
} else } else
MRI.emitLoadConstPool(MBB, MBBI, dl, LdReg, NumBytes); MRI.emitLoadConstPool(MBB, MBBI, dl, LdReg, 0, NumBytes);
// Emit add / sub. // Emit add / sub.
int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr : ARM::tADDrr); int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr : ARM::tADDrr);
@ -570,7 +572,7 @@ void Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg, emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg,
Offset, false, TII, *this, dl); Offset, false, TII, *this, dl);
else { else {
emitLoadConstPool(MBB, II, dl, TmpReg, Offset); emitLoadConstPool(MBB, II, dl, TmpReg, 0, Offset);
UseRR = true; UseRR = true;
} }
} else { } else {
@ -610,7 +612,7 @@ void Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg, emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg,
Offset, false, TII, *this, dl); Offset, false, TII, *this, dl);
else { else {
emitLoadConstPool(MBB, II, dl, TmpReg, Offset); emitLoadConstPool(MBB, II, dl, TmpReg, 0, Offset);
UseRR = true; UseRR = true;
} }
} else } else

View File

@ -32,7 +32,7 @@ public:
void emitLoadConstPool(MachineBasicBlock &MBB, void emitLoadConstPool(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &MBBI, MachineBasicBlock::iterator &MBBI,
DebugLoc dl, DebugLoc dl,
unsigned DestReg, int Val, unsigned DestReg, unsigned SubIdx, int Val,
ARMCC::CondCodes Pred = ARMCC::AL, ARMCC::CondCodes Pred = ARMCC::AL,
unsigned PredReg = 0) const; unsigned PredReg = 0) const;

View File

@ -46,7 +46,8 @@ Thumb2RegisterInfo::Thumb2RegisterInfo(const ARMBaseInstrInfo &tii,
void Thumb2RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB, void Thumb2RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &MBBI, MachineBasicBlock::iterator &MBBI,
DebugLoc dl, DebugLoc dl,
unsigned DestReg, int Val, unsigned DestReg, unsigned SubIdx,
int Val,
ARMCC::CondCodes Pred, ARMCC::CondCodes Pred,
unsigned PredReg) const { unsigned PredReg) const {
MachineFunction &MF = *MBB.getParent(); MachineFunction &MF = *MBB.getParent();
@ -55,7 +56,8 @@ void Thumb2RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB,
MF.getFunction()->getContext()->getConstantInt(Type::Int32Ty, Val); MF.getFunction()->getContext()->getConstantInt(Type::Int32Ty, Val);
unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4); unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
BuildMI(MBB, MBBI, dl, TII.get(ARM::t2LDRpci), DestReg) BuildMI(MBB, MBBI, dl, TII.get(ARM::t2LDRpci))
.addReg(DestReg, getDefRegState(true), SubIdx)
.addConstantPoolIndex(Idx).addImm((int64_t)ARMCC::AL).addReg(0); .addConstantPoolIndex(Idx).addImm((int64_t)ARMCC::AL).addReg(0);
} }

View File

@ -32,7 +32,7 @@ public:
void emitLoadConstPool(MachineBasicBlock &MBB, void emitLoadConstPool(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &MBBI, MachineBasicBlock::iterator &MBBI,
DebugLoc dl, DebugLoc dl,
unsigned DestReg, int Val, unsigned DestReg, unsigned SubIdx, int Val,
ARMCC::CondCodes Pred = ARMCC::AL, ARMCC::CondCodes Pred = ARMCC::AL,
unsigned PredReg = 0) const; unsigned PredReg = 0) const;

View File

@ -916,14 +916,11 @@ static bool isSafeToClobberEFLAGS(MachineBasicBlock &MBB,
void X86InstrInfo::reMaterialize(MachineBasicBlock &MBB, void X86InstrInfo::reMaterialize(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I, MachineBasicBlock::iterator I,
unsigned DestReg, unsigned DestReg, unsigned SubIdx,
const MachineInstr *Orig) const { const MachineInstr *Orig) const {
DebugLoc DL = DebugLoc::getUnknownLoc(); DebugLoc DL = DebugLoc::getUnknownLoc();
if (I != MBB.end()) DL = I->getDebugLoc(); if (I != MBB.end()) DL = I->getDebugLoc();
unsigned SubIdx = Orig->getOperand(0).isReg()
? Orig->getOperand(0).getSubReg() : 0;
bool ChangeSubIdx = SubIdx != 0;
if (SubIdx && TargetRegisterInfo::isPhysicalRegister(DestReg)) { if (SubIdx && TargetRegisterInfo::isPhysicalRegister(DestReg)) {
DestReg = RI.getSubReg(DestReg, SubIdx); DestReg = RI.getSubReg(DestReg, SubIdx);
SubIdx = 0; SubIdx = 0;
@ -931,37 +928,36 @@ void X86InstrInfo::reMaterialize(MachineBasicBlock &MBB,
// MOV32r0 etc. are implemented with xor which clobbers condition code. // MOV32r0 etc. are implemented with xor which clobbers condition code.
// Re-materialize them as movri instructions to avoid side effects. // Re-materialize them as movri instructions to avoid side effects.
bool Emitted = false; bool Clone = true;
switch (Orig->getOpcode()) { unsigned Opc = Orig->getOpcode();
switch (Opc) {
default: break; default: break;
case X86::MOV8r0: case X86::MOV8r0:
case X86::MOV16r0: case X86::MOV16r0:
case X86::MOV32r0: { case X86::MOV32r0: {
if (!isSafeToClobberEFLAGS(MBB, I)) { if (!isSafeToClobberEFLAGS(MBB, I)) {
unsigned Opc = 0; switch (Opc) {
switch (Orig->getOpcode()) {
default: break; default: break;
case X86::MOV8r0: Opc = X86::MOV8ri; break; case X86::MOV8r0: Opc = X86::MOV8ri; break;
case X86::MOV16r0: Opc = X86::MOV16ri; break; case X86::MOV16r0: Opc = X86::MOV16ri; break;
case X86::MOV32r0: Opc = X86::MOV32ri; break; case X86::MOV32r0: Opc = X86::MOV32ri; break;
} }
BuildMI(MBB, I, DL, get(Opc), DestReg).addImm(0); Clone = false;
Emitted = true;
} }
break; break;
} }
} }
if (!Emitted) { if (Clone) {
MachineInstr *MI = MBB.getParent()->CloneMachineInstr(Orig); MachineInstr *MI = MBB.getParent()->CloneMachineInstr(Orig);
MI->getOperand(0).setReg(DestReg); MI->getOperand(0).setReg(DestReg);
MBB.insert(I, MI); MBB.insert(I, MI);
} else {
BuildMI(MBB, I, DL, get(Opc), DestReg).addImm(0);
} }
if (ChangeSubIdx) { MachineInstr *NewMI = prior(I);
MachineInstr *NewMI = prior(I); NewMI->getOperand(0).setSubReg(SubIdx);
NewMI->getOperand(0).setSubReg(SubIdx);
}
} }
/// isInvariantLoad - Return true if the specified instruction (which is marked /// isInvariantLoad - Return true if the specified instruction (which is marked

View File

@ -456,7 +456,8 @@ public:
bool isReallyTriviallyReMaterializable(const MachineInstr *MI) const; bool isReallyTriviallyReMaterializable(const MachineInstr *MI) const;
void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
unsigned DestReg, const MachineInstr *Orig) const; unsigned DestReg, unsigned SubIdx,
const MachineInstr *Orig) const;
bool isInvariantLoad(const MachineInstr *MI) const; bool isInvariantLoad(const MachineInstr *MI) const;

View File

@ -1,7 +1,11 @@
; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin | grep movd | count 1
; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin | grep movq ; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin | grep movq
; PR2677 ; PR2677
; FIXME: llvm-as < %s | llc -mtriple=x86_64-apple-darwin | grep movd | count 1
; We now no longer allow instruction whose def has a sub-reg index to be
; rematerialized.
%struct.Bigint = type { %struct.Bigint*, i32, i32, i32, i32, [1 x i32] } %struct.Bigint = type { %struct.Bigint*, i32, i32, i32, i32, [1 x i32] }
define double @_Z7qstrtodPKcPS0_Pb(i8* %s00, i8** %se, i8* %ok) nounwind { define double @_Z7qstrtodPKcPS0_Pb(i8* %s00, i8** %se, i8* %ok) nounwind {

View File

@ -0,0 +1,210 @@
; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin10
; rdar://7059496
%struct.brinfo = type <{ %struct.brinfo*, %struct.brinfo*, i8*, i32, i32, i32, i8, i8, i8, i8 }>
%struct.cadata = type <{ i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i32, i32, %struct.cmatcher*, i8*, i8*, i8*, i8*, i8*, i8*, i32, i8, i8, i8, i8 }>
%struct.cline = type <{ %struct.cline*, i32, i8, i8, i8, i8, i8*, i32, i8, i8, i8, i8, i8*, i32, i8, i8, i8, i8, i8*, i32, i32, %struct.cline*, %struct.cline*, i32, i32 }>
%struct.cmatch = type <{ i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i32, i8, i8, i8, i8, i32*, i32*, i8*, i8*, i32, i32, i32, i32, i16, i8, i8, i16, i8, i8 }>
%struct.cmatcher = type <{ i32, i8, i8, i8, i8, %struct.cmatcher*, i32, i8, i8, i8, i8, %struct.cpattern*, i32, i8, i8, i8, i8, %struct.cpattern*, i32, i8, i8, i8, i8, %struct.cpattern*, i32, i8, i8, i8, i8, %struct.cpattern*, i32, i8, i8, i8, i8 }>
%struct.cpattern = type <{ %struct.cpattern*, i32, i8, i8, i8, i8, %union.anon }>
%struct.patprog = type <{ i64, i64, i64, i64, i32, i32, i32, i32, i8, i8, i8, i8, i8, i8, i8, i8 }>
%union.anon = type <{ [8 x i8] }>
define i32 @addmatches(%struct.cadata* %dat, i8** nocapture %argv) nounwind ssp {
entry:
br i1 undef, label %if.else, label %if.then91
if.then91: ; preds = %entry
br label %if.end96
if.else: ; preds = %entry
br label %if.end96
if.end96: ; preds = %if.else, %if.then91
br i1 undef, label %lor.lhs.false, label %if.then105
lor.lhs.false: ; preds = %if.end96
br i1 undef, label %if.else139, label %if.then105
if.then105: ; preds = %lor.lhs.false, %if.end96
unreachable
if.else139: ; preds = %lor.lhs.false
br i1 undef, label %land.end, label %land.rhs
land.rhs: ; preds = %if.else139
unreachable
land.end: ; preds = %if.else139
br i1 undef, label %land.lhs.true285, label %if.then315
land.lhs.true285: ; preds = %land.end
br i1 undef, label %if.end324, label %if.then322
if.then315: ; preds = %land.end
unreachable
if.then322: ; preds = %land.lhs.true285
unreachable
if.end324: ; preds = %land.lhs.true285
br i1 undef, label %if.end384, label %if.then358
if.then358: ; preds = %if.end324
unreachable
if.end384: ; preds = %if.end324
br i1 undef, label %if.end394, label %land.lhs.true387
land.lhs.true387: ; preds = %if.end384
unreachable
if.end394: ; preds = %if.end384
br i1 undef, label %if.end498, label %land.lhs.true399
land.lhs.true399: ; preds = %if.end394
br i1 undef, label %if.end498, label %if.then406
if.then406: ; preds = %land.lhs.true399
unreachable
if.end498: ; preds = %land.lhs.true399, %if.end394
br i1 undef, label %if.end514, label %if.then503
if.then503: ; preds = %if.end498
unreachable
if.end514: ; preds = %if.end498
br i1 undef, label %if.end585, label %if.then520
if.then520: ; preds = %if.end514
br i1 undef, label %lor.lhs.false547, label %if.then560
lor.lhs.false547: ; preds = %if.then520
unreachable
if.then560: ; preds = %if.then520
br i1 undef, label %if.end585, label %land.lhs.true566
land.lhs.true566: ; preds = %if.then560
br i1 undef, label %if.end585, label %if.then573
if.then573: ; preds = %land.lhs.true566
unreachable
if.end585: ; preds = %land.lhs.true566, %if.then560, %if.end514
br i1 undef, label %cond.true593, label %cond.false599
cond.true593: ; preds = %if.end585
unreachable
cond.false599: ; preds = %if.end585
br i1 undef, label %if.end647, label %if.then621
if.then621: ; preds = %cond.false599
br i1 undef, label %cond.true624, label %cond.false630
cond.true624: ; preds = %if.then621
br label %if.end647
cond.false630: ; preds = %if.then621
unreachable
if.end647: ; preds = %cond.true624, %cond.false599
br i1 undef, label %if.end723, label %if.then701
if.then701: ; preds = %if.end647
br label %if.end723
if.end723: ; preds = %if.then701, %if.end647
br i1 undef, label %if.else1090, label %if.then729
if.then729: ; preds = %if.end723
br i1 undef, label %if.end887, label %if.then812
if.then812: ; preds = %if.then729
unreachable
if.end887: ; preds = %if.then729
br i1 undef, label %if.end972, label %if.then893
if.then893: ; preds = %if.end887
br i1 undef, label %if.end919, label %if.then903
if.then903: ; preds = %if.then893
unreachable
if.end919: ; preds = %if.then893
br label %if.end972
if.end972: ; preds = %if.end919, %if.end887
%sline.0 = phi %struct.cline* [ undef, %if.end919 ], [ null, %if.end887 ] ; <%struct.cline*> [#uses=5]
%bcs.0 = phi i32 [ undef, %if.end919 ], [ 0, %if.end887 ] ; <i32> [#uses=5]
br i1 undef, label %if.end1146, label %land.lhs.true975
land.lhs.true975: ; preds = %if.end972
br i1 undef, label %if.end1146, label %if.then980
if.then980: ; preds = %land.lhs.true975
br i1 undef, label %cond.false1025, label %cond.false1004
cond.false1004: ; preds = %if.then980
unreachable
cond.false1025: ; preds = %if.then980
br i1 undef, label %if.end1146, label %if.then1071
if.then1071: ; preds = %cond.false1025
br i1 undef, label %if.then1074, label %if.end1081
if.then1074: ; preds = %if.then1071
br label %if.end1081
if.end1081: ; preds = %if.then1074, %if.then1071
%call1083 = call %struct.patprog* @patcompile(i8* undef, i32 0, i8** null) nounwind ssp ; <%struct.patprog*> [#uses=2]
br i1 undef, label %if.end1146, label %if.then1086
if.then1086: ; preds = %if.end1081
br label %if.end1146
if.else1090: ; preds = %if.end723
br i1 undef, label %if.end1146, label %land.lhs.true1093
land.lhs.true1093: ; preds = %if.else1090
br i1 undef, label %if.end1146, label %if.then1098
if.then1098: ; preds = %land.lhs.true1093
unreachable
if.end1146: ; preds = %land.lhs.true1093, %if.else1090, %if.then1086, %if.end1081, %cond.false1025, %land.lhs.true975, %if.end972
%cp.0 = phi %struct.patprog* [ %call1083, %if.then1086 ], [ null, %if.end972 ], [ null, %land.lhs.true975 ], [ null, %cond.false1025 ], [ %call1083, %if.end1081 ], [ null, %if.else1090 ], [ null, %land.lhs.true1093 ] ; <%struct.patprog*> [#uses=1]
%sline.1 = phi %struct.cline* [ %sline.0, %if.then1086 ], [ %sline.0, %if.end972 ], [ %sline.0, %land.lhs.true975 ], [ %sline.0, %cond.false1025 ], [ %sline.0, %if.end1081 ], [ null, %if.else1090 ], [ null, %land.lhs.true1093 ] ; <%struct.cline*> [#uses=1]
%bcs.1 = phi i32 [ %bcs.0, %if.then1086 ], [ %bcs.0, %if.end972 ], [ %bcs.0, %land.lhs.true975 ], [ %bcs.0, %cond.false1025 ], [ %bcs.0, %if.end1081 ], [ 0, %if.else1090 ], [ 0, %land.lhs.true1093 ] ; <i32> [#uses=1]
br i1 undef, label %if.end1307, label %do.body1270
do.body1270: ; preds = %if.end1146
unreachable
if.end1307: ; preds = %if.end1146
br i1 undef, label %if.end1318, label %if.then1312
if.then1312: ; preds = %if.end1307
unreachable
if.end1318: ; preds = %if.end1307
br i1 undef, label %for.cond1330.preheader, label %if.then1323
if.then1323: ; preds = %if.end1318
unreachable
for.cond1330.preheader: ; preds = %if.end1318
%call1587 = call i8* @comp_match(i8* undef, i8* undef, i8* undef, %struct.patprog* %cp.0, %struct.cline** undef, i32 0, %struct.brinfo** undef, i32 0, %struct.brinfo** undef, i32 %bcs.1, i32* undef) nounwind ssp ; <i8*> [#uses=0]
%call1667 = call %struct.cmatch* @add_match_data(i32 0, i8* undef, i8* undef, %struct.cline* undef, i8* undef, i8* null, i8* undef, i8* undef, i8* undef, i8* undef, %struct.cline* null, i8* undef, %struct.cline* %sline.1, i8* undef, i32 undef, i32 undef) ssp ; <%struct.cmatch*> [#uses=0]
unreachable
}
declare %struct.patprog* @patcompile(i8*, i32, i8**) ssp
declare i8* @comp_match(i8*, i8*, i8*, %struct.patprog*, %struct.cline**, i32, %struct.brinfo**, i32, %struct.brinfo**, i32, i32*) ssp
declare %struct.cmatch* @add_match_data(i32, i8*, i8*, %struct.cline*, i8*, i8*, i8*, i8*, i8*, i8*, %struct.cline*, i8*, %struct.cline*, i8*, i32, i32) nounwind ssp