[Mlir-commits] [mlir] [mlir] Skip symbol-user type verify when no type has the interface (PR #212160)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Sun Jul 26 17:51:33 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir
Author: Eric Hein (ehein6)
<details>
<summary>Changes</summary>
#<!-- -->198435 extended symbol table verification to walk, for every operation in a symbol table's scope, all operand, result and block-argument types plus the operation's entire attribute dictionary, looking for types that implement SymbolUserTypeInterface. The verifier runs after every pass, so that walk is repeated over the whole scope on every verification.
When no registered type implements the interface the walk cannot find anything, so the cost is pure overhead. It is not small: it doubled the compile time of a downstream MLIR pass pipeline, 14.1s -> 26.1s (1.85x) on a small graph, with the cost spread as a roughly fixed per-pass increment. The deduplication sets added by #<!-- -->198435 do not help here, as they are rebuilt on each verification.
Add MLIRContext::hasTypeImplementingInterface and query it once per symbol table, skipping the walk when no registered type participates. A type instance cannot exist unless its dialect is loaded and its type registered, so a negative answer guarantees that no type reachable in the scope implements the interface and verification results are unchanged.
---
Full diff: https://github.com/llvm/llvm-project/pull/212160.diff
3 Files Affected:
- (modified) mlir/include/mlir/IR/MLIRContext.h (+10)
- (modified) mlir/lib/IR/MLIRContext.cpp (+6)
- (modified) mlir/lib/IR/SymbolTable.cpp (+4-1)
``````````diff
diff --git a/mlir/include/mlir/IR/MLIRContext.h b/mlir/include/mlir/IR/MLIRContext.h
index 12cd00b60215e..1f4050362ef39 100644
--- a/mlir/include/mlir/IR/MLIRContext.h
+++ b/mlir/include/mlir/IR/MLIRContext.h
@@ -208,6 +208,16 @@ class MLIRContext {
/// Return true if this operation name is registered in this context.
bool isOperationRegistered(StringRef name);
+ /// Return true if any type registered with this context implements
+ /// `interfaceID`; false guarantees no type in this context's IR does.
+ bool hasTypeImplementingInterface(TypeID interfaceID);
+
+ /// Return true if any type registered with this context implements
+ /// `InterfaceT`.
+ template <typename InterfaceT> bool hasTypeImplementingInterface() {
+ return hasTypeImplementingInterface(InterfaceT::getInterfaceID());
+ }
+
// This is effectively private given that only MLIRContext.cpp can see the
// MLIRContextImpl type.
MLIRContextImpl &getImpl() { return *impl; }
diff --git a/mlir/lib/IR/MLIRContext.cpp b/mlir/lib/IR/MLIRContext.cpp
index da891a7e6e014..58df5210e12e4 100644
--- a/mlir/lib/IR/MLIRContext.cpp
+++ b/mlir/lib/IR/MLIRContext.cpp
@@ -714,6 +714,12 @@ ArrayRef<RegisteredOperationName> MLIRContext::getRegisteredOperations() {
return impl->sortedRegisteredOperations;
}
+bool MLIRContext::hasTypeImplementingInterface(TypeID interfaceID) {
+ return llvm::any_of(impl->registeredTypes, [&](const auto ®istered) {
+ return registered.second->hasInterface(interfaceID);
+ });
+}
+
/// Return information for registered operations by dialect.
ArrayRef<RegisteredOperationName>
MLIRContext::getRegisteredOperationsByDialect(StringRef dialectName) {
diff --git a/mlir/lib/IR/SymbolTable.cpp b/mlir/lib/IR/SymbolTable.cpp
index 100eba7146d81..c07ca879538af 100644
--- a/mlir/lib/IR/SymbolTable.cpp
+++ b/mlir/lib/IR/SymbolTable.cpp
@@ -558,6 +558,8 @@ LogicalResult detail::verifySymbolTable(Operation *op) {
// most once across the whole scope.
SetVector<Attribute> verifiedAttrs;
SetVector<Type> verifiedTypes;
+ const bool anyTypeImplementsSymbolUserTypeInterface =
+ op->getContext()->hasTypeImplementingInterface<SymbolUserTypeInterface>();
auto verifySymbolUserFn = [&](Operation *op) -> std::optional<WalkResult> {
if (SymbolUserOpInterface user = dyn_cast<SymbolUserOpInterface>(op))
if (failed(user.verifySymbolUses(symbolTable)))
@@ -570,7 +572,8 @@ LogicalResult detail::verifySymbolTable(Operation *op) {
return WalkResult::interrupt();
}
}
- if (failed(verifyOpTypeSymbolUses(op, symbolTable, verifiedTypes)))
+ if (anyTypeImplementsSymbolUserTypeInterface &&
+ failed(verifyOpTypeSymbolUses(op, symbolTable, verifiedTypes)))
return WalkResult::interrupt();
return WalkResult::advance();
};
``````````
</details>
https://github.com/llvm/llvm-project/pull/212160
More information about the Mlir-commits
mailing list