Skip to content

Commit

Permalink
ssa: optimizes slice allocations (#2242)
Browse files Browse the repository at this point in the history
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 <t.y.mathetake@gmail.com>
  • Loading branch information
mathetake authored Jun 10, 2024
1 parent d059981 commit 5c8366f
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 14 deletions.
6 changes: 3 additions & 3 deletions internal/engine/wazevo/ssa/pass.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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() {
Expand Down
22 changes: 11 additions & 11 deletions internal/engine/wazevo/ssa/pass_cfg.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -233,21 +233,21 @@ 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.
st.eulerTour(b.entryBlk(), 0)
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
Expand All @@ -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<<j <= n; j++ {
Expand All @@ -293,7 +293,7 @@ func (dt *dominatorSparseTree) buildSparseTable() {
}

// rmq performs a range minimum query on the sparse table.
func (dt *dominatorSparseTree) rmq(l, r int) int {
func (dt *dominatorSparseTree) rmq(l, r int32) int32 {
table := dt.table
depth := dt.depth
j := int(math.Log2(float64(r - l + 1)))
Expand Down

0 comments on commit 5c8366f

Please sign in to comment.