When I build the following program with go1.5.1 on windows_amd64
package main
import "strings"
func Split1(textnl string) (a, b, c string) {
fields := strings.Fields(textnl)
return fields[2], fields[1], fields[0]
}
func Split2(textnl string) (string, string, string) {
fields := strings.Fields(textnl)
return fields[2], fields[1], fields[0]
}
func main() {
Split1("")
Split2("")
}
and then disassemble it using `objdump`, there are some unnecessary instructions in the code.
TEXT main.Split1(SB)
main.go:5 GS MOVQ GS:0x28, CX
main.go:5 MOVQ 0(CX), CX
main.go:5 CMPQ 0x10(CX), SP
main.go:5 JBE 0x40111c
main.go:5 SUBQ $0x28, SP
main.go:5 XORL BX, BX
main.go:5 XORL BX, BX
main.go:5 XORL BX, BX
main.go:5 XORL BX, BX
main.go:5 MOVQ BX, 0x60(SP)
main.go:5 MOVQ BX, 0x68(SP)
main.go:5 XORL BX, BX
main.go:5 MOVQ BX, 0x50(SP)
main.go:5 MOVQ BX, 0x58(SP)
main.go:5 XORL BX, BX
main.go:5 MOVQ BX, 0x40(SP)
main.go:5 MOVQ BX, 0x48(SP)
main.go:7 CMPQ $0x1, AX
main.go:7 JBE out_of_bounds1
main.go:7 ...
main.go:7 CMPQ $0x0, AX
main.go:7 JBE out_of_bounds2
main.go:7 ...
main.go:7 CMPQ $0x2, AX
main.go:7 JBE out_of_bounds3
1. The second paragraph contains one XORL for every named return value. All these instructions don’t have any practical effect, since the value in BX is never used after that. (This only happens for named return values; Split2 doesn’t have these extra instructions.)
2. The third paragraph also contains unnecessary XORL instructions (all but the first one), but I can understand that these keep the code generation code clean and simple.
3. In the fourth paragraph, the three comparisons could be merged into one, saving 4 instructions plus the error handling code at the end of the function.
Are there any plans to avoid these unnecessary instructions? The resulting binaries would become significantly(?) smaller, which benefits everyone.
Roland