Closed
Description
The ssa back end does not eliminate as many write barriers as the non-ssa back end. This should be fixed. I thought there were tests of this. Were they disabled?
In particular, reslicing an addressable slice with low index 0 should not rewrite the pointer (or the cap, usually), and not rewriting the pointer will avoid the expense of a write barrier.
Test program:
package p
func f(x *[]byte) []byte {
*x = (*x)[:8]
g()
return *x
}
func g()
Without ssa:
0x0020 00032 (/tmp/x.go:4) MOVQ "".x+8(FP), BX
0x0025 00037 (/tmp/x.go:4) NOP
0x0025 00037 (/tmp/x.go:4) MOVQ 16(BX), BP
0x0029 00041 (/tmp/x.go:4) CMPQ BP, $8
0x002d 00045 (/tmp/x.go:4) JCS $0, 102
0x002f 00047 (/tmp/x.go:4) MOVQ $8, 8(BX)
With ssa:
0x0013 00019 (/tmp/x.go:4) MOVQ "".x+24(FP), CX
0x0018 00024 (/tmp/x.go:4) MOVQ (CX), DX
0x001b 00027 (/tmp/x.go:4) MOVQ 16(CX), BX
0x001f 00031 (/tmp/x.go:4) CMPQ BX, $8
0x0023 00035 (/tmp/x.go:4) JCS $0, 130
0x0025 00037 (/tmp/x.go:4) CMPQ BX, $0
0x0029 00041 (/tmp/x.go:4) JEQ $0, 43
0x002b 00043 (/tmp/x.go:4) MOVQ $8, 8(CX)
0x0033 00051 (/tmp/x.go:4) MOVQ BX, 16(CX) << rewritine slice cap
0x0037 00055 (/tmp/x.go:4) MOVL runtime.writeBarrier(SB), AX
0x003d 00061 (/tmp/x.go:4) TESTB AL, AL
0x003f 00063 (/tmp/x.go:4) JNE $0, 109
0x0041 00065 (/tmp/x.go:4) MOVQ DX, (CX) << rewriting slice base ptr
If I remember correctly, the optimization in the non-ssa back end applies to any expression of the form thing = thing[:n], where thing can be arbitrarily long, provided its the same on both sides, has no idempotency problems (like function calls), and is addressable.
/cc @randall77 @dr2chase