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/Compiler.h" 22 #include "llvm/Support/Debug.h" 23 #include "llvm/Support/raw_ostream.h" 24 25 using namespace llvm; 26 27 namespace { 28 29 class PrintModulePassWrapper : public ModulePass { 30 raw_ostream &OS; 31 std::string Banner; 32 bool ShouldPreserveUseListOrder; 33 34 public: 35 static char ID; 36 PrintModulePassWrapper() : ModulePass(ID), OS(dbgs()) {} 37 PrintModulePassWrapper(raw_ostream &OS, const std::string &Banner, 38 bool ShouldPreserveUseListOrder) 39 : ModulePass(ID), OS(OS), Banner(Banner), 40 ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {} 41 42 bool runOnModule(Module &M) override { 43 // Remove intrinsic declarations when printing in the new format. 44 // TODO: consider removing this as debug-intrinsics are gone. 45 M.removeDebugIntrinsicDeclarations(); 46 47 if (llvm::isFunctionInPrintList("*")) { 48 if (!Banner.empty()) 49 OS << Banner << "\n"; 50 M.print(OS, nullptr, ShouldPreserveUseListOrder); 51 } else { 52 bool BannerPrinted = false; 53 for (const auto &F : M.functions()) { 54 if (llvm::isFunctionInPrintList(F.getName())) { 55 if (!BannerPrinted && !Banner.empty()) { 56 OS << Banner << "\n"; 57 BannerPrinted = true; 58 } 59 F.print(OS); 60 } 61 } 62 } 63 64 return false; 65 } 66 67 void getAnalysisUsage(AnalysisUsage &AU) const override { 68 AU.setPreservesAll(); 69 } 70 71 StringRef getPassName() const override { return "Print Module IR"; } 72 }; 73 74 class PrintFunctionPassWrapper : public FunctionPass { 75 raw_ostream &OS; 76 std::string Banner; 77 78 public: 79 static char ID; 80 PrintFunctionPassWrapper() : FunctionPass(ID), OS(dbgs()) {} 81 PrintFunctionPassWrapper(raw_ostream &OS, const std::string &Banner) 82 : FunctionPass(ID), OS(OS), Banner(Banner) {} 83 84 // This pass just prints a banner followed by the function as it's processed. 85 bool runOnFunction(Function &F) override { 86 if (isFunctionInPrintList(F.getName())) { 87 if (forcePrintModuleIR()) 88 OS << Banner << " (function: " << F.getName() << ")\n" 89 << *F.getParent(); 90 else 91 OS << Banner << '\n' << static_cast<Value &>(F); 92 } 93 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 } // namespace 105 106 char PrintModulePassWrapper::ID = 0; 107 INITIALIZE_PASS(PrintModulePassWrapper, "print-module", 108 "Print module to stderr", false, true) 109 char PrintFunctionPassWrapper::ID = 0; 110 INITIALIZE_PASS(PrintFunctionPassWrapper, "print-function", 111 "Print function to stderr", false, true) 112 113 ModulePass *llvm::createPrintModulePass(llvm::raw_ostream &OS, 114 const std::string &Banner, 115 bool ShouldPreserveUseListOrder) { 116 return new PrintModulePassWrapper(OS, Banner, ShouldPreserveUseListOrder); 117 } 118 119 FunctionPass *llvm::createPrintFunctionPass(llvm::raw_ostream &OS, 120 const std::string &Banner) { 121 return new PrintFunctionPassWrapper(OS, Banner); 122 } 123 124 bool llvm::isIRPrintingPass(Pass *P) { 125 const char *PID = (const char *)P->getPassID(); 126 127 return (PID == &PrintModulePassWrapper::ID) || 128 (PID == &PrintFunctionPassWrapper::ID); 129 } 130