diff options
Diffstat (limited to 'src/cmd/compile/internal/ssa')
| -rw-r--r-- | src/cmd/compile/internal/ssa/_gen/genericOps.go | 1 | ||||
| -rw-r--r-- | src/cmd/compile/internal/ssa/deadcode.go | 14 | ||||
| -rw-r--r-- | src/cmd/compile/internal/ssa/func.go | 6 | ||||
| -rw-r--r-- | src/cmd/compile/internal/ssa/lower.go | 2 | ||||
| -rw-r--r-- | src/cmd/compile/internal/ssa/opGen.go | 6 | ||||
| -rw-r--r-- | src/cmd/compile/internal/ssa/writebarrier.go | 35 |
6 files changed, 17 insertions, 47 deletions
diff --git a/src/cmd/compile/internal/ssa/_gen/genericOps.go b/src/cmd/compile/internal/ssa/_gen/genericOps.go index 6ecccc3e92..deb2cb8bd5 100644 --- a/src/cmd/compile/internal/ssa/_gen/genericOps.go +++ b/src/cmd/compile/internal/ssa/_gen/genericOps.go @@ -379,6 +379,7 @@ var genericOps = []opData{ {name: "StoreWB", argLength: 3, typ: "Mem", aux: "Typ"}, // Store arg1 to arg0. arg2=memory, aux=type. Returns memory. {name: "MoveWB", argLength: 3, typ: "Mem", aux: "TypSize"}, // arg0=destptr, arg1=srcptr, arg2=mem, auxint=size, aux=type. Returns memory. {name: "ZeroWB", argLength: 2, typ: "Mem", aux: "TypSize"}, // arg0=destptr, arg1=mem, auxint=size, aux=type. Returns memory. + {name: "WBend", argLength: 1, typ: "Mem"}, // Write barrier code is done, interrupting is now allowed. // WB invokes runtime.gcWriteBarrier. This is not a normal // call: it takes arguments in registers, doesn't clobber diff --git a/src/cmd/compile/internal/ssa/deadcode.go b/src/cmd/compile/internal/ssa/deadcode.go index cfadda82b0..bd4282ecdb 100644 --- a/src/cmd/compile/internal/ssa/deadcode.go +++ b/src/cmd/compile/internal/ssa/deadcode.go @@ -290,20 +290,6 @@ func deadcode(f *Func) { b.truncateValues(i) } - // Remove dead blocks from WBLoads list. - i = 0 - for _, b := range f.WBLoads { - if reachable[b.ID] { - f.WBLoads[i] = b - i++ - } - } - clearWBLoads := f.WBLoads[i:] - for j := range clearWBLoads { - clearWBLoads[j] = nil - } - f.WBLoads = f.WBLoads[:i] - // Remove unreachable blocks. Return dead blocks to allocator. i = 0 for _, b := range f.Blocks { diff --git a/src/cmd/compile/internal/ssa/func.go b/src/cmd/compile/internal/ssa/func.go index b10911aa92..ba3d1e589e 100644 --- a/src/cmd/compile/internal/ssa/func.go +++ b/src/cmd/compile/internal/ssa/func.go @@ -64,12 +64,6 @@ type Func struct { // AuxCall describing parameters and results for this function. OwnAux *AuxCall - // WBLoads is a list of Blocks that branch on the write - // barrier flag. Safe-points are disabled from the OpLoad that - // reads the write-barrier flag until the control flow rejoins - // below the two successors of this block. - WBLoads []*Block - freeValues *Value // free Values linked by argstorage[0]. All other fields except ID are 0/nil. freeBlocks *Block // free Blocks linked by succstorage[0].b. All other fields except ID are 0/nil. diff --git a/src/cmd/compile/internal/ssa/lower.go b/src/cmd/compile/internal/ssa/lower.go index 88eb6748e8..e4aac47cee 100644 --- a/src/cmd/compile/internal/ssa/lower.go +++ b/src/cmd/compile/internal/ssa/lower.go @@ -29,7 +29,7 @@ func checkLower(f *Func) { continue // lowered } switch v.Op { - case OpSP, OpSPanchored, OpSB, OpInitMem, OpArg, OpArgIntReg, OpArgFloatReg, OpPhi, OpVarDef, OpVarLive, OpKeepAlive, OpSelect0, OpSelect1, OpSelectN, OpConvert, OpInlMark: + case OpSP, OpSPanchored, OpSB, OpInitMem, OpArg, OpArgIntReg, OpArgFloatReg, OpPhi, OpVarDef, OpVarLive, OpKeepAlive, OpSelect0, OpSelect1, OpSelectN, OpConvert, OpInlMark, OpWBend: continue // ok not to lower case OpMakeResult: if b.Controls[0] == v { diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go index baf0d7ba32..76ca9e059d 100644 --- a/src/cmd/compile/internal/ssa/opGen.go +++ b/src/cmd/compile/internal/ssa/opGen.go @@ -3022,6 +3022,7 @@ const ( OpStoreWB OpMoveWB OpZeroWB + OpWBend OpWB OpHasCPUFeature OpPanicBounds @@ -38929,6 +38930,11 @@ var opcodeTable = [...]opInfo{ generic: true, }, { + name: "WBend", + argLen: 1, + generic: true, + }, + { name: "WB", auxType: auxSym, argLen: 3, diff --git a/src/cmd/compile/internal/ssa/writebarrier.go b/src/cmd/compile/internal/ssa/writebarrier.go index 02f5649d59..d2e10cab62 100644 --- a/src/cmd/compile/internal/ssa/writebarrier.go +++ b/src/cmd/compile/internal/ssa/writebarrier.go @@ -197,8 +197,6 @@ func writebarrier(f *Func) { // order values in store order b.Values = storeOrder(b.Values, sset, storeNumber) - - firstSplit := true again: // find the start and end of the last contiguous WB store sequence. // a branch will be inserted there. values after it will be moved @@ -374,17 +372,19 @@ func writebarrier(f *Func) { } // merge memory - // Splice memory Phi into the last memory of the original sequence, - // which may be used in subsequent blocks. Other memories in the - // sequence must be dead after this block since there can be only - // one memory live. + mem = bEnd.NewValue2(pos, OpPhi, types.TypeMem, memThen, memElse) + // The last store becomes the WBend marker. This marker is used by the liveness + // pass to determine what parts of the code are preemption-unsafe. + // All subsequent memory operations use this memory, so we have to sacrifice the + // previous last memory op to become this new value. bEnd.Values = append(bEnd.Values, last) last.Block = bEnd - last.reset(OpPhi) + last.reset(OpWBend) last.Pos = last.Pos.WithNotStmt() last.Type = types.TypeMem - last.AddArg(memThen) - last.AddArg(memElse) + last.AddArg(mem) + + // Free all the old stores, except last which became the WBend marker. for _, w := range stores { if w != last { w.resetArgs() @@ -402,23 +402,6 @@ func writebarrier(f *Func) { w.Block = bEnd } - // Preemption is unsafe between loading the write - // barrier-enabled flag and performing the write - // because that would allow a GC phase transition, - // which would invalidate the flag. Remember the - // conditional block so liveness analysis can disable - // safe-points. This is somewhat subtle because we're - // splitting b bottom-up. - if firstSplit { - // Add b itself. - b.Func.WBLoads = append(b.Func.WBLoads, b) - firstSplit = false - } else { - // We've already split b, so we just pushed a - // write barrier test into bEnd. - b.Func.WBLoads = append(b.Func.WBLoads, bEnd) - } - // if we have more stores in this block, do this block again if nWBops > 0 { goto again |
