From 135109d241da1427461fdb19656a976b3e9c7b22 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Fri, 25 Mar 2016 15:34:55 -0700 Subject: [PATCH] cmd/compile: reduce slice header allocation when parsing := assignments The colas function allocates 2 slice headers in each call (via Nodes.Set) only to throw away those slice headers in the common case where both the lhs and rhs in "lhs := rhs" have length 1. Avoid the Nodes.Set calls in those cases. For make.bash, this eliminates ~63,000 slice header allocations. Also: Minor cleanups in colasdefn. Change-Id: Ib114a67c3adeb8821868bd71a5e0f5e2e19fcd4f Reviewed-on: https://go-review.googlesource.com/21170 Reviewed-by: Brad Fitzpatrick Run-TryBot: Robert Griesemer TryBot-Result: Gobot Gobot --- src/cmd/compile/internal/gc/alg.go | 4 +-- src/cmd/compile/internal/gc/dcl.go | 48 ++++++++++++--------------- src/cmd/compile/internal/gc/parser.go | 2 +- 3 files changed, 24 insertions(+), 30 deletions(-) diff --git a/src/cmd/compile/internal/gc/alg.go b/src/cmd/compile/internal/gc/alg.go index d07a1529d0..a23e38d2be 100644 --- a/src/cmd/compile/internal/gc/alg.go +++ b/src/cmd/compile/internal/gc/alg.go @@ -210,7 +210,7 @@ func genhash(sym *Sym, t *Type) { ni.Type = Types[TINT] n.List.Set1(ni) n.Colas = true - colasdefn(n.List, n) + colasdefn(n.List.Slice(), n) ni = n.List.First() // h = hashel(&p[i], h) @@ -390,7 +390,7 @@ func geneq(sym *Sym, t *Type) { ni.Type = Types[TINT] nrange.List.Set1(ni) nrange.Colas = true - colasdefn(nrange.List, nrange) + colasdefn(nrange.List.Slice(), nrange) ni = nrange.List.First() // if p[i] != q[i] { return false } diff --git a/src/cmd/compile/internal/gc/dcl.go b/src/cmd/compile/internal/gc/dcl.go index c55d0e34cc..a04fde1831 100644 --- a/src/cmd/compile/internal/gc/dcl.go +++ b/src/cmd/compile/internal/gc/dcl.go @@ -432,18 +432,15 @@ func colasname(n *Node) bool { return false } -func colasdefn(left Nodes, defn *Node) { - for _, n1 := range left.Slice() { - if n1.Sym != nil { - n1.Sym.Flags |= SymUniq +func colasdefn(left []*Node, defn *Node) { + for _, n := range left { + if n.Sym != nil { + n.Sym.Flags |= SymUniq } } - nnew := 0 - nerr := 0 - var n *Node - for i2, n2 := range left.Slice() { - n = n2 + var nnew, nerr int + for i, n := range left { if isblank(n) { continue } @@ -470,7 +467,7 @@ func colasdefn(left Nodes, defn *Node) { declare(n, dclcontext) n.Name.Defn = defn defn.Ninit.Append(Nod(ODCL, n, nil)) - left.SetIndex(i2, n) + left[i] = n } if nnew == 0 && nerr == 0 { @@ -478,24 +475,21 @@ func colasdefn(left Nodes, defn *Node) { } } -func colas(left []*Node, right []*Node, lno int32) *Node { - as := Nod(OAS2, nil, nil) - as.List.Set(left) - as.Rlist.Set(right) - as.Colas = true - as.Lineno = lno - colasdefn(as.List, as) - - // make the tree prettier; not necessary - if as.List.Len() == 1 && as.Rlist.Len() == 1 { - as.Left = as.List.First() - as.Right = as.Rlist.First() - as.List.Set(nil) - as.Rlist.Set(nil) - as.Op = OAS +func colas(left, right []*Node, lno int32) *Node { + n := Nod(OAS, nil, nil) // assume common case + n.Colas = true + n.Lineno = lno // set before calling colasdefn for correct error line + colasdefn(left, n) // modifies left, call before using left[0] in common case + if len(left) == 1 && len(right) == 1 { + // common case + n.Left = left[0] + n.Right = right[0] + } else { + n.Op = OAS2 + n.List.Set(left) + n.Rlist.Set(right) } - - return as + return n } // declare the arguments in an diff --git a/src/cmd/compile/internal/gc/parser.go b/src/cmd/compile/internal/gc/parser.go index db9d4c9ee5..892dd5969a 100644 --- a/src/cmd/compile/internal/gc/parser.go +++ b/src/cmd/compile/internal/gc/parser.go @@ -636,7 +636,7 @@ func (p *parser) simple_stmt(labelOk, rangeOk bool) *Node { r := Nod(ORANGE, nil, p.expr()) r.List.Set(lhs) r.Colas = true - colasdefn(r.List, r) + colasdefn(lhs, r) return r } -- 2.48.1