[wasm] Consume libc math functions directly from the jiterpreter without wrappers...
authorKatelyn Gadd <kg@luminance.org>
Wed, 8 Mar 2023 20:26:35 +0000 (12:26 -0800)
committerGitHub <noreply@github.com>
Wed, 8 Mar 2023 20:26:35 +0000 (12:26 -0800)
Implement more math opcodes and use the f32 functions as appropriate

src/mono/mono/mini/interp/jiterpreter.c
src/mono/wasm/runtime/jiterpreter-trace-generator.ts
src/mono/wasm/runtime/jiterpreter.ts
src/mono/wasm/wasm.proj

index ed926c3..03c2c8d 100644 (file)
@@ -1193,87 +1193,6 @@ mono_jiterp_debug_count ()
        return mono_debug_count();
 }
 
-EMSCRIPTEN_KEEPALIVE double
-mono_jiterp_math_rem (double lhs, double rhs) {
-       return fmod(lhs, rhs);
-}
-
-EMSCRIPTEN_KEEPALIVE double
-mono_jiterp_math_atan2 (double lhs, double rhs) {
-       return atan2(lhs, rhs);
-}
-
-EMSCRIPTEN_KEEPALIVE double
-mono_jiterp_math_pow (double lhs, double rhs) {
-       return pow(lhs, rhs);
-}
-
-EMSCRIPTEN_KEEPALIVE double
-mono_jiterp_math_acos (double value)
-{
-       return acos(value);
-}
-
-EMSCRIPTEN_KEEPALIVE double
-mono_jiterp_math_cos (double value)
-{
-       return cos(value);
-}
-
-EMSCRIPTEN_KEEPALIVE double
-mono_jiterp_math_asin (double value)
-{
-       return asin(value);
-}
-
-EMSCRIPTEN_KEEPALIVE double
-mono_jiterp_math_sin (double value)
-{
-       return sin(value);
-}
-
-EMSCRIPTEN_KEEPALIVE double
-mono_jiterp_math_atan (double value)
-{
-       return atan(value);
-}
-
-EMSCRIPTEN_KEEPALIVE double
-mono_jiterp_math_tan (double value)
-{
-       return tan(value);
-}
-
-EMSCRIPTEN_KEEPALIVE double
-mono_jiterp_math_exp (double value)
-{
-       return exp(value);
-}
-
-EMSCRIPTEN_KEEPALIVE double
-mono_jiterp_math_log (double value)
-{
-       return log(value);
-}
-
-EMSCRIPTEN_KEEPALIVE double
-mono_jiterp_math_log2 (double value)
-{
-       return log2(value);
-}
-
-EMSCRIPTEN_KEEPALIVE double
-mono_jiterp_math_log10 (double value)
-{
-       return log10(value);
-}
-
-EMSCRIPTEN_KEEPALIVE double
-mono_jiterp_math_fma (double x, double y, double z)
-{
-       return fma(x, y, z);
-}
-
 EMSCRIPTEN_KEEPALIVE int
 mono_jiterp_stelem_ref (
        MonoArray *o, gint32 aindex, MonoObject *ref
index 0b8ff2e..21135cc 100644 (file)
@@ -1062,19 +1062,11 @@ export function generate_wasm_body (
 
                 // LOCAL_VAR (ip [1], double) = fma (LOCAL_VAR (ip [2], double), LOCAL_VAR (ip [3], double), LOCAL_VAR (ip [4], double));
                 append_ldloc(builder, getArgU16(ip, 2), loadOp);
-                if (isF32)
-                    builder.appendU8(WasmOpcode.f64_promote_f32);
                 append_ldloc(builder, getArgU16(ip, 3), loadOp);
-                if (isF32)
-                    builder.appendU8(WasmOpcode.f64_promote_f32);
                 append_ldloc(builder, getArgU16(ip, 4), loadOp);
-                if (isF32)
-                    builder.appendU8(WasmOpcode.f64_promote_f32);
 
-                builder.callImport("fma");
+                builder.callImport(isF32 ? "fmaf" : "fma");
 
-                if (isF32)
-                    builder.appendU8(WasmOpcode.f32_demote_f64);
                 append_stloc_tail(builder, getArgU16(ip, 1), storeOp);
                 break;
             }
@@ -2584,25 +2576,33 @@ const mathIntrinsicTable : { [opcode: number] : [isUnary: boolean, isF32: boolea
     [MintOpcode.MINT_ABSF]:     [true, true,   WasmOpcode.f32_abs],
 
     [MintOpcode.MINT_ACOS]:     [true, false,  "acos"],
-    [MintOpcode.MINT_ACOSF]:    [true, true,   "acos"],
+    [MintOpcode.MINT_ACOSF]:    [true, true,   "acosf"],
+    [MintOpcode.MINT_ACOSH]:    [true, false,  "acosh"],
+    [MintOpcode.MINT_ACOSHF]:   [true, true,   "acoshf"],
     [MintOpcode.MINT_COS]:      [true, false,  "cos"],
-    [MintOpcode.MINT_COSF]:     [true, true,   "cos"],
+    [MintOpcode.MINT_COSF]:     [true, true,   "cosf"],
     [MintOpcode.MINT_ASIN]:     [true, false,  "asin"],
-    [MintOpcode.MINT_ASINF]:    [true, true,   "asin"],
+    [MintOpcode.MINT_ASINF]:    [true, true,   "asinf"],
+    [MintOpcode.MINT_ASINH]:    [true, false,  "asinh"],
+    [MintOpcode.MINT_ASINHF]:   [true, true,   "asinhf"],
     [MintOpcode.MINT_SIN]:      [true, false,  "sin"],
-    [MintOpcode.MINT_SINF]:     [true, true,   "sin"],
+    [MintOpcode.MINT_SINF]:     [true, true,   "sinf"],
     [MintOpcode.MINT_ATAN]:     [true, false,  "atan"],
-    [MintOpcode.MINT_ATANF]:    [true, true,   "atan"],
+    [MintOpcode.MINT_ATANF]:    [true, true,   "atanf"],
+    [MintOpcode.MINT_ATANH]:    [true, false,  "atanh"],
+    [MintOpcode.MINT_ATANHF]:   [true, true,   "atanhf"],
     [MintOpcode.MINT_TAN]:      [true, false,  "tan"],
-    [MintOpcode.MINT_TANF]:     [true, true,   "tan"],
+    [MintOpcode.MINT_TANF]:     [true, true,   "tanf"],
+    [MintOpcode.MINT_CBRT]:     [true, false,  "cbrt"],
+    [MintOpcode.MINT_CBRTF]:    [true, true,   "cbrtf"],
     [MintOpcode.MINT_EXP]:      [true, false,  "exp"],
-    [MintOpcode.MINT_EXPF]:     [true, true,   "exp"],
+    [MintOpcode.MINT_EXPF]:     [true, true,   "expf"],
     [MintOpcode.MINT_LOG]:      [true, false,  "log"],
-    [MintOpcode.MINT_LOGF]:     [true, true,   "log"],
+    [MintOpcode.MINT_LOGF]:     [true, true,   "logf"],
     [MintOpcode.MINT_LOG2]:     [true, false,  "log2"],
-    [MintOpcode.MINT_LOG2F]:    [true, true,   "log2"],
+    [MintOpcode.MINT_LOG2F]:    [true, true,   "log2f"],
     [MintOpcode.MINT_LOG10]:    [true, false,  "log10"],
-    [MintOpcode.MINT_LOG10F]:   [true, true,   "log10"],
+    [MintOpcode.MINT_LOG10F]:   [true, true,   "log10f"],
 
     [MintOpcode.MINT_MIN]:      [false, false,  WasmOpcode.f64_min],
     [MintOpcode.MINT_MINF]:     [false, true,   WasmOpcode.f32_min],
@@ -2610,11 +2610,11 @@ const mathIntrinsicTable : { [opcode: number] : [isUnary: boolean, isF32: boolea
     [MintOpcode.MINT_MAXF]:     [false, true,   WasmOpcode.f32_max],
 
     [MintOpcode.MINT_ATAN2]:    [false, false, "atan2"],
-    [MintOpcode.MINT_ATAN2F]:   [false, true,  "atan2"],
+    [MintOpcode.MINT_ATAN2F]:   [false, true,  "atan2f"],
     [MintOpcode.MINT_POW]:      [false, false, "pow"],
-    [MintOpcode.MINT_POWF]:     [false, true,  "pow"],
-    [MintOpcode.MINT_REM_R4]:   [false, true,  "rem"],
-    [MintOpcode.MINT_REM_R8]:   [false, false, "rem"],
+    [MintOpcode.MINT_POWF]:     [false, true,  "powf"],
+    [MintOpcode.MINT_REM_R8]:   [false, false, "fmod"],
+    [MintOpcode.MINT_REM_R4]:   [false, true,  "fmodf"],
 };
 
 function emit_math_intrinsic (builder: WasmBuilder, ip: MintOpcodePtr, opcode: MintOpcode) : boolean {
@@ -2644,29 +2644,19 @@ function emit_math_intrinsic (builder: WasmBuilder, ip: MintOpcodePtr, opcode: M
         if (wasmOp) {
             builder.appendU8(wasmOp);
         } else if (name) {
-            if (isF32)
-                builder.appendU8(WasmOpcode.f64_promote_f32);
             builder.callImport(name);
-            if (isF32)
-                builder.appendU8(WasmOpcode.f32_demote_f64);
         } else
             throw new Error("internal error");
         append_stloc_tail(builder, destOffset, isF32 ? WasmOpcode.f32_store : WasmOpcode.f64_store);
         return true;
     } else {
         append_ldloc(builder, srcOffset, isF32 ? WasmOpcode.f32_load : WasmOpcode.f64_load);
-        if (isF32 && name)
-            builder.appendU8(WasmOpcode.f64_promote_f32);
         append_ldloc(builder, rhsOffset, isF32 ? WasmOpcode.f32_load : WasmOpcode.f64_load);
-        if (isF32 && name)
-            builder.appendU8(WasmOpcode.f64_promote_f32);
 
         if (wasmOp) {
             builder.appendU8(wasmOp);
         } else if (name) {
             builder.callImport(name);
-            if (isF32)
-                builder.appendU8(WasmOpcode.f32_demote_f64);
         } else
             throw new Error("internal error");
 
index 3bce90e..28fb401 100644 (file)
@@ -224,24 +224,51 @@ export let traceImports : Array<[string, string, Function]> | undefined;
 
 export let _wrap_trace_function: Function;
 
-const mathOps1 = [
-    "asin",
-    "acos",
-    "atan",
-    "cos",
-    "exp",
-    "log",
-    "log2",
-    "log10",
-    "sin",
-    "tan",
-];
-
-const mathOps2 = [
-    "rem",
-    "atan2",
-    "pow",
-];
+const mathOps1d = [
+        "asin",
+        "acos",
+        "atan",
+        "asinh",
+        "acosh",
+        "atanh",
+        "cos",
+        "sin",
+        "tan",
+        "cosh",
+        "sinh",
+        "tanh",
+        "exp",
+        "log",
+        "log2",
+        "log10",
+        "cbrt",
+    ], mathOps2d = [
+        "fmod",
+        "atan2",
+        "pow",
+    ], mathOps1f = [
+        "asinf",
+        "acosf",
+        "atanf",
+        "asinhf",
+        "acoshf",
+        "atanhf",
+        "cosf",
+        "sinf",
+        "tanf",
+        "coshf",
+        "sinhf",
+        "tanhf",
+        "expf",
+        "logf",
+        "log2f",
+        "log10f",
+        "cbrtf",
+    ], mathOps2f = [
+        "fmodf",
+        "atan2f",
+        "powf",
+    ];
 
 function getTraceImports () {
     if (traceImports)
@@ -277,7 +304,8 @@ function getTraceImports () {
         importDef("cmpxchg_i32", getRawCwrap("mono_jiterp_cas_i32")),
         importDef("cmpxchg_i64", getRawCwrap("mono_jiterp_cas_i64")),
         importDef("stelem_ref", getRawCwrap("mono_jiterp_stelem_ref")),
-        importDef("fma", getRawCwrap("mono_jiterp_math_fma")),
+        importDef("fma", getRawCwrap("fma")),
+        importDef("fmaf", getRawCwrap("fmaf")),
     ];
 
     if (instrumentedMethodNames.length > 0) {
@@ -288,15 +316,17 @@ function getTraceImports () {
     if (nullCheckValidation)
         traceImports.push(importDef("notnull", assert_not_null));
 
-    for (let i = 0; i < mathOps1.length; i++) {
-        const mop = mathOps1[i];
-        traceImports.push([mop, "mathop_d_d", getRawCwrap("mono_jiterp_math_" + mop)]);
-    }
+    const pushMathOps = (list: string[], type: string) => {
+        for (let i = 0; i < list.length; i++) {
+            const mop = list[i];
+            traceImports!.push([mop, type, getRawCwrap(mop)]);
+        }
+    };
 
-    for (let i = 0; i < mathOps2.length; i++) {
-        const mop = mathOps2[i];
-        traceImports.push([mop, "mathop_dd_d", getRawCwrap("mono_jiterp_math_" + mop)]);
-    }
+    pushMathOps(mathOps1f, "mathop_f_f");
+    pushMathOps(mathOps2f, "mathop_ff_f");
+    pushMathOps(mathOps1d, "mathop_d_d");
+    pushMathOps(mathOps2d, "mathop_dd_d");
 
     return traceImports;
 }
@@ -412,6 +442,24 @@ function initialize_builder (builder: WasmBuilder) {
         }, WasmValtype.f64, true
     );
     builder.defineType(
+        "mathop_f_f", {
+            "value": WasmValtype.f32,
+        }, WasmValtype.f32, true
+    );
+    builder.defineType(
+        "mathop_ff_f", {
+            "lhs": WasmValtype.f32,
+            "rhs": WasmValtype.f32,
+        }, WasmValtype.f32, true
+    );
+    builder.defineType(
+        "fmaf", {
+            "x": WasmValtype.f32,
+            "y": WasmValtype.f32,
+            "z": WasmValtype.f32,
+        }, WasmValtype.f32, true
+    );
+    builder.defineType(
         "fma", {
             "x": WasmValtype.f64,
             "y": WasmValtype.f64,
index 348f2c1..ded4d1a 100644 (file)
       <EmccExportedFunction Include="_htons" />
       <EmccExportedFunction Include="_ntohs" />
     </ItemGroup>
+    <!-- for the jiterpreter -->
+    <ItemGroup>
+      <EmccExportedFunction Include="_fmod" />
+      <EmccExportedFunction Include="_atan2" />
+      <EmccExportedFunction Include="_fma" />
+      <EmccExportedFunction Include="_pow" />
+      <EmccExportedFunction Include="_fmodf" />
+      <EmccExportedFunction Include="_atan2f" />
+      <EmccExportedFunction Include="_fmaf" />
+      <EmccExportedFunction Include="_powf" />
+
+      <EmccExportedFunction Include="_asin" />
+      <EmccExportedFunction Include="_asinh" />
+      <EmccExportedFunction Include="_acos" />
+      <EmccExportedFunction Include="_acosh" />
+      <EmccExportedFunction Include="_atan" />
+      <EmccExportedFunction Include="_atanh" />
+      <EmccExportedFunction Include="_cbrt" />
+      <EmccExportedFunction Include="_cos" />
+      <EmccExportedFunction Include="_cosh" />
+      <EmccExportedFunction Include="_exp" />
+      <EmccExportedFunction Include="_log" />
+      <EmccExportedFunction Include="_log2" />
+      <EmccExportedFunction Include="_log10" />
+      <EmccExportedFunction Include="_sin" />
+      <EmccExportedFunction Include="_sinh" />
+      <EmccExportedFunction Include="_tan" />
+      <EmccExportedFunction Include="_tanh" />
+
+      <EmccExportedFunction Include="_asinf" />
+      <EmccExportedFunction Include="_asinhf" />
+      <EmccExportedFunction Include="_acosf" />
+      <EmccExportedFunction Include="_acoshf" />
+      <EmccExportedFunction Include="_atanf" />
+      <EmccExportedFunction Include="_atanhf" />
+      <EmccExportedFunction Include="_cbrtf" />
+      <EmccExportedFunction Include="_cosf" />
+      <EmccExportedFunction Include="_coshf" />
+      <EmccExportedFunction Include="_expf" />
+      <EmccExportedFunction Include="_logf" />
+      <EmccExportedFunction Include="_log2f" />
+      <EmccExportedFunction Include="_log10f" />
+      <EmccExportedFunction Include="_sinf" />
+      <EmccExportedFunction Include="_sinhf" />
+      <EmccExportedFunction Include="_tanf" />
+      <EmccExportedFunction Include="_tanhf" />
+    </ItemGroup>
     <!-- after 3.0 -->
     <ItemGroup Condition="$([MSBuild]::VersionGreaterThan('$(_EmccVersion)', '3.0'))">
       <EmccExportedFunction Include="_memset" />
       <_EmccLinkFlags Include="-s STRICT_JS=1" />
       <_EmccLinkFlags Include="-s EXPORT_NAME=&quot;'createDotnetRuntime'&quot;" />
       <_EmccLinkFlags Include="-s MODULARIZE=1"/>
-      
+
       <_EmccLinkFlags Include="-s ENVIRONMENT=&quot;web,webview,worker,node,shell&quot;" />
       <!-- remove -Wno-limited-postlink-optimizations once below issue is fixed
            active issue: https://github.com/emscripten-core/emscripten/pull/16727 -->
           SkipUnchangedFiles="true" />
 
     <Exec Command="$(CMakeBuildRuntimeConfigureCmd)" WorkingDirectory="$(NativeBinDir)" />
-    <Exec Command="$(CMakeBuildRuntimeCmd)"  WorkingDirectory="$(NativeBinDir)" 
+    <Exec Command="$(CMakeBuildRuntimeCmd)"  WorkingDirectory="$(NativeBinDir)"
           EnvironmentVariables="WasmEnableLegacyJsInterop=$(WasmEnableLegacyJsInterop)" />
 
     <ItemGroup>