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);
70 return errorHandler(errStr);
85 if (
auto *adaptor = dyn_cast<OpToOpPassAdaptor>(
this)) {
87 adaptor->getPassManagers(),
96 if (!argument.empty())
99 os <<
"unknown<" <<
getName() <<
">";
100 passOptions.
print(os);
122 for (
const std::unique_ptr<Pass> &pass : rhs.
passes) {
123 std::unique_ptr<Pass> newPass = pass->clone();
124 newPass->threadingSibling = pass.get();
125 passes.push_back(std::move(newPass));
147 void addPass(std::unique_ptr<Pass> pass);
165 return name.empty() ? std::optional<StringRef>()
166 : std::optional<StringRef>(
name);
188 std::vector<std::unique_ptr<Pass>>
passes;
202 assert(name == rhs.
name &&
"merging unrelated pass managers");
203 for (
auto &pass : passes)
204 rhs.
passes.push_back(std::move(pass));
210 addPass(std::unique_ptr<Pass>(adaptor));
211 return adaptor->getPassManagers().front();
214 void OpPassManagerImpl::addPass(std::unique_ptr<Pass> pass) {
217 std::optional<StringRef> pmOpName = getOpName();
218 std::optional<StringRef> passOpName = pass->getOpName();
219 if (pmOpName && passOpName && *pmOpName != *passOpName) {
221 return nest(*passOpName).addPass(std::move(pass));
222 llvm::report_fatal_error(llvm::Twine(
"Can't add pass '") + pass->getName() +
223 "' restricted to '" + *passOpName +
224 "' on a PassManager intended to run on '" +
225 getOpAnchorName() +
"', did you intend to nest?");
228 passes.emplace_back(std::move(pass));
231 void OpPassManagerImpl::clear() { passes.clear(); }
233 LogicalResult OpPassManagerImpl::finalizePassList(
MLIRContext *ctx) {
235 for (
auto &pm : adaptor->getPassManagers())
236 if (failed(pm.getImpl().finalizePassList(ctx)))
243 for (
auto &pass : passes) {
245 if (
auto *currentAdaptor = dyn_cast<OpToOpPassAdaptor>(pass.get())) {
249 lastAdaptor = currentAdaptor;
255 if (succeeded(currentAdaptor->tryMergeInto(ctx, *lastAdaptor)))
258 lastAdaptor = currentAdaptor;
259 }
else if (lastAdaptor) {
261 if (failed(finalizeAdaptor(lastAdaptor)))
263 lastAdaptor =
nullptr;
268 if (lastAdaptor && failed(finalizeAdaptor(lastAdaptor)))
273 llvm::erase_if(passes, std::logical_not<std::unique_ptr<Pass>>());
276 std::optional<OperationName> rawOpName = getOpName(*ctx);
282 std::optional<RegisteredOperationName> opName =
283 rawOpName->getRegisteredInfo();
284 for (std::unique_ptr<Pass> &pass : passes) {
285 if (opName && !pass->canScheduleOn(*opName)) {
287 <<
"unable to schedule pass '" << pass->getName()
288 <<
"' on a PassManager intended to run on '" << getOpAnchorName()
299 std::optional<OperationName> pmOpName = getOpName(context);
301 return pmOpName == opName;
305 std::optional<RegisteredOperationName> registeredInfo =
307 if (!registeredInfo ||
310 return llvm::all_of(passes, [&](
const std::unique_ptr<Pass> &pass) {
311 return pass->canScheduleOn(*registeredInfo);
328 impl = std::make_unique<OpPassManagerImpl>(*rhs.impl);
332 impl = std::move(rhs.impl);
355 return impl->nest(nestedName);
358 return impl->nest(nestedName);
365 impl->addPass(std::move(pass));
378 return impl->getOpName();
382 std::optional<OperationName>
384 return impl->getOpName(context);
388 return impl->getOpAnchorName();
394 raw_ostream &os, StringRef anchorName,
396 os << anchorName <<
"(";
399 [&]() { os <<
","; });
411 llvm::errs() <<
"Pass Manager with " <<
impl->passes.size() <<
" passes:\n";
413 llvm::errs() <<
"\n";
419 pass.getDependentDialects(dialects);
430 LogicalResult OpPassManager::initialize(
MLIRContext *context,
431 unsigned newInitGeneration) {
432 if (
impl->initializationGeneration == newInitGeneration)
434 impl->initializationGeneration = newInitGeneration;
437 auto *adaptor = dyn_cast<OpToOpPassAdaptor>(&pass);
439 if (failed(pass.initialize(context)))
446 if (failed(adaptorPM.initialize(context, newInitGeneration)))
452 llvm::hash_code OpPassManager::hash() {
453 llvm::hash_code hashCode{};
456 auto *adaptor = dyn_cast<OpToOpPassAdaptor>(&pass);
458 hashCode = llvm::hash_combine(hashCode, &pass);
463 llvm::hash_combine(hashCode, adaptorPM.hash());
473 LogicalResult OpToOpPassAdaptor::run(
Pass *pass,
Operation *op,
475 unsigned parentInitGeneration) {
479 <<
"trying to schedule a pass on an unregistered operation";
481 return op->
emitOpError() <<
"trying to schedule a pass on an operation not "
482 "marked as 'IsolatedFromAbove'";
485 <<
"trying to schedule a pass on an unsupported operation";
495 return root->emitOpError()
496 <<
"Trying to schedule a dynamic pipeline on an "
497 "operation that isn't "
498 "nested under the current operation the pass is processing";
507 if (failed(pipeline.initialize(root->getContext(), parentInitGeneration)))
510 return OpToOpPassAdaptor::runPipeline(pipeline, root, nestedAm,
511 verifyPasses, parentInitGeneration,
514 pass->passState.emplace(op, am, dynamicPipelineCallback);
520 bool passFailed =
false;
524 if (
auto *adaptor = dyn_cast<OpToOpPassAdaptor>(pass))
525 adaptor->runOnOperation(verifyPasses);
528 passFailed = pass->passState->irAndPassFailed.getInt();
533 am.
invalidate(pass->passState->preservedAnalyses);
537 if (!passFailed && verifyPasses) {
538 bool runVerifierNow =
true;
543 bool runVerifierRecursively = !isa<OpToOpPassAdaptor>(pass);
552 #ifndef EXPENSIVE_CHECKS
553 runVerifierNow = !pass->passState->preservedAnalyses.isAll();
556 passFailed = failed(
verify(op, runVerifierRecursively));
568 return failure(passFailed);
572 LogicalResult OpToOpPassAdaptor::runPipeline(
576 assert((!instrumentor || parentInfo) &&
577 "expected parent info if instrumentor is provided");
578 auto scopeExit = llvm::make_scope_exit([&] {
593 if (failed(run(&pass, op, am, verifyPasses, parentInitGeneration)))
607 auto *it = llvm::find_if(
609 return it == mgrs.end() ? nullptr : &*it;
618 return mgr.
getImpl().canScheduleOn(context, name);
620 return it == mgrs.end() ? nullptr : &*it;
624 mgrs.emplace_back(std::move(mgr));
628 for (
auto &pm : mgrs)
645 if (std::optional<OperationName> pmOpName = pm.
getOpName(*ctx))
658 auto *lhsGenericPMIt = llvm::find_if(mgrs, isGenericPM);
659 if (lhsGenericPMIt != mgrs.end() &&
660 hasScheduleConflictWith(*lhsGenericPMIt, rhs.mgrs))
663 auto *rhsGenericPMIt = llvm::find_if(rhs.mgrs, isGenericPM);
664 if (rhsGenericPMIt != rhs.mgrs.end() &&
665 hasScheduleConflictWith(*rhsGenericPMIt, mgrs))
668 for (
auto &pm : mgrs) {
671 if (
auto *existingPM =
676 rhs.mgrs.emplace_back(std::move(pm));
684 if (std::optional<StringRef> lhsName = lhs->
getOpName()) {
685 if (std::optional<StringRef> rhsName = rhs->
getOpName())
686 return lhsName->compare(*rhsName);
691 llvm::array_pod_sort(rhs.mgrs.begin(), rhs.mgrs.end(), compareFn);
696 std::string OpToOpPassAdaptor::getAdaptorName() {
697 std::string name =
"Pipeline Collection : [";
698 llvm::raw_string_ostream os(name);
699 llvm::interleaveComma(getPassManagers(), os, [&](
OpPassManager &pm) {
706 void OpToOpPassAdaptor::runOnOperation() {
708 "Unexpected call to Pass::runOnOperation() on OpToOpPassAdaptor");
712 void OpToOpPassAdaptor::runOnOperation(
bool verifyPasses) {
714 runOnOperationAsyncImpl(verifyPasses);
716 runOnOperationImpl(verifyPasses);
720 void OpToOpPassAdaptor::runOnOperationImpl(
bool verifyPasses) {
721 auto am = getAnalysisManager();
725 for (
auto ®ion : getOperation()->getRegions()) {
726 for (
auto &block : region) {
727 for (
auto &op : block) {
733 unsigned initGeneration = mgr->impl->initializationGeneration;
734 if (failed(runPipeline(*mgr, &op, am.
nest(&op), verifyPasses,
735 initGeneration, instrumentor, &parentInfo)))
736 return signalPassFailure();
746 return lhs.size() != rhs.size() ||
747 llvm::any_of(llvm::seq<size_t>(0, lhs.size()),
748 [&](
size_t i) { return lhs[i].size() != rhs[i].size(); });
752 void OpToOpPassAdaptor::runOnOperationAsyncImpl(
bool verifyPasses) {
758 if (asyncExecutors.empty() ||
hasSizeMismatch(asyncExecutors.front(), mgrs))
759 asyncExecutors.assign(context->
getThreadPool().getMaxConcurrency(), mgrs);
765 : passManagerIdx(passManagerIdx), op(op), am(am) {}
768 unsigned passManagerIdx;
778 std::vector<OpPMInfo> opInfos;
780 for (
auto ®ion : getOperation()->getRegions()) {
783 auto pmIdxIt = knownOpPMIdx.try_emplace(op.
getName(), std::nullopt);
784 if (pmIdxIt.second) {
786 pmIdxIt.first->second = std::distance(mgrs.begin(), mgr);
790 if (pmIdxIt.first->second)
791 opInfos.emplace_back(*pmIdxIt.first->second, &op, am.
nest(&op));
801 std::vector<std::atomic<bool>> activePMs(asyncExecutors.size());
802 std::fill(activePMs.begin(), activePMs.end(),
false);
803 auto processFn = [&](OpPMInfo &opInfo) {
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);
818 activePMs[pmIndex].store(
false);
819 return pipelineResult;
833 :
OpPassManager(operationName, nesting), context(ctx), passTiming(false),
834 verifyPasses(true) {}
838 context(operationName.
getContext()), passTiming(false),
839 verifyPasses(true) {}
848 std::optional<OperationName> anchorOp =
getOpName(*context);
849 if (anchorOp && anchorOp != op->
getName())
862 if (failed(
getImpl().finalizePassList(context)))
870 llvm::hash_code pipelineKey = hash();
871 if (newInitKey != initializationKey || pipelineKey != pipelineInitializationKey) {
872 if (failed(initialize(context,
impl->initializationGeneration + 1)))
874 initializationKey = newInitKey;
875 pipelineKey = pipelineInitializationKey;
883 LogicalResult result =
884 crashReproGenerator ? runWithCrashRecovery(op, am) : runPasses(op, am);
890 if (passStatisticsMode)
898 instrumentor = std::make_unique<PassInstrumentor>();
904 return OpToOpPassAdaptor::runPipeline(*
this, op, am, verifyPasses,
905 impl->initializationGeneration);
917 "expected valid descendant operation");
921 return nestImmediate(op);
926 opAncestors.push_back(op);
928 }
while (op != currentOp);
931 for (
Operation *op : llvm::reverse(opAncestors))
932 result = result.nestImmediate(op);
939 "expected immediate child operation");
941 auto [it, inserted] =
impl->childAnalyses.try_emplace(op);
943 it->second = std::make_unique<NestedAnalysisMap>(op,
impl);
944 return {it->second.get()};
966 while (!mapsToInvalidate.empty()) {
967 auto *map = mapsToInvalidate.pop_back_val();
968 for (
auto &analysisPair : map->childAnalyses) {
969 analysisPair.second->invalidate(pa);
970 if (!analysisPair.second->childAnalyses.empty())
971 mapsToInvalidate.push_back(analysisPair.second.get());
1009 std::optional<OperationName> name,
1011 llvm::sys::SmartScopedLock<true> instrumentationLock(
impl->mutex);
1012 for (
auto &instr :
impl->instrumentations)
1013 instr->runBeforePipeline(name, parentInfo);
1018 std::optional<OperationName> name,
1020 llvm::sys::SmartScopedLock<true> instrumentationLock(
impl->mutex);
1021 for (
auto &instr : llvm::reverse(
impl->instrumentations))
1022 instr->runAfterPipeline(name, parentInfo);
1027 llvm::sys::SmartScopedLock<true> instrumentationLock(
impl->mutex);
1028 for (
auto &instr :
impl->instrumentations)
1029 instr->runBeforePass(pass, op);
1034 llvm::sys::SmartScopedLock<true> instrumentationLock(
impl->mutex);
1035 for (
auto &instr : llvm::reverse(
impl->instrumentations))
1036 instr->runAfterPass(pass, op);
1041 llvm::sys::SmartScopedLock<true> instrumentationLock(
impl->mutex);
1042 for (
auto &instr : llvm::reverse(
impl->instrumentations))
1043 instr->runAfterPassFailed(pass, op);
1049 llvm::sys::SmartScopedLock<true> instrumentationLock(
impl->mutex);
1050 for (
auto &instr :
impl->instrumentations)
1051 instr->runBeforeAnalysis(name,
id, op);
1057 llvm::sys::SmartScopedLock<true> instrumentationLock(
impl->mutex);
1058 for (
auto &instr : llvm::reverse(
impl->instrumentations))
1059 instr->runAfterAnalysis(name,
id, op);
1064 std::unique_ptr<PassInstrumentation> pi) {
1065 llvm::sys::SmartScopedLock<true> instrumentationLock(
impl->mutex);
1066 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.
LogicalResult failableParallelForEach(MLIRContext *context, IteratorT begin, IteratorT end, FuncT &&func)
Invoke the given function on the elements between [begin, end) asynchronously.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
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.