• Josh Bleecher Snyder's avatar
    cmd/compile: avoid write barrier in append fast path · a4650a21
    Josh Bleecher Snyder authored
    When we are writing the result of an append back
    to the same slice, we don’t need a write barrier
    on the fast path.
    
    This re-implements an optimization that was present
    in the old backend.
    
    Updates #14921
    Fixes #14969
    
    Sample code:
    
    var x []byte
    
    func p() {
    	x = append(x, 1, 2, 3)
    }
    
    Before:
    
    "".p t=1 size=224 args=0x0 locals=0x48
    	0x0000 00000 (append.go:21)	TEXT	"".p(SB), $72-0
    	0x0000 00000 (append.go:21)	MOVQ	(TLS), CX
    	0x0009 00009 (append.go:21)	CMPQ	SP, 16(CX)
    	0x000d 00013 (append.go:21)	JLS	199
    	0x0013 00019 (append.go:21)	SUBQ	$72, SP
    	0x0017 00023 (append.go:21)	FUNCDATA	$0, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
    	0x0017 00023 (append.go:21)	FUNCDATA	$1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
    	0x0017 00023 (append.go:19)	MOVQ	"".x+16(SB), CX
    	0x001e 00030 (append.go:19)	MOVQ	"".x(SB), DX
    	0x0025 00037 (append.go:19)	MOVQ	"".x+8(SB), BX
    	0x002c 00044 (append.go:19)	MOVQ	BX, "".autotmp_0+64(SP)
    	0x0031 00049 (append.go:22)	LEAQ	3(BX), BP
    	0x0035 00053 (append.go:22)	CMPQ	BP, CX
    	0x0038 00056 (append.go:22)	JGT	$0, 131
    	0x003a 00058 (append.go:22)	MOVB	$1, (DX)(BX*1)
    	0x003e 00062 (append.go:22)	MOVB	$2, 1(DX)(BX*1)
    	0x0043 00067 (append.go:22)	MOVB	$3, 2(DX)(BX*1)
    	0x0048 00072 (append.go:22)	MOVQ	BP, "".x+8(SB)
    	0x004f 00079 (append.go:22)	MOVQ	CX, "".x+16(SB)
    	0x0056 00086 (append.go:22)	MOVL	runtime.writeBarrier(SB), AX
    	0x005c 00092 (append.go:22)	TESTB	AL, AL
    	0x005e 00094 (append.go:22)	JNE	$0, 108
    	0x0060 00096 (append.go:22)	MOVQ	DX, "".x(SB)
    	0x0067 00103 (append.go:23)	ADDQ	$72, SP
    	0x006b 00107 (append.go:23)	RET
    	0x006c 00108 (append.go:22)	LEAQ	"".x(SB), CX
    	0x0073 00115 (append.go:22)	MOVQ	CX, (SP)
    	0x0077 00119 (append.go:22)	MOVQ	DX, 8(SP)
    	0x007c 00124 (append.go:22)	PCDATA	$0, $0
    	0x007c 00124 (append.go:22)	CALL	runtime.writebarrierptr(SB)
    	0x0081 00129 (append.go:23)	JMP	103
    	0x0083 00131 (append.go:22)	LEAQ	type.[]uint8(SB), AX
    	0x008a 00138 (append.go:22)	MOVQ	AX, (SP)
    	0x008e 00142 (append.go:22)	MOVQ	DX, 8(SP)
    	0x0093 00147 (append.go:22)	MOVQ	BX, 16(SP)
    	0x0098 00152 (append.go:22)	MOVQ	CX, 24(SP)
    	0x009d 00157 (append.go:22)	MOVQ	BP, 32(SP)
    	0x00a2 00162 (append.go:22)	PCDATA	$0, $0
    	0x00a2 00162 (append.go:22)	CALL	runtime.growslice(SB)
    	0x00a7 00167 (append.go:22)	MOVQ	40(SP), DX
    	0x00ac 00172 (append.go:22)	MOVQ	48(SP), AX
    	0x00b1 00177 (append.go:22)	MOVQ	56(SP), CX
    	0x00b6 00182 (append.go:22)	ADDQ	$3, AX
    	0x00ba 00186 (append.go:19)	MOVQ	"".autotmp_0+64(SP), BX
    	0x00bf 00191 (append.go:22)	MOVQ	AX, BP
    	0x00c2 00194 (append.go:22)	JMP	58
    	0x00c7 00199 (append.go:22)	NOP
    	0x00c7 00199 (append.go:21)	CALL	runtime.morestack_noctxt(SB)
    	0x00cc 00204 (append.go:21)	JMP	0
    
    After:
    
    "".p t=1 size=208 args=0x0 locals=0x48
    	0x0000 00000 (append.go:21)	TEXT	"".p(SB), $72-0
    	0x0000 00000 (append.go:21)	MOVQ	(TLS), CX
    	0x0009 00009 (append.go:21)	CMPQ	SP, 16(CX)
    	0x000d 00013 (append.go:21)	JLS	191
    	0x0013 00019 (append.go:21)	SUBQ	$72, SP
    	0x0017 00023 (append.go:21)	FUNCDATA	$0, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
    	0x0017 00023 (append.go:21)	FUNCDATA	$1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
    	0x0017 00023 (append.go:19)	MOVQ	"".x+16(SB), CX
    	0x001e 00030 (append.go:19)	MOVQ	"".x+8(SB), DX
    	0x0025 00037 (append.go:19)	MOVQ	DX, "".autotmp_0+64(SP)
    	0x002a 00042 (append.go:19)	MOVQ	"".x(SB), BX
    	0x0031 00049 (append.go:22)	LEAQ	3(DX), BP
    	0x0035 00053 (append.go:22)	MOVQ	BP, "".x+8(SB)
    	0x003c 00060 (append.go:22)	CMPQ	BP, CX
    	0x003f 00063 (append.go:22)	JGT	$0, 84
    	0x0041 00065 (append.go:22)	MOVB	$1, (BX)(DX*1)
    	0x0045 00069 (append.go:22)	MOVB	$2, 1(BX)(DX*1)
    	0x004a 00074 (append.go:22)	MOVB	$3, 2(BX)(DX*1)
    	0x004f 00079 (append.go:23)	ADDQ	$72, SP
    	0x0053 00083 (append.go:23)	RET
    	0x0054 00084 (append.go:22)	LEAQ	type.[]uint8(SB), AX
    	0x005b 00091 (append.go:22)	MOVQ	AX, (SP)
    	0x005f 00095 (append.go:22)	MOVQ	BX, 8(SP)
    	0x0064 00100 (append.go:22)	MOVQ	DX, 16(SP)
    	0x0069 00105 (append.go:22)	MOVQ	CX, 24(SP)
    	0x006e 00110 (append.go:22)	MOVQ	BP, 32(SP)
    	0x0073 00115 (append.go:22)	PCDATA	$0, $0
    	0x0073 00115 (append.go:22)	CALL	runtime.growslice(SB)
    	0x0078 00120 (append.go:22)	MOVQ	40(SP), CX
    	0x007d 00125 (append.go:22)	MOVQ	56(SP), AX
    	0x0082 00130 (append.go:22)	MOVQ	AX, "".x+16(SB)
    	0x0089 00137 (append.go:22)	MOVL	runtime.writeBarrier(SB), AX
    	0x008f 00143 (append.go:22)	TESTB	AL, AL
    	0x0091 00145 (append.go:22)	JNE	$0, 168
    	0x0093 00147 (append.go:22)	MOVQ	CX, "".x(SB)
    	0x009a 00154 (append.go:22)	MOVQ	"".x(SB), BX
    	0x00a1 00161 (append.go:19)	MOVQ	"".autotmp_0+64(SP), DX
    	0x00a6 00166 (append.go:22)	JMP	65
    	0x00a8 00168 (append.go:22)	LEAQ	"".x(SB), DX
    	0x00af 00175 (append.go:22)	MOVQ	DX, (SP)
    	0x00b3 00179 (append.go:22)	MOVQ	CX, 8(SP)
    	0x00b8 00184 (append.go:22)	PCDATA	$0, $0
    	0x00b8 00184 (append.go:22)	CALL	runtime.writebarrierptr(SB)
    	0x00bd 00189 (append.go:22)	JMP	154
    	0x00bf 00191 (append.go:22)	NOP
    	0x00bf 00191 (append.go:21)	CALL	runtime.morestack_noctxt(SB)
    	0x00c4 00196 (append.go:21)	JMP	0
    
    Change-Id: I77a41ad3a22557a4bb4654de7d6d24a029efe34a
    Reviewed-on: https://go-review.googlesource.com/21813
    
    
    Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
    TryBot-Result: Gobot Gobot <gobot@golang.org>
    Reviewed-by: default avatarKeith Randall <khr@golang.org>
    a4650a21
ssa.go 132 KB