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)
case strings.HasPrefix(name, "syscall.rawSyscallNoError"):
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":
supportsRecover := uint64(0)
if b.supportsRecover() {

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

@ -20,6 +20,10 @@ import (
func (b *builder) defineIntrinsicFunction() {
name := b.fn.RelString(nil)
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()):
b.createFunctionStart()
returnValue := b.createAtomicOp(b.fn.Name())

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

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

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

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

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

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