1
0
mirror of https://github.com/golang/go synced 2024-11-23 13:00:07 -07:00

cmd/compile: optimize ssa if blocks for wasm architecture

Check for the next block and accordingly place the successor blocks.
This saves an additional jump instruction if the next block is any one
of the successor blocks.

While at it, inline the logic of goToBlock.

Reduces the size of pkg/js_wasm by 264 bytes.

Change-Id: I671ac4322e6edcb0d7e590dcca27e074268068d5
Reviewed-on: https://go-review.googlesource.com/c/go/+/195204
Run-TryBot: Agniva De Sarker <agniva.quicksilver@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Richard Musiol <neelance@gmail.com>
This commit is contained in:
Agniva De Sarker 2019-09-14 20:58:30 +05:30 committed by Agniva De Sarker
parent f1b6d1016e
commit 9c384cc570

View File

@ -68,24 +68,35 @@ func ssaMarkMoves(s *gc.SSAGenState, b *ssa.Block) {
} }
func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) { func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
goToBlock := func(block *ssa.Block, canFallthrough bool) {
if canFallthrough && block == next {
return
}
s.Br(obj.AJMP, block)
}
switch b.Kind { switch b.Kind {
case ssa.BlockPlain: case ssa.BlockPlain:
goToBlock(b.Succs[0].Block(), true) if next != b.Succs[0].Block() {
s.Br(obj.AJMP, b.Succs[0].Block())
}
case ssa.BlockIf: case ssa.BlockIf:
getValue32(s, b.Control) switch next {
s.Prog(wasm.AI32Eqz) case b.Succs[0].Block():
s.Prog(wasm.AIf) // if false, jump to b.Succs[1]
goToBlock(b.Succs[1].Block(), false) getValue32(s, b.Control)
s.Prog(wasm.AEnd) s.Prog(wasm.AI32Eqz)
goToBlock(b.Succs[0].Block(), true) s.Prog(wasm.AIf)
s.Br(obj.AJMP, b.Succs[1].Block())
s.Prog(wasm.AEnd)
case b.Succs[1].Block():
// if true, jump to b.Succs[0]
getValue32(s, b.Control)
s.Prog(wasm.AIf)
s.Br(obj.AJMP, b.Succs[0].Block())
s.Prog(wasm.AEnd)
default:
// if true, jump to b.Succs[0], else jump to b.Succs[1]
getValue32(s, b.Control)
s.Prog(wasm.AIf)
s.Br(obj.AJMP, b.Succs[0].Block())
s.Prog(wasm.AEnd)
s.Br(obj.AJMP, b.Succs[1].Block())
}
case ssa.BlockRet: case ssa.BlockRet:
s.Prog(obj.ARET) s.Prog(obj.ARET)
@ -104,9 +115,11 @@ func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
s.Prog(wasm.AI64Eqz) s.Prog(wasm.AI64Eqz)
s.Prog(wasm.AI32Eqz) s.Prog(wasm.AI32Eqz)
s.Prog(wasm.AIf) s.Prog(wasm.AIf)
goToBlock(b.Succs[1].Block(), false) s.Br(obj.AJMP, b.Succs[1].Block())
s.Prog(wasm.AEnd) s.Prog(wasm.AEnd)
goToBlock(b.Succs[0].Block(), true) if next != b.Succs[0].Block() {
s.Br(obj.AJMP, b.Succs[0].Block())
}
default: default:
panic("unexpected block") panic("unexpected block")