diff options
author | Evan Cheng <evan.cheng@apple.com> | 2009-07-01 08:19:36 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2009-07-01 08:19:36 +0000 |
commit | 459a7c6b6ad9c4fcb9f119aa6eaaf2769b00d9b1 (patch) | |
tree | 006dc09ed750a6cf80ca8dbd944db91063491f3e /lib | |
parent | d6bb283de9f81428762f13b7f6bae31adaba5768 (diff) |
Remove special handling of implicit_def. Fix a couple more bugs in liveintervalanalysis and coalescer handling of implicit_def.
Note, isUndef marker must be placed even on implicit_def def operand or else the scavenger will not ignore it. This is necessary because -O0 path does not use liveintervalanalysis, it treats implicit_def just like any other def.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74601 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/CodeGen/LiveIntervalAnalysis.cpp | 75 | ||||
-rw-r--r-- | lib/CodeGen/RegisterScavenging.cpp | 31 | ||||
-rw-r--r-- | lib/CodeGen/SimpleRegisterCoalescing.cpp | 19 |
3 files changed, 74 insertions, 51 deletions
diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp index 9339c951a8..52a30bc067 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -124,7 +124,9 @@ void LiveIntervals::processImplicitDefs() { ImpDefMIs.push_back(MI); continue; } - for (unsigned i = 0; i != MI->getNumOperands(); ++i) { + + bool ChangedToImpDef = false; + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { MachineOperand& MO = MI->getOperand(i); if (!MO.isReg() || !MO.isUse()) continue; @@ -133,16 +135,35 @@ void LiveIntervals::processImplicitDefs() { continue; if (!ImpDefRegs.count(Reg)) continue; + // Use is a copy, just turn it into an implicit_def. + unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; + if (tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg) && + Reg == SrcReg) { + bool isKill = MO.isKill(); + MI->setDesc(tii_->get(TargetInstrInfo::IMPLICIT_DEF)); + for (int j = MI->getNumOperands() - 1, ee = 0; j > ee; --j) + MI->RemoveOperand(j); + if (isKill) + ImpDefRegs.erase(Reg); + ChangedToImpDef = true; + break; + } + MO.setIsUndef(); if (MO.isKill() || MI->isRegTiedToDefOperand(i)) ImpDefRegs.erase(Reg); } - for (unsigned i = 0; i != MI->getNumOperands(); ++i) { - MachineOperand& MO = MI->getOperand(i); - if (!MO.isReg() || !MO.isDef()) - continue; - ImpDefRegs.erase(MO.getReg()); + if (ChangedToImpDef) { + // Backtrack to process this new implicit_def. + --I; + } else { + for (unsigned i = 0; i != MI->getNumOperands(); ++i) { + MachineOperand& MO = MI->getOperand(i); + if (!MO.isReg() || !MO.isDef()) + continue; + ImpDefRegs.erase(MO.getReg()); + } } } @@ -155,33 +176,39 @@ void LiveIntervals::processImplicitDefs() { continue; if (!ImpDefRegs.count(Reg)) continue; - bool HasLocalUse = false; - for (MachineRegisterInfo::reg_iterator RI = mri_->reg_begin(Reg), - RE = mri_->reg_end(); RI != RE; ) { - MachineOperand &RMO = RI.getOperand(); - MachineInstr *RMI = &*RI; - ++RI; - if (RMO.isDef()) { - // Don't expect another def of the same register. - assert(RMI == MI && - "Register with multiple defs including an implicit_def?"); - continue; + + // If there are multiple defs of the same register and at least one + // is not an implicit_def, do not insert implicit_def's before the + // uses. + bool Skip = false; + for (MachineRegisterInfo::def_iterator DI = mri_->def_begin(Reg), + DE = mri_->def_end(); DI != DE; ++DI) { + if (DI->getOpcode() != TargetInstrInfo::IMPLICIT_DEF) { + Skip = true; + break; } + } + if (Skip) + continue; + + for (MachineRegisterInfo::use_iterator UI = mri_->use_begin(Reg), + UE = mri_->use_end(); UI != UE; ) { + MachineOperand &RMO = UI.getOperand(); + MachineInstr *RMI = &*UI; + ++UI; MachineBasicBlock *RMBB = RMI->getParent(); - if (RMBB == MBB) { - HasLocalUse = true; + if (RMBB == MBB) continue; - } const TargetRegisterClass* RC = mri_->getRegClass(Reg); unsigned NewVReg = mri_->createVirtualRegister(RC); - BuildMI(*RMBB, RMI, RMI->getDebugLoc(), - tii_->get(TargetInstrInfo::IMPLICIT_DEF), NewVReg); + MachineInstrBuilder MIB = + BuildMI(*RMBB, RMI, RMI->getDebugLoc(), + tii_->get(TargetInstrInfo::IMPLICIT_DEF), NewVReg); + (*MIB).getOperand(0).setIsUndef(); RMO.setReg(NewVReg); RMO.setIsUndef(); RMO.setIsKill(); } - if (!HasLocalUse) - MI->eraseFromParent(); } ImpDefRegs.clear(); ImpDefMIs.clear(); diff --git a/lib/CodeGen/RegisterScavenging.cpp b/lib/CodeGen/RegisterScavenging.cpp index 58f4284ac7..d7fe7a2d54 100644 --- a/lib/CodeGen/RegisterScavenging.cpp +++ b/lib/CodeGen/RegisterScavenging.cpp @@ -57,28 +57,22 @@ static bool RedefinesSuperRegPart(const MachineInstr *MI, } /// setUsed - Set the register and its sub-registers as being used. -void RegScavenger::setUsed(unsigned Reg, bool ImpDef) { +void RegScavenger::setUsed(unsigned Reg) { RegsAvailable.reset(Reg); - ImplicitDefed[Reg] = ImpDef; for (const unsigned *SubRegs = TRI->getSubRegisters(Reg); - unsigned SubReg = *SubRegs; ++SubRegs) { + unsigned SubReg = *SubRegs; ++SubRegs) RegsAvailable.reset(SubReg); - ImplicitDefed[SubReg] = ImpDef; - } } /// setUnused - Set the register and its sub-registers as being unused. void RegScavenger::setUnused(unsigned Reg, const MachineInstr *MI) { RegsAvailable.set(Reg); - ImplicitDefed.reset(Reg); for (const unsigned *SubRegs = TRI->getSubRegisters(Reg); unsigned SubReg = *SubRegs; ++SubRegs) - if (!RedefinesSuperRegPart(MI, Reg, TRI)) { + if (!RedefinesSuperRegPart(MI, Reg, TRI)) RegsAvailable.set(SubReg); - ImplicitDefed.reset(SubReg); - } } void RegScavenger::enterBasicBlock(MachineBasicBlock *mbb) { @@ -94,7 +88,6 @@ void RegScavenger::enterBasicBlock(MachineBasicBlock *mbb) { if (!MBB) { NumPhysRegs = TRI->getNumRegs(); RegsAvailable.resize(NumPhysRegs); - ImplicitDefed.resize(NumPhysRegs); // Create reserved registers bitvector. ReservedRegs = TRI->getReservedRegs(MF); @@ -113,7 +106,6 @@ void RegScavenger::enterBasicBlock(MachineBasicBlock *mbb) { ScavengeRestore = NULL; CurrDist = 0; DistanceMap.clear(); - ImplicitDefed.reset(); // All registers started out unused. RegsAvailable.set(); @@ -195,7 +187,10 @@ void RegScavenger::forward() { ScavengeRestore = NULL; } - bool IsImpDef = MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF; +#if 0 + if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF) + return; +#endif // Separate register operands into 3 classes: uses, defs, earlyclobbers. SmallVector<std::pair<const MachineOperand*,unsigned>, 4> UseMOs; @@ -221,14 +216,7 @@ void RegScavenger::forward() { assert(isUsed(Reg) && "Using an undefined register!"); - // Kill of implicit_def defined registers are ignored. e.g. - // entry: 0x2029ab8, LLVM BB @0x1b06080, ID#0: - // Live Ins: %R0 - // %R0<def> = IMPLICIT_DEF - // %R0<def> = IMPLICIT_DEF - // STR %R0<kill>, %R0, %reg0, 0, 14, %reg0, Mem:ST(4,4) [0x1b06510 + 0] - // %R1<def> = LDR %R0, %reg0, 24, 14, %reg0, Mem:LD(4,4) [0x1b065bc + 0] - if (MO.isKill() && !isReserved(Reg) && !isImplicitlyDefined(Reg)) { + if (MO.isKill() && !isReserved(Reg)) { KillRegs.set(Reg); // Mark sub-registers as used. @@ -278,10 +266,9 @@ void RegScavenger::forward() { // Implicit def is allowed to "re-define" any register. Similarly, // implicitly defined registers can be clobbered. assert((isReserved(Reg) || isUnused(Reg) || - IsImpDef || isImplicitlyDefined(Reg) || isLiveInButUnusedBefore(Reg, MI, MBB, TRI, MRI)) && "Re-defining a live register!"); - setUsed(Reg, IsImpDef); + setUsed(Reg); } } diff --git a/lib/CodeGen/SimpleRegisterCoalescing.cpp b/lib/CodeGen/SimpleRegisterCoalescing.cpp index c2105e617b..7e7d6b8f68 100644 --- a/lib/CodeGen/SimpleRegisterCoalescing.cpp +++ b/lib/CodeGen/SimpleRegisterCoalescing.cpp @@ -2669,19 +2669,28 @@ SimpleRegisterCoalescing::TurnCopyIntoImpDef(MachineBasicBlock::iterator &I, CopyMI->setDesc(tii_->get(TargetInstrInfo::IMPLICIT_DEF)); for (int i = CopyMI->getNumOperands() - 1, e = 0; i > e; --i) CopyMI->RemoveOperand(i); + CopyMI->getOperand(0).setIsUndef(); bool NoUse = mri_->use_empty(SrcReg); if (NoUse) { - for (MachineRegisterInfo::reg_iterator I = mri_->reg_begin(SrcReg), - E = mri_->reg_end(); I != E; ) { - assert(I.getOperand().isDef()); - MachineInstr *DefMI = &*I; - ++I; + for (MachineRegisterInfo::reg_iterator RI = mri_->reg_begin(SrcReg), + RE = mri_->reg_end(); RI != RE; ) { + assert(RI.getOperand().isDef()); + MachineInstr *DefMI = &*RI; + ++RI; // The implicit_def source has no other uses, delete it. assert(DefMI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF); li_->RemoveMachineInstrFromMaps(DefMI); DefMI->eraseFromParent(); } } + + // Mark uses of implicit_def isUndef. + for (MachineRegisterInfo::use_iterator RI = mri_->use_begin(DstReg), + RE = mri_->use_end(); RI != RE; ++RI) { + assert((*RI).getParent() == MBB); + RI.getOperand().setIsUndef(); + } + ++I; return true; } |