From: Branden J Brown Date: Sun, 25 Oct 2020 18:26:19 +0000 (-0400) Subject: cmd/compile: inline functions evaluated in go and defer statements X-Git-Tag: go1.16beta1~418 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=4fb429138881e3fe171e4c2e958ed0da26ddfd9c;p=gostls13.git cmd/compile: inline functions evaluated in go and defer statements The inlining pass previously bailed upon encountering a go or defer statement, so it would not inline functions e.g. used to provide arguments to the deferred function. This change preserves the behavior of not inlining the deferred function itself, but it allows the inlining walk to proceed into its arguments. Fixes #42194 Change-Id: I4e82029d8dcbe69019cc83ae63a4b29af45ec777 Reviewed-on: https://go-review.googlesource.com/c/go/+/264997 Run-TryBot: Cuong Manh Le TryBot-Result: Go Bot Reviewed-by: Cuong Manh Le Reviewed-by: Matthew Dempsky Trust: Cuong Manh Le --- diff --git a/src/cmd/compile/internal/gc/inl.go b/src/cmd/compile/internal/gc/inl.go index a2fb00e132..137675aa20 100644 --- a/src/cmd/compile/internal/gc/inl.go +++ b/src/cmd/compile/internal/gc/inl.go @@ -574,13 +574,11 @@ func inlnode(n *Node, maxCost int32, inlMap map[*Node]bool) *Node { } switch n.Op { - // inhibit inlining of their argument case ODEFER, OGO: switch n.Left.Op { case OCALLFUNC, OCALLMETH: n.Left.SetNoInline(true) } - return n // TODO do them here (or earlier), // so escape analysis can avoid more heapmoves. diff --git a/test/inline.go b/test/inline.go index 9b75bc5065..470414f883 100644 --- a/test/inline.go +++ b/test/inline.go @@ -246,3 +246,20 @@ func ii() { // ERROR "can inline ii" f := getMeth(t1) // ERROR "inlining call to getMeth" "t1.meth does not escape" _ = f(3) } + +// Issue #42194 - make sure that functions evaluated in +// go and defer statements can be inlined. +func gd1(int) { + defer gd1(gd2()) // ERROR "inlining call to gd2" + defer gd3()() // ERROR "inlining call to gd3" + go gd1(gd2()) // ERROR "inlining call to gd2" + go gd3()() // ERROR "inlining call to gd3" +} + +func gd2() int { // ERROR "can inline gd2" + return 1 +} + +func gd3() func() { // ERROR "can inline gd3" + return ii +}