]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.ssa] cmd/compile: add constant cache
authorJosh Bleecher Snyder <josharian@gmail.com>
Sun, 28 Feb 2016 23:51:11 +0000 (15:51 -0800)
committerJosh Bleecher Snyder <josharian@gmail.com>
Mon, 29 Feb 2016 22:40:43 +0000 (22:40 +0000)
The cache gets a 62% hit rate while compiling
the standard library.

name      old time/op    new time/op    delta
Template     449ms ± 2%     443ms ± 4%  -1.40%  (p=0.006 n=23+25)
GoTypes      1.54s ± 1%     1.50s ± 2%  -2.53%  (p=0.000 n=22+22)
Compiler     5.51s ± 1%     5.39s ± 1%  -2.29%  (p=0.000 n=23+25)

name      old alloc/op   new alloc/op   delta
Template    90.4MB ± 0%    90.0MB ± 0%  -0.45%  (p=0.000 n=25+25)
GoTypes      334MB ± 0%     331MB ± 0%  -1.05%  (p=0.000 n=25+25)
Compiler    1.12GB ± 0%    1.10GB ± 0%  -1.57%  (p=0.000 n=25+24)

name      old allocs/op  new allocs/op  delta
Template      681k ± 0%      682k ± 0%  +0.26%  (p=0.000 n=25+25)
GoTypes      2.23M ± 0%     2.23M ± 0%  +0.05%  (p=0.000 n=23+24)
Compiler     6.46M ± 0%     6.46M ± 0%  +0.02%  (p=0.000 n=24+25)

Change-Id: I2629c291892827493d7b55ec4d83f6973a2ab133
Reviewed-on: https://go-review.googlesource.com/20026
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: Alexandru Moșoi <alexandru@mosoi.ro>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/compile/internal/ssa/TODO
src/cmd/compile/internal/ssa/func.go
src/cmd/compile/internal/ssa/gen/rulegen.go

index 57bed9a9a309fa41d3df541311ccde822557c3aa..4e39d1e9c35c774728d1c4124d360be861afcc9f 100644 (file)
@@ -47,7 +47,7 @@ Optimizations (better compiler)
 -------------------------------
 - Smaller Value.Type (int32 or ptr)?  Get rid of types altogether?
 - OpStore uses 3 args.  Increase the size of Value.argstorage to 3?
-- Constant cache
+- Use a constant cache for OpConstNil, OpConstInterface, OpConstSlice, maybe OpConstString
 - Handle signed division overflow and sign extension earlier
 - Implement 64 bit const division with high multiply, maybe in the frontend?
 - Add bit widths to complex ops
index 9441110769f0c86b918f2e2c542c5ca69fa24df3..7cc5f6c8d99f2d28cc55ff6cb03f5ffa1d97d982 100644 (file)
@@ -35,6 +35,8 @@ type Func struct {
 
        freeValues *Value // free Values linked by argstorage[0].  All other fields except ID are 0/nil.
        freeBlocks *Block // free Blocks linked by succstorage[0].  All other fields except ID are 0/nil.
+
+       constants map[int64][]*Value // constants cache, keyed by constant value; users must check value's Op and Type
 }
 
 // NumBlocks returns an integer larger than the id of any Block in the Func.
@@ -270,38 +272,47 @@ func (b *Block) NewValue3I(line int32, op Op, t Type, auxint int64, arg0, arg1,
        return v
 }
 
+// constVal returns a constant value for c.
+func (f *Func) constVal(line int32, op Op, t Type, c int64) *Value {
+       if f.constants == nil {
+               f.constants = make(map[int64][]*Value)
+       }
+       vv := f.constants[c]
+       for _, v := range vv {
+               if v.Op == op && v.Type.Equal(t) {
+                       return v
+               }
+       }
+       v := f.Entry.NewValue0I(line, op, t, c)
+       f.constants[c] = append(vv, v)
+       return v
+}
+
 // ConstInt returns an int constant representing its argument.
 func (f *Func) ConstBool(line int32, t Type, c bool) *Value {
-       // TODO: cache?
        i := int64(0)
        if c {
                i = 1
        }
-       return f.Entry.NewValue0I(line, OpConstBool, t, i)
+       return f.constVal(line, OpConstBool, t, i)
 }
 func (f *Func) ConstInt8(line int32, t Type, c int8) *Value {
-       // TODO: cache?
-       return f.Entry.NewValue0I(line, OpConst8, t, int64(c))
+       return f.constVal(line, OpConst8, t, int64(c))
 }
 func (f *Func) ConstInt16(line int32, t Type, c int16) *Value {
-       // TODO: cache?
-       return f.Entry.NewValue0I(line, OpConst16, t, int64(c))
+       return f.constVal(line, OpConst16, t, int64(c))
 }
 func (f *Func) ConstInt32(line int32, t Type, c int32) *Value {
-       // TODO: cache?
-       return f.Entry.NewValue0I(line, OpConst32, t, int64(c))
+       return f.constVal(line, OpConst32, t, int64(c))
 }
 func (f *Func) ConstInt64(line int32, t Type, c int64) *Value {
-       // TODO: cache?
-       return f.Entry.NewValue0I(line, OpConst64, t, c)
+       return f.constVal(line, OpConst64, t, c)
 }
 func (f *Func) ConstFloat32(line int32, t Type, c float64) *Value {
-       // TODO: cache?
-       return f.Entry.NewValue0I(line, OpConst32F, t, int64(math.Float64bits(c)))
+       return f.constVal(line, OpConst32F, t, int64(math.Float64bits(c)))
 }
 func (f *Func) ConstFloat64(line int32, t Type, c float64) *Value {
-       // TODO: cache?
-       return f.Entry.NewValue0I(line, OpConst64F, t, int64(math.Float64bits(c)))
+       return f.constVal(line, OpConst64F, t, int64(math.Float64bits(c)))
 }
 
 func (f *Func) Logf(msg string, args ...interface{})   { f.Config.Logf(msg, args...) }
index 55287c187d8c686e84a243098cbc456cc56481a6..c2da3e648928d0a62091f429be0cbca9a3764875 100644 (file)
@@ -426,6 +426,8 @@ func genResult(w io.Writer, arch arch, result string) {
        genResult0(w, arch, result, new(int), true, move)
 }
 func genResult0(w io.Writer, arch arch, result string, alloc *int, top, move bool) string {
+       // TODO: when generating a constant result, use f.constVal to avoid
+       // introducing copies just to clean them up again.
        if result[0] != '(' {
                // variable
                if top {