diff --git a/mlir/include/mlir/IR/Dialect.h b/mlir/include/mlir/IR/Dialect.h index db5ba53ad535..2bb672596212 100644 --- a/mlir/include/mlir/IR/Dialect.h +++ b/mlir/include/mlir/IR/Dialect.h @@ -127,11 +127,10 @@ public: static bool isValidNamespace(StringRef str); protected: - /// Note: The namePrefix can be empty, but it must not contain '.' characters. - /// Note: If the name is non empty, then all operations belonging to this - /// dialect will need to start with the namePrefix followed by a '.'. + /// Note: The namePrefix must not contain '.' characters. + /// Note: All operations belonging to this dialect will need to have names + /// starting with the namePrefix followed by '.'. /// Example: - /// - "" for the standard operation set. /// - "tf" for the TensorFlow ops like "tf.add". Dialect(StringRef namePrefix, MLIRContext *context); diff --git a/mlir/lib/IR/MLIRContext.cpp b/mlir/lib/IR/MLIRContext.cpp index aee0ac96917e..9db18f9fd5e2 100644 --- a/mlir/lib/IR/MLIRContext.cpp +++ b/mlir/lib/IR/MLIRContext.cpp @@ -704,6 +704,11 @@ void Dialect::registerDialect(MLIRContext *context) { // Lock access to the context registry. llvm::sys::SmartScopedWriter registryLock(impl.contextMutex); + assert(llvm::none_of(impl.dialects, + [this](std::unique_ptr &dialect) { + return dialect->getNamespace() == getNamespace(); + }) && + "a dialect with the given namespace has already been registered"); impl.dialects.push_back(std::unique_ptr(this)); } @@ -737,7 +742,7 @@ std::vector MLIRContext::getRegisteredOperations() { } void Dialect::addOperation(AbstractOperation opInfo) { - assert((namePrefix.empty() || (opInfo.name.split('.').first == namePrefix)) && + assert(opInfo.name.split('.').first == namePrefix && "op name doesn't start with dialect prefix"); assert(&opInfo.dialect == this && "Dialect object mismatch"); auto &impl = context->getImpl(); diff --git a/mlir/unittests/IR/DialectTest.cpp b/mlir/unittests/IR/DialectTest.cpp new file mode 100644 index 000000000000..89b641df15e5 --- /dev/null +++ b/mlir/unittests/IR/DialectTest.cpp @@ -0,0 +1,38 @@ +//===- DialectTest.cpp - Dialect unit tests -------------------------------===// +// +// Copyright 2019 The MLIR Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ============================================================================= + +#include "mlir/IR/Dialect.h" +#include "gtest/gtest.h" + +using namespace mlir; +using namespace mlir::detail; + +namespace { +struct TestDialect : public Dialect { + TestDialect(MLIRContext *context) : Dialect(/*namePrefix=*/"test", context) {} +}; + +TEST(DialectDeathTest, MultipleDialectsWithSameNamespace) { + MLIRContext context; + + // Registering a dialect with the same namespace twice should result in a + // failure. + new TestDialect(&context); + ASSERT_DEATH(new TestDialect(&context), ""); +} + +} // end namespace