diff options
-rw-r--r-- | include/llvm/CodeGen/MachineInstr.h | 13 | ||||
-rw-r--r-- | lib/CodeGen/MachineInstr.cpp | 33 |
2 files changed, 46 insertions, 0 deletions
diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index a6376bee4e..cae38f3470 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -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 diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp index 965c6c5bca..0ef1ef603b 100644 --- a/lib/CodeGen/MachineInstr.cpp +++ b/lib/CodeGen/MachineInstr.cpp @@ -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. |