X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FRegisterScavenging.cpp;h=ba2395a32a96d3695f48f87a94ec4cdc81abf243;hb=5ac319ac7125b009adddcc49294d2e040c4a91e5;hp=635e0cc825baed924974051d6001d4cf7ee46046;hpb=ed1fcd8987a7d39ca69bfa3cbf14b270738f029c;p=oota-llvm.git diff --git a/lib/CodeGen/RegisterScavenging.cpp b/lib/CodeGen/RegisterScavenging.cpp index 635e0cc825b..ba2395a32a9 100644 --- a/lib/CodeGen/RegisterScavenging.cpp +++ b/lib/CodeGen/RegisterScavenging.cpp @@ -19,9 +19,11 @@ #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/STLExtras.h" using namespace llvm; @@ -29,15 +31,21 @@ using namespace llvm; /// part of a super-register. static bool RedefinesSuperRegPart(const MachineInstr *MI, unsigned SubReg, const TargetRegisterInfo *TRI) { + bool SeenSuperUse = false; + bool SeenSuperDef = false; for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { const MachineOperand &MO = MI->getOperand(i); - if (!MO.isRegister() || !MO.isUse()) + if (!MO.isRegister()) continue; - if (TRI->isSuperRegister(SubReg, MO.getReg())) - return true; + if (TRI->isSuperRegister(SubReg, MO.getReg())) { + if (MO.isUse()) + SeenSuperUse = true; + else if (MO.isImplicit()) + SeenSuperDef = true; + } } - return false; + return SeenSuperDef && SeenSuperUse; } static bool RedefinesSuperRegPart(const MachineInstr *MI, @@ -48,29 +56,36 @@ static bool RedefinesSuperRegPart(const MachineInstr *MI, } /// setUsed - Set the register and its sub-registers as being used. -void RegScavenger::setUsed(unsigned Reg) { +void RegScavenger::setUsed(unsigned Reg, bool ImpDef) { 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) { - const MachineFunction &MF = *mbb->getParent(); + MachineFunction &MF = *mbb->getParent(); const TargetMachine &TM = MF.getTarget(); TII = TM.getInstrInfo(); TRI = TM.getRegisterInfo(); + MRI = &MF.getRegInfo(); assert((NumPhysRegs == 0 || NumPhysRegs == TRI->getNumRegs()) && "Target changed?"); @@ -78,6 +93,7 @@ void RegScavenger::enterBasicBlock(MachineBasicBlock *mbb) { if (!MBB) { NumPhysRegs = TRI->getNumRegs(); RegsAvailable.resize(NumPhysRegs); + ImplicitDefed.resize(NumPhysRegs); // Create reserved registers bitvector. ReservedRegs = TRI->getReservedRegs(MF); @@ -114,7 +130,7 @@ void RegScavenger::restoreScavengedReg() { return; TII->loadRegFromStackSlot(*MBB, MBBI, ScavengedReg, - ScavengingFrameIndex, ScavengedRC); + ScavengingFrameIndex, ScavengedRC); MachineBasicBlock::iterator II = prior(MBBI); TRI->eliminateFrameIndex(II, 0, this); setUsed(ScavengedReg); @@ -122,6 +138,40 @@ void RegScavenger::restoreScavengedReg() { ScavengedRC = NULL; } +/// isLiveInButUnusedBefore - Return true if register is livein the MBB not +/// not used before it reaches the MI that defines register. +static bool isLiveInButUnusedBefore(unsigned Reg, MachineInstr *MI, + MachineBasicBlock *MBB, + const TargetRegisterInfo *TRI, + MachineRegisterInfo* MRI) { + // First check if register is livein. + bool isLiveIn = false; + for (MachineBasicBlock::const_livein_iterator I = MBB->livein_begin(), + E = MBB->livein_end(); I != E; ++I) + if (Reg == *I || TRI->isSuperRegister(Reg, *I)) { + isLiveIn = true; + break; + } + if (!isLiveIn) + return false; + + // Is there any use of it before the specified MI? + SmallPtrSet UsesInMBB; + for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(Reg), + UE = MRI->use_end(); UI != UE; ++UI) { + MachineInstr *UseMI = &*UI; + if (UseMI->getParent() == MBB) + UsesInMBB.insert(UseMI); + } + if (UsesInMBB.empty()) + return true; + + for (MachineBasicBlock::iterator I = MBB->begin(), E = MI; I != E; ++I) + if (UsesInMBB.count(&*I)) + return false; + return true; +} + void RegScavenger::forward() { // Move ptr forward. if (!Tracking) { @@ -165,8 +215,7 @@ void RegScavenger::forward() { // instruction. for (const unsigned *SubRegs = TRI->getSubRegisters(Reg); unsigned SubReg = *SubRegs; ++SubRegs) - if (!RedefinesSuperRegPart(MI, Reg, TRI)) - ChangedRegs.set(SubReg); + ChangedRegs.set(SubReg); } } @@ -175,6 +224,7 @@ void RegScavenger::forward() { setUnused(ChangedRegs); // Process defs. + bool IsImpDef = MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF; for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { const MachineOperand &MO = MI->getOperand(i); @@ -199,9 +249,13 @@ void RegScavenger::forward() { if (RedefinesSuperRegPart(MI, MO, TRI)) continue; - assert((isUnused(Reg) || isReserved(Reg)) && + // 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); + setUsed(Reg, IsImpDef); } }