Skip to content

Commit

Permalink
wazevo(frontend): faster non-imported global access (#1889)
Browse files Browse the repository at this point in the history
Signed-off-by: Takeshi Yoneda <[email protected]>
  • Loading branch information
mathetake authored Dec 22, 2023
1 parent 68729c0 commit 2762404
Show file tree
Hide file tree
Showing 19 changed files with 339 additions and 201 deletions.
8 changes: 8 additions & 0 deletions internal/engine/compiler/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,14 @@ func (e *moduleEngine) ResolveImportedFunction(index, indexInImportedModule wasm
e.functions[index] = imported.functions[indexInImportedModule]
}

// GetGlobalValue implements the same method as documented on wasm.ModuleEngine.
func (e *moduleEngine) GetGlobalValue(wasm.Index) (lo, hi uint64) {
panic("BUG: GetGlobalValue should never be called on compiler mode")
}

// OwnsGlobals implements the same method as documented on wasm.ModuleEngine.
func (e *moduleEngine) OwnsGlobals() bool { return false }

// ResolveImportedMemory implements wasm.ModuleEngine.
func (e *moduleEngine) ResolveImportedMemory(wasm.ModuleEngine) {}

Expand Down
8 changes: 8 additions & 0 deletions internal/engine/interpreter/interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,14 @@ type moduleEngine struct {
parentEngine *engine
}

// GetGlobalValue implements the same method as documented on wasm.ModuleEngine.
func (e *moduleEngine) GetGlobalValue(wasm.Index) (lo, hi uint64) {
panic("BUG: GetGlobalValue should never be called on interpreter mode")
}

// OwnsGlobals implements the same method as documented on wasm.ModuleEngine.
func (e *moduleEngine) OwnsGlobals() bool { return false }

// callEngine holds context per moduleEngine.Call, and shared across all the
// function calls originating from the same moduleEngine.Call execution.
//
Expand Down
100 changes: 38 additions & 62 deletions internal/engine/wazevo/backend/backend_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1937,34 +1937,26 @@ L2:
L1 (SSA Block: blk0):
mov x128?, x0
mov x129?, x1
ldr x130?, [x129?, #0x8]
ldr w131?, [x130?, #0x8]
ldr x132?, [x129?, #0x10]
ldr x133?, [x132?, #0x8]
ldr x134?, [x129?, #0x18]
ldr s135?, [x134?, #0x8]
ldr x136?, [x129?, #0x20]
ldr d137?, [x136?, #0x8]
ldr w130?, [x129?, #0x8]
ldr x131?, [x129?, #0x18]
ldr s132?, [x129?, #0x28]
ldr d133?, [x129?, #0x38]
str x129?, [x128?, #0x8]
mov x0, x128?
mov x1, x129?
bl f1
ldr x138?, [x129?, #0x8]
ldr w139?, [x138?, #0x8]
ldr x140?, [x129?, #0x10]
ldr x141?, [x140?, #0x8]
ldr x142?, [x129?, #0x18]
ldr s143?, [x142?, #0x8]
ldr x144?, [x129?, #0x20]
ldr d145?, [x144?, #0x8]
mov v3.8b, v145?.8b
mov v2.8b, v143?.8b
mov x3, x141?
mov x2, x139?
mov v1.8b, v137?.8b
mov v0.8b, v135?.8b
mov x1, x133?
mov x0, x131?
ldr w134?, [x129?, #0x8]
ldr x135?, [x129?, #0x18]
ldr s136?, [x129?, #0x28]
ldr d137?, [x129?, #0x38]
mov v3.8b, v137?.8b
mov v2.8b, v136?.8b
mov x3, x135?
mov x2, x134?
mov v1.8b, v133?.8b
mov v0.8b, v132?.8b
mov x1, x131?
mov x0, x130?
ret
`,
afterFinalizeARM64: `
Expand All @@ -1974,29 +1966,21 @@ L1 (SSA Block: blk0):
orr x27, xzr, #0x20
str x27, [sp, #-0x10]!
str x1, [sp, #0x10]
ldr x8, [x1, #0x8]
ldr w8, [x8, #0x8]
ldr w8, [x1, #0x8]
str w8, [sp, #0x2c]
ldr x9, [x1, #0x10]
ldr x9, [x9, #0x8]
ldr x9, [x1, #0x18]
str x9, [sp, #0x24]
ldr x10, [x1, #0x18]
ldr s8, [x10, #0x8]
ldr s8, [x1, #0x28]
str s8, [sp, #0x20]
ldr x10, [x1, #0x20]
ldr d9, [x10, #0x8]
ldr d9, [x1, #0x38]
str d9, [sp, #0x18]
str x1, [x0, #0x8]
bl f1
ldr x8, [sp, #0x10]
ldr x9, [x8, #0x8]
ldr w9, [x9, #0x8]
ldr x10, [x8, #0x10]
ldr x10, [x10, #0x8]
ldr x11, [x8, #0x18]
ldr s8, [x11, #0x8]
ldr x8, [x8, #0x20]
ldr d9, [x8, #0x8]
ldr w9, [x8, #0x8]
ldr x10, [x8, #0x18]
ldr s8, [x8, #0x28]
ldr d9, [x8, #0x38]
mov v3.8b, v9.8b
mov v2.8b, v8.8b
mov x3, x10
Expand All @@ -2022,36 +2006,28 @@ L1 (SSA Block: blk0):
afterLoweringARM64: `
L1 (SSA Block: blk0):
mov x129?, x1
ldr x131?, [x129?, #0x8]
orr w141?, wzr, #0x1
str w141?, [x131?, #0x8]
ldr x133?, [x129?, #0x10]
orr x140?, xzr, #0x2
str x140?, [x133?, #0x8]
ldr x135?, [x129?, #0x18]
ldr s139?, #8; b 8; data.f32 3.000000
str s139?, [x135?, #0x8]
ldr x137?, [x129?, #0x20]
ldr d138?, #8; b 16; data.f64 4.000000
str d138?, [x137?, #0x8]
orr w137?, wzr, #0x1
str w137?, [x129?, #0x8]
orr x136?, xzr, #0x2
str x136?, [x129?, #0x18]
ldr s135?, #8; b 8; data.f32 3.000000
str s135?, [x129?, #0x28]
ldr d134?, #8; b 16; data.f64 4.000000
str d134?, [x129?, #0x38]
ret
`,
afterFinalizeARM64: `
L1 (SSA Block: blk0):
stp x30, xzr, [sp, #-0x10]!
str xzr, [sp, #-0x10]!
ldr x8, [x1, #0x8]
orr w9, wzr, #0x1
str w9, [x8, #0x8]
ldr x8, [x1, #0x10]
orr x9, xzr, #0x2
str x9, [x8, #0x8]
ldr x8, [x1, #0x18]
orr w8, wzr, #0x1
str w8, [x1, #0x8]
orr x8, xzr, #0x2
str x8, [x1, #0x18]
ldr s8, #8; b 8; data.f32 3.000000
str s8, [x8, #0x8]
ldr x8, [x1, #0x20]
str s8, [x1, #0x28]
ldr d8, #8; b 16; data.f64 4.000000
str d8, [x8, #0x8]
str d8, [x1, #0x38]
add sp, sp, #0x10
ldr x30, [sp], #0x10
ret
Expand Down
86 changes: 31 additions & 55 deletions internal/engine/wazevo/frontend/frontend_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1181,15 +1181,11 @@ blk0: (exec_ctx:i64, module_ctx:i64, v2:i32)
m: testcases.GlobalsGet.Module,
exp: `
blk0: (exec_ctx:i64, module_ctx:i64)
v2:i64 = Load module_ctx, 0x8
v3:i32 = Load v2, 0x8
v4:i64 = Load module_ctx, 0x10
v5:i64 = Load v4, 0x8
v6:i64 = Load module_ctx, 0x18
v7:f32 = Load v6, 0x8
v8:i64 = Load module_ctx, 0x20
v9:f64 = Load v8, 0x8
Jump blk_ret, v3, v5, v7, v9
v2:i32 = Load module_ctx, 0x8
v3:i64 = Load module_ctx, 0x18
v4:f32 = Load module_ctx, 0x28
v5:f64 = Load module_ctx, 0x38
Jump blk_ret, v2, v3, v4, v5
`,
},
{
Expand All @@ -1198,18 +1194,14 @@ blk0: (exec_ctx:i64, module_ctx:i64)
exp: `
blk0: (exec_ctx:i64, module_ctx:i64)
v2:i32 = Iconst_32 0x1
v3:i64 = Load module_ctx, 0x8
Store v2, v3, 0x8
v4:i64 = Iconst_64 0x2
v5:i64 = Load module_ctx, 0x10
Store v4, v5, 0x8
v6:f32 = F32const 3.000000
v7:i64 = Load module_ctx, 0x18
Store v6, v7, 0x8
v8:f64 = F64const 4.000000
v9:i64 = Load module_ctx, 0x20
Store v8, v9, 0x8
Jump blk_ret, v2, v4, v6, v8
Store v2, module_ctx, 0x8
v3:i64 = Iconst_64 0x2
Store v3, module_ctx, 0x18
v4:f32 = F32const 3.000000
Store v4, module_ctx, 0x28
v5:f64 = F64const 4.000000
Store v5, module_ctx, 0x38
Jump blk_ret, v2, v3, v4, v5
`,
},
{
Expand All @@ -1220,50 +1212,34 @@ signatures:
sig1: i64i64_v
blk0: (exec_ctx:i64, module_ctx:i64)
v2:i64 = Load module_ctx, 0x8
v3:i32 = Load v2, 0x8
v4:i64 = Load module_ctx, 0x10
v5:i64 = Load v4, 0x8
v6:i64 = Load module_ctx, 0x18
v7:f32 = Load v6, 0x8
v8:i64 = Load module_ctx, 0x20
v9:f64 = Load v8, 0x8
v2:i32 = Load module_ctx, 0x8
v3:i64 = Load module_ctx, 0x18
v4:f32 = Load module_ctx, 0x28
v5:f64 = Load module_ctx, 0x38
Store module_ctx, exec_ctx, 0x8
Call f1:sig1, exec_ctx, module_ctx
v10:i64 = Load module_ctx, 0x8
v11:i32 = Load v10, 0x8
v12:i64 = Load module_ctx, 0x10
v13:i64 = Load v12, 0x8
v14:i64 = Load module_ctx, 0x18
v15:f32 = Load v14, 0x8
v16:i64 = Load module_ctx, 0x20
v17:f64 = Load v16, 0x8
Jump blk_ret, v3, v5, v7, v9, v11, v13, v15, v17
v6:i32 = Load module_ctx, 0x8
v7:i64 = Load module_ctx, 0x18
v8:f32 = Load module_ctx, 0x28
v9:f64 = Load module_ctx, 0x38
Jump blk_ret, v2, v3, v4, v5, v6, v7, v8, v9
`,
expAfterOpt: `
signatures:
sig1: i64i64_v
blk0: (exec_ctx:i64, module_ctx:i64)
v2:i64 = Load module_ctx, 0x8
v3:i32 = Load v2, 0x8
v4:i64 = Load module_ctx, 0x10
v5:i64 = Load v4, 0x8
v6:i64 = Load module_ctx, 0x18
v7:f32 = Load v6, 0x8
v8:i64 = Load module_ctx, 0x20
v9:f64 = Load v8, 0x8
v2:i32 = Load module_ctx, 0x8
v3:i64 = Load module_ctx, 0x18
v4:f32 = Load module_ctx, 0x28
v5:f64 = Load module_ctx, 0x38
Store module_ctx, exec_ctx, 0x8
Call f1:sig1, exec_ctx, module_ctx
v10:i64 = Load module_ctx, 0x8
v11:i32 = Load v10, 0x8
v12:i64 = Load module_ctx, 0x10
v13:i64 = Load v12, 0x8
v14:i64 = Load module_ctx, 0x18
v15:f32 = Load v14, 0x8
v16:i64 = Load module_ctx, 0x20
v17:f64 = Load v16, 0x8
Jump blk_ret, v3, v5, v7, v9, v11, v13, v15, v17
v6:i32 = Load module_ctx, 0x8
v7:i64 = Load module_ctx, 0x18
v8:f32 = Load module_ctx, 0x28
v9:f64 = Load module_ctx, 0x38
Jump blk_ret, v2, v3, v4, v5, v6, v7, v8, v9
`,
},
{
Expand Down
49 changes: 29 additions & 20 deletions internal/engine/wazevo/frontend/lower.go
Original file line number Diff line number Diff line change
Expand Up @@ -3459,21 +3459,25 @@ func (c *Compiler) reloadMemoryBaseLen() {
c.clearSafeBounds()
}

// globalInstanceValueOffset is the offsetOf .Value field of wasm.GlobalInstance.
const globalInstanceValueOffset = 8

func (c *Compiler) setWasmGlobalValue(index wasm.Index, v ssa.Value) {
variable := c.globalVariables[index]
instanceOffset := c.offset.GlobalInstanceOffset(index)
opaqueOffset := c.offset.GlobalInstanceOffset(index)

builder := c.ssaBuilder
loadGlobalInstPtr := builder.AllocateInstruction()
loadGlobalInstPtr.AsLoad(c.moduleCtxPtrValue, uint32(instanceOffset), ssa.TypeI64)
builder.InsertInstruction(loadGlobalInstPtr)
if index < c.m.ImportGlobalCount {
loadGlobalInstPtr := builder.AllocateInstruction()
loadGlobalInstPtr.AsLoad(c.moduleCtxPtrValue, uint32(opaqueOffset), ssa.TypeI64)
builder.InsertInstruction(loadGlobalInstPtr)

store := builder.AllocateInstruction()
store.AsStore(ssa.OpcodeStore, v, loadGlobalInstPtr.Return(), uint32(globalInstanceValueOffset))
builder.InsertInstruction(store)
store := builder.AllocateInstruction()
store.AsStore(ssa.OpcodeStore, v, loadGlobalInstPtr.Return(), uint32(0))
builder.InsertInstruction(store)

} else {
store := builder.AllocateInstruction()
store.AsStore(ssa.OpcodeStore, v, c.moduleCtxPtrValue, uint32(opaqueOffset))
builder.InsertInstruction(store)
}

// The value has changed to `v`, so we record it.
builder.DefineVariableInCurrentBB(variable, v)
Expand All @@ -3482,7 +3486,7 @@ func (c *Compiler) setWasmGlobalValue(index wasm.Index, v ssa.Value) {
func (c *Compiler) getWasmGlobalValue(index wasm.Index, forceLoad bool) ssa.Value {
variable := c.globalVariables[index]
typ := c.globalVariablesTypes[index]
instanceOffset := c.offset.GlobalInstanceOffset(index)
opaqueOffset := c.offset.GlobalInstanceOffset(index)

builder := c.ssaBuilder
if !forceLoad {
Expand All @@ -3491,16 +3495,21 @@ func (c *Compiler) getWasmGlobalValue(index wasm.Index, forceLoad bool) ssa.Valu
}
}

loadGlobalInstPtr := builder.AllocateInstruction()
loadGlobalInstPtr.AsLoad(c.moduleCtxPtrValue, uint32(instanceOffset), ssa.TypeI64)
builder.InsertInstruction(loadGlobalInstPtr)
var load *ssa.Instruction
if index < c.m.ImportGlobalCount {
loadGlobalInstPtr := builder.AllocateInstruction()
loadGlobalInstPtr.AsLoad(c.moduleCtxPtrValue, uint32(opaqueOffset), ssa.TypeI64)
builder.InsertInstruction(loadGlobalInstPtr)
load = builder.AllocateInstruction().
AsLoad(loadGlobalInstPtr.Return(), uint32(0), typ)
} else {
load = builder.AllocateInstruction().
AsLoad(c.moduleCtxPtrValue, uint32(opaqueOffset), typ)
}

load := builder.AllocateInstruction()
load.AsLoad(loadGlobalInstPtr.Return(), uint32(globalInstanceValueOffset), typ)
builder.InsertInstruction(load)
ret := load.Return()
builder.DefineVariableInCurrentBB(variable, ret)
return ret
v := load.Insert(builder).Return()
builder.DefineVariableInCurrentBB(variable, v)
return v
}

const (
Expand Down
2 changes: 0 additions & 2 deletions internal/engine/wazevo/frontend/lower_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ import (
)

func Test_Offsets(t *testing.T) {
var globalInstance wasm.GlobalInstance
require.Equal(t, int(unsafe.Offsetof(globalInstance.Val)), globalInstanceValueOffset)
var memInstance wasm.MemoryInstance
require.Equal(t, int(unsafe.Offsetof(memInstance.Buffer)), memoryInstanceBufOffset)
var tableInstance wasm.TableInstance
Expand Down
Loading

0 comments on commit 2762404

Please sign in to comment.