[IR] Move support for dxil::TypedPointerType to LLVM core IR.

This allows the construct to be shared between different backends. However, it
still remains illegal to use TypedPointerType in LLVM IR--the type is intended
to remain an auxiliary type, not a real LLVM type. So no support is provided for
LLVM-C, nor bitcode, nor LLVM assembly (besides the bare minimum needed to make
Type->dump() work properly).

Reviewed By: beanz, nikic, aeubanks

Differential Revision: https://reviews.llvm.org/D130592

GitOrigin-RevId: 2138c906458ed37f0f833b1c7dda1bc6c6be8236
diff --git a/include/llvm/IR/LLVMContext.h b/include/llvm/IR/LLVMContext.h
index 91712df..792e59a 100644
--- a/include/llvm/IR/LLVMContext.h
+++ b/include/llvm/IR/LLVMContext.h
@@ -24,7 +24,6 @@
 
 namespace llvm {
 
-class Any;
 class DiagnosticInfo;
 enum DiagnosticSeverity : char;
 class Function;
@@ -323,10 +322,6 @@
   /// Whether typed pointers are supported. If false, all pointers are opaque.
   bool supportsTypedPointers() const;
 
-  /// Optionally target-spcific data can be attached to the context for lifetime
-  /// management and bypassing layering restrictions.
-  llvm::Any &getTargetData() const;
-
 private:
   // Module needs access to the add/removeModule methods.
   friend class Module;
diff --git a/include/llvm/IR/Type.h b/include/llvm/IR/Type.h
index 51263c6..52fce34 100644
--- a/include/llvm/IR/Type.h
+++ b/include/llvm/IR/Type.h
@@ -75,7 +75,7 @@
     ArrayTyID,          ///< Arrays
     FixedVectorTyID,    ///< Fixed width SIMD vector type
     ScalableVectorTyID, ///< Scalable SIMD vector type
-    DXILPointerTyID,    ///< DXIL typed pointer used by DirectX target
+    TypedPointerTyID,   ///< Typed pointer used by some GPU targets
   };
 
 private:
diff --git a/lib/Target/DirectX/DXILPointerType.h b/include/llvm/IR/TypedPointerType.h
similarity index 66%
rename from lib/Target/DirectX/DXILPointerType.h
rename to include/llvm/IR/TypedPointerType.h
index 52cf2db..1bea715 100644
--- a/lib/Target/DirectX/DXILPointerType.h
+++ b/include/llvm/IR/TypedPointerType.h
@@ -1,4 +1,4 @@
-//===- Target/DirectX/DXILPointerType.h - DXIL Typed Pointer Type ---------===//
+//===- llvm/IR/TypedPointerType.h - Typed Pointer Type --------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -6,19 +6,22 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// This file contains typed pointer type information. It is separated out into
+// a separate file to make it less likely to accidentally use this type.
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_TARGET_DIRECTX_DXILPOINTERTYPE_H
-#define LLVM_TARGET_DIRECTX_DXILPOINTERTYPE_H
+#ifndef LLVM_IR_TYPEDPOINTERTYPE_H
+#define LLVM_IR_TYPEDPOINTERTYPE_H
 
 #include "llvm/IR/Type.h"
 
 namespace llvm {
-namespace dxil {
 
-// DXIL has typed pointers, this pointer type abstraction is used for tracking
-// in PointerTypeAnalysis and for the bitcode ValueEnumerator
+/// A few GPU targets, such as DXIL and SPIR-V, have typed pointers. This
+/// pointer type abstraction is used for tracking the types of these pointers.
+/// It is not legal to use this type, or derived types containing this type, in
+/// LLVM IR.
 class TypedPointerType : public Type {
   explicit TypedPointerType(Type *ElType, unsigned AddrSpace);
 
@@ -42,11 +45,10 @@
 
   /// Implement support type inquiry through isa, cast, and dyn_cast.
   static bool classof(const Type *T) {
-    return T->getTypeID() == DXILPointerTyID;
+    return T->getTypeID() == TypedPointerTyID;
   }
 };
 
-} // namespace dxil
 } // namespace llvm
 
-#endif // LLVM_TARGET_DIRECTX_DXILPOINTERTYPE_H
+#endif // LLVM_IR_TYPEDPOINTERTYPE_H
diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp
index d7e012f..eda4ac7 100644
--- a/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -1029,8 +1029,8 @@
         TypeVals.push_back(true);
       break;
     }
-    case Type::DXILPointerTyID:
-      llvm_unreachable("DXIL pointers cannot be added to IR modules");
+    case Type::TypedPointerTyID:
+      llvm_unreachable("Typed pointers cannot be added to IR modules");
     }
 
     // Emit the finished record.
diff --git a/lib/IR/AsmWriter.cpp b/lib/IR/AsmWriter.cpp
index 3fb26f2..0ee559a 100644
--- a/lib/IR/AsmWriter.cpp
+++ b/lib/IR/AsmWriter.cpp
@@ -62,6 +62,7 @@
 #include "llvm/IR/Operator.h"
 #include "llvm/IR/Type.h"
 #include "llvm/IR/TypeFinder.h"
+#include "llvm/IR/TypedPointerType.h"
 #include "llvm/IR/Use.h"
 #include "llvm/IR/User.h"
 #include "llvm/IR/Value.h"
@@ -610,12 +611,13 @@
     OS << '>';
     return;
   }
-  case Type::DXILPointerTyID:
-    // DXIL pointer types are only handled by the DirectX backend. To avoid
-    // extra dependencies we just print the pointer's address here.
-    OS << "dxil-ptr (" << Ty << ")";
+  case Type::TypedPointerTyID: {
+    TypedPointerType *TPTy = cast<TypedPointerType>(Ty);
+    OS << "typedptr(" << *TPTy->getElementType() << ", "
+       << TPTy->getAddressSpace() << ")";
     return;
   }
+  }
   llvm_unreachable("Invalid TypeID");
 }
 
diff --git a/lib/IR/CMakeLists.txt b/lib/IR/CMakeLists.txt
index 13a28f5..ccd1055 100644
--- a/lib/IR/CMakeLists.txt
+++ b/lib/IR/CMakeLists.txt
@@ -57,6 +57,7 @@
   Statepoint.cpp
   StructuralHash.cpp
   Type.cpp
+  TypedPointerType.cpp
   TypeFinder.cpp
   Use.cpp
   User.cpp
diff --git a/lib/IR/Core.cpp b/lib/IR/Core.cpp
index 08b7b0e..59c9f2f 100644
--- a/lib/IR/Core.cpp
+++ b/lib/IR/Core.cpp
@@ -541,8 +541,8 @@
     return LLVMTokenTypeKind;
   case Type::ScalableVectorTyID:
     return LLVMScalableVectorTypeKind;
-  case Type::DXILPointerTyID:
-    llvm_unreachable("DXIL pointers are unsupported via the C API");
+  case Type::TypedPointerTyID:
+    llvm_unreachable("Typed pointers are unsupported via the C API");
   }
   llvm_unreachable("Unhandled TypeID.");
 }
diff --git a/lib/IR/LLVMContext.cpp b/lib/IR/LLVMContext.cpp
index 4a1d5d3..57d7261 100644
--- a/lib/IR/LLVMContext.cpp
+++ b/lib/IR/LLVMContext.cpp
@@ -374,7 +374,3 @@
 bool LLVMContext::supportsTypedPointers() const {
   return !pImpl->getOpaquePointers();
 }
-
-Any &LLVMContext::getTargetData() const {
-  return pImpl->TargetDataStorage;
-}
diff --git a/lib/IR/LLVMContextImpl.h b/lib/IR/LLVMContextImpl.h
index 47add94..a36e46f 100644
--- a/lib/IR/LLVMContextImpl.h
+++ b/lib/IR/LLVMContextImpl.h
@@ -70,6 +70,7 @@
 }
 template <typename T> class StringMapEntry;
 class StringRef;
+class TypedPointerType;
 class ValueHandleBase;
 
 using DenseMapAPIntKeyInfo = DenseMapInfo<APInt>;
@@ -1484,6 +1485,7 @@
   DenseMap<std::pair<Type *, ElementCount>, VectorType *> VectorTypes;
   DenseMap<Type *, PointerType *> PointerTypes; // Pointers in AddrSpace = 0
   DenseMap<std::pair<Type *, unsigned>, PointerType *> ASPointerTypes;
+  DenseMap<std::pair<Type *, unsigned>, TypedPointerType *> ASTypedPointerTypes;
 
   /// ValueHandles - This map keeps track of all of the value handles that are
   /// watching a Value*.  The Value::HasValueHandle bit is used to know
@@ -1571,8 +1573,6 @@
   bool hasOpaquePointersValue();
   void setOpaquePointers(bool OP);
 
-  llvm::Any TargetDataStorage;
-
 private:
   Optional<bool> OpaquePointers;
 };
diff --git a/lib/IR/TypedPointerType.cpp b/lib/IR/TypedPointerType.cpp
new file mode 100644
index 0000000..ed91080
--- /dev/null
+++ b/lib/IR/TypedPointerType.cpp
@@ -0,0 +1,43 @@
+//===- TypedPointerType.cpp - Typed Pointer Type --------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/IR/TypedPointerType.h"
+#include "LLVMContextImpl.h"
+
+using namespace llvm;
+
+TypedPointerType *TypedPointerType::get(Type *EltTy, unsigned AddressSpace) {
+  assert(EltTy && "Can't get a pointer to <null> type!");
+  assert(isValidElementType(EltTy) && "Invalid type for pointer element!");
+
+  LLVMContextImpl *CImpl = EltTy->getContext().pImpl;
+
+  // Since AddressSpace #0 is the common case, we special case it.
+  TypedPointerType *&Entry =
+      CImpl->ASTypedPointerTypes[std::make_pair(EltTy, AddressSpace)];
+
+  if (!Entry)
+    Entry = new (CImpl->Alloc) TypedPointerType(EltTy, AddressSpace);
+  return Entry;
+}
+
+TypedPointerType::TypedPointerType(Type *E, unsigned AddrSpace)
+    : Type(E->getContext(), TypedPointerTyID), PointeeTy(E) {
+  ContainedTys = &PointeeTy;
+  NumContainedTys = 1;
+  setSubclassData(AddrSpace);
+}
+
+bool TypedPointerType::isValidElementType(Type *ElemTy) {
+  return !ElemTy->isVoidTy() && !ElemTy->isLabelTy() &&
+         !ElemTy->isMetadataTy() && !ElemTy->isTokenTy() &&
+         !ElemTy->isX86_AMXTy();
+}
diff --git a/lib/IR/Value.cpp b/lib/IR/Value.cpp
index 3990536..c707004 100644
--- a/lib/IR/Value.cpp
+++ b/lib/IR/Value.cpp
@@ -25,6 +25,7 @@
 #include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/Operator.h"
+#include "llvm/IR/TypedPointerType.h"
 #include "llvm/IR/ValueHandle.h"
 #include "llvm/IR/ValueSymbolTable.h"
 #include "llvm/Support/CommandLine.h"
@@ -43,6 +44,8 @@
 //===----------------------------------------------------------------------===//
 static inline Type *checkType(Type *Ty) {
   assert(Ty && "Value defined with a null type: Error!");
+  assert(!isa<TypedPointerType>(Ty) &&
+         "Cannot have values with typed pointer types");
   return Ty;
 }
 
diff --git a/lib/Target/DirectX/CMakeLists.txt b/lib/Target/DirectX/CMakeLists.txt
index 5d33497..64467de 100644
--- a/lib/Target/DirectX/CMakeLists.txt
+++ b/lib/Target/DirectX/CMakeLists.txt
@@ -19,7 +19,6 @@
   DirectXTargetMachine.cpp
   DXILOpBuilder.cpp
   DXILOpLowering.cpp
-  DXILPointerType.cpp
   DXILPrepare.cpp
   DXILTranslateMetadata.cpp
   PointerTypeAnalysis.cpp
diff --git a/lib/Target/DirectX/DXILPointerType.cpp b/lib/Target/DirectX/DXILPointerType.cpp
deleted file mode 100644
index 1e67f1a..0000000
--- a/lib/Target/DirectX/DXILPointerType.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-//===- Target/DirectX/DXILTypedPointerType.cpp - DXIL Typed Pointer Type
-//-------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-//
-//===----------------------------------------------------------------------===//
-
-#include "DXILPointerType.h"
-#include "llvm/ADT/Any.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/IR/LLVMContext.h"
-
-using namespace llvm;
-using namespace llvm::dxil;
-
-class TypedPointerTracking {
-public:
-  TypedPointerTracking() {}
-  DenseMap<Type *, std::unique_ptr<TypedPointerType>> PointerTypes;
-  DenseMap<std::pair<Type *, unsigned>, std::unique_ptr<TypedPointerType>>
-      ASPointerTypes;
-};
-
-TypedPointerType *TypedPointerType::get(Type *EltTy, unsigned AddressSpace) {
-  assert(EltTy && "Can't get a pointer to <null> type!");
-  assert(isValidElementType(EltTy) && "Invalid type for pointer element!");
-
-  llvm::Any &TargetData = EltTy->getContext().getTargetData();
-  if (!TargetData.hasValue())
-    TargetData = Any{std::make_shared<TypedPointerTracking>()};
-
-  assert(any_isa<std::shared_ptr<TypedPointerTracking>>(TargetData) &&
-         "Unexpected target data type");
-
-  std::shared_ptr<TypedPointerTracking> Tracking =
-      any_cast<std::shared_ptr<TypedPointerTracking>>(TargetData);
-
-  // Since AddressSpace #0 is the common case, we special case it.
-  std::unique_ptr<TypedPointerType> &Entry =
-      AddressSpace == 0
-          ? Tracking->PointerTypes[EltTy]
-          : Tracking->ASPointerTypes[std::make_pair(EltTy, AddressSpace)];
-
-  if (!Entry)
-    Entry = std::unique_ptr<TypedPointerType>(
-        new TypedPointerType(EltTy, AddressSpace));
-  return Entry.get();
-}
-
-TypedPointerType::TypedPointerType(Type *E, unsigned AddrSpace)
-    : Type(E->getContext(), DXILPointerTyID), PointeeTy(E) {
-  ContainedTys = &PointeeTy;
-  NumContainedTys = 1;
-  setSubclassData(AddrSpace);
-}
-
-bool TypedPointerType::isValidElementType(Type *ElemTy) {
-  return !ElemTy->isVoidTy() && !ElemTy->isLabelTy() &&
-         !ElemTy->isMetadataTy() && !ElemTy->isTokenTy() &&
-         !ElemTy->isX86_AMXTy();
-}
diff --git a/lib/Target/DirectX/DXILWriter/DXILBitcodeWriter.cpp b/lib/Target/DirectX/DXILWriter/DXILBitcodeWriter.cpp
index 8694336..70004f4 100644
--- a/lib/Target/DirectX/DXILWriter/DXILBitcodeWriter.cpp
+++ b/lib/Target/DirectX/DXILWriter/DXILBitcodeWriter.cpp
@@ -1068,7 +1068,7 @@
       Code = bitc::TYPE_CODE_INTEGER;
       TypeVals.push_back(cast<IntegerType>(T)->getBitWidth());
       break;
-    case Type::DXILPointerTyID: {
+    case Type::TypedPointerTyID: {
       TypedPointerType *PTy = cast<TypedPointerType>(T);
       // POINTER: [pointee type, address space]
       Code = bitc::TYPE_CODE_POINTER;
diff --git a/lib/Target/DirectX/DXILWriter/DXILValueEnumerator.cpp b/lib/Target/DirectX/DXILWriter/DXILValueEnumerator.cpp
index a873662..d90ab96 100644
--- a/lib/Target/DirectX/DXILWriter/DXILValueEnumerator.cpp
+++ b/lib/Target/DirectX/DXILWriter/DXILValueEnumerator.cpp
@@ -12,7 +12,6 @@
 //===----------------------------------------------------------------------===//
 
 #include "DXILValueEnumerator.h"
-#include "DXILPointerType.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Config/llvm-config.h"
 #include "llvm/IR/Argument.h"
@@ -32,6 +31,7 @@
 #include "llvm/IR/Module.h"
 #include "llvm/IR/Operator.h"
 #include "llvm/IR/Type.h"
+#include "llvm/IR/TypedPointerType.h"
 #include "llvm/IR/Use.h"
 #include "llvm/IR/User.h"
 #include "llvm/IR/Value.h"
@@ -373,7 +373,7 @@
     EnumerateValue(&F);
     EnumerateType(F.getValueType());
     EnumerateType(
-        dxil::TypedPointerType::get(F.getFunctionType(), F.getAddressSpace()));
+        TypedPointerType::get(F.getFunctionType(), F.getAddressSpace()));
     EnumerateAttributes(F.getAttributes());
   }
 
@@ -394,7 +394,7 @@
     if (GV.hasInitializer())
       EnumerateValue(GV.getInitializer());
     EnumerateType(
-        dxil::TypedPointerType::get(GV.getValueType(), GV.getAddressSpace()));
+        TypedPointerType::get(GV.getValueType(), GV.getAddressSpace()));
     if (GV.hasAttributes())
       EnumerateAttributes(GV.getAttributesAsList(AttributeList::FunctionIndex));
   }
diff --git a/lib/Target/DirectX/PointerTypeAnalysis.h b/lib/Target/DirectX/PointerTypeAnalysis.h
index c4164b6..fe1d5d1 100644
--- a/lib/Target/DirectX/PointerTypeAnalysis.h
+++ b/lib/Target/DirectX/PointerTypeAnalysis.h
@@ -13,9 +13,9 @@
 #ifndef LLVM_TARGET_DIRECTX_POINTERTYPEANALYSIS_H
 #define LLVM_TARGET_DIRECTX_POINTERTYPEANALYSIS_H
 
-#include "DXILPointerType.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/IR/PassManager.h"
+#include "llvm/IR/TypedPointerType.h"
 
 namespace llvm {
 
diff --git a/lib/Target/Hexagon/HexagonTargetObjectFile.cpp b/lib/Target/Hexagon/HexagonTargetObjectFile.cpp
index c83ed16..b4ef659 100644
--- a/lib/Target/Hexagon/HexagonTargetObjectFile.cpp
+++ b/lib/Target/Hexagon/HexagonTargetObjectFile.cpp
@@ -332,7 +332,7 @@
   case Type::X86_MMXTyID:
   case Type::X86_AMXTyID:
   case Type::TokenTyID:
-  case Type::DXILPointerTyID:
+  case Type::TypedPointerTyID:
     return 0;
   }
 
diff --git a/unittests/IR/TypesTest.cpp b/unittests/IR/TypesTest.cpp
index 2ad4304..83fd559 100644
--- a/unittests/IR/TypesTest.cpp
+++ b/unittests/IR/TypesTest.cpp
@@ -8,6 +8,7 @@
 
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/TypedPointerType.h"
 #include "gtest/gtest.h"
 using namespace llvm;
 
@@ -60,4 +61,14 @@
   EXPECT_FALSE(P2C0->isOpaque());
 }
 
+TEST(TypedPointerType, PrintTest) {
+  std::string Buffer;
+  LLVMContext Context;
+  raw_string_ostream OS(Buffer);
+
+  Type *I8Ptr = TypedPointerType::get(Type::getInt8Ty(Context), 0);
+  I8Ptr->print(OS);
+  EXPECT_EQ(StringRef(Buffer), ("typedptr(i8, 0)"));
+}
+
 }  // end anonymous namespace
diff --git a/unittests/Target/DirectX/PointerTypeAnalysisTests.cpp b/unittests/Target/DirectX/PointerTypeAnalysisTests.cpp
index 22ec2bd..ee6c4f9 100644
--- a/unittests/Target/DirectX/PointerTypeAnalysisTests.cpp
+++ b/unittests/Target/DirectX/PointerTypeAnalysisTests.cpp
@@ -6,12 +6,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "DXILPointerType.h"
 #include "PointerTypeAnalysis.h"
 #include "llvm/AsmParser/Parser.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Type.h"
+#include "llvm/IR/TypedPointerType.h"
 #include "llvm/Support/SourceMgr.h"
 
 #include "gmock/gmock.h"
@@ -27,16 +27,6 @@
   friend bool operator==(const Value *V, const IsA &) { return isa<T>(V); }
 };
 
-TEST(DXILPointerType, PrintTest) {
-  std::string Buffer;
-  LLVMContext Context;
-  raw_string_ostream OS(Buffer);
-
-  Type *I8Ptr = TypedPointerType::get(Type::getInt8Ty(Context), 0);
-  I8Ptr->print(OS);
-  EXPECT_TRUE(StringRef(Buffer).startswith("dxil-ptr ("));
-}
-
 TEST(PointerTypeAnalysis, DigressToi8) {
   StringRef Assembly = R"(
     define i64 @test(ptr %p) {