1. Introduce a new TargetOperandInfo::getRegClass() helper method
authorChris Lattner <sabre@nondot.org>
Wed, 29 Jul 2009 21:10:12 +0000 (21:10 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 29 Jul 2009 21:10:12 +0000 (21:10 +0000)
   and convert code to using it, instead of having lots of things
   poke the isLookupPtrRegClass() method directly.

2. Make PointerLikeRegClass contain a 'kind' int, and store it in
   the existing regclass field of TargetOperandInfo when the
   isLookupPtrRegClass() predicate is set.  Make getRegClass pass
   this into TargetRegisterInfo::getPointerRegClass(), allowing
   targets to have multiple ptr_rc things.

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

include/llvm/Target/Target.td
include/llvm/Target/TargetInstrDesc.h
lib/CodeGen/MachineVerifier.cpp
lib/Target/TargetInstrInfo.cpp
lib/Target/X86/X86InstrInfo.cpp
utils/TableGen/InstrInfoEmitter.cpp

index a62036a5203c27baebce7faac3e3bd3de2b89f57..1532dba466f49da171bff1a6e910fbf8dbffd0e0 100644 (file)
@@ -263,8 +263,8 @@ def variable_ops;
 /// derived from this.  TableGen treats the register class as having a symbolic
 /// type that it doesn't know, and resolves the actual regclass to use by using
 /// the TargetRegisterInfo::getPointerRegClass() hook at codegen time.
-class PointerLikeRegClass {
-
+class PointerLikeRegClass<int Kind> {
+  int RegClassKind = Kind;
 }
 
 
@@ -272,7 +272,7 @@ class PointerLikeRegClass {
 /// register class is resolved dynamically via a callback to TargetInstrInfo.
 /// FIXME: We should probably change this to a class which contain a list of
 /// flags. But currently we have but one flag.
-def ptr_rc : PointerLikeRegClass;
+def ptr_rc : PointerLikeRegClass<0>;
 
 /// unknown definition - Mark this operand as being of unknown type, causing
 /// it to be resolved by inference in the context it is used.
index 622a216c33c63f6e775c1b20a52587667e7e980e..431e6e8b0637722414384f0d0781b39338f90f91 100644 (file)
@@ -18,7 +18,8 @@
 namespace llvm {
 
 class TargetRegisterClass;
-
+class TargetRegisterInfo;
+  
 //===----------------------------------------------------------------------===//
 // Machine Operand Flags and Description
 //===----------------------------------------------------------------------===//
@@ -45,14 +46,28 @@ namespace TOI {
 class TargetOperandInfo {
 public:
   /// RegClass - This specifies the register class enumeration of the operand 
-  /// if the operand is a register.  If not, this contains 0.
+  /// if the operand is a register.  If isLookupPtrRegClass is set, then this is
+  /// an index that is passed to TargetRegisterInfo::getPointerRegClass(x) to
+  /// get a dynamic register class.
+  ///
+  /// NOTE: This member should be considered to be private, all access should go
+  /// through "getRegClass(TRI)" below.
   unsigned short RegClass;
+  
+  /// Flags - These are flags from the TOI::OperandFlags enum.
   unsigned short Flags;
+  
   /// Lower 16 bits are used to specify which constraints are set. The higher 16
   /// bits are used to specify the value of constraints (4 bits each).
-  unsigned int Constraints;
+  unsigned Constraints;
   /// Currently no other information.
   
+  /// getRegClass - Get the register class for the operand, handling resolution
+  /// of "symbolic" pointer register classes etc.  If this is not a register
+  /// operand, this returns null.
+  const TargetRegisterClass *getRegClass(const TargetRegisterInfo *TRI) const;
+  
+  
   /// isLookupPtrRegClass - Set if this operand is a pointer value and it
   /// requires a callback to look up its register class.
   bool isLookupPtrRegClass() const { return Flags&(1 <<TOI::LookupPtrRegClass);}
index e4a26bcdc19f5f0bb4411381e002f641f5407c94..d9c37de2622c0bffc4af1aec9c153d88f939e572 100644 (file)
@@ -408,8 +408,7 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum)
           }
           sr = s;
         }
-        if (TOI.RegClass) {
-          const TargetRegisterClass *DRC = TRI->getRegClass(TOI.RegClass);
+        if (const TargetRegisterClass *DRC = TOI.getRegClass(TRI)) {
           if (!DRC->contains(sr)) {
             report("Illegal physical register for instruction", MO, MONum);
             *OS << TRI->getName(sr) << " is not a "
@@ -426,8 +425,7 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum)
           }
           RC = *(RC->subregclasses_begin()+SubIdx);
         }
-        if (TOI.RegClass) {
-          const TargetRegisterClass *DRC = TRI->getRegClass(TOI.RegClass);
+        if (const TargetRegisterClass *DRC = TOI.getRegClass(TRI)) {
           if (RC != DRC && !RC->hasSuperClass(DRC)) {
             report("Illegal virtual register for instruction", MO, MONum);
             *OS << "Expected a " << DRC->getName() << " register, but got a "
index ceaea0c2027ce20b6605eb68a9689292752dd6d2..afbadbfc63eb81feb59d9470bb61f32d456e0c0d 100644 (file)
@@ -37,14 +37,23 @@ bool TargetInstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const {
   return !isPredicated(MI);
 }
 
+/// getRegClass - Get the register class for the operand, handling resolution
+/// of "symbolic" pointer register classes etc.  If this is not a register
+/// operand, this returns null.
+const TargetRegisterClass *
+TargetOperandInfo::getRegClass(const TargetRegisterInfo *TRI) const {
+  if (isLookupPtrRegClass())
+    return TRI->getPointerRegClass(RegClass);
+  return TRI->getRegClass(RegClass);
+}
+
 /// getInstrOperandRegClass - Return register class of the operand of an
 /// instruction of the specified TargetInstrDesc.
 const TargetRegisterClass*
 llvm::getInstrOperandRegClass(const TargetRegisterInfo *TRI,
-                        const TargetInstrDesc &II, unsigned Op) {
+                              const TargetInstrDesc &II, unsigned Op) {
+  // FIXME: Should be an assert!
   if (Op >= II.getNumOperands())
     return NULL;
-  if (II.OpInfo[Op].isLookupPtrRegClass())
-    return TRI->getPointerRegClass();
-  return TRI->getRegClass(II.OpInfo[Op].RegClass);
+  return II.OpInfo[Op].getRegClass(TRI);
 }
index e3da39a4d07952139ecec404b2a78304dcb03e8c..4b293050864b64468fba36c4449367ef244c0f80 100644 (file)
@@ -2381,8 +2381,7 @@ bool X86InstrInfo::unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI,
 
   const TargetInstrDesc &TID = get(Opc);
   const TargetOperandInfo &TOI = TID.OpInfo[Index];
-  const TargetRegisterClass *RC = TOI.isLookupPtrRegClass()
-    ? RI.getPointerRegClass() : RI.getRegClass(TOI.RegClass);
+  const TargetRegisterClass *RC = TOI.getRegClass(&RI);
   SmallVector<MachineOperand, X86AddrNumOperands> AddrOps;
   SmallVector<MachineOperand,2> BeforeOps;
   SmallVector<MachineOperand,2> AfterOps;
@@ -2460,9 +2459,7 @@ bool X86InstrInfo::unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI,
 
   // Emit the store instruction.
   if (UnfoldStore) {
-    const TargetOperandInfo &DstTOI = TID.OpInfo[0];
-    const TargetRegisterClass *DstRC = DstTOI.isLookupPtrRegClass()
-      ? RI.getPointerRegClass() : RI.getRegClass(DstTOI.RegClass);
+    const TargetRegisterClass *DstRC = TID.OpInfo[0].getRegClass(&RI);
     storeRegToAddr(MF, Reg, true, AddrOps, DstRC, NewMIs);
   }
 
@@ -2484,9 +2481,7 @@ X86InstrInfo::unfoldMemoryOperand(SelectionDAG &DAG, SDNode *N,
   bool FoldedLoad = I->second.second & (1 << 4);
   bool FoldedStore = I->second.second & (1 << 5);
   const TargetInstrDesc &TID = get(Opc);
-  const TargetOperandInfo &TOI = TID.OpInfo[Index];
-  const TargetRegisterClass *RC = TOI.isLookupPtrRegClass()
-    ? RI.getPointerRegClass() : RI.getRegClass(TOI.RegClass);
+  const TargetRegisterClass *RC = TID.OpInfo[Index].getRegClass(&RI);
   unsigned NumDefs = TID.NumDefs;
   std::vector<SDValue> AddrOps;
   std::vector<SDValue> BeforeOps;
@@ -2521,9 +2516,7 @@ X86InstrInfo::unfoldMemoryOperand(SelectionDAG &DAG, SDNode *N,
   std::vector<MVT> VTs;
   const TargetRegisterClass *DstRC = 0;
   if (TID.getNumDefs() > 0) {
-    const TargetOperandInfo &DstTOI = TID.OpInfo[0];
-    DstRC = DstTOI.isLookupPtrRegClass()
-      ? RI.getPointerRegClass() : RI.getRegClass(DstTOI.RegClass);
+    DstRC = TID.OpInfo[0].getRegClass(&RI);
     VTs.push_back(*DstRC->vt_begin());
   }
   for (unsigned i = 0, e = N->getNumValues(); i != e; ++i) {
index c0e441cc48b467358bcf0c7abfc439965a8eb56d..ef52c07692a2843188e8b0017824e36823139670 100644 (file)
@@ -94,8 +94,11 @@ InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) {
       
       if (OpR->isSubClassOf("RegisterClass"))
         Res += getQualifiedName(OpR) + "RegClassID, ";
+      else if (OpR->isSubClassOf("PointerLikeRegClass"))
+        Res += utostr(OpR->getValueAsInt("RegClassKind")) + ", ";
       else
         Res += "0, ";
+      
       // Fill in applicable flags.
       Res += "0";