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