1 //===- PassDetail.h - MLIR Pass details -------------------------*- 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 #ifndef MLIR_PASS_PASSDETAIL_H_ 9 #define MLIR_PASS_PASSDETAIL_H_ 10 11 #include "mlir/Pass/Pass.h" 12 #include "mlir/Pass/PassManager.h" 13 14 namespace mlir { 15 namespace detail { 16 17 //===----------------------------------------------------------------------===// 18 // OpToOpPassAdaptor 19 //===----------------------------------------------------------------------===// 20 21 /// An adaptor pass used to run operation passes over nested operations. 22 class OpToOpPassAdaptor 23 : public PassWrapper<OpToOpPassAdaptor, OperationPass<>> { 24 public: 25 OpToOpPassAdaptor(OpPassManager &&mgr); 26 OpToOpPassAdaptor(const OpToOpPassAdaptor &rhs) = default; 27 28 /// Run the held pipeline over all operations. 29 void runOnOperation(bool verifyPasses); 30 void runOnOperation() override; 31 32 /// Try to merge the current pass adaptor into 'rhs'. This will try to append 33 /// the pass managers of this adaptor into those within `rhs`, or return 34 /// failure if merging isn't possible. The main situation in which merging is 35 /// not possible is if one of the adaptors has an `any` pipeline that is not 36 /// compatible with a pass manager in the other adaptor. For example, if this 37 /// adaptor has a `func.func` pipeline and `rhs` has an `any` pipeline that 38 /// operates on FunctionOpInterface. In this situation the pipelines have a 39 /// conflict (they both want to run on the same operations), so we can't 40 /// merge. 41 LogicalResult tryMergeInto(MLIRContext *ctx, OpToOpPassAdaptor &rhs); 42 43 /// Returns the pass managers held by this adaptor. getPassManagers()44 MutableArrayRef<OpPassManager> getPassManagers() { return mgrs; } 45 46 /// Populate the set of dependent dialects for the passes in the current 47 /// adaptor. 48 void getDependentDialects(DialectRegistry &dialects) const override; 49 50 /// Return the async pass managers held by this parallel adaptor. getParallelPassManagers()51 MutableArrayRef<SmallVector<OpPassManager, 1>> getParallelPassManagers() { 52 return asyncExecutors; 53 } 54 55 /// Returns the adaptor pass name. 56 std::string getAdaptorName(); 57 58 private: 59 /// Run this pass adaptor synchronously. 60 void runOnOperationImpl(bool verifyPasses); 61 62 /// Run this pass adaptor asynchronously. 63 void runOnOperationAsyncImpl(bool verifyPasses); 64 65 /// Run the given operation and analysis manager on a single pass. 66 /// `parentInitGeneration` is the initialization generation of the parent pass 67 /// manager, and is used to initialize any dynamic pass pipelines run by the 68 /// given pass. 69 static LogicalResult run(Pass *pass, Operation *op, AnalysisManager am, 70 bool verifyPasses, unsigned parentInitGeneration); 71 72 /// Run the given operation and analysis manager on a provided op pass 73 /// manager. `parentInitGeneration` is the initialization generation of the 74 /// parent pass manager, and is used to initialize any dynamic pass pipelines 75 /// run by the given passes. 76 static LogicalResult runPipeline( 77 OpPassManager &pm, Operation *op, AnalysisManager am, bool verifyPasses, 78 unsigned parentInitGeneration, PassInstrumentor *instrumentor = nullptr, 79 const PassInstrumentation::PipelineParentInfo *parentInfo = nullptr); 80 81 /// A set of adaptors to run. 82 SmallVector<OpPassManager, 1> mgrs; 83 84 /// A set of executors, cloned from the main executor, that run asynchronously 85 /// on different threads. This is used when threading is enabled. 86 SmallVector<SmallVector<OpPassManager, 1>, 8> asyncExecutors; 87 88 // For accessing "runPipeline". 89 friend class mlir::PassManager; 90 }; 91 92 //===----------------------------------------------------------------------===// 93 // PassCrashReproducerGenerator 94 //===----------------------------------------------------------------------===// 95 96 class PassCrashReproducerGenerator { 97 public: 98 PassCrashReproducerGenerator( 99 PassManager::ReproducerStreamFactory &streamFactory, 100 bool localReproducer); 101 ~PassCrashReproducerGenerator(); 102 103 /// Initialize the generator in preparation for reproducer generation. The 104 /// generator should be reinitialized before each run of the pass manager. 105 void initialize(iterator_range<PassManager::pass_iterator> passes, 106 Operation *op, bool pmFlagVerifyPasses); 107 /// Finalize the current run of the generator, generating any necessary 108 /// reproducers if the provided execution result is a failure. 109 void finalize(Operation *rootOp, LogicalResult executionResult); 110 111 /// Prepare a new reproducer for the given pass, operating on `op`. 112 void prepareReproducerFor(Pass *pass, Operation *op); 113 114 /// Prepare a new reproducer for the given passes, operating on `op`. 115 void prepareReproducerFor(iterator_range<PassManager::pass_iterator> passes, 116 Operation *op); 117 118 /// Remove the last recorded reproducer anchored at the given pass and 119 /// operation. 120 void removeLastReproducerFor(Pass *pass, Operation *op); 121 122 private: 123 struct Impl; 124 125 /// The internal implementation of the crash reproducer. 126 std::unique_ptr<Impl> impl; 127 }; 128 129 } // namespace detail 130 } // namespace mlir 131 #endif // MLIR_PASS_PASSDETAIL_H_ 132