Skip to content

Commit ed70f37

Browse files
valyalamdempsky
authored andcommitted
cmd/compile: pack bool fields in Node, Name, Func and Type structs to 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 <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
1 parent fbf4dd9 commit ed70f37

40 files changed

+611
-525
lines changed

src/cmd/compile/internal/amd64/ggen.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ func defframe(ptxt *obj.Prog) {
3333

3434
// iterate through declarations - they are sorted in decreasing xoffset order.
3535
for _, n := range gc.Curfn.Func.Dcl {
36-
if !n.Name.Needzero {
36+
if !n.Name.Needzero() {
3737
continue
3838
}
3939
if n.Class != gc.PAUTO {

src/cmd/compile/internal/arm/ggen.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func defframe(ptxt *obj.Prog) {
2727
lo := hi
2828
r0 := uint32(0)
2929
for _, n := range gc.Curfn.Func.Dcl {
30-
if !n.Name.Needzero {
30+
if !n.Name.Needzero() {
3131
continue
3232
}
3333
if n.Class != gc.PAUTO {

src/cmd/compile/internal/arm64/ggen.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ func defframe(ptxt *obj.Prog) {
3535

3636
// iterate through declarations - they are sorted in decreasing xoffset order.
3737
for _, n := range gc.Curfn.Func.Dcl {
38-
if !n.Name.Needzero {
38+
if !n.Name.Needzero() {
3939
continue
4040
}
4141
if n.Class != gc.PAUTO {

src/cmd/compile/internal/gc/alg.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,10 @@ func algtype(t *Type) AlgKind {
8484
// If it returns ANOEQ, it also returns the component type of t that
8585
// makes it incomparable.
8686
func algtype1(t *Type) (AlgKind, *Type) {
87-
if t.Broke {
87+
if t.Broke() {
8888
return AMEM, nil
8989
}
90-
if t.Noalg {
90+
if t.Noalg() {
9191
return ANOEQ, t
9292
}
9393

@@ -227,15 +227,15 @@ func genhash(sym *Sym, t *Type) {
227227
ni := newname(lookup("i"))
228228
ni.Type = Types[TINT]
229229
n.List.Set1(ni)
230-
n.Colas = true
230+
n.SetColas(true)
231231
colasdefn(n.List.Slice(), n)
232232
ni = n.List.First()
233233

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

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

299299
funcbody(fn)
300300
Curfn = fn
301-
fn.Func.Dupok = true
301+
fn.Func.SetDupok(true)
302302
fn = typecheck(fn, Etop)
303303
typecheckslice(fn.Nbody.Slice(), Etop)
304304
Curfn = nil
@@ -406,16 +406,16 @@ func geneq(sym *Sym, t *Type) {
406406
ni := newname(lookup("i"))
407407
ni.Type = Types[TINT]
408408
nrange.List.Set1(ni)
409-
nrange.Colas = true
409+
nrange.SetColas(true)
410410
colasdefn(nrange.List.Slice(), nrange)
411411
ni = nrange.List.First()
412412

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

416-
nx.Bounded = true
416+
nx.SetBounded(true)
417417
ny := nod(OINDEX, nq, ni)
418-
ny.Bounded = true
418+
ny.SetBounded(true)
419419

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

491491
funcbody(fn)
492492
Curfn = fn
493-
fn.Func.Dupok = true
493+
fn.Func.SetDupok(true)
494494
fn = typecheck(fn, Etop)
495495
typecheckslice(fn.Nbody.Slice(), Etop)
496496
Curfn = nil

src/cmd/compile/internal/gc/align.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,8 @@ func dowidth(t *Type) {
124124
}
125125

126126
if t.Width == -2 {
127-
if !t.Broke {
128-
t.Broke = true
127+
if !t.Broke() {
128+
t.SetBroke(true)
129129
yyerrorl(t.Pos, "invalid recursive type %v", t)
130130
}
131131

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

136136
// break infinite recursion if the broken recursive type
137137
// is referenced again
138-
if t.Broke && t.Width == 0 {
138+
if t.Broke() && t.Width == 0 {
139139
return
140140
}
141141

@@ -228,7 +228,7 @@ func dowidth(t *Type) {
228228
checkwidth(t.Key())
229229

230230
case TFORW: // should have been filled in
231-
if !t.Broke {
231+
if !t.Broke() {
232232
yyerror("invalid recursive type %v", t)
233233
}
234234
w = 1 // anything will do
@@ -249,9 +249,9 @@ func dowidth(t *Type) {
249249
break
250250
}
251251
if t.isDDDArray() {
252-
if !t.Broke {
252+
if !t.Broke() {
253253
yyerror("use of [...] array outside of array literal")
254-
t.Broke = true
254+
t.SetBroke(true)
255255
}
256256
break
257257
}
@@ -356,10 +356,10 @@ func checkwidth(t *Type) {
356356
return
357357
}
358358

359-
if t.Deferwidth {
359+
if t.Deferwidth() {
360360
return
361361
}
362-
t.Deferwidth = true
362+
t.SetDeferwidth(true)
363363

364364
deferredTypeStack = append(deferredTypeStack, t)
365365
}
@@ -379,7 +379,7 @@ func resumecheckwidth() {
379379
for len(deferredTypeStack) > 0 {
380380
t := deferredTypeStack[len(deferredTypeStack)-1]
381381
deferredTypeStack = deferredTypeStack[:len(deferredTypeStack)-1]
382-
t.Deferwidth = false
382+
t.SetDeferwidth(false)
383383
dowidth(t)
384384
}
385385

src/cmd/compile/internal/gc/bexport.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -702,7 +702,7 @@ func (p *exporter) typ(t *Type) {
702702
p.paramList(sig.Recvs(), inlineable)
703703
p.paramList(sig.Params(), inlineable)
704704
p.paramList(sig.Results(), inlineable)
705-
p.bool(m.Nointerface) // record go:nointerface pragma value (see also #16243)
705+
p.bool(m.Nointerface()) // record go:nointerface pragma value (see also #16243)
706706

707707
var f *Func
708708
if inlineable {
@@ -921,7 +921,7 @@ func (p *exporter) paramList(params *Type, numbered bool) {
921921

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

11851185
// from exprfmt (fmt.go)
1186-
for n != nil && n.Implicit && (n.Op == OIND || n.Op == OADDR) {
1186+
for n != nil && n.Implicit() && (n.Op == OIND || n.Op == OADDR) {
11871187
n = n.Left
11881188
}
11891189

@@ -1256,7 +1256,7 @@ func (p *exporter) expr(n *Node) {
12561256
case OPTRLIT:
12571257
p.op(OPTRLIT)
12581258
p.expr(n.Left)
1259-
p.bool(n.Implicit)
1259+
p.bool(n.Implicit())
12601260

12611261
case OSTRUCTLIT:
12621262
p.op(OSTRUCTLIT)
@@ -1337,16 +1337,16 @@ func (p *exporter) expr(n *Node) {
13371337
}
13381338
// only append() calls may contain '...' arguments
13391339
if op == OAPPEND {
1340-
p.bool(n.Isddd)
1341-
} else if n.Isddd {
1340+
p.bool(n.Isddd())
1341+
} else if n.Isddd() {
13421342
Fatalf("exporter: unexpected '...' with %s call", opnames[op])
13431343
}
13441344

13451345
case OCALL, OCALLFUNC, OCALLMETH, OCALLINTER, OGETG:
13461346
p.op(OCALL)
13471347
p.expr(n.Left)
13481348
p.exprList(n.List)
1349-
p.bool(n.Isddd)
1349+
p.bool(n.Isddd())
13501350

13511351
case OMAKEMAP, OMAKECHAN, OMAKESLICE:
13521352
p.op(op) // must keep separate from OMAKE for importer
@@ -1446,7 +1446,7 @@ func (p *exporter) stmt(n *Node) {
14461446
p.op(OASOP)
14471447
p.int(int(n.Etype))
14481448
p.expr(n.Left)
1449-
if p.bool(!n.Implicit) {
1449+
if p.bool(!n.Implicit()) {
14501450
p.expr(n.Right)
14511451
}
14521452

src/cmd/compile/internal/gc/bimport.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -688,7 +688,7 @@ func (p *importer) param(named bool) *Field {
688688
if f.Type.Etype == TDDDFIELD {
689689
// TDDDFIELD indicates wrapped ... slice type
690690
f.Type = typSlice(f.Type.DDDField())
691-
f.Isddd = true
691+
f.SetIsddd(true)
692692
}
693693

694694
if named {
@@ -898,7 +898,7 @@ func (p *importer) node() *Node {
898898
if n.Op == OCOMPLIT {
899899
// Special case for &T{...}: turn into (*T){...}.
900900
n.Right = nod(OIND, n.Right, nil)
901-
n.Right.Implicit = true
901+
n.Right.SetImplicit(true)
902902
} else {
903903
n = nod(OADDR, n, nil)
904904
}
@@ -975,7 +975,7 @@ func (p *importer) node() *Node {
975975
n := builtinCall(op)
976976
n.List.Set(p.exprList())
977977
if op == OAPPEND {
978-
n.Isddd = p.bool()
978+
n.SetIsddd(p.bool())
979979
}
980980
return n
981981

@@ -985,7 +985,7 @@ func (p *importer) node() *Node {
985985
case OCALL:
986986
n := nod(OCALL, p.expr(), nil)
987987
n.List.Set(p.exprList())
988-
n.Isddd = p.bool()
988+
n.SetIsddd(p.bool())
989989
return n
990990

991991
case OMAKEMAP, OMAKECHAN, OMAKESLICE:
@@ -1045,7 +1045,7 @@ func (p *importer) node() *Node {
10451045
n.Left = p.expr()
10461046
if !p.bool() {
10471047
n.Right = nodintconst(1)
1048-
n.Implicit = true
1048+
n.SetImplicit(true)
10491049
} else {
10501050
n.Right = p.expr()
10511051
}

src/cmd/compile/internal/gc/bitset.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright 2017 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package gc
6+
7+
type bitset8 uint8
8+
9+
func (f *bitset8) set(mask uint8, b bool) {
10+
if b {
11+
*(*uint8)(f) |= mask
12+
} else {
13+
*(*uint8)(f) &^= mask
14+
}
15+
}
16+
17+
type bitset16 uint16
18+
19+
func (f *bitset16) set(mask uint16, b bool) {
20+
if b {
21+
*(*uint16)(f) |= mask
22+
} else {
23+
*(*uint16)(f) &^= mask
24+
}
25+
}

0 commit comments

Comments
 (0)