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: optimize redundant iface->iface type assertions #41174

Open
quasilyte opened this issue Sep 2, 2020 · 3 comments
Open

cmd/compile: optimize redundant iface->iface type assertions #41174

quasilyte opened this issue Sep 2, 2020 · 3 comments

Comments

@quasilyte
Copy link
Contributor

@quasilyte quasilyte commented Sep 2, 2020

See https://go-review.googlesource.com/c/go/+/247478

For the real-world cases see https://github.com/VKCOM/noverify/blob/77ed62ed18e976f619031a5c828ea1f4b49c15ba/src/ir/irutil/clone.go#L219

That code was initially auto-generated, but it has a minor problem: it did F().(T) even in cases where F() already returns T. This is not a big problem, but since this optimization is so simple to implement in the compiler, maybe we can do it?

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

$ go version

go version devel +5c7748dc9d Mon Aug 10 23:44:58 2020 +0000 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/isharipov/.cache/go-build"
GOENV="/home/isharipov/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/home/isharipov/CODE/go/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/home/isharipov/CODE/go/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
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-build237409555=/tmp/go-build -gno-record-gcc-switches"

What did you do?

Compile this program:

package foo

import "io"

func example1(x io.Reader) io.Reader {
	return x
}

func example2(x io.Reader) io.Reader {
	return x.(io.Reader)
}

What did you expect to see?

Both example1 and example2 compiled to the same (efficient) code without type assertions.

What did you see instead?

example1 produces the type assertion CALL runtime.assertI2I(SB) (and a lot of code around it, as expected).

@randall77
Copy link
Contributor

@randall77 randall77 commented Sep 2, 2020

Note that example2 should panic when x is nil, whereas example1 shouldn't.

@randall77 randall77 added this to the Unplanned milestone Sep 2, 2020
@quasilyte
Copy link
Contributor Author

@quasilyte quasilyte commented Sep 2, 2020

Hmm. This is subtle detail I missed. We can close this issue (and CL) if this rewrite violates the correctness (it looks like it does).

@randall77
Copy link
Contributor

@randall77 randall77 commented Sep 2, 2020

It does, although nil checking you could do in a cheaper way than calling assertI2I. Although probably not much cheaper - assertI2I does the nil check and the identity-interface-conversion check first thing.

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
4 participants
You can’t perform that action at this time.