Skip to content
Commit 4433e52e authored by Matthias Springer's avatar Matthias Springer
Browse files

[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
parent b51b90d6
Loading
Loading
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment