[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
This commit is contained in:
Chris Bieneman 2022-05-10 14:58:01 -05:00
parent 41778e3dc5
commit d401a99306
6 changed files with 63 additions and 0 deletions

View File

@ -14,4 +14,5 @@ add_llvm_component_library(LLVMDXILBitWriter
MC
Object
Support
TransformUtils
)

View File

@ -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 @@ public:
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(); }

View File

@ -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

View File

@ -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 &);

View File

@ -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:

View File

@ -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"