1
0
mirror of https://github.com/golang/go synced 2024-11-22 20:50:05 -07:00

[dev.typeparams] cmd/compile: optimize wrapping of constant arguments

When wrapping a go/defer statement like:

	go f(g(), "x", 42)

we were wrapping it like:

	_0, _1, _2, _3 := f, g(), "x", 42
	go func() { _0(_1, _2, _3) }()

This is simple and general (and often necessary), but suboptimal in
some cases, such as this. Instead of evaluating the constant arguments
at the go/defer statement, and storing them into the closure context,
we can just keep them in the wrapped call expression.

This CL changes the code to instead generate (assuming f is a declared
function, not a function-typed variable):

	_0 := g()
	go func() { f(_0, "x", 42) }()

Change-Id: I2bdd4951e7ee93363e1656ecf9b5bd69a121c38a
Reviewed-on: https://go-review.googlesource.com/c/go/+/330332
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
This commit is contained in:
Matthew Dempsky 2021-06-23 00:49:03 -07:00
parent eb691fdd62
commit a72a499c24

View File

@ -293,6 +293,18 @@ func (e *escape) rewriteArgument(argp *ir.Node, init *ir.Nodes, call ir.Node, fn
}
visit := func(pos src.XPos, argp *ir.Node) {
// Optimize a few common constant expressions. By leaving these
// untouched in the call expression, we let the wrapper handle
// evaluating them, rather than taking up closure context space.
switch arg := *argp; arg.Op() {
case ir.OLITERAL, ir.ONIL, ir.OMETHEXPR:
return
case ir.ONAME:
if arg.(*ir.Name).Class == ir.PFUNC {
return
}
}
if unsafeUintptr(*argp) {
return
}