aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/MachineInstr.cpp
diff options
context:
space:
mode:
authorBob Wilson <bob.wilson@apple.com>2009-04-09 17:16:43 +0000
committerBob Wilson <bob.wilson@apple.com>2009-04-09 17:16:43 +0000
commitaded995fd1ea26db2191622c7c1d352662c06b8d (patch)
tree894d9bc70b3f7019ebfc3c0950f9133059a50638 /lib/CodeGen/MachineInstr.cpp
parenteef509d484c70d405c5e3fcfacefdd73ba61fc2c (diff)
downloadexternal_llvm-aded995fd1ea26db2191622c7c1d352662c06b8d.zip
external_llvm-aded995fd1ea26db2191622c7c1d352662c06b8d.tar.gz
external_llvm-aded995fd1ea26db2191622c7c1d352662c06b8d.tar.bz2
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.cpp26
1 files changed, 17 insertions, 9 deletions
diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp
index ade8683..d3b2e9a 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;
}