diff options
author | Bob Wilson <bob.wilson@apple.com> | 2009-04-09 17:16:43 +0000 |
---|---|---|
committer | Bob Wilson <bob.wilson@apple.com> | 2009-04-09 17:16:43 +0000 |
commit | d9df5017040489303acb57bdd8697ef0f8bafc08 (patch) | |
tree | 894d9bc70b3f7019ebfc3c0950f9133059a50638 /lib/CodeGen/MachineInstr.cpp | |
parent | 37831d0a1202ab105b495762cb6cce7b6eb2438c (diff) |
Fix pr3954. The register scavenger asserts for inline assembly with
register destinations that are tied to source operands. The
TargetInstrDescr::findTiedToSrcOperand method silently fails for inline
assembly. The existing MachineInstr::isRegReDefinedByTwoAddr was very
close to doing what is needed, so this revision makes a few changes to
that method and also renames it to isRegTiedToUseOperand (for consistency
with the very similar isRegTiedToDefOperand and because it handles both
two-address instructions and inline assembly with tied registers).
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@68714 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/MachineInstr.cpp')
-rw-r--r-- | lib/CodeGen/MachineInstr.cpp | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp index ade8683ec7..d3b2e9a91c 100644 --- a/lib/CodeGen/MachineInstr.cpp +++ b/lib/CodeGen/MachineInstr.cpp @@ -690,12 +690,14 @@ int MachineInstr::findFirstPredOperandIdx() const { return -1; } -/// isRegReDefinedByTwoAddr - Given the index of a register operand, -/// check if the register def is a re-definition due to two addr elimination. -bool MachineInstr::isRegReDefinedByTwoAddr(unsigned DefIdx) const{ +/// isRegTiedToUseOperand - Given the index of a register def operand, +/// check if the register def is tied to a source operand, due to either +/// two-address elimination or inline assembly constraints. Returns the +/// first tied use operand index by reference is UseOpIdx is not null. +bool MachineInstr::isRegTiedToUseOperand(unsigned DefOpIdx, unsigned *UseOpIdx){ if (getOpcode() == TargetInstrInfo::INLINEASM) { - assert(DefIdx >= 2); - const MachineOperand &MO = getOperand(DefIdx); + assert(DefOpIdx >= 2); + const MachineOperand &MO = getOperand(DefOpIdx); if (!MO.isReg() || !MO.isDef()) return false; // Determine the actual operand no corresponding to this index. @@ -705,7 +707,7 @@ bool MachineInstr::isRegReDefinedByTwoAddr(unsigned DefIdx) const{ assert(FMO.isImm()); // Skip over this def. i += InlineAsm::getNumOperandRegisters(FMO.getImm()) + 1; - if (i > DefIdx) + if (i > DefOpIdx) break; ++DefNo; } @@ -717,18 +719,24 @@ bool MachineInstr::isRegReDefinedByTwoAddr(unsigned DefIdx) const{ continue; unsigned Idx; if (InlineAsm::isUseOperandTiedToDef(FMO.getImm(), Idx) && - Idx == DefNo) + Idx == DefNo) { + if (UseOpIdx) + *UseOpIdx = (unsigned)i + 1; return true; + } } } - assert(getOperand(DefIdx).isDef() && "DefIdx is not a def!"); + assert(getOperand(DefOpIdx).isDef() && "DefOpIdx is not a def!"); const TargetInstrDesc &TID = getDesc(); for (unsigned i = 0, e = TID.getNumOperands(); i != e; ++i) { const MachineOperand &MO = getOperand(i); if (MO.isReg() && MO.isUse() && - TID.getOperandConstraint(i, TOI::TIED_TO) == (int)DefIdx) + TID.getOperandConstraint(i, TOI::TIED_TO) == (int)DefOpIdx) { + if (UseOpIdx) + *UseOpIdx = (unsigned)i; return true; + } } return false; } |