22 #include "llvm/ADT/Hashing.h"
23 #include "llvm/ADT/STLExtras.h"
24 #include "llvm/ADT/ScopeExit.h"
25 #include "llvm/Support/CommandLine.h"
26 #include "llvm/Support/CrashRecoveryContext.h"
27 #include "llvm/Support/Mutex.h"
28 #include "llvm/Support/Signals.h"
29 #include "llvm/Support/Threading.h"
30 #include "llvm/Support/ToolOutputFile.h"
42 :
Base(irUnits), pass(pass) {}
45 os << llvm::formatv(
"`{0}` running `{1}` on Operation `{2}`",
tag,
51 return irUnits.empty() ? nullptr
52 : llvm::dyn_cast_if_present<Operation *>(
irUnits[0]);
63 void Pass::anchor() {}
68 function_ref<LogicalResult(
const Twine &)> errorHandler) {
70 llvm::raw_string_ostream os(errStr);
72 return errorHandler(errStr);
88 if (
auto *adaptor = dyn_cast<OpToOpPassAdaptor>(
this)) {
90 adaptor->getPassManagers(),
91 [&](
OpPassManager &pm) { pm.printAsTextualPipeline(os, pretty); },
103 if (!argument.empty())
106 os <<
"unknown<" <<
getName() <<
">";
107 passOptions.
print(os);
129 for (
const std::unique_ptr<Pass> &pass : rhs.
passes) {
130 std::unique_ptr<Pass> newPass = pass->clone();
131 newPass->threadingSibling = pass.get();
132 passes.push_back(std::move(newPass));
154 void addPass(std::unique_ptr<Pass> pass);
172 return name.empty() ? std::optional<StringRef>()
173 : std::optional<StringRef>(
name);
195 std::vector<std::unique_ptr<Pass>>
passes;
209 assert(name == rhs.
name &&
"merging unrelated pass managers");
210 for (
auto &pass : passes)
211 rhs.
passes.push_back(std::move(pass));
217 addPass(std::unique_ptr<Pass>(adaptor));
218 return adaptor->getPassManagers().front();
221 void OpPassManagerImpl::addPass(std::unique_ptr<Pass> pass) {
224 std::optional<StringRef> pmOpName = getOpName();
225 std::optional<StringRef> passOpName = pass->getOpName();
226 if (pmOpName && passOpName && *pmOpName != *passOpName) {
228 return nest(*passOpName).addPass(std::move(pass));
229 llvm::report_fatal_error(llvm::Twine(
"Can't add pass '") + pass->getName() +
230 "' restricted to '" + *passOpName +
231 "' on a PassManager intended to run on '" +
232 getOpAnchorName() +
"', did you intend to nest?");
235 passes.emplace_back(std::move(pass));
238 void OpPassManagerImpl::clear() { passes.clear(); }
240 LogicalResult OpPassManagerImpl::finalizePassList(
MLIRContext *ctx) {
242 for (
auto &pm : adaptor->getPassManagers())
243 if (failed(pm.getImpl().finalizePassList(ctx)))
250 for (
auto &pass : passes) {
252 if (
auto *currentAdaptor = dyn_cast<OpToOpPassAdaptor>(pass.get())) {
256 lastAdaptor = currentAdaptor;
262 if (succeeded(currentAdaptor->tryMergeInto(ctx, *lastAdaptor)))
265 lastAdaptor = currentAdaptor;
266 }
else if (lastAdaptor) {
268 if (failed(finalizeAdaptor(lastAdaptor)))
270 lastAdaptor =
nullptr;
275 if (lastAdaptor && failed(finalizeAdaptor(lastAdaptor)))
280 llvm::erase_if(passes, std::logical_not<std::unique_ptr<Pass>>());
283 std::optional<OperationName> rawOpName = getOpName(*ctx);
289 std::optional<RegisteredOperationName> opName =
290 rawOpName->getRegisteredInfo();
291 for (std::unique_ptr<Pass> &pass : passes) {
292 if (opName && !pass->canScheduleOn(*opName)) {
294 <<
"unable to schedule pass '" << pass->getName()
295 <<
"' on a PassManager intended to run on '" << getOpAnchorName()
306 std::optional<OperationName> pmOpName = getOpName(context);
308 return pmOpName == opName;
312 std::optional<RegisteredOperationName> registeredInfo =
314 if (!registeredInfo ||
317 return llvm::all_of(passes, [&](
const std::unique_ptr<Pass> &pass) {
318 return pass->canScheduleOn(*registeredInfo);
335 impl = std::make_unique<OpPassManagerImpl>(*rhs.impl);
339 impl = std::move(rhs.impl);
362 return impl->nest(nestedName);
365 return impl->nest(nestedName);
372 impl->addPass(std::move(pass));
385 return impl->getOpName();
389 std::optional<OperationName>
391 return impl->getOpName(context);
395 return impl->getOpAnchorName();
404 bool pretty =
false) {
405 os << anchorName <<
"(";
425 raw_ostream &os, StringRef anchorName,
435 indentedOS, anchorName,
442 llvm::errs() <<
"Pass Manager with " <<
impl->passes.size() <<
" passes:\n";
444 llvm::errs() <<
"\n";
450 pass.getDependentDialects(dialects);
461 LogicalResult OpPassManager::initialize(
MLIRContext *context,
462 unsigned newInitGeneration) {
463 if (
impl->initializationGeneration == newInitGeneration)
465 impl->initializationGeneration = newInitGeneration;
468 auto *adaptor = dyn_cast<OpToOpPassAdaptor>(&pass);
470 if (failed(pass.initialize(context)))
477 if (failed(adaptorPM.initialize(context, newInitGeneration)))
483 llvm::hash_code OpPassManager::hash() {
484 llvm::hash_code hashCode{};
487 auto *adaptor = dyn_cast<OpToOpPassAdaptor>(&pass);
489 hashCode = llvm::hash_combine(hashCode, &pass);
494 llvm::hash_combine(hashCode, adaptorPM.hash());
503 LogicalResult OpToOpPassAdaptor::run(
Pass *pass,
Operation *op,
505 unsigned parentInitGeneration) {
509 <<
"trying to schedule a pass on an unregistered operation";
511 return op->
emitOpError() <<
"trying to schedule a pass on an operation not "
512 "marked as 'IsolatedFromAbove'";
515 <<
"trying to schedule a pass on an unsupported operation";
525 return root->emitOpError()
526 <<
"Trying to schedule a dynamic pipeline on an "
527 "operation that isn't "
528 "nested under the current operation the pass is processing";
537 if (failed(pipeline.initialize(root->getContext(), parentInitGeneration)))
540 return OpToOpPassAdaptor::runPipeline(pipeline, root, nestedAm,
541 verifyPasses, parentInitGeneration,
544 pass->passState.emplace(op, am, dynamicPipelineCallback);
550 bool passFailed =
false;
554 if (
auto *adaptor = dyn_cast<OpToOpPassAdaptor>(pass))
555 adaptor->runOnOperation(verifyPasses);
558 passFailed = pass->passState->irAndPassFailed.getInt();
563 am.
invalidate(pass->passState->preservedAnalyses);
567 if (!passFailed && verifyPasses) {
568 bool runVerifierNow =
true;
573 bool runVerifierRecursively = !isa<OpToOpPassAdaptor>(pass);
582 #ifndef EXPENSIVE_CHECKS
583 runVerifierNow = !pass->passState->preservedAnalyses.isAll();
586 passFailed = failed(
verify(op, runVerifierRecursively));
598 return failure(passFailed);
602 LogicalResult OpToOpPassAdaptor::runPipeline(
606 assert((!instrumentor || parentInfo) &&
607 "expected parent info if instrumentor is provided");
608 auto scopeExit = llvm::make_scope_exit([&] {
623 if (failed(run(&pass, op, am, verifyPasses, parentInitGeneration)))
637 auto *it = llvm::find_if(
639 return it == mgrs.end() ? nullptr : &*it;
648 return mgr.
getImpl().canScheduleOn(context, name);
650 return it == mgrs.end() ? nullptr : &*it;
654 mgrs.emplace_back(std::move(mgr));
658 for (
auto &pm : mgrs)
675 if (std::optional<OperationName> pmOpName = pm.
getOpName(*ctx))
688 auto *lhsGenericPMIt = llvm::find_if(mgrs, isGenericPM);
689 if (lhsGenericPMIt != mgrs.end() &&
690 hasScheduleConflictWith(*lhsGenericPMIt, rhs.mgrs))
693 auto *rhsGenericPMIt = llvm::find_if(rhs.mgrs, isGenericPM);
694 if (rhsGenericPMIt != rhs.mgrs.end() &&
695 hasScheduleConflictWith(*rhsGenericPMIt, mgrs))
698 for (
auto &pm : mgrs) {
701 if (
auto *existingPM =
706 rhs.mgrs.emplace_back(std::move(pm));
714 if (std::optional<StringRef> lhsName = lhs.
getOpName()) {
715 if (std::optional<StringRef> rhsName = rhs.
getOpName())
716 return *lhsName < *rhsName;
721 llvm::sort(rhs.mgrs, compareFn);
726 std::string OpToOpPassAdaptor::getAdaptorName() {
727 std::string name =
"Pipeline Collection : [";
728 llvm::raw_string_ostream os(name);
729 llvm::interleaveComma(getPassManagers(), os, [&](
OpPassManager &pm) {
736 void OpToOpPassAdaptor::runOnOperation() {
738 "Unexpected call to Pass::runOnOperation() on OpToOpPassAdaptor");
742 void OpToOpPassAdaptor::runOnOperation(
bool verifyPasses) {
744 runOnOperationAsyncImpl(verifyPasses);
746 runOnOperationImpl(verifyPasses);
750 void OpToOpPassAdaptor::runOnOperationImpl(
bool verifyPasses) {
751 auto am = getAnalysisManager();
755 for (
auto ®ion : getOperation()->getRegions()) {
756 for (
auto &block : region) {
757 for (
auto &op : block) {
763 unsigned initGeneration = mgr->impl->initializationGeneration;
764 if (failed(runPipeline(*mgr, &op, am.
nest(&op), verifyPasses,
765 initGeneration, instrumentor, &parentInfo)))
776 return lhs.size() != rhs.size() ||
777 llvm::any_of(llvm::seq<size_t>(0, lhs.size()),
778 [&](
size_t i) { return lhs[i].size() != rhs[i].size(); });
782 void OpToOpPassAdaptor::runOnOperationAsyncImpl(
bool verifyPasses) {
788 if (asyncExecutors.empty() ||
hasSizeMismatch(asyncExecutors.front(), mgrs))
789 asyncExecutors.assign(context->
getThreadPool().getMaxConcurrency(), mgrs);
795 : passManagerIdx(passManagerIdx), op(op), am(am) {}
798 unsigned passManagerIdx;
808 std::vector<OpPMInfo> opInfos;
810 for (
auto ®ion : getOperation()->getRegions()) {
813 auto pmIdxIt = knownOpPMIdx.try_emplace(op.
getName(), std::nullopt);
814 if (pmIdxIt.second) {
816 pmIdxIt.first->second = std::distance(mgrs.begin(), mgr);
820 if (pmIdxIt.first->second)
821 opInfos.emplace_back(*pmIdxIt.first->second, &op, am.
nest(&op));
831 std::vector<std::atomic<bool>> activePMs(asyncExecutors.size());
832 std::fill(activePMs.begin(), activePMs.end(),
false);
833 std::atomic<bool> hasFailure =
false;
836 auto it = llvm::find_if(activePMs, [](std::atomic<bool> &isActive) {
837 bool expectedInactive =
false;
838 return isActive.compare_exchange_strong(expectedInactive,
true);
840 unsigned pmIndex = it - activePMs.begin();
843 OpPassManager &pm = asyncExecutors[pmIndex][opInfo.passManagerIdx];
844 LogicalResult pipelineResult = runPipeline(
845 pm, opInfo.op, opInfo.am, verifyPasses,
846 pm.impl->initializationGeneration, instrumentor, &parentInfo);
847 if (failed(pipelineResult))
848 hasFailure.store(
true);
851 activePMs[pmIndex].store(
false);
865 :
OpPassManager(operationName, nesting), context(ctx), passTiming(false),
866 verifyPasses(true) {}
870 context(operationName.
getContext()), passTiming(false),
871 verifyPasses(true) {}
880 std::optional<OperationName> anchorOp =
getOpName(*context);
881 if (anchorOp && anchorOp != op->
getName())
894 if (failed(
getImpl().finalizePassList(context)))
902 llvm::hash_code pipelineKey = hash();
903 if (newInitKey != initializationKey ||
904 pipelineKey != pipelineInitializationKey) {
905 if (failed(initialize(context,
impl->initializationGeneration + 1)))
907 initializationKey = newInitKey;
908 pipelineKey = pipelineInitializationKey;
916 LogicalResult result =
917 crashReproGenerator ? runWithCrashRecovery(op, am) : runPasses(op, am);
923 if (passStatisticsMode)
931 instrumentor = std::make_unique<PassInstrumentor>();
937 return OpToOpPassAdaptor::runPipeline(*
this, op, am, verifyPasses,
938 impl->initializationGeneration);
950 "expected valid descendant operation");
954 return nestImmediate(op);
959 opAncestors.push_back(op);
961 }
while (op != currentOp);
964 for (
Operation *op : llvm::reverse(opAncestors))
965 result = result.nestImmediate(op);
972 "expected immediate child operation");
974 auto [it, inserted] =
impl->childAnalyses.try_emplace(op);
976 it->second = std::make_unique<NestedAnalysisMap>(op,
impl);
977 return {it->second.get()};
999 while (!mapsToInvalidate.empty()) {
1000 auto *map = mapsToInvalidate.pop_back_val();
1001 for (
auto &analysisPair : map->childAnalyses) {
1002 analysisPair.second->invalidate(pa);
1003 if (!analysisPair.second->childAnalyses.empty())
1004 mapsToInvalidate.push_back(analysisPair.second.get());
1042 std::optional<OperationName> name,
1044 llvm::sys::SmartScopedLock<true> instrumentationLock(
impl->mutex);
1045 for (
auto &instr :
impl->instrumentations)
1046 instr->runBeforePipeline(name, parentInfo);
1051 std::optional<OperationName> name,
1053 llvm::sys::SmartScopedLock<true> instrumentationLock(
impl->mutex);
1054 for (
auto &instr : llvm::reverse(
impl->instrumentations))
1055 instr->runAfterPipeline(name, parentInfo);
1060 llvm::sys::SmartScopedLock<true> instrumentationLock(
impl->mutex);
1061 for (
auto &instr :
impl->instrumentations)
1062 instr->runBeforePass(pass, op);
1067 llvm::sys::SmartScopedLock<true> instrumentationLock(
impl->mutex);
1068 for (
auto &instr : llvm::reverse(
impl->instrumentations))
1069 instr->runAfterPass(pass, op);
1074 llvm::sys::SmartScopedLock<true> instrumentationLock(
impl->mutex);
1075 for (
auto &instr : llvm::reverse(
impl->instrumentations))
1076 instr->runAfterPassFailed(pass, op);
1082 llvm::sys::SmartScopedLock<true> instrumentationLock(
impl->mutex);
1083 for (
auto &instr :
impl->instrumentations)
1084 instr->runBeforeAnalysis(name,
id, op);
1090 llvm::sys::SmartScopedLock<true> instrumentationLock(
impl->mutex);
1091 for (
auto &instr : llvm::reverse(
impl->instrumentations))
1092 instr->runAfterAnalysis(name,
id, op);
1097 std::unique_ptr<PassInstrumentation> pi) {
1098 llvm::sys::SmartScopedLock<true> instrumentationLock(
impl->mutex);
1099 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.