[llvm] d401a99 - [DirectX] Embed DXIL in LLVM Module

Chris Bieneman via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 6 13:04:35 PDT 2022


Author: Chris Bieneman
Date: 2022-06-06T15:04:26-05:00
New Revision: d401a9930628f38f773e40c1d6ad33942b10e8cf

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

LOG: [DirectX] Embed DXIL in LLVM Module

At the end of the codegen pipeline for DXIL we will emit the DXIL into
a global variable in the Module annotated for the "DXIL" section.

This will be used by the MCDXContainerStreamer to emit the DXIL into a
DXContainer DXIL part.

Other parts of the DXContainer will be constructed similarly by
serializing their values into GlobalVariables.

This will allow DXIL to flow into DXContainers through the normal
MCStreamer flow used in the MC layer.

Depends on D122270

Reviewed By: kuhar

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

Added: 
    llvm/test/CodeGen/DirectX/embed-dxil.ll

Modified: 
    llvm/lib/Target/DirectX/DXILWriter/CMakeLists.txt
    llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.cpp
    llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.h
    llvm/lib/Target/DirectX/DirectX.h
    llvm/lib/Target/DirectX/DirectXTargetMachine.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/DirectX/DXILWriter/CMakeLists.txt b/llvm/lib/Target/DirectX/DXILWriter/CMakeLists.txt
index 3a48942239bc4..0e56902c97c91 100644
--- a/llvm/lib/Target/DirectX/DXILWriter/CMakeLists.txt
+++ b/llvm/lib/Target/DirectX/DXILWriter/CMakeLists.txt
@@ -14,4 +14,5 @@ add_llvm_component_library(LLVMDXILBitWriter
   MC
   Object
   Support
+  TransformUtils
   )

diff  --git a/llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.cpp b/llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.cpp
index a60abfd3d7013..c1f9f4aec6725 100644
--- a/llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.cpp
+++ b/llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.cpp
@@ -15,10 +15,14 @@
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Analysis/ModuleSummaryAnalysis.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/GlobalVariable.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/PassManager.h"
 #include "llvm/InitializePasses.h"
 #include "llvm/Pass.h"
+#include "llvm/Support/Alignment.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
 
 using namespace llvm;
 using namespace llvm::dxil;
@@ -47,6 +51,36 @@ class WriteDXILPass : public llvm::ModulePass {
     AU.setPreservesAll();
   }
 };
+
+class EmbedDXILPass : public llvm::ModulePass {
+public:
+  static char ID; // Pass identification, replacement for typeid
+  EmbedDXILPass() : ModulePass(ID) {
+    initializeEmbedDXILPassPass(*PassRegistry::getPassRegistry());
+  }
+
+  StringRef getPassName() const override { return "DXIL Embedder"; }
+
+  bool runOnModule(Module &M) override {
+    std::string Data;
+    llvm::raw_string_ostream OS(Data);
+    WriteDXILToFile(M, OS);
+
+    Constant *ModuleConstant =
+        ConstantDataArray::get(M.getContext(), arrayRefFromStringRef(Data));
+    auto *GV = new llvm::GlobalVariable(M, ModuleConstant->getType(), true,
+                                        GlobalValue::PrivateLinkage,
+                                        ModuleConstant, "dx.dxil");
+    GV->setSection("DXIL");
+    GV->setAlignment(Align(4));
+    appendToCompilerUsed(M, {GV});
+    return true;
+  }
+
+  void getAnalysisUsage(AnalysisUsage &AU) const override {
+    AU.setPreservesAll();
+  }
+};
 } // namespace
 
 char WriteDXILPass::ID = 0;
@@ -59,3 +93,8 @@ INITIALIZE_PASS_END(WriteDXILPass, "write-bitcode", "Write Bitcode", false,
 ModulePass *llvm::createDXILWriterPass(raw_ostream &Str) {
   return new WriteDXILPass(Str);
 }
+
+char EmbedDXILPass::ID = 0;
+INITIALIZE_PASS(EmbedDXILPass, "dxil-embed", "Embed DXIL", false, true)
+
+ModulePass *llvm::createDXILEmbedderPass() { return new EmbedDXILPass(); }

diff  --git a/llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.h b/llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.h
index 612b4c53d3d1f..2c9c12178677b 100644
--- a/llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.h
+++ b/llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.h
@@ -27,6 +27,11 @@ class raw_ostream;
 /// manager.
 ModulePass *createDXILWriterPass(raw_ostream &Str);
 
+/// Create and return a pass that writes the module to a global variable in the
+/// module for later emission in the MCStreamer. Note that this pass is designed
+/// for use with the legacy pass manager because it is run in CodeGen only.
+ModulePass *createDXILEmbedderPass();
+
 } // namespace llvm
 
 #endif

diff  --git a/llvm/lib/Target/DirectX/DirectX.h b/llvm/lib/Target/DirectX/DirectX.h
index 713317df56a2f..3883e4ba46213 100644
--- a/llvm/lib/Target/DirectX/DirectX.h
+++ b/llvm/lib/Target/DirectX/DirectX.h
@@ -18,6 +18,9 @@ class PassRegistry;
 /// Initializer for dxil writer pass
 void initializeWriteDXILPassPass(PassRegistry &);
 
+/// Initializer for dxil embedder pass
+void initializeEmbedDXILPassPass(PassRegistry &);
+
 /// Initializer for DXIL-prepare
 void initializeDXILPrepareModulePass(PassRegistry &);
 

diff  --git a/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp b/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp
index bb61f292b0584..91d9ebb3d6960 100644
--- a/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp
+++ b/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp
@@ -34,6 +34,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeDirectXTarget() {
   RegisterTargetMachine<DirectXTargetMachine> X(getTheDirectXTarget());
   auto *PR = PassRegistry::getPassRegistry();
   initializeDXILPrepareModulePass(*PR);
+  initializeEmbedDXILPassPass(*PR);
   initializeDXILOpLoweringLegacyPass(*PR);
   initializeDXILTranslateMetadataPass(*PR);
 }
@@ -91,6 +92,9 @@ bool DirectXTargetMachine::addPassesToEmitFile(
   PM.add(createDXILTranslateMetadataPass());
   switch (FileType) {
   case CGFT_AssemblyFile:
+    if (TargetPassConfig::willCompleteCodeGenPipeline()) {
+      PM.add(createDXILEmbedderPass());
+    }
     PM.add(createPrintModulePass(Out, "", true));
     break;
   case CGFT_ObjectFile:

diff  --git a/llvm/test/CodeGen/DirectX/embed-dxil.ll b/llvm/test/CodeGen/DirectX/embed-dxil.ll
new file mode 100644
index 0000000000000..f56fefede7fce
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/embed-dxil.ll
@@ -0,0 +1,11 @@
+; RUN: llc %s --filetype=asm -o - | FileCheck %s
+; RUN: opt %s -dxil-embed -S -o - | FileCheck %s
+target triple = "dxil-unknown-unknown"
+
+define i32 @add(i32 %a, i32 %b) {
+  %sum = add i32 %a, %b
+  ret i32 %sum
+}
+
+; CHECK: @dx.dxil = private constant [[BC_TYPE:\[[0-9]+ x i8\]]] c"BC\C0\DE{{[^"]+}}", section "DXIL", align 4
+; CHECK: @llvm.compiler.used = appending global [1 x ptr] [ptr @dx.dxil], section "llvm.metadata"


        


More information about the llvm-commits mailing list