xref: /freebsd/contrib/llvm-project/llvm/lib/IR/IRPrintingPasses.cpp (revision a7dea1671b87c07d2d266f836bfa8b58efc7c134)
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 class PrintBasicBlockPass : public BasicBlockPass {
113   raw_ostream &Out;
114   std::string Banner;
115 
116 public:
117   static char ID;
118   PrintBasicBlockPass() : BasicBlockPass(ID), Out(dbgs()) {}
119   PrintBasicBlockPass(raw_ostream &Out, const std::string &Banner)
120       : BasicBlockPass(ID), Out(Out), Banner(Banner) {}
121 
122   bool runOnBasicBlock(BasicBlock &BB) override {
123     Out << Banner << BB;
124     return false;
125   }
126 
127   void getAnalysisUsage(AnalysisUsage &AU) const override {
128     AU.setPreservesAll();
129   }
130 
131   StringRef getPassName() const override { return "Print BasicBlock IR"; }
132 };
133 
134 }
135 
136 char PrintModulePassWrapper::ID = 0;
137 INITIALIZE_PASS(PrintModulePassWrapper, "print-module",
138                 "Print module to stderr", false, true)
139 char PrintFunctionPassWrapper::ID = 0;
140 INITIALIZE_PASS(PrintFunctionPassWrapper, "print-function",
141                 "Print function to stderr", false, true)
142 char PrintBasicBlockPass::ID = 0;
143 INITIALIZE_PASS(PrintBasicBlockPass, "print-bb", "Print BB to stderr", false,
144                 true)
145 
146 ModulePass *llvm::createPrintModulePass(llvm::raw_ostream &OS,
147                                         const std::string &Banner,
148                                         bool ShouldPreserveUseListOrder) {
149   return new PrintModulePassWrapper(OS, Banner, ShouldPreserveUseListOrder);
150 }
151 
152 FunctionPass *llvm::createPrintFunctionPass(llvm::raw_ostream &OS,
153                                             const std::string &Banner) {
154   return new PrintFunctionPassWrapper(OS, Banner);
155 }
156 
157 BasicBlockPass *llvm::createPrintBasicBlockPass(llvm::raw_ostream &OS,
158                                                 const std::string &Banner) {
159   return new PrintBasicBlockPass(OS, Banner);
160 }
161 
162 bool llvm::isIRPrintingPass(Pass *P) {
163   const char *PID = (const char*)P->getPassID();
164 
165   return (PID == &PrintModulePassWrapper::ID)
166       || (PID == &PrintFunctionPassWrapper::ID)
167       || (PID == &PrintBasicBlockPass::ID);
168 }
169