diff options
author | Evan Cheng <evan.cheng@apple.com> | 2009-03-23 08:01:15 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2009-03-23 08:01:15 +0000 |
commit | 2682ea07a439718636fb7f2d841dc1095331244f (patch) | |
tree | c2d5d369ef2db0b2fab9a7fc0aa4fbbb6a98a9c5 /lib/CodeGen/MachineInstr.cpp | |
parent | e8746322b19a60d50897ea85943a13a6ce8758e7 (diff) | |
download | external_llvm-2682ea07a439718636fb7f2d841dc1095331244f.zip external_llvm-2682ea07a439718636fb7f2d841dc1095331244f.tar.gz external_llvm-2682ea07a439718636fb7f2d841dc1095331244f.tar.bz2 |
Model inline asm constraint which ties an input to an output register as machine operand TIED_TO constraint. This eliminated the need to pre-allocate registers for these. This also allows register allocator can eliminate the unneeded copies.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@67512 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/MachineInstr.cpp')
-rw-r--r-- | lib/CodeGen/MachineInstr.cpp | 61 |
1 files changed, 60 insertions, 1 deletions
diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp index cc85b80..965c2a2 100644 --- a/lib/CodeGen/MachineInstr.cpp +++ b/lib/CodeGen/MachineInstr.cpp @@ -11,8 +11,9 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Constants.h" #include "llvm/CodeGen/MachineInstr.h" +#include "llvm/Constants.h" +#include "llvm/InlineAsm.h" #include "llvm/Value.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineRegisterInfo.h" @@ -692,6 +693,35 @@ int MachineInstr::findFirstPredOperandIdx() const { /// 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{ + if (getOpcode() == TargetInstrInfo::INLINEASM) { + assert(DefIdx >= 2); + const MachineOperand &MO = getOperand(DefIdx); + if (!MO.isReg() || !MO.isDef()) + return false; + // Determine the actual operand no corresponding to this index. + unsigned DefNo = 0; + for (unsigned i = 1, e = getNumOperands(); i < e; ) { + const MachineOperand &FMO = getOperand(i); + assert(FMO.isImm()); + // Skip over this def. + i += InlineAsm::getNumOperandRegisters(FMO.getImm()) + 1; + if (i > DefIdx) + break; + ++DefNo; + } + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { + const MachineOperand &FMO = getOperand(i); + if (!FMO.isImm()) + continue; + if (i+1 >= e || !getOperand(i+1).isReg() || !getOperand(i+1).isUse()) + continue; + unsigned Idx; + if (InlineAsm::isUseOperandTiedToDef(FMO.getImm(), Idx) && + Idx == DefNo) + return true; + } + } + assert(getOperand(DefIdx).isDef() && "DefIdx is not a def!"); const TargetInstrDesc &TID = getDesc(); for (unsigned i = 0, e = TID.getNumOperands(); i != e; ++i) { @@ -707,6 +737,35 @@ bool MachineInstr::isRegReDefinedByTwoAddr(unsigned DefIdx) const{ /// is a register use and it is tied to an def operand. It also returns the def /// operand index by reference. bool MachineInstr::isRegTiedToDefOperand(unsigned UseOpIdx, unsigned *DefOpIdx){ + if (getOpcode() == TargetInstrInfo::INLINEASM) { + const MachineOperand &MO = getOperand(UseOpIdx); + if (!MO.isReg() || !MO.isUse()) + return false; + assert(UseOpIdx > 0); + const MachineOperand &UFMO = getOperand(UseOpIdx-1); + if (!UFMO.isImm()) + return false; // Must be physreg uses. + unsigned DefNo; + if (InlineAsm::isUseOperandTiedToDef(UFMO.getImm(), DefNo)) { + if (!DefOpIdx) + return true; + + unsigned DefIdx = 1; + // Remember to adjust the index. First operand is asm string, then there + // is a flag for each. + while (DefNo) { + const MachineOperand &FMO = getOperand(DefIdx); + assert(FMO.isImm()); + // Skip over this def. + DefIdx += InlineAsm::getNumOperandRegisters(FMO.getImm()) + 1; + --DefNo; + } + *DefOpIdx = DefIdx+1; + return true; + } + return false; + } + const TargetInstrDesc &TID = getDesc(); if (UseOpIdx >= TID.getNumOperands()) return false; |