Skip to content

Commit e6f44a3

Browse files
committed
Add PointerType analysis for DirectX backend
As implemented this patch assumes that Typed pointer support remains in the llvm::PointerType class, however this could be modified to use a different subclass of llvm::Type that could be disallowed from use in other contexts. This does not rely on inserting typed pointers into the Module, it just uses the llvm::PointerType class to track and unique types. Fixes #54918 Reviewed By: kuhar Differential Revision: https://reviews.llvm.org/D122268
1 parent 987cd7c commit e6f44a3

File tree

15 files changed

+512
-7
lines changed

15 files changed

+512
-7
lines changed

llvm/include/llvm/IR/LLVMContext.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
namespace llvm {
2626

27+
class Any;
2728
class DiagnosticInfo;
2829
enum DiagnosticSeverity : char;
2930
class Function;
@@ -322,6 +323,10 @@ class LLVMContext {
322323
/// Whether typed pointers are supported. If false, all pointers are opaque.
323324
bool supportsTypedPointers() const;
324325

326+
/// Optionally target-spcific data can be attached to the context for lifetime
327+
/// management and bypassing layering restrictions.
328+
llvm::Any &getTargetData() const;
329+
325330
private:
326331
// Module needs access to the add/removeModule methods.
327332
friend class Module;

llvm/include/llvm/IR/Type.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,14 @@ class Type {
6868
TokenTyID, ///< Tokens
6969

7070
// Derived types... see DerivedTypes.h file.
71-
IntegerTyID, ///< Arbitrary bit width integers
72-
FunctionTyID, ///< Functions
73-
PointerTyID, ///< Pointers
74-
StructTyID, ///< Structures
75-
ArrayTyID, ///< Arrays
76-
FixedVectorTyID, ///< Fixed width SIMD vector type
77-
ScalableVectorTyID ///< Scalable SIMD vector type
71+
IntegerTyID, ///< Arbitrary bit width integers
72+
FunctionTyID, ///< Functions
73+
PointerTyID, ///< Pointers
74+
StructTyID, ///< Structures
75+
ArrayTyID, ///< Arrays
76+
FixedVectorTyID, ///< Fixed width SIMD vector type
77+
ScalableVectorTyID, ///< Scalable SIMD vector type
78+
DXILPointerTyID, ///< DXIL typed pointer used by DirectX target
7879
};
7980

8081
private:

llvm/lib/Bitcode/Writer/BitcodeWriter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,6 +1018,8 @@ void ModuleBitcodeWriter::writeTypeTable() {
10181018
TypeVals.push_back(true);
10191019
break;
10201020
}
1021+
case Type::DXILPointerTyID:
1022+
llvm_unreachable("DXIL pointers cannot be added to IR modules");
10211023
}
10221024

10231025
// Emit the finished record.

llvm/lib/IR/AsmWriter.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,11 @@ void TypePrinting::print(Type *Ty, raw_ostream &OS) {
612612
OS << '>';
613613
return;
614614
}
615+
case Type::DXILPointerTyID:
616+
// DXIL pointer types are only handled by the DirectX backend. To avoid
617+
// extra dependencies we just print the pointer's address here.
618+
OS << "dxil-ptr (" << Ty << ")";
619+
return;
615620
}
616621
llvm_unreachable("Invalid TypeID");
617622
}

llvm/lib/IR/Core.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,8 @@ LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty) {
534534
return LLVMTokenTypeKind;
535535
case Type::ScalableVectorTyID:
536536
return LLVMScalableVectorTypeKind;
537+
case Type::DXILPointerTyID:
538+
llvm_unreachable("DXIL pointers are unsupported via the C API");
537539
}
538540
llvm_unreachable("Unhandled TypeID.");
539541
}

llvm/lib/IR/LLVMContext.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,3 +374,7 @@ void LLVMContext::setOpaquePointers(bool Enable) const {
374374
bool LLVMContext::supportsTypedPointers() const {
375375
return !pImpl->getOpaquePointers();
376376
}
377+
378+
Any &LLVMContext::getTargetData() const {
379+
return pImpl->TargetDataStorage;
380+
}

llvm/lib/IR/LLVMContextImpl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "ConstantsContext.h"
1818
#include "llvm/ADT/APFloat.h"
1919
#include "llvm/ADT/APInt.h"
20+
#include "llvm/ADT/Any.h"
2021
#include "llvm/ADT/ArrayRef.h"
2122
#include "llvm/ADT/DenseMap.h"
2223
#include "llvm/ADT/DenseMapInfo.h"
@@ -1567,6 +1568,8 @@ class LLVMContextImpl {
15671568
bool hasOpaquePointersValue();
15681569
void setOpaquePointers(bool OP);
15691570

1571+
llvm::Any TargetDataStorage;
1572+
15701573
private:
15711574
Optional<bool> OpaquePointers;
15721575
};

llvm/lib/Target/DirectX/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ add_public_tablegen_target(DirectXCommonTableGen)
99
add_llvm_target(DirectXCodeGen
1010
DirectXSubtarget.cpp
1111
DirectXTargetMachine.cpp
12+
DXILPointerType.cpp
1213
DXILPrepare.cpp
14+
PointerTypeAnalysis.cpp
1315

1416
LINK_COMPONENTS
1517
Core
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
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:
23+
TypedPointerTracking() {}
24+
DenseMap<Type *, std::unique_ptr<TypedPointerType>> PointerTypes;
25+
DenseMap<std::pair<Type *, unsigned>, std::unique_ptr<TypedPointerType>>
26+
ASPointerTypes;
27+
};
28+
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+
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+
62+
bool TypedPointerType::isValidElementType(Type *ElemTy) {
63+
return !ElemTy->isVoidTy() && !ElemTy->isLabelTy() &&
64+
!ElemTy->isMetadataTy() && !ElemTy->isTokenTy() &&
65+
!ElemTy->isX86_AMXTy();
66+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//===- Target/DirectX/DXILPointerType.h - DXIL Typed Pointer Type ---------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
//
10+
//===----------------------------------------------------------------------===//
11+
12+
#ifndef LLVM_TARGET_DIRECTX_DXILPOINTERTYPE_H
13+
#define LLVM_TARGET_DIRECTX_DXILPOINTERTYPE_H
14+
15+
#include "llvm/IR/Type.h"
16+
17+
namespace llvm {
18+
namespace dxil {
19+
20+
// DXIL has typed pointers, this pointer type abstraction is used for tracking
21+
// in PointerTypeAnalysis and for the bitcode ValueEnumerator
22+
class TypedPointerType : public Type {
23+
explicit TypedPointerType(Type *ElType, unsigned AddrSpace);
24+
25+
Type *PointeeTy;
26+
27+
public:
28+
TypedPointerType(const TypedPointerType &) = delete;
29+
TypedPointerType &operator=(const TypedPointerType &) = delete;
30+
31+
/// This constructs a pointer to an object of the specified type in a numbered
32+
/// address space.
33+
static TypedPointerType *get(Type *ElementType, unsigned AddressSpace);
34+
35+
/// Return true if the specified type is valid as a element type.
36+
static bool isValidElementType(Type *ElemTy);
37+
38+
/// Return the address space of the Pointer type.
39+
unsigned getAddressSpace() const { return getSubclassData(); }
40+
41+
Type *getElementType() const { return PointeeTy; }
42+
43+
/// Implement support type inquiry through isa, cast, and dyn_cast.
44+
static bool classof(const Type *T) {
45+
return T->getTypeID() == DXILPointerTyID;
46+
}
47+
};
48+
49+
} // namespace dxil
50+
} // namespace llvm
51+
52+
#endif // LLVM_TARGET_DIRECTX_DXILPOINTERTYPE_H

0 commit comments

Comments
 (0)