Add MachineInstr::getRegClassConstraint().
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Wed, 12 Oct 2011 23:37:36 +0000 (23:37 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Wed, 12 Oct 2011 23:37:36 +0000 (23:37 +0000)
Most instructions have some requirements for their register operands.
Usually, this is expressed as register class constraints in the
MCInstrDesc, but for inline assembly the constraints are encoded in the
flag words.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141835 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/MachineInstr.h
lib/CodeGen/MachineInstr.cpp

index a6376bee4effa8d7966cf948d996a163ee406d39..cae38f34709dc089bfbd843c0c5f93574d8f3768 100644 (file)
@@ -32,6 +32,7 @@ namespace llvm {
 template <typename T> class SmallVectorImpl;
 class AliasAnalysis;
 class TargetInstrInfo;
+class TargetRegisterClass;
 class TargetRegisterInfo;
 class MachineFunction;
 class MachineMemOperand;
@@ -400,6 +401,18 @@ public:
   ///
   int findInlineAsmFlagIdx(unsigned OpIdx, unsigned *GroupNo = 0) const;
 
+  /// getRegClassConstraint - Compute the static register class constraint for
+  /// operand OpIdx.  For normal instructions, this is derived from the
+  /// MCInstrDesc.  For inline assembly it is derived from the flag words.
+  ///
+  /// Returns NULL if the static register classs constraint cannot be
+  /// determined.
+  ///
+  const TargetRegisterClass*
+  getRegClassConstraint(unsigned OpIdx,
+                        const TargetInstrInfo *TII,
+                        const TargetRegisterInfo *TRI) 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
index 965c6c5bcae83b5ac91a63cee2715a7c40e33c45..0ef1ef603b7bac881f1597355e05b09434b64ed7 100644 (file)
@@ -854,6 +854,39 @@ int MachineInstr::findInlineAsmFlagIdx(unsigned OpIdx,
   return -1;
 }
 
+const TargetRegisterClass*
+MachineInstr::getRegClassConstraint(unsigned OpIdx,
+                                    const TargetInstrInfo *TII,
+                                    const TargetRegisterInfo *TRI) const {
+  // Most opcodes have fixed constraints in their MCInstrDesc.
+  if (!isInlineAsm())
+    return TII->getRegClass(getDesc(), OpIdx, TRI);
+
+  if (!getOperand(OpIdx).isReg())
+    return NULL;
+
+  // For tied uses on inline asm, get the constraint from the def.
+  unsigned DefIdx;
+  if (getOperand(OpIdx).isUse() && isRegTiedToDefOperand(OpIdx, &DefIdx))
+    OpIdx = DefIdx;
+
+  // Inline asm stores register class constraints in the flag word.
+  int FlagIdx = findInlineAsmFlagIdx(OpIdx);
+  if (FlagIdx < 0)
+    return NULL;
+
+  unsigned Flag = getOperand(FlagIdx).getImm();
+  unsigned RCID;
+  if (InlineAsm::hasRegClassConstraint(Flag, RCID))
+    return TRI->getRegClass(RCID);
+
+  // Assume that all registers in a memory operand are pointers.
+  if (InlineAsm::getKind(Flag) == InlineAsm::Kind_Mem)
+    return TRI->getPointerRegClass();
+
+  return NULL;
+}
+
 /// findRegisterUseOperandIdx() - Returns the MachineOperand that is a use of
 /// the specific register or -1 if it is not found. It further tightens
 /// the search criteria to a use that kills the register if isKill is true.