compiler: really define runtime/volatile.* functions

This makes them available to deferred calls, among others.
Этот коммит содержится в:
Ayke van Laethem 2022-06-20 14:56:55 +02:00 коммит произвёл Ron Evans
родитель e1052f921c
коммит 1ceb63d14c
5 изменённых файлов: 22 добавлений и 19 удалений

Просмотреть файл

@ -1642,10 +1642,6 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error)
return b.createSyscall(instr) return b.createSyscall(instr)
case strings.HasPrefix(name, "syscall.rawSyscallNoError"): case strings.HasPrefix(name, "syscall.rawSyscallNoError"):
return b.createRawSyscallNoError(instr) return b.createRawSyscallNoError(instr)
case strings.HasPrefix(name, "runtime/volatile.Load"):
return b.createVolatileLoad(instr)
case strings.HasPrefix(name, "runtime/volatile.Store"):
return b.createVolatileStore(instr)
case name == "runtime.supportsRecover": case name == "runtime.supportsRecover":
supportsRecover := uint64(0) supportsRecover := uint64(0)
if b.supportsRecover() { if b.supportsRecover() {

Просмотреть файл

@ -20,6 +20,10 @@ import (
func (b *builder) defineIntrinsicFunction() { func (b *builder) defineIntrinsicFunction() {
name := b.fn.RelString(nil) name := b.fn.RelString(nil)
switch { switch {
case strings.HasPrefix(name, "runtime/volatile.Load"):
b.createVolatileLoad()
case strings.HasPrefix(name, "runtime/volatile.Store"):
b.createVolatileStore()
case strings.HasPrefix(name, "sync/atomic.") && token.IsExported(b.fn.Name()): case strings.HasPrefix(name, "sync/atomic.") && token.IsExported(b.fn.Name()):
b.createFunctionStart() b.createFunctionStart()
returnValue := b.createAtomicOp(b.fn.Name()) returnValue := b.createAtomicOp(b.fn.Name())

Просмотреть файл

@ -3,28 +3,25 @@ package compiler
// This file implements volatile loads/stores in runtime/volatile.LoadT and // This file implements volatile loads/stores in runtime/volatile.LoadT and
// runtime/volatile.StoreT as compiler builtins. // runtime/volatile.StoreT as compiler builtins.
import (
"golang.org/x/tools/go/ssa"
"tinygo.org/x/go-llvm"
)
// createVolatileLoad is the implementation of the intrinsic function // createVolatileLoad is the implementation of the intrinsic function
// runtime/volatile.LoadT(). // runtime/volatile.LoadT().
func (b *builder) createVolatileLoad(instr *ssa.CallCommon) (llvm.Value, error) { func (b *builder) createVolatileLoad() {
addr := b.getValue(instr.Args[0]) b.createFunctionStart()
b.createNilCheck(instr.Args[0], addr, "deref") addr := b.getValue(b.fn.Params[0])
b.createNilCheck(b.fn.Params[0], addr, "deref")
val := b.CreateLoad(addr, "") val := b.CreateLoad(addr, "")
val.SetVolatile(true) val.SetVolatile(true)
return val, nil b.CreateRet(val)
} }
// createVolatileStore is the implementation of the intrinsic function // createVolatileStore is the implementation of the intrinsic function
// runtime/volatile.StoreT(). // runtime/volatile.StoreT().
func (b *builder) createVolatileStore(instr *ssa.CallCommon) (llvm.Value, error) { func (b *builder) createVolatileStore() {
addr := b.getValue(instr.Args[0]) b.createFunctionStart()
val := b.getValue(instr.Args[1]) addr := b.getValue(b.fn.Params[0])
b.createNilCheck(instr.Args[0], addr, "deref") val := b.getValue(b.fn.Params[1])
b.createNilCheck(b.fn.Params[0], addr, "deref")
store := b.CreateStore(val, addr) store := b.CreateStore(val, addr)
store.SetVolatile(true) store.SetVolatile(true)
return llvm.Value{}, nil b.CreateRetVoid()
} }

7
testdata/atomic.go предоставленный
Просмотреть файл

@ -3,6 +3,8 @@ package main
import ( import (
"sync/atomic" "sync/atomic"
"unsafe" "unsafe"
"runtime/volatile"
) )
func main() { func main() {
@ -82,7 +84,7 @@ func main() {
testValue(int(3), int(-2)) testValue(int(3), int(-2))
testValue("", "foobar", "baz") testValue("", "foobar", "baz")
// Test atomic operations as deferred values. // Test atomic and volatile operations as deferred values.
testDefer() testDefer()
} }
@ -99,8 +101,11 @@ func testValue(values ...interface{}) {
func testDefer() { func testDefer() {
n1 := int32(5) n1 := int32(5)
n2 := uint32(6)
defer func() { defer func() {
println("deferred atomic add:", n1) println("deferred atomic add:", n1)
println("deferred volatile store:", n2)
}() }()
defer atomic.AddInt32(&n1, 3) defer atomic.AddInt32(&n1, 3)
defer volatile.StoreUint32(&n2, 22)
} }

1
testdata/atomic.txt предоставленный
Просмотреть файл

@ -34,3 +34,4 @@ StoreUint64: 20
StoreUintptr: 20 StoreUintptr: 20
StorePointer: true StorePointer: true
deferred atomic add: 8 deferred atomic add: 8
deferred volatile store: 22