21 #include "llvm/ADT/Hashing.h"
22 #include "llvm/ADT/STLExtras.h"
23 #include "llvm/ADT/ScopeExit.h"
24 #include "llvm/Support/CommandLine.h"
25 #include "llvm/Support/CrashRecoveryContext.h"
26 #include "llvm/Support/Mutex.h"
27 #include "llvm/Support/Signals.h"
28 #include "llvm/Support/Threading.h"
29 #include "llvm/Support/ToolOutputFile.h"
41 :
Base(irUnits), pass(pass) {}
44 os << llvm::formatv(
"`{0}` running `{1}` on Operation `{2}`",
tag,
50 return irUnits.empty() ? nullptr
51 : llvm::dyn_cast_if_present<Operation *>(
irUnits[0]);
60 void Pass::anchor() {}
65 function_ref<LogicalResult(
const Twine &)> errorHandler) {
67 llvm::raw_string_ostream os(errStr);
69 return errorHandler(errStr);
84 if (
auto *adaptor = dyn_cast<OpToOpPassAdaptor>(
this)) {
86 adaptor->getPassManagers(),
95 if (!argument.empty())
98 os <<
"unknown<" <<
getName() <<
">";
99 passOptions.
print(os);
121 for (
const std::unique_ptr<Pass> &pass : rhs.
passes) {
122 std::unique_ptr<Pass> newPass = pass->clone();
123 newPass->threadingSibling = pass.get();
124 passes.push_back(std::move(newPass));
146 void addPass(std::unique_ptr<Pass> pass);
164 return name.empty() ? std::optional<StringRef>()
165 : std::optional<StringRef>(
name);
187 std::vector<std::unique_ptr<Pass>>
passes;
201 assert(name == rhs.
name &&
"merging unrelated pass managers");
202 for (
auto &pass : passes)
203 rhs.
passes.push_back(std::move(pass));
209 addPass(std::unique_ptr<Pass>(adaptor));
210 return adaptor->getPassManagers().front();
213 void OpPassManagerImpl::addPass(std::unique_ptr<Pass> pass) {
216 std::optional<StringRef> pmOpName = getOpName();
217 std::optional<StringRef> passOpName = pass->getOpName();
218 if (pmOpName && passOpName && *pmOpName != *passOpName) {
220 return nest(*passOpName).addPass(std::move(pass));
221 llvm::report_fatal_error(llvm::Twine(
"Can't add pass '") + pass->getName() +
222 "' restricted to '" + *passOpName +
223 "' on a PassManager intended to run on '" +
224 getOpAnchorName() +
"', did you intend to nest?");
227 passes.emplace_back(std::move(pass));
230 void OpPassManagerImpl::clear() { passes.clear(); }
232 LogicalResult OpPassManagerImpl::finalizePassList(
MLIRContext *ctx) {
234 for (
auto &pm : adaptor->getPassManagers())
235 if (failed(pm.getImpl().finalizePassList(ctx)))
242 for (
auto &pass : passes) {
244 if (
auto *currentAdaptor = dyn_cast<OpToOpPassAdaptor>(pass.get())) {
248 lastAdaptor = currentAdaptor;
254 if (succeeded(currentAdaptor->tryMergeInto(ctx, *lastAdaptor)))
257 lastAdaptor = currentAdaptor;
258 }
else if (lastAdaptor) {
260 if (failed(finalizeAdaptor(lastAdaptor)))
262 lastAdaptor =
nullptr;
267 if (lastAdaptor && failed(finalizeAdaptor(lastAdaptor)))
272 llvm::erase_if(passes, std::logical_not<std::unique_ptr<Pass>>());
275 std::optional<OperationName> rawOpName = getOpName(*ctx);
281 std::optional<RegisteredOperationName> opName =
282 rawOpName->getRegisteredInfo();
283 for (std::unique_ptr<Pass> &pass : passes) {
284 if (opName && !pass->canScheduleOn(*opName)) {
286 <<
"unable to schedule pass '" << pass->getName()
287 <<
"' on a PassManager intended to run on '" << getOpAnchorName()
298 std::optional<OperationName> pmOpName = getOpName(context);
300 return pmOpName == opName;
304 std::optional<RegisteredOperationName> registeredInfo =
306 if (!registeredInfo ||
309 return llvm::all_of(passes, [&](
const std::unique_ptr<Pass> &pass) {
310 return pass->canScheduleOn(*registeredInfo);
327 impl = std::make_unique<OpPassManagerImpl>(*rhs.impl);
331 impl = std::move(rhs.impl);
354 return impl->nest(nestedName);
357 return impl->nest(nestedName);
364 impl->addPass(std::move(pass));
377 return impl->getOpName();
381 std::optional<OperationName>
383 return impl->getOpName(context);
387 return impl->getOpAnchorName();
393 raw_ostream &os, StringRef anchorName,
395 os << anchorName <<
"(";
398 [&]() { os <<
","; });
410 llvm::errs() <<
"Pass Manager with " <<
impl->passes.size() <<
" passes:\n";
412 llvm::errs() <<
"\n";
418 pass.getDependentDialects(dialects);
429 LogicalResult OpPassManager::initialize(
MLIRContext *context,
430 unsigned newInitGeneration) {
431 if (
impl->initializationGeneration == newInitGeneration)
433 impl->initializationGeneration = newInitGeneration;
436 auto *adaptor = dyn_cast<OpToOpPassAdaptor>(&pass);
438 if (failed(pass.initialize(context)))
445 if (failed(adaptorPM.initialize(context, newInitGeneration)))
451 llvm::hash_code OpPassManager::hash() {
452 llvm::hash_code hashCode{};
455 auto *adaptor = dyn_cast<OpToOpPassAdaptor>(&pass);
457 hashCode = llvm::hash_combine(hashCode, &pass);
462 llvm::hash_combine(hashCode, adaptorPM.hash());
472 LogicalResult OpToOpPassAdaptor::run(
Pass *pass,
Operation *op,
474 unsigned parentInitGeneration) {
478 <<
"trying to schedule a pass on an unregistered operation";
480 return op->
emitOpError() <<
"trying to schedule a pass on an operation not "
481 "marked as 'IsolatedFromAbove'";
484 <<
"trying to schedule a pass on an unsupported operation";
494 return root->emitOpError()
495 <<
"Trying to schedule a dynamic pipeline on an "
496 "operation that isn't "
497 "nested under the current operation the pass is processing";
506 if (failed(pipeline.initialize(root->getContext(), parentInitGeneration)))
509 return OpToOpPassAdaptor::runPipeline(pipeline, root, nestedAm,
510 verifyPasses, parentInitGeneration,
513 pass->passState.emplace(op, am, dynamicPipelineCallback);
519 bool passFailed =
false;
523 if (
auto *adaptor = dyn_cast<OpToOpPassAdaptor>(pass))
524 adaptor->runOnOperation(verifyPasses);
527 passFailed = pass->passState->irAndPassFailed.getInt();
532 am.
invalidate(pass->passState->preservedAnalyses);
536 if (!passFailed && verifyPasses) {
537 bool runVerifierNow =
true;
542 bool runVerifierRecursively = !isa<OpToOpPassAdaptor>(pass);
551 #ifndef EXPENSIVE_CHECKS
552 runVerifierNow = !pass->passState->preservedAnalyses.isAll();
555 passFailed = failed(
verify(op, runVerifierRecursively));
567 return failure(passFailed);
571 LogicalResult OpToOpPassAdaptor::runPipeline(
575 assert((!instrumentor || parentInfo) &&
576 "expected parent info if instrumentor is provided");
577 auto scopeExit = llvm::make_scope_exit([&] {
592 if (failed(run(&pass, op, am, verifyPasses, parentInitGeneration)))
606 auto *it = llvm::find_if(
608 return it == mgrs.end() ? nullptr : &*it;
617 return mgr.
getImpl().canScheduleOn(context, name);
619 return it == mgrs.end() ? nullptr : &*it;
623 mgrs.emplace_back(std::move(mgr));
627 for (
auto &pm : mgrs)
644 if (std::optional<OperationName> pmOpName = pm.
getOpName(*ctx))
657 auto *lhsGenericPMIt = llvm::find_if(mgrs, isGenericPM);
658 if (lhsGenericPMIt != mgrs.end() &&
659 hasScheduleConflictWith(*lhsGenericPMIt, rhs.mgrs))
662 auto *rhsGenericPMIt = llvm::find_if(rhs.mgrs, isGenericPM);
663 if (rhsGenericPMIt != rhs.mgrs.end() &&
664 hasScheduleConflictWith(*rhsGenericPMIt, mgrs))
667 for (
auto &pm : mgrs) {
670 if (
auto *existingPM =
675 rhs.mgrs.emplace_back(std::move(pm));
683 if (std::optional<StringRef> lhsName = lhs->
getOpName()) {
684 if (std::optional<StringRef> rhsName = rhs->
getOpName())
685 return lhsName->compare(*rhsName);
690 llvm::array_pod_sort(rhs.mgrs.begin(), rhs.mgrs.end(), compareFn);
695 std::string OpToOpPassAdaptor::getAdaptorName() {
696 std::string name =
"Pipeline Collection : [";
697 llvm::raw_string_ostream os(name);
698 llvm::interleaveComma(getPassManagers(), os, [&](
OpPassManager &pm) {
705 void OpToOpPassAdaptor::runOnOperation() {
707 "Unexpected call to Pass::runOnOperation() on OpToOpPassAdaptor");
711 void OpToOpPassAdaptor::runOnOperation(
bool verifyPasses) {
713 runOnOperationAsyncImpl(verifyPasses);
715 runOnOperationImpl(verifyPasses);
719 void OpToOpPassAdaptor::runOnOperationImpl(
bool verifyPasses) {
720 auto am = getAnalysisManager();
724 for (
auto ®ion : getOperation()->getRegions()) {
725 for (
auto &block : region) {
726 for (
auto &op : block) {
732 unsigned initGeneration = mgr->impl->initializationGeneration;
733 if (failed(runPipeline(*mgr, &op, am.
nest(&op), verifyPasses,
734 initGeneration, instrumentor, &parentInfo)))
745 return lhs.size() != rhs.size() ||
746 llvm::any_of(llvm::seq<size_t>(0, lhs.size()),
747 [&](
size_t i) { return lhs[i].size() != rhs[i].size(); });
751 void OpToOpPassAdaptor::runOnOperationAsyncImpl(
bool verifyPasses) {
757 if (asyncExecutors.empty() ||
hasSizeMismatch(asyncExecutors.front(), mgrs))
758 asyncExecutors.assign(context->
getThreadPool().getMaxConcurrency(), mgrs);
764 : passManagerIdx(passManagerIdx), op(op), am(am) {}
767 unsigned passManagerIdx;
777 std::vector<OpPMInfo> opInfos;
779 for (
auto ®ion : getOperation()->getRegions()) {
782 auto pmIdxIt = knownOpPMIdx.try_emplace(op.
getName(), std::nullopt);
783 if (pmIdxIt.second) {
785 pmIdxIt.first->second = std::distance(mgrs.begin(), mgr);
789 if (pmIdxIt.first->second)
790 opInfos.emplace_back(*pmIdxIt.first->second, &op, am.
nest(&op));
800 std::vector<std::atomic<bool>> activePMs(asyncExecutors.size());
801 std::fill(activePMs.begin(), activePMs.end(),
false);
802 std::atomic<bool> hasFailure =
false;
805 auto it = llvm::find_if(activePMs, [](std::atomic<bool> &isActive) {
806 bool expectedInactive =
false;
807 return isActive.compare_exchange_strong(expectedInactive,
true);
809 unsigned pmIndex = it - activePMs.begin();
812 OpPassManager &pm = asyncExecutors[pmIndex][opInfo.passManagerIdx];
813 LogicalResult pipelineResult = runPipeline(
814 pm, opInfo.op, opInfo.am, verifyPasses,
815 pm.impl->initializationGeneration, instrumentor, &parentInfo);
816 if (failed(pipelineResult))
817 hasFailure.store(
true);
820 activePMs[pmIndex].store(
false);
834 :
OpPassManager(operationName, nesting), context(ctx), passTiming(false),
835 verifyPasses(true) {}
839 context(operationName.
getContext()), passTiming(false),
840 verifyPasses(true) {}
849 std::optional<OperationName> anchorOp =
getOpName(*context);
850 if (anchorOp && anchorOp != op->
getName())
863 if (failed(
getImpl().finalizePassList(context)))
871 llvm::hash_code pipelineKey = hash();
872 if (newInitKey != initializationKey || pipelineKey != pipelineInitializationKey) {
873 if (failed(initialize(context,
impl->initializationGeneration + 1)))
875 initializationKey = newInitKey;
876 pipelineKey = pipelineInitializationKey;
884 LogicalResult result =
885 crashReproGenerator ? runWithCrashRecovery(op, am) : runPasses(op, am);
891 if (passStatisticsMode)
899 instrumentor = std::make_unique<PassInstrumentor>();
905 return OpToOpPassAdaptor::runPipeline(*
this, op, am, verifyPasses,
906 impl->initializationGeneration);
918 "expected valid descendant operation");
922 return nestImmediate(op);
927 opAncestors.push_back(op);
929 }
while (op != currentOp);
932 for (
Operation *op : llvm::reverse(opAncestors))
933 result = result.nestImmediate(op);
940 "expected immediate child operation");
942 auto [it, inserted] =
impl->childAnalyses.try_emplace(op);
944 it->second = std::make_unique<NestedAnalysisMap>(op,
impl);
945 return {it->second.get()};
967 while (!mapsToInvalidate.empty()) {
968 auto *map = mapsToInvalidate.pop_back_val();
969 for (
auto &analysisPair : map->childAnalyses) {
970 analysisPair.second->invalidate(pa);
971 if (!analysisPair.second->childAnalyses.empty())
972 mapsToInvalidate.push_back(analysisPair.second.get());
1010 std::optional<OperationName> name,
1012 llvm::sys::SmartScopedLock<true> instrumentationLock(
impl->mutex);
1013 for (
auto &instr :
impl->instrumentations)
1014 instr->runBeforePipeline(name, parentInfo);
1019 std::optional<OperationName> name,
1021 llvm::sys::SmartScopedLock<true> instrumentationLock(
impl->mutex);
1022 for (
auto &instr : llvm::reverse(
impl->instrumentations))
1023 instr->runAfterPipeline(name, parentInfo);
1028 llvm::sys::SmartScopedLock<true> instrumentationLock(
impl->mutex);
1029 for (
auto &instr :
impl->instrumentations)
1030 instr->runBeforePass(pass, op);
1035 llvm::sys::SmartScopedLock<true> instrumentationLock(
impl->mutex);
1036 for (
auto &instr : llvm::reverse(
impl->instrumentations))
1037 instr->runAfterPass(pass, op);
1042 llvm::sys::SmartScopedLock<true> instrumentationLock(
impl->mutex);
1043 for (
auto &instr : llvm::reverse(
impl->instrumentations))
1044 instr->runAfterPassFailed(pass, op);
1050 llvm::sys::SmartScopedLock<true> instrumentationLock(
impl->mutex);
1051 for (
auto &instr :
impl->instrumentations)
1052 instr->runBeforeAnalysis(name,
id, op);
1058 llvm::sys::SmartScopedLock<true> instrumentationLock(
impl->mutex);
1059 for (
auto &instr : llvm::reverse(
impl->instrumentations))
1060 instr->runAfterAnalysis(name,
id, op);
1065 std::unique_ptr<PassInstrumentation> pi) {
1066 llvm::sys::SmartScopedLock<true> instrumentationLock(
impl->mutex);
1067 impl->instrumentations.emplace_back(std::move(pi));
static MLIRContext * getContext(OpFoldResult val)
static llvm::ManagedStatic< PassManagerOptions > options
static void registerDialectsForPipeline(const OpPassManager &pm, DialectRegistry &dialects)
static bool hasSizeMismatch(ArrayRef< OpPassManager > lhs, ArrayRef< OpPassManager > rhs)
Utility functor that checks if the two ranges of pass managers have a size mismatch.
static OpPassManager * findPassManagerFor(MutableArrayRef< OpPassManager > mgrs, OperationName name, MLIRContext &context)
Find an operation pass manager that can operate on an operation of the given type,...
void printAsTextualPipeline(raw_ostream &os, StringRef anchorName, const llvm::iterator_range< OpPassManager::pass_iterator > &passes)
Prints out the passes of the pass manager as the textual representation of pipelines.
static OpPassManager * findPassManagerWithAnchor(MutableArrayRef< OpPassManager > mgrs, StringRef name)
Find an operation pass manager with the given anchor name, or nullptr if one does not exist.
This class represents an analysis manager for a particular operation instance.
void clear()
Clear any held analyses.
void invalidate(const PreservedAnalyses &pa)
Invalidate any non preserved analyses,.
AnalysisManager nest(Operation *op)
Get an analysis manager for the given operation, which must be a proper descendant of the current ope...
PassInstrumentor * getPassInstrumentor() const
Returns a pass instrumentation object for the current operation.
The DialectRegistry maps a dialect namespace to a constructor for the matching dialect.
auto getDialectNames() const
Return the names of dialects known to this registry.
MLIRContext is the top-level object for a collection of MLIR operations.
void appendDialectRegistry(const DialectRegistry ®istry)
Append the contents of the given dialect registry to the registry associated with this context.
void executeAction(function_ref< void()> actionFn, const tracing::Action &action)
Dispatch the provided action to the handler if any, or just execute it.
llvm::hash_code getRegistryHash()
Returns a hash of the registry of the context that may be used to give a rough indicator of if the st...
void enterMultiThreadedExecution()
These APIs are tracking whether the context will be used in a multithreading environment: this has no...
llvm::ThreadPoolInterface & getThreadPool()
Return the thread pool used by this context.
T * getOrLoadDialect()
Get (or create) a dialect for the given derived dialect type.
void exitMultiThreadedExecution()
An analysis manager class specifically for the top-level operation.
This class represents a pass manager that runs passes on either a specific operation type,...
OpPassManager & operator=(const OpPassManager &rhs)
friend class PassManager
Allow access to the constructor.
OpPassManager(Nesting nesting=Nesting::Explicit)
Construct a new op-agnostic ("any") pass manager with the given operation type and nesting behavior.
void printAsTextualPipeline(raw_ostream &os) const
Prints out the passes of the pass manager as the textual representation of pipelines.
std::optional< OperationName > getOpName(MLIRContext &context) const
Return the operation name that this pass manager operates on, or std::nullopt if this is an op-agnost...
void setNesting(Nesting nesting)
Enable or disable the implicit nesting on this particular PassManager.
size_t size() const
Returns the number of passes held by this manager.
detail::OpPassManagerImpl & getImpl()
Returns the internal implementation instance.
void addPass(std::unique_ptr< Pass > pass)
Add the given pass to this pass manager.
Nesting getNesting()
Return the current nesting mode.
Nesting
This enum represents the nesting behavior of the pass manager.
@ Implicit
Implicit nesting behavior.
void dump()
Raw dump of the pass manager to llvm::errs().
llvm::pointee_iterator< MutableArrayRef< std::unique_ptr< Pass > >::iterator > pass_iterator
Iterator over the passes in this pass manager.
llvm::pointee_iterator< ArrayRef< std::unique_ptr< Pass > >::const_iterator > const_pass_iterator
void getDependentDialects(DialectRegistry &dialects) const
Register dependent dialects for the current pass manager.
StringRef getOpAnchorName() const
Return the name used to anchor this pass manager.
std::optional< StringRef > getOpName() const
Return the operation name that this pass manager operates on, or std::nullopt if this is an op-agnost...
OpPassManager & nestAny()
Nest a new op-agnostic ("any") pass manager under this pass manager.
iterator_range< pass_iterator > getPasses()
static StringRef getAnyOpAnchorName()
Return the string name used to anchor op-agnostic pass managers that operate generically on any viabl...
void clear()
Clear the pipeline, but not the other options set on this OpPassManager.
This class provides the API for ops that are known to be isolated from above.
std::optional< RegisteredOperationName > getRegisteredInfo() const
If this operation is registered, returns the registered information, std::nullopt otherwise.
Operation is the basic unit of execution within MLIR.
MLIRContext * getContext()
Return the context this operation is associated with.
std::optional< RegisteredOperationName > getRegisteredInfo()
If this operation has a registered operation description, return it.
Location getLoc()
The source location the operation was defined or derived from.
Operation * getParentOp()
Returns the closest surrounding operation that contains this operation or nullptr if this is a top-le...
OperationName getName()
The name of an operation is the key identifier for it.
bool isAncestor(Operation *other)
Return true if this operation is an ancestor of the other operation.
bool isProperAncestor(Operation *other)
Return true if this operation is a proper ancestor of the other operation.
InFlightDiagnostic emitOpError(const Twine &message={})
Emit an error with the op name prefixed, like "'dim' op " which is convenient for verifiers.
This class encapsulates the "action" of executing a single pass.
void print(raw_ostream &os) const override
Print a textual version of this action to os.
PassExecutionAction(ArrayRef< IRUnit > irUnits, const Pass &pass)
Define a TypeID for this PassExecutionAction.
Operation * getOp() const
Get the operation that is the base of this pass.
static constexpr StringLiteral tag
The tag required by ActionImpl to identify this action.
const Pass & pass
Reference to the pass being run.
virtual void runAfterPipeline(std::optional< OperationName > name, const PipelineParentInfo &parentInfo)
A callback to run after a pass pipeline has executed.
virtual ~PassInstrumentation()=0
virtual void runBeforePipeline(std::optional< OperationName > name, const PipelineParentInfo &parentInfo)
A callback to run before a pass pipeline is executed.
This class holds a collection of PassInstrumentation objects, and invokes their respective call backs...
void runAfterPassFailed(Pass *pass, Operation *op)
See PassInstrumentation::runAfterPassFailed for details.
void addInstrumentation(std::unique_ptr< PassInstrumentation > pi)
Add the given instrumentation to the collection.
void runBeforeAnalysis(StringRef name, TypeID id, Operation *op)
See PassInstrumentation::runBeforeAnalysis for details.
void runAfterPass(Pass *pass, Operation *op)
See PassInstrumentation::runAfterPass for details.
void runAfterAnalysis(StringRef name, TypeID id, Operation *op)
See PassInstrumentation::runAfterAnalysis for details.
void runBeforePass(Pass *pass, Operation *op)
See PassInstrumentation::runBeforePass for details.
void runBeforePipeline(std::optional< OperationName > name, const PassInstrumentation::PipelineParentInfo &parentInfo)
See PassInstrumentation::runBeforePipeline for details.
void runAfterPipeline(std::optional< OperationName > name, const PassInstrumentation::PipelineParentInfo &parentInfo)
See PassInstrumentation::runAfterPipeline for details.
MLIRContext * getContext() const
Return an instance of the context.
LogicalResult run(Operation *op)
Run the passes within this manager on the provided operation.
void addInstrumentation(std::unique_ptr< PassInstrumentation > pi)
Add the provided instrumentation to the pass manager.
void enableVerifier(bool enabled=true)
Runs the verifier after each individual pass.
The abstract base pass class.
void copyOptionValuesFrom(const Pass *other)
Copy the option values from 'other', which is another instance of this pass.
void printAsTextualPipeline(raw_ostream &os)
Prints out the pass in the textual representation of pipelines.
virtual LogicalResult initializeOptions(StringRef options, function_ref< LogicalResult(const Twine &)> errorHandler)
Attempt to initialize the options of this pass from the given string.
virtual bool canScheduleOn(RegisteredOperationName opName) const =0
Indicate if the current pass can be scheduled on the given operation type.
std::optional< StringRef > getOpName() const
Returns the name of the operation that this pass operates on, or std::nullopt if this is a generic Op...
virtual void runOnOperation()=0
The polymorphic API that runs the pass over the currently held operation.
virtual StringRef getName() const =0
Returns the derived pass name.
virtual StringRef getArgument() const
Return the command line argument used when registering this pass.
This class provides an efficient unique identifier for a specific C++ type.
void invalidate(const PreservedAnalyses &pa)
Invalidate any cached analyses based upon the given set of preserved analyses.
An adaptor pass used to run operation passes over nested operations.
LogicalResult parseFromString(StringRef options, raw_ostream &errorStream=llvm::errs())
Parse options out as key=value pairs that can then be handed off to the llvm::cl command line passing...
void print(raw_ostream &os) const
Print the options held by this struct in a form that can be parsed via 'parseFromString'.
void copyOptionValuesFrom(const PassOptions &other)
Copy the option values from 'other' into 'this', where 'other' has the same options as 'this'.
A utility class to represent the analyses that are known to be preserved.
bool isAll() const
Returns true if all analyses were marked preserved.
bool isNone() const
Returns true if no analyses were marked preserved.
virtual ArrayRef< IRUnit > getContextIRUnits() const
Return the set of IR units that are associated with this action.
ArrayRef< IRUnit > irUnits
Set of IR units (operations, regions, blocks, values) that are associated with this action.
Include the generated interface declarations.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
void parallelForEach(MLIRContext *context, IteratorT begin, IteratorT end, FuncT &&func)
Invoke the given function on the elements between [begin, end) asynchronously.
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
LogicalResult verify(Operation *op, bool verifyRecursively=true)
Perform (potentially expensive) checks of invariants, used to detect compiler bugs,...
This struct represents information related to the parent pass of pipeline.
detail::AnalysisMap analyses
The analyses for the owning operation.
DenseMap< Operation *, std::unique_ptr< NestedAnalysisMap > > childAnalyses
The cached analyses for nested operations.
void invalidate(const PreservedAnalyses &pa)
Invalidate any non preserved analyses.
void clear()
Clear the list of passes in this pass manager, other options are preserved.
OpPassManagerImpl(const OpPassManagerImpl &rhs)
std::string name
The name of the operation that passes of this pass manager operate on.
OpPassManager::Nesting nesting
Control the implicit nesting of passes that mismatch the name set for this OpPassManager.
std::optional< OperationName > getOpName(MLIRContext &context)
Return the operation name of this pass manager.
void addPass(std::unique_ptr< Pass > pass)
Add the given pass to this pass manager.
OpPassManager & nest(StringRef nestedName)
unsigned initializationGeneration
The current initialization generation of this pass manager.
OpPassManagerImpl(OperationName opName, OpPassManager::Nesting nesting)
bool canScheduleOn(MLIRContext &context, OperationName opName)
Indicate if the current pass manager can be scheduled on the given operation type.
OpPassManagerImpl(OpPassManager::Nesting nesting)
StringRef getOpAnchorName() const
Return the name used to anchor this pass manager.
OpPassManager & nestAny()
OpPassManager & nest(OperationName nestedName)
Nest a new operation pass manager for the given operation kind under this pass manager.
std::vector< std::unique_ptr< Pass > > passes
The set of passes to run as part of this pass manager.
std::optional< StringRef > getOpName() const
void mergeInto(OpPassManagerImpl &rhs)
Merge the passes of this pass manager into the one provided.
LogicalResult finalizePassList(MLIRContext *ctx)
Finalize the pass list in preparation for execution.
std::optional< OperationName > opName
The cached OperationName (internalized in the context) for the name of the operation that passes of t...
OpPassManagerImpl(StringRef name, OpPassManager::Nesting nesting)
std::vector< std::unique_ptr< PassInstrumentation > > instrumentations
Set of registered instrumentations.
llvm::sys::SmartMutex< true > mutex
Mutex to keep instrumentation access thread-safe.