Commit 7758a940 authored by Matthew Dempsky's avatar Matthew Dempsky

cmd/compile: simplify Iter

Passes toolstash -cmp.

Change-Id: I325b02dcc8412ded0dc304d43377c0bdf59c66a8
Reviewed-on: https://go-review.googlesource.com/20405Reviewed-by: default avatarDavid Crawshaw <crawshaw@golang.org>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 50114312
...@@ -295,9 +295,9 @@ func dowidth(t *Type) { ...@@ -295,9 +295,9 @@ func dowidth(t *Type) {
case TFUNCARGS: case TFUNCARGS:
t1 := t.Type t1 := t.Type
w = widstruct(t.Type, *getthis(t1), 0, 0) w = widstruct(t.Type, getthisx(t1), 0, 0)
w = widstruct(t.Type, *getinarg(t1), w, Widthreg) w = widstruct(t.Type, getinargx(t1), w, Widthreg)
w = widstruct(t.Type, *Getoutarg(t1), w, Widthreg) w = widstruct(t.Type, getoutargx(t1), w, Widthreg)
t1.Argwid = w t1.Argwid = w
if w%int64(Widthreg) != 0 { if w%int64(Widthreg) != 0 {
Warn("bad type %v %d\n", t1, w) Warn("bad type %v %d\n", t1, w)
...@@ -616,27 +616,18 @@ func typeinit() { ...@@ -616,27 +616,18 @@ func typeinit() {
// compute total size of f's in/out arguments. // compute total size of f's in/out arguments.
func Argsize(t *Type) int { func Argsize(t *Type) int {
var save Iter var w int64
var x int64
w := int64(0)
fp := Structfirst(&save, Getoutarg(t)) for fp, ip := IterFields(getoutargx(t)); fp != nil; fp = ip.Next() {
for fp != nil { if x := fp.Width + fp.Type.Width; x > w {
x = fp.Width + fp.Type.Width
if x > w {
w = x w = x
} }
fp = structnext(&save)
} }
fp = funcfirst(&save, t) for fp, ip := IterParams(t); fp != nil; fp = ip.Next() {
for fp != nil { if x := fp.Width + fp.Type.Width; x > w {
x = fp.Width + fp.Type.Width
if x > w {
w = x w = x
} }
fp = funcnext(&save)
} }
w = (w + int64(Widthptr) - 1) &^ (int64(Widthptr) - 1) w = (w + int64(Widthptr) - 1) &^ (int64(Widthptr) - 1)
......
...@@ -1677,8 +1677,7 @@ func Igen(n *Node, a *Node, res *Node) { ...@@ -1677,8 +1677,7 @@ func Igen(n *Node, a *Node, res *Node) {
cgen_callinter(n, nil, 0) cgen_callinter(n, nil, 0)
} }
var flist Iter fp, _ := IterFields(getoutargx(n.Left.Type))
fp := Structfirst(&flist, Getoutarg(n.Left.Type))
*a = Node{} *a = Node{}
a.Op = OINDREG a.Op = OINDREG
a.Reg = int16(Thearch.REGSP) a.Reg = int16(Thearch.REGSP)
...@@ -2226,8 +2225,7 @@ func stkof(n *Node) int64 { ...@@ -2226,8 +2225,7 @@ func stkof(n *Node) int64 {
t = t.Type t = t.Type
} }
var flist Iter t, _ = IterFields(getoutargx(t))
t = Structfirst(&flist, Getoutarg(t))
if t != nil { if t != nil {
return t.Width + Ctxt.FixedFrameSize() return t.Width + Ctxt.FixedFrameSize()
} }
...@@ -2563,8 +2561,7 @@ func cgen_callret(n *Node, res *Node) { ...@@ -2563,8 +2561,7 @@ func cgen_callret(n *Node, res *Node) {
t = t.Type t = t.Type
} }
var flist Iter fp, _ := IterFields(getoutargx(t))
fp := Structfirst(&flist, Getoutarg(t))
if fp == nil { if fp == nil {
Fatalf("cgen_callret: nil") Fatalf("cgen_callret: nil")
} }
...@@ -2588,8 +2585,7 @@ func cgen_aret(n *Node, res *Node) { ...@@ -2588,8 +2585,7 @@ func cgen_aret(n *Node, res *Node) {
t = t.Type t = t.Type
} }
var flist Iter fp, _ := IterFields(getoutargx(t))
fp := Structfirst(&flist, Getoutarg(t))
if fp == nil { if fp == nil {
Fatalf("cgen_aret: nil") Fatalf("cgen_aret: nil")
} }
......
...@@ -548,8 +548,7 @@ func nodarg(t *Type, fp int) *Node { ...@@ -548,8 +548,7 @@ func nodarg(t *Type, fp int) *Node {
n = Nod(ONAME, nil, nil) n = Nod(ONAME, nil, nil)
n.Sym = Lookup(".args") n.Sym = Lookup(".args")
n.Type = t n.Type = t
var savet Iter first, _ := IterFields(t)
first := Structfirst(&savet, &t)
if first == nil { if first == nil {
Fatalf("nodarg: bad struct") Fatalf("nodarg: bad struct")
} }
......
...@@ -338,8 +338,7 @@ func copyret(n *Node, order *Order) Nodes { ...@@ -338,8 +338,7 @@ func copyret(n *Node, order *Order) Nodes {
var l1 []*Node var l1 []*Node
var l2 []*Node var l2 []*Node
var tl Iter for t, it := IterFields(n.Type); t != nil; t = it.Next() {
for t := Structfirst(&tl, &n.Type); t != nil; t = structnext(&tl) {
tmp := temp(t.Type) tmp := temp(t.Type)
l1 = append(l1, tmp) l1 = append(l1, tmp)
l2 = append(l2, tmp) l2 = append(l2, tmp)
......
...@@ -377,8 +377,7 @@ func compile(fn *Node) { ...@@ -377,8 +377,7 @@ func compile(fn *Node) {
if Curfn.Type.Outnamed { if Curfn.Type.Outnamed {
// add clearing of the output parameters // add clearing of the output parameters
var save Iter for t, it := IterFields(getoutargx(Curfn.Type)); t != nil; t = it.Next() {
for t := Structfirst(&save, Getoutarg(Curfn.Type)); t != nil; t = structnext(&save) {
if t.Nname != nil { if t.Nname != nil {
n := Nod(OAS, t.Nname, nil) n := Nod(OAS, t.Nname, nil)
typecheck(&n, Etop) typecheck(&n, Etop)
......
...@@ -2407,8 +2407,7 @@ func (s *state) call(n *Node, k callKind) *ssa.Value { ...@@ -2407,8 +2407,7 @@ func (s *state) call(n *Node, k callKind) *ssa.Value {
// Start exit block, find address of result. // Start exit block, find address of result.
s.startBlock(bNext) s.startBlock(bNext)
var titer Iter fp, _ := IterFields(getoutargx(n.Left.Type))
fp := Structfirst(&titer, Getoutarg(n.Left.Type))
if fp == nil || k != callNormal { if fp == nil || k != callNormal {
// call has no return value. Continue with the next statement. // call has no return value. Continue with the next statement.
return nil return nil
......
...@@ -1892,14 +1892,13 @@ func expandmeth(t *Type) { ...@@ -1892,14 +1892,13 @@ func expandmeth(t *Type) {
// Given funarg struct list, return list of ODCLFIELD Node fn args. // Given funarg struct list, return list of ODCLFIELD Node fn args.
func structargs(tl **Type, mustname int) []*Node { func structargs(tl **Type, mustname int) []*Node {
var savet Iter
var a *Node var a *Node
var n *Node var n *Node
var buf string var buf string
var args []*Node var args []*Node
gen := 0 gen := 0
for t := Structfirst(&savet, tl); t != nil; t = structnext(&savet) { for t, it := IterFields(*tl); t != nil; t = it.Next() {
n = nil n = nil
if mustname != 0 && (t.Sym == nil || t.Sym.Name == "_") { if mustname != 0 && (t.Sym == nil || t.Sym.Name == "_") {
// invent a name so that we can refer to it in the trampoline // invent a name so that we can refer to it in the trampoline
...@@ -2250,10 +2249,8 @@ func liststmt(l []*Node) *Node { ...@@ -2250,10 +2249,8 @@ func liststmt(l []*Node) *Node {
// return nelem of list // return nelem of list
func structcount(t *Type) int { func structcount(t *Type) int {
var s Iter
v := 0 v := 0
for t = Structfirst(&s, &t); t != nil; t = structnext(&s) { for t, it := IterFields(t); t != nil; t = it.Next() {
v++ v++
} }
return v return v
......
...@@ -164,103 +164,50 @@ type Type struct { ...@@ -164,103 +164,50 @@ type Type struct {
Lastfn *Node // for usefield Lastfn *Node // for usefield
} }
// Iter provides an abstraction for iterating across struct fields // Iter provides an abstraction for iterating across struct fields,
// and function parameters. // interface methods, and function parameters.
type Iter struct { type Iter struct {
Done int a, b *Type
Tfunc *Type
T *Type
} }
// iterator to walk a structure declaration // IterFields returns the first field or method in struct or interface type t
func Structfirst(s *Iter, nn **Type) *Type { // and an Iter value to continue iterating across the rest.
var t *Type func IterFields(t *Type) (*Type, Iter) {
if t.Etype != TSTRUCT && t.Etype != TINTER {
n := *nn Fatalf("IterFields: type %v does not have fields", t)
if n == nil {
goto bad
}
switch n.Etype {
default:
goto bad
case TSTRUCT, TINTER, TFUNC:
break
}
t = n.Type
if t == nil {
return nil
} }
i := Iter{a: t.Type}
f := i.Next()
return f, i
}
if t.Etype != TFIELD { // IterParams returns the first reeiver or input parameter in function type t
Fatalf("structfirst: not field %v", t) // and an Iter value to continue iterating across the rest.
func IterParams(t *Type) (*Type, Iter) {
if t.Etype != TFUNC {
Fatalf("IterParams: type %v does not have params", t)
} }
i := Iter{a: getthisx(t).Type, b: getinargx(t).Type}
s.T = t f := i.Next()
return t return f, i
bad:
Fatalf("structfirst: not struct %v", n)
return nil
} }
func structnext(s *Iter) *Type { // Next returns the next field, method, or parameter, if any.
n := s.T func (i *Iter) Next() *Type {
t := n.Down if i.a == nil {
if t == nil { if i.b == nil {
return nil return nil
}
i.a, i.b = i.b, nil
} }
t := i.a
if t.Etype != TFIELD { if t.Etype != TFIELD {
Fatalf("structnext: not struct %v", n) Fatalf("Iter.Next: type %v is not a field", t)
return nil
} }
i.a = t.Down
s.T = t
return t return t
} }
// iterator to this and inargs in a function
func funcfirst(s *Iter, t *Type) *Type {
var fp *Type
if t == nil {
goto bad
}
if t.Etype != TFUNC {
goto bad
}
s.Tfunc = t
s.Done = 0
fp = Structfirst(s, getthis(t))
if fp == nil {
s.Done = 1
fp = Structfirst(s, getinarg(t))
}
return fp
bad:
Fatalf("funcfirst: not func %v", t)
return nil
}
func funcnext(s *Iter) *Type {
fp := structnext(s)
if fp == nil && s.Done == 0 {
s.Done = 1
fp = Structfirst(s, getinarg(s.Tfunc))
}
return fp
}
func getthis(t *Type) **Type { func getthis(t *Type) **Type {
if t.Etype != TFUNC { if t.Etype != TFUNC {
Fatalf("getthis: not a func %v", t) Fatalf("getthis: not a func %v", t)
......
...@@ -3371,8 +3371,7 @@ func typecheckas2(n *Node) { ...@@ -3371,8 +3371,7 @@ func typecheckas2(n *Node) {
goto mismatch goto mismatch
} }
n.Op = OAS2FUNC n.Op = OAS2FUNC
var s Iter t, s := IterFields(r.Type)
t := Structfirst(&s, &r.Type)
for it := nodeSeqIterate(n.List); !it.Done(); it.Next() { for it := nodeSeqIterate(n.List); !it.Done(); it.Next() {
if t.Type != nil && it.N().Type != nil { if t.Type != nil && it.N().Type != nil {
checkassignto(t.Type, it.N()) checkassignto(t.Type, it.N())
...@@ -3380,7 +3379,7 @@ func typecheckas2(n *Node) { ...@@ -3380,7 +3379,7 @@ func typecheckas2(n *Node) {
if it.N().Name != nil && it.N().Name.Defn == n && it.N().Name.Param.Ntype == nil { if it.N().Name != nil && it.N().Name.Defn == n && it.N().Name.Param.Ntype == nil {
it.N().Type = t.Type it.N().Type = t.Type
} }
t = structnext(&s) t = s.Next()
} }
goto out goto out
......
...@@ -1706,12 +1706,11 @@ func ascompatet(op Op, nl Nodes, nr **Type, fp int, init *Nodes) []*Node { ...@@ -1706,12 +1706,11 @@ func ascompatet(op Op, nl Nodes, nr **Type, fp int, init *Nodes) []*Node {
var l *Node var l *Node
var tmp *Node var tmp *Node
var a *Node var a *Node
var saver Iter
// check assign type list to // check assign type list to
// a expression list. called in // a expression list. called in
// expr-list = func() // expr-list = func()
r := Structfirst(&saver, nr) r, saver := IterFields(*nr)
var nn []*Node var nn []*Node
var mm []*Node var mm []*Node
...@@ -1723,7 +1722,7 @@ func ascompatet(op Op, nl Nodes, nr **Type, fp int, init *Nodes) []*Node { ...@@ -1723,7 +1722,7 @@ func ascompatet(op Op, nl Nodes, nr **Type, fp int, init *Nodes) []*Node {
} }
l = it.N() l = it.N()
if isblank(l) { if isblank(l) {
r = structnext(&saver) r = saver.Next()
continue continue
} }
...@@ -1748,7 +1747,7 @@ func ascompatet(op Op, nl Nodes, nr **Type, fp int, init *Nodes) []*Node { ...@@ -1748,7 +1747,7 @@ func ascompatet(op Op, nl Nodes, nr **Type, fp int, init *Nodes) []*Node {
} }
nn = append(nn, a) nn = append(nn, a)
r = structnext(&saver) r = saver.Next()
} }
if !it.Done() || r != nil { if !it.Done() || r != nil {
...@@ -1797,12 +1796,10 @@ func mkdotargslice(lr0, nn []*Node, l *Type, fp int, init *Nodes, ddd *Node) []* ...@@ -1797,12 +1796,10 @@ func mkdotargslice(lr0, nn []*Node, l *Type, fp int, init *Nodes, ddd *Node) []*
// helpers for shape errors // helpers for shape errors
func dumptypes(nl **Type, what string) string { func dumptypes(nl **Type, what string) string {
var savel Iter
fmt_ := "" fmt_ := ""
fmt_ += "\t" fmt_ += "\t"
first := 1 first := 1
for l := Structfirst(&savel, nl); l != nil; l = structnext(&savel) { for l, it := IterFields(*nl); l != nil; l = it.Next() {
if first != 0 { if first != 0 {
first = 0 first = 0
} else { } else {
...@@ -1844,10 +1841,8 @@ func dumpnodetypes(l []*Node, what string) string { ...@@ -1844,10 +1841,8 @@ func dumpnodetypes(l []*Node, what string) string {
// return expr-list // return expr-list
// func(expr-list) // func(expr-list)
func ascompatte(op Op, call *Node, isddd bool, nl **Type, lr []*Node, fp int, init *Nodes) []*Node { func ascompatte(op Op, call *Node, isddd bool, nl **Type, lr []*Node, fp int, init *Nodes) []*Node {
var savel Iter
lr0 := lr lr0 := lr
l := Structfirst(&savel, nl) l, savel := IterFields(*nl)
var r *Node var r *Node
if nodeSeqLen(lr) > 0 { if nodeSeqLen(lr) > 0 {
r = nodeSeqFirst(lr) r = nodeSeqFirst(lr)
...@@ -1873,7 +1868,7 @@ func ascompatte(op Op, call *Node, isddd bool, nl **Type, lr []*Node, fp int, in ...@@ -1873,7 +1868,7 @@ func ascompatte(op Op, call *Node, isddd bool, nl **Type, lr []*Node, fp int, in
// copy into temporaries. // copy into temporaries.
var alist []*Node var alist []*Node
for l := Structfirst(&savel, &r.Type); l != nil; l = structnext(&savel) { for l, it := IterFields(r.Type); l != nil; l = it.Next() {
a = temp(l.Type) a = temp(l.Type)
alist = append(alist, a) alist = append(alist, a)
} }
...@@ -1886,13 +1881,13 @@ func ascompatte(op Op, call *Node, isddd bool, nl **Type, lr []*Node, fp int, in ...@@ -1886,13 +1881,13 @@ func ascompatte(op Op, call *Node, isddd bool, nl **Type, lr []*Node, fp int, in
init.Append(a) init.Append(a)
lr = alist lr = alist
r = nodeSeqFirst(lr) r = nodeSeqFirst(lr)
l = Structfirst(&savel, nl) l, savel = IterFields(*nl)
} }
loop: loop:
if l != nil && l.Isddd { if l != nil && l.Isddd {
// the ddd parameter must be last // the ddd parameter must be last
ll = structnext(&savel) ll = savel.Next()
if ll != nil { if ll != nil {
Yyerror("... must be last argument") Yyerror("... must be last argument")
...@@ -1935,7 +1930,7 @@ loop: ...@@ -1935,7 +1930,7 @@ loop:
a = convas(a, init) a = convas(a, init)
nn = append(nn, a) nn = append(nn, a)
l = structnext(&savel) l = savel.Next()
r = nil r = nil
lr = lr[1:] lr = lr[1:]
if len(lr) > 0 { if len(lr) > 0 {
...@@ -2036,7 +2031,7 @@ func walkprint(nn *Node, init *Nodes) *Node { ...@@ -2036,7 +2031,7 @@ func walkprint(nn *Node, init *Nodes) *Node {
continue continue
} }
t = *getinarg(on.Type) t = getinargx(on.Type)
if t != nil { if t != nil {
t = t.Type t = t.Type
} }
...@@ -2590,12 +2585,11 @@ func vmatch1(l *Node, r *Node) bool { ...@@ -2590,12 +2585,11 @@ func vmatch1(l *Node, r *Node) bool {
// generate and return code to allocate // generate and return code to allocate
// copies of escaped parameters to the heap. // copies of escaped parameters to the heap.
func paramstoheap(argin **Type, out int) []*Node { func paramstoheap(argin **Type, out int) []*Node {
var savet Iter
var v *Node var v *Node
var as *Node var as *Node
var nn []*Node var nn []*Node
for t := Structfirst(&savet, argin); t != nil; t = structnext(&savet) { for t, it := IterFields(*argin); t != nil; t = it.Next() {
v = t.Nname v = t.Nname
if v != nil && v.Sym != nil && v.Sym.Name[0] == '~' && v.Sym.Name[1] == 'r' { // unnamed result if v != nil && v.Sym != nil && v.Sym.Name[0] == '~' && v.Sym.Name[1] == 'r' { // unnamed result
v = nil v = nil
...@@ -2636,11 +2630,10 @@ func paramstoheap(argin **Type, out int) []*Node { ...@@ -2636,11 +2630,10 @@ func paramstoheap(argin **Type, out int) []*Node {
// walk through argout parameters copying back to stack // walk through argout parameters copying back to stack
func returnsfromheap(argin **Type) []*Node { func returnsfromheap(argin **Type) []*Node {
var savet Iter
var v *Node var v *Node
var nn []*Node var nn []*Node
for t := Structfirst(&savet, argin); t != nil; t = structnext(&savet) { for t, it := IterFields(*argin); t != nil; t = it.Next() {
v = t.Nname v = t.Nname
if v == nil || v.Class != PHEAP|PPARAMOUT { if v == nil || v.Class != PHEAP|PPARAMOUT {
continue continue
......
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