diff --git a/llvm/_core.cpp b/llvm/_core.cpp index 7abee27..c904ad1 100644 --- a/llvm/_core.cpp +++ b/llvm/_core.cpp @@ -746,6 +746,7 @@ _wrap_objobjobjobjstrint2obj(LLVMBuildAtomicCmpXchg, LLVMBuilderRef, LLVMValueRe _wrap_objstrobjobjstrint2obj(LLVMBuildAtomicRMW, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) _wrap_objobjstrint2obj(LLVMBuildAtomicLoad, LLVMBuilderRef, LLVMValueRef, LLVMValueRef) _wrap_objobjobjstrint2obj(LLVMBuildAtomicStore, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objstrint2obj(LLVMBuildFence, LLVMBuilderRef, LLVMValueRef) /* Miscellaneous instructions */ @@ -1659,6 +1660,7 @@ static PyMethodDef core_methods[] = { _method( LLVMBuildAtomicRMW ) _method( LLVMBuildAtomicLoad ) _method( LLVMBuildAtomicStore ) + _method( LLVMBuildFence ) /* Miscellaneous instructions */ _method( LLVMBuildGetResult ) diff --git a/llvm/core.py b/llvm/core.py index bdb1485..962b018 100644 --- a/llvm/core.py +++ b/llvm/core.py @@ -2070,6 +2070,11 @@ class Builder(object): inst.set_volatile(volatile) return inst + def fence(self, ordering, crossthread=True): + inst = _make_value(_core.LLVMBuildFence(self.ptr, ordering.lower(), + int(bool(crossthread)))) + return inst + #===----------------------------------------------------------------------=== # Memory buffer #===----------------------------------------------------------------------=== diff --git a/llvm/extra.cpp b/llvm/extra.cpp index ca5e0ea..cd6aeee 100644 --- a/llvm/extra.cpp +++ b/llvm/extra.cpp @@ -140,6 +140,17 @@ llvm::SynchronizationScope sync_scope_from_int(int crossthread) return llvm::SingleThread; } +LLVMValueRef LLVMBuildFence(LLVMBuilderRef builder, const char* ordering, + int crossthread) +{ + using namespace llvm; + AtomicOrdering atomic_order = atomic_ordering_from_string(ordering); + SynchronizationScope sync_scope = sync_scope_from_int(crossthread); + + Value * inst = unwrap(builder)->CreateFence(atomic_order, sync_scope); + return wrap(inst); +} + LLVMValueRef LLVMBuildAtomicRMW(LLVMBuilderRef builder, const char * opname, LLVMValueRef ptr, LLVMValueRef val, const char* ordering, int crossthread) diff --git a/llvm/extra.h b/llvm/extra.h index b773f19..9bd0ddb 100644 --- a/llvm/extra.h +++ b/llvm/extra.h @@ -47,12 +47,18 @@ extern "C" { /* - * Wraps IRBuilder::CreateLoad, setAtomic + * Wraps IRBuilder::CreateFence + */ +LLVMValueRef LLVMBuildFence(LLVMBuilderRef builder, const char* ordering, + int crossthread); + +/* + * Wraps IRBuilder::CreateLoad, LoadInst::setAtomic */ LLVMValueRef LLVMBuildAtomicLoad(LLVMBuilderRef builder, LLVMValueRef ptr, const char* ordering, int crossthread); /* - * Wraps IRBuilder::CreateStore, setAtomic + * Wraps IRBuilder::CreateStore, StoreInst::setAtomic */ LLVMValueRef LLVMBuildAtomicStore(LLVMBuilderRef builder, LLVMValueRef ptr, LLVMValueRef val, diff --git a/llvm/wrap.h b/llvm/wrap.h index fec5b72..9cebd74 100644 --- a/llvm/wrap.h +++ b/llvm/wrap.h @@ -694,6 +694,29 @@ _w ## func (PyObject *self, PyObject *args) \ return ctor_ ## outtype ( func (arg1, arg2, arg3, arg4)); \ } + +/** + * Wrap LLVM functions of the type + * outtype func(intype1 arg1, const char *arg2, arg3) + */ +#define _wrap_objstrint2obj(func, intype1, outtype)\ +static PyObject * \ +_w ## func (PyObject *self, PyObject *args) \ +{ \ + PyObject *obj1; \ + intype1 arg1; \ + const char *arg2; \ + int arg3; \ + \ + if (!PyArg_ParseTuple(args, "Osi", &obj1, &arg2, &arg3)) \ + return NULL; \ + \ + arg1 = ( intype1 ) PyCapsule_GetPointer(obj1, NULL); \ + \ + return ctor_ ## outtype ( func (arg1, arg2, arg3)); \ +} + + /** * Wrap LLVM functions of the type * outtype func(intype1 arg1, intype2 arg2, intype3, const char *arg4, arg5) diff --git a/test/atomic.py b/test/atomic.py index ad99525..dc4896d 100644 --- a/test/atomic.py +++ b/test/atomic.py @@ -90,10 +90,15 @@ class TestAtomic(unittest.TestCase): loaded = bldr.atomic_load(ptr, ordering) self.assertIn('load atomic', str(loaded)) self.assertEqual(ordering, str(loaded).strip().split(' ')[-1]) + stored = bldr.atomic_store(loaded, ptr, ordering) self.assertIn('store atomic', str(stored)) self.assertEqual(ordering, str(stored).strip().split(' ')[-1]) + fenced = bldr.fence(ordering) + self.assertEqual(['fence', ordering], str(fenced).strip().split(' ')) + + if __name__ == '__main__': unittest.main()