Locals in Wasm are always zero-initialized.
Wasm producers such as LLVM may use this fact and access an uninitialized local to strictly access a local with a zero value. In practice many Wasm producers don't rely on this.
Currently, Wasmi always zero-initializes locals which adds significant overhead to function calls.
If we track for every function if zero-initialization of local is required we could improve function call performance significantly in many cases.
Per local.get x this has the following consequences:
local x could have been assigned earlier: emit normal local. get x operation.
local x could have been uninitialized: emit 0 immediate operand.
- It is uncertain whether
local x has been initialized already or local x has been conditionally initialized.
Only if a function has a case 3. we need to zero-initialize locals. We could further optimize this by restricting which locals need zero-initialization but maybe this is already over complicating the matter.
LLVM should enforce initialized access of locals due to its “definite assignment” rule coming from its SSA IR. So all Wasm producers that use LLVM (Rust, emscripten etc.) are likely to benefit hugely from such an optimization.
In recent benchmarks I saw a drop from 2.8ms to 2.1ms in execute/fibonacci/rec when simply removing the zero initialization of locals from the call frame setup code. That's a whopping 25% improvement!
Locals in Wasm are always zero-initialized.
Wasm producers such as LLVM may use this fact and access an uninitialized local to strictly access a local with a zero value. In practice many Wasm producers don't rely on this.
Currently, Wasmi always zero-initializes locals which adds significant overhead to function calls.
If we track for every function if zero-initialization of local is required we could improve function call performance significantly in many cases.
Per
local.get xthis has the following consequences:local xcould have been assigned earlier: emit normallocal. get xoperation.local xcould have been uninitialized: emit0immediate operand.local xhas been initialized already orlocal xhas been conditionally initialized.Only if a function has a case 3. we need to zero-initialize locals. We could further optimize this by restricting which locals need zero-initialization but maybe this is already over complicating the matter.
LLVM should enforce initialized access of locals due to its “definite assignment” rule coming from its SSA IR. So all Wasm producers that use LLVM (Rust, emscripten etc.) are likely to benefit hugely from such an optimization.
In recent benchmarks I saw a drop from 2.8ms to 2.1ms in
execute/fibonacci/recwhen simply removing the zero initialization of locals from the call frame setup code. That's a whopping 25% improvement!