LLVM  12.0.0git
StandardInstrumentations.h
Go to the documentation of this file.
1 //===- StandardInstrumentations.h ------------------------------*- C++ -*--===//
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 /// \file
9 ///
10 /// This header defines a class that provides bookkeeping for all standard
11 /// (i.e in-tree) pass instrumentations.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_PASSES_STANDARDINSTRUMENTATIONS_H
16 #define LLVM_PASSES_STANDARDINSTRUMENTATIONS_H
17 
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/IR/BasicBlock.h"
21 #include "llvm/IR/OptBisect.h"
23 #include "llvm/IR/PassTimingInfo.h"
24 #include "llvm/IR/ValueHandle.h"
26 
27 #include <string>
28 #include <utility>
29 
30 namespace llvm {
31 
32 class Module;
33 class Function;
34 
35 /// Instrumentation to print IR before/after passes.
36 ///
37 /// Needs state to be able to print module after pass that invalidates IR unit
38 /// (typically Loop or SCC).
40 public:
42 
44 
45 private:
46  void printBeforePass(StringRef PassID, Any IR);
47  void printAfterPass(StringRef PassID, Any IR);
48  void printAfterPassInvalidated(StringRef PassID);
49 
50  using PrintModuleDesc = std::tuple<const Module *, std::string, StringRef>;
51 
52  void pushModuleDesc(StringRef PassID, Any IR);
53  PrintModuleDesc popModuleDesc(StringRef PassID);
54 
55  /// Stack of Module description, enough to print the module after a given
56  /// pass.
57  SmallVector<PrintModuleDesc, 2> ModuleDescStack;
58  bool StoreModuleDesc = false;
59 };
60 
62 public:
63  OptNoneInstrumentation(bool DebugLogging) : DebugLogging(DebugLogging) {}
65 
66 private:
67  bool DebugLogging;
68  bool shouldRun(StringRef PassID, Any IR);
69 };
70 
72 public:
75 };
76 
77 // Debug logging for transformation and analysis passes.
79 public:
80  PrintPassInstrumentation(bool DebugLogging) : DebugLogging(DebugLogging) {}
82 
83 private:
84  bool DebugLogging;
85 };
86 
88 private:
89  // CFG is a map BB -> {(Succ, Multiplicity)}, where BB is a non-leaf basic
90  // block, {(Succ, Multiplicity)} set of all pairs of the block's successors
91  // and the multiplicity of the edge (BB->Succ). As the mapped sets are
92  // unordered the order of successors is not tracked by the CFG. In other words
93  // this allows basic block successors to be swapped by a pass without
94  // reporting a CFG change. CFG can be guarded by basic block tracking pointers
95  // in the Graph (BBGuard). That is if any of the block is deleted or RAUWed
96  // then the CFG is treated poisoned and no block pointer of the Graph is used.
97  struct CFG {
98  struct BBGuard final : public CallbackVH {
99  BBGuard(const BasicBlock *BB) : CallbackVH(BB) {}
100  void deleted() override { CallbackVH::deleted(); }
102  bool isPoisoned() const { return !getValPtr(); }
103  };
104 
107 
108  CFG(const Function *F, bool TrackBBLifetime = false);
109 
110  bool operator==(const CFG &G) const {
111  return !isPoisoned() && !G.isPoisoned() && Graph == G.Graph;
112  }
113 
114  bool isPoisoned() const {
115  if (BBGuards)
116  for (auto &BB : *BBGuards) {
117  if (BB.second.isPoisoned())
118  return true;
119  }
120  return false;
121  }
122 
123  static void printDiff(raw_ostream &out, const CFG &Before,
124  const CFG &After);
125  };
126 
128 
129 public:
132 };
133 
134 // Base class for classes that report changes to the IR.
135 // It presents an interface for such classes and provides calls
136 // on various events as the new pass manager transforms the IR.
137 // It also provides filtering of information based on hidden options
138 // specifying which functions are interesting.
139 // Calls are made for the following events/queries:
140 // 1. The initial IR processed.
141 // 2. To get the representation of the IR (of type \p T).
142 // 3. When a pass does not change the IR.
143 // 4. When a pass changes the IR (given both before and after representations
144 // of type \p T).
145 // 5. When an IR is invalidated.
146 // 6. When a pass is run on an IR that is not interesting (based on options).
147 // 7. When a pass is ignored (pass manager or adapter pass).
148 // 8. To compare two IR representations (of type \p T).
149 template <typename IRUnitT> class ChangeReporter {
150 protected:
152 
153 public:
154  virtual ~ChangeReporter();
155 
156  // Determine if this pass/IR is interesting and if so, save the IR
157  // otherwise it is left on the stack without data.
158  void saveIRBeforePass(Any IR, StringRef PassID);
159  // Compare the IR from before the pass after the pass.
160  void handleIRAfterPass(Any IR, StringRef PassID);
161  // Handle the situation where a pass is invalidated.
162  void handleInvalidatedPass(StringRef PassID);
163 
164 protected:
165  // Register required callbacks.
166  void registerRequiredCallbacks(PassInstrumentationCallbacks &PIC);
167 
168  // Return true when this is a defined function for which printing
169  // of changes is desired.
170  bool isInterestingFunction(const Function &F);
171 
172  // Return true when this is a pass for which printing of changes is desired.
173  bool isInterestingPass(StringRef PassID);
174 
175  // Return true when this is a pass on IR for which printing
176  // of changes is desired.
177  bool isInteresting(Any IR, StringRef PassID);
178 
179  // Called on the first IR processed.
180  virtual void handleInitialIR(Any IR) = 0;
181  // Called before and after a pass to get the representation of the IR.
182  virtual void generateIRRepresentation(Any IR, StringRef PassID,
183  IRUnitT &Output) = 0;
184  // Called when the pass is not iteresting.
185  virtual void omitAfter(StringRef PassID, std::string &Name) = 0;
186  // Called when an interesting IR has changed.
187  virtual void handleAfter(StringRef PassID, std::string &Name,
188  const IRUnitT &Before, const IRUnitT &After,
189  Any) = 0;
190  // Called when an interesting pass is invalidated.
191  virtual void handleInvalidated(StringRef PassID) = 0;
192  // Called when the IR or pass is not interesting.
193  virtual void handleFiltered(StringRef PassID, std::string &Name) = 0;
194  // Called when an ignored pass is encountered.
195  virtual void handleIgnored(StringRef PassID, std::string &Name) = 0;
196  // Called to compare the before and after representations of the IR.
197  virtual bool same(const IRUnitT &Before, const IRUnitT &After) = 0;
198 
199  // Stack of IRs before passes.
200  std::vector<IRUnitT> BeforeStack;
201  // Is this the first IR seen?
202  bool InitialIR = true;
203 };
204 
205 // An abstract template base class that handles printing banners and
206 // reporting when things have not changed or are filtered out.
207 template <typename IRUnitT>
208 class TextChangeReporter : public ChangeReporter<IRUnitT> {
209 protected:
211 
212  // Print a module dump of the first IR that is changed.
213  void handleInitialIR(Any IR) override;
214  // Report that the IR was omitted because it did not change.
215  void omitAfter(StringRef PassID, std::string &Name) override;
216  // Report that the pass was invalidated.
217  void handleInvalidated(StringRef PassID) override;
218  // Report that the IR was filtered out.
219  void handleFiltered(StringRef PassID, std::string &Name) override;
220  // Report that the pass was ignored.
221  void handleIgnored(StringRef PassID, std::string &Name) override;
222  // Make substitutions in \p S suitable for reporting changes
223  // after the pass and then print it.
224 
226 };
227 
228 // A change printer based on the string representation of the IR as created
229 // by unwrapAndPrint. The string representation is stored in a std::string
230 // to preserve it as the IR changes in each pass. Note that the banner is
231 // included in this representation but it is massaged before reporting.
232 class IRChangedPrinter : public TextChangeReporter<std::string> {
233 public:
235  ~IRChangedPrinter() override;
237 
238 protected:
239  // Called before and after a pass to get the representation of the IR.
240  void generateIRRepresentation(Any IR, StringRef PassID,
241  std::string &Output) override;
242  // Called when an interesting IR has changed.
243  void handleAfter(StringRef PassID, std::string &Name,
244  const std::string &Before, const std::string &After,
245  Any) override;
246  // Called to compare the before and after representations of the IR.
247  bool same(const std::string &Before, const std::string &After) override;
248 };
249 
251  bool DebugLogging;
252 
253 public:
254  VerifyInstrumentation(bool DebugLogging) : DebugLogging(DebugLogging) {}
256 };
257 
258 /// This class provides an interface to register all the standard pass
259 /// instrumentations and manages their state (if any).
261  PrintIRInstrumentation PrintIR;
262  PrintPassInstrumentation PrintPass;
263  TimePassesHandler TimePasses;
264  OptNoneInstrumentation OptNone;
266  PreservedCFGCheckerInstrumentation PreservedCFGChecker;
267  IRChangedPrinter PrintChangedIR;
269 
270  bool VerifyEach;
271 
272 public:
273  StandardInstrumentations(bool DebugLogging, bool VerifyEach = false)
274  : PrintPass(DebugLogging), OptNone(DebugLogging), Verify(DebugLogging),
275  VerifyEach(VerifyEach) {}
276 
278 
279  TimePassesHandler &getTimePasses() { return TimePasses; }
280 };
281 
282 extern template class ChangeReporter<std::string>;
283 extern template class TextChangeReporter<std::string>;
284 
285 } // namespace llvm
286 
287 #endif
Definition: Any.h:26
This class represents lattice values for constants.
Definition: AllocatorList.h:23
Machine Debugify Module
F(f)
std::vector< IRUnitT > BeforeStack
This header defines classes/functions to handle pass execution timing information with interfaces for...
ppc ctr loops PowerPC CTR Loops Verify
This file defines the Pass Instrumentation classes that provide instrumentation points into the pass ...
This class provides an interface to register all the standard pass instrumentations and manages their...
This class implements a mechanism to disable passes and individual optimizations at compile time base...
Definition: OptBisect.h:43
LLVM Basic Block Representation.
Definition: BasicBlock.h:58
void registerCallbacks(PassInstrumentationCallbacks &PIC)
virtual void deleted()
Callback for Value destruction.
Definition: ValueHandle.h:414
static bool isInteresting(const SCEV *S, const Instruction *I, const Loop *L, ScalarEvolution *SE, LoopInfo *LI)
isInteresting - Test whether the given expression is "interesting" when used by the given expression...
Definition: IVUsers.cpp:60
const DataFlowGraph & G
Definition: RDFGraph.cpp:202
void deleted() override
Callback for Value destruction.
This file declares the interface for bisecting optimizations.
Flatten the CFG
This class implements -time-passes functionality for new pass manager.
LLVM Value Representation.
Definition: Value.h:75
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:50
This class manages callbacks registration, as well as provides a way for PassInstrumentation to pass ...
Value handle with callbacks on RAUW and destruction.
Definition: ValueHandle.h:383
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
Instrumentation to print IR before/after passes.
bool operator==(uint64_t V1, const APInt &V2)
Definition: APInt.h:2029
void allUsesReplacedWith(Value *) override
Callback for Value RAUW.
StandardInstrumentations(bool DebugLogging, bool VerifyEach=false)
Statically lint checks LLVM IR
Definition: Lint.cpp:743