]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: inline functions evaluated in go and defer statements
authorBranden J Brown <zephyrtronium@gmail.com>
Sun, 25 Oct 2020 18:26:19 +0000 (14:26 -0400)
committerCuong Manh Le <cuong.manhle.vn@gmail.com>
Thu, 29 Oct 2020 16:47:10 +0000 (16:47 +0000)
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 <cuong.manhle.vn@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com>

src/cmd/compile/internal/gc/inl.go
test/inline.go

index a2fb00e1323c5b41ab7edf392dbe5633a9c0f491..137675aa209fd78cd5333515b9725490e0518b20 100644 (file)
@@ -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.
index 9b75bc5065863aec4334d2087a17622d22ae85c5..470414f883a451aa66d8f8414637194bb7d6a276 100644 (file)
@@ -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
+}