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 36 WriteDXILPass() : ModulePass(ID), OS(dbgs()) { 37 initializeWriteDXILPassPass(*PassRegistry::getPassRegistry()); 38 } 39 40 explicit WriteDXILPass(raw_ostream &o) : ModulePass(ID), OS(o) { 41 initializeWriteDXILPassPass(*PassRegistry::getPassRegistry()); 42 } 43 44 StringRef getPassName() const override { return "Bitcode Writer"; } 45 46 bool runOnModule(Module &M) override { 47 WriteDXILToFile(M, OS); 48 return false; 49 } 50 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 58 EmbedDXILPass() : ModulePass(ID) { 59 initializeEmbedDXILPassPass(*PassRegistry::getPassRegistry()); 60 } 61 62 StringRef getPassName() const override { return "DXIL Embedder"; } 63 64 bool runOnModule(Module &M) override { 65 std::string Data; 66 llvm::raw_string_ostream OS(Data); 67 68 const std::string OriginalTriple = M.getTargetTriple(); 69 // Set to DXIL triple when write to bitcode. 70 // Only the output bitcode need to be DXIL triple. 71 M.setTargetTriple("dxil-ms-dx"); 72 73 WriteDXILToFile(M, OS); 74 75 // Recover triple. 76 M.setTargetTriple(OriginalTriple); 77 78 Constant *ModuleConstant = 79 ConstantDataArray::get(M.getContext(), arrayRefFromStringRef(Data)); 80 auto *GV = new llvm::GlobalVariable(M, ModuleConstant->getType(), true, 81 GlobalValue::PrivateLinkage, 82 ModuleConstant, "dx.dxil"); 83 GV->setSection("DXIL"); 84 GV->setAlignment(Align(4)); 85 appendToCompilerUsed(M, {GV}); 86 return true; 87 } 88 89 void getAnalysisUsage(AnalysisUsage &AU) const override { 90 AU.setPreservesAll(); 91 } 92 }; 93 } // namespace 94 95 char WriteDXILPass::ID = 0; 96 INITIALIZE_PASS_BEGIN(WriteDXILPass, "dxil-write-bitcode", "Write Bitcode", 97 false, true) 98 INITIALIZE_PASS_DEPENDENCY(ModuleSummaryIndexWrapperPass) 99 INITIALIZE_PASS_END(WriteDXILPass, "dxil-write-bitcode", "Write Bitcode", false, 100 true) 101 102 ModulePass *llvm::createDXILWriterPass(raw_ostream &Str) { 103 return new WriteDXILPass(Str); 104 } 105 106 char EmbedDXILPass::ID = 0; 107 INITIALIZE_PASS(EmbedDXILPass, "dxil-embed", "Embed DXIL", false, true) 108 109 ModulePass *llvm::createDXILEmbedderPass() { return new EmbedDXILPass(); } 110