LLVM 22.0.0git
DXILPrettyPrinter.cpp
Go to the documentation of this file.
1//===- DXILPrettyPrinter.cpp - Print resources for textual DXIL -----------===//
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#include "DXILPrettyPrinter.h"
10#include "DirectX.h"
11#include "llvm/ADT/StringRef.h"
13#include "llvm/IR/PassManager.h"
15#include "llvm/Pass.h"
19
20using namespace llvm;
21
23 switch (RC) {
24 case dxil::ResourceClass::SRV:
25 return "texture";
26 case dxil::ResourceClass::UAV:
27 return "UAV";
28 case dxil::ResourceClass::CBuffer:
29 return "cbuffer";
30 case dxil::ResourceClass::Sampler:
31 return "sampler";
32 }
33 llvm_unreachable("covered switch");
34}
35
37 switch (RC) {
38 case dxil::ResourceClass::SRV:
39 return "t";
40 case dxil::ResourceClass::UAV:
41 return "u";
42 case dxil::ResourceClass::CBuffer:
43 return "cb";
44 case dxil::ResourceClass::Sampler:
45 return "s";
46 }
47 llvm_unreachable("covered switch");
48}
49
51 if (RI.isTyped()) {
52 switch (RI.getTyped().ElementTy) {
53 case dxil::ElementType::I1:
54 return "i1";
55 case dxil::ElementType::I16:
56 return "i16";
57 case dxil::ElementType::U16:
58 return "u16";
59 case dxil::ElementType::I32:
60 return "i32";
61 case dxil::ElementType::U32:
62 return "u32";
63 case dxil::ElementType::I64:
64 return "i64";
65 case dxil::ElementType::U64:
66 return "u64";
67 case dxil::ElementType::F16:
68 return "f16";
69 case dxil::ElementType::F32:
70 return "f32";
71 case dxil::ElementType::F64:
72 return "f64";
73 case dxil::ElementType::SNormF16:
74 return "snorm_f16";
75 case dxil::ElementType::UNormF16:
76 return "unorm_f16";
77 case dxil::ElementType::SNormF32:
78 return "snorm_f32";
79 case dxil::ElementType::UNormF32:
80 return "unorm_f32";
81 case dxil::ElementType::SNormF64:
82 return "snorm_f64";
83 case dxil::ElementType::UNormF64:
84 return "unorm_f64";
85 case dxil::ElementType::PackedS8x32:
86 return "p32i8";
87 case dxil::ElementType::PackedU8x32:
88 return "p32u8";
89 case dxil::ElementType::Invalid:
90 llvm_unreachable("Invalid ElementType");
91 }
92 llvm_unreachable("Unhandled ElementType");
93 } else if (RI.isStruct())
94 return "struct";
95 else if (RI.isCBuffer() || RI.isSampler())
96 return "NA";
97 return "byte";
98}
99
101 switch (RK) {
102 case dxil::ResourceKind::Texture1D:
103 return "1d";
104 case dxil::ResourceKind::Texture2D:
105 return "2d";
106 case dxil::ResourceKind::Texture3D:
107 return "3d";
108 case dxil::ResourceKind::TextureCube:
109 return "cube";
110 case dxil::ResourceKind::Texture1DArray:
111 return "1darray";
112 case dxil::ResourceKind::Texture2DArray:
113 return "2darray";
114 case dxil::ResourceKind::TextureCubeArray:
115 return "cubearray";
116 case dxil::ResourceKind::TBuffer:
117 return "tbuffer";
118 case dxil::ResourceKind::FeedbackTexture2D:
119 return "fbtex2d";
120 case dxil::ResourceKind::FeedbackTexture2DArray:
121 return "fbtex2darray";
122 case dxil::ResourceKind::Texture2DMS:
123 return "2dMS";
124 case dxil::ResourceKind::Texture2DMSArray:
125 return "2darrayMS";
126 case dxil::ResourceKind::Invalid:
127 case dxil::ResourceKind::NumEntries:
128 case dxil::ResourceKind::CBuffer:
129 case dxil::ResourceKind::RawBuffer:
130 case dxil::ResourceKind::Sampler:
131 case dxil::ResourceKind::StructuredBuffer:
132 case dxil::ResourceKind::TypedBuffer:
133 case dxil::ResourceKind::RTAccelerationStructure:
134 llvm_unreachable("Invalid ResourceKind for texture");
135 }
136 llvm_unreachable("Unhandled ResourceKind");
137}
138
139namespace {
140struct FormatResourceDimension
141 : public llvm::FormatAdapter<const dxil::ResourceTypeInfo &> {
142 FormatResourceDimension(const dxil::ResourceTypeInfo &RI, bool HasCounter)
143 : llvm::FormatAdapter<const dxil::ResourceTypeInfo &>(RI),
144 HasCounter(HasCounter) {}
145
146 bool HasCounter;
147
148 void format(llvm::raw_ostream &OS, StringRef Style) override {
149 dxil::ResourceKind RK = Item.getResourceKind();
150 switch (RK) {
151 default: {
152 OS << getTextureDimName(RK);
153 if (Item.isMultiSample())
154 OS << Item.getMultiSampleCount();
155 break;
156 }
159 if (!Item.isUAV())
160 OS << "r/o";
161 else if (HasCounter)
162 OS << "r/w+cnt";
163 else
164 OS << "r/w";
165 break;
167 OS << "buf";
168 break;
170 OS << "NA";
171 break;
173 // TODO: dxc would print "ras" here. Can/should this happen?
174 llvm_unreachable("RTAccelerationStructure printing is not implemented");
175 }
176 }
177};
178
179struct FormatBindingID
180 : public llvm::FormatAdapter<const dxil::ResourceInfo &> {
182
183 explicit FormatBindingID(const dxil::ResourceInfo &RI,
184 const dxil::ResourceTypeInfo &RTI)
185 : llvm::FormatAdapter<const dxil::ResourceInfo &>(RI),
186 RC(RTI.getResourceClass()) {}
187
188 void format(llvm::raw_ostream &OS, StringRef Style) override {
189 OS << getRCPrefix(RC).upper() << Item.getBinding().RecordID;
190 }
191};
192
193struct FormatBindingLocation
194 : public llvm::FormatAdapter<const dxil::ResourceInfo &> {
196
197 explicit FormatBindingLocation(const dxil::ResourceInfo &RI,
198 const dxil::ResourceTypeInfo &RTI)
199 : llvm::FormatAdapter<const dxil::ResourceInfo &>(RI),
200 RC(RTI.getResourceClass()) {}
201
202 void format(llvm::raw_ostream &OS, StringRef Style) override {
203 const auto &Binding = Item.getBinding();
204 OS << getRCPrefix(RC) << Binding.LowerBound;
205 if (Binding.Space)
206 OS << ",space" << Binding.Space;
207 }
208};
209
210struct FormatBindingSize
211 : public llvm::FormatAdapter<const dxil::ResourceInfo &> {
212 explicit FormatBindingSize(const dxil::ResourceInfo &RI)
213 : llvm::FormatAdapter<const dxil::ResourceInfo &>(RI) {}
214
215 void format(llvm::raw_ostream &OS, StringRef Style) override {
216 uint32_t Size = Item.getBinding().Size;
217 if (Size == std::numeric_limits<uint32_t>::max())
218 OS << "unbounded";
219 else
220 OS << Size;
221 }
222};
223
224} // namespace
225
227 DXILResourceTypeMap &DRTM) {
228 // Column widths are arbitrary but match the widths DXC uses.
229 OS << ";\n; Resource Bindings:\n;\n";
230 OS << formatv("; {0,-30} {1,10} {2,7} {3,11} {4,7} {5,14} {6,9}\n", "Name",
231 "Type", "Format", "Dim", "ID", "HLSL Bind", "Count");
232 OS << formatv(
233 "; {0,-+30} {1,-+10} {2,-+7} {3,-+11} {4,-+7} {5,-+14} {6,-+9}\n", "", "",
234 "", "", "", "", "");
235
236 // TODO: Do we want to sort these by binding or something like that?
237 for (const dxil::ResourceInfo &RI : DRM) {
238 const dxil::ResourceTypeInfo &RTI = DRTM[RI.getHandleTy()];
239
241 StringRef Name(RI.getName());
243 StringRef Format(getFormatName(RTI));
244 FormatResourceDimension Dim(RTI, RI.hasCounter());
245 FormatBindingID ID(RI, RTI);
246 FormatBindingLocation Bind(RI, RTI);
247 FormatBindingSize Count(RI);
248 OS << formatv("; {0,-30} {1,10} {2,7} {3,11} {4,7} {5,14} {6,9}\n", Name,
249 Type, Format, Dim, ID, Bind, Count);
250 }
251 OS << ";\n";
252}
253
258 prettyPrintResources(OS, DRM, DRTM);
259 return PreservedAnalyses::all();
260}
261
262namespace {
263class DXILPrettyPrinterLegacy : public llvm::ModulePass {
264 raw_ostream &OS; // raw_ostream to print to.
265
266public:
267 static char ID;
268
269 explicit DXILPrettyPrinterLegacy(raw_ostream &O) : ModulePass(ID), OS(O) {}
270
271 StringRef getPassName() const override {
272 return "DXIL Metadata Pretty Printer";
273 }
274
275 bool runOnModule(Module &M) override;
276 void getAnalysisUsage(AnalysisUsage &AU) const override {
277 AU.setPreservesAll();
280 }
281};
282} // namespace
283
284char DXILPrettyPrinterLegacy::ID = 0;
285INITIALIZE_PASS_BEGIN(DXILPrettyPrinterLegacy, "dxil-pretty-printer",
286 "DXIL Metadata Pretty Printer", true, true)
289INITIALIZE_PASS_END(DXILPrettyPrinterLegacy, "dxil-pretty-printer",
290 "DXIL Metadata Pretty Printer", true, true)
291
292bool DXILPrettyPrinterLegacy::runOnModule(Module &M) {
293 const DXILResourceMap &DRM =
294 getAnalysis<DXILResourceWrapperPass>().getResourceMap();
295 DXILResourceTypeMap &DRTM =
296 getAnalysis<DXILResourceTypeWrapperPass>().getResourceTypeMap();
297 prettyPrintResources(OS, DRM, DRTM);
298 return false;
299}
300
302 return new DXILPrettyPrinterLegacy(OS);
303}
aarch64 promote const
static StringRef getTextureDimName(dxil::ResourceKind RK)
static void prettyPrintResources(raw_ostream &OS, const DXILResourceMap &DRM, DXILResourceTypeMap &DRTM)
static StringRef getRCPrefix(dxil::ResourceClass RC)
static StringRef getFormatName(const dxil::ResourceTypeInfo &RI)
dxil pretty printer
dxil pretty DXIL Metadata Pretty Printer
static StringRef getRCName(dxil::ResourceClass RC)
DXIL Resource Implicit Binding
std::string Name
uint64_t Size
This header defines various interfaces for pass management in LLVM.
ModuleAnalysisManager MAM
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition: PassSupport.h:42
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:44
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:39
raw_pwrite_stream & OS
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:255
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:412
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
void setPreservesAll()
Set by analyses that do not transform their input at all.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &)
Root of the metadata hierarchy.
Definition: Metadata.h:63
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:255
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
A set of analyses that are preserved following a run of a transformation pass.
Definition: Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: Analysis.h:118
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
LLVM_ABI std::string upper() const
Convert the given ASCII string to uppercase.
Definition: StringRef.cpp:117
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
dxil::ResourceClass getResourceClass() const
Definition: DXILResource.h:324
LLVM_ABI bool isSampler() const
LLVM_ABI bool isTyped() const
LLVM_ABI bool isCBuffer() const
LLVM_ABI TypedInfo getTyped() const
LLVM_ABI bool isStruct() const
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
virtual void format(raw_ostream &S, StringRef Options)=0
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
ResourceKind
The kind of resource for an SRV or UAV resource.
Definition: DXILABI.h:35
ResourceClass
Definition: DXILABI.h:26
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
ModulePass * createDXILPrettyPrinterLegacyPass(raw_ostream &OS)
Pass to pretty print DXIL metadata.