Commit 5bfd1ef0 authored by Cherry Zhang's avatar Cherry Zhang

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: 's avatarKeith Randall <khr@golang.org>
parent 4775b7fe
This diff is collapsed.
......@@ -298,10 +298,9 @@ var genericOps = []opData{
// Memory operations with write barriers.
// Expand to runtime calls. Write barrier will be removed if write on stack.
{name: "StoreWB", argLength: 3, typ: "Mem", aux: "Int64"}, // Store arg1 to arg0. arg2=memory, auxint=size. Returns memory.
{name: "MoveWB", argLength: 3, typ: "Mem", aux: "SymSizeAndAlign"}, // arg0=destptr, arg1=srcptr, arg2=mem, auxint=size+alignment, aux=symbol-of-type (for typedmemmove). Returns memory.
{name: "MoveWBVolatile", argLength: 3, typ: "Mem", aux: "SymSizeAndAlign"}, // arg0=destptr, arg1=srcptr, arg2=mem, auxint=size+alignment, aux=symbol-of-type (for typedmemmove). Returns memory. Src is volatile, i.e. needs to move to a temp space before calling typedmemmove.
{name: "ZeroWB", argLength: 2, typ: "Mem", aux: "SymSizeAndAlign"}, // arg0=destptr, arg1=mem, auxint=size+alignment, aux=symbol-of-type. Returns memory.
{name: "StoreWB", argLength: 3, typ: "Mem", aux: "Int64"}, // Store arg1 to arg0. arg2=memory, auxint=size. Returns memory.
{name: "MoveWB", argLength: 3, typ: "Mem", aux: "SymSizeAndAlign"}, // arg0=destptr, arg1=srcptr, arg2=mem, auxint=size+alignment, aux=symbol-of-type (for typedmemmove). Returns memory.
{name: "ZeroWB", argLength: 2, typ: "Mem", aux: "SymSizeAndAlign"}, // arg0=destptr, arg1=mem, auxint=size+alignment, aux=symbol-of-type. Returns memory.
// Function calls. Arguments to the call have already been written to the stack.
// Return values appear on the stack. The method receiver, if any, is treated
......
......@@ -1818,7 +1818,6 @@ const (
OpZero
OpStoreWB
OpMoveWB
OpMoveWBVolatile
OpZeroWB
OpClosureCall
OpStaticCall
......@@ -21623,12 +21622,6 @@ var opcodeTable = [...]opInfo{
argLen: 3,
generic: true,
},
{
name: "MoveWBVolatile",
auxType: auxSymSizeAndAlign,
argLen: 3,
generic: true,
},
{
name: "ZeroWB",
auxType: auxSymSizeAndAlign,
......
......@@ -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
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment