summaryrefslogtreecommitdiff
path: root/lib/CodeGen/CriticalAntiDepBreaker.cpp
diff options
context:
space:
mode:
authorAndrew Trick <atrick@apple.com>2010-11-02 18:16:45 +0000
committerAndrew Trick <atrick@apple.com>2010-11-02 18:16:45 +0000
commit46388526963aba92344ee8ebd9e86d3556baa088 (patch)
treea107c6f7bf05364db2a2bd5090797ff94afb19d2 /lib/CodeGen/CriticalAntiDepBreaker.cpp
parentec6f096c36f4144ff9b3b24c2939720cdcbb7bcc (diff)
downloadllvm-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.cpp36
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);