[Mlir-commits] [mlir] [MLIR][Wasm] Introduce the WasmSSA MLIR dialect (PR #149233)
Luc Forget
llvmlistbot at llvm.org
Wed Jul 23 16:07:56 PDT 2025
================
@@ -0,0 +1,186 @@
+//===-- WebAssemblySSAInterfaces.td - WebAssemblySSA Interfaces -*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines interfaces for the WebAssemblySSA dialect in MLIR.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef WEBASSEMBLYSSA_INTERFACES
+#define WEBASSEMBLYSSA_INTERFACES
+
+include "mlir/IR/OpBase.td"
+include "mlir/IR/BuiltinAttributes.td"
+
+def WasmSSALabelLevelInterface : OpInterface<"WasmSSALabelLevelInterface"> {
+ let description = [{
+ Operation that defines one level of nesting for wasm branching.
+ These operation region can be targeted by branch instructions.
+ }];
+ let methods = [
+ InterfaceMethod<
+ /*desc=*/ "Returns the target block address",
+ /*returnType=*/ "::mlir::Block*",
+ /*methodName=*/ "getLabelTarget",
+ /*args=*/ (ins)
+ >
+ ];
+}
+
+def WasmSSALabelBranchingInterface : OpInterface<"WasmSSALabelBranchingInterface"> {
+ let description = [{
+ Wasm operation that targets a label for a jump.
+ }];
+ let methods = [
+ InterfaceMethod<
+ /*desc=*/ "Returns the number of context to break from",
+ /*returnType=*/ "size_t",
+ /*methodName=*/ "getExitLevel",
+ /*args=*/ (ins)
+ >,
----------------
lforg37 wrote:
> I can't parse the example right now, is this supposed to be MLIR or some sort of pseudo-code?
This is some MLIR flavored pseudo code. Let me try to reformulate it better in English, along with comments on why I think it do solve the issue (as my understanding of LangRef might get wrong).
First, current design issue is that there are operations that have a semantics of escaping multiple levels of region nesting at once. E.g. `branch 2` in Wasm means roughly resume the execution at the end of the scope enclosing the scope enclosing the current scope. The current state of the PR is to mimic this, with some actual control flow path which are not reflected in the successor lists.
My understanding is that to make it compliant with LangRef we need to make the framework aware of all possible control flow paths via the successor mechanism. With successor of an op being in the same region that the op.
Currently a control flow op has only one successor which is the "continuation" block, where the control flow should go when the region of the op is executed completely without any early exit.
The proposal is to add one successor block for each of possible exit path.
Basically, at nesting level 0 there's only one exit level, early exit can only make you access it earlier.
At level 1 you can either early exit to level 1 continuation block or conceptually to level 0 continuation block, but this last one is not defined in an accessible region.
So a skip block in the enclosing region is added to have a path to exit that the framework is aware of.
In a more MLIR-ish way this would looks like
```
wasmssa.block() {
WasmSSA.block() {
// This would transfer the control flow back to the inner block op
// It will then flow to ^level0skip
wasmssa.branch 1
// This will continue to level1continuation
wasmssa.block_return
// (This is equivalent to wasmssa.branch 0)
} ^level0skip, level1continuation
^level1continuation:
// here are the instructions that follows inner block in top level block
^level0skip:
wasmssa.branch 0
} > ^levelOcontinuation
^levelOcontinuation:
//
```
Inner block has two possible successors: either the continuation block to continue after it inside outer block, or the skip block that will forward the control flow to outer block continuation block.
Generally speaking a control flow op at nesting level n would have n+1 successors. Not all of them will be actual accessible path, we could have a cleaning step to remove all skip blocks that are not used by inner operation branching.
https://github.com/llvm/llvm-project/pull/149233
More information about the Mlir-commits
mailing list