[Mlir-commits] [mlir] [mlir] Add `MLIRContext::executeCriticalSection` and `Pass::getOpDependentDialects` methods. (PR #98953)

Mehdi Amini llvmlistbot at llvm.org
Mon Jul 15 16:16:35 PDT 2024


================
@@ -513,6 +513,21 @@ LogicalResult OpToOpPassAdaptor::run(Pass *pass, Operation *op,
   };
   pass->passState.emplace(op, am, dynamicPipelineCallback);
 
+  // Get any op dependent dialects.
+  DialectRegistry dependentDialects;
+  pass->getOpDependentDialects(op, dependentDialects);
+  MLIRContext &context = pass->getContext();
+  // Only append a non-empty non-trivial registry.
+  if (!dependentDialects.empty() &&
+      !dependentDialects.isSubsetOf(context.getDialectRegistry())) {
+    context.executeCriticalSection([&]() {
+      // Load the dialects.
+      context.appendDialectRegistry(dependentDialects);
+      for (StringRef name : dependentDialects.getDialectNames())
+        context.getOrLoadDialect(name);
----------------
joker-eph wrote:

Imagine: `pass-pipeline=func.func(PassA, PassB)`
Now with a module containing `func.func @func1` and  `func.func @func2`.

Assume that PassA would `dyn_cast<FooOpInterface>` and this interface is loaded by a dialect you're trying to load in PassB here.

Some of the possible executions are:

```
PassA(@func1) // dyn_cast<FooOpInterface>
PassA(@func2) // dyn_cast<FooOpInterface>
PassB(@func1) // load FooOpInterface
PassB(@func2) // load FooOpInterface
```

```
PassA(@func1) // dyn_cast<FooOpInterface>
PassB(@func1) // load FooOpInterface
PassA(@func2) // dyn_cast<FooOpInterface>
PassB(@func2) // load FooOpInterface
```


Now you see here that in the first case, PassA never sees the `FooOpInterface` because it's not loaded, while in the second case it is loaded before PassA operates on func2.

https://github.com/llvm/llvm-project/pull/98953


More information about the Mlir-commits mailing list