1*0b57cec5SDimitry Andric //===- BitcodeWriterPass.cpp - Bitcode writing pass -----------------------===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric //
9*0b57cec5SDimitry Andric // BitcodeWriterPass implementation.
10*0b57cec5SDimitry Andric //
11*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
12*0b57cec5SDimitry Andric 
13*0b57cec5SDimitry Andric #include "llvm/Bitcode/BitcodeWriterPass.h"
14*0b57cec5SDimitry Andric #include "llvm/Analysis/ModuleSummaryAnalysis.h"
15*0b57cec5SDimitry Andric #include "llvm/Bitcode/BitcodeWriter.h"
16*0b57cec5SDimitry Andric #include "llvm/IR/Module.h"
17*0b57cec5SDimitry Andric #include "llvm/IR/PassManager.h"
18*0b57cec5SDimitry Andric #include "llvm/InitializePasses.h"
19*0b57cec5SDimitry Andric #include "llvm/Pass.h"
20*0b57cec5SDimitry Andric using namespace llvm;
21*0b57cec5SDimitry Andric 
run(Module & M,ModuleAnalysisManager & AM)22*0b57cec5SDimitry Andric PreservedAnalyses BitcodeWriterPass::run(Module &M, ModuleAnalysisManager &AM) {
23*0b57cec5SDimitry Andric   const ModuleSummaryIndex *Index =
24*0b57cec5SDimitry Andric       EmitSummaryIndex ? &(AM.getResult<ModuleSummaryIndexAnalysis>(M))
25*0b57cec5SDimitry Andric                        : nullptr;
26*0b57cec5SDimitry Andric   WriteBitcodeToFile(M, OS, ShouldPreserveUseListOrder, Index, EmitModuleHash);
27*0b57cec5SDimitry Andric   return PreservedAnalyses::all();
28*0b57cec5SDimitry Andric }
29*0b57cec5SDimitry Andric 
30*0b57cec5SDimitry Andric namespace {
31*0b57cec5SDimitry Andric   class WriteBitcodePass : public ModulePass {
32*0b57cec5SDimitry Andric     raw_ostream &OS; // raw_ostream to print on
33*0b57cec5SDimitry Andric     bool ShouldPreserveUseListOrder;
34*0b57cec5SDimitry Andric     bool EmitSummaryIndex;
35*0b57cec5SDimitry Andric     bool EmitModuleHash;
36*0b57cec5SDimitry Andric 
37*0b57cec5SDimitry Andric   public:
38*0b57cec5SDimitry Andric     static char ID; // Pass identification, replacement for typeid
WriteBitcodePass()39*0b57cec5SDimitry Andric     WriteBitcodePass() : ModulePass(ID), OS(dbgs()) {
40*0b57cec5SDimitry Andric       initializeWriteBitcodePassPass(*PassRegistry::getPassRegistry());
41*0b57cec5SDimitry Andric     }
42*0b57cec5SDimitry Andric 
WriteBitcodePass(raw_ostream & o,bool ShouldPreserveUseListOrder,bool EmitSummaryIndex,bool EmitModuleHash)43*0b57cec5SDimitry Andric     explicit WriteBitcodePass(raw_ostream &o, bool ShouldPreserveUseListOrder,
44*0b57cec5SDimitry Andric                               bool EmitSummaryIndex, bool EmitModuleHash)
45*0b57cec5SDimitry Andric         : ModulePass(ID), OS(o),
46*0b57cec5SDimitry Andric           ShouldPreserveUseListOrder(ShouldPreserveUseListOrder),
47*0b57cec5SDimitry Andric           EmitSummaryIndex(EmitSummaryIndex), EmitModuleHash(EmitModuleHash) {
48*0b57cec5SDimitry Andric       initializeWriteBitcodePassPass(*PassRegistry::getPassRegistry());
49*0b57cec5SDimitry Andric     }
50*0b57cec5SDimitry Andric 
getPassName() const51*0b57cec5SDimitry Andric     StringRef getPassName() const override { return "Bitcode Writer"; }
52*0b57cec5SDimitry Andric 
runOnModule(Module & M)53*0b57cec5SDimitry Andric     bool runOnModule(Module &M) override {
54*0b57cec5SDimitry Andric       const ModuleSummaryIndex *Index =
55*0b57cec5SDimitry Andric           EmitSummaryIndex
56*0b57cec5SDimitry Andric               ? &(getAnalysis<ModuleSummaryIndexWrapperPass>().getIndex())
57*0b57cec5SDimitry Andric               : nullptr;
58*0b57cec5SDimitry Andric       WriteBitcodeToFile(M, OS, ShouldPreserveUseListOrder, Index,
59*0b57cec5SDimitry Andric                          EmitModuleHash);
60*0b57cec5SDimitry Andric       return false;
61*0b57cec5SDimitry Andric     }
getAnalysisUsage(AnalysisUsage & AU) const62*0b57cec5SDimitry Andric     void getAnalysisUsage(AnalysisUsage &AU) const override {
63*0b57cec5SDimitry Andric       AU.setPreservesAll();
64*0b57cec5SDimitry Andric       if (EmitSummaryIndex)
65*0b57cec5SDimitry Andric         AU.addRequired<ModuleSummaryIndexWrapperPass>();
66*0b57cec5SDimitry Andric     }
67*0b57cec5SDimitry Andric   };
68*0b57cec5SDimitry Andric }
69*0b57cec5SDimitry Andric 
70*0b57cec5SDimitry Andric char WriteBitcodePass::ID = 0;
71*0b57cec5SDimitry Andric INITIALIZE_PASS_BEGIN(WriteBitcodePass, "write-bitcode", "Write Bitcode", false,
72*0b57cec5SDimitry Andric                       true)
INITIALIZE_PASS_DEPENDENCY(ModuleSummaryIndexWrapperPass)73*0b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(ModuleSummaryIndexWrapperPass)
74*0b57cec5SDimitry Andric INITIALIZE_PASS_END(WriteBitcodePass, "write-bitcode", "Write Bitcode", false,
75*0b57cec5SDimitry Andric                     true)
76*0b57cec5SDimitry Andric 
77*0b57cec5SDimitry Andric ModulePass *llvm::createBitcodeWriterPass(raw_ostream &Str,
78*0b57cec5SDimitry Andric                                           bool ShouldPreserveUseListOrder,
79*0b57cec5SDimitry Andric                                           bool EmitSummaryIndex, bool EmitModuleHash) {
80*0b57cec5SDimitry Andric   return new WriteBitcodePass(Str, ShouldPreserveUseListOrder,
81*0b57cec5SDimitry Andric                               EmitSummaryIndex, EmitModuleHash);
82*0b57cec5SDimitry Andric }
83*0b57cec5SDimitry Andric 
isBitcodeWriterPass(Pass * P)84*0b57cec5SDimitry Andric bool llvm::isBitcodeWriterPass(Pass *P) {
85*0b57cec5SDimitry Andric   return P->getPassID() == (llvm::AnalysisID)&WriteBitcodePass::ID;
86 }
87