[llvm] c861ea8 - Generate DXIL Shader hash

Chris Bieneman via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 7 13:26:39 PST 2022


Author: Chris Bieneman
Date: 2022-12-07T15:22:55-06:00
New Revision: c861ea8736bd8e624f8de6ab9ace90994744fa54

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

LOG: Generate DXIL Shader hash

DXIL shader bitcode is hashed and the hash is placed into the final
output object file in its own data part.

This change modifies the DXContainerGlobals pass to compute the shader
hash (just an MD5 of the bitcode) and put the shader hash data into a
global for the HASH part.

This also sets the hash flag as appropriate for if the hashed shader
contained debug information. There is additional handling required to
get debug information in shaders working correctly with our tooling,
but that will be addressed in subsequent patches.

Reviewed By: python3kgae

Differential Revision: https://reviews.llvm.org/D139357

Added: 
    llvm/test/CodeGen/DirectX/ContainerData/DebugShaderHash.ll
    llvm/test/CodeGen/DirectX/ContainerData/ShaderHash.ll

Modified: 
    llvm/lib/Target/DirectX/DXContainerGlobals.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
index 1a20a158e674a..a75c79a71bcb1 100644
--- a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
+++ b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
@@ -13,10 +13,12 @@
 #include "DXILShaderFlags.h"
 #include "DirectX.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/DXContainer.h"
 #include "llvm/CodeGen/Passes.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/InitializePasses.h"
 #include "llvm/Pass.h"
+#include "llvm/Support/MD5.h"
 #include "llvm/Transforms/Utils/ModuleUtils.h"
 
 using namespace llvm;
@@ -25,6 +27,9 @@ using namespace llvm::dxil;
 namespace {
 class DXContainerGlobals : public llvm::ModulePass {
 
+  GlobalVariable *getShaderFlags(Module &M);
+  GlobalVariable *computeShaderHash(Module &M);
+
 public:
   static char ID; // Pass identification, replacement for typeid
   DXContainerGlobals() : ModulePass(ID) {
@@ -46,6 +51,15 @@ class DXContainerGlobals : public llvm::ModulePass {
 } // namespace
 
 bool DXContainerGlobals::runOnModule(Module &M) {
+  llvm::SmallVector<GlobalValue *> Globals;
+  Globals.push_back(getShaderFlags(M));
+  Globals.push_back(computeShaderHash(M));
+
+  appendToCompilerUsed(M, Globals);
+  return true;
+}
+
+GlobalVariable *DXContainerGlobals::getShaderFlags(Module &M) {
   const uint64_t Flags =
       (uint64_t)(getAnalysis<ShaderFlagsAnalysisWrapper>().getShaderFlags());
 
@@ -55,8 +69,35 @@ bool DXContainerGlobals::runOnModule(Module &M) {
                                       FlagsConstant, "dx.sfi0");
   GV->setSection("SFI0");
   GV->setAlignment(Align(4));
-  appendToCompilerUsed(M, {GV});
-  return true;
+  return GV;
+}
+
+GlobalVariable *DXContainerGlobals::computeShaderHash(Module &M) {
+  auto *DXILConstant =
+      cast<ConstantDataArray>(M.getNamedGlobal("dx.dxil")->getInitializer());
+  MD5 Digest;
+  Digest.update(DXILConstant->getRawDataValues());
+  MD5::MD5Result Result = Digest.final();
+
+  dxbc::ShaderHash HashData = {0, {0}};
+  // The Hash's IncludesSource flag gets set whenever the hashed shader includes
+  // debug information.
+  if (M.debug_compile_units_begin() != M.debug_compile_units_end())
+    HashData.Flags = static_cast<uint32_t>(dxbc::HashFlags::IncludesSource);
+
+  memcpy(reinterpret_cast<void *>(&HashData.Digest), Result.data(), 16);
+  if (sys::IsBigEndianHost)
+    HashData.swapBytes();
+  StringRef Data(reinterpret_cast<char *>(&HashData), sizeof(dxbc::ShaderHash));
+
+  Constant *ModuleConstant =
+      ConstantDataArray::get(M.getContext(), arrayRefFromStringRef(Data));
+  auto *GV = new llvm::GlobalVariable(M, ModuleConstant->getType(), true,
+                                      GlobalValue::PrivateLinkage,
+                                      ModuleConstant, "dx.hash");
+  GV->setSection("HASH");
+  GV->setAlignment(Align(4));
+  return GV;
 }
 
 char DXContainerGlobals::ID = 0;

diff  --git a/llvm/test/CodeGen/DirectX/ContainerData/DebugShaderHash.ll b/llvm/test/CodeGen/DirectX/ContainerData/DebugShaderHash.ll
new file mode 100644
index 0000000000000..8e69242be771c
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/ContainerData/DebugShaderHash.ll
@@ -0,0 +1,25 @@
+; RUN: llc %s --filetype=asm -o - | FileCheck %s
+; RUN: llc %s --filetype=obj -o - | obj2yaml | FileCheck %s --check-prefix=DXC
+target triple = "dxil-unknown-shadermodel6.5-library"
+
+; CHECK: @dx.hash = private constant [20 x i8] c"\01\00\00\00{{.*}}", section "HASH", align 4
+
+define i32 @add(i32 %a, i32 %b) {
+  %sum = add i32 %a, %b
+  ret i32 %sum
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Some Compiler", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "hlsl.hlsl", directory: "/some-path")
+!2 = !{}
+!3 = !{i32 7, !"Dwarf Version", i32 2}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+
+; DXC: - Name:            HASH
+; DXC:   Size:            28
+; DXC:   Hash:
+; DXC:     IncludesSource:  true
+; DXC:     Digest:          [ 

diff  --git a/llvm/test/CodeGen/DirectX/ContainerData/ShaderHash.ll b/llvm/test/CodeGen/DirectX/ContainerData/ShaderHash.ll
new file mode 100644
index 0000000000000..327d3557dede5
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/ContainerData/ShaderHash.ll
@@ -0,0 +1,16 @@
+; RUN: llc %s --filetype=asm -o - | FileCheck %s
+; RUN: llc %s --filetype=obj -o - | obj2yaml | FileCheck %s --check-prefix=DXC
+target triple = "dxil-unknown-shadermodel6.5-library"
+
+; CHECK: @dx.hash = private constant [20 x i8] c"\00\00\00\00{{.*}}", section "HASH", align 4
+
+define i32 @add(i32 %a, i32 %b) {
+  %sum = add i32 %a, %b
+  ret i32 %sum
+}
+
+; DXC: - Name:            HASH
+; DXC:   Size:            28
+; DXC:   Hash:
+; DXC:     IncludesSource:  false
+; DXC:     Digest:          [ 


        


More information about the llvm-commits mailing list