aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/MachineInstr.cpp
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2009-03-23 08:01:15 +0000
committerEvan Cheng <evan.cheng@apple.com>2009-03-23 08:01:15 +0000
commit2682ea07a439718636fb7f2d841dc1095331244f (patch)
treec2d5d369ef2db0b2fab9a7fc0aa4fbbb6a98a9c5 /lib/CodeGen/MachineInstr.cpp
parente8746322b19a60d50897ea85943a13a6ce8758e7 (diff)
downloadexternal_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.cpp61
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;