From f8614473936de2a72a9beffed143716fc13357ed Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Tue, 2 Nov 2010 18:16:45 +0000 Subject: [PATCH] Fixes : During postRAsched, the antidependence breaker needs to check all definitions of the antidepenent register to avoid multiple defs of the same new register. llvm-svn: 118032 --- lib/CodeGen/CriticalAntiDepBreaker.cpp | 36 +++++++++++++++++++------- lib/CodeGen/CriticalAntiDepBreaker.h | 10 +++++-- 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/lib/CodeGen/CriticalAntiDepBreaker.cpp b/lib/CodeGen/CriticalAntiDepBreaker.cpp index 4a62cb7d11e..4817346061f 100644 --- a/lib/CodeGen/CriticalAntiDepBreaker.cpp +++ b/lib/CodeGen/CriticalAntiDepBreaker.cpp @@ -325,8 +325,25 @@ void CriticalAntiDepBreaker::ScanInstruction(MachineInstr *MI, } } +// Check all machine instructions that define the antidependent register. +// Return true if any of these instructions define the new register. +bool +CriticalAntiDepBreaker::isNewRegModifiedByRefs(RegRefIter RegRefBegin, + RegRefIter RegRefEnd, + unsigned NewReg) +{ + for (RegRefIter I = RegRefBegin; I != RegRefEnd; ++I ) { + MachineOperand *MO = I->second; + if (MO->isDef()) continue; + if (MO->getParent()->modifiesRegister(NewReg, TRI)) + return true; + } + return false; +} + unsigned -CriticalAntiDepBreaker::findSuitableFreeRegister(MachineInstr *MI, +CriticalAntiDepBreaker::findSuitableFreeRegister(RegRefIter RegRefBegin, + RegRefIter RegRefEnd, unsigned AntiDepReg, unsigned LastNewReg, const TargetRegisterClass *RC) @@ -342,10 +359,10 @@ CriticalAntiDepBreaker::findSuitableFreeRegister(MachineInstr *MI, // an anti-dependence with this AntiDepReg, because that would // re-introduce that anti-dependence. if (NewReg == LastNewReg) continue; - // If the instruction already has a def of the NewReg, it's not suitable. - // For example, Instruction with multiple definitions can result in this - // condition. - if (MI->modifiesRegister(NewReg, TRI)) continue; + // If any instructions that define AntiDepReg also define the NewReg, it's + // not suitable. For example, Instruction with multiple definitions can + // result in this condition. + if (isNewRegModifiedByRefs(RegRefBegin, RegRefEnd, NewReg)) continue; // If NewReg is dead and NewReg's most recent def is not before // AntiDepReg's kill, it's safe to replace AntiDepReg with NewReg. assert(((KillIndices[AntiDepReg] == ~0u) != (DefIndices[AntiDepReg] == ~0u)) @@ -552,7 +569,11 @@ BreakAntiDependencies(const std::vector& SUnits, // TODO: Instead of picking the first free register, consider which might // be the best. if (AntiDepReg != 0) { - if (unsigned NewReg = findSuitableFreeRegister(MI, AntiDepReg, + std::pair::iterator, + std::multimap::iterator> + Range = RegRefs.equal_range(AntiDepReg); + if (unsigned NewReg = findSuitableFreeRegister(Range.first, Range.second, + AntiDepReg, LastNewReg[AntiDepReg], RC)) { DEBUG(dbgs() << "Breaking anti-dependence edge on " @@ -562,9 +583,6 @@ BreakAntiDependencies(const std::vector& SUnits, // Update the references to the old register to refer to the new // register. - std::pair::iterator, - std::multimap::iterator> - Range = RegRefs.equal_range(AntiDepReg); for (std::multimap::iterator Q = Range.first, QE = Range.second; Q != QE; ++Q) { Q->second->setReg(NewReg); diff --git a/lib/CodeGen/CriticalAntiDepBreaker.h b/lib/CodeGen/CriticalAntiDepBreaker.h index 0ed7c35b0f0..df21ef28340 100644 --- a/lib/CodeGen/CriticalAntiDepBreaker.h +++ b/lib/CodeGen/CriticalAntiDepBreaker.h @@ -50,6 +50,8 @@ class TargetRegisterInfo; /// RegRegs - Map registers to all their references within a live range. std::multimap RegRefs; + typedef std::multimap::const_iterator + RegRefIter; /// KillIndices - The index of the most recent kill (proceding bottom-up), /// or ~0u if the register is not live. @@ -90,10 +92,14 @@ class TargetRegisterInfo; private: void PrescanInstruction(MachineInstr *MI); void ScanInstruction(MachineInstr *MI, unsigned Count); - unsigned findSuitableFreeRegister(MachineInstr *MI, + bool isNewRegModifiedByRefs(RegRefIter RegRefBegin, + RegRefIter RegRefEnd, + unsigned NewReg); + unsigned findSuitableFreeRegister(RegRefIter RegRefBegin, + RegRefIter RegRefEnd, unsigned AntiDepReg, unsigned LastNewReg, - const TargetRegisterClass *); + const TargetRegisterClass *RC); }; }