Mehdi Amini d905c10353 Add a mechanism for Dialects to provide a fallback for OpInterface
This mechanism makes it possible for a dialect to not register all
operations but still answer interface-based queries.
This can useful for dialects that are "open" or connected to an external
system and still interoperate with the compiler. It can also open up the
possibility to have a more extensible compiler at runtime: the compiler
does not need a pre-registration for each operation and the dialect can
inject behavior dynamically.

Reviewed By: rriddle, jpienaar

Differential Revision: https://reviews.llvm.org/D93085
2021-03-24 08:41:40 +00:00

91 lines
2.7 KiB
C++

//===- Dialect.cpp - Dialect wrapper class --------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Dialect wrapper to simplify using TableGen Record defining a MLIR dialect.
//
//===----------------------------------------------------------------------===//
#include "mlir/TableGen/Dialect.h"
#include "llvm/TableGen/Record.h"
using namespace mlir;
using namespace mlir::tblgen;
Dialect::Dialect(const llvm::Record *def) : def(def) {
if (def == nullptr)
return;
for (StringRef dialect : def->getValueAsListOfStrings("dependentDialects"))
dependentDialects.push_back(dialect);
}
StringRef Dialect::getName() const { return def->getValueAsString("name"); }
StringRef Dialect::getCppNamespace() const {
return def->getValueAsString("cppNamespace");
}
std::string Dialect::getCppClassName() const {
// Simply use the name and remove any '_' tokens.
std::string cppName = def->getName().str();
llvm::erase_if(cppName, [](char c) { return c == '_'; });
return cppName;
}
static StringRef getAsStringOrEmpty(const llvm::Record &record,
StringRef fieldName) {
if (auto valueInit = record.getValueInit(fieldName)) {
if (llvm::isa<llvm::StringInit>(valueInit))
return record.getValueAsString(fieldName);
}
return "";
}
StringRef Dialect::getSummary() const {
return getAsStringOrEmpty(*def, "summary");
}
StringRef Dialect::getDescription() const {
return getAsStringOrEmpty(*def, "description");
}
ArrayRef<StringRef> Dialect::getDependentDialects() const {
return dependentDialects;
}
llvm::Optional<StringRef> Dialect::getExtraClassDeclaration() const {
auto value = def->getValueAsString("extraClassDeclaration");
return value.empty() ? llvm::Optional<StringRef>() : value;
}
bool Dialect::hasConstantMaterializer() const {
return def->getValueAsBit("hasConstantMaterializer");
}
bool Dialect::hasOperationAttrVerify() const {
return def->getValueAsBit("hasOperationAttrVerify");
}
bool Dialect::hasRegionArgAttrVerify() const {
return def->getValueAsBit("hasRegionArgAttrVerify");
}
bool Dialect::hasRegionResultAttrVerify() const {
return def->getValueAsBit("hasRegionResultAttrVerify");
}
bool Dialect::hasOperationInterfaceFallback() const {
return def->getValueAsBit("hasOperationInterfaceFallback");
}
bool Dialect::operator==(const Dialect &other) const {
return def == other.def;
}
bool Dialect::operator<(const Dialect &other) const {
return getName() < other.getName();
}