forked from OSchip/llvm-project
[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
This commit is contained in:
parent
448adfee05
commit
2138c90645
|
@ -24,7 +24,6 @@
|
|||
|
||||
namespace llvm {
|
||||
|
||||
class Any;
|
||||
class DiagnosticInfo;
|
||||
enum DiagnosticSeverity : char;
|
||||
class Function;
|
||||
|
@ -323,10 +322,6 @@ public:
|
|||
/// 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;
|
||||
|
|
|
@ -75,7 +75,7 @@ public:
|
|||
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:
|
||||
|
|
|
@ -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 @@ public:
|
|||
|
||||
/// 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
|
|
@ -1029,8 +1029,8 @@ void ModuleBitcodeWriter::writeTypeTable() {
|
|||
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.
|
||||
|
|
|
@ -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 @@ void TypePrinting::print(Type *Ty, raw_ostream &OS) {
|
|||
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");
|
||||
}
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ add_llvm_component_library(LLVMCore
|
|||
Statepoint.cpp
|
||||
StructuralHash.cpp
|
||||
Type.cpp
|
||||
TypedPointerType.cpp
|
||||
TypeFinder.cpp
|
||||
Use.cpp
|
||||
User.cpp
|
||||
|
|
|
@ -541,8 +541,8 @@ LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty) {
|
|||
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.");
|
||||
}
|
||||
|
|
|
@ -374,7 +374,3 @@ void LLVMContext::setOpaquePointers(bool Enable) const {
|
|||
bool LLVMContext::supportsTypedPointers() const {
|
||||
return !pImpl->getOpaquePointers();
|
||||
}
|
||||
|
||||
Any &LLVMContext::getTargetData() const {
|
||||
return pImpl->TargetDataStorage;
|
||||
}
|
||||
|
|
|
@ -70,6 +70,7 @@ class RemarkStreamer;
|
|||
}
|
||||
template <typename T> class StringMapEntry;
|
||||
class StringRef;
|
||||
class TypedPointerType;
|
||||
class ValueHandleBase;
|
||||
|
||||
using DenseMapAPIntKeyInfo = DenseMapInfo<APInt>;
|
||||
|
@ -1484,6 +1485,7 @@ public:
|
|||
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 @@ public:
|
|||
bool hasOpaquePointersValue();
|
||||
void setOpaquePointers(bool OP);
|
||||
|
||||
llvm::Any TargetDataStorage;
|
||||
|
||||
private:
|
||||
Optional<bool> OpaquePointers;
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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 cl::opt<unsigned> UseDerefAtPointSemantics(
|
|||
//===----------------------------------------------------------------------===//
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@ add_llvm_target(DirectXCodeGen
|
|||
DirectXTargetMachine.cpp
|
||||
DXILOpBuilder.cpp
|
||||
DXILOpLowering.cpp
|
||||
DXILPointerType.cpp
|
||||
DXILPrepare.cpp
|
||||
DXILTranslateMetadata.cpp
|
||||
PointerTypeAnalysis.cpp
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -1068,7 +1068,7 @@ void DXILBitcodeWriter::writeTypeTable() {
|
|||
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;
|
||||
|
|
|
@ -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 @@ ValueEnumerator::ValueEnumerator(const Module &M, Type *PrefixType) {
|
|||
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 @@ ValueEnumerator::ValueEnumerator(const Module &M, Type *PrefixType) {
|
|||
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));
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -332,7 +332,7 @@ unsigned HexagonTargetObjectFile::getSmallestAddressableSize(const Type *Ty,
|
|||
case Type::X86_MMXTyID:
|
||||
case Type::X86_AMXTyID:
|
||||
case Type::TokenTyID:
|
||||
case Type::DXILPointerTyID:
|
||||
case Type::TypedPointerTyID:
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 @@ TEST(TypesTest, CopyPointerType) {
|
|||
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
|
||||
|
|
|
@ -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 @@ template <typename T> struct IsA {
|
|||
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) {
|
||||
|
|
Loading…
Reference in New Issue