diff --git a/llvm/include/llvm/IR/LLVMContext.h b/llvm/include/llvm/IR/LLVMContext.h --- a/llvm/include/llvm/IR/LLVMContext.h +++ b/llvm/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/llvm/include/llvm/IR/Type.h b/llvm/include/llvm/IR/Type.h --- a/llvm/include/llvm/IR/Type.h +++ b/llvm/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/llvm/lib/Target/DirectX/DXILPointerType.h b/llvm/include/llvm/IR/TypedPointerType.h rename from llvm/lib/Target/DirectX/DXILPointerType.h rename to llvm/include/llvm/IR/TypedPointerType.h --- a/llvm/lib/Target/DirectX/DXILPointerType.h +++ b/llvm/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/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/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/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/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(Ty); + OS << "typedptr(" << *TPTy->getElementType() << ", " + << TPTy->getAddressSpace() << ")"; return; } + } llvm_unreachable("Invalid TypeID"); } diff --git a/llvm/lib/IR/CMakeLists.txt b/llvm/lib/IR/CMakeLists.txt --- a/llvm/lib/IR/CMakeLists.txt +++ b/llvm/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/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp --- a/llvm/lib/IR/Core.cpp +++ b/llvm/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/llvm/lib/IR/LLVMContext.cpp b/llvm/lib/IR/LLVMContext.cpp --- a/llvm/lib/IR/LLVMContext.cpp +++ b/llvm/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/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -70,6 +70,7 @@ } template class StringMapEntry; class StringRef; +class TypedPointerType; class ValueHandleBase; using DenseMapAPIntKeyInfo = DenseMapInfo; @@ -1484,6 +1485,7 @@ DenseMap, VectorType *> VectorTypes; DenseMap PointerTypes; // Pointers in AddrSpace = 0 DenseMap, PointerType *> ASPointerTypes; + DenseMap, 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 OpaquePointers; }; diff --git a/llvm/lib/IR/TypedPointerType.cpp b/llvm/lib/IR/TypedPointerType.cpp new file mode 100644 --- /dev/null +++ b/llvm/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 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/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp --- a/llvm/lib/IR/Value.cpp +++ b/llvm/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(Ty) && + "Cannot have values with typed pointer types"); return Ty; } diff --git a/llvm/lib/Target/DirectX/CMakeLists.txt b/llvm/lib/Target/DirectX/CMakeLists.txt --- a/llvm/lib/Target/DirectX/CMakeLists.txt +++ b/llvm/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/llvm/lib/Target/DirectX/DXILPointerType.cpp b/llvm/lib/Target/DirectX/DXILPointerType.cpp deleted file mode 100644 --- a/llvm/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> PointerTypes; - DenseMap, std::unique_ptr> - ASPointerTypes; -}; - -TypedPointerType *TypedPointerType::get(Type *EltTy, unsigned AddressSpace) { - assert(EltTy && "Can't get a pointer to type!"); - assert(isValidElementType(EltTy) && "Invalid type for pointer element!"); - - llvm::Any &TargetData = EltTy->getContext().getTargetData(); - if (!TargetData.hasValue()) - TargetData = Any{std::make_shared()}; - - assert(any_isa>(TargetData) && - "Unexpected target data type"); - - std::shared_ptr Tracking = - any_cast>(TargetData); - - // Since AddressSpace #0 is the common case, we special case it. - std::unique_ptr &Entry = - AddressSpace == 0 - ? Tracking->PointerTypes[EltTy] - : Tracking->ASPointerTypes[std::make_pair(EltTy, AddressSpace)]; - - if (!Entry) - Entry = std::unique_ptr( - 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/llvm/lib/Target/DirectX/DXILWriter/DXILBitcodeWriter.cpp b/llvm/lib/Target/DirectX/DXILWriter/DXILBitcodeWriter.cpp --- a/llvm/lib/Target/DirectX/DXILWriter/DXILBitcodeWriter.cpp +++ b/llvm/lib/Target/DirectX/DXILWriter/DXILBitcodeWriter.cpp @@ -1068,7 +1068,7 @@ Code = bitc::TYPE_CODE_INTEGER; TypeVals.push_back(cast(T)->getBitWidth()); break; - case Type::DXILPointerTyID: { + case Type::TypedPointerTyID: { TypedPointerType *PTy = cast(T); // POINTER: [pointee type, address space] Code = bitc::TYPE_CODE_POINTER; diff --git a/llvm/lib/Target/DirectX/DXILWriter/DXILValueEnumerator.cpp b/llvm/lib/Target/DirectX/DXILWriter/DXILValueEnumerator.cpp --- a/llvm/lib/Target/DirectX/DXILWriter/DXILValueEnumerator.cpp +++ b/llvm/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/llvm/lib/Target/DirectX/PointerTypeAnalysis.h b/llvm/lib/Target/DirectX/PointerTypeAnalysis.h --- a/llvm/lib/Target/DirectX/PointerTypeAnalysis.h +++ b/llvm/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/llvm/lib/Target/Hexagon/HexagonTargetObjectFile.cpp b/llvm/lib/Target/Hexagon/HexagonTargetObjectFile.cpp --- a/llvm/lib/Target/Hexagon/HexagonTargetObjectFile.cpp +++ b/llvm/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/llvm/unittests/IR/TypesTest.cpp b/llvm/unittests/IR/TypesTest.cpp --- a/llvm/unittests/IR/TypesTest.cpp +++ b/llvm/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/llvm/unittests/Target/DirectX/PointerTypeAnalysisTests.cpp b/llvm/unittests/Target/DirectX/PointerTypeAnalysisTests.cpp --- a/llvm/unittests/Target/DirectX/PointerTypeAnalysisTests.cpp +++ b/llvm/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(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) {