19#include "llvm/ADT/MapVector.h"
20#include "llvm/ADT/SmallVectorExtras.h"
21#include "llvm/ADT/Twine.h"
22#include "llvm/Support/DebugLog.h"
23#include "llvm/Support/Regex.h"
26#define DEBUG_TYPE "dialect"
36 : name(name), dialectID(id), context(context) {
64 <<
"' provides no attribute parsing hook";
77 <<
"dialect '" <<
getNamespace() <<
"' provides no type parsing hook";
81std::optional<Dialect::ParseOpHook>
89 "Dialect hook invoked on non-dialect owned operation");
96 llvm::Regex dialectNameRegex(
"^[a-zA-Z_][a-zA-Z_0-9\\$]*$");
97 return dialectNameRegex.match(str);
105 auto it = registeredInterfaces.try_emplace(interface->getID(),
106 std::move(interface));
108 LDBG() <<
"repeated interface registration for dialect " <<
getNamespace();
118 return dialect->getContext();
125 dialect->handleUseOfUndefinedPromisedInterface(
126 dialect->getTypeID(), interfaceKind, interfaceName);
128 if (
auto *interface = dialect->getRegisteredInterface(interfaceKind)) {
129 interfaces.insert(interface);
130 orderedInterfaces.push_back(interface);
152 StringRef interfaceName) {
154 interfaceID, interfaceName);
164 TypeID interfaceRequestorID,
174template <
typename Fn>
175void applyExtensionsFn(
177 const llvm::MapVector<
TypeID, std::unique_ptr<DialectExtensionBase>>
183 const auto extractExtension =
185 return entry.second.get();
188 auto startIt = extensions.begin(), endIt = extensions.end();
190 while (startIt != endIt) {
191 count += endIt - startIt;
195 llvm::map_to_vector(llvm::make_range(startIt, endIt), extractExtension);
197 for (
const auto *ext : subset)
198 applyExtension(*ext);
201 startIt = extensions.begin() + count;
202 endIt = extensions.end();
211 auto it = registry.find(name);
212 if (it == registry.end())
214 return it->second.second;
220 std::make_pair(std::string(name), std::make_pair(typeID, ctor)));
222 llvm::report_fatal_error(
223 "Trying to register different dialects for the same namespace: " +
230 for (
const std::string &name : dialectsToPreload) {
233 emitError() <<
"can't load dialect '" << name
234 <<
"': missing registration?";
244 if (registry.count(name))
246 if (llvm::is_contained(dialectsToPreload, name))
248 dialectsToPreload.emplace_back(name);
259 auto constructor = [nameStr = name.str(), ctor](
MLIRContext *ctx) {
261 nameStr, [ctx, ctor](
DynamicDialect *dialect) { ctor(ctx, dialect); });
262 assert(dynDialect &&
"Dynamic dialect creation unexpectedly failed");
266 insert(typeID, name, constructor);
277 if (dialectNames.empty()) {
278 extension.apply(ctx, dialect);
284 if (dialectNames.size() == 1) {
285 if (dialectNames.front() == dialectName)
286 extension.apply(ctx, dialect);
291 const StringRef *nameIt = llvm::find(dialectNames, dialectName);
292 if (nameIt == dialectNames.end())
298 requiredDialects.reserve(dialectNames.size());
299 for (
auto it = dialectNames.begin(), e = dialectNames.end(); it != e;
303 requiredDialects.push_back(dialect);
310 requiredDialects.push_back(loadedDialect);
312 extension.apply(ctx, requiredDialects);
315 applyExtensionsFn(applyExtension, extensions);
322 if (dialectNames.empty()) {
324 extension.apply(ctx, loadedDialects);
330 requiredDialects.reserve(dialectNames.size());
331 for (StringRef dialectName : dialectNames) {
335 requiredDialects.push_back(loadedDialect);
337 extension.apply(ctx, requiredDialects);
340 applyExtensionsFn(applyExtension, extensions);
345 const auto hasExtension = [&](
const auto &key) {
346 return rhs.extensions.contains(key);
348 if (!llvm::all_of(make_first_range(extensions), hasExtension))
352 if (!llvm::all_of(registry, [&](
const auto &it) {
353 return rhs.registry.count(it.first);
358 return llvm::all_of(dialectsToPreload, [&](
const std::string &name) {
359 return rhs.registry.count(name) ||
360 llvm::is_contained(
rhs.dialectsToPreload, name);
*if copies could not be generated due to yet unimplemented cases *copyInPlacementStart and copyOutPlacementStart in copyPlacementBlock *specify the insertion points where the incoming copies and outgoing should be inserted(the insertion happens right before the *insertion point). Since `begin` can itself be invalidated due to the memref *rewriting done from this method
virtual InFlightDiagnostic emitError(SMLoc loc, const Twine &message={})=0
Emit a diagnostic at the specified location and return failure.
virtual SMLoc getNameLoc() const =0
Return the location of the original name token.
Attributes are known-constant values of operations.
The DialectAsmParser has methods for interacting with the asm parser when parsing attributes and type...
virtual StringRef getFullSymbolSpec() const =0
Returns the full specification of the symbol being parsed.
This class represents an opaque dialect extension.
virtual ~DialectExtensionBase()
This class represents an interface overridden for a single dialect.
virtual ~DialectInterface()
MLIRContext * getContext() const
Return the context that holds the parent dialect of this interface.
bool isSubsetOf(const DialectRegistry &rhs) const
Returns true if the current registry is a subset of 'rhs', i.e.
DialectAllocatorFunctionRef getDialectAllocator(StringRef name) const
Return an allocation function for constructing the dialect identified by its namespace,...
void insertDynamic(StringRef name, const DynamicDialectPopulationFunction &ctor)
Add a new dynamic dialect constructor in the registry.
LogicalResult preloadSelectDialects(MLIRContext *ctx, function_ref< InFlightDiagnostic()> emitError={}) const
Load into ctx every dialect previously added via addDialectToPreload(StringRef).
void addDialectToPreload(StringRef name)
Request that the dialect with the given name be preloaded into the MLIRContext, without providing an ...
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...
MLIRContext * getContext() const
virtual Type parseType(DialectAsmParser &parser) const
Parse a type registered to this dialect.
virtual std::optional< ParseOpHook > getParseOperationHook(StringRef opName) const
Return the hook to parse an operation registered to this dialect, if any.
void handleUseOfUndefinedPromisedInterface(TypeID interfaceRequestorID, TypeID interfaceID, StringRef interfaceName="")
Checks if the given interface, which is attempting to be used, is a promised interface of this dialec...
StringRef getNamespace() const
static bool isValidNamespace(StringRef str)
Utility function that returns if the given string is a valid dialect namespace.
virtual LogicalResult verifyRegionResultAttribute(Operation *, unsigned regionIndex, unsigned resultIndex, NamedAttribute)
Verify an attribute from this dialect on the result at 'resultIndex' for the region at 'regionIndex' ...
virtual LogicalResult verifyRegionArgAttribute(Operation *, unsigned regionIndex, unsigned argIndex, NamedAttribute)
Verify an attribute from this dialect on the argument at 'argIndex' for the region at 'regionIndex' o...
virtual llvm::unique_function< void(Operation *, OpAsmPrinter &printer)> getOperationPrinter(Operation *op) const
Print an operation registered to this dialect.
void handleAdditionOfUndefinedPromisedInterface(TypeID interfaceRequestorID, TypeID interfaceID)
Checks if the given interface, which is attempting to be attached to a construct owned by this dialec...
bool allowsUnknownTypes() const
Return true if this dialect allows for unregistered types, i.e., types prefixed with the dialect name...
virtual Attribute parseAttribute(DialectAsmParser &parser, Type type) const
Parse an attribute registered to this dialect.
void addInterface(std::unique_ptr< DialectInterface > interface)
Register a dialect interface with this dialect instance.
TypeID getTypeID() const
Returns the unique identifier that corresponds to this dialect.
bool hasPromisedInterface(TypeID interfaceRequestorID, TypeID interfaceID) const
Checks if a promise has been made for the interface/requestor pair.
Dialect(StringRef name, MLIRContext *context, TypeID id)
The constructor takes a unique namespace for this dialect as well as the context to bind to.
A dialect that can be defined at runtime.
This class represents a diagnostic that is inflight and set to be reported.
MLIRContext is the top-level object for a collection of MLIR operations.
T * getOrLoadDialect()
Get (or create) a dialect for the given derived dialect type.
Dialect * getLoadedDialect(StringRef name)
Get a registered IR dialect with the given namespace.
std::vector< Dialect * > getLoadedDialects()
Return information about all IR dialects loaded in the context.
DynamicDialect * getOrLoadDynamicDialect(StringRef dialectNamespace, function_ref< void(DynamicDialect *)> ctor)
Get (or create) a dynamic dialect for the given name.
NamedAttribute represents a combination of a name and an Attribute value.
This is a pure-virtual base class that exposes the asmprinter hooks necessary to implement a custom p...
Operation is the basic unit of execution within MLIR.
Dialect * getDialect()
Return the dialect this operation is associated with, or nullptr if the associated dialect is not loa...
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.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
const DialectInterface * getInterfaceFor(Operation *op) const
Get the interface for the dialect of given operation, or null if one is not registered.
virtual ~DialectInterfaceCollectionBase()
DialectInterfaceCollectionBase(MLIRContext *ctx, TypeID interfaceKind, StringRef interfaceName)
bool hasPromisedInterface(Dialect &dialect, TypeID interfaceRequestorID, TypeID interfaceID)
Checks if a promise has been made for the interface/requestor pair.
void handleAdditionOfUndefinedPromisedInterface(Dialect &dialect, TypeID interfaceRequestorID, TypeID interfaceID)
Checks if the given interface, which is attempting to be attached, is a promised interface of this di...
void handleUseOfUndefinedPromisedInterface(Dialect &dialect, TypeID interfaceRequestorID, TypeID interfaceID, StringRef interfaceName)
Checks if the given interface, which is attempting to be used, is a promised interface of this dialec...
Include the generated interface declarations.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
std::function< Dialect *(MLIRContext *)> DialectAllocatorFunction
function_ref< Dialect *(MLIRContext *)> DialectAllocatorFunctionRef
std::function< void(MLIRContext *, DynamicDialect *)> DynamicDialectPopulationFunction
llvm::function_ref< Fn > function_ref