Răsfoiți Sursa

[spirv] Update internals of SpirvContext.

* Use DenseSet instead of Vector
* Hybrid types do not need to be unique.
Ehsan 6 ani în urmă
părinte
comite
bacabde9b2

+ 70 - 18
tools/clang/include/clang/SPIRV/SPIRVContext.h

@@ -56,6 +56,71 @@ struct QualTypeDenseMapInfo {
   }
 };
 
+// Provides DenseMapInfo for ArrayType so we can create a DenseSet of array
+// types.
+struct ArrayTypeMapInfo {
+  static inline ArrayType *getEmptyKey() { return nullptr; }
+  static inline ArrayType *getTombstoneKey() { return nullptr; }
+  static unsigned getHashValue(const ArrayType *Val) {
+    return llvm::hash_combine(Val->getElementType(), Val->getElementCount(),
+                              Val->getStride().hasValue());
+  }
+  static bool isEqual(const ArrayType *LHS, const ArrayType *RHS) {
+    // Either both are null, or both should have the same underlying type.
+    return (LHS == RHS) || (LHS && RHS && *LHS == *RHS);
+  }
+};
+
+// Provides DenseMapInfo for RuntimeArrayType so we can create a DenseSet of
+// runtime array types.
+struct RuntimeArrayTypeMapInfo {
+  static inline RuntimeArrayType *getEmptyKey() { return nullptr; }
+  static inline RuntimeArrayType *getTombstoneKey() { return nullptr; }
+  static unsigned getHashValue(const RuntimeArrayType *Val) {
+    return llvm::hash_combine(Val->getElementType(),
+                              Val->getStride().hasValue());
+  }
+  static bool isEqual(const RuntimeArrayType *LHS,
+                      const RuntimeArrayType *RHS) {
+    // Either both are null, or both should have the same underlying type.
+    return (LHS == RHS) || (LHS && RHS && *LHS == *RHS);
+  }
+};
+
+// Provides DenseMapInfo for ImageType so we can create a DenseSet of
+// image types.
+struct ImageTypeMapInfo {
+  static inline ImageType *getEmptyKey() { return nullptr; }
+  static inline ImageType *getTombstoneKey() { return nullptr; }
+  static unsigned getHashValue(const ImageType *Val) {
+    return llvm::hash_combine(Val->getSampledType(), Val->isArrayedImage(),
+                              Val->isMSImage(),
+                              static_cast<uint32_t>(Val->getDimension()),
+                              static_cast<uint32_t>(Val->withSampler()),
+                              static_cast<uint32_t>(Val->getImageFormat()));
+  }
+  static bool isEqual(const ImageType *LHS, const ImageType *RHS) {
+    // Either both are null, or both should have the same underlying type.
+    return (LHS == RHS) || (LHS && RHS && *LHS == *RHS);
+  }
+};
+
+// Provides DenseMapInfo for FunctionType so we can create a DenseSet of
+// function types.
+struct FunctionTypeMapInfo {
+  static inline FunctionType *getEmptyKey() { return nullptr; }
+  static inline FunctionType *getTombstoneKey() { return nullptr; }
+  static unsigned getHashValue(const FunctionType *Val) {
+    // Hashing based on return type and number of function parameters.
+    return llvm::hash_combine(Val->getReturnType(),
+                              Val->getParamTypes().size());
+  }
+  static bool isEqual(const FunctionType *LHS, const FunctionType *RHS) {
+    // Either both are null, or both should have the same underlying type.
+    return (LHS == RHS) || (LHS && RHS && *LHS == *RHS);
+  }
+};
+
 /// The class owning various SPIR-V entities allocated in memory during CodeGen.
 ///
 /// All entities should be allocated from an object of this class using
@@ -164,34 +229,21 @@ private:
   using SCToPtrTyMap =
       llvm::DenseMap<spv::StorageClass, const SpirvPointerType *,
                      StorageClassDenseMapInfo>;
-  using SCToHybridPtrTyMap =
-      llvm::DenseMap<spv::StorageClass, const HybridPointerType *,
-                     StorageClassDenseMapInfo>;
 
   // Vector/matrix types for each possible element count.
   // Type at index is for vector of index components. Index 0/1 is unused.
 
   llvm::DenseMap<const ScalarType *, VectorTypeArray> vecTypes;
   llvm::DenseMap<const VectorType *, MatrixTypeVector> matTypes;
-
-  llvm::SmallVector<const ImageType *, 8> imageTypes;
+  llvm::DenseSet<const ImageType *, ImageTypeMapInfo> imageTypes;
   const SamplerType *samplerType;
   llvm::DenseMap<const ImageType *, const SampledImageType *> sampledImageTypes;
-  llvm::DenseMap<QualType, const HybridSampledImageType *, QualTypeDenseMapInfo>
-      hybridSampledImageTypes;
-
-  llvm::SmallVector<const ArrayType *, 8> arrayTypes;
-  llvm::SmallVector<const RuntimeArrayType *, 8> runtimeArrayTypes;
-
+  llvm::DenseSet<const ArrayType *, ArrayTypeMapInfo> arrayTypes;
+  llvm::DenseSet<const RuntimeArrayType *, RuntimeArrayTypeMapInfo>
+      runtimeArrayTypes;
   llvm::SmallVector<const StructType *, 8> structTypes;
-  llvm::SmallVector<const HybridStructType *, 8> hybridStructTypes;
-
   llvm::DenseMap<const SpirvType *, SCToPtrTyMap> pointerTypes;
-  llvm::DenseMap<QualType, SCToHybridPtrTyMap, QualTypeDenseMapInfo>
-      hybridPointerTypes;
-
-  llvm::SmallVector<FunctionType *, 8> functionTypes;
-  llvm::SmallVector<HybridFunctionType *, 8> hybridFunctionTypes;
+  llvm::DenseSet<FunctionType *, FunctionTypeMapInfo> functionTypes;
 };
 
 } // end namespace spirv

+ 25 - 86
tools/clang/lib/SPIRV/SPIRVContext.cpp

@@ -120,20 +120,16 @@ const ImageType *SpirvContext::getImageType(const SpirvType *sampledType,
   // assertion failure.
   const NumericalType *elemType = cast<NumericalType>(sampledType);
 
-  // Create a temporary object for finding in the vector.
+  // Create a temporary object for finding in the set.
   ImageType type(elemType, dim, depth, arrayed, ms, sampled, format);
-
-  auto found = std::find_if(
-      imageTypes.begin(), imageTypes.end(),
-      [&type](const ImageType *cachedType) { return type == *cachedType; });
-
+  auto found = imageTypes.find(&type);
   if (found != imageTypes.end())
     return *found;
 
-  imageTypes.push_back(
+  auto inserted = imageTypes.insert(
       new (this) ImageType(elemType, dim, depth, arrayed, ms, sampled, format));
 
-  return imageTypes.back();
+  return *(inserted.first);
 }
 
 const SampledImageType *
@@ -148,45 +144,36 @@ SpirvContext::getSampledImageType(const ImageType *image) {
 
 const HybridSampledImageType *
 SpirvContext::getSampledImageType(QualType image) {
-  auto found = hybridSampledImageTypes.find(image);
-
-  if (found != hybridSampledImageTypes.end())
-    return found->second;
-
-  return hybridSampledImageTypes[image] =
-             new (this) HybridSampledImageType(image);
+  return new (this) HybridSampledImageType(image);
 }
 
-const ArrayType *SpirvContext::getArrayType(const SpirvType *elemType,
-                                            uint32_t elemCount,
-                                            llvm::Optional<uint32_t> arrayStride) {
+const ArrayType *
+SpirvContext::getArrayType(const SpirvType *elemType, uint32_t elemCount,
+                           llvm::Optional<uint32_t> arrayStride) {
   ArrayType type(elemType, elemCount, arrayStride);
-  auto found = std::find_if(
-      arrayTypes.begin(), arrayTypes.end(),
-      [&type](const ArrayType *cachedType) { return type == *cachedType; });
 
+  auto found = arrayTypes.find(&type);
   if (found != arrayTypes.end())
     return *found;
 
-  arrayTypes.push_back(new (this) ArrayType(elemType, elemCount, arrayStride));
-  return arrayTypes.back();
+  auto inserted =
+      arrayTypes.insert(new (this) ArrayType(elemType, elemCount, arrayStride));
+  // The return value is an (iterator, bool) pair. The boolean indicates whether
+  // it was actually added as a new type.
+  return *(inserted.first);
 }
 
 const RuntimeArrayType *
 SpirvContext::getRuntimeArrayType(const SpirvType *elemType,
                                   llvm::Optional<uint32_t> arrayStride) {
   RuntimeArrayType type(elemType, arrayStride);
-  auto found = std::find_if(runtimeArrayTypes.begin(), runtimeArrayTypes.end(),
-                            [&type](const RuntimeArrayType *cachedType) {
-                              return type == *cachedType;
-                            });
-
+  auto found = runtimeArrayTypes.find(&type);
   if (found != runtimeArrayTypes.end())
     return *found;
 
-  runtimeArrayTypes.push_back(new (this)
-                                  RuntimeArrayType(elemType, arrayStride));
-  return runtimeArrayTypes.back();
+  auto inserted = runtimeArrayTypes.insert(
+      new (this) RuntimeArrayType(elemType, arrayStride));
+  return *(inserted.first);
 }
 
 const StructType *
@@ -216,25 +203,7 @@ SpirvContext::getStructType(llvm::ArrayRef<StructType::FieldInfo> fields,
 const HybridStructType *SpirvContext::getHybridStructType(
     llvm::ArrayRef<HybridStructType::FieldInfo> fields, llvm::StringRef name,
     bool isReadOnly, StructInterfaceType interfaceType) {
-  // We are creating a temporary struct type here for querying whether the
-  // same type was already created. It is a little bit costly, but we can
-  // avoid allocating directly from the bump pointer allocator, from which
-  // then we are unable to reclaim until the allocator itself is destroyed.
-
-  HybridStructType type(fields, name, isReadOnly, interfaceType);
-
-  auto found = std::find_if(hybridStructTypes.begin(), hybridStructTypes.end(),
-                            [&type](const HybridStructType *cachedType) {
-                              return type == *cachedType;
-                            });
-
-  if (found != hybridStructTypes.end())
-    return *found;
-
-  hybridStructTypes.push_back(
-      new (this) HybridStructType(fields, name, isReadOnly, interfaceType));
-
-  return hybridStructTypes.back();
+  return new (this) HybridStructType(fields, name, isReadOnly, interfaceType);
 }
 
 const SpirvPointerType *SpirvContext::getPointerType(const SpirvType *pointee,
@@ -254,56 +223,26 @@ const SpirvPointerType *SpirvContext::getPointerType(const SpirvType *pointee,
 
 const HybridPointerType *SpirvContext::getPointerType(QualType pointee,
                                                       spv::StorageClass sc) {
-  auto foundPointee = hybridPointerTypes.find(pointee);
-
-  if (foundPointee != hybridPointerTypes.end()) {
-    auto &pointeeMap = foundPointee->second;
-    auto foundSC = pointeeMap.find(sc);
-
-    if (foundSC != pointeeMap.end())
-      return foundSC->second;
-  }
-
-  return hybridPointerTypes[pointee][sc] =
-             new (this) HybridPointerType(pointee, sc);
+  return new (this) HybridPointerType(pointee, sc);
 }
 
 FunctionType *
 SpirvContext::getFunctionType(const SpirvType *ret,
                               llvm::ArrayRef<const SpirvType *> param) {
-  // Create a temporary object for finding in the vector.
+  // Create a temporary object for finding in the set.
   FunctionType type(ret, param);
-
-  auto found = std::find_if(
-      functionTypes.begin(), functionTypes.end(),
-      [&type](const FunctionType *cachedType) { return type == *cachedType; });
-
+  auto found = functionTypes.find(&type);
   if (found != functionTypes.end())
     return *found;
 
-  functionTypes.push_back(new (this) FunctionType(ret, param));
-
-  return functionTypes.back();
+  auto inserted = functionTypes.insert(new (this) FunctionType(ret, param));
+  return *inserted.first;
 }
 
 HybridFunctionType *
 SpirvContext::getFunctionType(QualType ret,
                               llvm::ArrayRef<const SpirvType *> param) {
-  // Create a temporary object for finding in the vector.
-  HybridFunctionType type(ret, param);
-
-  auto found =
-      std::find_if(hybridFunctionTypes.begin(), hybridFunctionTypes.end(),
-                   [&type](const HybridFunctionType *cachedType) {
-                     return type == *cachedType;
-                   });
-
-  if (found != hybridFunctionTypes.end())
-    return *found;
-
-  hybridFunctionTypes.push_back(new (this) HybridFunctionType(ret, param));
-
-  return hybridFunctionTypes.back();
+  return new (this) HybridFunctionType(ret, param);
 }
 
 const StructType *SpirvContext::getByteAddressBufferType(bool isWritable) {

+ 0 - 261
tools/clang/unittests/SPIRV/SPIRVContextTest.cpp

@@ -316,22 +316,6 @@ TEST_F(SpirvContextTest, SampledImageTypeUnique2) {
             spvContext.getSampledImageType(img2));
 }
 
-TEST_F(SpirvContextTest, HybridSampledImageTypeUnique1) {
-  const clang::ASTContext &astContext = getAstContext();
-  SpirvContext &spvContext = getSpirvContext();
-  clang::QualType int32 = astContext.IntTy;
-
-  EXPECT_EQ(spvContext.getSampledImageType(int32),
-            spvContext.getSampledImageType(int32));
-}
-
-TEST_F(SpirvContextTest, HybridSampledImageTypeUnique2) {
-  const clang::ASTContext &astContext = getAstContext();
-  SpirvContext &spvContext = getSpirvContext();
-  EXPECT_NE(spvContext.getSampledImageType(astContext.IntTy),
-            spvContext.getSampledImageType(astContext.UnsignedIntTy));
-}
-
 TEST_F(SpirvContextTest, ArrayTypeUnique1) {
   SpirvContext &spvContext = getSpirvContext();
   const auto *int32 = spvContext.getSIntType(32);
@@ -415,31 +399,6 @@ TEST_F(SpirvContextTest, PointerTypeUnique3) {
             spvContext.getPointerType(int32, spv::StorageClass::Uniform));
 }
 
-TEST_F(SpirvContextTest, HybridPointerTypeUnique1) {
-  auto &astContext = getAstContext();
-  auto &spvContext = getSpirvContext();
-  EXPECT_EQ(
-      spvContext.getPointerType(astContext.IntTy, spv::StorageClass::Function),
-      spvContext.getPointerType(astContext.IntTy, spv::StorageClass::Function));
-}
-
-TEST_F(SpirvContextTest, HybridPointerTypeUnique2) {
-  auto &astContext = getAstContext();
-  auto &spvContext = getSpirvContext();
-  EXPECT_NE(
-      spvContext.getPointerType(astContext.IntTy, spv::StorageClass::Function),
-      spvContext.getPointerType(astContext.FloatTy,
-                                spv::StorageClass::Function));
-}
-
-TEST_F(SpirvContextTest, HybridPointerTypeUnique3) {
-  auto &astContext = getAstContext();
-  auto &spvContext = getSpirvContext();
-  EXPECT_NE(
-      spvContext.getPointerType(astContext.IntTy, spv::StorageClass::Function),
-      spvContext.getPointerType(astContext.IntTy, spv::StorageClass::Uniform));
-}
-
 TEST_F(SpirvContextTest, FunctionTypeUnique1) {
   auto &spvContext = getSpirvContext();
   const auto *int32 = spvContext.getSIntType(32);
@@ -483,57 +442,6 @@ TEST_F(SpirvContextTest, FunctionTypeUnique4) {
   EXPECT_NE(fnType1, fnType2);
 }
 
-TEST_F(SpirvContextTest, HybridFunctionTypeUnique1) {
-  auto &spvContext = getSpirvContext();
-  auto &astContext = getAstContext();
-  const auto *uint32 = spvContext.getUIntType(32);
-  const auto *float32 = spvContext.getFloatType(32);
-  auto *fnType1 =
-      spvContext.getFunctionType(astContext.IntTy, {uint32, float32});
-  auto *fnType2 =
-      spvContext.getFunctionType(astContext.IntTy, {uint32, float32});
-  EXPECT_EQ(fnType1, fnType2);
-}
-
-TEST_F(SpirvContextTest, HybridFunctionTypeUnique2) {
-  // The number of params is different.
-  auto &spvContext = getSpirvContext();
-  auto &astContext = getAstContext();
-  const auto *uint32 = spvContext.getUIntType(32);
-  const auto *float32 = spvContext.getFloatType(32);
-  auto *fnType1 =
-      spvContext.getFunctionType(astContext.IntTy, {uint32, float32});
-  auto *fnType2 = spvContext.getFunctionType(astContext.IntTy, {uint32});
-  EXPECT_NE(fnType1, fnType2);
-}
-
-TEST_F(SpirvContextTest, HybridFunctionTypeUnique3) {
-  // Return type is different.
-  auto &spvContext = getSpirvContext();
-  auto &astContext = getAstContext();
-  const auto *uint32 = spvContext.getUIntType(32);
-  const auto *float32 = spvContext.getFloatType(32);
-  auto *fnType1 =
-      spvContext.getFunctionType(astContext.IntTy, {uint32, float32});
-  auto *fnType2 =
-      spvContext.getFunctionType(astContext.UnsignedIntTy, {uint32, float32});
-  EXPECT_NE(fnType1, fnType2);
-}
-
-TEST_F(SpirvContextTest, HybridFunctionTypeUnique4) {
-  // Parameter kinds are different.
-  auto &spvContext = getSpirvContext();
-  auto &astContext = getAstContext();
-  const auto *int32 = spvContext.getSIntType(32);
-  const auto *uint32 = spvContext.getUIntType(32);
-  const auto *float32 = spvContext.getFloatType(32);
-  const auto *fnType1 =
-      spvContext.getFunctionType(astContext.IntTy, {uint32, float32});
-  const auto *fnType2 =
-      spvContext.getFunctionType(astContext.IntTy, {int32, float32});
-  EXPECT_NE(fnType1, fnType2);
-}
-
 TEST_F(SpirvContextTest, ByteAddressBufferTypeUnique1) {
   auto &spvContext = getSpirvContext();
   const auto *type1 = spvContext.getByteAddressBufferType(false);
@@ -729,173 +637,4 @@ TEST_F(SpirvContextTest, StructTypeUnique9) {
   EXPECT_NE(type1, type2);
 }
 
-TEST_F(SpirvContextTest, HybridStructTypeUnique1) {
-  auto &astContext = getAstContext();
-  auto &spvContext = getSpirvContext();
-  const auto int32 = astContext.IntTy;
-  const auto uint32 = astContext.UnsignedIntTy;
-
-  const auto *type1 = spvContext.getHybridStructType(
-      {HybridStructType::FieldInfo(int32, "field1"),
-       HybridStructType::FieldInfo(uint32, "field2")},
-      "struct1", /*isReadOnly*/ false, StructInterfaceType::InternalStorage);
-
-  const auto *type2 = spvContext.getHybridStructType(
-      {HybridStructType::FieldInfo(int32, "field1"),
-       HybridStructType::FieldInfo(uint32, "field2")},
-      "struct1", /*isReadOnly*/ false, StructInterfaceType::InternalStorage);
-
-  EXPECT_EQ(type1, type2);
-}
-
-TEST_F(SpirvContextTest, HybridStructTypeUnique2) {
-  // Struct names are different
-  auto &astContext = getAstContext();
-  auto &spvContext = getSpirvContext();
-  const auto int32 = astContext.IntTy;
-  const auto uint32 = astContext.UnsignedIntTy;
-
-  const auto *type1 = spvContext.getHybridStructType(
-      {HybridStructType::FieldInfo(int32, "field1"),
-       HybridStructType::FieldInfo(uint32, "field2")},
-      "struct1", /*isReadOnly*/ false, StructInterfaceType::InternalStorage);
-
-  const auto *type2 = spvContext.getHybridStructType(
-      {HybridStructType::FieldInfo(int32, "field1"),
-       HybridStructType::FieldInfo(uint32, "field2")},
-      "struct2", /*isReadOnly*/ false, StructInterfaceType::InternalStorage);
-
-  EXPECT_NE(type1, type2);
-}
-
-TEST_F(SpirvContextTest, HybridStructTypeUnique3) {
-  // Read-only-ness is different
-  auto &astContext = getAstContext();
-  auto &spvContext = getSpirvContext();
-  const auto int32 = astContext.IntTy;
-  const auto uint32 = astContext.UnsignedIntTy;
-
-  const auto *type1 = spvContext.getHybridStructType(
-      {HybridStructType::FieldInfo(int32, "field1"),
-       HybridStructType::FieldInfo(uint32, "field2")},
-      "struct1", /*isReadOnly*/ false, StructInterfaceType::InternalStorage);
-
-  const auto *type2 = spvContext.getHybridStructType(
-      {HybridStructType::FieldInfo(int32, "field1"),
-       HybridStructType::FieldInfo(uint32, "field2")},
-      "struct1", /*isReadOnly*/ true, StructInterfaceType::InternalStorage);
-
-  EXPECT_NE(type1, type2);
-}
-
-TEST_F(SpirvContextTest, HybridStructTypeUnique4) {
-  // Interface type is different
-  auto &astContext = getAstContext();
-  auto &spvContext = getSpirvContext();
-  const auto int32 = astContext.IntTy;
-  const auto uint32 = astContext.UnsignedIntTy;
-
-  const auto *type1 = spvContext.getHybridStructType(
-      {HybridStructType::FieldInfo(int32, "field1"),
-       HybridStructType::FieldInfo(uint32, "field2")},
-      "struct1", /*isReadOnly*/ false, StructInterfaceType::InternalStorage);
-
-  const auto *type2 = spvContext.getHybridStructType(
-      {HybridStructType::FieldInfo(int32, "field1"),
-       HybridStructType::FieldInfo(uint32, "field2")},
-      "struct1", /*isReadOnly*/ false, StructInterfaceType::StorageBuffer);
-
-  EXPECT_NE(type1, type2);
-}
-
-TEST_F(SpirvContextTest, HybridStructTypeUnique5) {
-  // Fields have different types
-  auto &astContext = getAstContext();
-  auto &spvContext = getSpirvContext();
-  const auto int32 = astContext.IntTy;
-  const auto uint32 = astContext.UnsignedIntTy;
-
-  const auto *type1 = spvContext.getHybridStructType(
-      {HybridStructType::FieldInfo(int32, "field"),
-       HybridStructType::FieldInfo(uint32, "field")},
-      "struct1", /*isReadOnly*/ false, StructInterfaceType::InternalStorage);
-
-  const auto *type2 = spvContext.getHybridStructType(
-      {HybridStructType::FieldInfo(uint32, "field"),
-       HybridStructType::FieldInfo(int32, "field")},
-      "struct1", /*isReadOnly*/ false, StructInterfaceType::StorageBuffer);
-
-  EXPECT_NE(type1, type2);
-}
-
-TEST_F(SpirvContextTest, HybridStructTypeUnique6) {
-  // Fields have different names
-  auto &astContext = getAstContext();
-  auto &spvContext = getSpirvContext();
-  const auto int32 = astContext.IntTy;
-  const auto uint32 = astContext.UnsignedIntTy;
-
-  const auto *type1 = spvContext.getHybridStructType(
-      {HybridStructType::FieldInfo(int32, "sine"),
-       HybridStructType::FieldInfo(uint32, "field2")},
-      "struct1", /*isReadOnly*/ false, StructInterfaceType::InternalStorage);
-
-  const auto *type2 = spvContext.getHybridStructType(
-      {HybridStructType::FieldInfo(int32, "cosine"),
-       HybridStructType::FieldInfo(uint32, "field2")},
-      "struct1", /*isReadOnly*/ false, StructInterfaceType::StorageBuffer);
-
-  EXPECT_NE(type1, type2);
-}
-
-TEST_F(SpirvContextTest, HybridStructTypeUnique7) {
-  // Fields have different vk::offset.
-  auto &astContext = getAstContext();
-  auto &spvContext = getSpirvContext();
-  const auto int32 = astContext.IntTy;
-  const auto uint32 = astContext.UnsignedIntTy;
-  auto *vkOffsetAttr1 = clang::VKOffsetAttr::CreateImplicit(astContext, 4, {});
-  auto *vkOffsetAttr2 = clang::VKOffsetAttr::CreateImplicit(astContext, 8, {});
-
-  const auto *type1 = spvContext.getHybridStructType(
-      {HybridStructType::FieldInfo(int32, "field1", vkOffsetAttr1),
-       HybridStructType::FieldInfo(uint32, "field2")},
-      "struct1", /*isReadOnly*/ false, StructInterfaceType::InternalStorage);
-
-  const auto *type2 = spvContext.getHybridStructType(
-      {HybridStructType::FieldInfo(int32, "field1", vkOffsetAttr2),
-       HybridStructType::FieldInfo(uint32, "field2")},
-      "struct1", /*isReadOnly*/ false, StructInterfaceType::StorageBuffer);
-
-  EXPECT_NE(type1, type2);
-}
-
-TEST_F(SpirvContextTest, HybridStructTypeUnique8) {
-  // Fields have different :packoffset.
-  auto &astContext = getAstContext();
-  auto &spvContext = getSpirvContext();
-  const auto int32 = astContext.IntTy;
-  const auto uint32 = astContext.UnsignedIntTy;
-  auto *vkOffsetAttr = clang::VKOffsetAttr::CreateImplicit(astContext, 4, {});
-
-  hlsl::ConstantPacking packing1;
-  packing1.ComponentOffset = 0;
-  packing1.Subcomponent = 1;
-  hlsl::ConstantPacking packing2;
-  packing2.ComponentOffset = 1;
-  packing2.Subcomponent = 2;
-
-  const auto *type1 = spvContext.getHybridStructType(
-      {HybridStructType::FieldInfo(int32, "field1", vkOffsetAttr),
-       HybridStructType::FieldInfo(uint32, "field2", nullptr, &packing1)},
-      "struct1", /*isReadOnly*/ false, StructInterfaceType::InternalStorage);
-
-  const auto *type2 = spvContext.getHybridStructType(
-      {HybridStructType::FieldInfo(int32, "field1", vkOffsetAttr),
-       HybridStructType::FieldInfo(uint32, "field2", nullptr, &packing2)},
-      "struct1", /*isReadOnly*/ false, StructInterfaceType::StorageBuffer);
-
-  EXPECT_NE(type1, type2);
-}
-
 } // anonymous namespace