aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/ssa/export_test.go
diff options
context:
space:
mode:
authorPhilip Hofer <phofer@umich.edu>2017-03-03 10:57:53 -0800
committerDavid Chase <drchase@google.com>2017-03-13 18:24:57 +0000
commit4e0c7c3f61475116c4ae8d11ef796819d9c404f0 (patch)
tree62b5e1615ca8dcfd06658b6f2f955141abd4a396 /src/cmd/compile/internal/ssa/export_test.go
parent26e726c3092264584053a4f81714dcc8c91d2153 (diff)
downloadgo-4e0c7c3f61475116c4ae8d11ef796819d9c404f0.tar.gz
go-4e0c7c3f61475116c4ae8d11ef796819d9c404f0.zip
cmd/compile: de-virtualize interface calls
With this change, code like h := sha1.New() h.Write(buf) sum := h.Sum() gets compiled into static calls rather than interface calls, because the compiler is able to prove that 'h' is really a *sha1.digest. The InterCall re-write rule hits a few dozen times during make.bash, and hundreds of times during all.bash. The most common pattern identified by the compiler is a constructor like func New() Interface { return &impl{...} } where the constructor gets inlined into the caller, and the result is used immediately. Examples include {sha1,md5,crc32,crc64,...}.New, base64.NewEncoder, base64.NewDecoder, errors.New, net.Pipe, and so on. Some existing benchmarks that change on darwin/amd64: Crc64/ISO4KB-8 2.67µs ± 1% 2.66µs ± 0% -0.36% (p=0.015 n=10+10) Crc64/ISO1KB-8 694ns ± 0% 690ns ± 1% -0.59% (p=0.001 n=10+10) Adler32KB-8 473ns ± 1% 471ns ± 0% -0.39% (p=0.010 n=10+9) On architectures like amd64, the reduction in code size appears to contribute more to benchmark improvements than just removing the indirect call, since that branch gets predicted accurately when called in a loop. Updates #19361 Change-Id: Ia9d30afdd5f6b4d38d38b14b88f308acae8ce7ed Reviewed-on: https://go-review.googlesource.com/37751 Run-TryBot: Philip Hofer <phofer@umich.edu> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/ssa/export_test.go')
-rw-r--r--src/cmd/compile/internal/ssa/export_test.go31
1 files changed, 16 insertions, 15 deletions
diff --git a/src/cmd/compile/internal/ssa/export_test.go b/src/cmd/compile/internal/ssa/export_test.go
index 74bb08d5c2..b687076a28 100644
--- a/src/cmd/compile/internal/ssa/export_test.go
+++ b/src/cmd/compile/internal/ssa/export_test.go
@@ -97,21 +97,22 @@ func (d DummyFrontend) Warnl(_ src.XPos, msg string, args ...interface{}) { d.t
func (d DummyFrontend) Debug_checknil() bool { return false }
func (d DummyFrontend) Debug_wb() bool { return false }
-func (d DummyFrontend) TypeBool() Type { return TypeBool }
-func (d DummyFrontend) TypeInt8() Type { return TypeInt8 }
-func (d DummyFrontend) TypeInt16() Type { return TypeInt16 }
-func (d DummyFrontend) TypeInt32() Type { return TypeInt32 }
-func (d DummyFrontend) TypeInt64() Type { return TypeInt64 }
-func (d DummyFrontend) TypeUInt8() Type { return TypeUInt8 }
-func (d DummyFrontend) TypeUInt16() Type { return TypeUInt16 }
-func (d DummyFrontend) TypeUInt32() Type { return TypeUInt32 }
-func (d DummyFrontend) TypeUInt64() Type { return TypeUInt64 }
-func (d DummyFrontend) TypeFloat32() Type { return TypeFloat32 }
-func (d DummyFrontend) TypeFloat64() Type { return TypeFloat64 }
-func (d DummyFrontend) TypeInt() Type { return TypeInt64 }
-func (d DummyFrontend) TypeUintptr() Type { return TypeUInt64 }
-func (d DummyFrontend) TypeString() Type { panic("unimplemented") }
-func (d DummyFrontend) TypeBytePtr() Type { return TypeBytePtr }
+func (d DummyFrontend) TypeBool() Type { return TypeBool }
+func (d DummyFrontend) TypeInt8() Type { return TypeInt8 }
+func (d DummyFrontend) TypeInt16() Type { return TypeInt16 }
+func (d DummyFrontend) TypeInt32() Type { return TypeInt32 }
+func (d DummyFrontend) TypeInt64() Type { return TypeInt64 }
+func (d DummyFrontend) TypeUInt8() Type { return TypeUInt8 }
+func (d DummyFrontend) TypeUInt16() Type { return TypeUInt16 }
+func (d DummyFrontend) TypeUInt32() Type { return TypeUInt32 }
+func (d DummyFrontend) TypeUInt64() Type { return TypeUInt64 }
+func (d DummyFrontend) TypeFloat32() Type { return TypeFloat32 }
+func (d DummyFrontend) TypeFloat64() Type { return TypeFloat64 }
+func (d DummyFrontend) TypeInt() Type { return TypeInt64 }
+func (d DummyFrontend) TypeUintptr() Type { return TypeUInt64 }
+func (d DummyFrontend) TypeString() Type { panic("unimplemented") }
+func (d DummyFrontend) TypeBytePtr() Type { return TypeBytePtr }
+func (d DummyFrontend) DerefItab(sym *obj.LSym, off int64) *obj.LSym { return nil }
func (d DummyFrontend) CanSSA(t Type) bool {
// There are no un-SSAable types in dummy land.