mirror of
https://github.com/golang/go.git
synced 2026-01-29 07:02:05 +03:00
cmd/compile: disable inlining for functions using runtime.deferrangefunc
The rangefunc rewrite pass implements defer using deferrangefunc and deferproccat. The loop body is rewritten into a closure, it cannot be inlined due to defer call. But the outer function may still be inlined in certain scenarios (e.g., with PGO), leading to the defer executing at the wrong time. Fixes #77033 Change-Id: I4649fad5cd1b65891832523522002d9352711123 Reviewed-on: https://go-review.googlesource.com/c/go/+/732140 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Cherry Mui <cherryyz@google.com>
This commit is contained in:
committed by
Cherry Mui
parent
06eff0f7c3
commit
cd668d744f
@@ -516,6 +516,9 @@ opSwitch:
|
||||
break opSwitch
|
||||
case "panicrangestate":
|
||||
cheap = true
|
||||
case "deferrangefunc":
|
||||
v.reason = "defer call in range func"
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
40
src/cmd/compile/testdata/script/issue77033.txt
vendored
Normal file
40
src/cmd/compile/testdata/script/issue77033.txt
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
go test -bench=Foo -cpuprofile=default.pgo
|
||||
go test -bench=Foo -pgo=default.pgo
|
||||
! stdout 'FAIL'
|
||||
|
||||
-- main_test.go --
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
var a int
|
||||
|
||||
func save(x int) {
|
||||
a = x
|
||||
}
|
||||
|
||||
func foo() {
|
||||
for i := range yield1 {
|
||||
defer save(i)
|
||||
}
|
||||
}
|
||||
|
||||
func yield1(yield func(int) bool) {
|
||||
yield(1)
|
||||
}
|
||||
|
||||
func BenchmarkFoo(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
foo()
|
||||
}
|
||||
if a != 1 {
|
||||
b.Fatalf("a = %d; want 1", a)
|
||||
}
|
||||
}
|
||||
|
||||
-- go.mod --
|
||||
module demo
|
||||
|
||||
go 1.24
|
||||
Reference in New Issue
Block a user