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 <bradfitz@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Robert Griesemer 2016-03-25 15:34:55 -07:00
parent a7f7a9cca7
commit 135109d241
3 changed files with 24 additions and 30 deletions

View file

@ -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 }

View file

@ -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

View file

@ -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
}