aboutsummaryrefslogtreecommitdiff
path: root/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp')
-rw-r--r--mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp47
1 files changed, 33 insertions, 14 deletions
diff --git a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
index c3420d4..9690115 100644
--- a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
+++ b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
@@ -790,6 +790,14 @@ private:
Method *genOpInterfaceMethod(const tblgen::InterfaceMethod &method,
bool declaration = true);
+ // Generate a `using` declaration for the op interface method to include
+ // the default implementation from the interface trait.
+ // This is needed when the interface defines multiple methods with the same
+ // name, but some have a default implementation and some don't.
+ UsingDeclaration *
+ genOpInterfaceMethodUsingDecl(const tblgen::InterfaceTrait *opTrait,
+ const tblgen::InterfaceMethod &method);
+
// Generate the side effect interface methods.
void genSideEffectInterfaceMethods();
@@ -816,6 +824,10 @@ private:
// Helper for emitting op code.
OpOrAdaptorHelper emitHelper;
+
+ // Keep track of the interface using declarations that have been generated to
+ // avoid duplicates.
+ llvm::StringSet<> interfaceUsingNames;
};
} // namespace
@@ -3673,8 +3685,10 @@ void OpEmitter::genOpInterfaceMethods(const tblgen::InterfaceTrait *opTrait) {
// Don't declare if the method has a default implementation and the op
// didn't request that it always be declared.
if (method.getDefaultImplementation() &&
- !alwaysDeclaredMethods.count(method.getName()))
+ !alwaysDeclaredMethods.count(method.getName())) {
+ genOpInterfaceMethodUsingDecl(opTrait, method);
continue;
+ }
// Interface methods are allowed to overlap with existing methods, so don't
// check if pruned.
(void)genOpInterfaceMethod(method);
@@ -3693,6 +3707,17 @@ Method *OpEmitter::genOpInterfaceMethod(const InterfaceMethod &method,
std::move(paramList));
}
+UsingDeclaration *
+OpEmitter::genOpInterfaceMethodUsingDecl(const tblgen::InterfaceTrait *opTrait,
+ const InterfaceMethod &method) {
+ std::string name = (llvm::Twine(opTrait->getFullyQualifiedTraitName()) + "<" +
+ op.getCppClassName() + ">::" + method.getName())
+ .str();
+ if (interfaceUsingNames.insert(name).second)
+ return opClass.declare<UsingDeclaration>(std::move(name));
+ return nullptr;
+}
+
void OpEmitter::genOpInterfaceMethods() {
for (const auto &trait : op.getTraits()) {
if (const auto *opTrait = dyn_cast<tblgen::InterfaceTrait>(&trait))
@@ -4801,11 +4826,9 @@ void OpOperandAdaptorEmitter::emitDef(
}
/// Emit the class declarations or definitions for the given op defs.
-static void
-emitOpClasses(const RecordKeeper &records,
- const std::vector<const Record *> &defs, raw_ostream &os,
- const StaticVerifierFunctionEmitter &staticVerifierEmitter,
- bool emitDecl) {
+static void emitOpClasses(
+ const RecordKeeper &records, ArrayRef<const Record *> defs, raw_ostream &os,
+ const StaticVerifierFunctionEmitter &staticVerifierEmitter, bool emitDecl) {
if (defs.empty())
return;
@@ -4840,18 +4863,14 @@ emitOpClasses(const RecordKeeper &records,
/// Emit the declarations for the provided op classes.
static void emitOpClassDecls(const RecordKeeper &records,
- const std::vector<const Record *> &defs,
- raw_ostream &os) {
+ ArrayRef<const Record *> defs, raw_ostream &os) {
// First emit forward declaration for each class, this allows them to refer
// to each others in traits for example.
- for (auto *def : defs) {
+ for (const Record *def : defs) {
Operator op(*def);
NamespaceEmitter emitter(os, op.getCppNamespace());
- std::string comments = tblgen::emitSummaryAndDescComments(
- op.getSummary(), op.getDescription());
- if (!comments.empty()) {
- os << comments << "\n";
- }
+ tblgen::emitSummaryAndDescComments(os, op.getSummary(),
+ op.getDescription());
os << "class " << op.getCppClassName() << ";\n";
}