atomic Load/Store

This commit is contained in:
xushiwei
2024-06-16 16:35:46 +08:00
parent fbd15a81b4
commit 340b5bd165
9 changed files with 236 additions and 156 deletions

View File

@@ -27,6 +27,18 @@ import (
"github.com/goplus/llvm"
)
type AtomicOrdering = llvm.AtomicOrdering
const (
OrderingNotAtomic = llvm.AtomicOrderingNotAtomic
OrderingUnordered = llvm.AtomicOrderingUnordered
OrderingMonotonic = llvm.AtomicOrderingMonotonic
OrderingAcquire = llvm.AtomicOrderingAcquire
OrderingRelease = llvm.AtomicOrderingRelease
OrderingAcquireRelease = llvm.AtomicOrderingAcquireRelease
OrderingSeqConsistent = llvm.AtomicOrderingSequentiallyConsistent
)
// -----------------------------------------------------------------------------
type Expr struct {
@@ -41,6 +53,12 @@ func (v Expr) IsNil() bool {
return v.Type == nil
}
// SetOrdering sets the ordering of the atomic operation.
func (v Expr) SetOrdering(ordering AtomicOrdering) Expr {
v.impl.SetOrdering(ordering)
return v
}
// -----------------------------------------------------------------------------
type builtinTy struct {

View File

@@ -26,46 +26,6 @@ import (
// -----------------------------------------------------------------------------
// Advance returns the pointer ptr advanced by offset.
func (b Builder) Advance(ptr Expr, offset Expr) Expr {
if debugInstr {
log.Printf("Advance %v, %v\n", ptr.impl, offset.impl)
}
var elem llvm.Type
var prog = b.Prog
switch t := ptr.raw.Type.(type) {
case *types.Basic: // void
elem = prog.tyInt8()
default:
elem = prog.rawType(t.(*types.Pointer).Elem()).ll
}
ret := llvm.CreateGEP(b.impl, elem, ptr.impl, []llvm.Value{offset.impl})
return Expr{ret, ptr.Type}
}
// Load returns the value at the pointer ptr.
func (b Builder) Load(ptr Expr) Expr {
if debugInstr {
log.Printf("Load %v\n", ptr.impl)
}
if ptr.kind == vkPyVarRef {
return b.pyLoad(ptr)
}
telem := b.Prog.Elem(ptr.Type)
return Expr{llvm.CreateLoad(b.impl, telem.ll, ptr.impl), telem}
}
// Store stores val at the pointer ptr.
func (b Builder) Store(ptr, val Expr) Builder {
raw := ptr.raw.Type
if debugInstr {
log.Printf("Store %v, %v, %v\n", raw, ptr.impl, val.impl)
}
val = checkExpr(val, raw.(*types.Pointer).Elem(), b)
b.impl.CreateStore(val.impl, ptr.impl)
return b
}
func (b Builder) aggregateAllocU(t Type, flds ...llvm.Value) llvm.Value {
prog := b.Prog
size := prog.SizeOf(t)
@@ -295,4 +255,43 @@ func (b Builder) AtomicCmpXchg(ptr, old, new Expr) Expr {
return Expr{ret, t}
}
// Load returns the value at the pointer ptr.
func (b Builder) Load(ptr Expr) Expr {
if debugInstr {
log.Printf("Load %v\n", ptr.impl)
}
if ptr.kind == vkPyVarRef {
return b.pyLoad(ptr)
}
telem := b.Prog.Elem(ptr.Type)
return Expr{llvm.CreateLoad(b.impl, telem.ll, ptr.impl), telem}
}
// Store stores val at the pointer ptr.
func (b Builder) Store(ptr, val Expr) Expr {
raw := ptr.raw.Type
if debugInstr {
log.Printf("Store %v, %v, %v\n", raw, ptr.impl, val.impl)
}
val = checkExpr(val, raw.(*types.Pointer).Elem(), b)
return Expr{b.impl.CreateStore(val.impl, ptr.impl), b.Prog.Void()}
}
// Advance returns the pointer ptr advanced by offset.
func (b Builder) Advance(ptr Expr, offset Expr) Expr {
if debugInstr {
log.Printf("Advance %v, %v\n", ptr.impl, offset.impl)
}
var elem llvm.Type
var prog = b.Prog
switch t := ptr.raw.Type.(type) {
case *types.Basic: // void
elem = prog.tyInt8()
default:
elem = prog.rawType(t.(*types.Pointer).Elem()).ll
}
ret := llvm.CreateGEP(b.impl, elem, ptr.impl, []llvm.Value{offset.impl})
return Expr{ret, ptr.Type}
}
// -----------------------------------------------------------------------------