14#include "TypeDetail.h"
29#include "llvm/ADT/DenseMap.h"
30#include "llvm/ADT/Twine.h"
31#include "llvm/Support/Allocator.h"
32#include "llvm/Support/CommandLine.h"
33#include "llvm/Support/Compiler.h"
34#include "llvm/Support/DebugLog.h"
35#include "llvm/Support/ManagedStatic.h"
36#include "llvm/Support/Mutex.h"
37#include "llvm/Support/RWMutex.h"
38#include "llvm/Support/ThreadPool.h"
39#include "llvm/Support/raw_ostream.h"
43#define DEBUG_TYPE "mlircontext"
56struct MLIRContextOptions {
57 llvm::cl::opt<bool> disableThreading{
58 "mlir-disable-threading",
59 llvm::cl::desc(
"Disable multi-threading within MLIR, overrides any "
60 "further call to MLIRContext::enableMultiThreading()")};
62 llvm::cl::opt<bool> printOpOnDiagnostic{
63 "mlir-print-op-on-diagnostic",
64 llvm::cl::desc(
"When a diagnostic is emitted on an operation, also print "
65 "the operation as an attached note"),
66 llvm::cl::init(
true)};
68 llvm::cl::opt<bool> printStackTraceOnDiagnostic{
69 "mlir-print-stacktrace-on-diagnostic",
70 llvm::cl::desc(
"When a diagnostic is emitted, also print the stack trace "
71 "as an attached note")};
75static llvm::ManagedStatic<MLIRContextOptions>
clOptions;
78#if LLVM_ENABLE_THREADS != 0
100struct ScopedWriterLock {
101 ScopedWriterLock(llvm::sys::SmartRWMutex<true> &mutexParam,
bool shouldLock)
102 : mutex(shouldLock ? &mutexParam :
nullptr) {
106 ~ScopedWriterLock() {
110 llvm::sys::SmartRWMutex<true> *mutex;
190 llvm::StringMap<std::unique_ptr<OperationName::Impl>>
195 llvm::StringMap<std::unique_ptr<OperationName::Impl>, llvm::BumpPtrAllocator>
309 typeMapping.second->~AbstractType();
311 attrMapping.second->~AbstractAttribute();
324 printOpOnDiagnostic(clOptions->printOpOnDiagnostic);
325 printStackTraceOnDiagnostic(clOptions->printStackTraceOnDiagnostic);
368 impl->falseAttr = IntegerAttr::getBoolAttrUnchecked(
impl->int1Ty,
false);
369 impl->trueAttr = IntegerAttr::getBoolAttrUnchecked(
impl->int1Ty,
true);
373 impl->emptyDictionaryAttr = DictionaryAttr::getEmptyUnchecked(
this);
375 impl->emptyStringAttr = StringAttr::getEmptyStringAttrUnchecked(
this);
389 impl->remarkEngine.reset();
409void MLIRContext::executeActionInternal(
function_ref<
void()> actionFn,
411 assert(
getImpl().actionHandler);
429 std::unique_ptr<remark::detail::RemarkEngine> engine) {
445 assert(
impl->multiThreadedExecutionContext == 0 &&
446 "appending to the MLIRContext dialect registry while in a "
447 "multi-threaded execution context");
448 assert(!
impl->transientState &&
449 "cannot append to dialect registry while in a transient scope");
458 return impl->dialectsRegistry;
463 std::vector<Dialect *>
result;
465 for (
auto &dialect :
impl->loadedDialects)
466 result.push_back(dialect.second.get());
469 return (*lhs)->getNamespace() < (*rhs)->getNamespace();
474 std::vector<StringRef>
result;
475 for (
auto dialect :
impl->dialectsRegistry.getRegisteredDialectNames())
476 result.push_back(dialect);
484 auto it =
impl->loadedDialects.find(name);
485 return (it !=
impl->loadedDialects.end()) ? it->second.get() :
nullptr;
493 impl->dialectsRegistry.getDialectAllocator(name);
494 return allocator ? allocator(
this) :
nullptr;
505 auto dialectIt =
impl.loadedDialects.try_emplace(dialectNamespace,
nullptr);
507 if (dialectIt.second) {
508 LDBG() <<
"Load new dialect in Context " << dialectNamespace;
509 assert(!
impl.transientState &&
510 "cannot load new dialects while in a transient scope");
512 if (
impl.multiThreadedExecutionContext != 0)
513 llvm::report_fatal_error(
514 "Loading a dialect (" + dialectNamespace +
515 ") while in a multi-threaded execution context (maybe "
516 "the PassManager): this can indicate a "
517 "missing `dependentDialects` in a pass for example.");
523 std::unique_ptr<Dialect> &dialectOwned =
524 impl.loadedDialects[dialectNamespace] = ctor();
525 Dialect *dialect = dialectOwned.get();
526 assert(dialect &&
"dialect ctor failed");
531 auto stringAttrsIt =
impl.dialectReferencingStrAttrs.find(dialectNamespace);
532 if (stringAttrsIt !=
impl.dialectReferencingStrAttrs.end()) {
535 impl.dialectReferencingStrAttrs.erase(stringAttrsIt);
539 impl.dialectsRegistry.applyExtensions(dialect);
544 if (dialectIt.first->second ==
nullptr)
545 llvm::report_fatal_error(
546 "Loading (and getting) a dialect (" + dialectNamespace +
547 ") while the same dialect is still loading: use loadDialect instead "
548 "of getOrLoadDialect.");
552 std::unique_ptr<Dialect> &dialect = dialectIt.first->second;
553 if (dialect->getTypeID() != dialectID)
554 llvm::report_fatal_error(
"a dialect with namespace '" + dialectNamespace +
555 "' has already been registered");
557 return dialect.get();
560bool MLIRContext::isDialectLoading(StringRef dialectNamespace) {
570 auto dialectIt =
impl.loadedDialects.find(dialectNamespace);
572 if (dialectIt !=
impl.loadedDialects.end()) {
573 if (
auto *dynDialect = dyn_cast<DynamicDialect>(dialectIt->second.get()))
575 llvm::report_fatal_error(
"a dialect with namespace '" + dialectNamespace +
576 "' has already been registered");
579 LDBG() <<
"Load new dynamic dialect in Context " << dialectNamespace;
581 if (
impl.multiThreadedExecutionContext != 0)
582 llvm::report_fatal_error(
583 "Loading a dynamic dialect (" + dialectNamespace +
584 ") while in a multi-threaded execution context (maybe "
585 "the PassManager): this can indicate a "
586 "missing `dependentDialects` in a pass for example.");
589 auto name = StringAttr::get(
this, dialectNamespace);
593 return std::unique_ptr<DynamicDialect>(dialect);
606 llvm::hash_code
hash(0);
608 hash = llvm::hash_combine(
hash,
impl->loadedDialects.size());
609 hash = llvm::hash_combine(
hash,
impl->registeredAttributes.size());
610 hash = llvm::hash_combine(
hash,
impl->registeredOperations.size());
611 hash = llvm::hash_combine(
hash,
impl->registeredTypes.size());
616 return impl->allowUnregisteredDialects;
620 assert(
impl->multiThreadedExecutionContext == 0 &&
621 "changing MLIRContext `allow-unregistered-dialects` configuration "
622 "while in a multi-threaded execution context");
623 impl->allowUnregisteredDialects = allowing;
627#if LLVM_ENABLE_THREADS
637 assert(
impl->multiThreadedExecutionContext == 0 &&
638 "changing MLIRContext `disable-threading` configuration while "
639 "in a multi-threaded execution context");
641 impl->threadingIsEnabled = !disable;
643 impl->setThreadSafeLocking(!disable);
651 if (
impl->ownedThreadPool) {
652 assert(
impl->threadPool);
653 impl->threadPool =
nullptr;
654 impl->ownedThreadPool.reset();
656 }
else if (!
impl->threadPool) {
658 assert(!
impl->ownedThreadPool);
659 impl->ownedThreadPool = std::make_unique<llvm::DefaultThreadPool>();
660 impl->threadPool =
impl->ownedThreadPool.get();
664#if LLVM_ENABLE_THREADS
666 return impl->threadSafeLockingIsEnabled;
671 impl->setThreadSafeLocking(
true);
676 "expected multi-threading to be disabled when setting a ThreadPool");
677 impl->threadPool = &pool;
678 impl->ownedThreadPool.reset();
684 assert(
impl->threadPool &&
685 "multi-threading is enabled but threadpool not set");
686 return impl->threadPool->getMaxConcurrency();
694 "expected multi-threading to be enabled within the context");
695 assert(
impl->threadPool &&
696 "multi-threading is enabled but threadpool not set");
697 return *
impl->threadPool;
702 ++
impl->multiThreadedExecutionContext;
707 --
impl->multiThreadedExecutionContext;
714 "Beginning a transient scope while in a multi-threaded execution "
716 assert(!ctxImpl.
transientState &&
"context is already in a transient scope");
718 std::make_unique<MLIRContextImpl::TransientScopeState>();
737 ctxImpl.
transientState->baseDialectReferencingStrAttrCounts[entry.first] =
744 assert(ctxImpl.
transientState &&
"context is not in a transient scope");
746 "Ending a transient scope while in a multi-threaded execution "
757 if (!ctxImpl.
transientState->baseOperations.contains(entry.first()))
758 opsToErase.push_back(entry.first());
759 for (StringRef op : opsToErase)
776 ctxImpl.
transientState->baseDialectReferencingStrAttrCounts.end()) {
777 dialectsToErase.push_back(entry.first);
779 entry.second.resize(countIt->second);
782 for (StringRef dialect : dialectsToErase)
803 return impl->printOpOnDiagnostic;
809 assert(
impl->multiThreadedExecutionContext == 0 &&
810 "changing MLIRContext `print-op-on-diagnostic` configuration while in "
811 "a multi-threaded execution context");
812 impl->printOpOnDiagnostic = enable;
818 return impl->printStackTraceOnDiagnostic;
824 assert(
impl->multiThreadedExecutionContext == 0 &&
825 "changing MLIRContext `print-stacktrace-on-diagnostic` configuration "
826 "while in a multi-threaded execution context");
827 impl->printStackTraceOnDiagnostic = enable;
832 return impl->sortedRegisteredOperations;
839 llvm::lower_bound(
impl->sortedRegisteredOperations, dialectName,
841 return lhs.getDialect().getNamespace() < rhs;
844 if (lowerBound ==
impl->sortedRegisteredOperations.end() ||
845 lowerBound->getDialect().getNamespace() != dialectName)
848 auto *upperBound = std::upper_bound(
849 lowerBound,
impl->sortedRegisteredOperations.end(), dialectName,
851 return lhs < rhs.getDialect().getNamespace();
854 size_t count = std::distance(lowerBound, upperBound);
855 return ArrayRef(&*lowerBound, count);
863 auto &
impl = context->getImpl();
864 assert(
impl.multiThreadedExecutionContext == 0 &&
865 "Registering a new type kind while in a multi-threaded execution "
870 if (!
impl.registeredTypes.insert({typeID, newInfo}).second)
871 llvm::report_fatal_error(
"Dialect Type already registered.");
872 if (!
impl.nameToType.insert({newInfo->getName(), newInfo}).second)
873 llvm::report_fatal_error(
"Dialect Type with name " + newInfo->getName() +
874 " is already registered.");
878 auto &
impl = context->getImpl();
879 assert(
impl.multiThreadedExecutionContext == 0 &&
880 "Registering a new attribute kind while in a multi-threaded execution "
885 if (!
impl.registeredAttributes.insert({typeID, newInfo}).second)
886 llvm::report_fatal_error(
"Dialect Attribute already registered.");
887 if (!
impl.nameToAttribute.insert({newInfo->getName(), newInfo}).second)
888 llvm::report_fatal_error(
"Dialect Attribute with name " +
889 newInfo->getName() +
" is already registered.");
899 const AbstractAttribute *abstract = lookupMutable(typeID, context);
901 llvm::report_fatal_error(
"Trying to create an Attribute that was not "
902 "registered in this MLIRContext.");
909 return impl.registeredAttributes.lookup(typeID);
912std::optional<std::reference_wrapper<const AbstractAttribute>>
915 const AbstractAttribute *type =
impl.nameToAttribute.lookup(name);
932 MLIRContextImpl &ctxImpl = context->
getImpl();
939 impl = registeredIt->second.get();
949 impl = it->second.get();
959 auto nameAttr = StringAttr::get(context, name);
960 it.first->second = std::make_unique<UnregisteredOpModel>(
964 impl = it.first->second.get();
969 return dialect->getNamespace();
984 llvm::report_fatal_error(
"getParseAssemblyFn hook called on unregistered op");
1001std::optional<Attribute>
1006 return std::nullopt;
1009 return std::nullopt;
1063 return llvm::hash_combine(*prop.
as<
Attribute *>());
1070std::optional<RegisteredOperationName>
1073 auto it =
impl.registeredOperations.find(typeID);
1074 if (it !=
impl.registeredOperations.end())
1076 return std::nullopt;
1079std::optional<RegisteredOperationName>
1082 auto it =
impl.registeredOperationsByName.find(name);
1083 if (it !=
impl.registeredOperationsByName.end())
1084 return RegisteredOperationName(it->second.get());
1085 return std::nullopt;
1089 std::unique_ptr<RegisteredOperationName::Impl> ownedImpl,
1093 auto &ctxImpl = ctx->
getImpl();
1094 assert(ctxImpl.multiThreadedExecutionContext == 0 &&
1095 "registering a new operation kind while in a multi-threaded execution "
1100 if (!attrNames.empty()) {
1102 ctxImpl.abstractDialectSymbolAllocator.Allocate<StringAttr>(
1105 for (
unsigned i : llvm::seq<unsigned>(0, attrNames.size()))
1106 new (&cachedAttrNames[i]) StringAttr(StringAttr::get(ctx, attrNames[i]));
1107 impl->attributeNames = cachedAttrNames;
1109 StringRef name =
impl->getName().strref();
1112 auto emplaced = ctxImpl.registeredOperations.try_emplace(
1114 assert(emplaced.second &&
"operation name registration must be successful");
1115 auto emplacedByName = ctxImpl.registeredOperationsByName.try_emplace(
1116 name, std::move(ownedImpl));
1117 (
void)emplacedByName;
1118 assert(emplacedByName.second &&
1119 "operation name registration must be successful");
1123 ctxImpl.sortedRegisteredOperations.
insert(
1124 llvm::upper_bound(ctxImpl.sortedRegisteredOperations, value,
1125 [](
auto &lhs,
auto &rhs) {
1126 return lhs.getIdentifier().strref() <
1127 rhs.getIdentifier().strref();
1132void *RegisteredOperationName::allocateModelStorage() {
1133 return ::operator
new(
sizeof(
Impl));
1141 const AbstractType *type = lookupMutable(typeID, context);
1143 llvm::report_fatal_error(
1144 "Trying to create a Type that was not registered in this MLIRContext.");
1150 return impl.registeredTypes.lookup(typeID);
1153std::optional<std::reference_wrapper<const AbstractType>>
1156 const AbstractType *type =
impl.nameToType.lookup(name);
1159 return std::nullopt;
1171BFloat16Type BFloat16Type::get(
MLIRContext *context) {
1174Float16Type Float16Type::get(
MLIRContext *context) {
1177FloatTF32Type FloatTF32Type::get(MLIRContext *context) {
1180Float32Type Float32Type::get(MLIRContext *context) {
1183Float64Type Float64Type::get(MLIRContext *context) {
1186Float80Type Float80Type::get(MLIRContext *context) {
1189Float128Type Float128Type::get(MLIRContext *context) {
1194IndexType IndexType::get(MLIRContext *context) {
1202 IntegerType::SignednessSemantics signedness,
1204 if (signedness != IntegerType::Signless)
1205 return IntegerType();
1221 return IntegerType();
1225IntegerType IntegerType::get(MLIRContext *context,
unsigned width,
1226 IntegerType::SignednessSemantics signedness) {
1229 return Base::get(context, width, signedness);
1234 MLIRContext *context,
unsigned width,
1235 SignednessSemantics signedness) {
1238 return Base::getChecked(
emitError, context, width, signedness);
1242NoneType NoneType::get(MLIRContext *context) {
1247 return Base::get(context);
1257 return getImpl().attributeUniquer;
1261void AttributeUniquer::initializeAttributeStorage(
AttributeStorage *storage,
1279DistinctAttrStorage *
1280detail::DistinctAttributeUniquer::allocateStorage(MLIRContext *context,
1281 Attribute referencedAttr) {
1286DictionaryAttr DictionaryAttr::getEmpty(MLIRContext *context) {
1293 auto dialectNamePair =
value.split(
'.');
1294 if (dialectNamePair.first.empty() || dialectNamePair.second.empty())
1304 llvm::sys::SmartScopedLock<true> lock(
impl.dialectRefStrAttrMutex);
1305 impl.dialectReferencingStrAttrs[dialectNamePair.first].push_back(
this);
1318 return getImpl().affineUniquer;
1321AffineMap AffineMap::getImpl(
unsigned dimCount,
unsigned symbolCount,
1327 symbolCount, results);
1336[[maybe_unused]]
static bool
1340 int64_t maxSymbolPosition = -1;
1343 if ((maxDimPosition >= dimCount) || (maxSymbolPosition >= symbolCount)) {
1345 <<
"maximum dimensional identifier position in result expression must "
1346 "be less than `dimCount` and maximum symbolic identifier position "
1347 "in result expression must be less than `symbolCount`";
1354 return getImpl(0, 0, {}, context);
1359 return getImpl(dimCount, symbolCount, {}, context);
1371 return getImpl(dimCount, symbolCount, results, context);
1383 assert(!constraints.empty());
1384 assert(constraints.size() == eqFlags.size());
1386 auto &
impl = constraints[0].getContext()->getImpl();
1401 return [ctx] {
return emitError(UnknownLoc::get(ctx)); };
static llvm::ManagedStatic< DebugCounterOptions > clOptions
static size_t hash(const T &value)
Local helper to compute std::hash for a value.
static bool willBeValidAffineMap(unsigned dimCount, unsigned symbolCount, ArrayRef< AffineExpr > results)
Check whether the arguments passed to the AffineMap::get() are consistent.
static bool isThreadingGloballyDisabled()
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.
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: () -> ().
constexpr AffineMap()=default
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...
void addType(TypeID typeID, AbstractType &&typeInfo)
Register a type instance with this dialect.
void addAttribute(TypeID typeID, AbstractAttribute &&attrInfo)
Register an attribute instance with this dialect.
A dialect that can be defined at runtime.
This class represents a diagnostic that is inflight and set to be reported.
constexpr IntegerSet()=default
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.
llvm::ThreadPoolInterface * threadPool
This points to the ThreadPool used when processing MLIR tasks in parallel.
DictionaryAttr emptyDictionaryAttr
bool printStackTraceOnDiagnostic
If the current stack trace should be attached when emitting diagnostics.
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.
BFloat16Type bf16Ty
Cached Type Instances.
DenseMap< StringRef, SmallVector< StringAttrStorage * > > dialectReferencingStrAttrs
std::unique_ptr< TransientScopeState > transientState
std::atomic< int > multiThreadedExecutionContext
Track if we are currently executing in a threaded execution environment (like the pass-manager): this...
StringAttr emptyStringAttr
llvm::StringMap< std::unique_ptr< OperationName::Impl >, llvm::BumpPtrAllocator > registeredOperationsByName
std::function< void(function_ref< void()>, const tracing::Action &)> actionHandler
An action handler for handling actions that are dispatched through this context.
bool allowUnregisteredDialects
In most cases, creating operation in unregistered dialect is not desired and indicate a misconfigurat...
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
bool printOpOnDiagnostic
If the operation should be attached to diagnostics printed via the Operation::emit methods.
llvm::BumpPtrAllocator abstractDialectSymbolAllocator
An allocator used for AbstractAttribute and AbstractType objects.
DenseMap< TypeID, AbstractType * > registeredTypes
StorageUniquer affineUniquer
DiagnosticEngine diagEngine
std::unique_ptr< remark::detail::RemarkEngine > remarkEngine
UnknownLoc unknownLocAttr
DenseMap< TypeID, AbstractAttribute * > registeredAttributes
std::unique_ptr< llvm::ThreadPoolInterface > ownedThreadPool
In case where the thread pool is owned by the context, this ensures destruction with the context.
SmallVector< RegisteredOperationName, 0 > sortedRegisteredOperations
This is a sorted container of registered operations for a deterministic and efficient getRegisteredOp...
llvm::StringMap< std::unique_ptr< OperationName::Impl > > unregisteredOperationsByName
This is a mapping from unregistered operation name to the operation info describing it.
DistinctAttributeAllocator distinctAttributeAllocator
A distinct attribute allocator that allocates every time since the address of the distinct attribute ...
MLIRContextImpl(bool threadingIsEnabled)
StorageUniquer attributeUniquer
DialectRegistry dialectsRegistry
bool threadSafeLockingIsEnabled
Enable locking for context access independently of parallel execution.
bool threadingIsEnabled
Enable support for multi-threading within MLIR.
void setThreadSafeLocking(bool enable)
Update the locking mode for context access and each of the uniquers.
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 isInTransientScope() const
Returns true if the context is currently in a transient scope.
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.
T * getOrLoadDialect()
Get (or create) a dialect for the given derived dialect type.
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 setRemarkEngine(std::unique_ptr< remark::detail::RemarkEngine > engine)
Set the remark engine for this context.
void setThreadPool(llvm::ThreadPoolInterface &pool)
Set a new thread pool to be used in this context.
const HandlerTy & getActionHandler() const
Return a reference to the currently registered action handler.
void enableMultithreading(bool enable=true)
remark::detail::RemarkEngine * getRemarkEngine()
Returns the remark engine for this context, or nullptr if none has been set.
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.
void enableThreadSafeLocking()
Enable thread-safe locking for context access, including uniquing types, attributes,...
StorageUniquer & getAttributeUniquer()
Returns the storage uniquer used for constructing attribute storage instances.
StorageUniquer & getAffineUniquer()
Returns the storage uniquer used for creating affine constructs.
void endTransientScope()
Ends the transient scope and resets the context to the base state, pruning all types,...
std::function< void(function_ref< void()>, const tracing::Action &)> HandlerTy
Signatures for the action handler that can be registered with the context.
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 isThreadSafeLockingEnabled()
Return true if thread-safe locking is enabled for context access.
void allowUnregisteredDialects(bool allow=true)
Enables creating operations in unregistered dialects.
bool allowsUnregisteredDialects()
Return true if we allow to create operation for unregistered dialects.
DiagnosticEngine & getDiagEngine()
Returns the diagnostic engine for this context.
MLIRContextImpl & getImpl()
void exitMultiThreadedExecution()
bool isMultithreadingEnabled()
Return true if multi-threading is enabled by the context.
bool shouldPrintOpOnDiagnostic()
Return true if we should attach the operation to diagnostics emitted via Operation::emit.
void beginTransientScope()
Begins a transient scope on the context, freezing the current state (all loaded dialects,...
void loadAllAvailableDialects()
Load all dialects available in the registry in this context.
T * getLoadedDialect()
Get a registered IR dialect for the given derived dialect type.
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.
StringAttr name
The name of the operation.
TypeID typeID
The unique identifier of the derived Op class.
Impl(StringRef, Dialect *dialect, TypeID typeID, detail::InterfaceMap interfaceMap)
Dialect * dialect
The following fields are only populated when the operation is registered.
detail::InterfaceMap interfaceMap
A map of interfaces that were registered to this operation.
StringRef getStringRef() const
Return the name of this operation. This always succeeds.
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.
llvm::unique_function< ParseResult(OpAsmParser &, OperationState &)> ParseAssemblyFn
llvm::function_ref< void(StringRef, Attribute &)> InherentAttrVisitor
MLIRContext * getContext()
Return the context this operation is associated with.
Operation is the basic unit of execution within MLIR.
PropertyRef getPropertiesStorage()
Return a generic (but typed) reference to the property type storage.
MLIRContext * getContext()
Return the context this operation is associated with.
Type-safe wrapper around a void* for passing properties, including the properties structs of operatio...
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".
void beginTransientScope()
Begins a transient scope.
void endTransientScope()
Ends the transient scope and resets back to the base state, freeing all transiently allocated storage...
This class provides an efficient unique identifier for a specific C++ type.
static TypeID get()
Construct a type info object for the given type T.
static T get(MLIRContext *ctx, Args &&...args)
Get an uniqued instance of an attribute T.
An allocator for distinct attribute storage instances.
void beginTransientScope()
DistinctAttrStorage * allocate(Attribute referencedAttr)
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.
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 ...
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 ...
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
llvm::DenseMap< KeyT, ValueT, KeyInfoT, BucketT > DenseMap
function_ref< Dialect *(MLIRContext *)> DialectAllocatorFunctionRef
llvm::function_ref< Fn > function_ref
Bundled state dynamically allocated when in a transient scope.
llvm::DenseMap< StringRef, size_t > baseDialectReferencingStrAttrCounts
Number of entries in dialectReferencingStrAttrs per dialect at snapshot time.
llvm::DenseSet< StringRef > baseOperations
Set of operation names in unregisteredOperationsByName at snapshot time.
LogicalResult foldHook(Operation *, ArrayRef< Attribute >, SmallVectorImpl< OpFoldResult > &) final
int getOpPropertyByteSize() final
void setInherentAttr(Operation *op, StringAttr name, Attribute value) final
llvm::hash_code hashProperties(PropertyRef) final
void initProperties(OperationName opName, PropertyRef storage, PropertyRef init) final
OperationName::ParseAssemblyFn getParseAssemblyFn() final
void deleteProperties(PropertyRef) final
bool hasTrait(TypeID) final
LogicalResult verifyRegionInvariants(Operation *) final
std::optional< Attribute > getInherentAttr(Operation *op, StringRef name) final
Implementation for properties.
void walkInherentAttrs(Operation *op, InherentAttrVisitor visitor) final
void getCanonicalizationPatterns(RewritePatternSet &, MLIRContext *) final
LogicalResult setPropertiesFromAttr(OperationName, PropertyRef, Attribute, function_ref< InFlightDiagnostic()> emitError) final
void populateDefaultAttrs(const OperationName &, NamedAttrList &) final
void printAssembly(Operation *, OpAsmPrinter &, StringRef) final
LogicalResult verifyInvariants(Operation *) final
void populateDefaultProperties(OperationName opName, PropertyRef properties) final
LogicalResult verifyInherentAttrs(OperationName opName, NamedAttrList &attributes, function_ref< InFlightDiagnostic()> emitError) final
Attribute getPropertiesAsAttr(Operation *) final
bool compareProperties(PropertyRef, PropertyRef) final
void copyProperties(PropertyRef, PropertyRef) 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.
StringRef value
The raw string value.
Dialect * referencedDialect
If the string value contains a dialect namespace prefix (e.g.
void initialize(MLIRContext *context)
Initialize the storage given an MLIRContext.
static T get(MLIRContext *ctx, Args &&...args)
Get an uniqued instance of a type T.