Skip to content

Commit

Permalink
cmd/compile: pack bool fields in Node, Name, Func and Type structs to…
Browse files Browse the repository at this point in the history
… bitsets

This reduces compiler memory usage by up to 4% - see compilebench
results below.

name       old time/op     new time/op     delta
Template       245ms ± 4%      241ms ± 2%  -1.88%  (p=0.029 n=10+10)
Unicode        126ms ± 3%      124ms ± 3%    ~     (p=0.105 n=10+10)
GoTypes        805ms ± 2%      813ms ± 3%    ~     (p=0.515 n=8+10)
Compiler       3.95s ± 2%      3.83s ± 1%  -2.96%  (p=0.000 n=9+10)
MakeBash       47.4s ± 4%      46.6s ± 1%  -1.59%  (p=0.028 n=9+10)

name       old user-ns/op  new user-ns/op  delta
Template        324M ± 5%       326M ± 3%    ~     (p=0.935 n=10+10)
Unicode         186M ± 5%       178M ±10%    ~     (p=0.067 n=9+10)
GoTypes        1.08G ± 7%      1.09G ± 4%    ~     (p=0.956 n=10+10)
Compiler       5.34G ± 4%      5.31G ± 1%    ~     (p=0.501 n=10+8)

name       old alloc/op    new alloc/op    delta
Template      41.0MB ± 0%     39.8MB ± 0%  -3.03%  (p=0.000 n=10+10)
Unicode       32.3MB ± 0%     31.0MB ± 0%  -4.13%  (p=0.000 n=10+10)
GoTypes        119MB ± 0%      116MB ± 0%  -2.39%  (p=0.000 n=10+10)
Compiler       499MB ± 0%      487MB ± 0%  -2.48%  (p=0.000 n=10+10)

name       old allocs/op   new allocs/op   delta
Template        380k ± 1%       379k ± 1%    ~     (p=0.436 n=10+10)
Unicode         324k ± 1%       324k ± 0%    ~     (p=0.853 n=10+10)
GoTypes        1.15M ± 0%      1.15M ± 0%    ~     (p=0.481 n=10+10)
Compiler       4.41M ± 0%      4.41M ± 0%  -0.12%  (p=0.007 n=10+10)

name       old text-bytes  new text-bytes  delta
HelloSize       623k ± 0%       623k ± 0%    ~     (all equal)
CmdGoSize      6.64M ± 0%      6.64M ± 0%    ~     (all equal)

name       old data-bytes  new data-bytes  delta
HelloSize      5.81k ± 0%      5.81k ± 0%    ~     (all equal)
CmdGoSize       238k ± 0%       238k ± 0%    ~     (all equal)

name       old bss-bytes   new bss-bytes   delta
HelloSize       134k ± 0%       134k ± 0%    ~     (all equal)
CmdGoSize       152k ± 0%       152k ± 0%    ~     (all equal)

name       old exe-bytes   new exe-bytes   delta
HelloSize       967k ± 0%       967k ± 0%    ~     (all equal)
CmdGoSize      10.2M ± 0%      10.2M ± 0%    ~     (all equal)

Change-Id: I1f40af738254892bd6c8ba2eb43390b175753d52
Reviewed-on: https://go-review.googlesource.com/37445
Reviewed-by: Matthew Dempsky <[email protected]>
Run-TryBot: Matthew Dempsky <[email protected]>
TryBot-Result: Gobot Gobot <[email protected]>
  • Loading branch information
valyala authored and mdempsky committed Mar 3, 2017
1 parent fbf4dd9 commit ed70f37
Show file tree
Hide file tree
Showing 40 changed files with 611 additions and 525 deletions.
2 changes: 1 addition & 1 deletion src/cmd/compile/internal/amd64/ggen.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func defframe(ptxt *obj.Prog) {

// iterate through declarations - they are sorted in decreasing xoffset order.
for _, n := range gc.Curfn.Func.Dcl {
if !n.Name.Needzero {
if !n.Name.Needzero() {
continue
}
if n.Class != gc.PAUTO {
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/compile/internal/arm/ggen.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func defframe(ptxt *obj.Prog) {
lo := hi
r0 := uint32(0)
for _, n := range gc.Curfn.Func.Dcl {
if !n.Name.Needzero {
if !n.Name.Needzero() {
continue
}
if n.Class != gc.PAUTO {
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/compile/internal/arm64/ggen.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func defframe(ptxt *obj.Prog) {

// iterate through declarations - they are sorted in decreasing xoffset order.
for _, n := range gc.Curfn.Func.Dcl {
if !n.Name.Needzero {
if !n.Name.Needzero() {
continue
}
if n.Class != gc.PAUTO {
Expand Down
18 changes: 9 additions & 9 deletions src/cmd/compile/internal/gc/alg.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,10 @@ func algtype(t *Type) AlgKind {
// If it returns ANOEQ, it also returns the component type of t that
// makes it incomparable.
func algtype1(t *Type) (AlgKind, *Type) {
if t.Broke {
if t.Broke() {
return AMEM, nil
}
if t.Noalg {
if t.Noalg() {
return ANOEQ, t
}

Expand Down Expand Up @@ -227,15 +227,15 @@ func genhash(sym *Sym, t *Type) {
ni := newname(lookup("i"))
ni.Type = Types[TINT]
n.List.Set1(ni)
n.Colas = true
n.SetColas(true)
colasdefn(n.List.Slice(), n)
ni = n.List.First()

// h = hashel(&p[i], h)
call := nod(OCALL, hashel, nil)

nx := nod(OINDEX, np, ni)
nx.Bounded = true
nx.SetBounded(true)
na := nod(OADDR, nx, nil)
na.Etype = 1 // no escape to heap
call.List.Append(na)
Expand Down Expand Up @@ -298,7 +298,7 @@ func genhash(sym *Sym, t *Type) {

funcbody(fn)
Curfn = fn
fn.Func.Dupok = true
fn.Func.SetDupok(true)
fn = typecheck(fn, Etop)
typecheckslice(fn.Nbody.Slice(), Etop)
Curfn = nil
Expand Down Expand Up @@ -406,16 +406,16 @@ func geneq(sym *Sym, t *Type) {
ni := newname(lookup("i"))
ni.Type = Types[TINT]
nrange.List.Set1(ni)
nrange.Colas = true
nrange.SetColas(true)
colasdefn(nrange.List.Slice(), nrange)
ni = nrange.List.First()

// if p[i] != q[i] { return false }
nx := nod(OINDEX, np, ni)

nx.Bounded = true
nx.SetBounded(true)
ny := nod(OINDEX, nq, ni)
ny.Bounded = true
ny.SetBounded(true)

nif := nod(OIF, nil, nil)
nif.Left = nod(ONE, nx, ny)
Expand Down Expand Up @@ -490,7 +490,7 @@ func geneq(sym *Sym, t *Type) {

funcbody(fn)
Curfn = fn
fn.Func.Dupok = true
fn.Func.SetDupok(true)
fn = typecheck(fn, Etop)
typecheckslice(fn.Nbody.Slice(), Etop)
Curfn = nil
Expand Down
18 changes: 9 additions & 9 deletions src/cmd/compile/internal/gc/align.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ func dowidth(t *Type) {
}

if t.Width == -2 {
if !t.Broke {
t.Broke = true
if !t.Broke() {
t.SetBroke(true)
yyerrorl(t.Pos, "invalid recursive type %v", t)
}

Expand All @@ -135,7 +135,7 @@ func dowidth(t *Type) {

// break infinite recursion if the broken recursive type
// is referenced again
if t.Broke && t.Width == 0 {
if t.Broke() && t.Width == 0 {
return
}

Expand Down Expand Up @@ -228,7 +228,7 @@ func dowidth(t *Type) {
checkwidth(t.Key())

case TFORW: // should have been filled in
if !t.Broke {
if !t.Broke() {
yyerror("invalid recursive type %v", t)
}
w = 1 // anything will do
Expand All @@ -249,9 +249,9 @@ func dowidth(t *Type) {
break
}
if t.isDDDArray() {
if !t.Broke {
if !t.Broke() {
yyerror("use of [...] array outside of array literal")
t.Broke = true
t.SetBroke(true)
}
break
}
Expand Down Expand Up @@ -356,10 +356,10 @@ func checkwidth(t *Type) {
return
}

if t.Deferwidth {
if t.Deferwidth() {
return
}
t.Deferwidth = true
t.SetDeferwidth(true)

deferredTypeStack = append(deferredTypeStack, t)
}
Expand All @@ -379,7 +379,7 @@ func resumecheckwidth() {
for len(deferredTypeStack) > 0 {
t := deferredTypeStack[len(deferredTypeStack)-1]
deferredTypeStack = deferredTypeStack[:len(deferredTypeStack)-1]
t.Deferwidth = false
t.SetDeferwidth(false)
dowidth(t)
}

Expand Down
16 changes: 8 additions & 8 deletions src/cmd/compile/internal/gc/bexport.go
Original file line number Diff line number Diff line change
Expand Up @@ -702,7 +702,7 @@ func (p *exporter) typ(t *Type) {
p.paramList(sig.Recvs(), inlineable)
p.paramList(sig.Params(), inlineable)
p.paramList(sig.Results(), inlineable)
p.bool(m.Nointerface) // record go:nointerface pragma value (see also #16243)
p.bool(m.Nointerface()) // record go:nointerface pragma value (see also #16243)

var f *Func
if inlineable {
Expand Down Expand Up @@ -921,7 +921,7 @@ func (p *exporter) paramList(params *Type, numbered bool) {

func (p *exporter) param(q *Field, n int, numbered bool) {
t := q.Type
if q.Isddd {
if q.Isddd() {
// create a fake type to encode ... just for the p.typ call
t = typDDDField(t.Elem())
}
Expand Down Expand Up @@ -1183,7 +1183,7 @@ func (p *exporter) expr(n *Node) {
// }

// from exprfmt (fmt.go)
for n != nil && n.Implicit && (n.Op == OIND || n.Op == OADDR) {
for n != nil && n.Implicit() && (n.Op == OIND || n.Op == OADDR) {
n = n.Left
}

Expand Down Expand Up @@ -1256,7 +1256,7 @@ func (p *exporter) expr(n *Node) {
case OPTRLIT:
p.op(OPTRLIT)
p.expr(n.Left)
p.bool(n.Implicit)
p.bool(n.Implicit())

case OSTRUCTLIT:
p.op(OSTRUCTLIT)
Expand Down Expand Up @@ -1337,16 +1337,16 @@ func (p *exporter) expr(n *Node) {
}
// only append() calls may contain '...' arguments
if op == OAPPEND {
p.bool(n.Isddd)
} else if n.Isddd {
p.bool(n.Isddd())
} else if n.Isddd() {
Fatalf("exporter: unexpected '...' with %s call", opnames[op])
}

case OCALL, OCALLFUNC, OCALLMETH, OCALLINTER, OGETG:
p.op(OCALL)
p.expr(n.Left)
p.exprList(n.List)
p.bool(n.Isddd)
p.bool(n.Isddd())

case OMAKEMAP, OMAKECHAN, OMAKESLICE:
p.op(op) // must keep separate from OMAKE for importer
Expand Down Expand Up @@ -1446,7 +1446,7 @@ func (p *exporter) stmt(n *Node) {
p.op(OASOP)
p.int(int(n.Etype))
p.expr(n.Left)
if p.bool(!n.Implicit) {
if p.bool(!n.Implicit()) {
p.expr(n.Right)
}

Expand Down
10 changes: 5 additions & 5 deletions src/cmd/compile/internal/gc/bimport.go
Original file line number Diff line number Diff line change
Expand Up @@ -688,7 +688,7 @@ func (p *importer) param(named bool) *Field {
if f.Type.Etype == TDDDFIELD {
// TDDDFIELD indicates wrapped ... slice type
f.Type = typSlice(f.Type.DDDField())
f.Isddd = true
f.SetIsddd(true)
}

if named {
Expand Down Expand Up @@ -898,7 +898,7 @@ func (p *importer) node() *Node {
if n.Op == OCOMPLIT {
// Special case for &T{...}: turn into (*T){...}.
n.Right = nod(OIND, n.Right, nil)
n.Right.Implicit = true
n.Right.SetImplicit(true)
} else {
n = nod(OADDR, n, nil)
}
Expand Down Expand Up @@ -975,7 +975,7 @@ func (p *importer) node() *Node {
n := builtinCall(op)
n.List.Set(p.exprList())
if op == OAPPEND {
n.Isddd = p.bool()
n.SetIsddd(p.bool())
}
return n

Expand All @@ -985,7 +985,7 @@ func (p *importer) node() *Node {
case OCALL:
n := nod(OCALL, p.expr(), nil)
n.List.Set(p.exprList())
n.Isddd = p.bool()
n.SetIsddd(p.bool())
return n

case OMAKEMAP, OMAKECHAN, OMAKESLICE:
Expand Down Expand Up @@ -1045,7 +1045,7 @@ func (p *importer) node() *Node {
n.Left = p.expr()
if !p.bool() {
n.Right = nodintconst(1)
n.Implicit = true
n.SetImplicit(true)
} else {
n.Right = p.expr()
}
Expand Down
25 changes: 25 additions & 0 deletions src/cmd/compile/internal/gc/bitset.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package gc

type bitset8 uint8

func (f *bitset8) set(mask uint8, b bool) {
if b {
*(*uint8)(f) |= mask
} else {
*(*uint8)(f) &^= mask
}
}

type bitset16 uint16

func (f *bitset16) set(mask uint16, b bool) {
if b {
*(*uint16)(f) |= mask
} else {
*(*uint16)(f) &^= mask
}
}
Loading

0 comments on commit ed70f37

Please sign in to comment.