1 //===- DXILWriterPass.cpp - Bitcode writing pass --------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // DXILWriterPass implementation.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "DXILWriterPass.h"
14 #include "DXILBitcodeWriter.h"
15 #include "llvm/ADT/DenseMap.h"
16 #include "llvm/ADT/StringRef.h"
17 #include "llvm/Analysis/ModuleSummaryAnalysis.h"
18 #include "llvm/IR/Constants.h"
19 #include "llvm/IR/GlobalVariable.h"
20 #include "llvm/IR/Module.h"
21 #include "llvm/IR/PassManager.h"
22 #include "llvm/InitializePasses.h"
23 #include "llvm/Pass.h"
24 #include "llvm/Support/Alignment.h"
25 #include "llvm/Transforms/Utils/ModuleUtils.h"
26 
27 using namespace llvm;
28 using namespace llvm::dxil;
29 
30 namespace {
31 class WriteDXILPass : public llvm::ModulePass {
32   raw_ostream &OS; // raw_ostream to print on
33 
34 public:
35   static char ID; // Pass identification, replacement for typeid
WriteDXILPass()36   WriteDXILPass() : ModulePass(ID), OS(dbgs()) {
37     initializeWriteDXILPassPass(*PassRegistry::getPassRegistry());
38   }
39 
WriteDXILPass(raw_ostream & o)40   explicit WriteDXILPass(raw_ostream &o) : ModulePass(ID), OS(o) {
41     initializeWriteDXILPassPass(*PassRegistry::getPassRegistry());
42   }
43 
getPassName() const44   StringRef getPassName() const override { return "Bitcode Writer"; }
45 
runOnModule(Module & M)46   bool runOnModule(Module &M) override {
47     WriteDXILToFile(M, OS);
48     return false;
49   }
getAnalysisUsage(AnalysisUsage & AU) const50   void getAnalysisUsage(AnalysisUsage &AU) const override {
51     AU.setPreservesAll();
52   }
53 };
54 
55 class EmbedDXILPass : public llvm::ModulePass {
56 public:
57   static char ID; // Pass identification, replacement for typeid
EmbedDXILPass()58   EmbedDXILPass() : ModulePass(ID) {
59     initializeEmbedDXILPassPass(*PassRegistry::getPassRegistry());
60   }
61 
getPassName() const62   StringRef getPassName() const override { return "DXIL Embedder"; }
63 
runOnModule(Module & M)64   bool runOnModule(Module &M) override {
65     std::string Data;
66     llvm::raw_string_ostream OS(Data);
67     WriteDXILToFile(M, OS);
68 
69     Constant *ModuleConstant =
70         ConstantDataArray::get(M.getContext(), arrayRefFromStringRef(Data));
71     auto *GV = new llvm::GlobalVariable(M, ModuleConstant->getType(), true,
72                                         GlobalValue::PrivateLinkage,
73                                         ModuleConstant, "dx.dxil");
74     GV->setSection("DXIL");
75     GV->setAlignment(Align(4));
76     appendToCompilerUsed(M, {GV});
77     return true;
78   }
79 
getAnalysisUsage(AnalysisUsage & AU) const80   void getAnalysisUsage(AnalysisUsage &AU) const override {
81     AU.setPreservesAll();
82   }
83 };
84 } // namespace
85 
86 char WriteDXILPass::ID = 0;
87 INITIALIZE_PASS_BEGIN(WriteDXILPass, "write-bitcode", "Write Bitcode", false,
88                       true)
INITIALIZE_PASS_DEPENDENCY(ModuleSummaryIndexWrapperPass)89 INITIALIZE_PASS_DEPENDENCY(ModuleSummaryIndexWrapperPass)
90 INITIALIZE_PASS_END(WriteDXILPass, "write-bitcode", "Write Bitcode", false,
91                     true)
92 
93 ModulePass *llvm::createDXILWriterPass(raw_ostream &Str) {
94   return new WriteDXILPass(Str);
95 }
96 
97 char EmbedDXILPass::ID = 0;
98 INITIALIZE_PASS(EmbedDXILPass, "dxil-embed", "Embed DXIL", false, true)
99 
createDXILEmbedderPass()100 ModulePass *llvm::createDXILEmbedderPass() { return new EmbedDXILPass(); }
101