aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Chase <drchase@google.com>2024-11-15 17:08:34 -0500
committerDavid Chase <drchase@google.com>2024-11-19 00:04:51 +0000
commit170436c045f1303543e6d0bf8b36fccac57da2cd (patch)
tree2c383dfdddacab1d55823ebcecc0282cf5ec2870 /src
parentb8fe88393b122a06e00163dc464bf8cd14187f4b (diff)
downloadgo-170436c045f1303543e6d0bf8b36fccac57da2cd.tar.xz
cmd/compile: strongly favor closure inlining
This tweaks the inlining cost knob for closures specifically, they receive a doubled budget. The rationale for this is that closures have a lot of "crud" in their IR that will disappear after inlining, so the standard budget penalizes them unnecessarily. This is also the cause of these bugs -- looking at the code involved, these closures "should" be inlineable, therefore tweak the parameters until behavior matches expectations. It's not costly in binary size, because the only-called-from-one-site case is common (especially for rangefunc iterators). I can imagine better fixes and I am going to try to get that done, but this one is small and makes things better. Fixes #69411, #69539. Change-Id: I8a892c40323173a723799e0ddad69dcc2724a8f9 Reviewed-on: https://go-review.googlesource.com/c/go/+/629195 Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Robert Griesemer <gri@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Diffstat (limited to 'src')
-rw-r--r--src/cmd/cgo/internal/test/callback_windows.go5
-rw-r--r--src/cmd/compile/internal/inline/inl.go7
2 files changed, 10 insertions, 2 deletions
diff --git a/src/cmd/cgo/internal/test/callback_windows.go b/src/cmd/cgo/internal/test/callback_windows.go
index 77bdfa4dd3..0e2b543a38 100644
--- a/src/cmd/cgo/internal/test/callback_windows.go
+++ b/src/cmd/cgo/internal/test/callback_windows.go
@@ -69,11 +69,11 @@ func testCallbackCallersSEH(t *testing.T) {
want := []string{
"test._Cfunc_backtrace",
"test.testCallbackCallersSEH.func1.1",
- "test.testCallbackCallersSEH.func1",
+ // "test.testCallbackCallersSEH.func1", // hidden by inlining
"test.goCallback",
"test._Cfunc_callback",
"test.nestedCall.func1",
- "test.nestedCall",
+ // "test.nestedCall", // hidden by inlining
"test.testCallbackCallersSEH",
"test.TestCallbackCallersSEH",
}
@@ -84,6 +84,7 @@ func testCallbackCallersSEH(t *testing.T) {
})
got := make([]string, 0, n)
for i := 0; i < n; i++ {
+ // This test is brittle in the face of inliner changes
f := runtime.FuncForPC(pc[i] - 1)
if f == nil {
continue
diff --git a/src/cmd/compile/internal/inline/inl.go b/src/cmd/compile/internal/inline/inl.go
index 6c0521d1f5..6835b919b6 100644
--- a/src/cmd/compile/internal/inline/inl.go
+++ b/src/cmd/compile/internal/inline/inl.go
@@ -206,6 +206,9 @@ func inlineBudget(fn *ir.Func, profile *pgoir.Profile, relaxed bool, verbose boo
if relaxed {
budget += inlheur.BudgetExpansion(inlineMaxBudget)
}
+ if fn.ClosureParent != nil {
+ budget *= 2
+ }
return budget
}
@@ -861,6 +864,10 @@ var InlineCall = func(callerfn *ir.Func, call *ir.CallExpr, fn *ir.Func, inlInde
// - whether the inlined function is "hot" according to PGO.
func inlineCostOK(n *ir.CallExpr, caller, callee *ir.Func, bigCaller bool) (bool, int32, int32, bool) {
maxCost := int32(inlineMaxBudget)
+ if callee.ClosureParent != nil {
+ maxCost *= 2 // favor inlining closures
+ }
+
if bigCaller {
// We use this to restrict inlining into very big functions.
// See issue 26546 and 17566.