diff --git a/mlir/lib/TableGen/Interfaces.cpp b/mlir/lib/TableGen/Interfaces.cpp --- a/mlir/lib/TableGen/Interfaces.cpp +++ b/mlir/lib/TableGen/Interfaces.cpp @@ -9,6 +9,7 @@ #include "mlir/TableGen/Interfaces.h" #include "llvm/ADT/FunctionExtras.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringSet.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/TableGen/Error.h" #include "llvm/TableGen/Record.h" @@ -83,6 +84,8 @@ // Initialize the interface base classes. auto *basesInit = dyn_cast(def->getValueInit("baseInterfaces")); + // Chained inheritance will produce duplicates in the base interface set. + StringSet<> basesAdded; llvm::unique_function addBaseInterfaceFn = [&](const Interface &baseInterface) { // Inherit any base interfaces. @@ -90,7 +93,10 @@ addBaseInterfaceFn(baseBaseInterface); // Add the base interface. + if (basesAdded.contains(baseInterface.getName())) + return; baseInterfaces.push_back(std::make_unique(baseInterface)); + basesAdded.insert(baseInterface.getName()); }; for (llvm::Init *init : basesInit->getValues()) addBaseInterfaceFn(Interface(cast(init)->getDef())); diff --git a/mlir/test/mlir-tblgen/op-interface.td b/mlir/test/mlir-tblgen/op-interface.td --- a/mlir/test/mlir-tblgen/op-interface.td +++ b/mlir/test/mlir-tblgen/op-interface.td @@ -34,7 +34,18 @@ // DECL-NEXT: return (*static_cast(this)).someOtherMethod(); // DECL-NEXT: } -def TestInheritanceBaseInterface : OpInterface<"TestInheritanceBaseInterface"> { +def TestInheritanceMultiBaseInterface : OpInterface<"TestInheritanceMultiBaseInterface"> { + let methods = [ + InterfaceMethod< + /*desc=*/[{some function comment}], + /*retTy=*/"int", + /*methodName=*/"baz", + /*args=*/(ins "int":$input) + > + ]; +} + +def TestInheritanceBaseInterface : OpInterface<"TestInheritanceBaseInterface", [TestInheritanceMultiBaseInterface]> { let methods = [ InterfaceMethod< /*desc=*/[{some function comment}], @@ -60,6 +71,8 @@ // DECL: class TestInheritanceZDerivedInterface // DECL: struct Concept { +// DECL: const TestInheritanceMultiBaseInterface::Concept *implTestInheritanceMultiBaseInterface = nullptr; +// DECL-NOT: const TestInheritanceMultiBaseInterface::Concept // DECL: const TestInheritanceBaseInterface::Concept *implTestInheritanceBaseInterface = nullptr; // DECL: const TestInheritanceMiddleBaseInterface::Concept *implTestInheritanceMiddleBaseInterface = nullptr;