diff options
author | Andrew Trick <atrick@apple.com> | 2010-11-02 18:16:45 +0000 |
---|---|---|
committer | Andrew Trick <atrick@apple.com> | 2010-11-02 18:16:45 +0000 |
commit | 46388526963aba92344ee8ebd9e86d3556baa088 (patch) | |
tree | a107c6f7bf05364db2a2bd5090797ff94afb19d2 /lib | |
parent | ec6f096c36f4144ff9b3b24c2939720cdcbb7bcc (diff) | |
download | external_llvm-46388526963aba92344ee8ebd9e86d3556baa088.zip external_llvm-46388526963aba92344ee8ebd9e86d3556baa088.tar.gz external_llvm-46388526963aba92344ee8ebd9e86d3556baa088.tar.bz2 |
Fixes <rdar://problem/8612856>: During postRAsched, the antidependence
breaker needs to check all definitions of the antidepenent register to
avoid multiple defs of the same new register.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@118032 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/CodeGen/CriticalAntiDepBreaker.cpp | 36 | ||||
-rw-r--r-- | 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 4a62cb7..4817346 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<SUnit>& 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<std::multimap<unsigned, MachineOperand *>::iterator, + std::multimap<unsigned, MachineOperand *>::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<SUnit>& SUnits, // Update the references to the old register to refer to the new // register. - std::pair<std::multimap<unsigned, MachineOperand *>::iterator, - std::multimap<unsigned, MachineOperand *>::iterator> - Range = RegRefs.equal_range(AntiDepReg); for (std::multimap<unsigned, MachineOperand *>::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 0ed7c35..df21ef2 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<unsigned, MachineOperand *> RegRefs; + typedef std::multimap<unsigned, MachineOperand *>::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); }; } |