[Mlir-commits] [mlir] [MLIR][Wasm] Introduce the WasmSSA MLIR dialect (PR #149233)
Ferdinand Lemaire
llvmlistbot at llvm.org
Tue Jul 22 00:08:16 PDT 2025
================
@@ -0,0 +1,674 @@
+//===- WebAssemblySSAOps.td - WebAssemblySSA op definitions -*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef WEBASSEMBLYSSA_OPS
+#define WEBASSEMBLYSSA_OPS
+
+
+include "mlir/Dialect/WebAssemblySSA/IR/WebAssemblySSABase.td"
+include "mlir/Dialect/WebAssemblySSA/IR/WebAssemblySSATypes.td"
+include "mlir/Dialect/WebAssemblySSA/IR/WebAssemblySSAInterfaces.td"
+
+include "mlir/Interfaces/FunctionInterfaces.td"
+include "mlir/Interfaces/InferTypeOpInterface.td"
+include "mlir/IR/BuiltinAttributeInterfaces.td"
+include "mlir/IR/SymbolInterfaces.td"
+
+class WasmSSA_Op<string mnemonic, list<Trait> traits = []> :
+ Op<WasmSSA_Dialect, mnemonic, traits>;
+
+class WasmSSA_BlockLikeOp<string mnemonic, string summaryStr> :
+ WasmSSA_Op<mnemonic, [Terminator, DeclareOpInterfaceMethods<WasmSSALabelLevelInterface>]> {
+ let summary = summaryStr;
+ let arguments = (ins Variadic<WasmSSA_ValType>: $inputs);
+ let regions = (region AnyRegion: $body);
+ let successors = (successor AnySuccessor: $target);
+ let extraClassDeclaration = [{
+ ::mlir::Block* createBlock() {
+ auto &block = getBody().emplaceBlock();
+ for (auto input : getInputs())
+ block.addArgument(input.getType(), input.getLoc());
+ return █
+ }
+ }];
+ let assemblyFormat = "(`(`$inputs^`)` `:` type($inputs))? attr-dict `:` $body `>` $target";
+}
+
+def WasmSSA_BlockOp : WasmSSA_BlockLikeOp<"block", "Create a nesting level"> {}
+
+def WasmSSA_LoopOp : WasmSSA_BlockLikeOp<"loop", "Create a nesting level similar to Block Op, except that it has itself as a successor."> {}
+
+def WasmSSA_BlockReturnOp : WasmSSA_Op<"block_return", [Terminator,
+ DeclareOpInterfaceMethods<WasmSSALabelBranchingInterface>]> {
+ let summary = "Return from the current block";
+ let arguments = (ins Variadic<WasmSSA_ValType>: $inputs);
+ let extraClassDeclaration = [{
+ ::mlir::Block* getTarget();
+ }];
+ let assemblyFormat = "($inputs^ `:` type($inputs))? attr-dict";
+}
+
+def WasmSSA_BranchIfOp : WasmSSA_Op<"branch_if", [
+ Terminator,
+ DeclareOpInterfaceMethods<WasmSSALabelBranchingInterface>]> {
+ let summary = "Jump to target level if condition has non-zero value";
+ let arguments = (ins I32: $condition,
+ UI32Attr: $exitLevel,
+ Variadic<WasmSSA_ValType>: $inputs);
+ let successors = (successor AnySuccessor: $elseSuccessor);
+ let assemblyFormat = "$condition `to` `level` $exitLevel (`with` `args` `(`$inputs^ `:` type($inputs)`)`)? `else` $elseSuccessor attr-dict";
+}
+
+def WasmSSA_ConstOp : WasmSSA_Op<"const", [
+ AllTypesMatch<["value", "result"]>, WasmSSAConstantExprInterface]> {
+ let summary = "Operator that represents a constant value";
+ let arguments = (ins TypedAttrInterface: $value);
+ let results = (outs WasmSSA_NumericType: $result);
+ let assemblyFormat = "$value attr-dict";
+}
+
+def WasmSSA_FuncOp : WasmSSA_Op<"func", [
+ AffineScope, AutomaticAllocationScope,
+ DeclareOpInterfaceMethods<FunctionOpInterface>,
+ IsolatedFromAbove,
+ Symbol]> {
+ let description = [{
+ Represents a Wasm function definition.
+
+ In Wasm function, locals and function arguments are interchangeable.
+ They are for instance both accessed using `local.get` instruction.
+
+ On the other hand, a function type is defined as a pair of tuples of Wasm value types.
+ To model this, the wasm.func operation has:
+
+ - A function type that represents the corresponding wasm type (tuples of value types)
+
+ - Arguments of the entry block of type `!wasm<local T>`, with T the corresponding type
+ in the function type.
+ }];
+ let arguments = (ins SymbolNameAttr: $sym_name,
+ WasmSSA_FuncTypeAttr: $functionType,
+ OptionalAttr<DictArrayAttr>:$arg_attrs,
+ OptionalAttr<DictArrayAttr>:$res_attrs,
+ DefaultValuedAttr<StrAttr, "\"nested\"">:$sym_visibility);
+ let regions = (region AnyRegion: $body);
+ let extraClassDeclaration = [{
+
+ /// Create the entry block for the function with parameters wrapped in local ref.
+ ::mlir::Block* addEntryBlock();
+
+ //===------------------------------------------------------------------===//
+ // FunctionOpInterface Methods
+ //===------------------------------------------------------------------===//
+
+ /// Returns the region on the current operation that is callable. This may
+ /// return null in the case of an external callable object, e.g. an external
+ /// function.
+ ::mlir::Region *getCallableRegion() { return isExternal() ? nullptr : &getBody(); }
+
+ ::mlir::LogicalResult verifyBody();
+
+ /// Returns the argument types of this function.
+ ArrayRef<Type> getArgumentTypes() { return getFunctionType().getInputs(); }
+
+ /// Returns the result types of this function.
+ ArrayRef<Type> getResultTypes() { return getFunctionType().getResults(); }
+ }];
+
+ let builders = [
+ OpBuilder<(ins "llvm::StringRef":$symbol, "FunctionType":$funcType )>
+ ];
+ let hasCustomAssemblyFormat = 1;
+}
+
+def WasmSSA_FuncCallOp : WasmSSA_Op<"call"> {
----------------
flemairen6 wrote:
We thought about it but I think the interface implies the implementation of a bunch of functions we had no use for at the time so we left it as-is
https://github.com/llvm/llvm-project/pull/149233
More information about the Mlir-commits
mailing list