mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: get rid of "volatile" in SSA
A value is "volatile" if it is a pointer to the argument region on stack which will be clobbered by function call. This is used to make sure the value is safe when inserting write barrier calls. The writebarrier pass can tell whether a value is such a pointer. Therefore no need to mark it when building SSA and thread this information through. Passes "toolstash -cmp" on std. Updates #17583. Change-Id: Idc5fc0d710152b94b3c504ce8db55ea9ff5b5195 Reviewed-on: https://go-review.googlesource.com/36835 Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
4775b7feb1
commit
5bfd1ef036
4 changed files with 69 additions and 81 deletions
|
|
@ -35,12 +35,12 @@ func writebarrier(f *Func) {
|
|||
hasStore := false
|
||||
for _, v := range b.Values {
|
||||
switch v.Op {
|
||||
case OpStoreWB, OpMoveWB, OpMoveWBVolatile, OpZeroWB:
|
||||
case OpStoreWB, OpMoveWB, OpZeroWB:
|
||||
if IsStackAddr(v.Args[0]) {
|
||||
switch v.Op {
|
||||
case OpStoreWB:
|
||||
v.Op = OpStore
|
||||
case OpMoveWB, OpMoveWBVolatile:
|
||||
case OpMoveWB:
|
||||
v.Op = OpMove
|
||||
v.Aux = nil
|
||||
case OpZeroWB:
|
||||
|
|
@ -103,7 +103,7 @@ func writebarrier(f *Func) {
|
|||
values := b.Values
|
||||
for i := len(values) - 1; i >= 0; i-- {
|
||||
w := values[i]
|
||||
if w.Op == OpStoreWB || w.Op == OpMoveWB || w.Op == OpMoveWBVolatile || w.Op == OpZeroWB {
|
||||
if w.Op == OpStoreWB || w.Op == OpMoveWB || w.Op == OpZeroWB {
|
||||
if last == nil {
|
||||
last = w
|
||||
end = i + 1
|
||||
|
|
@ -159,7 +159,7 @@ func writebarrier(f *Func) {
|
|||
var val *Value
|
||||
ptr := w.Args[0]
|
||||
siz := w.AuxInt
|
||||
typ := w.Aux // only non-nil for MoveWB, MoveWBVolatile, ZeroWB
|
||||
typ := w.Aux // only non-nil for MoveWB, ZeroWB
|
||||
pos = w.Pos
|
||||
|
||||
var op Op
|
||||
|
|
@ -169,7 +169,7 @@ func writebarrier(f *Func) {
|
|||
op = OpStore
|
||||
fn = writebarrierptr
|
||||
val = w.Args[1]
|
||||
case OpMoveWB, OpMoveWBVolatile:
|
||||
case OpMoveWB:
|
||||
op = OpMove
|
||||
fn = typedmemmove
|
||||
val = w.Args[1]
|
||||
|
|
@ -179,7 +179,8 @@ func writebarrier(f *Func) {
|
|||
}
|
||||
|
||||
// then block: emit write barrier call
|
||||
memThen = wbcall(pos, bThen, fn, typ, ptr, val, memThen, sp, sb, w.Op == OpMoveWBVolatile)
|
||||
volatile := w.Op == OpMoveWB && isVolatile(val)
|
||||
memThen = wbcall(pos, bThen, fn, typ, ptr, val, memThen, sp, sb, volatile)
|
||||
|
||||
// else block: normal store
|
||||
if op == OpZero {
|
||||
|
|
@ -223,7 +224,7 @@ func writebarrier(f *Func) {
|
|||
|
||||
// if we have more stores in this block, do this block again
|
||||
for _, w := range b.Values {
|
||||
if w.Op == OpStoreWB || w.Op == OpMoveWB || w.Op == OpMoveWBVolatile || w.Op == OpZeroWB {
|
||||
if w.Op == OpStoreWB || w.Op == OpMoveWB || w.Op == OpZeroWB {
|
||||
goto again
|
||||
}
|
||||
}
|
||||
|
|
@ -303,3 +304,12 @@ func IsStackAddr(v *Value) bool {
|
|||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// isVolatile returns whether v is a pointer to argument region on stack which
|
||||
// will be clobbered by a function call.
|
||||
func isVolatile(v *Value) bool {
|
||||
for v.Op == OpOffPtr || v.Op == OpAddPtr || v.Op == OpPtrIndex || v.Op == OpCopy {
|
||||
v = v.Args[0]
|
||||
}
|
||||
return v.Op == OpSP
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue