namespace llvm {
-class Any;
class DiagnosticInfo;
enum DiagnosticSeverity : char;
class Function;
/// 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;
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:
-//===- 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.
//
//===----------------------------------------------------------------------===//
//
+// 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);
/// 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
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.
#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"
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");
}
Statepoint.cpp
StructuralHash.cpp
Type.cpp
+ TypedPointerType.cpp
TypeFinder.cpp
Use.cpp
User.cpp
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.");
}
bool LLVMContext::supportsTypedPointers() const {
return !pImpl->getOpaquePointers();
}
-
-Any &LLVMContext::getTargetData() const {
- return pImpl->TargetDataStorage;
-}
}
template <typename T> class StringMapEntry;
class StringRef;
+class TypedPointerType;
class ValueHandleBase;
using DenseMapAPIntKeyInfo = DenseMapInfo<APInt>;
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
bool hasOpaquePointersValue();
void setOpaquePointers(bool OP);
- llvm::Any TargetDataStorage;
-
private:
Optional<bool> OpaquePointers;
};
--- /dev/null
+//===- 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();
+}
#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"
//===----------------------------------------------------------------------===//
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;
}
DirectXTargetMachine.cpp
DXILOpBuilder.cpp
DXILOpLowering.cpp
- DXILPointerType.cpp
DXILPrepare.cpp
DXILTranslateMetadata.cpp
PointerTypeAnalysis.cpp
+++ /dev/null
-//===- 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();
-}
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;
//===----------------------------------------------------------------------===//
#include "DXILValueEnumerator.h"
-#include "DXILPointerType.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/Argument.h"
#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"
EnumerateValue(&F);
EnumerateType(F.getValueType());
EnumerateType(
- dxil::TypedPointerType::get(F.getFunctionType(), F.getAddressSpace()));
+ TypedPointerType::get(F.getFunctionType(), F.getAddressSpace()));
EnumerateAttributes(F.getAttributes());
}
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));
}
#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 {
case Type::X86_MMXTyID:
case Type::X86_AMXTyID:
case Type::TokenTyID:
- case Type::DXILPointerTyID:
+ case Type::TypedPointerTyID:
return 0;
}
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/TypedPointerType.h"
#include "gtest/gtest.h"
using namespace llvm;
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
//
//===----------------------------------------------------------------------===//
-#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"
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) {