[dev.typeparams] cmd/compile: remove CallExpr.PreserveClosure

This flag is only needed to prevent the directClosureCall optimization
in walkCall, when called for walkGoDefer. But walkGoDefer don't need
to call walkCall: at this point in the compile, the call expression
isn't a real call anymore.

Instead, we just need to walkExpr on the function expression.

Change-Id: I8a5176cfe1bff53700cbd21ed1b479ebd9a839ad
Reviewed-on: https://go-review.googlesource.com/c/go/+/330271
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Trust: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Matthew Dempsky 2021-06-22 20:37:42 -07:00
parent e59a19cceb
commit 1a445dab66
4 changed files with 10 additions and 21 deletions

View file

@ -157,13 +157,12 @@ const (
type CallExpr struct { type CallExpr struct {
miniExpr miniExpr
origNode origNode
X Node X Node
Args Nodes Args Nodes
KeepAlive []*Name // vars to be kept alive until call returns KeepAlive []*Name // vars to be kept alive until call returns
IsDDD bool IsDDD bool
Use CallUse Use CallUse
NoInline bool NoInline bool
PreserveClosure bool // disable directClosureCall for this call
} }
func NewCallExpr(pos src.XPos, op Op, fun Node, args []Node) *CallExpr { func NewCallExpr(pos src.XPos, op Op, fun Node, args []Node) *CallExpr {

View file

@ -37,14 +37,6 @@ func directClosureCall(n *ir.CallExpr) {
return // leave for walkClosure to handle return // leave for walkClosure to handle
} }
// If wrapGoDefer() in the order phase has flagged this call,
// avoid eliminating the closure even if there is a direct call to
// (the closure is needed to simplify the register ABI). See
// wrapGoDefer for more details.
if n.PreserveClosure {
return
}
// We are going to insert captured variables before input args. // We are going to insert captured variables before input args.
var params []*types.Field var params []*types.Field
var decls []*ir.Name var decls []*ir.Name

View file

@ -1564,11 +1564,10 @@ func (o *orderState) wrapGoDefer(n *ir.GoDeferStmt) {
// TODO: maybe not wrap if the called function has no arguments and // TODO: maybe not wrap if the called function has no arguments and
// only in-register results? // only in-register results?
if len(callArgs) == 0 && call.Op() == ir.OCALLFUNC && callX.Type().NumResults() == 0 { if len(callArgs) == 0 && call.Op() == ir.OCALLFUNC && callX.Type().NumResults() == 0 {
if c, ok := call.(*ir.CallExpr); ok && callX != nil && callX.Op() == ir.OCLOSURE { if callX.Op() == ir.OCLOSURE {
clo := callX.(*ir.ClosureExpr) clo := callX.(*ir.ClosureExpr)
clo.Func.SetClosureCalled(false) clo.Func.SetClosureCalled(false)
clo.IsGoWrap = true clo.IsGoWrap = true
c.PreserveClosure = true
} }
return return
} }
@ -1771,9 +1770,6 @@ func (o *orderState) wrapGoDefer(n *ir.GoDeferStmt) {
topcall := ir.NewCallExpr(n.Pos(), ir.OCALL, clo, nil) topcall := ir.NewCallExpr(n.Pos(), ir.OCALL, clo, nil)
typecheck.Call(topcall) typecheck.Call(topcall)
// Tag the call to insure that directClosureCall doesn't undo our work.
topcall.PreserveClosure = true
fn.SetClosureCalled(false) fn.SetClosureCalled(false)
// Finally, point the defer statement at the newly generated call. // Finally, point the defer statement at the newly generated call.

View file

@ -204,7 +204,9 @@ func walkGoDefer(n *ir.GoDeferStmt) ir.Node {
} }
var init ir.Nodes var init ir.Nodes
n.Call = walkExpr(n.Call, &init)
call := n.Call.(*ir.CallExpr)
call.X = walkExpr(call.X, &init)
if len(init) > 0 { if len(init) > 0 {
init.Append(n) init.Append(n)