diff options
author | Evan Cheng <evan.cheng@apple.com> | 2008-04-05 01:27:09 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2008-04-05 01:27:09 +0000 |
commit | 1dc7869025d91906e8305e921ddb82dac780d70e (patch) | |
tree | 34e3610e0637e52e4b08f40ea377cb1f73bd8721 /lib/CodeGen/RegisterScavenging.cpp | |
parent | 0c0f83ff5d214a7f42e86ae62814526ba40a28cf (diff) | |
download | external_llvm-1dc7869025d91906e8305e921ddb82dac780d70e.zip external_llvm-1dc7869025d91906e8305e921ddb82dac780d70e.tar.gz external_llvm-1dc7869025d91906e8305e921ddb82dac780d70e.tar.bz2 |
1. IMPLICIT_DEF can *re-define* any register.
2. Coalescer can now create an interesting situation where a register def can
reaches itself without being killed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@49246 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/RegisterScavenging.cpp')
-rw-r--r-- | lib/CodeGen/RegisterScavenging.cpp | 44 |
1 files changed, 42 insertions, 2 deletions
diff --git a/lib/CodeGen/RegisterScavenging.cpp b/lib/CodeGen/RegisterScavenging.cpp index eb1570d..c71d3be 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; @@ -76,6 +78,7 @@ void RegScavenger::enterBasicBlock(MachineBasicBlock *mbb) { const TargetMachine &TM = MF.getTarget(); TII = TM.getInstrInfo(); TRI = TM.getRegisterInfo(); + MRI = &MF.getRegInfo(); assert((NumPhysRegs == 0 || NumPhysRegs == TRI->getNumRegs()) && "Target changed?"); @@ -119,7 +122,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); @@ -127,6 +130,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<MachineInstr*, 4> 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) { @@ -203,7 +240,10 @@ void RegScavenger::forward() { if (RedefinesSuperRegPart(MI, MO, TRI)) continue; - assert((isUnused(Reg) || isReserved(Reg)) && + // Implicit def is allowed to "re-define" any register. + assert((isReserved(Reg) || isUnused(Reg) || + MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF || + isLiveInButUnusedBefore(Reg, MI, MBB, TRI, MRI)) && "Re-defining a live register!"); setUsed(Reg); } |