LLVM 20.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"
11#include "DirectX.h"
12#include "llvm/ADT/StringRef.h"
14#include "llvm/IR/PassManager.h"
16#include "llvm/Pass.h"
20
21using namespace llvm;
22
24 switch (RC) {
25 case dxil::ResourceClass::SRV:
26 return "SRV";
27 case dxil::ResourceClass::UAV:
28 return "UAV";
29 case dxil::ResourceClass::CBuffer:
30 return "cbuffer";
31 case dxil::ResourceClass::Sampler:
32 return "sampler";
33 }
34 llvm_unreachable("covered switch");
35}
36
38 switch (RC) {
39 case dxil::ResourceClass::SRV:
40 return "t";
41 case dxil::ResourceClass::UAV:
42 return "u";
43 case dxil::ResourceClass::CBuffer:
44 return "cb";
45 case dxil::ResourceClass::Sampler:
46 return "s";
47 }
48 llvm_unreachable("covered switch");
49}
50
52 if (RI.isTyped()) {
53 switch (RI.getTyped().ElementTy) {
54 case dxil::ElementType::I1:
55 return "i1";
56 case dxil::ElementType::I16:
57 return "i16";
58 case dxil::ElementType::U16:
59 return "u16";
60 case dxil::ElementType::I32:
61 return "i32";
62 case dxil::ElementType::U32:
63 return "u32";
64 case dxil::ElementType::I64:
65 return "i64";
66 case dxil::ElementType::U64:
67 return "u64";
68 case dxil::ElementType::F16:
69 return "f16";
70 case dxil::ElementType::F32:
71 return "f32";
72 case dxil::ElementType::F64:
73 return "f64";
74 case dxil::ElementType::SNormF16:
75 return "snorm_f16";
76 case dxil::ElementType::UNormF16:
77 return "unorm_f16";
78 case dxil::ElementType::SNormF32:
79 return "snorm_f32";
80 case dxil::ElementType::UNormF32:
81 return "unorm_f32";
82 case dxil::ElementType::SNormF64:
83 return "snorm_f64";
84 case dxil::ElementType::UNormF64:
85 return "unorm_f64";
86 case dxil::ElementType::PackedS8x32:
87 return "p32i8";
88 case dxil::ElementType::PackedU8x32:
89 return "p32u8";
90 case dxil::ElementType::Invalid:
91 llvm_unreachable("Invalid ElementType");
92 }
93 llvm_unreachable("Unhandled ElementType");
94 } else if (RI.isStruct())
95 return "struct";
96 else if (RI.isCBuffer() || RI.isSampler())
97 return "NA";
98 return "byte";
99}
100
102 switch (RK) {
103 case dxil::ResourceKind::Texture1D:
104 return "1d";
105 case dxil::ResourceKind::Texture2D:
106 return "2d";
107 case dxil::ResourceKind::Texture3D:
108 return "3d";
109 case dxil::ResourceKind::TextureCube:
110 return "cube";
111 case dxil::ResourceKind::Texture1DArray:
112 return "1darray";
113 case dxil::ResourceKind::Texture2DArray:
114 return "2darray";
115 case dxil::ResourceKind::TextureCubeArray:
116 return "cubearray";
117 case dxil::ResourceKind::TBuffer:
118 return "tbuffer";
119 case dxil::ResourceKind::FeedbackTexture2D:
120 return "fbtex2d";
121 case dxil::ResourceKind::FeedbackTexture2DArray:
122 return "fbtex2darray";
123 case dxil::ResourceKind::Texture2DMS:
124 return "2dMS";
125 case dxil::ResourceKind::Texture2DMSArray:
126 return "2darrayMS";
127 case dxil::ResourceKind::Invalid:
128 case dxil::ResourceKind::NumEntries:
129 case dxil::ResourceKind::CBuffer:
130 case dxil::ResourceKind::RawBuffer:
131 case dxil::ResourceKind::Sampler:
132 case dxil::ResourceKind::StructuredBuffer:
133 case dxil::ResourceKind::TypedBuffer:
134 case dxil::ResourceKind::RTAccelerationStructure:
135 llvm_unreachable("Invalid ResourceKind for texture");
136 }
137 llvm_unreachable("Unhandled ResourceKind");
138}
139
140namespace {
141struct FormatResourceDimension
142 : public llvm::FormatAdapter<const dxil::ResourceTypeInfo &> {
143 explicit FormatResourceDimension(const dxil::ResourceTypeInfo &RI)
144 : llvm::FormatAdapter<const dxil::ResourceTypeInfo &>(RI) {}
145
146 void format(llvm::raw_ostream &OS, StringRef Style) override {
147 dxil::ResourceKind RK = Item.getResourceKind();
148 switch (RK) {
149 default: {
150 OS << getTextureDimName(RK);
151 if (Item.isMultiSample())
152 OS << Item.getMultiSampleCount();
153 break;
154 }
157 if (!Item.isUAV())
158 OS << "r/o";
159 else if (Item.getUAV().HasCounter)
160 OS << "r/w+cnt";
161 else
162 OS << "r/w";
163 break;
165 OS << "buf";
166 break;
168 // TODO: dxc would print "ras" here. Can/should this happen?
169 llvm_unreachable("RTAccelerationStructure printing is not implemented");
170 }
171 }
172};
173
174struct FormatBindingID
175 : public llvm::FormatAdapter<const dxil::ResourceBindingInfo &> {
177
178 explicit FormatBindingID(const dxil::ResourceBindingInfo &RBI,
179 const dxil::ResourceTypeInfo &RTI)
180 : llvm::FormatAdapter<const dxil::ResourceBindingInfo &>(RBI),
181 RC(RTI.getResourceClass()) {}
182
183 void format(llvm::raw_ostream &OS, StringRef Style) override {
184 OS << getRCPrefix(RC).upper() << Item.getBinding().RecordID;
185 }
186};
187
188struct FormatBindingLocation
189 : public llvm::FormatAdapter<const dxil::ResourceBindingInfo &> {
191
192 explicit FormatBindingLocation(const dxil::ResourceBindingInfo &RBI,
193 const dxil::ResourceTypeInfo &RTI)
194 : llvm::FormatAdapter<const dxil::ResourceBindingInfo &>(RBI),
195 RC(RTI.getResourceClass()) {}
196
197 void format(llvm::raw_ostream &OS, StringRef Style) override {
198 const auto &Binding = Item.getBinding();
199 OS << getRCPrefix(RC) << Binding.LowerBound;
200 if (Binding.Space)
201 OS << ",space" << Binding.Space;
202 }
203};
204
205struct FormatBindingSize
206 : public llvm::FormatAdapter<const dxil::ResourceBindingInfo &> {
207 explicit FormatBindingSize(const dxil::ResourceBindingInfo &RI)
208 : llvm::FormatAdapter<const dxil::ResourceBindingInfo &>(RI) {}
209
210 void format(llvm::raw_ostream &OS, StringRef Style) override {
211 uint32_t Size = Item.getBinding().Size;
212 if (Size == std::numeric_limits<uint32_t>::max())
213 OS << "unbounded";
214 else
215 OS << Size;
216 }
217};
218
219} // namespace
220
223 const dxil::Resources &MDResources) {
224 // Column widths are arbitrary but match the widths DXC uses.
225 OS << ";\n; Resource Bindings:\n;\n";
226 OS << formatv("; {0,-30} {1,10} {2,7} {3,11} {4,7} {5,14} {6,9}\n", "Name",
227 "Type", "Format", "Dim", "ID", "HLSL Bind", "Count");
228 OS << formatv(
229 "; {0,-+30} {1,-+10} {2,-+7} {3,-+11} {4,-+7} {5,-+14} {6,-+9}\n", "", "",
230 "", "", "", "", "");
231
232 // TODO: Do we want to sort these by binding or something like that?
233 for (const dxil::ResourceBindingInfo &RBI : DBM) {
234 const dxil::ResourceTypeInfo &RTI = DRTM[RBI.getHandleTy()];
235
237 assert((RC != dxil::ResourceClass::CBuffer || !MDResources.hasCBuffers()) &&
238 "Old and new cbuffer representations can't coexist");
239 assert((RC != dxil::ResourceClass::UAV || !MDResources.hasUAVs()) &&
240 "Old and new UAV representations can't coexist");
241
242 StringRef Name(RBI.getName());
244 StringRef Format(getFormatName(RTI));
245 FormatResourceDimension Dim(RTI);
246 FormatBindingID ID(RBI, RTI);
247 FormatBindingLocation Bind(RBI, RTI);
248 FormatBindingSize Count(RBI);
249 OS << formatv("; {0,-30} {1,10} {2,7} {3,11} {4,7} {5,14} {6,9}\n", Name,
250 Type, Format, Dim, ID, Bind, Count);
251 }
252
253 if (MDResources.hasCBuffers())
254 MDResources.printCBuffers(OS);
255 if (MDResources.hasUAVs())
256 MDResources.printUAVs(OS);
257
258 OS << ";\n";
259}
260
265 const dxil::Resources &MDResources = MAM.getResult<DXILResourceMDAnalysis>(M);
266 prettyPrintResources(OS, DBM, DRTM, MDResources);
267 return PreservedAnalyses::all();
268}
269
270namespace {
271class DXILPrettyPrinterLegacy : public llvm::ModulePass {
272 raw_ostream &OS; // raw_ostream to print to.
273
274public:
275 static char ID;
276 DXILPrettyPrinterLegacy() : ModulePass(ID), OS(dbgs()) {
278 }
279
280 explicit DXILPrettyPrinterLegacy(raw_ostream &O) : ModulePass(ID), OS(O) {
282 }
283
284 StringRef getPassName() const override {
285 return "DXIL Metadata Pretty Printer";
286 }
287
288 bool runOnModule(Module &M) override;
289 void getAnalysisUsage(AnalysisUsage &AU) const override {
290 AU.setPreservesAll();
294 }
295};
296} // namespace
297
298char DXILPrettyPrinterLegacy::ID = 0;
299INITIALIZE_PASS_BEGIN(DXILPrettyPrinterLegacy, "dxil-pretty-printer",
300 "DXIL Metadata Pretty Printer", true, true)
304INITIALIZE_PASS_END(DXILPrettyPrinterLegacy, "dxil-pretty-printer",
305 "DXIL Metadata Pretty Printer", true, true)
306
307bool DXILPrettyPrinterLegacy::runOnModule(Module &M) {
308 const DXILBindingMap &DBM =
309 getAnalysis<DXILResourceBindingWrapperPass>().getBindingMap();
310 DXILResourceTypeMap &DRTM =
311 getAnalysis<DXILResourceTypeWrapperPass>().getResourceTypeMap();
312 dxil::Resources &Res = getAnalysis<DXILResourceMDWrapper>().getDXILResource();
313 prettyPrintResources(OS, DBM, DRTM, Res);
314 return false;
315}
316
318 return new DXILPrettyPrinterLegacy(OS);
319}
aarch64 promote const
basic Basic Alias true
static void prettyPrintResources(raw_ostream &OS, const DXILBindingMap &DBM, DXILResourceTypeMap &DRTM, const dxil::Resources &MDResources)
static StringRef getTextureDimName(dxil::ResourceKind RK)
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)
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:55
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:57
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:52
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:253
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:410
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 &)
Analysis pass that exposes the DXILResource for a module.
The legacy pass manager's analysis pass to compute DXIL resource information.
Root of the metadata hierarchy.
Definition: Metadata.h:62
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:251
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
A set of analyses that are preserved following a run of a transformation pass.
Definition: Analysis.h:111
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: Analysis.h:117
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
std::string upper() const
Convert the given ASCII string to uppercase.
Definition: StringRef.cpp:118
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:294
bool hasUAVs() const
Definition: DXILResource.h:121
void printUAVs(raw_ostream &OS) const
void printCBuffers(raw_ostream &OS) const
bool hasCBuffers() const
Definition: DXILResource.h:124
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
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:34
ResourceClass
Definition: DXILABI.h:25
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
void initializeDXILPrettyPrinterLegacyPass(PassRegistry &)
Initializer for DXILPrettyPrinter.
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
ModulePass * createDXILPrettyPrinterLegacyPass(raw_ostream &OS)
Pass to pretty print DXIL metadata.