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