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