Skip to content

cmd/compile: does not inline method of generic type across packages when there are multiple instantiations #59070

Open
@578559967

Description

@578559967

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

$ go version
go version go1.20.2 darwin/arm64

Does this issue reproduce with the latest release?

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

go env Output
$ go env
GO111MODULE=""
GOARCH="arm64"
GOBIN=""
GOCACHE="/Users/r/Library/Caches/go-build"
GOENV="/Users/r/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="arm64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/r/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/r/go"
GOPRIVATE=""
GOPROXY="https://goproxy.cn,direct"
GOROOT="/Users/r/sdk/go1.20.2"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/Users/r/sdk/go1.20.2/pkg/tool/darwin_arm64"
GOVCS=""
GOVERSION="go1.20.2"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/r/workspace/testcode/testinlinegeneric/go.mod"
GOWORK=""
CGO_CFLAGS="-O2 -g"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-O2 -g"
CGO_FFLAGS="-O2 -g"
CGO_LDFLAGS="-O2 -g"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/j_/rq9ph2cd3h50w468sgv34lwh0000gn/T/go-build2389814434=/tmp/go-build -gno-record-gcc-switches -fno-common"
GOROOT/bin/go version: go version go1.20.2 darwin/arm64
GOROOT/bin/go tool compile -V: compile version go1.20.2
uname -v: Darwin Kernel Version 22.3.0: Mon Jan 30 20:38:37 PST 2023; root:xnu-8792.81.3~2/RELEASE_ARM64_T6000
ProductName:		macOS
ProductVersion:		13.2.1
BuildVersion:		22D68
lldb --version: lldb-1400.0.38.17
Apple Swift version 5.7.2 (swiftlang-5.7.2.135.5 clang-1400.0.29.51)

What did you do?

go.mod:

module test/inlinegeneric

go 1.20

a/a.go:

package a

type Foo1[T any] struct {
}

func (*Foo1[T]) Run() {
}

type Foo2 struct {
}

func (*Foo2) Run() {
}

b/b.go:

package b

import "test/inlinegeneric/a"

func Bar() {
	var f1 a.Foo1[int]
	f1.Run()
	var f2 a.Foo2
	f2.Run()
}

type Boo struct {
	f1 a.Foo1[int]
	f2 a.Foo2
}

main.go:

package main

import "test/inlinegeneric/b"

func main() {
	var x b.Boo
	_ = x
	b.Bar()
}

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:

# command-line-arguments
./main.go:5:6: can inline main with cost 20 as: func() { b.Bar() }
./main.go:8:7: inlining call to b.Bar
./main.go:8:7: inlining call to a.(*Foo1[go.shape.int]).Run
./main.go:8:7: inlining call to a.(*Foo2).Run

For go1.19.7

# command-line-arguments
./main.go:5:6: can inline main with cost 20 as: func() { b.Bar() }
./main.go:8:7: inlining call to b.Bar
./main.go:8:7: inlining call to a.(*Foo1[go.shape.int_0]).Run
./main.go:8:7: inlining call to a.(*Foo2).Run

What did you see instead?

For go1.20.2:

# command-line-arguments
./main.go:5:6: can inline main with cost 27 as: func() { x = <nil>; _ = x; b.Bar() }
./main.go:8:7: inlining call to b.Bar
./main.go:8:7: inlining call to a.(*Foo2).Run
./a/a.go:6:6: can inline a.(*Foo1[go.shape.int]).Run with cost 0 as: method(*a.Foo1[go.shape.int]) func(*[0]uintptr) {  }
./a/a.go:6:6: can inline a.(*Foo1[int]).Run with cost 9 as: method(*a.Foo1[int]) func() { var .autotmp_0 *a.Foo1[int]; .autotmp_0 = <nil>; (*a.Foo1[go.shape.int]).Run(.autotmp_0, &a..dict.Foo1[int]) }
./a/a.go:6:6: inlining call to a.(*Foo1[go.shape.int]).Run

For go1.19.7

# command-line-arguments
./main.go:5:6: can inline main with cost 27 as: func() { var x b.Boo; x = <nil>; _ = x; b.Bar() }
./main.go:8:7: inlining call to b.Bar
./main.go:8:7: inlining call to a.(*Foo2).Run
./a/a.go:6:17: can inline a.(*Foo1[go.shape.int_0]).Run with cost 0 as: func(uintptr, *a.Foo1[go.shape.int_0]) {  }

Metadata

Metadata

Assignees

Labels

NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.compiler/runtimeIssues related to the Go compiler and/or runtime.

Type

No type

Projects

Status

Todo

Relationships

None yet

Development

No branches or pull requests

Issue actions