1 //===- Target/DirectX/DXILTypedPointerType.cpp - DXIL Typed Pointer Type
2 //-------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "DXILPointerType.h"
14 #include "llvm/ADT/Any.h"
15 #include "llvm/ADT/DenseMap.h"
16 #include "llvm/IR/LLVMContext.h"
17
18 using namespace llvm;
19 using namespace llvm::dxil;
20
21 class TypedPointerTracking {
22 public:
TypedPointerTracking()23 TypedPointerTracking() {}
24 DenseMap<Type *, std::unique_ptr<TypedPointerType>> PointerTypes;
25 DenseMap<std::pair<Type *, unsigned>, std::unique_ptr<TypedPointerType>>
26 ASPointerTypes;
27 };
28
get(Type * EltTy,unsigned AddressSpace)29 TypedPointerType *TypedPointerType::get(Type *EltTy, unsigned AddressSpace) {
30 assert(EltTy && "Can't get a pointer to <null> type!");
31 assert(isValidElementType(EltTy) && "Invalid type for pointer element!");
32
33 llvm::Any &TargetData = EltTy->getContext().getTargetData();
34 if (!TargetData.hasValue())
35 TargetData = Any{std::make_shared<TypedPointerTracking>()};
36
37 assert(any_isa<std::shared_ptr<TypedPointerTracking>>(TargetData) &&
38 "Unexpected target data type");
39
40 std::shared_ptr<TypedPointerTracking> Tracking =
41 any_cast<std::shared_ptr<TypedPointerTracking>>(TargetData);
42
43 // Since AddressSpace #0 is the common case, we special case it.
44 std::unique_ptr<TypedPointerType> &Entry =
45 AddressSpace == 0
46 ? Tracking->PointerTypes[EltTy]
47 : Tracking->ASPointerTypes[std::make_pair(EltTy, AddressSpace)];
48
49 if (!Entry)
50 Entry = std::unique_ptr<TypedPointerType>(
51 new TypedPointerType(EltTy, AddressSpace));
52 return Entry.get();
53 }
54
TypedPointerType(Type * E,unsigned AddrSpace)55 TypedPointerType::TypedPointerType(Type *E, unsigned AddrSpace)
56 : Type(E->getContext(), DXILPointerTyID), PointeeTy(E) {
57 ContainedTys = &PointeeTy;
58 NumContainedTys = 1;
59 setSubclassData(AddrSpace);
60 }
61
isValidElementType(Type * ElemTy)62 bool TypedPointerType::isValidElementType(Type *ElemTy) {
63 return !ElemTy->isVoidTy() && !ElemTy->isLabelTy() &&
64 !ElemTy->isMetadataTy() && !ElemTy->isTokenTy() &&
65 !ElemTy->isX86_AMXTy();
66 }
67