diff options
Diffstat (limited to 'mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp')
-rw-r--r-- | mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp | 47 |
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"; } |