Commit 52d9479e authored by Ian Lance Taylor's avatar Ian Lance Taylor

cmd/compile: convert Func.Cvars from *NodeList to *[]*Node

Passes toolstash -cmp.

Update #14473.

Change-Id: I7285175b1992a29033fdc9e81d6f30545e5cc30d
Reviewed-on: https://go-review.googlesource.com/19967Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 92bf58c2
...@@ -67,9 +67,7 @@ func closurebody(body *NodeList) *Node { ...@@ -67,9 +67,7 @@ func closurebody(body *NodeList) *Node {
// ordinary ones in the symbol table; see oldname. // ordinary ones in the symbol table; see oldname.
// unhook them. // unhook them.
// make the list of pointers for the closure call. // make the list of pointers for the closure call.
var v *Node for _, v := range func_.Func.Cvars() {
for l := func_.Func.Cvars; l != nil; l = l.Next {
v = l.N
v.Name.Param.Closure.Name.Param.Closure = v.Name.Param.Outer v.Name.Param.Closure.Name.Param.Closure = v.Name.Param.Outer
v.Name.Param.Outerexpr = oldname(v.Sym) v.Name.Param.Outerexpr = oldname(v.Sym)
} }
...@@ -78,10 +76,8 @@ func closurebody(body *NodeList) *Node { ...@@ -78,10 +76,8 @@ func closurebody(body *NodeList) *Node {
} }
func typecheckclosure(func_ *Node, top int) { func typecheckclosure(func_ *Node, top int) {
var n *Node for _, ln := range func_.Func.Cvars() {
n := ln.Name.Param.Closure
for l := func_.Func.Cvars; l != nil; l = l.Next {
n = l.N.Name.Param.Closure
if !n.Name.Captured { if !n.Name.Captured {
n.Name.Captured = true n.Name.Captured = true
if n.Name.Decldepth == 0 { if n.Name.Decldepth == 0 {
...@@ -221,7 +217,6 @@ func makeclosure(func_ *Node) *Node { ...@@ -221,7 +217,6 @@ func makeclosure(func_ *Node) *Node {
// We use value capturing for values <= 128 bytes that are never reassigned // We use value capturing for values <= 128 bytes that are never reassigned
// after capturing (effectively constant). // after capturing (effectively constant).
func capturevars(xfunc *Node) { func capturevars(xfunc *Node) {
var v *Node
var outer *Node var outer *Node
lno := int(lineno) lno := int(lineno)
...@@ -229,8 +224,7 @@ func capturevars(xfunc *Node) { ...@@ -229,8 +224,7 @@ func capturevars(xfunc *Node) {
func_ := xfunc.Func.Closure func_ := xfunc.Func.Closure
func_.Func.Enter = nil func_.Func.Enter = nil
for l := func_.Func.Cvars; l != nil; l = l.Next { for _, v := range func_.Func.Cvars() {
v = l.N
if v.Type == nil { if v.Type == nil {
// if v->type is nil, it means v looked like it was // if v->type is nil, it means v looked like it was
// going to be used in the closure but wasn't. // going to be used in the closure but wasn't.
...@@ -310,11 +304,9 @@ func transformclosure(xfunc *Node) { ...@@ -310,11 +304,9 @@ func transformclosure(xfunc *Node) {
original_dcl := xfunc.Func.Dcl original_dcl := xfunc.Func.Dcl
xfunc.Func.Dcl = nil xfunc.Func.Dcl = nil
var v *Node
var addr *Node var addr *Node
var fld *Type var fld *Type
for l := func_.Func.Cvars; l != nil; l = l.Next { for _, v := range func_.Func.Cvars() {
v = l.N
if v.Op == OXXX { if v.Op == OXXX {
continue continue
} }
...@@ -363,10 +355,8 @@ func transformclosure(xfunc *Node) { ...@@ -363,10 +355,8 @@ func transformclosure(xfunc *Node) {
var body *NodeList var body *NodeList
offset := int64(Widthptr) offset := int64(Widthptr)
var addr *Node var addr *Node
var v *Node
var cv *Node var cv *Node
for l := func_.Func.Cvars; l != nil; l = l.Next { for _, v := range func_.Func.Cvars() {
v = l.N
if v.Op == OXXX { if v.Op == OXXX {
continue continue
} }
...@@ -417,7 +407,7 @@ func transformclosure(xfunc *Node) { ...@@ -417,7 +407,7 @@ func transformclosure(xfunc *Node) {
func walkclosure(func_ *Node, init **NodeList) *Node { func walkclosure(func_ *Node, init **NodeList) *Node {
// If no closure vars, don't bother wrapping. // If no closure vars, don't bother wrapping.
if func_.Func.Cvars == nil { if len(func_.Func.Cvars()) == 0 {
return func_.Func.Closure.Func.Nname return func_.Func.Closure.Func.Nname
} }
...@@ -439,9 +429,7 @@ func walkclosure(func_ *Node, init **NodeList) *Node { ...@@ -439,9 +429,7 @@ func walkclosure(func_ *Node, init **NodeList) *Node {
typ.List = list1(Nod(ODCLFIELD, newname(Lookup(".F")), typenod(Types[TUINTPTR]))) typ.List = list1(Nod(ODCLFIELD, newname(Lookup(".F")), typenod(Types[TUINTPTR])))
var typ1 *Node var typ1 *Node
var v *Node for _, v := range func_.Func.Cvars() {
for l := func_.Func.Cvars; l != nil; l = l.Next {
v = l.N
if v.Op == OXXX { if v.Op == OXXX {
continue continue
} }
......
...@@ -426,7 +426,7 @@ func oldname(s *Sym) *Node { ...@@ -426,7 +426,7 @@ func oldname(s *Sym) *Node {
n.Name.Param.Closure = c n.Name.Param.Closure = c
c.Name.Param.Closure = n c.Name.Param.Closure = n
c.Xoffset = 0 c.Xoffset = 0
Curfn.Func.Cvars = list(Curfn.Func.Cvars, c) Curfn.Func.CvarAppend(c)
} }
// return ref to closure var, not original // return ref to closure var, not original
......
...@@ -864,9 +864,7 @@ func esc(e *EscState, n *Node, up *Node) { ...@@ -864,9 +864,7 @@ func esc(e *EscState, n *Node, up *Node) {
// Link addresses of captured variables to closure. // Link addresses of captured variables to closure.
case OCLOSURE: case OCLOSURE:
var a *Node var a *Node
var v *Node for _, v := range n.Func.Cvars() {
for ll := n.Func.Cvars; ll != nil; ll = ll.Next {
v = ll.N
if v.Op == OXXX { // unnamed out argument; see dcl.go:/^funcargs if v.Op == OXXX { // unnamed out argument; see dcl.go:/^funcargs
continue continue
} }
......
...@@ -1137,7 +1137,7 @@ func orderexpr(np **Node, order *Order, lhs *Node) { ...@@ -1137,7 +1137,7 @@ func orderexpr(np **Node, order *Order, lhs *Node) {
} }
case OCLOSURE: case OCLOSURE:
if n.Noescape && n.Func.Cvars != nil { if n.Noescape && len(n.Func.Cvars()) > 0 {
prealloc[n] = ordertemp(Types[TUINT8], order, false) // walk will fill in correct type prealloc[n] = ordertemp(Types[TUINT8], order, false) // walk will fill in correct type
} }
......
...@@ -475,7 +475,7 @@ func staticassign(l *Node, r *Node, out **NodeList) bool { ...@@ -475,7 +475,7 @@ func staticassign(l *Node, r *Node, out **NodeList) bool {
break break
case OCLOSURE: case OCLOSURE:
if r.Func.Cvars == nil { if len(r.Func.Cvars()) == 0 {
// Closures with no captured variables are globals, // Closures with no captured variables are globals,
// so the assignment can be done at link time. // so the assignment can be done at link time.
n := *l n := *l
......
...@@ -151,9 +151,9 @@ type Func struct { ...@@ -151,9 +151,9 @@ type Func struct {
Shortname *Node Shortname *Node
Enter *NodeList Enter *NodeList
Exit *NodeList Exit *NodeList
Cvars *NodeList // closure params cvars *[]*Node // closure params
Dcl []*Node // autodcl for this func/closure Dcl []*Node // autodcl for this func/closure
Inldcl []*Node // copy of dcl for use in inlining Inldcl []*Node // copy of dcl for use in inlining
Closgen int Closgen int
Outerfunc *Node Outerfunc *Node
Fieldtrack []*Type Fieldtrack []*Type
...@@ -177,6 +177,27 @@ type Func struct { ...@@ -177,6 +177,27 @@ type Func struct {
Needctxt bool // function uses context register (has closure variables) Needctxt bool // function uses context register (has closure variables)
} }
// Cvars returns the closure variables for this Func.
// These are referenced variables that are defined in enclosing
// functions.
// The cvars field is a pointer to save space, since most Func values
// have no cvars.
func (f *Func) Cvars() []*Node {
if f.cvars == nil {
return nil
}
return *f.cvars
}
// AppendCvar appends a new closure variable.
func (f *Func) CvarAppend(n *Node) {
if f.cvars == nil {
f.cvars = &[]*Node{n}
} else {
*f.cvars = append(*f.cvars, n)
}
}
type Op uint8 type Op uint8
// Node ops. // Node ops.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment