Skip to content
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

ssa: memory usage optimization around lastDefinitions #2233

Merged
merged 1 commit into from
Jun 7, 2024
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
8 changes: 4 additions & 4 deletions internal/engine/wazevo/backend/backend_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -458,11 +458,11 @@ L2 (SSA Block: blk2):
name: "single_predecessor_local_refs", m: testcases.SinglePredecessorLocalRefs.Module,
afterLoweringARM64: `
L1 (SSA Block: blk0):
mov x132?, xzr
cbz w132?, (L2)
L3 (SSA Block: blk1):
mov x131?, xzr
mov x0, x131?
cbz w131?, (L2)
L3 (SSA Block: blk1):
mov x130?, xzr
mov x0, x130?
ret
L2 (SSA Block: blk2):
L4 (SSA Block: blk3):
Expand Down
21 changes: 1 addition & 20 deletions internal/engine/wazevo/frontend/frontend.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,26 +301,7 @@ func (c *Compiler) declareWasmLocals(entry ssa.BasicBlock) {
st := WasmTypeToSSAType(typ)
variable := c.ssaBuilder.DeclareVariable(st)
c.setWasmLocalVariable(wasm.Index(i)+localCount, variable)

zeroInst := c.ssaBuilder.AllocateInstruction()
switch st {
case ssa.TypeI32:
zeroInst.AsIconst32(0)
case ssa.TypeI64:
zeroInst.AsIconst64(0)
case ssa.TypeF32:
zeroInst.AsF32const(0)
case ssa.TypeF64:
zeroInst.AsF64const(0)
case ssa.TypeV128:
zeroInst.AsVconst(0, 0)
default:
panic("TODO: " + wasm.ValueTypeName(typ))
}

c.ssaBuilder.InsertInstruction(zeroInst)
value := zeroInst.Return()
c.ssaBuilder.DefineVariable(variable, value, entry)
c.ssaBuilder.InsertZeroValue(st)
}
}

Expand Down
7 changes: 2 additions & 5 deletions internal/engine/wazevo/frontend/frontend_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -375,13 +375,11 @@ blk3: () <-- (blk1)
exp: `
blk0: (exec_ctx:i64, module_ctx:i64)
v2:i32 = Iconst_32 0x0
v3:i32 = Iconst_32 0x0
v4:i32 = Iconst_32 0x0
Brz v2, blk2
Jump blk1

blk1: () <-- (blk0)
Return v4
Return v2

blk2: () <-- (blk0)
Jump blk3
Expand All @@ -392,12 +390,11 @@ blk3: () <-- (blk2)
expAfterPasses: `
blk0: (exec_ctx:i64, module_ctx:i64)
v2:i32 = Iconst_32 0x0
v4:i32 = Iconst_32 0x0
Brz v2, blk2
Jump fallthrough

blk1: () <-- (blk0)
Return v4
Return v2

blk2: () <-- (blk0)
Jump fallthrough
Expand Down
34 changes: 34 additions & 0 deletions internal/engine/wazevo/ssa/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,11 @@ type Builder interface {
// Idom returns the immediate dominator of the given BasicBlock.
Idom(blk BasicBlock) BasicBlock

// VarLengthPool returns the VarLengthPool of Value.
VarLengthPool() *wazevoapi.VarLengthPool[Value]

// InsertZeroValue inserts a zero value constant instruction of the given type.
InsertZeroValue(t Type)
}

// NewBuilder returns a new Builder implementation.
Expand Down Expand Up @@ -203,6 +207,32 @@ type builder struct {
donePostBlockLayoutPasses bool

currentSourceOffset SourceOffset

// zeros are the zero value constants for each type.
zeros [typeEnd]Value
}

// InsertZeroValue implements Builder.InsertZeroValue.
func (b *builder) InsertZeroValue(t Type) {
if b.zeros[t].Valid() {
return
}
zeroInst := b.AllocateInstruction()
switch t {
case TypeI32:
zeroInst.AsIconst32(0)
case TypeI64:
zeroInst.AsIconst64(0)
case TypeF32:
zeroInst.AsF32const(0)
case TypeF64:
zeroInst.AsF64const(0)
case TypeV128:
zeroInst.AsVconst(0, 0)
default:
panic("TODO: " + t.String())
}
b.zeros[t] = zeroInst.Insert(b).Return()
}

func (b *builder) VarLengthPool() *wazevoapi.VarLengthPool[Value] {
Expand All @@ -218,6 +248,7 @@ func (b *builder) ReturnBlock() BasicBlock {
func (b *builder) Init(s *Signature) {
b.nextVariable = 0
b.currentSignature = s
b.zeros = [typeEnd]Value{ValueInvalid, ValueInvalid, ValueInvalid, ValueInvalid, ValueInvalid, ValueInvalid}
resetBasicBlock(b.returnBlk)
b.instructionsPool.Reset()
b.basicBlocksPool.Reset()
Expand Down Expand Up @@ -486,6 +517,9 @@ func (b *builder) findValue(typ Type, variable Variable, blk *basicBlock) Value
value: value,
})
return value
} else if blk.EntryBlock() {
// If this is the entry block, we reach the uninitialized variable which has zero value.
return b.zeros[b.definedVariableType(variable)]
}

if pred := blk.singlePred; pred != nil {
Expand Down
3 changes: 3 additions & 0 deletions internal/engine/wazevo/ssa/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ const (

// TypeV128 represents 128-bit SIMD vectors.
TypeV128

// -- Do not add new types after this line. ----
typeEnd
)

// String implements fmt.Stringer.
Expand Down
Loading