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/CodeGen/CriticalAntiDepBreaker.cpp | |
parent | ec6f096c36f4144ff9b3b24c2939720cdcbb7bcc (diff) | |
download | llvm-46388526963aba92344ee8ebd9e86d3556baa088.tar.gz llvm-46388526963aba92344ee8ebd9e86d3556baa088.tar.bz2 llvm-46388526963aba92344ee8ebd9e86d3556baa088.tar.xz |
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/CodeGen/CriticalAntiDepBreaker.cpp')
-rw-r--r-- | lib/CodeGen/CriticalAntiDepBreaker.cpp | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/lib/CodeGen/CriticalAntiDepBreaker.cpp b/lib/CodeGen/CriticalAntiDepBreaker.cpp index 4a62cb7d11..4817346061 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); |