]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: add ir.ContainsClosure
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Tue, 18 Feb 2025 16:03:54 +0000 (23:03 +0700)
committerGopher Robot <gobot@golang.org>
Wed, 19 Feb 2025 01:52:54 +0000 (17:52 -0800)
And use it to unify all codes that need parent/closure checking.

Change-Id: I0b0aa1b007598668dff2c4bee31e21f0fb3830ce
Reviewed-on: https://go-review.googlesource.com/c/go/+/650315
Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: David Chase <drchase@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
src/cmd/compile/internal/escape/solve.go
src/cmd/compile/internal/inline/inl.go
src/cmd/compile/internal/ir/func.go

index 32f5a771a34a668cfd96a2f851f2b5082bf969f7..2002f2fbe41f3e30b8a613d605c165920092d487 100644 (file)
@@ -278,7 +278,7 @@ func (b *batch) outlives(l, other *location) bool {
                //      var u int  // okay to stack allocate
                //      fn := func() *int { return &u }()
                //      *fn() = 42
-               if containsClosure(other.curfn, l.curfn) && !l.curfn.ClosureResultsLost() {
+               if ir.ContainsClosure(other.curfn, l.curfn) && !l.curfn.ClosureResultsLost() {
                        return false
                }
 
@@ -304,24 +304,9 @@ func (b *batch) outlives(l, other *location) bool {
        //      func() {
        //              l = new(int) // must heap allocate: outlives call frame (if not inlined)
        //      }()
-       if containsClosure(l.curfn, other.curfn) {
+       if ir.ContainsClosure(l.curfn, other.curfn) {
                return true
        }
 
        return false
 }
-
-// containsClosure reports whether c is a closure contained within f.
-func containsClosure(f, c *ir.Func) bool {
-       // Common cases.
-       if f == c || c.OClosure == nil {
-               return false
-       }
-
-       for p := c.ClosureParent; p != nil; p = p.ClosureParent {
-               if p == f {
-                       return true
-               }
-       }
-       return false
-}
index a8809f368283168758d74ca7c523f3c20d106851..1b1a9cf3383699be48876ebccc184e6984683745 100644 (file)
@@ -1009,26 +1009,19 @@ func canInlineCallExpr(callerfn *ir.Func, n *ir.CallExpr, callee *ir.Func, bigCa
                return false, 0, false
        }
 
-       isClosureParent := func(closure, parent *ir.Func) bool {
-               for p := closure.ClosureParent; p != nil; p = p.ClosureParent {
-                       if p == parent {
-                               return true
-                       }
-               }
-               return false
-       }
-       if isClosureParent(callerfn, callee) {
+       if ir.ContainsClosure(callee, callerfn) {
                // Can't recursively inline a parent of the closure into itself.
                if log && logopt.Enabled() {
                        logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", fmt.Sprintf("recursive call to closure parent: %s, %s", ir.FuncName(callerfn), ir.FuncName(callee)))
                }
                return false, 0, false
        }
-       if isClosureParent(callee, callerfn) {
+
+       if ir.ContainsClosure(callerfn, callee) {
                // Can't recursively inline a closure if there's a call to the parent in closure body.
                if ir.Any(callee, func(node ir.Node) bool {
                        if call, ok := node.(*ir.CallExpr); ok {
-                               if name, ok := call.Fun.(*ir.Name); ok && isClosureParent(callerfn, name.Func) {
+                               if name, ok := call.Fun.(*ir.Name); ok && ir.ContainsClosure(name.Func, callerfn) {
                                        return true
                                }
                        }
index 6354da3556531e3fdab0dac2f75caf9c6b20620e..668537c90e6a4090007ce1b0588152d34ef445e7 100644 (file)
@@ -627,3 +627,18 @@ func (fn *Func) DeclareParams(setNname bool) {
        declareParams(params, PPARAM, "~p", 0)
        declareParams(results, PPARAMOUT, "~r", len(params))
 }
+
+// ContainsClosure reports whether c is a closure contained within f.
+func ContainsClosure(f, c *Func) bool {
+       // Common cases.
+       if f == c || c.OClosure == nil {
+               return false
+       }
+
+       for p := c.ClosureParent; p != nil; p = p.ClosureParent {
+               if p == f {
+                       return true
+               }
+       }
+       return false
+}