Skip to content

wasm2js: Avoid 64-bit scratch memory helpers in wasm-intrinsics #2926

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jun 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions src/abi/js.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ namespace wasm2js {

extern cashew::IString SCRATCH_LOAD_I32;
extern cashew::IString SCRATCH_STORE_I32;
extern cashew::IString SCRATCH_LOAD_I64;
extern cashew::IString SCRATCH_STORE_I64;
extern cashew::IString SCRATCH_LOAD_F32;
extern cashew::IString SCRATCH_STORE_F32;
extern cashew::IString SCRATCH_LOAD_F64;
Expand Down Expand Up @@ -76,8 +74,6 @@ inline void ensureHelpers(Module* wasm,

ensureImport(SCRATCH_LOAD_I32, {Type::i32}, Type::i32);
ensureImport(SCRATCH_STORE_I32, {Type::i32, Type::i32}, Type::none);
ensureImport(SCRATCH_LOAD_I64, {}, Type::i64);
ensureImport(SCRATCH_STORE_I64, {Type::i64}, Type::none);
ensureImport(SCRATCH_LOAD_F32, {}, Type::f32);
ensureImport(SCRATCH_STORE_F32, {Type::f32}, Type::none);
ensureImport(SCRATCH_LOAD_F64, {}, Type::f64);
Expand All @@ -98,7 +94,6 @@ inline void ensureHelpers(Module* wasm,

inline bool isHelper(cashew::IString name) {
return name == SCRATCH_LOAD_I32 || name == SCRATCH_STORE_I32 ||
name == SCRATCH_LOAD_I64 || name == SCRATCH_STORE_I64 ||
name == SCRATCH_LOAD_F32 || name == SCRATCH_STORE_F32 ||
name == SCRATCH_LOAD_F64 || name == SCRATCH_STORE_F64 ||
name == ATOMIC_WAIT_I32 || name == MEMORY_INIT ||
Expand Down
2 changes: 0 additions & 2 deletions src/asmjs/shared-constants.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,6 @@ namespace wasm2js {

cashew::IString SCRATCH_LOAD_I32("wasm2js_scratch_load_i32");
cashew::IString SCRATCH_STORE_I32("wasm2js_scratch_store_i32");
cashew::IString SCRATCH_LOAD_I64("wasm2js_scratch_load_i64");
cashew::IString SCRATCH_STORE_I64("wasm2js_scratch_store_i64");
cashew::IString SCRATCH_LOAD_F32("wasm2js_scratch_load_f32");
cashew::IString SCRATCH_STORE_F32("wasm2js_scratch_store_f32");
cashew::IString SCRATCH_LOAD_F64("wasm2js_scratch_load_f64");
Expand Down
5 changes: 5 additions & 0 deletions src/passes/RemoveNonJSOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ struct RemoveNonJSOpsPass : public WalkerPass<PostWalker<RemoveNonJSOpsPass>> {
neededFunctions.clear();
}

// Copy all the globals in the intrinsics module
for (auto& global : intrinsicsModule.globals) {
ModuleUtils::copyGlobal(global.get(), *module);
}

// Intrinsics may use memory, so ensure the module has one.
MemoryUtils::ensureExists(module->memory);

Expand Down
22 changes: 10 additions & 12 deletions src/passes/wasm-intrinsics.wat
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@
;; (aka inlining and whatnot)
;;
;; LOCAL MODS done by hand afterwards:
;; * Remove hardcoded address 1024 (apparently a free memory location rustc
;; thinks is ok to use?); add intrinsic functions, which load/store to
;; special scratch space, wasm2js_scratch_load_i32 etc.
;; * Remove hardcoded address 1024 which was used for temporary data; instead
;; add $wasm-intrinsics-temp-i64 global for that.
;; * Fix function type of __wasm_ctz_i64, which was wrong somehow,
;; i32, i32 => i32 instead of i64 => i64
;;
Expand All @@ -22,8 +21,6 @@
(type $4 (func (param i32 i32) (result i32)))
(type $5 (func (param i64) (result i64)))
(import "env" "memory" (memory $0 17))
(import "env" "wasm2js_scratch_load_i64" (func $wasm2js_scratch_load_i64 (result i64)))
(import "env" "wasm2js_scratch_store_i64" (func $wasm2js_scratch_store_i64 (param i64)))
(export "__wasm_i64_sdiv" (func $__wasm_i64_sdiv))
(export "__wasm_i64_udiv" (func $__wasm_i64_udiv))
(export "__wasm_i64_srem" (func $__wasm_i64_srem))
Expand All @@ -41,6 +38,7 @@
(export "__wasm_nearest_f64" (func $__wasm_nearest_f64))
(export "__wasm_popcnt_i32" (func $__wasm_popcnt_i32))
(export "__wasm_popcnt_i64" (func $__wasm_popcnt_i64))
(global $__wasm-intrinsics-temp-i64 (mut i64) (i64.const 0))

;; lowering of the i32.popcnt instruction, counts the number of bits set in the
;; input and returns the result
Expand Down Expand Up @@ -137,7 +135,7 @@
(local.get $var$1)
)
)
(call $wasm2js_scratch_load_i64)
(global.get $__wasm-intrinsics-temp-i64)
)
;; lowering of the i64.mul instruction, return $var0 * $var$1
(func $__wasm_i64_mul (; 4 ;) (type $0) (param $var$0 i64) (param $var$1 i64) (result i64)
Expand Down Expand Up @@ -578,7 +576,7 @@
(i64.const 4294967296)
)
)
(call $wasm2js_scratch_store_i64
(global.set $__wasm-intrinsics-temp-i64
(i64.extend_i32_u
(i32.sub
(local.tee $var$2
Expand Down Expand Up @@ -639,7 +637,7 @@
(local.get $var$3)
)
)
(call $wasm2js_scratch_store_i64
(global.set $__wasm-intrinsics-temp-i64
(i64.or
(i64.shl
(i64.extend_i32_u
Expand Down Expand Up @@ -719,7 +717,7 @@
)
(br $label$3)
)
(call $wasm2js_scratch_store_i64
(global.set $__wasm-intrinsics-temp-i64
(i64.shl
(i64.extend_i32_u
(i32.sub
Expand Down Expand Up @@ -761,7 +759,7 @@
)
(br $label$2)
)
(call $wasm2js_scratch_store_i64
(global.set $__wasm-intrinsics-temp-i64
(i64.extend_i32_u
(i32.and
(local.get $var$4)
Expand Down Expand Up @@ -892,7 +890,7 @@
)
)
)
(call $wasm2js_scratch_store_i64
(global.set $__wasm-intrinsics-temp-i64
(local.get $var$5)
)
(return
Expand All @@ -905,7 +903,7 @@
)
)
)
(call $wasm2js_scratch_store_i64
(global.set $__wasm-intrinsics-temp-i64
(local.get $var$0)
)
(local.set $var$0
Expand Down
16 changes: 2 additions & 14 deletions src/wasm2js.h
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,8 @@ Ref Wasm2JSBuilder::processWasm(Module* wasm, Name funcName) {
{
PassRunner runner(wasm, options);
runner.add(make_unique<AutoDrop>());
// TODO: only legalize if necessary - emscripten would already do so, and
// likely other toolchains. but spec test suite needs that.
runner.add("legalize-js-interface");
// First up remove as many non-JS operations we can, including things like
// 64-bit integer multiplication/division, `f32.nearest` instructions, etc.
Expand Down Expand Up @@ -2376,20 +2378,6 @@ void Wasm2JSGlue::emitSpecialSupport() {
out << R"(
function wasm2js_scratch_load_i32(index) {
return i32ScratchView[index];
}
)";
} else if (import->base == ABI::wasm2js::SCRATCH_STORE_I64) {
out << R"(
function legalimport$wasm2js_scratch_store_i64(low, high) {
i32ScratchView[0] = low;
i32ScratchView[1] = high;
}
)";
} else if (import->base == ABI::wasm2js::SCRATCH_LOAD_I64) {
out << R"(
function legalimport$wasm2js_scratch_load_i64() {
if (typeof setTempRet0 === 'function') setTempRet0(i32ScratchView[1]);
return i32ScratchView[0];
}
)";
} else if (import->base == ABI::wasm2js::SCRATCH_STORE_F32) {
Expand Down
19 changes: 8 additions & 11 deletions test/passes/remove-non-js-ops.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,17 @@
(type $i32_=>_none (func (param i32)))
(type $i32_i32_=>_none (func (param i32 i32)))
(type $i32_i32_i32_i32_=>_none (func (param i32 i32 i32 i32)))
(type $i64_=>_none (func (param i64)))
(type $f32_=>_none (func (param f32)))
(type $f64_=>_none (func (param f64)))
(type $none_=>_i32 (func (result i32)))
(type $i32_i32_i32_i32_=>_i32 (func (param i32 i32 i32 i32) (result i32)))
(type $i32_i32_i32_i32_i32_i32_=>_i32 (func (param i32 i32 i32 i32 i32 i32) (result i32)))
(type $none_=>_i64 (func (result i64)))
(type $none_=>_f32 (func (result f32)))
(type $f32_f32_=>_f32 (func (param f32 f32) (result f32)))
(type $none_=>_f64 (func (result f64)))
(type $f64_f64_=>_f64 (func (param f64 f64) (result f64)))
(import "env" "wasm2js_scratch_load_i32" (func $wasm2js_scratch_load_i32 (param i32) (result i32)))
(import "env" "wasm2js_scratch_store_i32" (func $wasm2js_scratch_store_i32 (param i32 i32)))
(import "env" "wasm2js_scratch_load_i64" (func $wasm2js_scratch_load_i64 (result i64)))
(import "env" "wasm2js_scratch_store_i64" (func $wasm2js_scratch_store_i64 (param i64)))
(import "env" "wasm2js_scratch_load_f32" (func $wasm2js_scratch_load_f32 (result f32)))
(import "env" "wasm2js_scratch_store_f32" (func $wasm2js_scratch_store_f32 (param f32)))
(import "env" "wasm2js_scratch_load_f64" (func $wasm2js_scratch_load_f64 (result f64)))
Expand All @@ -35,6 +31,7 @@
(import "env" "wasm2js_atomic_rmw_i64" (func $wasm2js_atomic_rmw_i64 (param i32 i32 i32 i32 i32 i32) (result i32)))
(import "env" "wasm2js_get_stashed_bits" (func $wasm2js_get_stashed_bits (result i32)))
(memory $0 1)
(global $__wasm-intrinsics-temp-i64 (mut i64) (i64.const 0))
(func $copysign64 (param $0 f64) (param $1 f64) (result f64)
(f64.reinterpret_i64
(i64.or
Expand Down Expand Up @@ -426,7 +423,7 @@
(i64.const 4294967296)
)
)
(call $wasm2js_scratch_store_i64
(global.set $__wasm-intrinsics-temp-i64
(i64.extend_i32_u
(i32.sub
(local.tee $var$2
Expand Down Expand Up @@ -487,7 +484,7 @@
(local.get $var$3)
)
)
(call $wasm2js_scratch_store_i64
(global.set $__wasm-intrinsics-temp-i64
(i64.or
(i64.shl
(i64.extend_i32_u
Expand Down Expand Up @@ -567,7 +564,7 @@
)
(br $label$3)
)
(call $wasm2js_scratch_store_i64
(global.set $__wasm-intrinsics-temp-i64
(i64.shl
(i64.extend_i32_u
(i32.sub
Expand Down Expand Up @@ -609,7 +606,7 @@
)
(br $label$2)
)
(call $wasm2js_scratch_store_i64
(global.set $__wasm-intrinsics-temp-i64
(i64.extend_i32_u
(i32.and
(local.get $var$4)
Expand Down Expand Up @@ -740,7 +737,7 @@
)
)
)
(call $wasm2js_scratch_store_i64
(global.set $__wasm-intrinsics-temp-i64
(local.get $var$5)
)
(return
Expand All @@ -753,7 +750,7 @@
)
)
)
(call $wasm2js_scratch_store_i64
(global.set $__wasm-intrinsics-temp-i64
(local.get $var$0)
)
(local.set $var$0
Expand Down Expand Up @@ -813,7 +810,7 @@
(local.get $var$1)
)
)
(call $wasm2js_scratch_load_i64)
(global.get $__wasm-intrinsics-temp-i64)
)
(func $__wasm_nearest_f32 (param $var$0 f32) (result f32)
(local $var$1 f32)
Expand Down
Loading