cmd/compile: change Node.Nbody, Func.Inl from *NodeList to Nodes

Passes toolstash -cmp.

Casual timings show about a 3% improvement in compile times.

Update #14473.

Change-Id: I584add2e8f1a52486ba418b25ba6122b7347b643
Reviewed-on: https://go-review.googlesource.com/19989
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
Ian Lance Taylor 2016-02-27 14:31:33 -08:00
parent 75cc05fa55
commit 1d5001afef
24 changed files with 525 additions and 327 deletions

View file

@ -41,8 +41,8 @@ import (
// Order holds state during the ordering process.
type Order struct {
out *NodeList // list of generated statements
temp []*Node // stack of temporary variables
out []*Node // list of generated statements
temp []*Node // stack of temporary variables
}
// Order rewrites fn->nbody to apply the ordering constraints
@ -50,10 +50,10 @@ type Order struct {
func order(fn *Node) {
if Debug['W'] > 1 {
s := fmt.Sprintf("\nbefore order %v", fn.Func.Nname.Sym)
dumplist(s, fn.Nbody)
dumpslice(s, fn.Nbody.Slice())
}
orderblock(&fn.Nbody)
orderblockNodes(&fn.Nbody)
}
// Ordertemp allocates a new temporary with the given type,
@ -64,7 +64,7 @@ func ordertemp(t *Type, order *Order, clear bool) *Node {
if clear {
a := Nod(OAS, var_, nil)
typecheck(&a, Etop)
order.out = list(order.out, a)
order.out = append(order.out, a)
}
order.temp = append(order.temp, var_)
@ -87,7 +87,7 @@ func ordercopyexpr(n *Node, t *Type, order *Order, clear int) *Node {
var_ := ordertemp(t, order, clear != 0)
a := Nod(OAS, var_, n)
typecheck(&a, Etop)
order.out = list(order.out, a)
order.out = append(order.out, a)
return var_
}
@ -223,7 +223,7 @@ func poptemp(mark ordermarker, order *Order) {
// Cleantempnopop emits to *out VARKILL instructions for each temporary
// above the mark on the temporary stack, but it does not pop them
// from the stack.
func cleantempnopop(mark ordermarker, order *Order, out **NodeList) {
func cleantempnopop(mark ordermarker, order *Order, out *[]*Node) {
var kill *Node
for i := len(order.temp) - 1; i >= int(mark); i-- {
@ -232,11 +232,11 @@ func cleantempnopop(mark ordermarker, order *Order, out **NodeList) {
n.Name.Keepalive = false
kill = Nod(OVARLIVE, n, nil)
typecheck(&kill, Etop)
*out = list(*out, kill)
*out = append(*out, kill)
}
kill = Nod(OVARKILL, n, nil)
typecheck(&kill, Etop)
*out = list(*out, kill)
*out = append(*out, kill)
}
}
@ -254,6 +254,13 @@ func orderstmtlist(l *NodeList, order *Order) {
}
}
// Orderstmtslice orders each of the statements in the slice.
func orderstmtslice(l []*Node, order *Order) {
for _, n := range l {
orderstmt(n, order)
}
}
// Orderblock orders the block of statements *l onto a new list,
// and then replaces *l with that list.
func orderblock(l **NodeList) {
@ -261,7 +268,21 @@ func orderblock(l **NodeList) {
mark := marktemp(&order)
orderstmtlist(*l, &order)
cleantemp(mark, &order)
*l = order.out
var ll *NodeList
for _, n := range order.out {
ll = list(ll, n)
}
*l = ll
}
// OrderblockNodes orders the block of statements in n into a new slice,
// and then replaces the old slice in n with the new slice.
func orderblockNodes(n *Nodes) {
var order Order
mark := marktemp(&order)
orderstmtslice(n.Slice(), &order)
cleantemp(mark, &order)
n.Set(order.out)
}
// Orderexprinplace orders the side effects in *np and
@ -270,7 +291,7 @@ func orderexprinplace(np **Node, outer *Order) {
n := *np
var order Order
orderexpr(&n, &order, nil)
addinit(&n, order.out)
addinitslice(&n, order.out)
// insert new temporaries from order
// at head of outer list.
@ -287,7 +308,7 @@ func orderstmtinplace(np **Node) {
mark := marktemp(&order)
orderstmt(n, &order)
cleantemp(mark, &order)
*np = liststmt(order.out)
*np = liststmtslice(order.out)
}
// Orderinit moves n's init list to order->out.
@ -413,7 +434,7 @@ func ordermapassign(n *Node, order *Order) {
Fatalf("ordermapassign %v", Oconv(int(n.Op), 0))
case OAS:
order.out = list(order.out, n)
order.out = append(order.out, n)
// We call writebarrierfat only for values > 4 pointers long. See walk.go.
if (n.Left.Op == OINDEXMAP || (needwritebarrier(n.Left, n.Right) && n.Left.Type.Width > int64(4*Widthptr))) && !isaddrokay(n.Right) {
@ -421,11 +442,11 @@ func ordermapassign(n *Node, order *Order) {
n.Left = ordertemp(m.Type, order, false)
a := Nod(OAS, m, n.Left)
typecheck(&a, Etop)
order.out = list(order.out, a)
order.out = append(order.out, a)
}
case OAS2, OAS2DOTTYPE, OAS2MAPR, OAS2FUNC:
var post *NodeList
var post []*Node
var m *Node
var a *Node
for l := n.List; l != nil; l = l.Next {
@ -440,18 +461,18 @@ func ordermapassign(n *Node, order *Order) {
l.N = ordertemp(m.Type, order, false)
a = Nod(OAS, m, l.N)
typecheck(&a, Etop)
post = list(post, a)
post = append(post, a)
} else if instrumenting && n.Op == OAS2FUNC && !isblank(l.N) {
m = l.N
l.N = ordertemp(m.Type, order, false)
a = Nod(OAS, m, l.N)
typecheck(&a, Etop)
post = list(post, a)
post = append(post, a)
}
}
order.out = list(order.out, n)
order.out = concat(order.out, post)
order.out = append(order.out, n)
order.out = append(order.out, post...)
}
}
@ -472,7 +493,7 @@ func orderstmt(n *Node, order *Order) {
Fatalf("orderstmt %v", Oconv(int(n.Op), 0))
case OVARKILL, OVARLIVE:
order.out = list(order.out, n)
order.out = append(order.out, n)
case OAS:
t := marktemp(order)
@ -497,7 +518,7 @@ func orderstmt(n *Node, order *Order) {
case OAS2, OAS2DOTTYPE:
ordermapassign(n, order)
default:
order.out = list(order.out, n)
order.out = append(order.out, n)
}
cleantemp(t, order)
@ -561,11 +582,11 @@ func orderstmt(n *Node, order *Order) {
orderexprlist(n.List, order)
orderexpr(&n.Rlist.N.Left, order, nil) // i in i.(T)
if isblank(n.List.N) {
order.out = list(order.out, n)
order.out = append(order.out, n)
} else {
typ := n.Rlist.N.Type
tmp1 := ordertemp(typ, order, haspointers(typ))
order.out = list(order.out, n)
order.out = append(order.out, n)
r := Nod(OAS, n.List.N, tmp1)
typecheck(&r, Etop)
ordermapassign(r, order)
@ -589,7 +610,7 @@ func orderstmt(n *Node, order *Order) {
} else {
tmp2 = ordertemp(Types[TBOOL], order, false)
}
order.out = list(order.out, n)
order.out = append(order.out, n)
r := Nod(OAS, n.List.N, tmp1)
typecheck(&r, Etop)
ordermapassign(r, order)
@ -614,14 +635,14 @@ func orderstmt(n *Node, order *Order) {
OGOTO,
OLABEL,
ORETJMP:
order.out = list(order.out, n)
order.out = append(order.out, n)
// Special: handle call arguments.
case OCALLFUNC, OCALLINTER, OCALLMETH:
t := marktemp(order)
ordercall(n, order)
order.out = list(order.out, n)
order.out = append(order.out, n)
cleantemp(t, order)
// Special: order arguments to inner call but not call itself.
@ -644,7 +665,7 @@ func orderstmt(n *Node, order *Order) {
ordercall(n.Left, order)
}
order.out = list(order.out, n)
order.out = append(order.out, n)
cleantemp(t, order)
case ODELETE:
@ -652,7 +673,7 @@ func orderstmt(n *Node, order *Order) {
orderexpr(&n.List.N, order, nil)
orderexpr(&n.List.Next.N, order, nil)
orderaddrtemp(&n.List.Next.N, order) // map key
order.out = list(order.out, n)
order.out = append(order.out, n)
cleantemp(t, order)
// Clean temporaries from condition evaluation at
@ -661,12 +682,12 @@ func orderstmt(n *Node, order *Order) {
t := marktemp(order)
orderexprinplace(&n.Left, order)
var l *NodeList
var l []*Node
cleantempnopop(t, order, &l)
n.Nbody = concat(l, n.Nbody)
orderblock(&n.Nbody)
n.Nbody.Set(append(l, n.Nbody.Slice()...))
orderblockNodes(&n.Nbody)
orderstmtinplace(&n.Right)
order.out = list(order.out, n)
order.out = append(order.out, n)
cleantemp(t, order)
// Clean temporaries from condition at
@ -675,16 +696,20 @@ func orderstmt(n *Node, order *Order) {
t := marktemp(order)
orderexprinplace(&n.Left, order)
var l *NodeList
var l []*Node
cleantempnopop(t, order, &l)
n.Nbody = concat(l, n.Nbody)
n.Nbody.Set(append(l, n.Nbody.Slice()...))
l = nil
cleantempnopop(t, order, &l)
n.Rlist = concat(l, n.Rlist)
var ll *NodeList
for _, n := range l {
ll = list(ll, n)
}
n.Rlist = concat(ll, n.Rlist)
poptemp(t, order)
orderblock(&n.Nbody)
orderblockNodes(&n.Nbody)
orderblock(&n.Rlist)
order.out = list(order.out, n)
order.out = append(order.out, n)
// Special: argument will be converted to interface using convT2E
// so make sure it is an addressable temporary.
@ -695,7 +720,7 @@ func orderstmt(n *Node, order *Order) {
if !Isinter(n.Left.Type) {
orderaddrtemp(&n.Left, order)
}
order.out = list(order.out, n)
order.out = append(order.out, n)
cleantemp(t, order)
// n->right is the expression being ranged over.
@ -756,13 +781,13 @@ func orderstmt(n *Node, order *Order) {
for l := n.List; l != nil; l = l.Next {
orderexprinplace(&l.N, order)
}
orderblock(&n.Nbody)
order.out = list(order.out, n)
orderblockNodes(&n.Nbody)
order.out = append(order.out, n)
cleantemp(t, order)
case ORETURN:
ordercallargs(&n.List, order)
order.out = list(order.out, n)
order.out = append(order.out, n)
// Special: clean case temporaries in each block entry.
// Select must enter one of its blocks, so there is no
@ -897,19 +922,23 @@ func orderstmt(n *Node, order *Order) {
}
}
orderblock(&l.N.Nbody)
orderblockNodes(&l.N.Nbody)
}
// Now that we have accumulated all the temporaries, clean them.
// Also insert any ninit queued during the previous loop.
// (The temporary cleaning must follow that ninit work.)
for l := n.List; l != nil; l = l.Next {
cleantempnopop(t, order, &l.N.Ninit)
l.N.Nbody = concat(l.N.Ninit, l.N.Nbody)
s := make([]*Node, 0, count(l.N.Ninit))
for ll := l.N.Ninit; ll != nil; ll = ll.Next {
s = append(s, ll.N)
}
cleantempnopop(t, order, &s)
l.N.Nbody.Set(append(s, l.N.Nbody.Slice()...))
l.N.Ninit = nil
}
order.out = list(order.out, n)
order.out = append(order.out, n)
poptemp(t, order)
// Special: value being sent is passed as a pointer; make it addressable.
@ -919,7 +948,7 @@ func orderstmt(n *Node, order *Order) {
orderexpr(&n.Left, order, nil)
orderexpr(&n.Right, order, nil)
orderaddrtemp(&n.Right, order)
order.out = list(order.out, n)
order.out = append(order.out, n)
cleantemp(t, order)
// TODO(rsc): Clean temporaries more aggressively.
@ -938,10 +967,10 @@ func orderstmt(n *Node, order *Order) {
Fatalf("order switch case %v", Oconv(int(l.N.Op), 0))
}
orderexprlistinplace(l.N.List, order)
orderblock(&l.N.Nbody)
orderblockNodes(&l.N.Nbody)
}
order.out = list(order.out, n)
order.out = append(order.out, n)
cleantemp(t, order)
}
@ -1080,9 +1109,13 @@ func orderexpr(np **Node, order *Order, lhs *Node) {
// Clean temporaries from first branch at beginning of second.
// Leave them on the stack so that they can be killed in the outer
// context in case the short circuit is taken.
var l *NodeList
var s []*Node
cleantempnopop(mark, order, &l)
cleantempnopop(mark, order, &s)
var l *NodeList
for _, n := range s {
l = list(l, n)
}
n.Right.Ninit = concat(l, n.Right.Ninit)
orderexprinplace(&n.Right, order)