[llvm-commits] [llvm] r58623 - in /llvm/trunk: include/llvm/CodeGen/ValueTypes.h lib/VMCore/ValueTypes.cpp test/CodeGen/X86/i2k.ll utils/TableGen/CMakeLists.txt utils/TableGen/TGValueTypes.cpp

Dan Gohman gohman at apple.com
Mon Nov 3 09:56:27 PST 2008


Author: djg
Date: Mon Nov  3 11:56:27 2008
New Revision: 58623

URL: http://llvm.org/viewvc/llvm-project?rev=58623&view=rev
Log:
Change how extended types are represented in MVTs. Instead of fiddling
bits, use a union of a SimpleValueType enum and a regular Type*.

This increases the size of MVT on 64-bit hosts from 32 bits to 64 bits.
In most cases, this doesn't add significant overhead. There are places
in codegen that use arrays of MVTs, so these are now larger, but
they're small in common cases.

This eliminates restrictions on the size of integer types and vector
types that can be represented in codegen. As the included testcase
demonstrates, it's now possible to codegen very large add operations.
There are still some complications with using very large types. PR2880
is still open so they can't be used as return values on normal targets,
there are no libcalls defined for very large integers so operations
like multiply and divide aren't supported.

This also introduces a minimal tablgen Type library, capable of
handling IntegerType and VectorType. This will allow parts of
TableGen that don't depend on using SimpleValueType values to handle
arbitrary integer and vector types.

Added:
    llvm/trunk/test/CodeGen/X86/i2k.ll
    llvm/trunk/utils/TableGen/TGValueTypes.cpp
Modified:
    llvm/trunk/include/llvm/CodeGen/ValueTypes.h
    llvm/trunk/lib/VMCore/ValueTypes.cpp
    llvm/trunk/utils/TableGen/CMakeLists.txt

Modified: llvm/trunk/include/llvm/CodeGen/ValueTypes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ValueTypes.h?rev=58623&r1=58622&r2=58623&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/ValueTypes.h (original)
+++ llvm/trunk/include/llvm/CodeGen/ValueTypes.h Mon Nov  3 11:56:27 2008
@@ -26,7 +26,6 @@
 
   struct MVT { // MVT = Machine Value Type
   public:
-
     enum SimpleValueType {
       // If you change this numbering, you must change the values in
       // ValueTypes.td as well!
@@ -87,10 +86,14 @@
 
       // iPTR - An int value the size of the pointer of the current
       // target.  This should only be used internal to tblgen!
-      iPTR           =  255
+      iPTR           =  255,
+
+      // LastSimpleValueType - The greatest valid SimpleValueType value.
+      LastSimpleValueType = 255
     };
 
-    /// MVT - This type holds low-level value types. Valid values include any of
+  private:
+    /// This union holds low-level value types. Valid values include any of
     /// the values in the SimpleValueType enum, or any value returned from one
     /// of the MVT methods.  Any value type equal to one of the SimpleValueType
     /// enum values is a "simple" value type.  All others are "extended".
@@ -99,48 +102,22 @@
     /// All legal value types must be simple, but often there are some simple
     /// value types that are not legal.
     ///
-    /// @internal
-    /// Extended types are either vector types or arbitrary precision integers.
-    /// Arbitrary precision integers have iAny in the first SimpleTypeBits bits,
-    /// and the bit-width in the next PrecisionBits bits, offset by minus one.
-    /// Vector types are encoded by having the first
-    /// SimpleTypeBits+PrecisionBits bits encode the vector element type
-    /// (which must be a scalar type, possibly an arbitrary precision integer)
-    /// and the remaining VectorBits upper bits encode the vector length, offset
-    /// by one.
-    ///
-    /// 32--------------16-----------8-------------0
-    ///  | Vector length | Precision | Simple type |
-    ///  |               |      Vector element     |
-    ///
-
-  private:
-
-    static const int SimpleTypeBits = 8;
-    static const int PrecisionBits  = 8;
-    static const int VectorBits     = 32 - SimpleTypeBits - PrecisionBits;
-
-    static const uint32_t SimpleTypeMask =
-      (~uint32_t(0) << (32 - SimpleTypeBits)) >> (32 - SimpleTypeBits);
-
-    static const uint32_t PrecisionMask =
-      ((~uint32_t(0) << VectorBits) >> (32 - PrecisionBits)) << SimpleTypeBits;
-
-    static const uint32_t VectorMask =
-      (~uint32_t(0) >> (32 - VectorBits)) << (32 - VectorBits);
-
-    static const uint32_t ElementMask =
-      (~uint32_t(0) << VectorBits) >> VectorBits;
-
-    uint32_t V;
+    union {
+      uintptr_t V;
+      SimpleValueType SimpleTy;
+      const Type *LLVMTy;
+    };
 
   public:
-
     MVT() {}
     MVT(SimpleValueType S) : V(S) {}
 
-    bool operator== (const MVT VT) const { return V == VT.V; }
-    bool operator!= (const MVT VT) const { return V != VT.V; }
+    bool operator==(const MVT VT) const {
+      return getRawBits() == VT.getRawBits();
+    }
+    bool operator!=(const MVT VT) const {
+      return getRawBits() != VT.getRawBits();
+    }
 
     /// getFloatingPointVT - Returns the MVT that represents a floating point
     /// type with the given number of bits.  There are two floating point types
@@ -179,10 +156,7 @@
       case 128:
         return i128;
       }
-      MVT VT;
-      VT.V = iAny | (((BitWidth - 1) << SimpleTypeBits) & PrecisionMask);
-      assert(VT.getSizeInBits() == BitWidth && "Bad bit width!");
-      return VT;
+      return getExtendedIntegerVT(BitWidth);
     }
 
     /// getVectorVT - Returns the MVT that represents a vector NumElements in
@@ -217,13 +191,7 @@
         if (NumElements == 2)  return v2f64;
         break;
       }
-      MVT Result;
-      Result.V = VT.V | ((NumElements + 1) << (32 - VectorBits));
-      assert(Result.getVectorElementType() == VT &&
-             "Bad vector element type!");
-      assert(Result.getVectorNumElements() == NumElements &&
-             "Bad vector length!");
-      return Result;
+      return getExtendedVectorVT(VT, NumElements);
     }
 
     /// getIntVectorWithNumElements - Return any integer vector type that has
@@ -240,11 +208,10 @@
       }
     }
 
-
     /// isSimple - Test if the given MVT is simple (as opposed to being
     /// extended).
     bool isSimple() const {
-      return V <= SimpleTypeMask;
+      return V <= LastSimpleValueType;
     }
 
     /// isExtended - Test if the given MVT is extended (as opposed to
@@ -255,34 +222,43 @@
 
     /// isFloatingPoint - Return true if this is a FP, or a vector FP type.
     bool isFloatingPoint() const {
-      uint32_t SVT = V & SimpleTypeMask;
-      return (SVT >= f32 && SVT <= ppcf128) || (SVT >= v2f32 && SVT <= v2f64);
+      return isSimple() ?
+             ((SimpleTy >= f32 && SimpleTy <= ppcf128) ||
+              (SimpleTy >= v2f32 && SimpleTy <= v2f64)) :
+             isExtendedFloatingPoint();
     }
 
     /// isInteger - Return true if this is an integer, or a vector integer type.
     bool isInteger() const {
-      uint32_t SVT = V & SimpleTypeMask;
-      return (SVT >= FIRST_INTEGER_VALUETYPE && SVT <= LAST_INTEGER_VALUETYPE) ||
-        (SVT >= v8i8 && SVT <= v2i64) || (SVT == iAny && (V & PrecisionMask));
+      return isSimple() ?
+             ((SimpleTy >= FIRST_INTEGER_VALUETYPE &&
+               SimpleTy <= LAST_INTEGER_VALUETYPE) ||
+              (SimpleTy >= v8i8 && SimpleTy <= v2i64)) :
+             isExtendedInteger();
     }
 
     /// isVector - Return true if this is a vector value type.
     bool isVector() const {
-      return (V >= FIRST_VECTOR_VALUETYPE && V <= LAST_VECTOR_VALUETYPE) ||
-             (V & VectorMask);
+      return isSimple() ?
+             (SimpleTy >= FIRST_VECTOR_VALUETYPE &&
+              SimpleTy <= LAST_VECTOR_VALUETYPE) :
+             isExtendedVector();
     }
 
     /// is64BitVector - Return true if this is a 64-bit vector type.
     bool is64BitVector() const {
-      return (V==v8i8 || V==v4i16 || V==v2i32 || V==v1i64 || V==v2f32 ||
-              (isExtended() && isVector() && getSizeInBits()==64));
+      return isSimple() ?
+             (SimpleTy==v8i8 || SimpleTy==v4i16 || SimpleTy==v2i32 ||
+              SimpleTy==v1i64 || SimpleTy==v2f32) :
+             isExtended64BitVector();
     }
 
     /// is128BitVector - Return true if this is a 128-bit vector type.
     bool is128BitVector() const {
-      return (V==v16i8 || V==v8i16 || V==v4i32 || V==v2i64 ||
-              V==v4f32 || V==v2f64 ||
-              (isExtended() && isVector() && getSizeInBits()==128));
+      return isSimple() ?
+             (SimpleTy==v16i8 || SimpleTy==v8i16 || SimpleTy==v4i32 ||
+              SimpleTy==v2i64 || SimpleTy==v4f32 || SimpleTy==v2f64) :
+             isExtended128BitVector();
     }
 
     /// isByteSized - Return true if the bit size is a multiple of 8.
@@ -321,7 +297,7 @@
     /// simple MVT.
     SimpleValueType getSimpleVT() const {
       assert(isSimple() && "Expected a SimpleValueType!");
-      return (SimpleValueType)V;
+      return SimpleTy;
     }
 
     /// getVectorElementType - Given a vector type, return the type of
@@ -329,12 +305,8 @@
     MVT getVectorElementType() const {
       assert(isVector() && "Invalid vector type!");
       switch (V) {
-      default: {
-        assert(isExtended() && "Unknown simple vector type!");
-        MVT VT;
-        VT.V = V & ElementMask;
-        return VT;
-      }
+      default:
+        return getExtendedVectorElementType();
       case v8i8 :
       case v16i8: return i8;
       case v4i16:
@@ -357,8 +329,7 @@
       assert(isVector() && "Invalid vector type!");
       switch (V) {
       default:
-        assert(isExtended() && "Unknown simple vector type!");
-        return ((V & VectorMask) >> (32 - VectorBits)) - 1;
+        return getExtendedVectorNumElements();
       case v16i8: return 16;
       case v8i8 :
       case v8i16: return 8;
@@ -379,13 +350,7 @@
     unsigned getSizeInBits() const {
       switch (V) {
       default:
-        assert(isExtended() && "MVT has no known size!");
-        if (isVector())
-          return getVectorElementType().getSizeInBits()*getVectorNumElements();
-        if (isInteger())
-          return ((V & PrecisionMask) >> SimpleTypeBits) + 1;
-        assert(false && "Unknown value type!");
-        return 0;
+        return getExtendedSizeInBits();
       case i1  :  return 1;
       case i8  :  return 8;
       case i16 :  return 16;
@@ -410,6 +375,12 @@
       case v2i64:
       case v4f32:
       case v2f64: return 128;
+      case iPTR:
+        assert(false && "Value type size is target-dependent. Ask TLI.");
+      case iPTRAny:
+      case iAny:
+      case fAny:
+        assert(false && "Value type is overloaded.");
       }
     }
 
@@ -461,7 +432,7 @@
     static MVT getMVT(const Type *Ty, bool HandleUnknown = false);
 
     /// getRawBits - Represent the type as a bunch of bits.
-    uint32_t getRawBits() const { return V; }
+    uintptr_t getRawBits() const { return V; }
 
     /// compareRawBits - A meaningless but well-behaved order, useful for
     /// constructing containers.
@@ -470,6 +441,21 @@
         return L.getRawBits() < R.getRawBits();
       }
     };
+
+  private:
+    // Methods for handling the Extended-type case in functions above.
+    // These are all out-of-line to prevent users of this header file
+    // from having a dependency on Type.h.
+    static MVT getExtendedIntegerVT(unsigned BitWidth);
+    static MVT getExtendedVectorVT(MVT VT, unsigned NumElements);
+    bool isExtendedFloatingPoint() const;
+    bool isExtendedInteger() const;
+    bool isExtendedVector() const;
+    bool isExtended64BitVector() const;
+    bool isExtended128BitVector() const;
+    MVT getExtendedVectorElementType() const;
+    unsigned getExtendedVectorNumElements() const;
+    unsigned getExtendedSizeInBits() const;
   };
 
 } // End llvm namespace

Modified: llvm/trunk/lib/VMCore/ValueTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/ValueTypes.cpp?rev=58623&r1=58622&r2=58623&view=diff

==============================================================================
--- llvm/trunk/lib/VMCore/ValueTypes.cpp (original)
+++ llvm/trunk/lib/VMCore/ValueTypes.cpp Mon Nov  3 11:56:27 2008
@@ -17,6 +17,60 @@
 #include "llvm/DerivedTypes.h"
 using namespace llvm;
 
+MVT MVT::getExtendedIntegerVT(unsigned BitWidth) {
+  MVT VT;
+  VT.LLVMTy = IntegerType::get(BitWidth);
+  return VT;
+}
+
+MVT MVT::getExtendedVectorVT(MVT VT, unsigned NumElements) {
+  MVT ResultVT;
+  ResultVT.LLVMTy = VectorType::get(VT.getTypeForMVT(), NumElements);
+  return ResultVT;
+}
+
+bool MVT::isExtendedFloatingPoint() const {
+  assert(isExtended() && "Type is not extended!");
+  return LLVMTy->isFPOrFPVector();
+}
+
+bool MVT::isExtendedInteger() const {
+  assert(isExtended() && "Type is not extended!");
+  return LLVMTy->isIntOrIntVector();
+}
+
+bool MVT::isExtendedVector() const {
+  assert(isExtended() && "Type is not extended!");
+  return isa<VectorType>(LLVMTy);
+}
+
+bool MVT::isExtended64BitVector() const {
+  return isExtendedVector() && getSizeInBits() == 64;
+}
+
+bool MVT::isExtended128BitVector() const {
+  return isExtendedVector() && getSizeInBits() == 128;
+}
+
+MVT MVT::getExtendedVectorElementType() const {
+  assert(isExtended() && "Type is not extended!");
+  return MVT::getMVT(cast<VectorType>(LLVMTy)->getElementType());
+}
+
+unsigned MVT::getExtendedVectorNumElements() const {
+  assert(isExtended() && "Type is not extended!");
+  return cast<VectorType>(LLVMTy)->getNumElements();
+}
+
+unsigned MVT::getExtendedSizeInBits() const {
+  assert(isExtended() && "Type is not extended!");
+  if (const IntegerType *ITy = dyn_cast<IntegerType>(LLVMTy))
+    return ITy->getBitWidth();
+  if (const VectorType *VTy = dyn_cast<VectorType>(LLVMTy))
+    return VTy->getBitWidth();
+  assert(false && "Unrecognized extended type!");
+}
+
 /// getMVTString - This function returns value type as a string, e.g. "i32".
 std::string MVT::getMVTString() const {
   switch (V) {

Added: llvm/trunk/test/CodeGen/X86/i2k.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/i2k.ll?rev=58623&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/X86/i2k.ll (added)
+++ llvm/trunk/test/CodeGen/X86/i2k.ll Mon Nov  3 11:56:27 2008
@@ -0,0 +1,9 @@
+; RUN: llvm-as < %s | llc -march=x86
+
+define void @foo(i2011* %x, i2011* %y, i2011* %p) nounwind {
+  %a = load i2011* %x
+  %b = load i2011* %y
+  %c = add i2011 %a, %b
+  store i2011 %c, i2011* %p
+  ret void
+}

Modified: llvm/trunk/utils/TableGen/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CMakeLists.txt?rev=58623&r1=58622&r2=58623&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/CMakeLists.txt (original)
+++ llvm/trunk/utils/TableGen/CMakeLists.txt Mon Nov  3 11:56:27 2008
@@ -15,6 +15,7 @@
   SubtargetEmitter.cpp
   TGLexer.cpp
   TGParser.cpp
+  TGValueTypes.cpp
   TableGen.cpp
   TableGenBackend.cpp
   FastISelEmitter.cpp

Added: llvm/trunk/utils/TableGen/TGValueTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGValueTypes.cpp?rev=58623&view=auto

==============================================================================
--- llvm/trunk/utils/TableGen/TGValueTypes.cpp (added)
+++ llvm/trunk/utils/TableGen/TGValueTypes.cpp Mon Nov  3 11:56:27 2008
@@ -0,0 +1,123 @@
+//===- ValueTypes.cpp - Tablegen extended ValueType implementation --------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The MVT type is used by tablegen as well as in LLVM. In order to handle
+// extended types, the MVT type uses support functions that call into
+// LLVM's type system code. These aren't accessible in tablegen, so this
+// file provides simple replacements.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/Support/Streams.h"
+#include <map>
+#include <vector>
+using namespace llvm;
+
+namespace llvm {
+
+class Type {
+public:
+  virtual unsigned getSizeInBits() const = 0;
+};
+
+}
+
+class ExtendedIntegerType : public Type {
+  unsigned BitWidth;
+public:
+  explicit ExtendedIntegerType(unsigned bits)
+    : BitWidth(bits) {}
+  unsigned getSizeInBits() const {
+    return getBitWidth();
+  }
+  unsigned getBitWidth() const {
+    return BitWidth;
+  }
+};
+
+class ExtendedVectorType : public Type {
+  MVT ElementType;
+  unsigned NumElements;
+public:
+  ExtendedVectorType(MVT elty, unsigned num)
+    : ElementType(elty), NumElements(num) {}
+  unsigned getSizeInBits() const {
+    return getNumElements() * getElementType().getSizeInBits();
+  }
+  MVT getElementType() const {
+    return ElementType;
+  }
+  unsigned getNumElements() const {
+    return NumElements;
+  }
+};
+
+static std::map<unsigned, const Type *>
+  ExtendedIntegerTypeMap;
+static std::map<std::pair<uintptr_t, uintptr_t>, const Type *>
+  ExtendedVectorTypeMap;
+
+MVT MVT::getExtendedIntegerVT(unsigned BitWidth) {
+  const Type *&ET = ExtendedIntegerTypeMap[BitWidth];
+  if (!ET) ET = new ExtendedIntegerType(BitWidth);
+  MVT VT;
+  VT.LLVMTy = ET;
+  return VT;
+}
+
+MVT MVT::getExtendedVectorVT(MVT VT, unsigned NumElements) {
+  const Type *&ET = ExtendedVectorTypeMap[std::make_pair(VT.getRawBits(),
+                                                         NumElements)];
+  if (!ET) ET = new ExtendedVectorType(VT, NumElements);
+  MVT ResultVT;
+  ResultVT.LLVMTy = ET;
+  return ResultVT;
+}
+
+bool MVT::isExtendedFloatingPoint() const {
+  assert(isExtended() && "Type is not extended!");
+  // Extended floating-point types are not supported yet.
+  return false;
+}
+
+bool MVT::isExtendedInteger() const {
+  assert(isExtended() && "Type is not extended!");
+  return dynamic_cast<const ExtendedIntegerType *>(LLVMTy) != 0;
+}
+
+bool MVT::isExtendedVector() const {
+  assert(isExtended() && "Type is not extended!");
+  return dynamic_cast<const ExtendedVectorType *>(LLVMTy) != 0;
+}
+
+bool MVT::isExtended64BitVector() const {
+  assert(isExtended() && "Type is not extended!");
+  return isExtendedVector() && getSizeInBits() == 64;
+}
+
+bool MVT::isExtended128BitVector() const {
+  assert(isExtended() && "Type is not extended!");
+  return isExtendedVector() && getSizeInBits() == 128;
+}
+
+MVT MVT::getExtendedVectorElementType() const {
+  assert(isExtendedVector() && "Type is not an extended vector!");
+  return static_cast<const ExtendedVectorType *>(LLVMTy)->getElementType();
+}
+
+unsigned MVT::getExtendedVectorNumElements() const {
+  assert(isExtendedVector() && "Type is not an extended vector!");
+  return static_cast<const ExtendedVectorType *>(LLVMTy)->getNumElements();
+}
+
+unsigned MVT::getExtendedSizeInBits() const {
+  assert(isExtended() && "Type is not extended!");
+  return LLVMTy->getSizeInBits();
+}





More information about the llvm-commits mailing list