]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.typeparams] cmd/compile: set Func.ClosureCalled in escape analysis
authorMatthew Dempsky <mdempsky@google.com>
Sat, 3 Jul 2021 18:22:26 +0000 (11:22 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Sun, 4 Jul 2021 00:19:26 +0000 (00:19 +0000)
The Func.ClosureCalled flag is an optimization used by escape analysis
to detect closures that were directly called, so we know we have
visibility of the result flows. It's not needed by any other phases of
the compiler, so we might as well calculate it within escape analysis
too.

This saves some trouble during IR construction and trying to maintain
the ClosureCalled flag through inlining and copying.

Passes toolstash -cmp.

Change-Id: Ic53cecb7ac439745c0dfba2cd202b9cc40f1e47c
Reviewed-on: https://go-review.googlesource.com/c/go/+/332691
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Trust: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
src/cmd/compile/internal/escape/call.go
src/cmd/compile/internal/inline/inl.go
src/cmd/compile/internal/ir/func.go
src/cmd/compile/internal/noder/helpers.go
src/cmd/compile/internal/noder/reader.go
src/cmd/compile/internal/noder/stencil.go
src/cmd/compile/internal/typecheck/func.go

index 6fcfb1b3b4a189e8b57ceec4749898349f52bea6..9e5abed59142edaf7b6dba120d733f765e4cf6cb 100644 (file)
@@ -57,6 +57,13 @@ func (e *escape) callCommon(ks []hole, call ir.Node, init *ir.Nodes, wrapper *ir
                var fn *ir.Name
                switch call.Op() {
                case ir.OCALLFUNC:
+                       // If we have a direct call to a closure (not just one we were
+                       // able to statically resolve with ir.StaticValue), mark it as
+                       // such so batch.outlives can optimize the flow results.
+                       if call.X.Op() == ir.OCLOSURE {
+                               call.X.(*ir.ClosureExpr).Func.SetClosureCalled(true)
+                       }
+
                        switch v := ir.StaticValue(call.X); v.Op() {
                        case ir.ONAME:
                                if v := v.(*ir.Name); v.Class == ir.PFUNC {
index f1e927d643223ef324605e6098ffdb1ce8af4200..45a533fcafc3dfd70baf0e04c75f50fe2e6f1083 100644 (file)
@@ -470,9 +470,6 @@ func inlcopy(n ir.Node) ir.Node {
                        // x.Func.Body for iexport and local inlining.
                        oldfn := x.Func
                        newfn := ir.NewFunc(oldfn.Pos())
-                       if oldfn.ClosureCalled() {
-                               newfn.SetClosureCalled(true)
-                       }
                        m.(*ir.ClosureExpr).Func = newfn
                        newfn.Nname = ir.NewNameAt(oldfn.Nname.Pos(), oldfn.Nname.Sym())
                        // XXX OK to share fn.Type() ??
@@ -1154,11 +1151,7 @@ func (subst *inlsubst) closure(n *ir.ClosureExpr) ir.Node {
        // the closure is inlined in a specific function.
        newclo := newfn.OClosure
        newclo.SetInit(subst.list(n.Init()))
-       if oldfn.ClosureCalled() {
-               return typecheck.Callee(newclo)
-       } else {
-               return typecheck.Expr(newclo)
-       }
+       return typecheck.Expr(newclo)
 }
 
 // node recursively copies a node from the saved pristine body of the
index 3b9e36d4c59691066e766cb260f020e69c15e4aa..269b6f14ec1873188c0ca353ce912cd810cfcad5 100644 (file)
@@ -202,7 +202,7 @@ const (
        funcExportInline             // include inline body in export data
        funcInstrumentBody           // add race/msan instrumentation during SSA construction
        funcOpenCodedDeferDisallowed // can't do open-coded defers
-       funcClosureCalled            // closure is only immediately called
+       funcClosureCalled            // closure is only immediately called; used by escape analysis
 )
 
 type SymAndPos struct {
index 08affe44119a86c608155ff19326bcbdee01af6b..b0fb913ee846f28112e01ed2b2deffae9520b98e 100644 (file)
@@ -160,8 +160,6 @@ func Call(pos src.XPos, typ *types.Type, fun ir.Node, args []ir.Node, dots bool)
 
        // Add information, now that we know that fun is actually being called.
        switch fun := fun.(type) {
-       case *ir.ClosureExpr:
-               fun.Func.SetClosureCalled(true)
        case *ir.SelectorExpr:
                if fun.Op() == ir.OMETHVALUE {
                        op := ir.ODOTMETH
index d938dca5d4acd30bc4d209ba9a4345e616748fb9..05cfc614a274208e96c52c4c05ada3fe4b17479b 100644 (file)
@@ -1523,9 +1523,6 @@ func (r *reader) expr() ir.Node {
 
        case exprCall:
                fun := r.expr()
-               if clo, ok := fun.(*ir.ClosureExpr); ok {
-                       clo.Func.SetClosureCalled(true)
-               }
                pos := r.pos()
                args := r.exprs()
                dots := r.bool()
index d35e036ae6d67d92ec20139ca34751c5428583a1..dbaebf7623879219780496afba3ed6192cccf827 100644 (file)
@@ -1193,8 +1193,6 @@ func (subst *subster) node(n ir.Node) ir.Node {
                        newfn := ir.NewClosureFunc(oldfn.Pos(), subst.newf != nil)
                        ir.NameClosure(newfn.OClosure, subst.newf)
 
-                       newfn.SetClosureCalled(oldfn.ClosureCalled())
-
                        saveNewf := subst.newf
                        ir.CurFunc = newfn
                        subst.newf = newfn
index 68f0c20e526802b718eca23ba011587d6ef3e687..847e9b9aeadfbcdbab229989740083b77f30d90f 100644 (file)
@@ -242,8 +242,6 @@ func tcClosure(clo *ir.ClosureExpr, top int) ir.Node {
                fn.Iota = x
        }
 
-       fn.SetClosureCalled(top&ctxCallee != 0)
-
        ir.NameClosure(clo, ir.CurFunc)
        Func(fn)