[mlir] Fix circular dialect initialization
This change fixes a bug where a dialect is initialized multiple times. This triggers an assertion when the ops of the dialect are registered (`error: operation named ... is already registered`). This bug can be triggered as follows: 1. Dialect A depends on dialect B (as per ADialect.td). 2. Somewhere there is an extension of dialect B that depends on dialect A (e.g., it defines external models create ops from dialect A). E.g.: ``` registry.addExtension(+[](MLIRContext *ctx, BDialect *dialect) { BDialectOp::attachInterface ... ctx->loadDialect<ADialect>(); }); ``` 3. When dialect A is loaded, its `initialize` function is called twice: ``` ADialect::ADialect() | | | v | ADialect::initialize() v getOrLoadDialect<BDialect>() | v (load extension of BDialect) | v ctx->loadDialect<ADialect>() // user wrote this in the extension | v getOrLoadDialect<ADialect>() // the dialect is not "fully" loaded yet | v ADialect::ADialect() | v ADialect::initialize() ``` An example of a dialect extension that depends on other dialects is `Dialect/Tensor/Transforms/BufferizableOpInterfaceImpl.cpp`. That particular dialect extension does not trigger this bug. (It would trigger this bug if the SCF dialect would depend on the Tensor dialect.) This change introduces a new dialect state: dialects that are currently being loaded. Same as dialects that were already fully loaded (and initialized), dialects that are in the process of being loaded are not loaded a second time. Differential Revision: https://reviews.llvm.org/D136685
Loading
Please sign in to comment