-
Notifications
You must be signed in to change notification settings - Fork 18.5k
Description
Go version
go version devel go1.24-6d39245514 Thu Oct 31 01:28:37 2024 +0000 linux/arm64
Output of go env in your module/workspace:
GO111MODULE=''
GOARCH='arm64'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/home/asamoylov/.cache/go-build'
GOENV='/home/asamoylov/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/asamoylov/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/asamoylov/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/home/asamoylov/repos/go-gh/'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/home/asamoylov/repos/go-gh/pkg/tool/linux_arm64'
GOVCS=''
GOVERSION='devel go1.24-6d39245514 Thu Oct 31 01:28:37 2024 +0000'
GODEBUG=''
GOTELEMETRY='local'
GOTELEMETRYDIR='/home/asamoylov/.config/go/telemetry'
GCCGO='gccgo'
GOARM64='v8.0'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/dev/null'
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 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build2613944426=/tmp/go-build -gno-record-gcc-switches'What did you do?
Hello! I found error in inlining. Basically, if module A imports module B. Module B imports module C. Module A can call functions from module C but can't inline them! However, if you directly import module C into A, then inlining succeeds.
Here is a example:
project/
--- go.mod
--- transform.go
--- Descriptor/
--- go.mod
--- descriptor.go
--- DescriptorWrapper/
--- go.mod
--- wrapper.go
descriptor.go
package Descriptor
type Descriptor struct {
numberKind int64
}
func (d Descriptor) NumberKind() int64 {
return d.numberKind
}
wrapper.go
package DescriptorWrapper
import "Descriptor"
type Wrapper struct {
Desc Descriptor.Descriptor
}
transform.go
package transform
import (
"DescriptorWrapper"
)
func GaugeArray(wr DescriptorWrapper.Wrapper) {
desc := wr.Desc
_ = desc.NumberKind()
}
Here we can see that call to NumberKind() wasn't inlined:
go build -a -gcflags="-m" transform.go
# command-line-arguments
./transform.go:8:6: can inline GaugeArray
However, if we add direct import of "Descriptor":
transform.go
package transform
import (
_ "Descriptor"
"DescriptorWrapper"
)
func GaugeArray(wr DescriptorWrapper.Wrapper) {
desc := wr.Desc
_ = desc.NumberKind()
}
Here call to NumberKind() is inlined!
go build -a -gcflags="-m" transform.go
# command-line-arguments
./transform.go:8:6: can inline GaugeArray
./transform.go:10:21: inlining call to Descriptor.Descriptor.NumberKind
In this example, in first case (when inlining do not happen) 'bodyReaderFor' from 'unifiedHaveInlineBody' return false and inlining fails (in second case it returns true):
cmd/compile/internal/noder/reader.go
// unifiedHaveInlineBody reports whether we have the function body for
// fn, so we can inline it.
func unifiedHaveInlineBody(fn *ir.Func) bool {
if fn.Inl == nil {
return false
}
_, ok := bodyReaderFor(fn)
return ok
}
What did you see happen?
Function that can be inlined wasn't inlined.
What did you expect to see?
Inlining of function that can be inlined
Metadata
Metadata
Assignees
Labels
Type
Projects
Status