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 cl::opt<bool> WriteNewDbgInfoFormat( 27 "write-experimental-debuginfo", 28 cl::desc("Write debug info in the new non-intrinsic format. Has no effect " 29 "if --preserve-input-debuginfo-format=true."), 30 cl::init(true)); 31 32 namespace { 33 34 class PrintModulePassWrapper : public ModulePass { 35 raw_ostream &OS; 36 std::string Banner; 37 bool ShouldPreserveUseListOrder; 38 39 public: 40 static char ID; 41 PrintModulePassWrapper() : ModulePass(ID), OS(dbgs()) {} 42 PrintModulePassWrapper(raw_ostream &OS, const std::string &Banner, 43 bool ShouldPreserveUseListOrder) 44 : ModulePass(ID), OS(OS), Banner(Banner), 45 ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {} 46 47 bool runOnModule(Module &M) override { 48 // RemoveDIs: Regardless of the format we've processed this module in, use 49 // `WriteNewDbgInfoFormat` to determine which format we use to write it. 50 ScopedDbgInfoFormatSetter FormatSetter(M, WriteNewDbgInfoFormat); 51 // Remove intrinsic declarations when printing in the new format. 52 // TODO: Move this into Module::setIsNewDbgInfoFormat when we're ready to 53 // update test output. 54 if (WriteNewDbgInfoFormat) 55 M.removeDebugIntrinsicDeclarations(); 56 57 if (llvm::isFunctionInPrintList("*")) { 58 if (!Banner.empty()) 59 OS << Banner << "\n"; 60 M.print(OS, nullptr, ShouldPreserveUseListOrder); 61 } else { 62 bool BannerPrinted = false; 63 for (const auto &F : M.functions()) { 64 if (llvm::isFunctionInPrintList(F.getName())) { 65 if (!BannerPrinted && !Banner.empty()) { 66 OS << Banner << "\n"; 67 BannerPrinted = true; 68 } 69 F.print(OS); 70 } 71 } 72 } 73 74 return false; 75 } 76 77 void getAnalysisUsage(AnalysisUsage &AU) const override { 78 AU.setPreservesAll(); 79 } 80 81 StringRef getPassName() const override { return "Print Module IR"; } 82 }; 83 84 class PrintFunctionPassWrapper : public FunctionPass { 85 raw_ostream &OS; 86 std::string Banner; 87 88 public: 89 static char ID; 90 PrintFunctionPassWrapper() : FunctionPass(ID), OS(dbgs()) {} 91 PrintFunctionPassWrapper(raw_ostream &OS, const std::string &Banner) 92 : FunctionPass(ID), OS(OS), Banner(Banner) {} 93 94 // This pass just prints a banner followed by the function as it's processed. 95 bool runOnFunction(Function &F) override { 96 // RemoveDIs: Regardless of the format we've processed this function in, use 97 // `WriteNewDbgInfoFormat` to determine which format we use to write it. 98 ScopedDbgInfoFormatSetter FormatSetter(F, WriteNewDbgInfoFormat); 99 100 if (isFunctionInPrintList(F.getName())) { 101 if (forcePrintModuleIR()) 102 OS << Banner << " (function: " << F.getName() << ")\n" 103 << *F.getParent(); 104 else 105 OS << Banner << '\n' << static_cast<Value &>(F); 106 } 107 108 return false; 109 } 110 111 void getAnalysisUsage(AnalysisUsage &AU) const override { 112 AU.setPreservesAll(); 113 } 114 115 StringRef getPassName() const override { return "Print Function IR"; } 116 }; 117 118 } // namespace 119 120 char PrintModulePassWrapper::ID = 0; 121 INITIALIZE_PASS(PrintModulePassWrapper, "print-module", 122 "Print module to stderr", false, true) 123 char PrintFunctionPassWrapper::ID = 0; 124 INITIALIZE_PASS(PrintFunctionPassWrapper, "print-function", 125 "Print function to stderr", false, true) 126 127 ModulePass *llvm::createPrintModulePass(llvm::raw_ostream &OS, 128 const std::string &Banner, 129 bool ShouldPreserveUseListOrder) { 130 return new PrintModulePassWrapper(OS, Banner, ShouldPreserveUseListOrder); 131 } 132 133 FunctionPass *llvm::createPrintFunctionPass(llvm::raw_ostream &OS, 134 const std::string &Banner) { 135 return new PrintFunctionPassWrapper(OS, Banner); 136 } 137 138 bool llvm::isIRPrintingPass(Pass *P) { 139 const char *PID = (const char *)P->getPassID(); 140 141 return (PID == &PrintModulePassWrapper::ID) || 142 (PID == &PrintFunctionPassWrapper::ID); 143 } 144