1 //===--- IRPrintingPasses.cpp - Module and Function printing passes -------===// 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 // PrintModulePass and PrintFunctionPass implementations. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "llvm/IR/IRPrintingPasses.h" 14 #include "llvm/IR/Function.h" 15 #include "llvm/IR/Module.h" 16 #include "llvm/IR/PassManager.h" 17 #include "llvm/Pass.h" 18 #include "llvm/Support/Debug.h" 19 #include "llvm/Support/raw_ostream.h" 20 using namespace llvm; 21 22 PrintModulePass::PrintModulePass() : OS(dbgs()) {} 23 PrintModulePass::PrintModulePass(raw_ostream &OS, const std::string &Banner, 24 bool ShouldPreserveUseListOrder) 25 : OS(OS), Banner(Banner), 26 ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {} 27 28 PreservedAnalyses PrintModulePass::run(Module &M, ModuleAnalysisManager &) { 29 if (llvm::isFunctionInPrintList("*")) { 30 if (!Banner.empty()) 31 OS << Banner << "\n"; 32 M.print(OS, nullptr, ShouldPreserveUseListOrder); 33 } 34 else { 35 bool BannerPrinted = false; 36 for(const auto &F : M.functions()) { 37 if (llvm::isFunctionInPrintList(F.getName())) { 38 if (!BannerPrinted && !Banner.empty()) { 39 OS << Banner << "\n"; 40 BannerPrinted = true; 41 } 42 F.print(OS); 43 } 44 } 45 } 46 return PreservedAnalyses::all(); 47 } 48 49 PrintFunctionPass::PrintFunctionPass() : OS(dbgs()) {} 50 PrintFunctionPass::PrintFunctionPass(raw_ostream &OS, const std::string &Banner) 51 : OS(OS), Banner(Banner) {} 52 53 PreservedAnalyses PrintFunctionPass::run(Function &F, 54 FunctionAnalysisManager &) { 55 if (isFunctionInPrintList(F.getName())) { 56 if (forcePrintModuleIR()) 57 OS << Banner << " (function: " << F.getName() << ")\n" << *F.getParent(); 58 else 59 OS << Banner << static_cast<Value &>(F); 60 } 61 return PreservedAnalyses::all(); 62 } 63 64 namespace { 65 66 class PrintModulePassWrapper : public ModulePass { 67 PrintModulePass P; 68 69 public: 70 static char ID; 71 PrintModulePassWrapper() : ModulePass(ID) {} 72 PrintModulePassWrapper(raw_ostream &OS, const std::string &Banner, 73 bool ShouldPreserveUseListOrder) 74 : ModulePass(ID), P(OS, Banner, ShouldPreserveUseListOrder) {} 75 76 bool runOnModule(Module &M) override { 77 ModuleAnalysisManager DummyMAM; 78 P.run(M, DummyMAM); 79 return false; 80 } 81 82 void getAnalysisUsage(AnalysisUsage &AU) const override { 83 AU.setPreservesAll(); 84 } 85 86 StringRef getPassName() const override { return "Print Module IR"; } 87 }; 88 89 class PrintFunctionPassWrapper : public FunctionPass { 90 PrintFunctionPass P; 91 92 public: 93 static char ID; 94 PrintFunctionPassWrapper() : FunctionPass(ID) {} 95 PrintFunctionPassWrapper(raw_ostream &OS, const std::string &Banner) 96 : FunctionPass(ID), P(OS, Banner) {} 97 98 // This pass just prints a banner followed by the function as it's processed. 99 bool runOnFunction(Function &F) override { 100 FunctionAnalysisManager DummyFAM; 101 P.run(F, DummyFAM); 102 return false; 103 } 104 105 void getAnalysisUsage(AnalysisUsage &AU) const override { 106 AU.setPreservesAll(); 107 } 108 109 StringRef getPassName() const override { return "Print Function IR"; } 110 }; 111 112 class PrintBasicBlockPass : public BasicBlockPass { 113 raw_ostream &Out; 114 std::string Banner; 115 116 public: 117 static char ID; 118 PrintBasicBlockPass() : BasicBlockPass(ID), Out(dbgs()) {} 119 PrintBasicBlockPass(raw_ostream &Out, const std::string &Banner) 120 : BasicBlockPass(ID), Out(Out), Banner(Banner) {} 121 122 bool runOnBasicBlock(BasicBlock &BB) override { 123 Out << Banner << BB; 124 return false; 125 } 126 127 void getAnalysisUsage(AnalysisUsage &AU) const override { 128 AU.setPreservesAll(); 129 } 130 131 StringRef getPassName() const override { return "Print BasicBlock IR"; } 132 }; 133 134 } 135 136 char PrintModulePassWrapper::ID = 0; 137 INITIALIZE_PASS(PrintModulePassWrapper, "print-module", 138 "Print module to stderr", false, true) 139 char PrintFunctionPassWrapper::ID = 0; 140 INITIALIZE_PASS(PrintFunctionPassWrapper, "print-function", 141 "Print function to stderr", false, true) 142 char PrintBasicBlockPass::ID = 0; 143 INITIALIZE_PASS(PrintBasicBlockPass, "print-bb", "Print BB to stderr", false, 144 true) 145 146 ModulePass *llvm::createPrintModulePass(llvm::raw_ostream &OS, 147 const std::string &Banner, 148 bool ShouldPreserveUseListOrder) { 149 return new PrintModulePassWrapper(OS, Banner, ShouldPreserveUseListOrder); 150 } 151 152 FunctionPass *llvm::createPrintFunctionPass(llvm::raw_ostream &OS, 153 const std::string &Banner) { 154 return new PrintFunctionPassWrapper(OS, Banner); 155 } 156 157 BasicBlockPass *llvm::createPrintBasicBlockPass(llvm::raw_ostream &OS, 158 const std::string &Banner) { 159 return new PrintBasicBlockPass(OS, Banner); 160 } 161 162 bool llvm::isIRPrintingPass(Pass *P) { 163 const char *PID = (const char*)P->getPassID(); 164 165 return (PID == &PrintModulePassWrapper::ID) 166 || (PID == &PrintFunctionPassWrapper::ID) 167 || (PID == &PrintBasicBlockPass::ID); 168 } 169