1
0
mirror of https://github.com/golang/go synced 2024-11-23 06:20:07 -07:00

cmd/compile: factor out rewrite multi-valued f()

So next CL can reuse code to rewrite OAS2FUNC.

Passes toolstash -cmp.

For #46725

Change-Id: I1113ed615b6d6b9494dd87000ce342d7a46d9e7b
Reviewed-on: https://go-review.googlesource.com/c/go/+/327650
Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Cuong Manh Le 2021-06-13 22:26:21 +07:00
parent 14305bf0b9
commit 3249b645c9

View File

@ -945,16 +945,18 @@ func typecheckargs(n ir.InitNode) {
return return
} }
// Rewrite f(g()) into t1, t2, ... = g(); f(t1, t2, ...).
// Save n as n.Orig for fmt.go. // Save n as n.Orig for fmt.go.
if ir.Orig(n) == n { if ir.Orig(n) == n {
n.(ir.OrigNode).SetOrig(ir.SepCopy(n)) n.(ir.OrigNode).SetOrig(ir.SepCopy(n))
} }
as := ir.NewAssignListStmt(base.Pos, ir.OAS2, nil, nil) // Rewrite f(g()) into t1, t2, ... = g(); f(t1, t2, ...).
as.Rhs.Append(list...) rewriteMultiValueCall(n, list[0])
}
// rewriteMultiValueCall rewrites multi-valued f() to use temporaries,
// so the backend wouldn't need to worry about tuple-valued expressions.
func rewriteMultiValueCall(n ir.InitNode, call ir.Node) {
// If we're outside of function context, then this call will // If we're outside of function context, then this call will
// be executed during the generated init function. However, // be executed during the generated init function. However,
// init.go hasn't yet created it. Instead, associate the // init.go hasn't yet created it. Instead, associate the
@ -964,25 +966,30 @@ func typecheckargs(n ir.InitNode) {
if static { if static {
ir.CurFunc = InitTodoFunc ir.CurFunc = InitTodoFunc
} }
list = nil
for _, f := range t.FieldSlice() { as := ir.NewAssignListStmt(base.Pos, ir.OAS2, nil, []ir.Node{call})
t := Temp(f.Type) results := call.Type().FieldSlice()
as.PtrInit().Append(ir.NewDecl(base.Pos, ir.ODCL, t)) list := make([]ir.Node, len(results))
as.Lhs.Append(t) for i, result := range results {
list = append(list, t) tmp := Temp(result.Type)
as.PtrInit().Append(ir.NewDecl(base.Pos, ir.ODCL, tmp))
as.Lhs.Append(tmp)
list[i] = tmp
} }
if static { if static {
ir.CurFunc = nil ir.CurFunc = nil
} }
n.PtrInit().Append(Stmt(as))
switch n := n.(type) { switch n := n.(type) {
default:
base.Fatalf("rewriteMultiValueCall %+v", n.Op())
case *ir.CallExpr: case *ir.CallExpr:
n.Args = list n.Args = list
case *ir.ReturnStmt: case *ir.ReturnStmt:
n.Results = list n.Results = list
} }
n.PtrInit().Append(Stmt(as))
} }
func checksliceindex(l ir.Node, r ir.Node, tp *types.Type) bool { func checksliceindex(l ir.Node, r ir.Node, tp *types.Type) bool {