Commit 135109d2 authored by Robert Griesemer's avatar Robert Griesemer

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/21170Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent a7f7a9cc
...@@ -210,7 +210,7 @@ func genhash(sym *Sym, t *Type) { ...@@ -210,7 +210,7 @@ func genhash(sym *Sym, t *Type) {
ni.Type = Types[TINT] ni.Type = Types[TINT]
n.List.Set1(ni) n.List.Set1(ni)
n.Colas = true n.Colas = true
colasdefn(n.List, n) colasdefn(n.List.Slice(), n)
ni = n.List.First() ni = n.List.First()
// h = hashel(&p[i], h) // h = hashel(&p[i], h)
...@@ -390,7 +390,7 @@ func geneq(sym *Sym, t *Type) { ...@@ -390,7 +390,7 @@ func geneq(sym *Sym, t *Type) {
ni.Type = Types[TINT] ni.Type = Types[TINT]
nrange.List.Set1(ni) nrange.List.Set1(ni)
nrange.Colas = true nrange.Colas = true
colasdefn(nrange.List, nrange) colasdefn(nrange.List.Slice(), nrange)
ni = nrange.List.First() ni = nrange.List.First()
// if p[i] != q[i] { return false } // if p[i] != q[i] { return false }
......
...@@ -432,18 +432,15 @@ func colasname(n *Node) bool { ...@@ -432,18 +432,15 @@ func colasname(n *Node) bool {
return false return false
} }
func colasdefn(left Nodes, defn *Node) { func colasdefn(left []*Node, defn *Node) {
for _, n1 := range left.Slice() { for _, n := range left {
if n1.Sym != nil { if n.Sym != nil {
n1.Sym.Flags |= SymUniq n.Sym.Flags |= SymUniq
} }
} }
nnew := 0 var nnew, nerr int
nerr := 0 for i, n := range left {
var n *Node
for i2, n2 := range left.Slice() {
n = n2
if isblank(n) { if isblank(n) {
continue continue
} }
...@@ -470,7 +467,7 @@ func colasdefn(left Nodes, defn *Node) { ...@@ -470,7 +467,7 @@ func colasdefn(left Nodes, defn *Node) {
declare(n, dclcontext) declare(n, dclcontext)
n.Name.Defn = defn n.Name.Defn = defn
defn.Ninit.Append(Nod(ODCL, n, nil)) defn.Ninit.Append(Nod(ODCL, n, nil))
left.SetIndex(i2, n) left[i] = n
} }
if nnew == 0 && nerr == 0 { if nnew == 0 && nerr == 0 {
...@@ -478,24 +475,21 @@ func colasdefn(left Nodes, defn *Node) { ...@@ -478,24 +475,21 @@ func colasdefn(left Nodes, defn *Node) {
} }
} }
func colas(left []*Node, right []*Node, lno int32) *Node { func colas(left, right []*Node, lno int32) *Node {
as := Nod(OAS2, nil, nil) n := Nod(OAS, nil, nil) // assume common case
as.List.Set(left) n.Colas = true
as.Rlist.Set(right) n.Lineno = lno // set before calling colasdefn for correct error line
as.Colas = true colasdefn(left, n) // modifies left, call before using left[0] in common case
as.Lineno = lno if len(left) == 1 && len(right) == 1 {
colasdefn(as.List, as) // common case
n.Left = left[0]
// make the tree prettier; not necessary n.Right = right[0]
if as.List.Len() == 1 && as.Rlist.Len() == 1 { } else {
as.Left = as.List.First() n.Op = OAS2
as.Right = as.Rlist.First() n.List.Set(left)
as.List.Set(nil) n.Rlist.Set(right)
as.Rlist.Set(nil)
as.Op = OAS
} }
return n
return as
} }
// declare the arguments in an // declare the arguments in an
......
...@@ -636,7 +636,7 @@ func (p *parser) simple_stmt(labelOk, rangeOk bool) *Node { ...@@ -636,7 +636,7 @@ func (p *parser) simple_stmt(labelOk, rangeOk bool) *Node {
r := Nod(ORANGE, nil, p.expr()) r := Nod(ORANGE, nil, p.expr())
r.List.Set(lhs) r.List.Set(lhs)
r.Colas = true r.Colas = true
colasdefn(r.List, r) colasdefn(lhs, r)
return r return r
} }
......
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