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