-
Notifications
You must be signed in to change notification settings - Fork 18k
cmd/compile: does not inline method of generic type across packages when there are multiple instantiations #59070
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
Comments
See #57505. Closing as a dup. |
I don't think this issue is same as #57505. And I found that if we remove the field f1 in b.Boo struct or remove the variable x in main, then go1.20 will do inline the method, but go1.19 or non-unified will not inline. b/b.go: package b
func Bar() {
var f1 Foo1[int]
f1.Run()
var f2 Foo2[int]
f2.Run()
}
type Boo struct {
f1 Foo1[int]
}
type Foo1[T any] struct {
}
func (*Foo1[T]) Run() {
}
type Foo2[T any] struct {
}
func (*Foo2[T]) Run() {
} main.go: package main
import "test/inlinegeneric/b"
func main() {
var x b.Boo
_ = x
b.Bar()
} go1.19.7 & go1.20 non-unified: None of the methods Run of Foo1[T] or Foo2[T] is inlined. $ go1.19.7 build --gcflags="-m=2" ./main.go
# command-line-arguments
./main.go:5:6: can inline main with cost 29 as: func() { var x b.Boo; x = <nil>; _ = x; b.Bar() }
./main.go:8:7: inlining call to b.Bar
./b/b.go:17:17: can inline b.(*Foo1[go.shape.int_0]).Run with cost 0 as: func(uintptr, *b.Foo1[go.shape.int_0]) { }
$ GOEXPERIMENT=nounified go1.20.2 build --gcflags="-m=2" ./main.go [0](0s)[14:35:03]
# command-line-arguments
./main.go:5:6: can inline main with cost 29 as: func() { var x b.Boo; x = <nil>; _ = x; b.Bar() }
./main.go:8:7: inlining call to b.Bar
./b/b.go:17:17: can inline b.(*Foo1[go.shape.int_0]).Run with cost 0 as: func(uintptr, *b.Foo1[go.shape.int_0]) { } go1.20: Only Foo1[T].Run is not inlined, Foo2[T].Run is inlined. And the difference between Foo1[T] and Foo2[T] is that Boo has a field of type Foo1[T] and Boo is used in main package. $ go1.20.2 build --gcflags="-m=2" ./main.go [146](38s)[14:35:00]
# command-line-arguments
./main.go:5:6: can inline main with cost 29 as: func() { x = <nil>; _ = x; b.Bar() }
./main.go:8:7: inlining call to b.Bar
./main.go:8:7: inlining call to b.(*Foo2[go.shape.int]).Run
./b/b.go:17:6: can inline b.(*Foo1[go.shape.int]).Run with cost 0 as: method(*b.Foo1[go.shape.int]) func(*[0]uintptr) { }
./b/b.go:17:6: can inline b.(*Foo1[int]).Run with cost 9 as: method(*b.Foo1[int]) func() { var .autotmp_0 *b.Foo1[int]; .autotmp_0 = <nil>; (*b.Foo1[go.shape.int]).Run(.autotmp_0, &b..dict.Foo1[int]) }
./b/b.go:17:6: inlining call to b.(*Foo1[go.shape.int]).Run |
Could you clarify which function(s) you expect to inline, but not? Is it
So, it sounds like the two instantiations of Also, it doesn't seem to require two levels of imports. Even if I put |
Yes, a.(*Foo1[go.shape.int]).Run is expected to be inlined into
Yes.
Yes, no need package |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
go.mod:
a/a.go:
b/b.go:
main.go:
go1.20.2 build --gcflags="-m=2" ./main.go
go1.19.7 build --gcflags="-m=2" ./main.go
What did you expect to see?
For go1.20.2:
For go1.19.7
What did you see instead?
For go1.20.2:
For go1.19.7
The text was updated successfully, but these errors were encountered: