14 #include "TypeDetail.h"
29 #include "llvm/ADT/DenseMap.h"
30 #include "llvm/ADT/DenseSet.h"
31 #include "llvm/ADT/SmallString.h"
32 #include "llvm/ADT/StringSet.h"
33 #include "llvm/ADT/Twine.h"
34 #include "llvm/Support/Allocator.h"
35 #include "llvm/Support/CommandLine.h"
36 #include "llvm/Support/Compiler.h"
37 #include "llvm/Support/Debug.h"
38 #include "llvm/Support/Mutex.h"
39 #include "llvm/Support/RWMutex.h"
40 #include "llvm/Support/ThreadPool.h"
41 #include "llvm/Support/raw_ostream.h"
45 #define DEBUG_TYPE "mlircontext"
58 struct MLIRContextOptions {
59 llvm::cl::opt<bool> disableThreading{
60 "mlir-disable-threading",
61 llvm::cl::desc(
"Disable multi-threading within MLIR, overrides any "
62 "further call to MLIRContext::enableMultiThreading()")};
64 llvm::cl::opt<bool> printOpOnDiagnostic{
65 "mlir-print-op-on-diagnostic",
66 llvm::cl::desc(
"When a diagnostic is emitted on an operation, also print "
67 "the operation as an attached note"),
68 llvm::cl::init(
true)};
70 llvm::cl::opt<bool> printStackTraceOnDiagnostic{
71 "mlir-print-stacktrace-on-diagnostic",
72 llvm::cl::desc(
"When a diagnostic is emitted, also print the stack trace "
73 "as an attached note")};
77 static llvm::ManagedStatic<MLIRContextOptions>
clOptions;
80 #if LLVM_ENABLE_THREADS != 0
102 struct ScopedWriterLock {
103 ScopedWriterLock(llvm::sys::SmartRWMutex<true> &mutexParam,
bool shouldLock)
104 : mutex(shouldLock ? &mutexParam : nullptr) {
108 ~ScopedWriterLock() {
112 llvm::sys::SmartRWMutex<true> *mutex;
146 bool allowUnregisteredDialects =
false;
149 bool threadingIsEnabled =
true;
155 std::atomic<int> multiThreadedExecutionContext{0};
160 bool printOpOnDiagnostic =
true;
163 bool printStackTraceOnDiagnostic =
false;
173 llvm::ThreadPoolInterface *threadPool =
nullptr;
183 llvm::StringMap<std::unique_ptr<OperationName::Impl>>
operations;
243 IntegerType int1Ty, int8Ty, int16Ty, int32Ty, int64Ty,
int128Ty;
282 : threadingIsEnabled(threadingIsEnabled) {
283 if (threadingIsEnabled) {
284 ownedThreadPool = std::make_unique<llvm::DefaultThreadPool>();
285 threadPool = ownedThreadPool.get();
289 for (
auto typeMapping : registeredTypes)
290 typeMapping.second->~AbstractType();
291 for (
auto attrMapping : registeredAttributes)
292 attrMapping.second->~AbstractAttribute();
313 getOrLoadDialect<BuiltinDialect>();
320 impl->f4E2M1FNTy = TypeUniquer::get<Float4E2M1FNType>(
this);
321 impl->f6E2M3FNTy = TypeUniquer::get<Float6E2M3FNType>(
this);
322 impl->f6E3M2FNTy = TypeUniquer::get<Float6E3M2FNType>(
this);
323 impl->f8E5M2Ty = TypeUniquer::get<Float8E5M2Type>(
this);
324 impl->f8E4M3Ty = TypeUniquer::get<Float8E4M3Type>(
this);
325 impl->f8E4M3FNTy = TypeUniquer::get<Float8E4M3FNType>(
this);
326 impl->f8E5M2FNUZTy = TypeUniquer::get<Float8E5M2FNUZType>(
this);
327 impl->f8E4M3FNUZTy = TypeUniquer::get<Float8E4M3FNUZType>(
this);
328 impl->f8E4M3B11FNUZTy = TypeUniquer::get<Float8E4M3B11FNUZType>(
this);
329 impl->f8E3M4Ty = TypeUniquer::get<Float8E3M4Type>(
this);
330 impl->f8E8M0FNUTy = TypeUniquer::get<Float8E8M0FNUType>(
this);
331 impl->bf16Ty = TypeUniquer::get<BFloat16Type>(
this);
332 impl->f16Ty = TypeUniquer::get<Float16Type>(
this);
333 impl->tf32Ty = TypeUniquer::get<FloatTF32Type>(
this);
334 impl->f32Ty = TypeUniquer::get<Float32Type>(
this);
335 impl->f64Ty = TypeUniquer::get<Float64Type>(
this);
336 impl->f80Ty = TypeUniquer::get<Float80Type>(
this);
337 impl->f128Ty = TypeUniquer::get<Float128Type>(
this);
339 impl->indexTy = TypeUniquer::get<IndexType>(
this);
341 impl->int1Ty = TypeUniquer::get<IntegerType>(
this, 1, IntegerType::Signless);
342 impl->int8Ty = TypeUniquer::get<IntegerType>(
this, 8, IntegerType::Signless);
344 TypeUniquer::get<IntegerType>(
this, 16, IntegerType::Signless);
346 TypeUniquer::get<IntegerType>(
this, 32, IntegerType::Signless);
348 TypeUniquer::get<IntegerType>(
this, 64, IntegerType::Signless);
350 TypeUniquer::get<IntegerType>(
this, 128, IntegerType::Signless);
352 impl->noneType = TypeUniquer::get<NoneType>(
this);
358 impl->unknownLocAttr = AttributeUniquer::get<UnknownLoc>(
this);
360 impl->falseAttr = IntegerAttr::getBoolAttrUnchecked(
impl->int1Ty,
false);
361 impl->trueAttr = IntegerAttr::getBoolAttrUnchecked(
impl->int1Ty,
true);
363 impl->unitAttr = AttributeUniquer::get<UnitAttr>(
this);
365 impl->emptyDictionaryAttr = DictionaryAttr::getEmptyUnchecked(
this);
367 impl->emptyStringAttr = StringAttr::getEmptyStringAttrUnchecked(
this);
383 template <
typename T>
386 auto result = allocator.Allocate<T>(elements.size());
387 std::uninitialized_copy(elements.begin(), elements.end(), result);
400 void MLIRContext::executeActionInternal(
function_ref<
void()> actionFn,
402 assert(
getImpl().actionHandler);
423 assert(
impl->multiThreadedExecutionContext == 0 &&
424 "appending to the MLIRContext dialect registry while in a "
425 "multi-threaded execution context");
433 return impl->dialectsRegistry;
438 std::vector<Dialect *> result;
439 result.reserve(
impl->loadedDialects.size());
440 for (
auto &dialect :
impl->loadedDialects)
441 result.push_back(dialect.second.get());
442 llvm::array_pod_sort(result.begin(), result.end(),
444 return (*lhs)->getNamespace() < (*rhs)->getNamespace();
449 std::vector<StringRef> result;
450 for (
auto dialect :
impl->dialectsRegistry.getDialectNames())
451 result.push_back(dialect);
459 auto it =
impl->loadedDialects.find(name);
460 return (it !=
impl->loadedDialects.end()) ? it->second.get() :
nullptr;
468 impl->dialectsRegistry.getDialectAllocator(name);
469 return allocator ? allocator(
this) :
nullptr;
480 auto dialectIt =
impl.loadedDialects.try_emplace(dialectNamespace,
nullptr);
482 if (dialectIt.second) {
483 LLVM_DEBUG(llvm::dbgs()
484 <<
"Load new dialect in Context " << dialectNamespace <<
"\n");
486 if (
impl.multiThreadedExecutionContext != 0)
487 llvm::report_fatal_error(
488 "Loading a dialect (" + dialectNamespace +
489 ") while in a multi-threaded execution context (maybe "
490 "the PassManager): this can indicate a "
491 "missing `dependentDialects` in a pass for example.");
497 std::unique_ptr<Dialect> &dialectOwned =
498 impl.loadedDialects[dialectNamespace] = ctor();
499 Dialect *dialect = dialectOwned.get();
500 assert(dialect &&
"dialect ctor failed");
505 auto stringAttrsIt =
impl.dialectReferencingStrAttrs.find(dialectNamespace);
506 if (stringAttrsIt !=
impl.dialectReferencingStrAttrs.end()) {
509 impl.dialectReferencingStrAttrs.erase(stringAttrsIt);
513 impl.dialectsRegistry.applyExtensions(dialect);
518 if (dialectIt.first->second ==
nullptr)
519 llvm::report_fatal_error(
520 "Loading (and getting) a dialect (" + dialectNamespace +
521 ") while the same dialect is still loading: use loadDialect instead "
522 "of getOrLoadDialect.");
526 std::unique_ptr<Dialect> &dialect = dialectIt.first->second;
527 if (dialect->getTypeID() != dialectID)
528 llvm::report_fatal_error(
"a dialect with namespace '" + dialectNamespace +
529 "' has already been registered");
531 return dialect.get();
534 bool MLIRContext::isDialectLoading(StringRef dialectNamespace) {
544 auto dialectIt =
impl.loadedDialects.find(dialectNamespace);
546 if (dialectIt !=
impl.loadedDialects.end()) {
547 if (
auto *dynDialect = dyn_cast<DynamicDialect>(dialectIt->second.get()))
549 llvm::report_fatal_error(
"a dialect with namespace '" + dialectNamespace +
550 "' has already been registered");
553 LLVM_DEBUG(llvm::dbgs() <<
"Load new dynamic dialect in Context "
554 << dialectNamespace <<
"\n");
556 if (
impl.multiThreadedExecutionContext != 0)
557 llvm::report_fatal_error(
558 "Loading a dynamic dialect (" + dialectNamespace +
559 ") while in a multi-threaded execution context (maybe "
560 "the PassManager): this can indicate a "
561 "missing `dependentDialects` in a pass for example.");
568 return std::unique_ptr<DynamicDialect>(dialect);
581 llvm::hash_code hash(0);
583 hash = llvm::hash_combine(hash,
impl->loadedDialects.size());
584 hash = llvm::hash_combine(hash,
impl->registeredAttributes.size());
585 hash = llvm::hash_combine(hash,
impl->registeredOperations.size());
586 hash = llvm::hash_combine(hash,
impl->registeredTypes.size());
591 return impl->allowUnregisteredDialects;
595 assert(
impl->multiThreadedExecutionContext == 0 &&
596 "changing MLIRContext `allow-unregistered-dialects` configuration "
597 "while in a multi-threaded execution context");
598 impl->allowUnregisteredDialects = allowing;
603 return impl->threadingIsEnabled && llvm::llvm_is_multithreaded();
612 assert(
impl->multiThreadedExecutionContext == 0 &&
613 "changing MLIRContext `disable-threading` configuration while "
614 "in a multi-threaded execution context");
616 impl->threadingIsEnabled = !disable;
619 impl->affineUniquer.disableMultithreading(disable);
620 impl->attributeUniquer.disableMultithreading(disable);
621 impl->typeUniquer.disableMultithreading(disable);
629 if (
impl->ownedThreadPool) {
630 assert(
impl->threadPool);
631 impl->threadPool =
nullptr;
632 impl->ownedThreadPool.reset();
634 }
else if (!
impl->threadPool) {
636 assert(!
impl->ownedThreadPool);
637 impl->ownedThreadPool = std::make_unique<llvm::DefaultThreadPool>();
638 impl->threadPool =
impl->ownedThreadPool.get();
644 "expected multi-threading to be disabled when setting a ThreadPool");
645 impl->threadPool = &pool;
646 impl->ownedThreadPool.reset();
652 assert(
impl->threadPool &&
653 "multi-threading is enabled but threadpool not set");
654 return impl->threadPool->getMaxConcurrency();
662 "expected multi-threading to be enabled within the context");
663 assert(
impl->threadPool &&
664 "multi-threading is enabled but threadpool not set");
665 return *
impl->threadPool;
670 ++
impl->multiThreadedExecutionContext;
675 --
impl->multiThreadedExecutionContext;
682 return impl->printOpOnDiagnostic;
688 assert(
impl->multiThreadedExecutionContext == 0 &&
689 "changing MLIRContext `print-op-on-diagnostic` configuration while in "
690 "a multi-threaded execution context");
691 impl->printOpOnDiagnostic = enable;
697 return impl->printStackTraceOnDiagnostic;
703 assert(
impl->multiThreadedExecutionContext == 0 &&
704 "changing MLIRContext `print-stacktrace-on-diagnostic` configuration "
705 "while in a multi-threaded execution context");
706 impl->printStackTraceOnDiagnostic = enable;
711 return impl->sortedRegisteredOperations;
718 std::lower_bound(
impl->sortedRegisteredOperations.begin(),
719 impl->sortedRegisteredOperations.end(), dialectName,
720 [](
auto &lhs,
auto &rhs) {
721 return lhs.getDialect().getNamespace().compare(rhs);
724 if (lowerBound ==
impl->sortedRegisteredOperations.end() ||
725 lowerBound->getDialect().getNamespace() != dialectName)
729 std::upper_bound(lowerBound,
impl->sortedRegisteredOperations.end(),
730 dialectName, [](
auto &lhs,
auto &rhs) {
731 return lhs.compare(rhs.getDialect().getNamespace());
734 size_t count = std::distance(lowerBound, upperBound);
735 return ArrayRef(&*lowerBound, count);
744 assert(
impl.multiThreadedExecutionContext == 0 &&
745 "Registering a new type kind while in a multi-threaded execution "
750 if (!
impl.registeredTypes.insert({typeID, newInfo}).second)
751 llvm::report_fatal_error(
"Dialect Type already registered.");
752 if (!
impl.nameToType.insert({newInfo->getName(), newInfo}).second)
753 llvm::report_fatal_error(
"Dialect Type with name " + newInfo->getName() +
754 " is already registered.");
759 assert(
impl.multiThreadedExecutionContext == 0 &&
760 "Registering a new attribute kind while in a multi-threaded execution "
765 if (!
impl.registeredAttributes.insert({typeID, newInfo}).second)
766 llvm::report_fatal_error(
"Dialect Attribute already registered.");
767 if (!
impl.nameToAttribute.insert({newInfo->getName(), newInfo}).second)
768 llvm::report_fatal_error(
"Dialect Attribute with name " +
769 newInfo->getName() +
" is already registered.");
781 llvm::report_fatal_error(
"Trying to create an Attribute that was not "
782 "registered in this MLIRContext.");
789 return impl.registeredAttributes.lookup(typeID);
792 std::optional<std::reference_wrapper<const AbstractAttribute>>
809 std::move(interfaceMap)) {}
816 if (isMultithreadingEnabled) {
822 impl = registeredIt->second.impl;
829 impl = it->second.get();
837 auto it = ctxImpl.
operations.insert({name,
nullptr});
840 it.first->second = std::make_unique<UnregisteredOpModel>(
841 nameAttr, nameAttr.getReferencedDialect(), TypeID::get<void>(),
844 impl = it.first->second.get();
849 return dialect->getNamespace();
864 llvm::report_fatal_error(
"getParseAssemblyFn hook called on unregistered op");
881 std::optional<Attribute>
884 auto dict = dyn_cast_or_null<DictionaryAttr>(getPropertiesAsAttr(op));
894 auto dict = dyn_cast_or_null<DictionaryAttr>(getPropertiesAsAttr(op));
897 attrs.
set(name, value);
941 return llvm::hash_combine(*prop.
as<
Attribute *>());
948 std::optional<RegisteredOperationName>
951 auto it =
impl.registeredOperations.find(typeID);
952 if (it !=
impl.registeredOperations.end())
957 std::optional<RegisteredOperationName>
960 auto it =
impl.registeredOperationsByName.find(name);
961 if (it !=
impl.registeredOperationsByName.end())
962 return it->getValue();
967 std::unique_ptr<RegisteredOperationName::Impl> ownedImpl,
971 auto &ctxImpl = ctx->
getImpl();
972 assert(ctxImpl.multiThreadedExecutionContext == 0 &&
973 "registering a new operation kind while in a multi-threaded execution "
978 if (!attrNames.empty()) {
980 ctxImpl.abstractDialectSymbolAllocator.Allocate<StringAttr>(
983 for (
unsigned i : llvm::seq<unsigned>(0, attrNames.size()))
984 new (&cachedAttrNames[i]) StringAttr(
StringAttr::get(ctx, attrNames[i]));
985 impl->attributeNames = cachedAttrNames;
987 StringRef name =
impl->getName().strref();
989 ctxImpl.operations[name] = std::move(ownedImpl);
992 auto emplaced = ctxImpl.registeredOperations.try_emplace(
994 assert(emplaced.second &&
"operation name registration must be successful");
995 auto emplacedByName = ctxImpl.registeredOperationsByName.try_emplace(
997 (void)emplacedByName;
998 assert(emplacedByName.second &&
999 "operation name registration must be successful");
1003 ctxImpl.sortedRegisteredOperations.
insert(
1004 llvm::upper_bound(ctxImpl.sortedRegisteredOperations, value,
1005 [](
auto &lhs,
auto &rhs) {
1006 return lhs.getIdentifier().compare(
1007 rhs.getIdentifier());
1017 const AbstractType *type = lookupMutable(typeID, context);
1019 llvm::report_fatal_error(
1020 "Trying to create a Type that was not registered in this MLIRContext.");
1026 return impl.registeredTypes.lookup(typeID);
1029 std::optional<std::reference_wrapper<const AbstractType>>
1035 return std::nullopt;
1111 IntegerType::SignednessSemantics signedness,
1113 if (signedness != IntegerType::Signless)
1114 return IntegerType();
1130 return IntegerType();
1135 IntegerType::SignednessSemantics signedness) {
1138 return Base::get(context, width, signedness);
1144 SignednessSemantics signedness) {
1147 return Base::getChecked(
emitError, context, width, signedness);
1166 return getImpl().attributeUniquer;
1170 void AttributeUniquer::initializeAttributeStorage(
AttributeStorage *storage,
1189 detail::DistinctAttributeUniquer::allocateStorage(
MLIRContext *context,
1195 DictionaryAttr DictionaryAttr::getEmpty(
MLIRContext *context) {
1202 auto dialectNamePair = value.split(
'.');
1203 if (dialectNamePair.first.empty() || dialectNamePair.second.empty())
1209 if ((referencedDialect = context->
getLoadedDialect(dialectNamePair.first)))
1213 llvm::sys::SmartScopedLock<true> lock(
impl.dialectRefStrAttrMutex);
1214 impl.dialectReferencingStrAttrs[dialectNamePair.first].push_back(
this);
1227 return getImpl().affineUniquer;
1230 AffineMap AffineMap::getImpl(
unsigned dimCount,
unsigned symbolCount,
1236 symbolCount, results);
1245 LLVM_ATTRIBUTE_UNUSED
static bool
1248 int64_t maxDimPosition = -1;
1249 int64_t maxSymbolPosition = -1;
1252 if ((maxDimPosition >= dimCount) || (maxSymbolPosition >= symbolCount)) {
1255 <<
"maximum dimensional identifier position in result expression must "
1256 "be less than `dimCount` and maximum symbolic identifier position "
1257 "in result expression must be less than `symbolCount`\n");
1264 return getImpl(0, 0, {}, context);
1269 return getImpl(dimCount, symbolCount, {}, context);
1281 return getImpl(dimCount, symbolCount, results, context);
1293 assert(!constraints.empty());
1294 assert(constraints.size() == eqFlags.size());
1296 auto &
impl = constraints[0].getContext()->getImpl();
static MLIRContext * getContext(OpFoldResult val)
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.
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
llvm::DenseMap< StringRef, AbstractAttribute * > nameToAttribute
This is a mapping from attribute name to the abstract attribute describing it.
DenseMap< StringRef, std::unique_ptr< Dialect > > loadedDialects
This is a list of dialects that are created referring to this context.
llvm::DenseMap< TypeID, RegisteredOperationName > registeredOperations
A vector of operation info specifically for registered operations.
BoolAttr falseAttr
Cached Attribute Instances.
llvm::sys::SmartRWMutex< true > operationInfoMutex
A mutex used when accessing operation information.
Float8E5M2FNUZType f8E5M2FNUZTy
Float6E2M3FNType f6E2M3FNTy
DenseMap< StringRef, SmallVector< StringAttrStorage * > > dialectReferencingStrAttrs
llvm::StringMap< RegisteredOperationName > registeredOperationsByName
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.
llvm::DenseMap< StringRef, AbstractType * > nameToType
This is a mapping from type name to the abstract type describing it.
StorageUniquer typeUniquer
llvm::BumpPtrAllocator abstractDialectSymbolAllocator
An allocator used for AbstractAttribute and AbstractType objects.
Float6E3M2FNType f6E3M2FNTy
DenseMap< TypeID, AbstractType * > registeredTypes
StorageUniquer affineUniquer
DiagnosticEngine diagEngine
UnknownLoc unknownLocAttr
DenseMap< TypeID, AbstractAttribute * > registeredAttributes
Float4E2M1FNType f4E2M1FNTy
Cached Type Instances.
llvm::StringMap< std::unique_ptr< OperationName::Impl > > operations
This is a mapping from operation name to the operation info describing it.
Float8E4M3FNUZType f8E4M3FNUZTy
Float8E4M3B11FNUZType f8E4M3B11FNUZTy
std::unique_ptr< llvm::ThreadPoolInterface > ownedThreadPool
In case where the thread pool is owned by the context, this ensures destruction with the context.
Float8E8M0FNUType f8E8M0FNUTy
SmallVector< RegisteredOperationName, 0 > sortedRegisteredOperations
This is a sorted container of registered operations for a deterministic and efficient getRegisteredOp...
Float8E4M3FNType f8E4M3FNTy
DistinctAttributeAllocator distinctAttributeAllocator
A distinct attribute allocator that allocates every time since the address of the distinct attribute ...
MLIRContextImpl(bool threadingIsEnabled)
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::ThreadPoolInterface &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.
ArrayRef< RegisteredOperationName > getRegisteredOperationsByDialect(StringRef dialectName)
Return a sorted array containing the information for registered operations filtered by dialect name.
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.
StorageUniquer & getTypeUniquer()
Returns the storage uniquer used for constructing type storage instances.
llvm::ThreadPoolInterface & getThreadPool()
Return the thread pool used by this context.
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.
An allocator for distinct attribute storage instances.
DistinctAttrStorage * allocate(Attribute referencedAttr)
Allocates a distinct attribute storage using a thread local bump pointer allocator to enable synchron...
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...
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...
Include the generated interface declarations.
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 ...
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...
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
LogicalResult setPropertiesFromAttr(OperationName, OpaqueProperties, Attribute, function_ref< InFlightDiagnostic()> emitError) final
int getOpPropertyByteSize() 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 verifyInherentAttrs(OperationName opName, NamedAttrList &attributes, function_ref< InFlightDiagnostic()> emitError) final
Attribute getPropertiesAsAttr(Operation *) final
bool compareProperties(OpaqueProperties, OpaqueProperties) 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.
An attribute to store a distinct reference to another attribute.
Dialect * referencedDialect
If the string value contains a dialect namespace prefix (e.g.