Skip to content

Commit daa7923

Browse files
authored
[DirectX] Implement metadata lowering for resources
Generate metadata from target extension type based resources. Part of #91366 Pull Request: #104447
1 parent 79154a9 commit daa7923

File tree

5 files changed

+95
-10
lines changed

5 files changed

+95
-10
lines changed

llvm/include/llvm/Analysis/DXILResource.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,46 @@ class DXILResourceMap {
280280
: (Resources.begin() + Pos->second);
281281
}
282282

283+
iterator srv_begin() { return begin(); }
284+
const_iterator srv_begin() const { return begin(); }
285+
iterator srv_end() { return begin() + FirstUAV; }
286+
const_iterator srv_end() const { return begin() + FirstUAV; }
287+
iterator_range<iterator> srvs() { return make_range(srv_begin(), srv_end()); }
288+
iterator_range<const_iterator> srvs() const {
289+
return make_range(srv_begin(), srv_end());
290+
}
291+
292+
iterator uav_begin() { return begin() + FirstUAV; }
293+
const_iterator uav_begin() const { return begin() + FirstUAV; }
294+
iterator uav_end() { return begin() + FirstCBuffer; }
295+
const_iterator uav_end() const { return begin() + FirstCBuffer; }
296+
iterator_range<iterator> uavs() { return make_range(uav_begin(), uav_end()); }
297+
iterator_range<const_iterator> uavs() const {
298+
return make_range(uav_begin(), uav_end());
299+
}
300+
301+
iterator cbuffer_begin() { return begin() + FirstCBuffer; }
302+
const_iterator cbuffer_begin() const { return begin() + FirstCBuffer; }
303+
iterator cbuffer_end() { return begin() + FirstSampler; }
304+
const_iterator cbuffer_end() const { return begin() + FirstSampler; }
305+
iterator_range<iterator> cbuffers() {
306+
return make_range(cbuffer_begin(), cbuffer_end());
307+
}
308+
iterator_range<const_iterator> cbuffers() const {
309+
return make_range(cbuffer_begin(), cbuffer_end());
310+
}
311+
312+
iterator sampler_begin() { return begin() + FirstSampler; }
313+
const_iterator sampler_begin() const { return begin() + FirstSampler; }
314+
iterator sampler_end() { return end(); }
315+
const_iterator sampler_end() const { return end(); }
316+
iterator_range<iterator> samplers() {
317+
return make_range(sampler_begin(), sampler_end());
318+
}
319+
iterator_range<const_iterator> samplers() const {
320+
return make_range(sampler_begin(), sampler_end());
321+
}
322+
283323
void print(raw_ostream &OS) const;
284324
};
285325

llvm/lib/Target/DirectX/DXILMetadata.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,11 @@ void dxil::createEntryMD(Module &M, const uint64_t ShaderFlags) {
284284
EntryList.emplace_back(&F);
285285
}
286286

287+
// If there are no entries, do nothing. This is mostly to allow for writing
288+
// tests with no actual entry functions.
289+
if (EntryList.empty())
290+
return;
291+
287292
auto &Ctx = M.getContext();
288293
// FIXME: generate metadata for resource.
289294
// See https://github.com/llvm/llvm-project/issues/57926.

llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,27 +13,45 @@
1313
#include "DXILShaderFlags.h"
1414
#include "DirectX.h"
1515
#include "llvm/ADT/StringSet.h"
16+
#include "llvm/Analysis/DXILResource.h"
1617
#include "llvm/IR/Constants.h"
1718
#include "llvm/IR/Metadata.h"
1819
#include "llvm/IR/Module.h"
20+
#include "llvm/InitializePasses.h"
1921
#include "llvm/Pass.h"
2022
#include "llvm/TargetParser/Triple.h"
2123

2224
using namespace llvm;
2325
using namespace llvm::dxil;
2426

25-
static void emitResourceMetadata(Module &M,
27+
static void emitResourceMetadata(Module &M, const DXILResourceMap &DRM,
2628
const dxil::Resources &MDResources) {
27-
Metadata *SRVMD = nullptr, *UAVMD = nullptr, *CBufMD = nullptr,
28-
*SmpMD = nullptr;
29-
bool HasResources = false;
29+
LLVMContext &Context = M.getContext();
30+
31+
SmallVector<Metadata *> SRVs, UAVs, CBufs, Smps;
32+
for (const ResourceInfo &RI : DRM.srvs())
33+
SRVs.push_back(RI.getAsMetadata(Context));
34+
for (const ResourceInfo &RI : DRM.uavs())
35+
UAVs.push_back(RI.getAsMetadata(Context));
36+
for (const ResourceInfo &RI : DRM.cbuffers())
37+
CBufs.push_back(RI.getAsMetadata(Context));
38+
for (const ResourceInfo &RI : DRM.samplers())
39+
Smps.push_back(RI.getAsMetadata(Context));
40+
41+
Metadata *SRVMD = SRVs.empty() ? nullptr : MDNode::get(Context, SRVs);
42+
Metadata *UAVMD = UAVs.empty() ? nullptr : MDNode::get(Context, UAVs);
43+
Metadata *CBufMD = CBufs.empty() ? nullptr : MDNode::get(Context, CBufs);
44+
Metadata *SmpMD = Smps.empty() ? nullptr : MDNode::get(Context, Smps);
45+
bool HasResources = !DRM.empty();
3046

3147
if (MDResources.hasUAVs()) {
48+
assert(!UAVMD && "Old and new UAV representations can't coexist");
3249
UAVMD = MDResources.writeUAVs(M);
3350
HasResources = true;
3451
}
3552

3653
if (MDResources.hasCBuffers()) {
54+
assert(!CBufMD && "Old and new cbuffer representations can't coexist");
3755
CBufMD = MDResources.writeCBuffers(M);
3856
HasResources = true;
3957
}
@@ -46,26 +64,28 @@ static void emitResourceMetadata(Module &M,
4664
MDNode::get(M.getContext(), {SRVMD, UAVMD, CBufMD, SmpMD}));
4765
}
4866

49-
static void translateMetadata(Module &M, const dxil::Resources &MDResources,
67+
static void translateMetadata(Module &M, const DXILResourceMap &DRM,
68+
const dxil::Resources &MDResources,
5069
const ComputedShaderFlags &ShaderFlags) {
5170
dxil::ValidatorVersionMD ValVerMD(M);
5271
if (ValVerMD.isEmpty())
5372
ValVerMD.update(VersionTuple(1, 0));
5473
dxil::createShaderModelMD(M);
5574
dxil::createDXILVersionMD(M);
5675

57-
emitResourceMetadata(M, MDResources);
76+
emitResourceMetadata(M, DRM, MDResources);
5877

5978
dxil::createEntryMD(M, static_cast<uint64_t>(ShaderFlags));
6079
}
6180

6281
PreservedAnalyses DXILTranslateMetadata::run(Module &M,
6382
ModuleAnalysisManager &MAM) {
83+
const DXILResourceMap &DRM = MAM.getResult<DXILResourceAnalysis>(M);
6484
const dxil::Resources &MDResources = MAM.getResult<DXILResourceMDAnalysis>(M);
6585
const ComputedShaderFlags &ShaderFlags =
6686
MAM.getResult<ShaderFlagsAnalysis>(M);
6787

68-
translateMetadata(M, MDResources, ShaderFlags);
88+
translateMetadata(M, DRM, MDResources, ShaderFlags);
6989

7090
return PreservedAnalyses::all();
7191
}
@@ -80,17 +100,20 @@ class DXILTranslateMetadataLegacy : public ModulePass {
80100

81101
void getAnalysisUsage(AnalysisUsage &AU) const override {
82102
AU.setPreservesAll();
103+
AU.addRequired<DXILResourceWrapperPass>();
83104
AU.addRequired<DXILResourceMDWrapper>();
84105
AU.addRequired<ShaderFlagsAnalysisWrapper>();
85106
}
86107

87108
bool runOnModule(Module &M) override {
109+
const DXILResourceMap &DRM =
110+
getAnalysis<DXILResourceWrapperPass>().getResourceMap();
88111
const dxil::Resources &MDResources =
89112
getAnalysis<DXILResourceMDWrapper>().getDXILResource();
90113
const ComputedShaderFlags &ShaderFlags =
91114
getAnalysis<ShaderFlagsAnalysisWrapper>().getShaderFlags();
92115

93-
translateMetadata(M, MDResources, ShaderFlags);
116+
translateMetadata(M, DRM, MDResources, ShaderFlags);
94117
return true;
95118
}
96119
};
@@ -105,6 +128,7 @@ ModulePass *llvm::createDXILTranslateMetadataLegacyPass() {
105128

106129
INITIALIZE_PASS_BEGIN(DXILTranslateMetadataLegacy, "dxil-translate-metadata",
107130
"DXIL Translate Metadata", false, false)
131+
INITIALIZE_PASS_DEPENDENCY(DXILResourceWrapperPass)
108132
INITIALIZE_PASS_DEPENDENCY(DXILResourceMDWrapper)
109133
INITIALIZE_PASS_DEPENDENCY(ShaderFlagsAnalysisWrapper)
110134
INITIALIZE_PASS_END(DXILTranslateMetadataLegacy, "dxil-translate-metadata",

llvm/test/CodeGen/DirectX/CreateHandle.ll

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: opt -S -dxil-op-lower %s | FileCheck %s
1+
; RUN: opt -S -passes=dxil-op-lower,dxil-translate-metadata %s | FileCheck %s
22

33
target triple = "dxil-pc-shadermodel6.0-compute"
44

@@ -50,4 +50,12 @@ define void @test_buffers() {
5050
ret void
5151
}
5252

53+
; Just check that we have the right types and number of metadata nodes, the
54+
; contents of the metadata are tested elsewhere.
55+
;
56+
; CHECK: !dx.resources = !{[[RESMD:![0-9]+]]}
57+
; CHECK: [[RESMD]] = !{[[SRVMD:![0-9]+]], [[UAVMD:![0-9]+]], null, null}
58+
; CHECK-DAG: [[SRVMD]] = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}}
59+
; CHECK-DAG: [[UAVMD]] = !{!{{[0-9]+}}, !{{[0-9]+}}}
60+
5361
attributes #0 = { nocallback nofree nosync nounwind willreturn memory(none) }

llvm/test/CodeGen/DirectX/CreateHandleFromBinding.ll

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: opt -S -dxil-op-lower %s | FileCheck %s
1+
; RUN: opt -S -passes=dxil-op-lower,dxil-translate-metadata %s | FileCheck %s
22

33
target triple = "dxil-pc-shadermodel6.6-compute"
44

@@ -55,4 +55,12 @@ define void @test_bindings() {
5555
ret void
5656
}
5757

58+
; Just check that we have the right types and number of metadata nodes, the
59+
; contents of the metadata are tested elsewhere.
60+
;
61+
; CHECK: !dx.resources = !{[[RESMD:![0-9]+]]}
62+
; CHECK: [[RESMD]] = !{[[SRVMD:![0-9]+]], [[UAVMD:![0-9]+]], null, null}
63+
; CHECK-DAG: [[SRVMD]] = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}}
64+
; CHECK-DAG: [[UAVMD]] = !{!{{[0-9]+}}, !{{[0-9]+}}}
65+
5866
attributes #0 = { nocallback nofree nosync nounwind willreturn memory(none) }

0 commit comments

Comments
 (0)