LCOV - code coverage report
Current view: top level - include/llvm/IR - PassInstrumentation.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 169 277 61.0 %
Date: 2018-10-20 13:21:21 Functions: 48 61 78.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- llvm/IR/PassInstrumentation.h ----------------------*- C++ -*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : /// \file
      10             : ///
      11             : /// This file defines the Pass Instrumentation classes that provide
      12             : /// instrumentation points into the pass execution by PassManager.
      13             : ///
      14             : /// There are two main classes:
      15             : ///   - PassInstrumentation provides a set of instrumentation points for
      16             : ///     pass managers to call on.
      17             : ///
      18             : ///   - PassInstrumentationCallbacks registers callbacks and provides access
      19             : ///     to them for PassInstrumentation.
      20             : ///
      21             : /// PassInstrumentation object is being used as a result of
      22             : /// PassInstrumentationAnalysis (so it is intended to be easily copyable).
      23             : ///
      24             : /// Intended scheme of use for Pass Instrumentation is as follows:
      25             : ///    - register instrumentation callbacks in PassInstrumentationCallbacks
      26             : ///      instance. PassBuilder provides helper for that.
      27             : ///
      28             : ///    - register PassInstrumentationAnalysis with all the PassManagers.
      29             : ///      PassBuilder handles that automatically when registering analyses.
      30             : ///
      31             : ///    - Pass Manager requests PassInstrumentationAnalysis from analysis manager
      32             : ///      and gets PassInstrumentation as its result.
      33             : ///
      34             : ///    - Pass Manager invokes PassInstrumentation entry points appropriately,
      35             : ///      passing StringRef identification ("name") of the pass currently being
      36             : ///      executed and IRUnit it works on. There can be different schemes of
      37             : ///      providing names in future, currently it is just a name() of the pass.
      38             : ///
      39             : ///    - PassInstrumentation wraps address of IRUnit into llvm::Any and passes
      40             : ///      control to all the registered callbacks. Note that we specifically wrap
      41             : ///      'const IRUnitT*' so as to avoid any accidental changes to IR in
      42             : ///      instrumenting callbacks.
      43             : ///
      44             : ///    - Some instrumentation points (BeforePass) allow to control execution
      45             : ///      of a pass. For those callbacks returning false means pass will not be
      46             : ///      executed.
      47             : ///
      48             : /// TODO: currently there is no way for a pass to opt-out of execution control
      49             : /// (e.g. become unskippable). PassManager is the only entity that determines
      50             : /// how pass instrumentation affects pass execution.
      51             : ///
      52             : //===----------------------------------------------------------------------===//
      53             : 
      54             : #ifndef LLVM_IR_PASSINSTRUMENTATION_H
      55             : #define LLVM_IR_PASSINSTRUMENTATION_H
      56             : 
      57             : #include "llvm/ADT/Any.h"
      58             : #include "llvm/ADT/FunctionExtras.h"
      59             : #include "llvm/ADT/SmallVector.h"
      60             : #include "llvm/Support/TypeName.h"
      61             : #include <type_traits>
      62             : 
      63             : namespace llvm {
      64             : 
      65             : class PreservedAnalyses;
      66             : 
      67             : /// This class manages callbacks registration, as well as provides a way for
      68             : /// PassInstrumentation to pass control to the registered callbacks.
      69             : class PassInstrumentationCallbacks {
      70             : public:
      71             :   // Before/After callbacks accept IRUnits, so they need to take them
      72             :   // as pointers, wrapped with llvm::Any
      73             :   using BeforePassFunc = bool(StringRef, Any);
      74             :   using AfterPassFunc = void(StringRef, Any);
      75             :   using BeforeAnalysisFunc = void(StringRef, Any);
      76             :   using AfterAnalysisFunc = void(StringRef, Any);
      77             : 
      78             : public:
      79         955 :   PassInstrumentationCallbacks() {}
      80             : 
      81             :   /// Copying PassInstrumentationCallbacks is not intended.
      82             :   PassInstrumentationCallbacks(const PassInstrumentationCallbacks &) = delete;
      83             :   void operator=(const PassInstrumentationCallbacks &) = delete;
      84             : 
      85             :   template <typename CallableT> void registerBeforePassCallback(CallableT C) {
      86          12 :     BeforePassCallbacks.emplace_back(std::move(C));
      87             :   }
      88             : 
      89             :   template <typename CallableT> void registerAfterPassCallback(CallableT C) {
      90          18 :     AfterPassCallbacks.emplace_back(std::move(C));
      91             :   }
      92             : 
      93             :   template <typename CallableT>
      94             :   void registerBeforeAnalysisCallback(CallableT C) {
      95          11 :     BeforeAnalysisCallbacks.emplace_back(std::move(C));
      96             :   }
      97             : 
      98             :   template <typename CallableT>
      99             :   void registerAfterAnalysisCallback(CallableT C) {
     100          11 :     AfterAnalysisCallbacks.emplace_back(std::move(C));
     101             :   }
     102             : 
     103             : private:
     104             :   friend class PassInstrumentation;
     105             : 
     106             :   SmallVector<llvm::unique_function<BeforePassFunc>, 4> BeforePassCallbacks;
     107             :   SmallVector<llvm::unique_function<AfterPassFunc>, 4> AfterPassCallbacks;
     108             :   SmallVector<llvm::unique_function<BeforeAnalysisFunc>, 4>
     109             :       BeforeAnalysisCallbacks;
     110             :   SmallVector<llvm::unique_function<AfterAnalysisFunc>, 4>
     111             :       AfterAnalysisCallbacks;
     112             : };
     113             : 
     114             : /// This class provides instrumentation entry points for the Pass Manager,
     115             : /// doing calls to callbacks registered in PassInstrumentationCallbacks.
     116             : class PassInstrumentation {
     117             :   PassInstrumentationCallbacks *Callbacks;
     118             : 
     119             : public:
     120             :   /// Callbacks object is not owned by PassInstrumentation, its life-time
     121             :   /// should at least match the life-time of corresponding
     122             :   /// PassInstrumentationAnalysis (which usually is till the end of current
     123             :   /// compilation).
     124             :   PassInstrumentation(PassInstrumentationCallbacks *CB = nullptr)
     125       31741 :       : Callbacks(CB) {}
     126             : 
     127             :   /// BeforePass instrumentation point - takes \p Pass instance to be executed
     128             :   /// and constant reference to IR it operates on. \Returns true if pass is
     129             :   /// allowed to be executed.
     130             :   template <typename IRUnitT, typename PassT>
     131       28243 :   bool runBeforePass(const PassT &Pass, const IRUnitT &IR) const {
     132       28243 :     if (!Callbacks)
     133           0 :       return true;
     134             : 
     135             :     bool ShouldRun = true;
     136       20527 :     for (auto &C : Callbacks->BeforePassCallbacks)
     137         634 :       ShouldRun &= C(Pass.name(), llvm::Any(&IR));
     138             :     return ShouldRun;
     139             :   }
     140       12918 : 
     141       12918 :   /// AfterPass instrumentation point - takes \p Pass instance that has
     142             :   /// just been executed and constant reference to IR it operates on.
     143             :   template <typename IRUnitT, typename PassT>
     144        3216 :   void runAfterPass(const PassT &Pass, const IRUnitT &IR) const {
     145       11455 :     if (Callbacks)
     146        2945 :       for (auto &C : Callbacks->AfterPassCallbacks)
     147          68 :         C(Pass.name(), llvm::Any(&IR));
     148        3216 :   }
     149        7945 : 
     150        7945 :   /// BeforeAnalysis instrumentation point - takes \p Analysis instance
     151             :   /// to be executed and constant reference to IR it operates on.
     152             :   template <typename IRUnitT, typename PassT>
     153        5143 :   void runBeforeAnalysis(const PassT &Analysis, const IRUnitT &IR) const {
     154       11533 :     if (Callbacks)
     155        4145 :       for (auto &C : Callbacks->BeforeAnalysisCallbacks)
     156          60 :         C(Analysis.name(), llvm::Any(&IR));
     157        5143 :   }
     158         387 : 
     159         387 :   /// AfterAnalysis instrumentation point - takes \p Analysis instance
     160         120 :   /// that has just been executed and constant reference to IR it operated on.
     161           0 :   template <typename IRUnitT, typename PassT>
     162       23828 :   void runAfterAnalysis(const PassT &Analysis, const IRUnitT &IR) const {
     163       26919 :     if (Callbacks)
     164       18998 :       for (auto &C : Callbacks->AfterAnalysisCallbacks)
     165        3237 :         C(Analysis.name(), llvm::Any(&IR));
     166       23698 :   }
     167       16182 : 
     168       12991 :   /// Handle invalidation from the pass manager when PassInstrumentation
     169        8205 :   /// is used as the result of PassInstrumentationAnalysis.
     170         378 :   ///
     171       12857 :   /// On attempt to invalidate just return false. There is nothing to become
     172       11975 :   /// invalid here.
     173       11915 :   template <typename IRUnitT, typename... ExtraArgsT>
     174        8861 :   bool invalidate(IRUnitT &, const class llvm::PreservedAnalyses &,
     175         214 :                   ExtraArgsT...) {
     176       11914 :     return false;
     177         490 :   }
     178         487 : };
     179         402 : 
     180          35 : } // namespace llvm
     181       24263 : 
     182       27765 : #endif

Generated by: LCOV version 1.13