[llvm-commits] [llvm] r61834 - in /llvm/trunk: include/llvm/DerivedTypes.h include/llvm/Intrinsics.td lib/VMCore/Verifier.cpp utils/TableGen/CodeGenTarget.cpp utils/TableGen/IntrinsicEmitter.cpp

Bob Wilson bob.wilson at apple.com
Tue Jan 6 16:09:01 PST 2009


Author: bwilson
Date: Tue Jan  6 18:09:01 2009
New Revision: 61834

URL: http://llvm.org/viewvc/llvm-project?rev=61834&view=rev
Log:
Improve support for type-generic vector intrinsics by teaching TableGen how
to handle LLVMMatchType intrinsic parameters, and by adding new subclasses
of LLVMMatchType to match vector types with integral elements that are 
either twice as wide or half as wide as the elements of the matched type.

Modified:
    llvm/trunk/include/llvm/DerivedTypes.h
    llvm/trunk/include/llvm/Intrinsics.td
    llvm/trunk/lib/VMCore/Verifier.cpp
    llvm/trunk/utils/TableGen/CodeGenTarget.cpp
    llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp

Modified: llvm/trunk/include/llvm/DerivedTypes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DerivedTypes.h?rev=61834&r1=61833&r2=61834&view=diff

==============================================================================
--- llvm/trunk/include/llvm/DerivedTypes.h (original)
+++ llvm/trunk/include/llvm/DerivedTypes.h Tue Jan  6 18:09:01 2009
@@ -369,6 +369,26 @@
     return VectorType::get(EltTy, VTy->getNumElements());
   }
 
+  /// VectorType::getExtendedElementVectorType - This static method is like
+  /// getInteger except that the element types are twice as wide as the
+  /// elements in the input type.
+  ///
+  static VectorType *getExtendedElementVectorType(const VectorType *VTy) {
+    unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
+    const Type *EltTy = IntegerType::get(EltBits * 2);
+    return VectorType::get(EltTy, VTy->getNumElements());
+  }
+
+  /// VectorType::getTruncatedElementVectorType - This static method is like
+  /// getInteger except that the element types are half as wide as the
+  /// elements in the input type.
+  ///
+  static VectorType *getTruncatedElementVectorType(const VectorType *VTy) {
+    unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
+    const Type *EltTy = IntegerType::get(EltBits / 2);
+    return VectorType::get(EltTy, VTy->getNumElements());
+  }
+
   /// @brief Return the number of elements in the Vector type.
   inline unsigned getNumElements() const { return NumElements; }
 

Modified: llvm/trunk/include/llvm/Intrinsics.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Intrinsics.td?rev=61834&r1=61833&r2=61834&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Intrinsics.td (original)
+++ llvm/trunk/include/llvm/Intrinsics.td Tue Jan  6 18:09:01 2009
@@ -74,6 +74,13 @@
   int Number = num;
 }
 
+// Match the type of another intrinsic parameter that is expected to be 
+// an integral vector type, but change the element size to be twice as wide
+// or half as wide as the other type.  This is only useful when the intrinsic
+// is overloaded, so the matched type should be declared as iAny.
+class LLVMExtendedElementVectorType<int num> : LLVMMatchType<num>;
+class LLVMTruncatedElementVectorType<int num> : LLVMMatchType<num>;
+
 def llvm_void_ty       : LLVMType<isVoid>;
 def llvm_anyint_ty     : LLVMType<iAny>;
 def llvm_anyfloat_ty   : LLVMType<fAny>;

Modified: llvm/trunk/lib/VMCore/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=61834&r1=61833&r2=61834&view=diff

==============================================================================
--- llvm/trunk/lib/VMCore/Verifier.cpp (original)
+++ llvm/trunk/lib/VMCore/Verifier.cpp Tue Jan  6 18:09:01 2009
@@ -1313,6 +1313,11 @@
   InstsInThisBlock.insert(&I);
 }
 
+// Flags used by TableGen to mark intrinsic parameters with the
+// LLVMExtendedElementVectorType and LLVMTruncatedElementVectorType classes.
+static const unsigned ExtendedElementVectorType = 0x40000000;
+static const unsigned TruncatedElementVectorType = 0x20000000;
+
 /// visitIntrinsicFunction - Allow intrinsics to be verified in different ways.
 ///
 void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
@@ -1376,13 +1381,34 @@
 
   unsigned NumElts = 0;
   const Type *EltTy = Ty;
-  if (const VectorType *VTy = dyn_cast<VectorType>(Ty)) {
+  const VectorType *VTy = dyn_cast<VectorType>(Ty);
+  if (VTy) {
     EltTy = VTy->getElementType();
     NumElts = VTy->getNumElements();
   }
 
   if (VT < 0) {
     int Match = ~VT;
+
+    // Check flags that indicate a type that is an integral vector type with
+    // elements that are larger or smaller than the elements of the matched
+    // type.
+    if ((Match & (ExtendedElementVectorType |
+                  TruncatedElementVectorType)) != 0) {
+      if (!VTy) {
+        CheckFailed("Intrinsic parameter #" + utostr(ArgNo - 1) + " is not "
+                    "a vector type.", F);
+        return false;
+      }
+      // Adjust the current Ty (in the opposite direction) rather than
+      // the type being matched against.
+      if ((Match & ExtendedElementVectorType) != 0)
+        Ty = VectorType::getTruncatedElementVectorType(VTy);
+      else
+        Ty = VectorType::getExtendedElementVectorType(VTy);
+      Match &= ~(ExtendedElementVectorType | TruncatedElementVectorType);
+    }
+
     const Type *RetTy = FTy->getReturnType();
     const StructType *ST = dyn_cast<StructType>(RetTy);
     unsigned NumRets = 1;

Modified: llvm/trunk/utils/TableGen/CodeGenTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenTarget.cpp?rev=61834&r1=61833&r2=61834&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenTarget.cpp (original)
+++ llvm/trunk/utils/TableGen/CodeGenTarget.cpp Tue Jan  6 18:09:01 2009
@@ -483,7 +483,17 @@
   for (unsigned i = 0, e = TypeList->getSize(); i != e; ++i) {
     Record *TyEl = TypeList->getElementAsRecord(i);
     assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
-    MVT::SimpleValueType VT = getValueType(TyEl->getValueAsDef("VT"));
+    MVT::SimpleValueType VT;
+    if (TyEl->isSubClassOf("LLVMMatchType")) {
+      VT = IS.RetVTs[TyEl->getValueAsInt("Number")];
+      // It only makes sense to use the extended and truncated vector element
+      // variants with iAny types; otherwise, if the intrinsic is not
+      // overloaded, all the types can be specified directly.
+      assert(((!TyEl->isSubClassOf("LLVMExtendedElementVectorType") &&
+               !TyEl->isSubClassOf("LLVMTruncatedElementVectorType")) ||
+              VT == MVT::iAny) && "Expected iAny type");
+    } else
+      VT = getValueType(TyEl->getValueAsDef("VT"));
     isOverloaded |= VT == MVT::iAny || VT == MVT::fAny || VT == MVT::iPTRAny;
     IS.RetVTs.push_back(VT);
     IS.RetTypeDefs.push_back(TyEl);
@@ -497,7 +507,21 @@
   for (unsigned i = 0, e = TypeList->getSize(); i != e; ++i) {
     Record *TyEl = TypeList->getElementAsRecord(i);
     assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
-    MVT::SimpleValueType VT = getValueType(TyEl->getValueAsDef("VT"));
+    MVT::SimpleValueType VT;
+    if (TyEl->isSubClassOf("LLVMMatchType")) {
+      unsigned MatchTy = TyEl->getValueAsInt("Number");
+      if (MatchTy < IS.RetVTs.size())
+        VT = IS.RetVTs[MatchTy];
+      else
+        VT = IS.ParamVTs[MatchTy - IS.RetVTs.size()];
+      // It only makes sense to use the extended and truncated vector element
+      // variants with iAny types; otherwise, if the intrinsic is not
+      // overloaded, all the types can be specified directly.
+      assert(((!TyEl->isSubClassOf("LLVMExtendedElementVectorType") &&
+               !TyEl->isSubClassOf("LLVMTruncatedElementVectorType")) ||
+              VT == MVT::iAny) && "Expected iAny type");
+    } else
+      VT = getValueType(TyEl->getValueAsDef("VT"));
     isOverloaded |= VT == MVT::iAny || VT == MVT::fAny || VT == MVT::iPTRAny;
     IS.ParamVTs.push_back(VT);
     IS.ParamTypeDefs.push_back(TyEl);

Modified: llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp?rev=61834&r1=61833&r2=61834&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp Tue Jan  6 18:09:01 2009
@@ -167,7 +167,14 @@
   if (ArgType->isSubClassOf("LLVMMatchType")) {
     unsigned Number = ArgType->getValueAsInt("Number");
     assert(Number < ArgNo && "Invalid matching number!");
-    OS << "Tys[" << Number << "]";
+    if (ArgType->isSubClassOf("LLVMExtendedElementVectorType"))
+      OS << "VectorType::getExtendedElementVectorType"
+         << "(dyn_cast<VectorType>(Tys[" << Number << "]))";
+    else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType"))
+      OS << "VectorType::getTruncatedElementVectorType"
+         << "(dyn_cast<VectorType>(Tys[" << Number << "]))";
+    else
+      OS << "Tys[" << Number << "]";
   } else if (VT == MVT::iAny || VT == MVT::fAny) {
     // NOTE: The ArgNo variable here is not the absolute argument number, it is
     // the index of the "arbitrary" type in the Tys array passed to the
@@ -281,7 +288,12 @@
       if (ArgType->isSubClassOf("LLVMMatchType")) {
         unsigned Number = ArgType->getValueAsInt("Number");
         assert(Number < j && "Invalid matching number!");
-        OS << "~" << Number;
+        if (ArgType->isSubClassOf("LLVMExtendedElementVectorType"))
+          OS << "~(ExtendedElementVectorType | " << Number << ")";
+        else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType"))
+          OS << "~(TruncatedElementVectorType | " << Number << ")";
+        else
+          OS << "~" << Number;
       } else {
         MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT"));
         OS << getEnumName(VT);
@@ -299,7 +311,12 @@
       if (ArgType->isSubClassOf("LLVMMatchType")) {
         unsigned Number = ArgType->getValueAsInt("Number");
         assert(Number < j + RetTys.size() && "Invalid matching number!");
-        OS << "~" << Number;
+        if (ArgType->isSubClassOf("LLVMExtendedElementVectorType"))
+          OS << "~(ExtendedElementVectorType | " << Number << ")";
+        else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType"))
+          OS << "~(TruncatedElementVectorType | " << Number << ")";
+        else
+          OS << "~" << Number;
       } else {
         MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT"));
         OS << getEnumName(VT);





More information about the llvm-commits mailing list