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/IR/Identifier.h" 13 #include "mlir/Support/LLVM.h" 14 #include "mlir/Support/TypeID.h" 15 16 namespace mlir { 17 class Operation; 18 class Pass; 19 20 namespace detail { 21 struct PassInstrumentorImpl; 22 } // end 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, and information related 45 /// to the parent that spawned this pipeline. runBeforePipeline(Identifier name,const PipelineParentInfo & parentInfo)46 virtual void runBeforePipeline(Identifier name, 47 const PipelineParentInfo &parentInfo) {} 48 49 /// A callback to run after a pass pipeline has executed. This function takes 50 /// the name of the operation type being operated on, and information related 51 /// to the parent that spawned this pipeline. runAfterPipeline(Identifier name,const PipelineParentInfo & parentInfo)52 virtual void runAfterPipeline(Identifier name, 53 const PipelineParentInfo &parentInfo) {} 54 55 /// A callback to run before a pass is executed. This function takes a pointer 56 /// to the pass to be executed, as well as the current operation being 57 /// operated on. runBeforePass(Pass * pass,Operation * op)58 virtual void runBeforePass(Pass *pass, Operation *op) {} 59 60 /// A callback to run after a pass is successfully executed. This function 61 /// takes a pointer to the pass to be executed, as well as the current 62 /// operation being operated on. runAfterPass(Pass * pass,Operation * op)63 virtual void runAfterPass(Pass *pass, Operation *op) {} 64 65 /// A callback to run when a pass execution fails. This function takes a 66 /// pointer to the pass that was being executed, as well as the current 67 /// operation being operated on. Note that the operation may be in an invalid 68 /// state. runAfterPassFailed(Pass * pass,Operation * op)69 virtual void runAfterPassFailed(Pass *pass, Operation *op) {} 70 71 /// A callback to run before an analysis is computed. This function takes the 72 /// name of the analysis to be computed, its TypeID, as well as the 73 /// current operation being analyzed. runBeforeAnalysis(StringRef name,TypeID id,Operation * op)74 virtual void runBeforeAnalysis(StringRef name, TypeID id, Operation *op) {} 75 76 /// A callback to run before an analysis is computed. This function takes the 77 /// name of the analysis that was computed, its TypeID, as well as the 78 /// current operation being analyzed. runAfterAnalysis(StringRef name,TypeID id,Operation * op)79 virtual void runAfterAnalysis(StringRef name, TypeID id, Operation *op) {} 80 }; 81 82 /// This class holds a collection of PassInstrumentation objects, and invokes 83 /// their respective call backs. 84 class PassInstrumentor { 85 public: 86 PassInstrumentor(); 87 PassInstrumentor(PassInstrumentor &&) = delete; 88 PassInstrumentor(const PassInstrumentor &) = delete; 89 ~PassInstrumentor(); 90 91 /// See PassInstrumentation::runBeforePipeline for details. 92 void 93 runBeforePipeline(Identifier name, 94 const PassInstrumentation::PipelineParentInfo &parentInfo); 95 96 /// See PassInstrumentation::runAfterPipeline for details. 97 void 98 runAfterPipeline(Identifier name, 99 const PassInstrumentation::PipelineParentInfo &parentInfo); 100 101 /// See PassInstrumentation::runBeforePass for details. 102 void runBeforePass(Pass *pass, Operation *op); 103 104 /// See PassInstrumentation::runAfterPass for details. 105 void runAfterPass(Pass *pass, Operation *op); 106 107 /// See PassInstrumentation::runAfterPassFailed for details. 108 void runAfterPassFailed(Pass *pass, Operation *op); 109 110 /// See PassInstrumentation::runBeforeAnalysis for details. 111 void runBeforeAnalysis(StringRef name, TypeID id, Operation *op); 112 113 /// See PassInstrumentation::runAfterAnalysis for details. 114 void runAfterAnalysis(StringRef name, TypeID id, Operation *op); 115 116 /// Add the given instrumentation to the collection. 117 void addInstrumentation(std::unique_ptr<PassInstrumentation> pi); 118 119 private: 120 std::unique_ptr<detail::PassInstrumentorImpl> impl; 121 }; 122 123 } // end namespace mlir 124 125 namespace llvm { 126 template <> struct DenseMapInfo<mlir::PassInstrumentation::PipelineParentInfo> { 127 using T = mlir::PassInstrumentation::PipelineParentInfo; 128 using PairInfo = DenseMapInfo<std::pair<uint64_t, void *>>; 129 130 static T getEmptyKey() { 131 auto pair = PairInfo::getEmptyKey(); 132 return {pair.first, reinterpret_cast<mlir::Pass *>(pair.second)}; 133 } 134 static T getTombstoneKey() { 135 auto pair = PairInfo::getTombstoneKey(); 136 return {pair.first, reinterpret_cast<mlir::Pass *>(pair.second)}; 137 } 138 static unsigned getHashValue(T val) { 139 return PairInfo::getHashValue({val.parentThreadID, val.parentPass}); 140 } 141 static bool isEqual(T lhs, T rhs) { 142 return lhs.parentThreadID == rhs.parentThreadID && 143 lhs.parentPass == rhs.parentPass; 144 } 145 }; 146 } // end namespace llvm 147 148 #endif // MLIR_PASS_PASSINSTRUMENTATION_H_ 149