]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.regabi] cmd/compile: use names for keep alive variables in function call
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Wed, 30 Dec 2020 07:08:44 +0000 (14:08 +0700)
committerCuong Manh Le <cuong.manhle.vn@gmail.com>
Thu, 31 Dec 2020 09:43:13 +0000 (09:43 +0000)
Back to pre Russquake, Node.Nbody of OCALL* node is used to attach
variables which must be kept alive during that call.

Now after Russquake, we have CallExpr to represent a function call,
so use a dedicated field for those variables instead.

Passes toolstash -cmp.

Change-Id: I4f40ebefcc7c41cdcc4e29c7a6d8496a083b68f4
Reviewed-on: https://go-review.googlesource.com/c/go/+/280733
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>
src/cmd/compile/internal/ir/expr.go
src/cmd/compile/internal/ir/node_gen.go
src/cmd/compile/internal/ssagen/ssa.go
src/cmd/compile/internal/walk/order.go
src/cmd/compile/internal/walk/stmt.go

index 55e4b61baf04e57bfb7fe3537f32e0a5a3857451..f435a5bb2613ed5c89941f3788e83efcd3f51de8 100644 (file)
@@ -159,13 +159,13 @@ const (
 type CallExpr struct {
        miniExpr
        origNode
-       X        Node
-       Args     Nodes
-       Rargs    Nodes // TODO(rsc): Delete.
-       Body     Nodes // TODO(rsc): Delete.
-       IsDDD    bool
-       Use      CallUse
-       NoInline bool
+       X         Node
+       Args      Nodes
+       Rargs     Nodes   // TODO(rsc): Delete.
+       KeepAlive []*Name // vars to be kept alive until call returns
+       IsDDD     bool
+       Use       CallUse
+       NoInline  bool
 }
 
 func NewCallExpr(pos src.XPos, op Op, fun Node, args []Node) *CallExpr {
index 65c0b239ed5689ded9ecfa765b565b2976ec3a49..7f494b16cd3409fed10727445fda39e00e932edb 100644 (file)
@@ -251,7 +251,7 @@ func (n *CallExpr) copy() Node {
        c.init = copyNodes(c.init)
        c.Args = copyNodes(c.Args)
        c.Rargs = copyNodes(c.Rargs)
-       c.Body = copyNodes(c.Body)
+       c.KeepAlive = copyNames(c.KeepAlive)
        return &c
 }
 func (n *CallExpr) doChildren(do func(Node) bool) bool {
@@ -267,7 +267,7 @@ func (n *CallExpr) doChildren(do func(Node) bool) bool {
        if doNodes(n.Rargs, do) {
                return true
        }
-       if doNodes(n.Body, do) {
+       if doNames(n.KeepAlive, do) {
                return true
        }
        return false
@@ -279,7 +279,7 @@ func (n *CallExpr) editChildren(edit func(Node) Node) {
        }
        editNodes(n.Args, edit)
        editNodes(n.Rargs, edit)
-       editNodes(n.Body, edit)
+       editNames(n.KeepAlive, edit)
 }
 
 func (n *CaseClause) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
@@ -1381,6 +1381,30 @@ func editCommClauses(list []*CommClause, edit func(Node) Node) {
        }
 }
 
+func copyNames(list []*Name) []*Name {
+       if list == nil {
+               return nil
+       }
+       c := make([]*Name, len(list))
+       copy(c, list)
+       return c
+}
+func doNames(list []*Name, do func(Node) bool) bool {
+       for _, x := range list {
+               if x != nil && do(x) {
+                       return true
+               }
+       }
+       return false
+}
+func editNames(list []*Name, edit func(Node) Node) {
+       for i, x := range list {
+               if x != nil {
+                       list[i] = edit(x).(*Name)
+               }
+       }
+}
+
 func copyNodes(list []Node) []Node {
        if list == nil {
                return nil
index ddf65eb20961f8fdf1a041d23147b7e0c8e9575a..022959a934ef4d9478cb849f2de721d0470c242d 100644 (file)
@@ -4867,7 +4867,9 @@ func (s *state) call(n *ir.CallExpr, k callKind, returnResultAddr bool) *ssa.Val
                s.vars[memVar] = call
        }
        // Insert OVARLIVE nodes
-       s.stmtList(n.Body)
+       for _, name := range n.KeepAlive {
+               s.stmt(ir.NewUnaryExpr(n.Pos(), ir.OVARLIVE, name))
+       }
 
        // Finish block for defers
        if k == callDefer || k == callDeferStack {
index b3d2eaec17a34365757ffb9c2de1d8dae5c0ef33..681f5dcc76501e7e05c5b03541a50f9cd9a45af6 100644 (file)
@@ -518,7 +518,7 @@ func (o *orderState) call(nn ir.Node) {
                                x := o.copyExpr(arg.X)
                                arg.X = x
                                x.Name().SetAddrtaken(true) // ensure SSA keeps the x variable
-                               n.Body.Append(typecheck.Stmt(ir.NewUnaryExpr(base.Pos, ir.OVARLIVE, x)))
+                               n.KeepAlive = append(n.KeepAlive, x.(*ir.Name))
                        }
                }
        }
index f843d2c4faf32bc704735db48e91a5a8793ceb20..cfd1da46d278f8610df40d5706c2003f0913be7d 100644 (file)
@@ -228,7 +228,7 @@ func walkGoDefer(n *ir.GoDeferStmt) ir.Node {
 
        case ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER:
                call := call.(*ir.CallExpr)
-               if len(call.Body) > 0 {
+               if len(call.KeepAlive) > 0 {
                        n.Call = wrapCall(call, &init)
                } else {
                        n.Call = walkExpr(call, &init)