PassPrinters.cpp revision 360784
1//===- PassPrinters.cpp - Utilities to print analysis info for 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/// \file
10/// Utilities to print analysis info for various kinds of passes.
11///
12//===----------------------------------------------------------------------===//
13
14#include "PassPrinters.h"
15#include "llvm/Analysis/CallGraph.h"
16#include "llvm/Analysis/CallGraphSCCPass.h"
17#include "llvm/Analysis/LoopInfo.h"
18#include "llvm/Analysis/LoopPass.h"
19#include "llvm/Analysis/RegionInfo.h"
20#include "llvm/Analysis/RegionPass.h"
21#include "llvm/IR/BasicBlock.h"
22#include "llvm/IR/Function.h"
23#include "llvm/Pass.h"
24#include "llvm/Support/raw_ostream.h"
25#include <string>
26
27using namespace llvm;
28
29namespace {
30
31struct FunctionPassPrinter : public FunctionPass {
32  const PassInfo *PassToPrint;
33  raw_ostream &Out;
34  static char ID;
35  std::string PassName;
36  bool QuietPass;
37
38  FunctionPassPrinter(const PassInfo *PI, raw_ostream &out, bool Quiet)
39      : FunctionPass(ID), PassToPrint(PI), Out(out), QuietPass(Quiet) {
40    std::string PassToPrintName = PassToPrint->getPassName();
41    PassName = "FunctionPass Printer: " + PassToPrintName;
42  }
43
44  bool runOnFunction(Function &F) override {
45    if (!QuietPass)
46      Out << "Printing analysis '" << PassToPrint->getPassName()
47          << "' for function '" << F.getName() << "':\n";
48
49    // Get and print pass...
50    getAnalysisID<Pass>(PassToPrint->getTypeInfo()).print(Out, F.getParent());
51    return false;
52  }
53
54  StringRef getPassName() const override { return PassName; }
55
56  void getAnalysisUsage(AnalysisUsage &AU) const override {
57    AU.addRequiredID(PassToPrint->getTypeInfo());
58    AU.setPreservesAll();
59  }
60};
61
62char FunctionPassPrinter::ID = 0;
63
64struct CallGraphSCCPassPrinter : public CallGraphSCCPass {
65  static char ID;
66  const PassInfo *PassToPrint;
67  raw_ostream &Out;
68  std::string PassName;
69  bool QuietPass;
70
71  CallGraphSCCPassPrinter(const PassInfo *PI, raw_ostream &out, bool Quiet)
72      : CallGraphSCCPass(ID), PassToPrint(PI), Out(out), QuietPass(Quiet) {
73    std::string PassToPrintName = PassToPrint->getPassName();
74    PassName = "CallGraphSCCPass Printer: " + PassToPrintName;
75  }
76
77  bool runOnSCC(CallGraphSCC &SCC) override {
78    if (!QuietPass)
79      Out << "Printing analysis '" << PassToPrint->getPassName() << "':\n";
80
81    // Get and print pass...
82    for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) {
83      Function *F = (*I)->getFunction();
84      if (F)
85        getAnalysisID<Pass>(PassToPrint->getTypeInfo())
86            .print(Out, F->getParent());
87    }
88    return false;
89  }
90
91  StringRef getPassName() const override { return PassName; }
92
93  void getAnalysisUsage(AnalysisUsage &AU) const override {
94    AU.addRequiredID(PassToPrint->getTypeInfo());
95    AU.setPreservesAll();
96  }
97};
98
99char CallGraphSCCPassPrinter::ID = 0;
100
101struct ModulePassPrinter : public ModulePass {
102  static char ID;
103  const PassInfo *PassToPrint;
104  raw_ostream &Out;
105  std::string PassName;
106  bool QuietPass;
107
108  ModulePassPrinter(const PassInfo *PI, raw_ostream &out, bool Quiet)
109      : ModulePass(ID), PassToPrint(PI), Out(out), QuietPass(Quiet) {
110    std::string PassToPrintName = PassToPrint->getPassName();
111    PassName = "ModulePass Printer: " + PassToPrintName;
112  }
113
114  bool runOnModule(Module &M) override {
115    if (!QuietPass)
116      Out << "Printing analysis '" << PassToPrint->getPassName() << "':\n";
117
118    // Get and print pass...
119    getAnalysisID<Pass>(PassToPrint->getTypeInfo()).print(Out, &M);
120    return false;
121  }
122
123  StringRef getPassName() const override { return PassName; }
124
125  void getAnalysisUsage(AnalysisUsage &AU) const override {
126    AU.addRequiredID(PassToPrint->getTypeInfo());
127    AU.setPreservesAll();
128  }
129};
130
131char ModulePassPrinter::ID = 0;
132
133struct LoopPassPrinter : public LoopPass {
134  static char ID;
135  const PassInfo *PassToPrint;
136  raw_ostream &Out;
137  std::string PassName;
138  bool QuietPass;
139
140  LoopPassPrinter(const PassInfo *PI, raw_ostream &out, bool Quiet)
141      : LoopPass(ID), PassToPrint(PI), Out(out), QuietPass(Quiet) {
142    std::string PassToPrintName = PassToPrint->getPassName();
143    PassName = "LoopPass Printer: " + PassToPrintName;
144  }
145
146  bool runOnLoop(Loop *L, LPPassManager &LPM) override {
147    if (!QuietPass)
148      Out << "Printing analysis '" << PassToPrint->getPassName() << "':\n";
149
150    // Get and print pass...
151    getAnalysisID<Pass>(PassToPrint->getTypeInfo())
152        .print(Out, L->getHeader()->getParent()->getParent());
153    return false;
154  }
155
156  StringRef getPassName() const override { return PassName; }
157
158  void getAnalysisUsage(AnalysisUsage &AU) const override {
159    AU.addRequiredID(PassToPrint->getTypeInfo());
160    AU.setPreservesAll();
161  }
162};
163
164char LoopPassPrinter::ID = 0;
165
166struct RegionPassPrinter : public RegionPass {
167  static char ID;
168  const PassInfo *PassToPrint;
169  raw_ostream &Out;
170  std::string PassName;
171  bool QuietPass;
172
173  RegionPassPrinter(const PassInfo *PI, raw_ostream &out, bool Quiet)
174      : RegionPass(ID), PassToPrint(PI), Out(out), QuietPass(Quiet) {
175    std::string PassToPrintName = PassToPrint->getPassName();
176    PassName = "RegionPass Printer: " + PassToPrintName;
177  }
178
179  bool runOnRegion(Region *R, RGPassManager &RGM) override {
180    if (!QuietPass) {
181      Out << "Printing analysis '" << PassToPrint->getPassName() << "' for "
182          << "region: '" << R->getNameStr() << "' in function '"
183          << R->getEntry()->getParent()->getName() << "':\n";
184    }
185    // Get and print pass...
186    getAnalysisID<Pass>(PassToPrint->getTypeInfo())
187        .print(Out, R->getEntry()->getParent()->getParent());
188    return false;
189  }
190
191  StringRef getPassName() const override { return PassName; }
192
193  void getAnalysisUsage(AnalysisUsage &AU) const override {
194    AU.addRequiredID(PassToPrint->getTypeInfo());
195    AU.setPreservesAll();
196  }
197};
198
199char RegionPassPrinter::ID = 0;
200
201} // end anonymous namespace
202
203FunctionPass *llvm::createFunctionPassPrinter(const PassInfo *PI,
204                                              raw_ostream &OS, bool Quiet) {
205  return new FunctionPassPrinter(PI, OS, Quiet);
206}
207
208CallGraphSCCPass *llvm::createCallGraphPassPrinter(const PassInfo *PI,
209                                                   raw_ostream &OS,
210                                                   bool Quiet) {
211  return new CallGraphSCCPassPrinter(PI, OS, Quiet);
212}
213
214ModulePass *llvm::createModulePassPrinter(const PassInfo *PI, raw_ostream &OS,
215                                          bool Quiet) {
216  return new ModulePassPrinter(PI, OS, Quiet);
217}
218
219LoopPass *llvm::createLoopPassPrinter(const PassInfo *PI, raw_ostream &OS,
220                                      bool Quiet) {
221  return new LoopPassPrinter(PI, OS, Quiet);
222}
223
224RegionPass *llvm::createRegionPassPrinter(const PassInfo *PI, raw_ostream &OS,
225                                          bool Quiet) {
226  return new RegionPassPrinter(PI, OS, Quiet);
227}
228
229