xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Passes/StandardInstrumentations.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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/STLExtras.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/ADT/StringSet.h"
22 #include "llvm/CodeGen/MachineBasicBlock.h"
23 #include "llvm/IR/BasicBlock.h"
24 #include "llvm/IR/DebugInfoMetadata.h"
25 #include "llvm/IR/DroppedVariableStatsIR.h"
26 #include "llvm/IR/OptBisect.h"
27 #include "llvm/IR/PassTimingInfo.h"
28 #include "llvm/IR/ValueHandle.h"
29 #include "llvm/Support/CommandLine.h"
30 #include "llvm/Support/Compiler.h"
31 #include "llvm/Support/TimeProfiler.h"
32 #include "llvm/Transforms/IPO/SampleProfileProbe.h"
33 
34 #include <string>
35 #include <utility>
36 
37 namespace llvm {
38 
39 class Module;
40 class Function;
41 class MachineFunction;
42 class PassInstrumentationCallbacks;
43 
44 /// Instrumentation to print IR before/after passes.
45 ///
46 /// Needs state to be able to print module after pass that invalidates IR unit
47 /// (typically Loop or SCC).
48 class PrintIRInstrumentation {
49 public:
50   LLVM_ABI ~PrintIRInstrumentation();
51 
52   LLVM_ABI void registerCallbacks(PassInstrumentationCallbacks &PIC);
53 
54 private:
55   struct PassRunDescriptor {
56     const Module *M;
57     const unsigned PassNumber;
58     const std::string IRFileDisplayName;
59     const std::string IRName;
60     const StringRef PassID;
61 
PassRunDescriptorPassRunDescriptor62     PassRunDescriptor(const Module *M, unsigned PassNumber,
63                       std::string &&IRFileDisplayName, std::string &&IRName,
64                       const StringRef PassID)
65         : M{M}, PassNumber{PassNumber}, IRFileDisplayName(IRFileDisplayName),
66           IRName{IRName}, PassID(PassID) {}
67   };
68 
69   void printBeforePass(StringRef PassID, Any IR);
70   void printAfterPass(StringRef PassID, Any IR);
71   void printAfterPassInvalidated(StringRef PassID);
72 
73   bool shouldPrintBeforePass(StringRef PassID);
74   bool shouldPrintAfterPass(StringRef PassID);
75   bool shouldPrintBeforeCurrentPassNumber();
76   bool shouldPrintAfterCurrentPassNumber();
77   bool shouldPrintPassNumbers();
78   bool shouldPrintBeforeSomePassNumber();
79   bool shouldPrintAfterSomePassNumber();
80 
81   void pushPassRunDescriptor(StringRef PassID, Any IR, unsigned PassNumber);
82   PassRunDescriptor popPassRunDescriptor(StringRef PassID);
83 
84   enum class IRDumpFileSuffixType {
85     Before,
86     After,
87     Invalidated,
88   };
89 
90   static StringRef
91   getFileSuffix(PrintIRInstrumentation::IRDumpFileSuffixType Type);
92   std::string fetchDumpFilename(StringRef PassId, StringRef IRFileDisplayName,
93                                 unsigned PassNumber,
94                                 IRDumpFileSuffixType SuffixType);
95 
96   PassInstrumentationCallbacks *PIC;
97   /// Stack of Pass Run descriptions, enough to print the IR unit after a given
98   /// pass.
99   SmallVector<PassRunDescriptor, 2> PassRunDescriptorStack;
100 
101   /// Used for print-at-pass-number
102   unsigned CurrentPassNumber = 0;
103 };
104 
105 class OptNoneInstrumentation {
106 public:
OptNoneInstrumentation(bool DebugLogging)107   OptNoneInstrumentation(bool DebugLogging) : DebugLogging(DebugLogging) {}
108   LLVM_ABI void registerCallbacks(PassInstrumentationCallbacks &PIC);
109 
110 private:
111   bool DebugLogging;
112   bool shouldRun(StringRef PassID, Any IR);
113 };
114 
115 class OptPassGateInstrumentation {
116   LLVMContext &Context;
117   bool HasWrittenIR = false;
118 public:
OptPassGateInstrumentation(LLVMContext & Context)119   OptPassGateInstrumentation(LLVMContext &Context) : Context(Context) {}
120   LLVM_ABI bool shouldRun(StringRef PassName, Any IR);
121   LLVM_ABI void registerCallbacks(PassInstrumentationCallbacks &PIC);
122 };
123 
124 struct PrintPassOptions {
125   /// Print adaptors and pass managers.
126   bool Verbose = false;
127   /// Don't print information for analyses.
128   bool SkipAnalyses = false;
129   /// Indent based on hierarchy.
130   bool Indent = false;
131 };
132 
133 // Debug logging for transformation and analysis passes.
134 class PrintPassInstrumentation {
135   raw_ostream &print();
136 
137 public:
PrintPassInstrumentation(bool Enabled,PrintPassOptions Opts)138   PrintPassInstrumentation(bool Enabled, PrintPassOptions Opts)
139       : Enabled(Enabled), Opts(Opts) {}
140   LLVM_ABI void registerCallbacks(PassInstrumentationCallbacks &PIC);
141 
142 private:
143   bool Enabled;
144   PrintPassOptions Opts;
145   int Indent = 0;
146 };
147 
148 class PreservedCFGCheckerInstrumentation {
149 public:
150   // Keeps sticky poisoned flag for the given basic block once it has been
151   // deleted or RAUWed.
152   struct BBGuard final : public CallbackVH {
BBGuardfinal153     BBGuard(const BasicBlock *BB) : CallbackVH(BB) {}
deletedfinal154     void deleted() override { CallbackVH::deleted(); }
allUsesReplacedWithfinal155     void allUsesReplacedWith(Value *) override { CallbackVH::deleted(); }
isPoisonedfinal156     bool isPoisoned() const { return !getValPtr(); }
157   };
158 
159   // CFG is a map BB -> {(Succ, Multiplicity)}, where BB is a non-leaf basic
160   // block, {(Succ, Multiplicity)} set of all pairs of the block's successors
161   // and the multiplicity of the edge (BB->Succ). As the mapped sets are
162   // unordered the order of successors is not tracked by the CFG. In other words
163   // this allows basic block successors to be swapped by a pass without
164   // reporting a CFG change. CFG can be guarded by basic block tracking pointers
165   // in the Graph (BBGuard). That is if any of the block is deleted or RAUWed
166   // then the CFG is treated poisoned and no block pointer of the Graph is used.
167   struct CFG {
168     std::optional<DenseMap<intptr_t, BBGuard>> BBGuards;
169     DenseMap<const BasicBlock *, DenseMap<const BasicBlock *, unsigned>> Graph;
170 
171     LLVM_ABI CFG(const Function *F, bool TrackBBLifetime);
172 
173     bool operator==(const CFG &G) const {
174       return !isPoisoned() && !G.isPoisoned() && Graph == G.Graph;
175     }
176 
isPoisonedCFG177     bool isPoisoned() const {
178       return BBGuards && llvm::any_of(*BBGuards, [](const auto &BB) {
179                return BB.second.isPoisoned();
180              });
181     }
182 
183     LLVM_ABI static void printDiff(raw_ostream &out, const CFG &Before,
184                                    const CFG &After);
185     LLVM_ABI bool invalidate(Function &F, const PreservedAnalyses &PA,
186                              FunctionAnalysisManager::Invalidator &);
187   };
188 
189 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
190   SmallVector<StringRef, 8> PassStack;
191 #endif
192 
193   LLVM_ABI void registerCallbacks(PassInstrumentationCallbacks &PIC,
194                                   ModuleAnalysisManager &MAM);
195 };
196 
197 // Base class for classes that report changes to the IR.
198 // It presents an interface for such classes and provides calls
199 // on various events as the new pass manager transforms the IR.
200 // It also provides filtering of information based on hidden options
201 // specifying which functions are interesting.
202 // Calls are made for the following events/queries:
203 // 1.  The initial IR processed.
204 // 2.  To get the representation of the IR (of type \p T).
205 // 3.  When a pass does not change the IR.
206 // 4.  When a pass changes the IR (given both before and after representations
207 //         of type \p T).
208 // 5.  When an IR is invalidated.
209 // 6.  When a pass is run on an IR that is not interesting (based on options).
210 // 7.  When a pass is ignored (pass manager or adapter pass).
211 // 8.  To compare two IR representations (of type \p T).
212 template <typename IRUnitT> class LLVM_ABI ChangeReporter {
213 protected:
ChangeReporter(bool RunInVerboseMode)214   ChangeReporter(bool RunInVerboseMode) : VerboseMode(RunInVerboseMode) {}
215 
216 public:
217   virtual ~ChangeReporter();
218 
219   // Determine if this pass/IR is interesting and if so, save the IR
220   // otherwise it is left on the stack without data.
221   void saveIRBeforePass(Any IR, StringRef PassID, StringRef PassName);
222   // Compare the IR from before the pass after the pass.
223   void handleIRAfterPass(Any IR, StringRef PassID, StringRef PassName);
224   // Handle the situation where a pass is invalidated.
225   void handleInvalidatedPass(StringRef PassID);
226 
227 protected:
228   // Register required callbacks.
229   void registerRequiredCallbacks(PassInstrumentationCallbacks &PIC);
230 
231   // Called on the first IR processed.
232   virtual void handleInitialIR(Any IR) = 0;
233   // Called before and after a pass to get the representation of the IR.
234   virtual void generateIRRepresentation(Any IR, StringRef PassID,
235                                         IRUnitT &Output) = 0;
236   // Called when the pass is not iteresting.
237   virtual void omitAfter(StringRef PassID, std::string &Name) = 0;
238   // Called when an interesting IR has changed.
239   virtual void handleAfter(StringRef PassID, std::string &Name,
240                            const IRUnitT &Before, const IRUnitT &After,
241                            Any) = 0;
242   // Called when an interesting pass is invalidated.
243   virtual void handleInvalidated(StringRef PassID) = 0;
244   // Called when the IR or pass is not interesting.
245   virtual void handleFiltered(StringRef PassID, std::string &Name) = 0;
246   // Called when an ignored pass is encountered.
247   virtual void handleIgnored(StringRef PassID, std::string &Name) = 0;
248 
249   // Stack of IRs before passes.
250   std::vector<IRUnitT> BeforeStack;
251   // Is this the first IR seen?
252   bool InitialIR = true;
253 
254   // Run in verbose mode, printing everything?
255   const bool VerboseMode;
256 };
257 
258 // An abstract template base class that handles printing banners and
259 // reporting when things have not changed or are filtered out.
260 template <typename IRUnitT>
261 class LLVM_ABI TextChangeReporter : public ChangeReporter<IRUnitT> {
262 protected:
263   TextChangeReporter(bool Verbose);
264 
265   // Print a module dump of the first IR that is changed.
266   void handleInitialIR(Any IR) override;
267   // Report that the IR was omitted because it did not change.
268   void omitAfter(StringRef PassID, std::string &Name) override;
269   // Report that the pass was invalidated.
270   void handleInvalidated(StringRef PassID) override;
271   // Report that the IR was filtered out.
272   void handleFiltered(StringRef PassID, std::string &Name) override;
273   // Report that the pass was ignored.
274   void handleIgnored(StringRef PassID, std::string &Name) override;
275   // Make substitutions in \p S suitable for reporting changes
276   // after the pass and then print it.
277 
278   raw_ostream &Out;
279 };
280 
281 // A change printer based on the string representation of the IR as created
282 // by unwrapAndPrint.  The string representation is stored in a std::string
283 // to preserve it as the IR changes in each pass.  Note that the banner is
284 // included in this representation but it is massaged before reporting.
285 class LLVM_ABI IRChangedPrinter : public TextChangeReporter<std::string> {
286 public:
IRChangedPrinter(bool VerboseMode)287   IRChangedPrinter(bool VerboseMode)
288       : TextChangeReporter<std::string>(VerboseMode) {}
289   ~IRChangedPrinter() override;
290   void registerCallbacks(PassInstrumentationCallbacks &PIC);
291 
292 protected:
293   // Called before and after a pass to get the representation of the IR.
294   void generateIRRepresentation(Any IR, StringRef PassID,
295                                 std::string &Output) override;
296   // Called when an interesting IR has changed.
297   void handleAfter(StringRef PassID, std::string &Name,
298                    const std::string &Before, const std::string &After,
299                    Any) override;
300 };
301 
302 class LLVM_ABI IRChangedTester : public IRChangedPrinter {
303 public:
IRChangedTester()304   IRChangedTester() : IRChangedPrinter(true) {}
305   ~IRChangedTester() override;
306   void registerCallbacks(PassInstrumentationCallbacks &PIC);
307 
308 protected:
309   void handleIR(const std::string &IR, StringRef PassID);
310 
311   // Check initial IR
312   void handleInitialIR(Any IR) override;
313   // Do nothing.
314   void omitAfter(StringRef PassID, std::string &Name) override;
315   // Do nothing.
316   void handleInvalidated(StringRef PassID) override;
317   // Do nothing.
318   void handleFiltered(StringRef PassID, std::string &Name) override;
319   // Do nothing.
320   void handleIgnored(StringRef PassID, std::string &Name) override;
321 
322   // Call test as interesting IR has changed.
323   void handleAfter(StringRef PassID, std::string &Name,
324                    const std::string &Before, const std::string &After,
325                    Any) override;
326 };
327 
328 // Information that needs to be saved for a basic block in order to compare
329 // before and after the pass to determine if it was changed by a pass.
330 template <typename T> class BlockDataT {
331 public:
BlockDataT(const BasicBlock & B)332   BlockDataT(const BasicBlock &B) : Label(B.getName().str()), Data(B) {
333     raw_string_ostream SS(Body);
334     B.print(SS, nullptr, true, true);
335   }
336 
BlockDataT(const MachineBasicBlock & B)337   BlockDataT(const MachineBasicBlock &B) : Label(B.getName().str()), Data(B) {
338     raw_string_ostream SS(Body);
339     B.print(SS);
340   }
341 
342   bool operator==(const BlockDataT &That) const { return Body == That.Body; }
343   bool operator!=(const BlockDataT &That) const { return Body != That.Body; }
344 
345   // Return the label of the represented basic block.
getLabel()346   StringRef getLabel() const { return Label; }
347   // Return the string representation of the basic block.
getBody()348   StringRef getBody() const { return Body; }
349 
350   // Return the associated data
getData()351   const T &getData() const { return Data; }
352 
353 protected:
354   std::string Label;
355   std::string Body;
356 
357   // Extra data associated with a basic block
358   T Data;
359 };
360 
361 template <typename T> class OrderedChangedData {
362 public:
363   // Return the names in the order they were saved
getOrder()364   std::vector<std::string> &getOrder() { return Order; }
getOrder()365   const std::vector<std::string> &getOrder() const { return Order; }
366 
367   // Return a map of names to saved representations
getData()368   StringMap<T> &getData() { return Data; }
getData()369   const StringMap<T> &getData() const { return Data; }
370 
371   bool operator==(const OrderedChangedData<T> &That) const {
372     return Data == That.getData();
373   }
374 
375   // Call the lambda \p HandlePair on each corresponding pair of data from
376   // \p Before and \p After.  The order is based on the order in \p After
377   // with ones that are only in \p Before interspersed based on where they
378   // occur in \p Before.  This is used to present the output in an order
379   // based on how the data is ordered in LLVM.
380   static void report(const OrderedChangedData &Before,
381                      const OrderedChangedData &After,
382                      function_ref<void(const T *, const T *)> HandlePair);
383 
384 protected:
385   std::vector<std::string> Order;
386   StringMap<T> Data;
387 };
388 
389 // Do not need extra information for patch-style change reporter.
390 class EmptyData {
391 public:
EmptyData(const BasicBlock &)392   EmptyData(const BasicBlock &) {}
EmptyData(const MachineBasicBlock &)393   EmptyData(const MachineBasicBlock &) {}
394 };
395 
396 // The data saved for comparing functions.
397 template <typename T>
398 class FuncDataT : public OrderedChangedData<BlockDataT<T>> {
399 public:
FuncDataT(std::string S)400   FuncDataT(std::string S) : EntryBlockName(S) {}
401 
402   // Return the name of the entry block
getEntryBlockName()403   std::string getEntryBlockName() const { return EntryBlockName; }
404 
405 protected:
406   std::string EntryBlockName;
407 };
408 
409 // The data saved for comparing IRs.
410 template <typename T>
411 class IRDataT : public OrderedChangedData<FuncDataT<T>> {};
412 
413 // Abstract template base class for a class that compares two IRs.  The
414 // class is created with the 2 IRs to compare and then compare is called.
415 // The static function analyzeIR is used to build up the IR representation.
416 template <typename T> class IRComparer {
417 public:
IRComparer(const IRDataT<T> & Before,const IRDataT<T> & After)418   IRComparer(const IRDataT<T> &Before, const IRDataT<T> &After)
419       : Before(Before), After(After) {}
420 
421   // Compare the 2 IRs. \p handleFunctionCompare is called to handle the
422   // compare of a function. When \p InModule is set,
423   // this function is being handled as part of comparing a module.
424   void compare(
425       bool CompareModule,
426       std::function<void(bool InModule, unsigned Minor,
427                          const FuncDataT<T> &Before, const FuncDataT<T> &After)>
428           CompareFunc);
429 
430   // Analyze \p IR and build the IR representation in \p Data.
431   static void analyzeIR(Any IR, IRDataT<T> &Data);
432 
433 protected:
434   // Generate the data for \p F into \p Data.
435   template <typename FunctionT>
436   static bool generateFunctionData(IRDataT<T> &Data, const FunctionT &F);
437 
438   const IRDataT<T> &Before;
439   const IRDataT<T> &After;
440 };
441 
442 // A change printer that prints out in-line differences in the basic
443 // blocks.  It uses an InlineComparer to do the comparison so it shows
444 // the differences prefixed with '-' and '+' for code that is removed
445 // and added, respectively.  Changes to the IR that do not affect basic
446 // blocks are not reported as having changed the IR.  The option
447 // -print-module-scope does not affect this change reporter.
448 class LLVM_ABI InLineChangePrinter
449     : public TextChangeReporter<IRDataT<EmptyData>> {
450 public:
InLineChangePrinter(bool VerboseMode,bool ColourMode)451   InLineChangePrinter(bool VerboseMode, bool ColourMode)
452       : TextChangeReporter<IRDataT<EmptyData>>(VerboseMode),
453         UseColour(ColourMode) {}
454   ~InLineChangePrinter() override;
455   void registerCallbacks(PassInstrumentationCallbacks &PIC);
456 
457 protected:
458   // Create a representation of the IR.
459   void generateIRRepresentation(Any IR, StringRef PassID,
460                                 IRDataT<EmptyData> &Output) override;
461 
462   // Called when an interesting IR has changed.
463   void handleAfter(StringRef PassID, std::string &Name,
464                    const IRDataT<EmptyData> &Before,
465                    const IRDataT<EmptyData> &After, Any) override;
466 
467   void handleFunctionCompare(StringRef Name, StringRef Prefix, StringRef PassID,
468                              StringRef Divider, bool InModule, unsigned Minor,
469                              const FuncDataT<EmptyData> &Before,
470                              const FuncDataT<EmptyData> &After);
471 
472   bool UseColour;
473 };
474 
475 class VerifyInstrumentation {
476   bool DebugLogging;
477 
478 public:
VerifyInstrumentation(bool DebugLogging)479   VerifyInstrumentation(bool DebugLogging) : DebugLogging(DebugLogging) {}
480   LLVM_ABI void registerCallbacks(PassInstrumentationCallbacks &PIC,
481                                   ModuleAnalysisManager *MAM);
482 };
483 
484 /// This class implements --time-trace functionality for new pass manager.
485 /// It provides the pass-instrumentation callbacks that measure the pass
486 /// execution time. They collect time tracing info by TimeProfiler.
487 class TimeProfilingPassesHandler {
488 public:
489   LLVM_ABI TimeProfilingPassesHandler();
490   // We intend this to be unique per-compilation, thus no copies.
491   TimeProfilingPassesHandler(const TimeProfilingPassesHandler &) = delete;
492   void operator=(const TimeProfilingPassesHandler &) = delete;
493 
494   LLVM_ABI void registerCallbacks(PassInstrumentationCallbacks &PIC);
495 
496 private:
497   // Implementation of pass instrumentation callbacks.
498   void runBeforePass(StringRef PassID, Any IR);
499   void runAfterPass();
500 };
501 
502 // Class that holds transitions between basic blocks.  The transitions
503 // are contained in a map of values to names of basic blocks.
504 class DCData {
505 public:
506   // Fill the map with the transitions from basic block \p B.
507   LLVM_ABI DCData(const BasicBlock &B);
508   LLVM_ABI DCData(const MachineBasicBlock &B);
509 
510   // Return an iterator to the names of the successor blocks.
begin()511   StringMap<std::string>::const_iterator begin() const {
512     return Successors.begin();
513   }
end()514   StringMap<std::string>::const_iterator end() const {
515     return Successors.end();
516   }
517 
518   // Return the label of the basic block reached on a transition on \p S.
getSuccessorLabel(StringRef S)519   StringRef getSuccessorLabel(StringRef S) const {
520     assert(Successors.count(S) == 1 && "Expected to find successor.");
521     return Successors.find(S)->getValue();
522   }
523 
524 protected:
525   // Add a transition to \p Succ on \p Label
addSuccessorLabel(StringRef Succ,StringRef Label)526   void addSuccessorLabel(StringRef Succ, StringRef Label) {
527     std::pair<std::string, std::string> SS{Succ.str(), Label.str()};
528     Successors.insert(SS);
529   }
530 
531   StringMap<std::string> Successors;
532 };
533 
534 // A change reporter that builds a website with links to pdf files showing
535 // dot control flow graphs with changed instructions shown in colour.
536 class LLVM_ABI DotCfgChangeReporter : public ChangeReporter<IRDataT<DCData>> {
537 public:
538   DotCfgChangeReporter(bool Verbose);
539   ~DotCfgChangeReporter() override;
540   void registerCallbacks(PassInstrumentationCallbacks &PIC);
541 
542 protected:
543   // Initialize the HTML file and output the header.
544   bool initializeHTML();
545 
546   // Called on the first IR processed.
547   void handleInitialIR(Any IR) override;
548   // Called before and after a pass to get the representation of the IR.
549   void generateIRRepresentation(Any IR, StringRef PassID,
550                                 IRDataT<DCData> &Output) override;
551   // Called when the pass is not iteresting.
552   void omitAfter(StringRef PassID, std::string &Name) override;
553   // Called when an interesting IR has changed.
554   void handleAfter(StringRef PassID, std::string &Name,
555                    const IRDataT<DCData> &Before, const IRDataT<DCData> &After,
556                    Any) override;
557   // Called when an interesting pass is invalidated.
558   void handleInvalidated(StringRef PassID) override;
559   // Called when the IR or pass is not interesting.
560   void handleFiltered(StringRef PassID, std::string &Name) override;
561   // Called when an ignored pass is encountered.
562   void handleIgnored(StringRef PassID, std::string &Name) override;
563 
564   // Generate the pdf file into \p Dir / \p PDFFileName using \p DotFile as
565   // input and return the html <a> tag with \Text as the content.
566   static std::string genHTML(StringRef Text, StringRef DotFile,
567                              StringRef PDFFileName);
568 
569   void handleFunctionCompare(StringRef Name, StringRef Prefix, StringRef PassID,
570                              StringRef Divider, bool InModule, unsigned Minor,
571                              const FuncDataT<DCData> &Before,
572                              const FuncDataT<DCData> &After);
573 
574   unsigned N = 0;
575   std::unique_ptr<raw_fd_ostream> HTML;
576 };
577 
578 // Print IR on crash.
579 class PrintCrashIRInstrumentation {
580 public:
PrintCrashIRInstrumentation()581   PrintCrashIRInstrumentation()
582       : SavedIR("*** Dump of IR Before Last Pass Unknown ***") {}
583   LLVM_ABI ~PrintCrashIRInstrumentation();
584   LLVM_ABI void registerCallbacks(PassInstrumentationCallbacks &PIC);
585   LLVM_ABI void reportCrashIR();
586 
587 protected:
588   std::string SavedIR;
589 
590 private:
591   // The crash reporter that will report on a crash.
592   static PrintCrashIRInstrumentation *CrashReporter;
593   // Crash handler registered when print-on-crash is specified.
594   static void SignalHandler(void *);
595 };
596 
597 /// This class provides an interface to register all the standard pass
598 /// instrumentations and manages their state (if any).
599 class StandardInstrumentations {
600   PrintIRInstrumentation PrintIR;
601   PrintPassInstrumentation PrintPass;
602   TimePassesHandler TimePasses;
603   TimeProfilingPassesHandler TimeProfilingPasses;
604   OptNoneInstrumentation OptNone;
605   OptPassGateInstrumentation OptPassGate;
606   PreservedCFGCheckerInstrumentation PreservedCFGChecker;
607   IRChangedPrinter PrintChangedIR;
608   PseudoProbeVerifier PseudoProbeVerification;
609   InLineChangePrinter PrintChangedDiff;
610   DotCfgChangeReporter WebsiteChangeReporter;
611   PrintCrashIRInstrumentation PrintCrashIR;
612   IRChangedTester ChangeTester;
613   VerifyInstrumentation Verify;
614   DroppedVariableStatsIR DroppedStatsIR;
615 
616   bool VerifyEach;
617 
618 public:
619   LLVM_ABI
620   StandardInstrumentations(LLVMContext &Context, bool DebugLogging,
621                            bool VerifyEach = false,
622                            PrintPassOptions PrintPassOpts = PrintPassOptions());
623 
624   // Register all the standard instrumentation callbacks. If \p FAM is nullptr
625   // then PreservedCFGChecker is not enabled.
626   LLVM_ABI void registerCallbacks(PassInstrumentationCallbacks &PIC,
627                                   ModuleAnalysisManager *MAM = nullptr);
628 
getTimePasses()629   TimePassesHandler &getTimePasses() { return TimePasses; }
630 };
631 
632 extern template class BlockDataT<EmptyData>;
633 extern template class FuncDataT<EmptyData>;
634 extern template class IRDataT<EmptyData>;
635 extern template class IRComparer<EmptyData>;
636 
637 } // namespace llvm
638 
639 #endif
640