From 5c8366f8d5f8f8e355c241c423b254eb1c10b02b Mon Sep 17 00:00:00 2001 From: Takeshi Yoneda Date: Mon, 10 Jun 2024 08:25:29 -0700 Subject: [PATCH] ssa: optimizes slice allocations (#2242) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes the compilation faster and use less memory: ``` goos: darwin goarch: arm64 pkg: github.com/tetratelabs/wazero │ old.txt │ new.txt │ │ sec/op │ sec/op vs base │ Compilation/wazero-10 2.184 ± 0% 2.110 ± 0% -3.40% (p=0.001 n=7) Compilation/zig-10 4.331 ± 1% 4.187 ± 1% -3.31% (p=0.001 n=7) geomean 3.075 2.972 -3.36% │ old.txt │ new.txt │ │ B/op │ B/op vs base │ Compilation/wazero-10 337.3Mi ± 0% 301.9Mi ± 0% -10.49% (p=0.001 n=7) Compilation/zig-10 599.3Mi ± 0% 594.3Mi ± 0% -0.84% (p=0.001 n=7) geomean 449.6Mi 423.6Mi -5.79% │ old.txt │ new.txt │ │ allocs/op │ allocs/op vs base │ Compilation/wazero-10 592.9k ± 0% 527.9k ± 0% -10.97% (p=0.001 n=7) Compilation/zig-10 287.8k ± 0% 278.6k ± 0% -3.20% (p=0.001 n=7) geomean 413.1k 383.5k -7.17% ``` Signed-off-by: Takeshi Yoneda --- internal/engine/wazevo/ssa/pass.go | 6 +++--- internal/engine/wazevo/ssa/pass_cfg.go | 22 +++++++++++----------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/internal/engine/wazevo/ssa/pass.go b/internal/engine/wazevo/ssa/pass.go index e3ba4075df..89ec34b7eb 100644 --- a/internal/engine/wazevo/ssa/pass.go +++ b/internal/engine/wazevo/ssa/pass.go @@ -232,10 +232,10 @@ func passRedundantPhiEliminationOpt(b *builder) { func passDeadCodeEliminationOpt(b *builder) { nvid := int(b.nextValueID) if nvid >= len(b.valueRefCounts) { - b.valueRefCounts = append(b.valueRefCounts, make([]int, b.nextValueID)...) + b.valueRefCounts = append(b.valueRefCounts, make([]int, nvid-len(b.valueRefCounts)+1)...) } if nvid >= len(b.valueIDToInstruction) { - b.valueIDToInstruction = append(b.valueIDToInstruction, make([]*Instruction, b.nextValueID)...) + b.valueIDToInstruction = append(b.valueIDToInstruction, make([]*Instruction, nvid-len(b.valueIDToInstruction)+1)...) } // First, we gather all the instructions with side effects. @@ -358,7 +358,7 @@ func (b *builder) incRefCount(id ValueID, from *Instruction) { // passNopInstElimination eliminates the instructions which is essentially a no-op. func passNopInstElimination(b *builder) { if int(b.nextValueID) >= len(b.valueIDToInstruction) { - b.valueIDToInstruction = append(b.valueIDToInstruction, make([]*Instruction, b.nextValueID)...) + b.valueIDToInstruction = append(b.valueIDToInstruction, make([]*Instruction, int(b.nextValueID)-len(b.valueIDToInstruction)+1)...) } for blk := b.blockIteratorBegin(); blk != nil; blk = b.blockIteratorNext() { diff --git a/internal/engine/wazevo/ssa/pass_cfg.go b/internal/engine/wazevo/ssa/pass_cfg.go index 109438ad75..e8288c4bd3 100644 --- a/internal/engine/wazevo/ssa/pass_cfg.go +++ b/internal/engine/wazevo/ssa/pass_cfg.go @@ -203,10 +203,10 @@ func printLoopNestingForest(root *basicBlock, depth int) { } type dominatorSparseTree struct { - time int + time int32 euler []*basicBlock - first, depth []int - table [][]int + first, depth []int32 + table [][]int32 } // passBuildDominatorTree builds the dominator tree for the function, and constructs builder.sparseTree. @@ -233,11 +233,11 @@ func passBuildDominatorTree(b *builder) { n := b.basicBlocksPool.Allocated() st := &b.sparseTree st.euler = append(st.euler[:0], make([]*basicBlock, 2*n-1)...) - st.first = append(st.first[:0], make([]int, n)...) + st.first = append(st.first[:0], make([]int32, n)...) for i := range st.first { st.first[i] = -1 } - st.depth = append(st.depth[:0], make([]int, 2*n-1)...) + st.depth = append(st.depth[:0], make([]int32, 2*n-1)...) st.time = 0 // Start building the sparse tree. @@ -245,9 +245,9 @@ func passBuildDominatorTree(b *builder) { st.buildSparseTable() } -func (dt *dominatorSparseTree) eulerTour(node *basicBlock, height int) { +func (dt *dominatorSparseTree) eulerTour(node *basicBlock, height int32) { if wazevoapi.SSALoggingEnabled { - fmt.Println(strings.Repeat("\t", height), "euler tour:", node.ID()) + fmt.Println(strings.Repeat("\t", int(height)), "euler tour:", node.ID()) } dt.euler[dt.time] = node dt.depth[dt.time] = height @@ -271,13 +271,13 @@ func (dt *dominatorSparseTree) buildSparseTable() { table := dt.table if n >= len(table) { - table = append(table, make([][]int, n+1)...) + table = append(table, make([][]int32, n-len(table)+1)...) } for i := range table { if len(table[i]) < k { - table[i] = append(table[i], make([]int, k)...) + table[i] = append(table[i], make([]int32, k-len(table[i]))...) } - table[i][0] = i + table[i][0] = int32(i) } for j := 1; 1<