Skip to content

Track access of uninitialized locals to optimize call frame setups #1681

@Robbepop

Description

@Robbepop

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:

  1. local x could have been assigned earlier: emit normal local. get x operation.
  2. local x could have been uninitialized: emit 0 immediate operand.
  3. 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!

Metadata

Metadata

Assignees

No one assigned

    Labels

    optimizationAn performance optimization issue.

    Type

    No type

    Projects

    Status

    Open

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions