21 #include "llvm/ADT/Hashing.h"
22 #include "llvm/ADT/STLExtras.h"
23 #include "llvm/ADT/ScopeExit.h"
24 #include "llvm/Support/Mutex.h"
25 #include "llvm/Support/Signals.h"
26 #include "llvm/Support/Threading.h"
38 :
Base(irUnits), pass(pass) {}
41 os << llvm::formatv(
"`{0}` running `{1}` on Operation `{2}`",
tag,
47 return irUnits.empty() ? nullptr
48 : llvm::dyn_cast_if_present<Operation *>(
irUnits[0]);
59 void Pass::anchor() {}
64 function_ref<LogicalResult(
const Twine &)> errorHandler) {
66 llvm::raw_string_ostream os(errStr);
68 return errorHandler(errStr);
84 if (
auto *adaptor = dyn_cast<OpToOpPassAdaptor>(
this)) {
86 adaptor->getPassManagers(),
87 [&](
OpPassManager &pm) { pm.printAsTextualPipeline(os, pretty); },
99 if (!argument.empty())
102 os <<
"unknown<" <<
getName() <<
">";
103 passOptions.
print(os);
125 for (
const std::unique_ptr<Pass> &pass : rhs.
passes) {
126 std::unique_ptr<Pass> newPass = pass->clone();
127 newPass->threadingSibling = pass.get();
128 passes.push_back(std::move(newPass));
150 void addPass(std::unique_ptr<Pass> pass);
168 return name.empty() ? std::optional<StringRef>()
169 : std::optional<StringRef>(
name);
191 std::vector<std::unique_ptr<Pass>>
passes;
205 assert(name == rhs.
name &&
"merging unrelated pass managers");
206 for (
auto &pass : passes)
207 rhs.
passes.push_back(std::move(pass));
213 addPass(std::unique_ptr<Pass>(adaptor));
214 return adaptor->getPassManagers().front();
217 void OpPassManagerImpl::addPass(std::unique_ptr<Pass> pass) {
220 std::optional<StringRef> pmOpName = getOpName();
221 std::optional<StringRef> passOpName = pass->getOpName();
222 if (pmOpName && passOpName && *pmOpName != *passOpName) {
224 return nest(*passOpName).addPass(std::move(pass));
225 llvm::report_fatal_error(llvm::Twine(
"Can't add pass '") + pass->getName() +
226 "' restricted to '" + *passOpName +
227 "' on a PassManager intended to run on '" +
228 getOpAnchorName() +
"', did you intend to nest?");
231 passes.emplace_back(std::move(pass));
234 void OpPassManagerImpl::clear() { passes.clear(); }
236 LogicalResult OpPassManagerImpl::finalizePassList(
MLIRContext *ctx) {
238 for (
auto &pm : adaptor->getPassManagers())
239 if (failed(pm.getImpl().finalizePassList(ctx)))
246 for (
auto &pass : passes) {
248 if (
auto *currentAdaptor = dyn_cast<OpToOpPassAdaptor>(pass.get())) {
252 lastAdaptor = currentAdaptor;
258 if (succeeded(currentAdaptor->tryMergeInto(ctx, *lastAdaptor)))
261 lastAdaptor = currentAdaptor;
262 }
else if (lastAdaptor) {
264 if (failed(finalizeAdaptor(lastAdaptor)))
266 lastAdaptor =
nullptr;
271 if (lastAdaptor && failed(finalizeAdaptor(lastAdaptor)))
276 llvm::erase_if(passes, std::logical_not<std::unique_ptr<Pass>>());
279 std::optional<OperationName> rawOpName = getOpName(*ctx);
285 std::optional<RegisteredOperationName> opName =
286 rawOpName->getRegisteredInfo();
287 for (std::unique_ptr<Pass> &pass : passes) {
288 if (opName && !pass->canScheduleOn(*opName)) {
290 <<
"unable to schedule pass '" << pass->getName()
291 <<
"' on a PassManager intended to run on '" << getOpAnchorName()
302 std::optional<OperationName> pmOpName = getOpName(context);
304 return pmOpName == opName;
308 std::optional<RegisteredOperationName> registeredInfo =
310 if (!registeredInfo ||
313 return llvm::all_of(passes, [&](
const std::unique_ptr<Pass> &pass) {
314 return pass->canScheduleOn(*registeredInfo);
331 impl = std::make_unique<OpPassManagerImpl>(*rhs.impl);
335 impl = std::move(rhs.impl);
358 return impl->nest(nestedName);
361 return impl->nest(nestedName);
368 impl->addPass(std::move(pass));
381 return impl->getOpName();
385 std::optional<OperationName>
387 return impl->getOpName(context);
391 return impl->getOpAnchorName();
400 bool pretty =
false) {
401 os << anchorName <<
"(";
421 raw_ostream &os, StringRef anchorName,
431 indentedOS, anchorName,
438 llvm::errs() <<
"Pass Manager with " <<
impl->passes.size() <<
" passes:\n";
440 llvm::errs() <<
"\n";
446 pass.getDependentDialects(dialects);
457 LogicalResult OpPassManager::initialize(
MLIRContext *context,
458 unsigned newInitGeneration) {
459 if (
impl->initializationGeneration == newInitGeneration)
461 impl->initializationGeneration = newInitGeneration;
464 auto *adaptor = dyn_cast<OpToOpPassAdaptor>(&pass);
466 if (failed(pass.initialize(context)))
473 if (failed(adaptorPM.initialize(context, newInitGeneration)))
479 llvm::hash_code OpPassManager::hash() {
480 llvm::hash_code hashCode{};
483 auto *adaptor = dyn_cast<OpToOpPassAdaptor>(&pass);
485 hashCode = llvm::hash_combine(hashCode, &pass);
490 llvm::hash_combine(hashCode, adaptorPM.hash());
499 LogicalResult OpToOpPassAdaptor::run(
Pass *pass,
Operation *op,
501 unsigned parentInitGeneration) {
505 <<
"trying to schedule a pass on an unregistered operation";
507 return op->
emitOpError() <<
"trying to schedule a pass on an operation not "
508 "marked as 'IsolatedFromAbove'";
511 <<
"trying to schedule a pass on an unsupported operation";
521 return root->emitOpError()
522 <<
"Trying to schedule a dynamic pipeline on an "
523 "operation that isn't "
524 "nested under the current operation the pass is processing";
533 if (failed(pipeline.initialize(root->getContext(), parentInitGeneration)))
536 return OpToOpPassAdaptor::runPipeline(pipeline, root, nestedAm,
537 verifyPasses, parentInitGeneration,
540 pass->passState.emplace(op, am, dynamicPipelineCallback);
546 bool passFailed =
false;
550 if (
auto *adaptor = dyn_cast<OpToOpPassAdaptor>(pass))
551 adaptor->runOnOperation(verifyPasses);
554 passFailed = pass->passState->irAndPassFailed.getInt();
559 am.
invalidate(pass->passState->preservedAnalyses);
563 if (!passFailed && verifyPasses) {
564 bool runVerifierNow =
true;
569 bool runVerifierRecursively = !isa<OpToOpPassAdaptor>(pass);
578 #ifndef EXPENSIVE_CHECKS
579 runVerifierNow = !pass->passState->preservedAnalyses.isAll();
582 passFailed = failed(
verify(op, runVerifierRecursively));
594 return failure(passFailed);
598 LogicalResult OpToOpPassAdaptor::runPipeline(
602 assert((!instrumentor || parentInfo) &&
603 "expected parent info if instrumentor is provided");
604 auto scopeExit = llvm::make_scope_exit([&] {
619 if (failed(run(&pass, op, am, verifyPasses, parentInitGeneration)))
633 auto *it = llvm::find_if(
635 return it == mgrs.end() ? nullptr : &*it;
644 return mgr.
getImpl().canScheduleOn(context, name);
646 return it == mgrs.end() ? nullptr : &*it;
650 mgrs.emplace_back(std::move(mgr));
654 for (
auto &pm : mgrs)
671 if (std::optional<OperationName> pmOpName = pm.
getOpName(*ctx))
684 auto *lhsGenericPMIt = llvm::find_if(mgrs, isGenericPM);
685 if (lhsGenericPMIt != mgrs.end() &&
686 hasScheduleConflictWith(*lhsGenericPMIt, rhs.mgrs))
689 auto *rhsGenericPMIt = llvm::find_if(rhs.mgrs, isGenericPM);
690 if (rhsGenericPMIt != rhs.mgrs.end() &&
691 hasScheduleConflictWith(*rhsGenericPMIt, mgrs))
694 for (
auto &pm : mgrs) {
697 if (
auto *existingPM =
702 rhs.mgrs.emplace_back(std::move(pm));
710 if (std::optional<StringRef> lhsName = lhs.
getOpName()) {
711 if (std::optional<StringRef> rhsName = rhs.
getOpName())
712 return *lhsName < *rhsName;
717 llvm::sort(rhs.mgrs, compareFn);
722 std::string OpToOpPassAdaptor::getAdaptorName() {
723 std::string name =
"Pipeline Collection : [";
724 llvm::raw_string_ostream os(name);
725 llvm::interleaveComma(getPassManagers(), os, [&](
OpPassManager &pm) {
732 void OpToOpPassAdaptor::runOnOperation() {
734 "Unexpected call to Pass::runOnOperation() on OpToOpPassAdaptor");
738 void OpToOpPassAdaptor::runOnOperation(
bool verifyPasses) {
740 runOnOperationAsyncImpl(verifyPasses);
742 runOnOperationImpl(verifyPasses);
746 void OpToOpPassAdaptor::runOnOperationImpl(
bool verifyPasses) {
747 auto am = getAnalysisManager();
751 for (
auto ®ion : getOperation()->getRegions()) {
752 for (
auto &block : region) {
753 for (
auto &op : block) {
759 unsigned initGeneration = mgr->impl->initializationGeneration;
760 if (failed(runPipeline(*mgr, &op, am.
nest(&op), verifyPasses,
761 initGeneration, instrumentor, &parentInfo)))
772 return lhs.size() != rhs.size() ||
773 llvm::any_of(llvm::seq<size_t>(0, lhs.size()),
774 [&](
size_t i) { return lhs[i].size() != rhs[i].size(); });
778 void OpToOpPassAdaptor::runOnOperationAsyncImpl(
bool verifyPasses) {
784 if (asyncExecutors.empty() ||
hasSizeMismatch(asyncExecutors.front(), mgrs))
785 asyncExecutors.assign(context->
getThreadPool().getMaxConcurrency(), mgrs);
791 : passManagerIdx(passManagerIdx), op(op), am(am) {}
794 unsigned passManagerIdx;
804 std::vector<OpPMInfo> opInfos;
806 for (
auto ®ion : getOperation()->getRegions()) {
809 auto pmIdxIt = knownOpPMIdx.try_emplace(op.
getName(), std::nullopt);
810 if (pmIdxIt.second) {
812 pmIdxIt.first->second = std::distance(mgrs.begin(), mgr);
816 if (pmIdxIt.first->second)
817 opInfos.emplace_back(*pmIdxIt.first->second, &op, am.
nest(&op));
827 std::vector<std::atomic<bool>> activePMs(asyncExecutors.size());
828 llvm::fill(activePMs,
false);
829 std::atomic<bool> hasFailure =
false;
832 auto it = llvm::find_if(activePMs, [](std::atomic<bool> &isActive) {
833 bool expectedInactive =
false;
834 return isActive.compare_exchange_strong(expectedInactive,
true);
836 unsigned pmIndex = it - activePMs.begin();
839 OpPassManager &pm = asyncExecutors[pmIndex][opInfo.passManagerIdx];
840 LogicalResult pipelineResult = runPipeline(
841 pm, opInfo.op, opInfo.am, verifyPasses,
842 pm.impl->initializationGeneration, instrumentor, &parentInfo);
843 if (failed(pipelineResult))
844 hasFailure.store(
true);
847 activePMs[pmIndex].store(
false);
861 :
OpPassManager(operationName, nesting), context(ctx), passTiming(false),
862 verifyPasses(true) {}
866 context(operationName.
getContext()), passTiming(false),
867 verifyPasses(true) {}
876 std::optional<OperationName> anchorOp =
getOpName(*context);
877 if (anchorOp && anchorOp != op->
getName())
890 if (failed(
getImpl().finalizePassList(context)))
898 llvm::hash_code pipelineKey = hash();
899 if (newInitKey != initializationKey ||
900 pipelineKey != pipelineInitializationKey) {
901 if (failed(initialize(context,
impl->initializationGeneration + 1)))
903 initializationKey = newInitKey;
904 pipelineKey = pipelineInitializationKey;
912 LogicalResult result =
913 crashReproGenerator ? runWithCrashRecovery(op, am) : runPasses(op, am);
919 if (passStatisticsMode)
927 instrumentor = std::make_unique<PassInstrumentor>();
933 return OpToOpPassAdaptor::runPipeline(*
this, op, am, verifyPasses,
934 impl->initializationGeneration);
946 "expected valid descendant operation");
950 return nestImmediate(op);
955 opAncestors.push_back(op);
957 }
while (op != currentOp);
960 for (
Operation *op : llvm::reverse(opAncestors))
961 result = result.nestImmediate(op);
968 "expected immediate child operation");
970 auto [it, inserted] =
impl->childAnalyses.try_emplace(op);
972 it->second = std::make_unique<NestedAnalysisMap>(op,
impl);
973 return {it->second.get()};
995 while (!mapsToInvalidate.empty()) {
996 auto *map = mapsToInvalidate.pop_back_val();
997 for (
auto &analysisPair : map->childAnalyses) {
998 analysisPair.second->invalidate(pa);
999 if (!analysisPair.second->childAnalyses.empty())
1000 mapsToInvalidate.push_back(analysisPair.second.get());
1038 std::optional<OperationName> name,
1040 llvm::sys::SmartScopedLock<true> instrumentationLock(
impl->mutex);
1041 for (
auto &instr :
impl->instrumentations)
1042 instr->runBeforePipeline(name, parentInfo);
1047 std::optional<OperationName> name,
1049 llvm::sys::SmartScopedLock<true> instrumentationLock(
impl->mutex);
1050 for (
auto &instr : llvm::reverse(
impl->instrumentations))
1051 instr->runAfterPipeline(name, parentInfo);
1056 llvm::sys::SmartScopedLock<true> instrumentationLock(
impl->mutex);
1057 for (
auto &instr :
impl->instrumentations)
1058 instr->runBeforePass(pass, op);
1063 llvm::sys::SmartScopedLock<true> instrumentationLock(
impl->mutex);
1064 for (
auto &instr : llvm::reverse(
impl->instrumentations))
1065 instr->runAfterPass(pass, op);
1070 llvm::sys::SmartScopedLock<true> instrumentationLock(
impl->mutex);
1071 for (
auto &instr : llvm::reverse(
impl->instrumentations))
1072 instr->runAfterPassFailed(pass, op);
1078 llvm::sys::SmartScopedLock<true> instrumentationLock(
impl->mutex);
1079 for (
auto &instr :
impl->instrumentations)
1080 instr->runBeforeAnalysis(name,
id, op);
1086 llvm::sys::SmartScopedLock<true> instrumentationLock(
impl->mutex);
1087 for (
auto &instr : llvm::reverse(
impl->instrumentations))
1088 instr->runAfterAnalysis(name,
id, op);
1093 std::unique_ptr<PassInstrumentation> pi) {
1094 llvm::sys::SmartScopedLock<true> instrumentationLock(
impl->mutex);
1095 impl->instrumentations.emplace_back(std::move(pi));
static MLIRContext * getContext(OpFoldResult val)
static llvm::ManagedStatic< PassManagerOptions > options
void printAsTextualPipeline(raw_indented_ostream &os, StringRef anchorName, const llvm::iterator_range< OpPassManager::pass_iterator > &passes, bool pretty=false)
Prints out the passes of the pass manager as the textual representation of pipelines.
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,...
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.
#define MLIR_DEFINE_EXPLICIT_TYPE_ID(CLASS_NAME)
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,...
void printAsTextualPipeline(raw_ostream &os, bool pretty=false) const
Prints out the passes of the pass manager as the textual representation of pipelines.
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.
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)
Construct a 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.
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.
void printAsTextualPipeline(raw_ostream &os, bool pretty=false)
Prints out the pass in the textual representation of pipelines.
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.
raw_ostream subclass that simplifies indention a sequence of code.
raw_indented_ostream & unindent()
Decreases the indent and returning this raw_indented_ostream.
raw_indented_ostream & indent()
Increases the indent and returning this raw_indented_ostream.
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.