Commit c907a754 authored by Martin Möhrmann's avatar Martin Möhrmann

cmd/compile: refactor appendslice to use newer gc code style

- add comments with builtin function signatures that are instantiated
- use Nodes type from the beginning instead of
  []*Node with a later conversion to Nodes
- use conv(x, y) helper function instead of nod(OCONV, x, y)
- factor out repeated calls to Type.Elem()

This makes the function style similar to newer functions like extendslice.

passes toolstash -cmp

Change-Id: Iedab191af9e0884fb6762c9c168430c1d2246979
Reviewed-on: https://go-review.googlesource.com/112598
Run-TryBot: Martin Möhrmann <moehrmann@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 379d2dea
...@@ -2950,92 +2950,93 @@ func appendslice(n *Node, init *Nodes) *Node { ...@@ -2950,92 +2950,93 @@ func appendslice(n *Node, init *Nodes) *Node {
l1 := n.List.First() l1 := n.List.First()
l2 := n.List.Second() l2 := n.List.Second()
var l []*Node var nodes Nodes
// var s []T // var s []T
s := temp(l1.Type) s := temp(l1.Type)
l = append(l, nod(OAS, s, l1)) // s = l1 nodes.Append(nod(OAS, s, l1)) // s = l1
elemtype := s.Type.Elem()
// n := len(s) + len(l2) // n := len(s) + len(l2)
nn := temp(types.Types[TINT]) nn := temp(types.Types[TINT])
l = append(l, nod(OAS, nn, nod(OADD, nod(OLEN, s, nil), nod(OLEN, l2, nil)))) nodes.Append(nod(OAS, nn, nod(OADD, nod(OLEN, s, nil), nod(OLEN, l2, nil))))
// if uint(n) > uint(cap(s)) // if uint(n) > uint(cap(s))
nif := nod(OIF, nil, nil) nif := nod(OIF, nil, nil)
nif.Left = nod(OGT, nod(OCONV, nn, nil), nod(OCONV, nod(OCAP, s, nil), nil)) nuint := conv(nn, types.Types[TUINT])
nif.Left.Left.Type = types.Types[TUINT] scapuint := conv(nod(OCAP, s, nil), types.Types[TUINT])
nif.Left.Right.Type = types.Types[TUINT] nif.Left = nod(OGT, nuint, scapuint)
// instantiate growslice(Type*, []any, int) []any // instantiate growslice(typ *type, []any, int) []any
fn := syslook("growslice") fn := syslook("growslice")
fn = substArgTypes(fn, s.Type.Elem(), s.Type.Elem()) fn = substArgTypes(fn, elemtype, elemtype)
// s = growslice(T, s, n) // s = growslice(T, s, n)
nif.Nbody.Set1(nod(OAS, s, mkcall1(fn, s.Type, &nif.Ninit, typename(s.Type.Elem()), s, nn))) nif.Nbody.Set1(nod(OAS, s, mkcall1(fn, s.Type, &nif.Ninit, typename(elemtype), s, nn)))
l = append(l, nif) nodes.Append(nif)
// s = s[:n] // s = s[:n]
nt := nod(OSLICE, s, nil) nt := nod(OSLICE, s, nil)
nt.SetSliceBounds(nil, nn, nil) nt.SetSliceBounds(nil, nn, nil)
l = append(l, nod(OAS, s, nt)) nodes.Append(nod(OAS, s, nt))
if l1.Type.Elem().HasHeapPointer() { var ncopy *Node
if elemtype.HasHeapPointer() {
// copy(s[len(l1):], l2) // copy(s[len(l1):], l2)
nptr1 := nod(OSLICE, s, nil) nptr1 := nod(OSLICE, s, nil)
nptr1.SetSliceBounds(nod(OLEN, l1, nil), nil, nil) nptr1.SetSliceBounds(nod(OLEN, l1, nil), nil, nil)
nptr2 := l2 nptr2 := l2
Curfn.Func.setWBPos(n.Pos) Curfn.Func.setWBPos(n.Pos)
// instantiate typedslicecopy(typ *type, dst any, src any) int
fn := syslook("typedslicecopy") fn := syslook("typedslicecopy")
fn = substArgTypes(fn, l1.Type, l2.Type) fn = substArgTypes(fn, l1.Type, l2.Type)
var ln Nodes ncopy = mkcall1(fn, types.Types[TINT], &nodes, typename(elemtype), nptr1, nptr2)
ln.Set(l)
nt := mkcall1(fn, types.Types[TINT], &ln, typename(l1.Type.Elem()), nptr1, nptr2)
l = append(ln.Slice(), nt)
} else if instrumenting && !compiling_runtime { } else if instrumenting && !compiling_runtime {
// rely on runtime to instrument copy. // rely on runtime to instrument copy.
// copy(s[len(l1):], l2) // copy(s[len(l1):], l2)
nptr1 := nod(OSLICE, s, nil) nptr1 := nod(OSLICE, s, nil)
nptr1.SetSliceBounds(nod(OLEN, l1, nil), nil, nil) nptr1.SetSliceBounds(nod(OLEN, l1, nil), nil, nil)
nptr2 := l2 nptr2 := l2
var ln Nodes
ln.Set(l)
var nt *Node
if l2.Type.IsString() { if l2.Type.IsString() {
// instantiate func slicestringcopy(to any, fr any) int
fn := syslook("slicestringcopy") fn := syslook("slicestringcopy")
fn = substArgTypes(fn, l1.Type, l2.Type) fn = substArgTypes(fn, l1.Type, l2.Type)
nt = mkcall1(fn, types.Types[TINT], &ln, nptr1, nptr2) ncopy = mkcall1(fn, types.Types[TINT], &nodes, nptr1, nptr2)
} else { } else {
// instantiate func slicecopy(to any, fr any, wid uintptr) int
fn := syslook("slicecopy") fn := syslook("slicecopy")
fn = substArgTypes(fn, l1.Type, l2.Type) fn = substArgTypes(fn, l1.Type, l2.Type)
nt = mkcall1(fn, types.Types[TINT], &ln, nptr1, nptr2, nodintconst(s.Type.Elem().Width)) ncopy = mkcall1(fn, types.Types[TINT], &nodes, nptr1, nptr2, nodintconst(elemtype.Width))
} }
l = append(ln.Slice(), nt)
} else { } else {
// memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T)) // memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T))
nptr1 := nod(OINDEX, s, nod(OLEN, l1, nil)) nptr1 := nod(OINDEX, s, nod(OLEN, l1, nil))
nptr1.SetBounded(true) nptr1.SetBounded(true)
nptr1 = nod(OADDR, nptr1, nil) nptr1 = nod(OADDR, nptr1, nil)
nptr2 := nod(OSPTR, l2, nil) nptr2 := nod(OSPTR, l2, nil)
fn := syslook("memmove") nwid := cheapexpr(conv(nod(OLEN, l2, nil), types.Types[TUINTPTR]), &nodes)
fn = substArgTypes(fn, s.Type.Elem(), s.Type.Elem()) nwid = nod(OMUL, nwid, nodintconst(elemtype.Width))
var ln Nodes
ln.Set(l)
nwid := cheapexpr(conv(nod(OLEN, l2, nil), types.Types[TUINTPTR]), &ln)
nwid = nod(OMUL, nwid, nodintconst(s.Type.Elem().Width)) // instantiate func memmove(to *any, frm *any, length uintptr)
nt := mkcall1(fn, nil, &ln, nptr1, nptr2, nwid) fn := syslook("memmove")
l = append(ln.Slice(), nt) fn = substArgTypes(fn, elemtype, elemtype)
ncopy = mkcall1(fn, nil, &nodes, nptr1, nptr2, nwid)
} }
ln := append(nodes.Slice(), ncopy)
typecheckslice(l, Etop) typecheckslice(ln, Etop)
walkstmtlist(l) walkstmtlist(ln)
init.Append(l...) init.Append(ln...)
return s return s
} }
......
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