mirror of
https://github.com/golang/go
synced 2024-09-29 14:24:32 -06:00
[dev.regabi] cmd/compile: use names for keep alive variables in function call
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>
This commit is contained in:
parent
8fe1197654
commit
77fd81a3e6
@ -159,13 +159,13 @@ const (
|
|||||||
type CallExpr struct {
|
type CallExpr struct {
|
||||||
miniExpr
|
miniExpr
|
||||||
origNode
|
origNode
|
||||||
X Node
|
X Node
|
||||||
Args Nodes
|
Args Nodes
|
||||||
Rargs Nodes // TODO(rsc): Delete.
|
Rargs Nodes // TODO(rsc): Delete.
|
||||||
Body Nodes // TODO(rsc): Delete.
|
KeepAlive []*Name // vars to be kept alive until call returns
|
||||||
IsDDD bool
|
IsDDD bool
|
||||||
Use CallUse
|
Use CallUse
|
||||||
NoInline bool
|
NoInline bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCallExpr(pos src.XPos, op Op, fun Node, args []Node) *CallExpr {
|
func NewCallExpr(pos src.XPos, op Op, fun Node, args []Node) *CallExpr {
|
||||||
|
@ -251,7 +251,7 @@ func (n *CallExpr) copy() Node {
|
|||||||
c.init = copyNodes(c.init)
|
c.init = copyNodes(c.init)
|
||||||
c.Args = copyNodes(c.Args)
|
c.Args = copyNodes(c.Args)
|
||||||
c.Rargs = copyNodes(c.Rargs)
|
c.Rargs = copyNodes(c.Rargs)
|
||||||
c.Body = copyNodes(c.Body)
|
c.KeepAlive = copyNames(c.KeepAlive)
|
||||||
return &c
|
return &c
|
||||||
}
|
}
|
||||||
func (n *CallExpr) doChildren(do func(Node) bool) bool {
|
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) {
|
if doNodes(n.Rargs, do) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if doNodes(n.Body, do) {
|
if doNames(n.KeepAlive, do) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
@ -279,7 +279,7 @@ func (n *CallExpr) editChildren(edit func(Node) Node) {
|
|||||||
}
|
}
|
||||||
editNodes(n.Args, edit)
|
editNodes(n.Args, edit)
|
||||||
editNodes(n.Rargs, 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) }
|
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 {
|
func copyNodes(list []Node) []Node {
|
||||||
if list == nil {
|
if list == nil {
|
||||||
return nil
|
return nil
|
||||||
|
@ -4867,7 +4867,9 @@ func (s *state) call(n *ir.CallExpr, k callKind, returnResultAddr bool) *ssa.Val
|
|||||||
s.vars[memVar] = call
|
s.vars[memVar] = call
|
||||||
}
|
}
|
||||||
// Insert OVARLIVE nodes
|
// 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
|
// Finish block for defers
|
||||||
if k == callDefer || k == callDeferStack {
|
if k == callDefer || k == callDeferStack {
|
||||||
|
@ -518,7 +518,7 @@ func (o *orderState) call(nn ir.Node) {
|
|||||||
x := o.copyExpr(arg.X)
|
x := o.copyExpr(arg.X)
|
||||||
arg.X = x
|
arg.X = x
|
||||||
x.Name().SetAddrtaken(true) // ensure SSA keeps the x variable
|
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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -228,7 +228,7 @@ func walkGoDefer(n *ir.GoDeferStmt) ir.Node {
|
|||||||
|
|
||||||
case ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER:
|
case ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER:
|
||||||
call := call.(*ir.CallExpr)
|
call := call.(*ir.CallExpr)
|
||||||
if len(call.Body) > 0 {
|
if len(call.KeepAlive) > 0 {
|
||||||
n.Call = wrapCall(call, &init)
|
n.Call = wrapCall(call, &init)
|
||||||
} else {
|
} else {
|
||||||
n.Call = walkExpr(call, &init)
|
n.Call = walkExpr(call, &init)
|
||||||
|
Loading…
Reference in New Issue
Block a user