[llvm] daa7923 - [DirectX] Implement metadata lowering for resources

via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 26 17:19:19 PDT 2024


Author: Justin Bogner
Date: 2024-08-26T17:19:15-07:00
New Revision: daa79232f76c645e38aeffc9074bf0eb5c8010bd

URL: https://github.com/llvm/llvm-project/commit/daa79232f76c645e38aeffc9074bf0eb5c8010bd
DIFF: https://github.com/llvm/llvm-project/commit/daa79232f76c645e38aeffc9074bf0eb5c8010bd.diff

LOG: [DirectX] Implement metadata lowering for resources

Generate metadata from target extension type based resources.

Part of #91366

Pull Request: https://github.com/llvm/llvm-project/pull/104447

Added: 
    

Modified: 
    llvm/include/llvm/Analysis/DXILResource.h
    llvm/lib/Target/DirectX/DXILMetadata.cpp
    llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp
    llvm/test/CodeGen/DirectX/CreateHandle.ll
    llvm/test/CodeGen/DirectX/CreateHandleFromBinding.ll

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Analysis/DXILResource.h b/llvm/include/llvm/Analysis/DXILResource.h
index d9b4e968fe3e97..58db0a93f2f351 100644
--- a/llvm/include/llvm/Analysis/DXILResource.h
+++ b/llvm/include/llvm/Analysis/DXILResource.h
@@ -280,6 +280,46 @@ class DXILResourceMap {
                                 : (Resources.begin() + Pos->second);
   }
 
+  iterator srv_begin() { return begin(); }
+  const_iterator srv_begin() const { return begin(); }
+  iterator srv_end() { return begin() + FirstUAV; }
+  const_iterator srv_end() const { return begin() + FirstUAV; }
+  iterator_range<iterator> srvs() { return make_range(srv_begin(), srv_end()); }
+  iterator_range<const_iterator> srvs() const {
+    return make_range(srv_begin(), srv_end());
+  }
+
+  iterator uav_begin() { return begin() + FirstUAV; }
+  const_iterator uav_begin() const { return begin() + FirstUAV; }
+  iterator uav_end() { return begin() + FirstCBuffer; }
+  const_iterator uav_end() const { return begin() + FirstCBuffer; }
+  iterator_range<iterator> uavs() { return make_range(uav_begin(), uav_end()); }
+  iterator_range<const_iterator> uavs() const {
+    return make_range(uav_begin(), uav_end());
+  }
+
+  iterator cbuffer_begin() { return begin() + FirstCBuffer; }
+  const_iterator cbuffer_begin() const { return begin() + FirstCBuffer; }
+  iterator cbuffer_end() { return begin() + FirstSampler; }
+  const_iterator cbuffer_end() const { return begin() + FirstSampler; }
+  iterator_range<iterator> cbuffers() {
+    return make_range(cbuffer_begin(), cbuffer_end());
+  }
+  iterator_range<const_iterator> cbuffers() const {
+    return make_range(cbuffer_begin(), cbuffer_end());
+  }
+
+  iterator sampler_begin() { return begin() + FirstSampler; }
+  const_iterator sampler_begin() const { return begin() + FirstSampler; }
+  iterator sampler_end() { return end(); }
+  const_iterator sampler_end() const { return end(); }
+  iterator_range<iterator> samplers() {
+    return make_range(sampler_begin(), sampler_end());
+  }
+  iterator_range<const_iterator> samplers() const {
+    return make_range(sampler_begin(), sampler_end());
+  }
+
   void print(raw_ostream &OS) const;
 };
 

diff  --git a/llvm/lib/Target/DirectX/DXILMetadata.cpp b/llvm/lib/Target/DirectX/DXILMetadata.cpp
index ed0434ac98a18b..1f5759c3630135 100644
--- a/llvm/lib/Target/DirectX/DXILMetadata.cpp
+++ b/llvm/lib/Target/DirectX/DXILMetadata.cpp
@@ -284,6 +284,11 @@ void dxil::createEntryMD(Module &M, const uint64_t ShaderFlags) {
     EntryList.emplace_back(&F);
   }
 
+  // If there are no entries, do nothing. This is mostly to allow for writing
+  // tests with no actual entry functions.
+  if (EntryList.empty())
+    return;
+
   auto &Ctx = M.getContext();
   // FIXME: generate metadata for resource.
   // See https://github.com/llvm/llvm-project/issues/57926.

diff  --git a/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp b/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp
index 007af0b46b9f3a..2c6d20112060df 100644
--- a/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp
+++ b/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp
@@ -13,27 +13,45 @@
 #include "DXILShaderFlags.h"
 #include "DirectX.h"
 #include "llvm/ADT/StringSet.h"
+#include "llvm/Analysis/DXILResource.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/Metadata.h"
 #include "llvm/IR/Module.h"
+#include "llvm/InitializePasses.h"
 #include "llvm/Pass.h"
 #include "llvm/TargetParser/Triple.h"
 
 using namespace llvm;
 using namespace llvm::dxil;
 
-static void emitResourceMetadata(Module &M,
+static void emitResourceMetadata(Module &M, const DXILResourceMap &DRM,
                                  const dxil::Resources &MDResources) {
-  Metadata *SRVMD = nullptr, *UAVMD = nullptr, *CBufMD = nullptr,
-           *SmpMD = nullptr;
-  bool HasResources = false;
+  LLVMContext &Context = M.getContext();
+
+  SmallVector<Metadata *> SRVs, UAVs, CBufs, Smps;
+  for (const ResourceInfo &RI : DRM.srvs())
+    SRVs.push_back(RI.getAsMetadata(Context));
+  for (const ResourceInfo &RI : DRM.uavs())
+    UAVs.push_back(RI.getAsMetadata(Context));
+  for (const ResourceInfo &RI : DRM.cbuffers())
+    CBufs.push_back(RI.getAsMetadata(Context));
+  for (const ResourceInfo &RI : DRM.samplers())
+    Smps.push_back(RI.getAsMetadata(Context));
+
+  Metadata *SRVMD = SRVs.empty() ? nullptr : MDNode::get(Context, SRVs);
+  Metadata *UAVMD = UAVs.empty() ? nullptr : MDNode::get(Context, UAVs);
+  Metadata *CBufMD = CBufs.empty() ? nullptr : MDNode::get(Context, CBufs);
+  Metadata *SmpMD = Smps.empty() ? nullptr : MDNode::get(Context, Smps);
+  bool HasResources = !DRM.empty();
 
   if (MDResources.hasUAVs()) {
+    assert(!UAVMD && "Old and new UAV representations can't coexist");
     UAVMD = MDResources.writeUAVs(M);
     HasResources = true;
   }
 
   if (MDResources.hasCBuffers()) {
+    assert(!CBufMD && "Old and new cbuffer representations can't coexist");
     CBufMD = MDResources.writeCBuffers(M);
     HasResources = true;
   }
@@ -46,7 +64,8 @@ static void emitResourceMetadata(Module &M,
       MDNode::get(M.getContext(), {SRVMD, UAVMD, CBufMD, SmpMD}));
 }
 
-static void translateMetadata(Module &M, const dxil::Resources &MDResources,
+static void translateMetadata(Module &M, const DXILResourceMap &DRM,
+                              const dxil::Resources &MDResources,
                               const ComputedShaderFlags &ShaderFlags) {
   dxil::ValidatorVersionMD ValVerMD(M);
   if (ValVerMD.isEmpty())
@@ -54,18 +73,19 @@ static void translateMetadata(Module &M, const dxil::Resources &MDResources,
   dxil::createShaderModelMD(M);
   dxil::createDXILVersionMD(M);
 
-  emitResourceMetadata(M, MDResources);
+  emitResourceMetadata(M, DRM, MDResources);
 
   dxil::createEntryMD(M, static_cast<uint64_t>(ShaderFlags));
 }
 
 PreservedAnalyses DXILTranslateMetadata::run(Module &M,
                                              ModuleAnalysisManager &MAM) {
+  const DXILResourceMap &DRM = MAM.getResult<DXILResourceAnalysis>(M);
   const dxil::Resources &MDResources = MAM.getResult<DXILResourceMDAnalysis>(M);
   const ComputedShaderFlags &ShaderFlags =
       MAM.getResult<ShaderFlagsAnalysis>(M);
 
-  translateMetadata(M, MDResources, ShaderFlags);
+  translateMetadata(M, DRM, MDResources, ShaderFlags);
 
   return PreservedAnalyses::all();
 }
@@ -80,17 +100,20 @@ class DXILTranslateMetadataLegacy : public ModulePass {
 
   void getAnalysisUsage(AnalysisUsage &AU) const override {
     AU.setPreservesAll();
+    AU.addRequired<DXILResourceWrapperPass>();
     AU.addRequired<DXILResourceMDWrapper>();
     AU.addRequired<ShaderFlagsAnalysisWrapper>();
   }
 
   bool runOnModule(Module &M) override {
+    const DXILResourceMap &DRM =
+        getAnalysis<DXILResourceWrapperPass>().getResourceMap();
     const dxil::Resources &MDResources =
         getAnalysis<DXILResourceMDWrapper>().getDXILResource();
     const ComputedShaderFlags &ShaderFlags =
         getAnalysis<ShaderFlagsAnalysisWrapper>().getShaderFlags();
 
-    translateMetadata(M, MDResources, ShaderFlags);
+    translateMetadata(M, DRM, MDResources, ShaderFlags);
     return true;
   }
 };
@@ -105,6 +128,7 @@ ModulePass *llvm::createDXILTranslateMetadataLegacyPass() {
 
 INITIALIZE_PASS_BEGIN(DXILTranslateMetadataLegacy, "dxil-translate-metadata",
                       "DXIL Translate Metadata", false, false)
+INITIALIZE_PASS_DEPENDENCY(DXILResourceWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(DXILResourceMDWrapper)
 INITIALIZE_PASS_DEPENDENCY(ShaderFlagsAnalysisWrapper)
 INITIALIZE_PASS_END(DXILTranslateMetadataLegacy, "dxil-translate-metadata",

diff  --git a/llvm/test/CodeGen/DirectX/CreateHandle.ll b/llvm/test/CodeGen/DirectX/CreateHandle.ll
index 13d59c6caf6c95..55e72e1cb2eb04 100644
--- a/llvm/test/CodeGen/DirectX/CreateHandle.ll
+++ b/llvm/test/CodeGen/DirectX/CreateHandle.ll
@@ -1,4 +1,4 @@
-; RUN: opt -S -dxil-op-lower %s | FileCheck %s
+; RUN: opt -S -passes=dxil-op-lower,dxil-translate-metadata %s | FileCheck %s
 
 target triple = "dxil-pc-shadermodel6.0-compute"
 
@@ -50,4 +50,12 @@ define void @test_buffers() {
   ret void
 }
 
+; Just check that we have the right types and number of metadata nodes, the
+; contents of the metadata are tested elsewhere.
+;
+; CHECK: !dx.resources = !{[[RESMD:![0-9]+]]}
+; CHECK: [[RESMD]] = !{[[SRVMD:![0-9]+]], [[UAVMD:![0-9]+]], null, null}
+; CHECK-DAG: [[SRVMD]] = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}}
+; CHECK-DAG: [[UAVMD]] = !{!{{[0-9]+}}, !{{[0-9]+}}}
+
 attributes #0 = { nocallback nofree nosync nounwind willreturn memory(none) }

diff  --git a/llvm/test/CodeGen/DirectX/CreateHandleFromBinding.ll b/llvm/test/CodeGen/DirectX/CreateHandleFromBinding.ll
index e78a0bf02e4ae3..c8f9f05c351086 100644
--- a/llvm/test/CodeGen/DirectX/CreateHandleFromBinding.ll
+++ b/llvm/test/CodeGen/DirectX/CreateHandleFromBinding.ll
@@ -1,4 +1,4 @@
-; RUN: opt -S -dxil-op-lower %s | FileCheck %s
+; RUN: opt -S -passes=dxil-op-lower,dxil-translate-metadata %s | FileCheck %s
 
 target triple = "dxil-pc-shadermodel6.6-compute"
 
@@ -55,4 +55,12 @@ define void @test_bindings() {
   ret void
 }
 
+; Just check that we have the right types and number of metadata nodes, the
+; contents of the metadata are tested elsewhere.
+;
+; CHECK: !dx.resources = !{[[RESMD:![0-9]+]]}
+; CHECK: [[RESMD]] = !{[[SRVMD:![0-9]+]], [[UAVMD:![0-9]+]], null, null}
+; CHECK-DAG: [[SRVMD]] = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}}
+; CHECK-DAG: [[UAVMD]] = !{!{{[0-9]+}}, !{{[0-9]+}}}
+
 attributes #0 = { nocallback nofree nosync nounwind willreturn memory(none) }


        


More information about the llvm-commits mailing list