1 //===- PassInstrumentation.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 9 #ifndef MLIR_PASS_PASSINSTRUMENTATION_H_ 10 #define MLIR_PASS_PASSINSTRUMENTATION_H_ 11 12 #include "mlir/Support/LLVM.h" 13 #include "mlir/Support/TypeID.h" 14 15 namespace mlir { 16 class OperationName; 17 class Operation; 18 class Pass; 19 20 namespace detail { 21 struct PassInstrumentorImpl; 22 } // namespace detail 23 24 /// PassInstrumentation provides several entry points into the pass manager 25 /// infrastructure. Instrumentations should be added directly to a PassManager 26 /// before running a pipeline. 27 class PassInstrumentation { 28 public: 29 /// This struct represents information related to the parent pass of pipeline. 30 /// It includes information that allows for effectively linking pipelines that 31 /// run on different threads. 32 struct PipelineParentInfo { 33 /// The thread of the parent pass that the current pipeline was spawned 34 /// from. Note: This is acquired from llvm::get_threadid(). 35 uint64_t parentThreadID; 36 37 /// The pass that spawned this pipeline. 38 Pass *parentPass; 39 }; 40 41 virtual ~PassInstrumentation() = 0; 42 43 /// A callback to run before a pass pipeline is executed. This function takes 44 /// the name of the operation type being operated on, or None if the pipeline 45 /// is op-agnostic, and information related to the parent that spawned this 46 /// pipeline. 47 virtual void runBeforePipeline(Optional<OperationName> name, 48 const PipelineParentInfo &parentInfo); 49 50 /// A callback to run after a pass pipeline has executed. This function takes 51 /// the name of the operation type being operated on, or None if the pipeline 52 /// is op-agnostic, and information related to the parent that spawned this 53 /// pipeline. 54 virtual void runAfterPipeline(Optional<OperationName> name, 55 const PipelineParentInfo &parentInfo); 56 57 /// A callback to run before a pass is executed. This function takes a pointer 58 /// to the pass to be executed, as well as the current operation being 59 /// operated on. runBeforePass(Pass * pass,Operation * op)60 virtual void runBeforePass(Pass *pass, Operation *op) {} 61 62 /// A callback to run after a pass is successfully executed. This function 63 /// takes a pointer to the pass to be executed, as well as the current 64 /// operation being operated on. runAfterPass(Pass * pass,Operation * op)65 virtual void runAfterPass(Pass *pass, Operation *op) {} 66 67 /// A callback to run when a pass execution fails. This function takes a 68 /// pointer to the pass that was being executed, as well as the current 69 /// operation being operated on. Note that the operation may be in an invalid 70 /// state. runAfterPassFailed(Pass * pass,Operation * op)71 virtual void runAfterPassFailed(Pass *pass, Operation *op) {} 72 73 /// A callback to run before an analysis is computed. This function takes the 74 /// name of the analysis to be computed, its TypeID, as well as the 75 /// current operation being analyzed. runBeforeAnalysis(StringRef name,TypeID id,Operation * op)76 virtual void runBeforeAnalysis(StringRef name, TypeID id, Operation *op) {} 77 78 /// A callback to run before an analysis is computed. This function takes the 79 /// name of the analysis that was computed, its TypeID, as well as the 80 /// current operation being analyzed. runAfterAnalysis(StringRef name,TypeID id,Operation * op)81 virtual void runAfterAnalysis(StringRef name, TypeID id, Operation *op) {} 82 }; 83 84 /// This class holds a collection of PassInstrumentation objects, and invokes 85 /// their respective call backs. 86 class PassInstrumentor { 87 public: 88 PassInstrumentor(); 89 PassInstrumentor(PassInstrumentor &&) = delete; 90 PassInstrumentor(const PassInstrumentor &) = delete; 91 ~PassInstrumentor(); 92 93 /// See PassInstrumentation::runBeforePipeline for details. 94 void 95 runBeforePipeline(Optional<OperationName> name, 96 const PassInstrumentation::PipelineParentInfo &parentInfo); 97 98 /// See PassInstrumentation::runAfterPipeline for details. 99 void 100 runAfterPipeline(Optional<OperationName> name, 101 const PassInstrumentation::PipelineParentInfo &parentInfo); 102 103 /// See PassInstrumentation::runBeforePass for details. 104 void runBeforePass(Pass *pass, Operation *op); 105 106 /// See PassInstrumentation::runAfterPass for details. 107 void runAfterPass(Pass *pass, Operation *op); 108 109 /// See PassInstrumentation::runAfterPassFailed for details. 110 void runAfterPassFailed(Pass *pass, Operation *op); 111 112 /// See PassInstrumentation::runBeforeAnalysis for details. 113 void runBeforeAnalysis(StringRef name, TypeID id, Operation *op); 114 115 /// See PassInstrumentation::runAfterAnalysis for details. 116 void runAfterAnalysis(StringRef name, TypeID id, Operation *op); 117 118 /// Add the given instrumentation to the collection. 119 void addInstrumentation(std::unique_ptr<PassInstrumentation> pi); 120 121 private: 122 std::unique_ptr<detail::PassInstrumentorImpl> impl; 123 }; 124 125 } // namespace mlir 126 127 namespace llvm { 128 template <> 129 struct DenseMapInfo<mlir::PassInstrumentation::PipelineParentInfo> { 130 using T = mlir::PassInstrumentation::PipelineParentInfo; 131 using PairInfo = DenseMapInfo<std::pair<uint64_t, void *>>; 132 133 static T getEmptyKey() { 134 auto pair = PairInfo::getEmptyKey(); 135 return {pair.first, reinterpret_cast<mlir::Pass *>(pair.second)}; 136 } 137 static T getTombstoneKey() { 138 auto pair = PairInfo::getTombstoneKey(); 139 return {pair.first, reinterpret_cast<mlir::Pass *>(pair.second)}; 140 } 141 static unsigned getHashValue(T val) { 142 return PairInfo::getHashValue({val.parentThreadID, val.parentPass}); 143 } 144 static bool isEqual(T lhs, T rhs) { 145 return lhs.parentThreadID == rhs.parentThreadID && 146 lhs.parentPass == rhs.parentPass; 147 } 148 }; 149 } // namespace llvm 150 151 #endif // MLIR_PASS_PASSINSTRUMENTATION_H_ 152