14 #include "TypeDetail.h"
28 #include "llvm/ADT/DenseMap.h"
29 #include "llvm/ADT/DenseSet.h"
30 #include "llvm/ADT/SmallString.h"
31 #include "llvm/ADT/StringSet.h"
32 #include "llvm/ADT/Twine.h"
33 #include "llvm/Support/Allocator.h"
34 #include "llvm/Support/CommandLine.h"
35 #include "llvm/Support/Compiler.h"
36 #include "llvm/Support/Debug.h"
37 #include "llvm/Support/Mutex.h"
38 #include "llvm/Support/RWMutex.h"
39 #include "llvm/Support/ThreadPool.h"
40 #include "llvm/Support/raw_ostream.h"
44 #define DEBUG_TYPE "mlircontext"
57 struct MLIRContextOptions {
58 llvm::cl::opt<bool> disableThreading{
59 "mlir-disable-threading",
60 llvm::cl::desc(
"Disable multi-threading within MLIR, overrides any "
61 "further call to MLIRContext::enableMultiThreading()")};
63 llvm::cl::opt<bool> printOpOnDiagnostic{
64 "mlir-print-op-on-diagnostic",
65 llvm::cl::desc(
"When a diagnostic is emitted on an operation, also print "
66 "the operation as an attached note"),
67 llvm::cl::init(
true)};
69 llvm::cl::opt<bool> printStackTraceOnDiagnostic{
70 "mlir-print-stacktrace-on-diagnostic",
71 llvm::cl::desc(
"When a diagnostic is emitted, also print the stack trace "
72 "as an attached note")};
76 static llvm::ManagedStatic<MLIRContextOptions>
clOptions;
79 #if LLVM_ENABLE_THREADS != 0
101 struct ScopedWriterLock {
102 ScopedWriterLock(llvm::sys::SmartRWMutex<true> &mutexParam,
bool shouldLock)
103 : mutex(shouldLock ? &mutexParam : nullptr) {
107 ~ScopedWriterLock() {
111 llvm::sys::SmartRWMutex<true> *mutex;
145 bool allowUnregisteredDialects =
false;
148 bool threadingIsEnabled =
true;
154 std::atomic<int> multiThreadedExecutionContext{0};
159 bool printOpOnDiagnostic =
true;
162 bool printStackTraceOnDiagnostic =
false;
172 llvm::ThreadPool *threadPool =
nullptr;
182 llvm::StringMap<std::unique_ptr<OperationName::Impl>>
operations;
227 IntegerType int1Ty, int8Ty, int16Ty, int32Ty, int64Ty,
int128Ty;
252 : threadingIsEnabled(threadingIsEnabled) {
253 if (threadingIsEnabled) {
254 ownedThreadPool = std::make_unique<llvm::ThreadPool>();
255 threadPool = ownedThreadPool.get();
259 for (
auto typeMapping : registeredTypes)
260 typeMapping.second->~AbstractType();
261 for (
auto attrMapping : registeredAttributes)
262 attrMapping.second->~AbstractAttribute();
283 getOrLoadDialect<BuiltinDialect>();
290 impl->f8E5M2Ty = TypeUniquer::get<Float8E5M2Type>(
this);
291 impl->f8E4M3FNTy = TypeUniquer::get<Float8E4M3FNType>(
this);
292 impl->f8E5M2FNUZTy = TypeUniquer::get<Float8E5M2FNUZType>(
this);
293 impl->f8E4M3FNUZTy = TypeUniquer::get<Float8E4M3FNUZType>(
this);
294 impl->f8E4M3B11FNUZTy = TypeUniquer::get<Float8E4M3B11FNUZType>(
this);
295 impl->bf16Ty = TypeUniquer::get<BFloat16Type>(
this);
296 impl->f16Ty = TypeUniquer::get<Float16Type>(
this);
297 impl->f32Ty = TypeUniquer::get<Float32Type>(
this);
298 impl->f64Ty = TypeUniquer::get<Float64Type>(
this);
299 impl->f80Ty = TypeUniquer::get<Float80Type>(
this);
300 impl->f128Ty = TypeUniquer::get<Float128Type>(
this);
302 impl->indexTy = TypeUniquer::get<IndexType>(
this);
304 impl->int1Ty = TypeUniquer::get<IntegerType>(
this, 1, IntegerType::Signless);
305 impl->int8Ty = TypeUniquer::get<IntegerType>(
this, 8, IntegerType::Signless);
307 TypeUniquer::get<IntegerType>(
this, 16, IntegerType::Signless);
309 TypeUniquer::get<IntegerType>(
this, 32, IntegerType::Signless);
311 TypeUniquer::get<IntegerType>(
this, 64, IntegerType::Signless);
313 TypeUniquer::get<IntegerType>(
this, 128, IntegerType::Signless);
315 impl->noneType = TypeUniquer::get<NoneType>(
this);
321 impl->unknownLocAttr = AttributeUniquer::get<UnknownLoc>(
this);
323 impl->falseAttr = IntegerAttr::getBoolAttrUnchecked(
impl->int1Ty,
false);
324 impl->trueAttr = IntegerAttr::getBoolAttrUnchecked(
impl->int1Ty,
true);
326 impl->unitAttr = AttributeUniquer::get<UnitAttr>(
this);
328 impl->emptyDictionaryAttr = DictionaryAttr::getEmptyUnchecked(
this);
330 impl->emptyStringAttr = StringAttr::getEmptyStringAttrUnchecked(
this);
346 template <
typename T>
349 auto result = allocator.Allocate<T>(elements.size());
350 std::uninitialized_copy(elements.begin(), elements.end(), result);
363 void MLIRContext::executeActionInternal(
function_ref<
void()> actionFn,
365 assert(
getImpl().actionHandler);
386 assert(
impl->multiThreadedExecutionContext == 0 &&
387 "appending to the MLIRContext dialect registry while in a "
388 "multi-threaded execution context");
396 return impl->dialectsRegistry;
401 std::vector<Dialect *> result;
402 result.reserve(
impl->loadedDialects.size());
403 for (
auto &dialect :
impl->loadedDialects)
404 result.push_back(dialect.second.get());
405 llvm::array_pod_sort(result.begin(), result.end(),
407 return (*lhs)->getNamespace() < (*rhs)->getNamespace();
412 std::vector<StringRef> result;
413 for (
auto dialect :
impl->dialectsRegistry.getDialectNames())
414 result.push_back(dialect);
422 auto it =
impl->loadedDialects.find(name);
423 return (it !=
impl->loadedDialects.end()) ? it->second.get() :
nullptr;
431 impl->dialectsRegistry.getDialectAllocator(name);
432 return allocator ? allocator(
this) :
nullptr;
443 auto dialectIt =
impl.loadedDialects.try_emplace(dialectNamespace,
nullptr);
445 if (dialectIt.second) {
446 LLVM_DEBUG(llvm::dbgs()
447 <<
"Load new dialect in Context " << dialectNamespace <<
"\n");
449 if (
impl.multiThreadedExecutionContext != 0)
450 llvm::report_fatal_error(
451 "Loading a dialect (" + dialectNamespace +
452 ") while in a multi-threaded execution context (maybe "
453 "the PassManager): this can indicate a "
454 "missing `dependentDialects` in a pass for example.");
460 std::unique_ptr<Dialect> &dialect =
impl.loadedDialects[dialectNamespace] =
462 assert(dialect &&
"dialect ctor failed");
467 auto stringAttrsIt =
impl.dialectReferencingStrAttrs.find(dialectNamespace);
468 if (stringAttrsIt !=
impl.dialectReferencingStrAttrs.end()) {
471 impl.dialectReferencingStrAttrs.erase(stringAttrsIt);
475 impl.dialectsRegistry.applyExtensions(dialect.get());
476 return dialect.get();
480 if (dialectIt.first->second ==
nullptr)
481 llvm::report_fatal_error(
482 "Loading (and getting) a dialect (" + dialectNamespace +
483 ") while the same dialect is still loading: use loadDialect instead "
484 "of getOrLoadDialect.");
488 std::unique_ptr<Dialect> &dialect = dialectIt.first->second;
489 if (dialect->getTypeID() != dialectID)
490 llvm::report_fatal_error(
"a dialect with namespace '" + dialectNamespace +
491 "' has already been registered");
493 return dialect.get();
496 bool MLIRContext::isDialectLoading(StringRef dialectNamespace) {
506 auto dialectIt =
impl.loadedDialects.find(dialectNamespace);
508 if (dialectIt !=
impl.loadedDialects.end()) {
509 if (
auto *dynDialect = dyn_cast<DynamicDialect>(dialectIt->second.get()))
511 llvm::report_fatal_error(
"a dialect with namespace '" + dialectNamespace +
512 "' has already been registered");
515 LLVM_DEBUG(llvm::dbgs() <<
"Load new dynamic dialect in Context "
516 << dialectNamespace <<
"\n");
518 if (
impl.multiThreadedExecutionContext != 0)
519 llvm::report_fatal_error(
520 "Loading a dynamic dialect (" + dialectNamespace +
521 ") while in a multi-threaded execution context (maybe "
522 "the PassManager): this can indicate a "
523 "missing `dependentDialects` in a pass for example.");
530 return std::unique_ptr<DynamicDialect>(dialect);
543 llvm::hash_code hash(0);
545 hash = llvm::hash_combine(hash,
impl->loadedDialects.size());
546 hash = llvm::hash_combine(hash,
impl->registeredAttributes.size());
547 hash = llvm::hash_combine(hash,
impl->registeredOperations.size());
548 hash = llvm::hash_combine(hash,
impl->registeredTypes.size());
553 return impl->allowUnregisteredDialects;
557 assert(
impl->multiThreadedExecutionContext == 0 &&
558 "changing MLIRContext `allow-unregistered-dialects` configuration "
559 "while in a multi-threaded execution context");
560 impl->allowUnregisteredDialects = allowing;
565 return impl->threadingIsEnabled && llvm::llvm_is_multithreaded();
574 assert(
impl->multiThreadedExecutionContext == 0 &&
575 "changing MLIRContext `disable-threading` configuration while "
576 "in a multi-threaded execution context");
578 impl->threadingIsEnabled = !disable;
581 impl->affineUniquer.disableMultithreading(disable);
582 impl->attributeUniquer.disableMultithreading(disable);
583 impl->typeUniquer.disableMultithreading(disable);
591 if (
impl->ownedThreadPool) {
592 assert(
impl->threadPool);
593 impl->threadPool =
nullptr;
594 impl->ownedThreadPool.reset();
596 }
else if (!
impl->threadPool) {
598 assert(!
impl->ownedThreadPool);
599 impl->ownedThreadPool = std::make_unique<llvm::ThreadPool>();
600 impl->threadPool =
impl->ownedThreadPool.get();
606 "expected multi-threading to be disabled when setting a ThreadPool");
607 impl->threadPool = &pool;
608 impl->ownedThreadPool.reset();
614 assert(
impl->threadPool &&
615 "multi-threading is enabled but threadpool not set");
616 return impl->threadPool->getThreadCount();
624 "expected multi-threading to be enabled within the context");
625 assert(
impl->threadPool &&
626 "multi-threading is enabled but threadpool not set");
627 return *
impl->threadPool;
632 ++
impl->multiThreadedExecutionContext;
637 --
impl->multiThreadedExecutionContext;
644 return impl->printOpOnDiagnostic;
650 assert(
impl->multiThreadedExecutionContext == 0 &&
651 "changing MLIRContext `print-op-on-diagnostic` configuration while in "
652 "a multi-threaded execution context");
653 impl->printOpOnDiagnostic = enable;
659 return impl->printStackTraceOnDiagnostic;
665 assert(
impl->multiThreadedExecutionContext == 0 &&
666 "changing MLIRContext `print-stacktrace-on-diagnostic` configuration "
667 "while in a multi-threaded execution context");
668 impl->printStackTraceOnDiagnostic = enable;
673 return impl->sortedRegisteredOperations;
682 assert(
impl.multiThreadedExecutionContext == 0 &&
683 "Registering a new type kind while in a multi-threaded execution "
688 if (!
impl.registeredTypes.insert({typeID, newInfo}).second)
689 llvm::report_fatal_error(
"Dialect Type already registered.");
694 assert(
impl.multiThreadedExecutionContext == 0 &&
695 "Registering a new attribute kind while in a multi-threaded execution "
700 if (!
impl.registeredAttributes.insert({typeID, newInfo}).second)
701 llvm::report_fatal_error(
"Dialect Attribute already registered.");
713 llvm::report_fatal_error(
"Trying to create an Attribute that was not "
714 "registered in this MLIRContext.");
721 auto it =
impl.registeredAttributes.find(typeID);
722 if (it ==
impl.registeredAttributes.end())
733 :
Impl(StringAttr::
get(dialect->getContext(), name), dialect, typeID,
734 std::move(interfaceMap)) {}
741 if (isMultithreadingEnabled) {
747 impl = registeredIt->second.impl;
754 impl = it->second.get();
762 auto it = ctxImpl.
operations.insert({name,
nullptr});
765 it.first->second = std::make_unique<UnregisteredOpModel>(
766 nameAttr, nameAttr.getReferencedDialect(), TypeID::get<void>(),
769 impl = it.first->second.get();
774 return dialect->getNamespace();
789 llvm::report_fatal_error(
"getParseAssemblyFn hook called on unregistered op");
806 std::optional<Attribute>
809 auto dict = dyn_cast_or_null<DictionaryAttr>(getPropertiesAsAttr(op));
819 auto dict = dyn_cast_or_null<DictionaryAttr>(getPropertiesAsAttr(op));
822 attrs.
set(name, value);
861 return llvm::hash_combine(*prop.
as<
Attribute *>());
868 std::optional<RegisteredOperationName>
871 auto it =
impl.registeredOperations.find(name);
872 if (it !=
impl.registeredOperations.end())
873 return it->getValue();
878 std::unique_ptr<RegisteredOperationName::Impl> ownedImpl,
882 auto &ctxImpl = ctx->
getImpl();
883 assert(ctxImpl.multiThreadedExecutionContext == 0 &&
884 "registering a new operation kind while in a multi-threaded execution "
889 if (!attrNames.empty()) {
891 ctxImpl.abstractDialectSymbolAllocator.Allocate<StringAttr>(
894 for (
unsigned i : llvm::seq<unsigned>(0, attrNames.size()))
895 new (&cachedAttrNames[i]) StringAttr(
StringAttr::get(ctx, attrNames[i]));
896 impl->attributeNames = cachedAttrNames;
898 StringRef name =
impl->getName().strref();
900 auto it = ctxImpl.operations.insert({name,
nullptr});
901 it.first->second = std::move(ownedImpl);
904 auto emplaced = ctxImpl.registeredOperations.try_emplace(
906 assert(emplaced.second &&
"operation name registration must be successful");
910 ctxImpl.sortedRegisteredOperations.
insert(
911 llvm::upper_bound(ctxImpl.sortedRegisteredOperations, value,
912 [](
auto &lhs,
auto &rhs) {
913 return lhs.getIdentifier().compare(
914 rhs.getIdentifier());
924 const AbstractType *type = lookupMutable(typeID, context);
926 llvm::report_fatal_error(
927 "Trying to create a Type that was not registered in this MLIRContext.");
933 auto it =
impl.registeredTypes.find(typeID);
934 if (it ==
impl.registeredTypes.end())
990 IntegerType::SignednessSemantics signedness,
992 if (signedness != IntegerType::Signless)
993 return IntegerType();
1009 return IntegerType();
1014 IntegerType::SignednessSemantics signedness) {
1017 return Base::get(context, width, signedness);
1023 SignednessSemantics signedness) {
1026 return Base::getChecked(
emitError, context, width, signedness);
1045 return getImpl().attributeUniquer;
1049 void AttributeUniquer::initializeAttributeStorage(
AttributeStorage *storage,
1068 DictionaryAttr DictionaryAttr::getEmpty(
MLIRContext *context) {
1075 auto dialectNamePair = value.split(
'.');
1076 if (dialectNamePair.first.empty() || dialectNamePair.second.empty())
1082 if ((referencedDialect = context->
getLoadedDialect(dialectNamePair.first)))
1086 llvm::sys::SmartScopedLock<true> lock(
impl.dialectRefStrAttrMutex);
1087 impl.dialectReferencingStrAttrs[dialectNamePair.first].push_back(
this);
1100 return getImpl().affineUniquer;
1103 AffineMap AffineMap::getImpl(
unsigned dimCount,
unsigned symbolCount,
1109 symbolCount, results);
1118 LLVM_ATTRIBUTE_UNUSED
static bool
1121 int64_t maxDimPosition = -1;
1122 int64_t maxSymbolPosition = -1;
1125 if ((maxDimPosition >= dimCount) || (maxSymbolPosition >= symbolCount)) {
1128 <<
"maximum dimensional identifier position in result expression must "
1129 "be less than `dimCount` and maximum symbolic identifier position "
1130 "in result expression must be less than `symbolCount`\n");
1137 return getImpl(0, 0, {}, context);
1142 return getImpl(dimCount, symbolCount, {}, context);
1154 return getImpl(dimCount, symbolCount, results, context);
1166 assert(!constraints.empty());
1167 assert(constraints.size() == eqFlags.size());
1169 auto &
impl = constraints[0].getContext()->getImpl();
static LLVM_ATTRIBUTE_UNUSED bool willBeValidAffineMap(unsigned dimCount, unsigned symbolCount, ArrayRef< AffineExpr > results)
Check whether the arguments passed to the AffineMap::get() are consistent.
static bool isThreadingGloballyDisabled()
static ArrayRef< T > copyArrayRefInto(llvm::BumpPtrAllocator &allocator, ArrayRef< T > elements)
Copy the specified array of elements into memory managed by the provided bump pointer allocator.
static llvm::ManagedStatic< MLIRContextOptions > clOptions
static IntegerType getCachedIntegerType(unsigned width, IntegerType::SignednessSemantics signedness, MLIRContext *context)
Return an existing integer type instance if one is cached within the context.
static std::string diag(const llvm::Value &value)
This class contains all of the static information common to all instances of a registered Attribute.
static const AbstractAttribute & lookup(TypeID typeID, MLIRContext *context)
Look up the specified abstract attribute in the MLIRContext and return a reference to it.
This class contains all of the static information common to all instances of a registered Type.
static const AbstractType & lookup(TypeID typeID, MLIRContext *context)
Look up the specified abstract type in the MLIRContext and return a reference to it.
Base type for affine expression.
MLIRContext * getContext() const
A multi-dimensional affine map Affine map's are immutable like Type's, and they are uniqued.
static AffineMap get(MLIRContext *context)
Returns a zero result affine map with no dimensions or symbols: () -> ().
Base storage class appearing in an attribute.
void initializeAbstractAttribute(const AbstractAttribute &abstractAttr)
Set the abstract attribute for this storage instance.
Attributes are known-constant values of operations.
Special case of IntegerAttr to represent boolean integers, i.e., signless i1 integers.
static BoolAttr get(MLIRContext *context, bool value)
This class is the main interface for diagnostics.
The DialectRegistry maps a dialect namespace to a constructor for the matching dialect.
bool isSubsetOf(const DialectRegistry &rhs) const
Returns true if the current registry is a subset of 'rhs', i.e.
void appendTo(DialectRegistry &destination) const
void applyExtensions(Dialect *dialect) const
Apply any held extensions that require the given dialect.
Dialects are groups of MLIR operations, types and attributes, as well as behavior associated with the...
A dialect that can be defined at runtime.
This class represents a diagnostic that is inflight and set to be reported.
An integer set representing a conjunction of one or more affine equalities and inequalities.
static IntegerSet get(unsigned dimCount, unsigned symbolCount, ArrayRef< AffineExpr > constraints, ArrayRef< bool > eqFlags)
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
This is the implementation of the MLIRContext class, using the pImpl idiom.
DictionaryAttr emptyDictionaryAttr
DenseMap< StringRef, std::unique_ptr< Dialect > > loadedDialects
This is a list of dialects that are created referring to this context.
BoolAttr falseAttr
Cached Attribute Instances.
llvm::sys::SmartRWMutex< true > operationInfoMutex
A mutex used when accessing operation information.
Float8E5M2FNUZType f8E5M2FNUZTy
DenseMap< StringRef, SmallVector< StringAttrStorage * > > dialectReferencingStrAttrs
StringAttr emptyStringAttr
std::function< void(function_ref< void()>, const tracing::Action &)> actionHandler
An action handler for handling actions that are dispatched through this context.
llvm::sys::SmartMutex< true > dialectRefStrAttrMutex
Map of string attributes that may reference a dialect, that are awaiting that dialect to be loaded.
StorageUniquer typeUniquer
llvm::BumpPtrAllocator abstractDialectSymbolAllocator
An allocator used for AbstractAttribute and AbstractType objects.
DenseMap< TypeID, AbstractType * > registeredTypes
Float8E5M2Type f8E5M2Ty
Cached Type Instances.
StorageUniquer affineUniquer
DiagnosticEngine diagEngine
UnknownLoc unknownLocAttr
DenseMap< TypeID, AbstractAttribute * > registeredAttributes
llvm::StringMap< std::unique_ptr< OperationName::Impl > > operations
This is a mapping from operation name to the operation info describing it.
Float8E4M3FNUZType f8E4M3FNUZTy
llvm::StringMap< RegisteredOperationName > registeredOperations
A vector of operation info specifically for registered operations.
Float8E4M3B11FNUZType f8E4M3B11FNUZTy
SmallVector< RegisteredOperationName, 0 > sortedRegisteredOperations
This is a sorted container of registered operations for a deterministic and efficient getRegisteredOp...
Float8E4M3FNType f8E4M3FNTy
MLIRContextImpl(bool threadingIsEnabled)
std::unique_ptr< llvm::ThreadPool > ownedThreadPool
In case where the thread pool is owned by the context, this ensures destruction with the context.
StorageUniquer attributeUniquer
DialectRegistry dialectsRegistry
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.
bool shouldPrintStackTraceOnDiagnostic()
Return true if we should attach the current stacktrace to diagnostics when emitted.
unsigned getNumThreads()
Return the number of threads used by the thread pool in this context.
bool isOperationRegistered(StringRef name)
Return true if this operation name is registered in this context.
MLIRContext(Threading multithreading=Threading::ENABLED)
Create a new Context.
void disableMultithreading(bool disable=true)
Set the flag specifying if multi-threading is disabled by the context.
void printStackTraceOnDiagnostic(bool enable)
Set the flag specifying if we should attach the current stacktrace when emitting diagnostics.
Dialect * getLoadedDialect(StringRef name)
Get a registered IR dialect with the given namespace.
bool hasActionHandler()
Return true if a valid ActionHandler is set.
void setThreadPool(llvm::ThreadPool &pool)
Set a new thread pool to be used in this context.
void enableMultithreading(bool enable=true)
std::vector< Dialect * > getLoadedDialects()
Return information about all IR dialects loaded in the context.
void printOpOnDiagnostic(bool enable)
Set the flag specifying if we should attach the operation to diagnostics emitted via Operation::emit.
void registerActionHandler(HandlerTy handler)
Register a handler for handling actions that are dispatched through this context.
ArrayRef< RegisteredOperationName > getRegisteredOperations()
Return a sorted array containing the information about all registered operations.
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...
const DialectRegistry & getDialectRegistry()
Return the dialect registry associated with this context.
DynamicDialect * getOrLoadDynamicDialect(StringRef dialectNamespace, function_ref< void(DynamicDialect *)> ctor)
Get (or create) a dynamic dialect for the given name.
StorageUniquer & getAttributeUniquer()
Returns the storage uniquer used for constructing attribute storage instances.
StorageUniquer & getAffineUniquer()
Returns the storage uniquer used for creating affine constructs.
llvm::ThreadPool & getThreadPool()
Return the thread pool used by this context.
StorageUniquer & getTypeUniquer()
Returns the storage uniquer used for constructing type storage instances.
std::vector< StringRef > getAvailableDialects()
Return information about all available dialects in the registry in this context.
bool isMultithreadingEnabled()
Return true if multi-threading is enabled by the context.
void allowUnregisteredDialects(bool allow=true)
Enables creating operations in unregistered dialects.
bool allowsUnregisteredDialects()
Return true if we allow to create operation for unregistered dialects.
T * getLoadedDialect()
Get a registered IR dialect for the given derived dialect type.
DiagnosticEngine & getDiagEngine()
Returns the diagnostic engine for this context.
std::function< void(function_ref< void()>, const tracing::Action &)> HandlerTy
Signatures for the action handler that can be registered with the context.
MLIRContextImpl & getImpl()
T * getOrLoadDialect()
Get (or create) a dialect for the given derived dialect type.
void exitMultiThreadedExecution()
bool shouldPrintOpOnDiagnostic()
Return true if we should attach the operation to diagnostics emitted via Operation::emit.
void loadAllAvailableDialects()
Load all dialects available in the registry in this context.
NamedAttrList is array of NamedAttributes that tracks whether it is sorted and does some basic work t...
DictionaryAttr getDictionary(MLIRContext *context) const
Return a dictionary attribute for the underlying dictionary.
Attribute set(StringAttr name, Attribute value)
If the an attribute exists with the specified name, change it to the new value.
This is a pure-virtual base class that exposes the asmprinter hooks necessary to implement a custom p...
virtual void printGenericOp(Operation *op, bool printOpName=true)=0
Print the entire operation with the default generic assembly form.
Simple wrapper around a void* in order to express generically how to pass in op properties through AP...
Impl(StringRef, Dialect *dialect, TypeID typeID, detail::InterfaceMap interfaceMap)
StringRef getStringRef() const
Return the name of this operation. This always succeeds.
llvm::unique_function< ParseResult(OpAsmParser &, OperationState &)> ParseAssemblyFn
Dialect * getDialect() const
Return the dialect this operation is registered to if the dialect is loaded in the context,...
OperationName(StringRef name, MLIRContext *context)
StringRef getDialectNamespace() const
Return the name of the dialect this operation is registered to.
Operation is the basic unit of execution within MLIR.
MLIRContext * getContext()
Return the context this operation is associated with.
OpaqueProperties getPropertiesStorage()
Returns the properties storage.
This is a "type erased" representation of a registered operation.
static void insert(Dialect &dialect)
Register a new operation in a Dialect object.
static std::optional< RegisteredOperationName > lookup(StringRef name, MLIRContext *ctx)
Lookup the registered operation information for the given operation.
A utility class to get or create instances of "storage classes".
This class provides an efficient unique identifier for a specific C++ type.
This class provides an efficient mapping between a given Interface type, and a particular implementat...
An action is a specific action that is to be taken by the compiler, that can be toggled and controlle...
Detect if any of the given parameter types has a sub-element handler.
llvm::unique_function< InFlightDiagnostic()> getDefaultDiagnosticEmitFn(MLIRContext *ctx)
Utility method to generate a callback that can be used to generate a diagnostic when checking the con...
This header declares functions that assist transformations in the MemRef dialect.
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
void registerMLIRContextCLOptions()
Register a set of useful command-line options that can be used to configure various flags within the ...
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
static void getMaxDimAndSymbol(ArrayRef< AffineExprContainer > exprsList, int64_t &maxDim, int64_t &maxSym)
Calculates maximum dimension and symbol positions from the expressions in exprsLists and stores them ...
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
This class represents an efficient way to signal success or failure.
LogicalResult foldHook(Operation *, ArrayRef< Attribute >, SmallVectorImpl< OpFoldResult > &) final
llvm::hash_code hashProperties(OpaqueProperties) final
void populateInherentAttrs(Operation *op, NamedAttrList &attrs) final
void deleteProperties(OpaqueProperties) final
int getOpPropertyByteSize() final
LogicalResult verifyInherentAttrs(OperationName opName, NamedAttrList &attributes, function_ref< InFlightDiagnostic()> getDiag) final
void setInherentAttr(Operation *op, StringAttr name, Attribute value) final
void populateDefaultProperties(OperationName opName, OpaqueProperties properties) final
OperationName::ParseAssemblyFn getParseAssemblyFn() final
bool hasTrait(TypeID) final
LogicalResult verifyRegionInvariants(Operation *) final
std::optional< Attribute > getInherentAttr(Operation *op, StringRef name) final
Implementation for properties.
void getCanonicalizationPatterns(RewritePatternSet &, MLIRContext *) final
void initProperties(OperationName opName, OpaqueProperties storage, OpaqueProperties init) final
void populateDefaultAttrs(const OperationName &, NamedAttrList &) final
void printAssembly(Operation *, OpAsmPrinter &, StringRef) final
LogicalResult verifyInvariants(Operation *) final
void copyProperties(OpaqueProperties, OpaqueProperties) final
LogicalResult setPropertiesFromAttr(Operation *, Attribute, InFlightDiagnostic *) final
Attribute getPropertiesAsAttr(Operation *) final
A binary operation appearing in an affine expression.
An integer constant appearing in affine expression.
A dimensional or symbolic identifier appearing in an affine expression.
Dialect * referencedDialect
If the string value contains a dialect namespace prefix (e.g.