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