cmd/compile: stop adding implicit OKEY nodes

Keys are uncommon in array and slice literals, and normalizing
OARRAYLIT and OSLICELIT nodes to always use OKEY ends up not reducing
complexity much. Instead, only create OKEY nodes to represent explicit
keys, and recalculate implicit keys when/where necessary.

Fixes #15350.

name       old time/op     new time/op     delta
Template       299ms ± 9%      299ms ±12%    ~           (p=0.694 n=28+30)
Unicode        165ms ± 7%      162ms ± 9%    ~           (p=0.084 n=27+27)
GoTypes        950ms ± 9%      963ms ± 5%    ~           (p=0.301 n=30+29)
Compiler       4.23s ± 7%      4.17s ± 7%    ~           (p=0.057 n=29+27)

name       old user-ns/op  new user-ns/op  delta
Template        389M ±15%       400M ±12%    ~           (p=0.202 n=30+29)
Unicode         246M ±21%       232M ±22%  -5.76%        (p=0.006 n=28+29)
GoTypes        1.34G ± 8%      1.34G ± 7%    ~           (p=0.775 n=28+30)
Compiler       5.91G ± 6%      5.87G ± 7%    ~           (p=0.298 n=28+29)

name       old alloc/op    new alloc/op    delta
Template      41.2MB ± 0%     41.2MB ± 0%    ~           (p=0.085 n=30+30)
Unicode       34.0MB ± 0%     31.5MB ± 0%  -7.28%        (p=0.000 n=30+29)
GoTypes        121MB ± 0%      121MB ± 0%    ~           (p=0.657 n=30+30)
Compiler       511MB ± 0%      511MB ± 0%  -0.01%        (p=0.001 n=29+29)

name       old allocs/op   new allocs/op   delta
Template        390k ± 0%       390k ± 0%    ~           (p=0.225 n=30+29)
Unicode         318k ± 0%       293k ± 0%  -8.03%        (p=0.000 n=30+29)
GoTypes        1.16M ± 0%      1.16M ± 0%    ~           (p=0.745 n=30+30)
Compiler       4.35M ± 0%      4.35M ± 0%    ~           (p=0.105 n=30+30)

Change-Id: I6310739a0bfdb54f1ab8a460b2c03615ad1ff5bc
Reviewed-on: https://go-review.googlesource.com/32221
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Matthew Dempsky 2016-10-27 02:02:30 -07:00
parent 4951c79363
commit bba1ac4fd9
4 changed files with 71 additions and 60 deletions

View file

@ -621,11 +621,13 @@ func getdyn(n *Node, top bool) initGenType {
var mode initGenType
for _, n1 := range n.List.Slice() {
value := n1.Right
if n.Op == OSTRUCTLIT {
value = n1.Left
switch n1.Op {
case OKEY:
n1 = n1.Right
case OSTRUCTKEY:
n1 = n1.Left
}
mode |= getdyn(value, false)
mode |= getdyn(n1, false)
if mode == initDynamic|initConst {
break
}
@ -640,10 +642,10 @@ func isStaticCompositeLiteral(n *Node) bool {
return false
case OARRAYLIT:
for _, r := range n.List.Slice() {
if r.Op != OKEY {
Fatalf("isStaticCompositeLiteral: rhs not OKEY: %v", r)
if r.Op == OKEY {
r = r.Right
}
if r.Left.Op != OLITERAL || !isStaticCompositeLiteral(r.Right) {
if !isStaticCompositeLiteral(r) {
return false
}
}
@ -700,11 +702,15 @@ func fixedlit(ctxt initContext, kind initKind, n *Node, var_ *Node, init *Nodes)
var splitnode func(*Node) (a *Node, value *Node)
switch n.Op {
case OARRAYLIT, OSLICELIT:
var k int64
splitnode = func(r *Node) (*Node, *Node) {
if r.Op != OKEY {
Fatalf("fixedlit: rhs not OKEY: %v", r)
if r.Op == OKEY {
k = nonnegintconst(r.Left)
r = r.Right
}
return nod(OINDEX, var_, r.Left), r.Right
a := nod(OINDEX, var_, nodintconst(k))
k++
return a, r
}
case OSTRUCTLIT:
splitnode = func(r *Node) (*Node, *Node) {
@ -733,9 +739,6 @@ func fixedlit(ctxt initContext, kind initKind, n *Node, var_ *Node, init *Nodes)
}
islit := isliteral(value)
if n.Op == OARRAYLIT {
islit = islit && isliteral(r.Left)
}
if (kind == initKindStatic && !islit) || (kind == initKindDynamic && islit) {
continue
}
@ -863,14 +866,16 @@ func slicelit(ctxt initContext, n *Node, var_ *Node, init *Nodes) {
}
// put dynamics into array (5)
var index int64
for _, r := range n.List.Slice() {
if r.Op != OKEY {
Fatalf("slicelit: rhs not OKEY: %v", r)
value := r
if r.Op == OKEY {
index = nonnegintconst(r.Left)
value = r.Right
}
index := r.Left
value := r.Right
a := nod(OINDEX, vauto, index)
a := nod(OINDEX, vauto, nodintconst(index))
a.Bounded = true
index++
// TODO need to check bounds?
@ -883,7 +888,7 @@ func slicelit(ctxt initContext, n *Node, var_ *Node, init *Nodes) {
continue
}
if isliteral(index) && isliteral(value) {
if isliteral(value) {
continue
}
@ -1237,12 +1242,14 @@ func initplan(n *Node) {
Fatalf("initplan")
case OARRAYLIT, OSLICELIT:
var k int64
for _, a := range n.List.Slice() {
index := nonnegintconst(a.Left)
if a.Op != OKEY || index < 0 {
Fatalf("initplan fixedlit")
if a.Op == OKEY {
k = nonnegintconst(a.Left)
a = a.Right
}
addvalue(p, index*n.Type.Elem().Width, a.Right)
addvalue(p, k*n.Type.Elem().Width, a)
k++
}
case OSTRUCTLIT:
@ -1308,7 +1315,10 @@ func iszero(n *Node) bool {
case OARRAYLIT:
for _, n1 := range n.List.Slice() {
if !iszero(n1.Right) {
if n1.Op == OKEY {
n1 = n1.Right
}
if !iszero(n1) {
return false
}
}