aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/ssa/regalloc.go
diff options
context:
space:
mode:
authorJosh Bleecher Snyder <josharian@gmail.com>2018-03-16 07:15:59 -0700
committerJosh Bleecher Snyder <josharian@gmail.com>2018-03-29 18:47:18 +0000
commit014a9048d4f25b4afd090c9d5e7efe0b7c7b6dda (patch)
treee8cbaf071e24c5cb3eeecba2f966fbd663796e50 /src/cmd/compile/internal/ssa/regalloc.go
parent5d8d3d52b0075de122d1536dff1a9fab942ab700 (diff)
downloadgo-014a9048d4f25b4afd090c9d5e7efe0b7c7b6dda.tar.gz
go-014a9048d4f25b4afd090c9d5e7efe0b7c7b6dda.zip
cmd/compile: prefer to evict a rematerializable register
This resolves a long-standing regalloc TODO: If you must evict a register, choose to evict a register containing a rematerializable value, since that value won't need to be spilled. Provides very minor performance and size improvements. name old time/op new time/op delta BinaryTree17-8 2.20s ± 3% 2.18s ± 2% -0.77% (p=0.000 n=45+49) Fannkuch11-8 2.14s ± 2% 2.15s ± 2% +0.73% (p=0.000 n=43+44) FmtFprintfEmpty-8 30.6ns ± 4% 30.2ns ± 3% -1.14% (p=0.000 n=50+48) FmtFprintfString-8 54.5ns ± 6% 53.6ns ± 5% -1.64% (p=0.001 n=50+48) FmtFprintfInt-8 58.0ns ± 7% 57.6ns ± 4% ~ (p=0.220 n=50+50) FmtFprintfIntInt-8 85.3ns ± 2% 84.8ns ± 3% -0.62% (p=0.001 n=44+47) FmtFprintfPrefixedInt-8 93.9ns ± 6% 93.6ns ± 5% ~ (p=0.706 n=50+48) FmtFprintfFloat-8 178ns ± 4% 177ns ± 4% ~ (p=0.107 n=49+50) FmtManyArgs-8 376ns ± 4% 374ns ± 3% -0.58% (p=0.013 n=45+50) GobDecode-8 4.77ms ± 2% 4.76ms ± 3% ~ (p=0.059 n=47+46) GobEncode-8 4.04ms ± 2% 3.99ms ± 3% -1.13% (p=0.000 n=49+49) Gzip-8 177ms ± 2% 180ms ± 3% +1.43% (p=0.000 n=48+48) Gunzip-8 28.5ms ± 6% 28.3ms ± 5% ~ (p=0.104 n=50+49) HTTPClientServer-8 72.1µs ± 1% 72.0µs ± 1% -0.15% (p=0.042 n=48+42) JSONEncode-8 9.81ms ± 5% 10.03ms ± 6% +2.29% (p=0.000 n=50+49) JSONDecode-8 39.2ms ± 3% 39.3ms ± 2% ~ (p=0.095 n=49+49) Mandelbrot200-8 3.48ms ± 2% 3.46ms ± 2% -0.80% (p=0.000 n=47+48) GoParse-8 2.54ms ± 3% 2.51ms ± 3% -1.35% (p=0.000 n=49+49) RegexpMatchEasy0_32-8 66.0ns ± 7% 65.7ns ± 8% ~ (p=0.331 n=50+50) RegexpMatchEasy0_1K-8 155ns ± 4% 154ns ± 4% ~ (p=0.986 n=49+50) RegexpMatchEasy1_32-8 62.6ns ± 8% 62.2ns ± 5% ~ (p=0.395 n=50+49) RegexpMatchEasy1_1K-8 260ns ± 5% 255ns ± 3% -1.92% (p=0.000 n=49+49) RegexpMatchMedium_32-8 92.9ns ± 2% 91.8ns ± 2% -1.25% (p=0.000 n=46+48) RegexpMatchMedium_1K-8 27.7µs ± 3% 27.0µs ± 2% -2.59% (p=0.000 n=49+49) RegexpMatchHard_32-8 1.23µs ± 4% 1.21µs ± 2% -2.16% (p=0.000 n=49+44) RegexpMatchHard_1K-8 36.4µs ± 2% 35.7µs ± 2% -1.87% (p=0.000 n=48+49) Revcomp-8 274ms ± 2% 276ms ± 3% +0.70% (p=0.034 n=45+48) Template-8 45.1ms ± 8% 45.1ms ± 8% ~ (p=0.643 n=50+50) TimeParse-8 223ns ± 2% 223ns ± 2% ~ (p=0.401 n=47+47) TimeFormat-8 245ns ± 2% 246ns ± 3% ~ (p=0.758 n=49+50) [Geo mean] 36.5µs 36.3µs -0.54% name old object-bytes new object-bytes delta Template 480kB ± 0% 480kB ± 0% ~ (all equal) Unicode 214kB ± 0% 214kB ± 0% ~ (all equal) GoTypes 1.54MB ± 0% 1.54MB ± 0% -0.03% (p=0.008 n=5+5) Compiler 5.75MB ± 0% 5.75MB ± 0% ~ (all equal) SSA 14.6MB ± 0% 14.6MB ± 0% -0.01% (p=0.008 n=5+5) Flate 300kB ± 0% 300kB ± 0% -0.01% (p=0.008 n=5+5) GoParser 366kB ± 0% 366kB ± 0% ~ (all equal) Reflect 1.20MB ± 0% 1.20MB ± 0% ~ (all equal) Tar 413kB ± 0% 413kB ± 0% ~ (all equal) XML 529kB ± 0% 528kB ± 0% -0.13% (p=0.008 n=5+5) [Geo mean] 909kB 909kB -0.02% Change-Id: I46d37a55197683a98913f35801dc2b0d609653c8 Reviewed-on: https://go-review.googlesource.com/103240 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> Reviewed-by: Cherry Zhang <cherryyz@google.com>
Diffstat (limited to 'src/cmd/compile/internal/ssa/regalloc.go')
-rw-r--r--src/cmd/compile/internal/ssa/regalloc.go20
1 files changed, 15 insertions, 5 deletions
diff --git a/src/cmd/compile/internal/ssa/regalloc.go b/src/cmd/compile/internal/ssa/regalloc.go
index a16353a781..0839bba86d 100644
--- a/src/cmd/compile/internal/ssa/regalloc.go
+++ b/src/cmd/compile/internal/ssa/regalloc.go
@@ -1746,9 +1746,10 @@ type edgeState struct {
destinations []dstRecord
extra []dstRecord
- usedRegs regMask // registers currently holding something
- uniqueRegs regMask // registers holding the only copy of a value
- finalRegs regMask // registers holding final target
+ usedRegs regMask // registers currently holding something
+ uniqueRegs regMask // registers holding the only copy of a value
+ finalRegs regMask // registers holding final target
+ rematerializeableRegs regMask // registers that hold rematerializeable values
}
type contentRecord struct {
@@ -1782,6 +1783,7 @@ func (e *edgeState) setup(idx int, srcReg []endReg, dstReg []startReg, stacklive
e.usedRegs = 0
e.uniqueRegs = 0
e.finalRegs = 0
+ e.rematerializeableRegs = 0
// Live registers can be sources.
for _, x := range srcReg {
@@ -2041,6 +2043,9 @@ func (e *edgeState) set(loc Location, vid ID, c *Value, final bool, pos src.XPos
e.uniqueRegs &^= regMask(1) << uint(t.num)
}
}
+ if e.s.values[vid].rematerializeable {
+ e.rematerializeableRegs |= regMask(1) << uint(r.num)
+ }
}
if e.s.f.pass.debug > regDebug {
fmt.Printf("%s\n", c.LongString())
@@ -2082,6 +2087,7 @@ func (e *edgeState) erase(loc Location) {
if cr.final {
e.finalRegs &^= regMask(1) << uint(r.num)
}
+ e.rematerializeableRegs &^= regMask(1) << uint(r.num)
}
if len(a) == 1 {
if r, ok := e.s.f.getHome(a[0].ID).(*Register); ok {
@@ -2105,7 +2111,7 @@ func (e *edgeState) findRegFor(typ *types.Type) Location {
// 1) an unused register
// 2) a non-unique register not holding a final value
// 3) a non-unique register
- // 4) TODO: a register holding a rematerializeable value
+ // 4) a register holding a rematerializeable value
x := m &^ e.usedRegs
if x != 0 {
return &e.s.registers[pickReg(x)]
@@ -2118,6 +2124,10 @@ func (e *edgeState) findRegFor(typ *types.Type) Location {
if x != 0 {
return &e.s.registers[pickReg(x)]
}
+ x = m & e.rematerializeableRegs
+ if x != 0 {
+ return &e.s.registers[pickReg(x)]
+ }
// No register is available.
// Pick a register to spill.
@@ -2145,7 +2155,7 @@ func (e *edgeState) findRegFor(typ *types.Type) Location {
}
}
- fmt.Printf("m:%d unique:%d final:%d\n", m, e.uniqueRegs, e.finalRegs)
+ fmt.Printf("m:%d unique:%d final:%d rematerializable:%d\n", m, e.uniqueRegs, e.finalRegs, e.rematerializeableRegs)
for _, vid := range e.cachedVals {
a := e.cache[vid]
for _, c := range a {