[dev.typeparams] cmd/compile: set Func.ClosureCalled in escape analysis

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>
diff --git a/src/cmd/compile/internal/escape/call.go b/src/cmd/compile/internal/escape/call.go
index 6fcfb1b..9e5abed 100644
--- a/src/cmd/compile/internal/escape/call.go
+++ b/src/cmd/compile/internal/escape/call.go
@@ -57,6 +57,13 @@
 		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 {
diff --git a/src/cmd/compile/internal/inline/inl.go b/src/cmd/compile/internal/inline/inl.go
index f1e927d..45a533f 100644
--- a/src/cmd/compile/internal/inline/inl.go
+++ b/src/cmd/compile/internal/inline/inl.go
@@ -470,9 +470,6 @@
 			// 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 @@
 	// 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
diff --git a/src/cmd/compile/internal/ir/func.go b/src/cmd/compile/internal/ir/func.go
index 3b9e36d..269b6f1 100644
--- a/src/cmd/compile/internal/ir/func.go
+++ b/src/cmd/compile/internal/ir/func.go
@@ -202,7 +202,7 @@
 	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 {
diff --git a/src/cmd/compile/internal/noder/helpers.go b/src/cmd/compile/internal/noder/helpers.go
index 08affe4..b0fb913 100644
--- a/src/cmd/compile/internal/noder/helpers.go
+++ b/src/cmd/compile/internal/noder/helpers.go
@@ -160,8 +160,6 @@
 
 	// 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
diff --git a/src/cmd/compile/internal/noder/reader.go b/src/cmd/compile/internal/noder/reader.go
index d938dca..05cfc61 100644
--- a/src/cmd/compile/internal/noder/reader.go
+++ b/src/cmd/compile/internal/noder/reader.go
@@ -1523,9 +1523,6 @@
 
 	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()
diff --git a/src/cmd/compile/internal/noder/stencil.go b/src/cmd/compile/internal/noder/stencil.go
index d35e036..dbaebf7 100644
--- a/src/cmd/compile/internal/noder/stencil.go
+++ b/src/cmd/compile/internal/noder/stencil.go
@@ -1193,8 +1193,6 @@
 			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
diff --git a/src/cmd/compile/internal/typecheck/func.go b/src/cmd/compile/internal/typecheck/func.go
index 68f0c20..847e9b9 100644
--- a/src/cmd/compile/internal/typecheck/func.go
+++ b/src/cmd/compile/internal/typecheck/func.go
@@ -242,8 +242,6 @@
 		fn.Iota = x
 	}
 
-	fn.SetClosureCalled(top&ctxCallee != 0)
-
 	ir.NameClosure(clo, ir.CurFunc)
 	Func(fn)