Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/compile: stringtoslicebytetmp optimization on unescaped slice #38501

Closed
tdakkota opened this issue Apr 17, 2020 · 3 comments
Closed

cmd/compile: stringtoslicebytetmp optimization on unescaped slice #38501

tdakkota opened this issue Apr 17, 2020 · 3 comments

Comments

@tdakkota
Copy link

@tdakkota tdakkota commented Apr 17, 2020

What version of Go are you using (go version)?

$ go version
go version go1.14 linux/amd64

Does this issue reproduce with the latest release?

yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/tdakkota/.cache/go-build"
GOENV="/home/tdakkota/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/tdakkota/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build263265353=/tmp/go-build -gno-record-gcc-switches"

What did you do?

https://play.golang.org/p/kSKRNgYnQCS

package main

import (
	"fmt"
)

func allocme(n int) string {
	arr := make([]byte, n) // first allocation
	for i := 0; i < n; i++ {
		arr[i] = byte(i + 97)
	}
	return string(arr) // second allocation + copy
}

func main() {
	fmt.Println(allocme(25))
}

Then run with gc's flag -S

$ go build -gcflags "-S" main.go
Output
"".allocme STEXT size=161 args=0x18 locals=0x38
	0x0000 00000 (/home/tdakkota/workspace/expirm/main.go:7)	TEXT	"".allocme(SB), ABIInternal, $56-24
	0x0000 00000 (/home/tdakkota/workspace/expirm/main.go:7)	MOVQ	(TLS), CX
	0x0009 00009 (/home/tdakkota/workspace/expirm/main.go:7)	CMPQ	SP, 16(CX)
	0x000d 00013 (/home/tdakkota/workspace/expirm/main.go:7)	PCDATA	$0, $-2
	0x000d 00013 (/home/tdakkota/workspace/expirm/main.go:7)	JLS	151
	0x0013 00019 (/home/tdakkota/workspace/expirm/main.go:7)	PCDATA	$0, $-1
	0x0013 00019 (/home/tdakkota/workspace/expirm/main.go:7)	SUBQ	$56, SP
	0x0017 00023 (/home/tdakkota/workspace/expirm/main.go:7)	MOVQ	BP, 48(SP)
	0x001c 00028 (/home/tdakkota/workspace/expirm/main.go:7)	LEAQ	48(SP), BP
	0x0021 00033 (/home/tdakkota/workspace/expirm/main.go:7)	PCDATA	$0, $-2
	0x0021 00033 (/home/tdakkota/workspace/expirm/main.go:7)	PCDATA	$1, $-2
	0x0021 00033 (/home/tdakkota/workspace/expirm/main.go:7)	FUNCDATA	$0, gclocals·568470801006e5c0dc3947ea998fe279(SB)
	0x0021 00033 (/home/tdakkota/workspace/expirm/main.go:7)	FUNCDATA	$1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
	0x0021 00033 (/home/tdakkota/workspace/expirm/main.go:7)	FUNCDATA	$2, gclocals·1cf923758aae2e428391d1783fe59973(SB)
	0x0021 00033 (/home/tdakkota/workspace/expirm/main.go:8)	PCDATA	$0, $1
	0x0021 00033 (/home/tdakkota/workspace/expirm/main.go:8)	PCDATA	$1, $0
	0x0021 00033 (/home/tdakkota/workspace/expirm/main.go:8)	LEAQ	type.uint8(SB), AX
	0x0028 00040 (/home/tdakkota/workspace/expirm/main.go:8)	PCDATA	$0, $0
	0x0028 00040 (/home/tdakkota/workspace/expirm/main.go:8)	MOVQ	AX, (SP)
	0x002c 00044 (/home/tdakkota/workspace/expirm/main.go:8)	MOVQ	"".n+64(SP), AX
	0x0031 00049 (/home/tdakkota/workspace/expirm/main.go:8)	MOVQ	AX, 8(SP)
	0x0036 00054 (/home/tdakkota/workspace/expirm/main.go:8)	MOVQ	AX, 16(SP)
	0x003b 00059 (/home/tdakkota/workspace/expirm/main.go:8)	CALL	runtime.makeslice(SB)
	0x0040 00064 (/home/tdakkota/workspace/expirm/main.go:8)	PCDATA	$0, $1
	0x0040 00064 (/home/tdakkota/workspace/expirm/main.go:8)	MOVQ	24(SP), AX
	0x0045 00069 (/home/tdakkota/workspace/expirm/main.go:10)	MOVQ	"".n+64(SP), CX
	0x004a 00074 (/home/tdakkota/workspace/expirm/main.go:10)	XORL	DX, DX
	0x004c 00076 (/home/tdakkota/workspace/expirm/main.go:10)	JMP	88
	0x004e 00078 (/home/tdakkota/workspace/expirm/main.go:11)	LEAQ	97(DX), BX
	0x0052 00082 (/home/tdakkota/workspace/expirm/main.go:11)	MOVB	BL, (AX)(DX*1)
	0x0055 00085 (/home/tdakkota/workspace/expirm/main.go:10)	INCQ	DX
	0x0058 00088 (/home/tdakkota/workspace/expirm/main.go:10)	CMPQ	DX, CX
	0x005b 00091 (/home/tdakkota/workspace/expirm/main.go:10)	JLT	78
	0x005d 00093 (/home/tdakkota/workspace/expirm/main.go:14)	MOVQ	$0, (SP)
	0x0065 00101 (/home/tdakkota/workspace/expirm/main.go:14)	PCDATA	$0, $0
	0x0065 00101 (/home/tdakkota/workspace/expirm/main.go:14)	MOVQ	AX, 8(SP)
	0x006a 00106 (/home/tdakkota/workspace/expirm/main.go:14)	MOVQ	CX, 16(SP)
	0x006f 00111 (/home/tdakkota/workspace/expirm/main.go:14)	MOVQ	CX, 24(SP)
	0x0074 00116 (/home/tdakkota/workspace/expirm/main.go:14)	CALL	runtime.slicebytetostring(SB)
	0x0079 00121 (/home/tdakkota/workspace/expirm/main.go:14)	MOVQ	40(SP), AX
	0x007e 00126 (/home/tdakkota/workspace/expirm/main.go:14)	PCDATA	$0, $2
	0x007e 00126 (/home/tdakkota/workspace/expirm/main.go:14)	MOVQ	32(SP), CX
	0x0083 00131 (/home/tdakkota/workspace/expirm/main.go:14)	PCDATA	$0, $0
	0x0083 00131 (/home/tdakkota/workspace/expirm/main.go:14)	PCDATA	$1, $1
	0x0083 00131 (/home/tdakkota/workspace/expirm/main.go:14)	MOVQ	CX, "".~r1+72(SP)
	0x0088 00136 (/home/tdakkota/workspace/expirm/main.go:14)	MOVQ	AX, "".~r1+80(SP)
	0x008d 00141 (/home/tdakkota/workspace/expirm/main.go:14)	MOVQ	48(SP), BP
	0x0092 00146 (/home/tdakkota/workspace/expirm/main.go:14)	ADDQ	$56, SP
	0x0096 00150 (/home/tdakkota/workspace/expirm/main.go:14)	RET
	0x0097 00151 (/home/tdakkota/workspace/expirm/main.go:14)	NOP
	0x0097 00151 (/home/tdakkota/workspace/expirm/main.go:7)	PCDATA	$1, $-1
	0x0097 00151 (/home/tdakkota/workspace/expirm/main.go:7)	PCDATA	$0, $-2
	0x0097 00151 (/home/tdakkota/workspace/expirm/main.go:7)	CALL	runtime.morestack_noctxt(SB)
	0x009c 00156 (/home/tdakkota/workspace/expirm/main.go:7)	PCDATA	$0, $-1
	0x009c 00156 (/home/tdakkota/workspace/expirm/main.go:7)	JMP	0

What did you expect to see?

One allocation at all.
arr does not escape, so we can use runtime.slicebytetostringtmp instead of runtime.slicebytetostring

What did you see instead?

Two allocation and copying,

@mvdan
Copy link
Member

@mvdan mvdan commented Apr 17, 2020

Did you mean make([]byte, n)? The code you shared doesn't compile.

@tdakkota
Copy link
Author

@tdakkota tdakkota commented Apr 17, 2020

Yes, it should be []byte.
Fixed.

@randall77
Copy link
Contributor

@randall77 randall77 commented Apr 17, 2020

Closing as dup of #6714.

@randall77 randall77 closed this Apr 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants
You can’t perform that action at this time.