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