Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

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