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