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