[Mlir-commits] [mlir] [mlir] Make symbol-user type verification proportional to participating IR (PR #212354)
Mehdi Amini
llvmlistbot at llvm.org
Tue Aug 18 01:59:13 PDT 2026
================
@@ -476,49 +476,57 @@ raw_ostream &mlir::operator<<(raw_ostream &os,
// SymbolTable Trait Types
//===----------------------------------------------------------------------===//
-/// Verify the symbol uses held by the types owned by `op`: its operand,
-/// result, and block-argument types, and any types nested within its
-/// attributes. `op` is the anchor used for symbol lookups. `verifiedTypes`
-/// records the types already verified within the current symbol table so that
-/// each type, which may be uniqued and shared across many positions or
-/// operations, is verified at most once. Verification fails fast on the first
-/// invalid symbol use.
+/// Verify the symbol uses held by the types owned by `op`: its operand, result,
+/// and block-argument types, and any types nested within its attributes.
+/// `typeWalker` carries the SymbolUserTypeInterface check as a walk callback,
+/// anchored at `op` for symbol lookups, and its shared visited set makes each
+/// uniqued type, which may recur across many positions and operations, verified
+/// against the enclosing symbol table at most once. A type or attribute whose
+/// interning-time bit is clear is skipped: it provably contains no
+/// SymbolRefAttr, and a SymbolUserTypeInterface type is required to spell its
+/// references as SymbolRefAttr sub-elements, so walking it would verify
+/// nothing. Verification fails fast on the first invalid symbol use.
static LogicalResult verifyOpTypeSymbolUses(Operation *op,
- SymbolTableCollection &symbolTable,
- SetVector<Type> &verifiedTypes) {
- // Walk `type` and any nested type parameters reachable from it, verifying
- // each not-yet-seen type and interrupting on the first failure.
- auto verify = [&](Type type) {
- return type.walk<WalkOrder::PreOrder>([&](Type nestedType) {
- if (!verifiedTypes.insert(nestedType))
- return WalkResult::advance();
- if (auto user = dyn_cast<SymbolUserTypeInterface>(nestedType))
- if (failed(user.verifySymbolUses(op, symbolTable)))
- return WalkResult::interrupt();
+ AttrTypeWalker &typeWalker) {
+ auto verifyType = [&](Type type) {
+ if (!type.mayContainSymbolRefs())
return WalkResult::advance();
- });
+ return typeWalker.walk<WalkOrder::PreOrder>(type);
+ };
+ auto verifyAttr = [&](Attribute attr) {
+ if (!attr || !attr.mayContainSymbolRefs())
+ return WalkResult::advance();
+ return typeWalker.walk<WalkOrder::PreOrder>(attr);
};
for (Type type : op->getOperandTypes())
- if (verify(type).wasInterrupted())
+ if (verifyType(type).wasInterrupted())
return failure();
for (Type type : op->getResultTypes())
- if (verify(type).wasInterrupted())
+ if (verifyType(type).wasInterrupted())
return failure();
for (Region ®ion : op->getRegions())
for (Block &block : region)
for (BlockArgument argument : block.getArguments())
- if (verify(argument.getType()).wasInterrupted())
+ if (verifyType(argument.getType()).wasInterrupted())
return failure();
- // Verify types nested within the operation's attributes.
- WalkResult attrResult =
- op->getAttrDictionary().walk<WalkOrder::PreOrder>([&](Type type) {
- if (verify(type).wasInterrupted())
- return WalkResult::interrupt();
- return WalkResult::advance();
- });
- return failure(attrResult.wasInterrupted());
+ // Verify types nested within the operation's attributes. Read the raw stored
+ // attribute dictionary rather than getAttrDictionary(): the latter allocates
+ // and uniques a fresh dictionary for every operation that keeps its inherent
+ // attributes in properties. The raw dictionary already covers inherent
+ // attributes for operations that do not use properties; the properties-held
+ // inherent attributes are walked separately below.
+ if (verifyAttr(op->getRawDictionaryAttrs()).wasInterrupted())
+ return failure();
+ if (op->getPropertiesStorageSize()) {
+ NamedAttrList inherentAttrs;
+ op->getName().populateInherentAttrs(op, inherentAttrs);
----------------
joker-eph wrote:
That seems expensive: converting properties to attribute does not seem like something we'd want to do. We should try to instead generate some dispatch hook with every property to avoid this.
https://github.com/llvm/llvm-project/pull/212354
More information about the Mlir-commits
mailing list