]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.regabi] cmd/compile: simplify walkReturn
authorMatthew Dempsky <mdempsky@google.com>
Sun, 3 Jan 2021 06:43:58 +0000 (22:43 -0800)
committerMatthew Dempsky <mdempsky@google.com>
Sun, 3 Jan 2021 19:20:13 +0000 (19:20 +0000)
Just de-duplicating some logic and adding better comments.

Passes toolstash -cmp.

Change-Id: I15ec07070510692c6d4367880bc3d2d9847370ab
Reviewed-on: https://go-review.googlesource.com/c/go/+/281132
Trust: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: 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/walk/assign.go

index 7f3e4cc995c0f5571808dcab565bc590b867db73..d552749d2660ab4cce98583eac5a4c5ef4dc28c0 100644 (file)
@@ -143,8 +143,6 @@ func walkAssignFunc(init *ir.Nodes, n *ir.AssignListStmt) ir.Node {
 // walkAssignList walks an OAS2 node.
 func walkAssignList(init *ir.Nodes, n *ir.AssignListStmt) ir.Node {
        init.Append(ir.TakeInit(n)...)
-       walkExprListSafe(n.Lhs, init)
-       walkExprListSafe(n.Rhs, init)
        return ir.NewBlockStmt(src.NoXPos, ascompatee(ir.OAS, n.Lhs, n.Rhs, init))
 }
 
@@ -232,54 +230,33 @@ func walkAssignRecv(init *ir.Nodes, n *ir.AssignListStmt) ir.Node {
 
 // walkReturn walks an ORETURN node.
 func walkReturn(n *ir.ReturnStmt) ir.Node {
-       ir.CurFunc.NumReturns++
+       fn := ir.CurFunc
+
+       fn.NumReturns++
        if len(n.Results) == 0 {
                return n
        }
-       if (ir.HasNamedResults(ir.CurFunc) && len(n.Results) > 1) || paramoutheap(ir.CurFunc) {
-               // assign to the function out parameters,
-               // so that ascompatee can fix up conflicts
-               var rl []ir.Node
-
-               for _, ln := range ir.CurFunc.Dcl {
-                       cl := ln.Class_
-                       if cl == ir.PAUTO || cl == ir.PAUTOHEAP {
-                               break
-                       }
-                       if cl == ir.PPARAMOUT {
-                               var ln ir.Node = ln
-                               if ir.IsParamStackCopy(ln) {
-                                       ln = walkExpr(typecheck.Expr(ir.NewStarExpr(base.Pos, ln.Name().Heapaddr)), nil)
-                               }
-                               rl = append(rl, ln)
-                       }
-               }
 
-               if got, want := len(n.Results), len(rl); got != want {
-                       // order should have rewritten multi-value function calls
-                       // with explicit OAS2FUNC nodes.
-                       base.Fatalf("expected %v return arguments, have %v", want, got)
-               }
-
-               // move function calls out, to make ascompatee's job easier.
-               walkExprListSafe(n.Results, n.PtrInit())
+       results := fn.Type().Results().FieldSlice()
+       dsts := make([]ir.Node, len(results))
+       for i, v := range results {
+               // TODO(mdempsky): typecheck should have already checked the result variables.
+               dsts[i] = typecheck.AssignExpr(v.Nname.(*ir.Name))
+       }
 
-               n.Results = ascompatee(n.Op(), rl, n.Results, n.PtrInit())
+       if (ir.HasNamedResults(fn) && len(n.Results) > 1) || paramoutheap(fn) {
+               // General case: For anything tricky, let ascompatee handle
+               // ordering the assignments correctly.
+               n.Results = ascompatee(n.Op(), dsts, n.Results, n.PtrInit())
                return n
        }
-       walkExprList(n.Results, n.PtrInit())
 
-       // For each return parameter (lhs), assign the corresponding result (rhs).
-       lhs := ir.CurFunc.Type().Results()
-       rhs := n.Results
-       res := make([]ir.Node, lhs.NumFields())
-       for i, nl := range lhs.FieldSlice() {
-               nname := ir.AsNode(nl.Nname)
-               if ir.IsParamHeapCopy(nname) {
-                       nname = nname.Name().Stackcopy
-               }
-               a := ir.NewAssignStmt(base.Pos, nname, rhs[i])
-               res[i] = convas(a, n.PtrInit())
+       // Common case: Assignment order doesn't matter. Simply assign to
+       // each result parameter in order.
+       walkExprList(n.Results, n.PtrInit())
+       res := make([]ir.Node, len(results))
+       for i, v := range n.Results {
+               res[i] = convas(ir.NewAssignStmt(base.Pos, dsts[i], v), n.PtrInit())
        }
        n.Results = res
        return n
@@ -348,6 +325,14 @@ func ascompatee(op ir.Op, nl, nr []ir.Node, init *ir.Nodes) []ir.Node {
                base.Fatalf("assignment operands mismatch: %+v / %+v", ir.Nodes(nl), ir.Nodes(nr))
        }
 
+       // TODO(mdempsky): Simplify this code. Not only is it redundant to
+       // call safeExpr on the operands twice, but ensuring order of
+       // evaluation for function calls was already handled by order.go.
+
+       // move function calls out, to make ascompatee's job easier.
+       walkExprListSafe(nl, init)
+       walkExprListSafe(nr, init)
+
        // ensure order of evaluation for function calls
        for i := range nl {
                nl[i] = safeExpr(nl[i], init)