Skip to content

Commit 94a017f

Browse files
committed
cmd/compile: allow OpVarXXX calls to be duplicated in writebarrier blocks
OpVarXXX Values don't generate instructions, so there's no reason not to duplicate them, and duplicating them generates better code (fewer branches). This requires changing the start/end accounting to correctly handle the case in which we have run of Values beginning with an OpVarXXX, e.g. OpVarDef, OpZeroWB, OpMoveWB. In that case, the sequence of values should begin at the OpZeroWB, not the OpVarDef. This also lays the groundwork for experimenting with allowing duplication of some scalar stores. Shrinks function text sizes a tiny amount: name old object-bytes new object-bytes delta Template 381k ± 0% 381k ± 0% -0.01% (p=0.008 n=5+5) Unicode 203k ± 0% 203k ± 0% -0.04% (p=0.008 n=5+5) GoTypes 1.17M ± 0% 1.17M ± 0% -0.01% (p=0.008 n=5+5) SSA 8.24M ± 0% 8.24M ± 0% -0.00% (p=0.008 n=5+5) Flate 230k ± 0% 230k ± 0% ~ (all equal) GoParser 286k ± 0% 286k ± 0% ~ (all equal) Reflect 1.00M ± 0% 1.00M ± 0% ~ (all equal) Tar 189k ± 0% 189k ± 0% ~ (all equal) XML 415k ± 0% 415k ± 0% -0.01% (p=0.008 n=5+5) Updates #19838 Change-Id: Ic5ef30855919f1468066eba08ae5c4bd9a01db27 Reviewed-on: https://go-review.googlesource.com/42011 Run-TryBot: Josh Bleecher Snyder <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Cherry Zhang <[email protected]>
1 parent 5331e7e commit 94a017f

File tree

1 file changed

+28
-12
lines changed

1 file changed

+28
-12
lines changed

src/cmd/compile/internal/ssa/writebarrier.go

+28-12
Original file line numberDiff line numberDiff line change
@@ -117,18 +117,23 @@ func writebarrier(f *Func) {
117117
var last *Value
118118
var start, end int
119119
values := b.Values
120+
FindSeq:
120121
for i := len(values) - 1; i >= 0; i-- {
121122
w := values[i]
122-
if w.Op == OpStoreWB || w.Op == OpMoveWB || w.Op == OpZeroWB {
123+
switch w.Op {
124+
case OpStoreWB, OpMoveWB, OpZeroWB:
125+
start = i
123126
if last == nil {
124127
last = w
125128
end = i + 1
126129
}
127-
} else {
128-
if last != nil {
129-
start = i + 1
130-
break
130+
case OpVarDef, OpVarLive, OpVarKill:
131+
continue
132+
default:
133+
if last == nil {
134+
continue
131135
}
136+
break FindSeq
132137
}
133138
}
134139
stores = append(stores[:0], b.Values[start:end]...) // copy to avoid aliasing
@@ -190,11 +195,17 @@ func writebarrier(f *Func) {
190195
case OpZeroWB:
191196
fn = typedmemclr
192197
typ = &ExternSymbol{Sym: w.Aux.(*types.Type).Symbol()}
198+
case OpVarDef, OpVarLive, OpVarKill:
193199
}
194200

195201
// then block: emit write barrier call
196-
volatile := w.Op == OpMoveWB && isVolatile(val)
197-
memThen = wbcall(pos, bThen, fn, typ, ptr, val, memThen, sp, sb, volatile)
202+
switch w.Op {
203+
case OpStoreWB, OpMoveWB, OpZeroWB:
204+
volatile := w.Op == OpMoveWB && isVolatile(val)
205+
memThen = wbcall(pos, bThen, fn, typ, ptr, val, memThen, sp, sb, volatile)
206+
case OpVarDef, OpVarLive, OpVarKill:
207+
memThen = bThen.NewValue1A(pos, w.Op, types.TypeMem, w.Aux, memThen)
208+
}
198209

199210
// else block: normal store
200211
switch w.Op {
@@ -206,13 +217,18 @@ func writebarrier(f *Func) {
206217
case OpZeroWB:
207218
memElse = bElse.NewValue2I(pos, OpZero, types.TypeMem, w.AuxInt, ptr, memElse)
208219
memElse.Aux = w.Aux
220+
case OpVarDef, OpVarLive, OpVarKill:
221+
memElse = bElse.NewValue1A(pos, w.Op, types.TypeMem, w.Aux, memElse)
209222
}
210223

211-
if !f.WBPos.IsKnown() {
212-
f.WBPos = pos
213-
}
214-
if f.fe.Debug_wb() {
215-
f.Warnl(pos, "write barrier")
224+
if fn != nil {
225+
// Note that we set up a writebarrier function call.
226+
if !f.WBPos.IsKnown() {
227+
f.WBPos = pos
228+
}
229+
if f.fe.Debug_wb() {
230+
f.Warnl(pos, "write barrier")
231+
}
216232
}
217233
}
218234

0 commit comments

Comments
 (0)