diff --git a/llvm/_core.cpp b/llvm/_core.cpp index c904ad1..14143f2 100644 --- a/llvm/_core.cpp +++ b/llvm/_core.cpp @@ -744,8 +744,8 @@ _wrap_objenumobjobjstr2obj(LLVMBuildFCmp, LLVMBuilderRef, LLVMRealPredicate, LLV /* Atomics */ _wrap_objobjobjobjstrint2obj(LLVMBuildAtomicCmpXchg, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) _wrap_objstrobjobjstrint2obj(LLVMBuildAtomicRMW, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobjstrint2obj(LLVMBuildAtomicLoad, LLVMBuilderRef, LLVMValueRef, LLVMValueRef) -_wrap_objobjobjstrint2obj(LLVMBuildAtomicStore, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjintstrint2obj(LLVMBuildAtomicLoad, LLVMBuilderRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjintstrint2obj(LLVMBuildAtomicStore, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) _wrap_objstrint2obj(LLVMBuildFence, LLVMBuilderRef, LLVMValueRef) /* Miscellaneous instructions */ diff --git a/llvm/core.py b/llvm/core.py index 962b018..47b3b8a 100644 --- a/llvm/core.py +++ b/llvm/core.py @@ -2048,23 +2048,24 @@ class Builder(object): return self.atomic_rmw('umin', *args, **kwargs) - def atomic_load(self, ptr, ordering, crossthread=True, volatile=False, name=""): + def atomic_load(self, ptr, ordering, align=1, crossthread=True, + volatile=False, name=""): check_is_value(ptr) inst = _make_value(_core.LLVMBuildAtomicLoad( - self.ptr, ptr.ptr, ordering.lower(), - int(bool(crossthread)))) + self.ptr, ptr.ptr, int(align), + ordering.lower(), int(bool(crossthread)))) if volatile: inst.set_volatile(volatile) if inst: inst.name = name return inst - def atomic_store(self, value, ptr, ordering, crossthread=True, + def atomic_store(self, value, ptr, ordering, align=1, crossthread=True, volatile=False): check_is_value(value) check_is_value(ptr) inst = _make_value(_core.LLVMBuildAtomicStore( - self.ptr, ptr.ptr, value.ptr, + self.ptr, ptr.ptr, value.ptr, int(align), ordering.lower(), int(bool(crossthread)))) if volatile: inst.set_volatile(volatile) diff --git a/llvm/extra.cpp b/llvm/extra.cpp index cd6aeee..122d387 100644 --- a/llvm/extra.cpp +++ b/llvm/extra.cpp @@ -193,7 +193,8 @@ LLVMValueRef LLVMBuildAtomicRMW(LLVMBuilderRef builder, const char * opname, } LLVMValueRef LLVMBuildAtomicLoad(LLVMBuilderRef builder, LLVMValueRef ptr, - const char* ordering, int crossthread) + unsigned align, const char* ordering, + int crossthread) { using namespace llvm; AtomicOrdering atomic_order = atomic_ordering_from_string(ordering); @@ -202,13 +203,15 @@ LLVMValueRef LLVMBuildAtomicLoad(LLVMBuilderRef builder, LLVMValueRef ptr, LoadInst * inst = unwrap(builder)->CreateLoad(unwrap(ptr)); inst->setAtomic(atomic_order, sync_scope); + inst->setAlignment(align); return wrap(inst); } LLVMValueRef LLVMBuildAtomicStore(LLVMBuilderRef builder, LLVMValueRef ptr, LLVMValueRef val, - const char* ordering, int crossthread) + unsigned align, const char* ordering, + int crossthread) { using namespace llvm; AtomicOrdering atomic_order = atomic_ordering_from_string(ordering); @@ -217,6 +220,7 @@ LLVMValueRef LLVMBuildAtomicStore(LLVMBuilderRef builder, StoreInst * inst = unwrap(builder)->CreateStore(unwrap(val), unwrap(ptr)); inst->setAtomic(atomic_order, sync_scope); + inst->setAlignment(align); return wrap(inst); } diff --git a/llvm/extra.h b/llvm/extra.h index 9bd0ddb..b13c80f 100644 --- a/llvm/extra.h +++ b/llvm/extra.h @@ -56,13 +56,15 @@ LLVMValueRef LLVMBuildFence(LLVMBuilderRef builder, const char* ordering, * Wraps IRBuilder::CreateLoad, LoadInst::setAtomic */ LLVMValueRef LLVMBuildAtomicLoad(LLVMBuilderRef builder, LLVMValueRef ptr, - const char* ordering, int crossthread); + unsigned align, const char* ordering, + int crossthread); /* * Wraps IRBuilder::CreateStore, StoreInst::setAtomic */ LLVMValueRef LLVMBuildAtomicStore(LLVMBuilderRef builder, LLVMValueRef ptr, LLVMValueRef val, - const char* ordering, int crossthread); + unsigned align, const char* ordering, + int crossthread); /* * Wraps IRBuilder::CreateAtomicRMW diff --git a/llvm/wrap.h b/llvm/wrap.h index 9cebd74..bceca87 100644 --- a/llvm/wrap.h +++ b/llvm/wrap.h @@ -695,6 +695,31 @@ _w ## func (PyObject *self, PyObject *args) \ } + +/** + * Wrap LLVM functions of the type + * outtype func(intype1 arg1, intype2 arg2, arg3, const char *arg4, arg5) + */ +#define _wrap_objobjintstrint2obj(func, intype1, intype2, outtype)\ +static PyObject * \ +_w ## func (PyObject *self, PyObject *args) \ +{ \ + PyObject *obj1, *obj2; \ + intype1 arg1; \ + intype2 arg2; \ + int arg3; \ + const char *arg4; \ + int arg5; \ + \ + if (!PyArg_ParseTuple(args, "OOisi", &obj1, &obj2, &arg3, &arg4, &arg5)) \ + return NULL; \ + \ + arg1 = ( intype1 ) PyCapsule_GetPointer(obj1, NULL); \ + arg2 = ( intype2 ) PyCapsule_GetPointer(obj2, NULL); \ + \ + return ctor_ ## outtype ( func (arg1, arg2, arg3, arg4, arg5)); \ +} + /** * Wrap LLVM functions of the type * outtype func(intype1 arg1, const char *arg2, arg3) @@ -743,6 +768,34 @@ _w ## func (PyObject *self, PyObject *args) \ } + + +/** + * Wrap LLVM functions of the type + * outtype func(intype1 arg1, intype2 arg2, intype3, arg4, const char *arg5, arg6) + */ +#define _wrap_objobjobjintstrint2obj(func, intype1, intype2, intype3, outtype)\ +static PyObject * \ +_w ## func (PyObject *self, PyObject *args) \ +{ \ + PyObject *obj1, *obj2, *obj3; \ + intype1 arg1; \ + intype2 arg2; \ + intype3 arg3; \ + int arg4; \ + const char *arg5; \ + int arg6; \ + \ + if (!PyArg_ParseTuple(args, "OOOisi", &obj1, &obj2, &obj3, &arg4, &arg5, &arg6)) \ + return NULL; \ + \ + arg1 = ( intype1 ) PyCapsule_GetPointer(obj1, NULL); \ + arg2 = ( intype2 ) PyCapsule_GetPointer(obj2, NULL); \ + arg3 = ( intype3 ) PyCapsule_GetPointer(obj3, NULL); \ + \ + return ctor_ ## outtype ( func (arg1, arg2, arg3, arg4, arg5, arg6)); \ +} + /** * Wrap LLVM functions of the type * outtype func(intype1 arg1, intype2 arg2, intype3 arg3, intype4, const char *arg5, arg6) @@ -770,6 +823,7 @@ _w ## func (PyObject *self, PyObject *args) \ return ctor_ ## outtype ( func (arg1, arg2, arg3, arg4, arg5, arg6)); \ } + /** * Wrap LLVM functions of the type * outtype func(intype1 arg1, const char* arg2, intype3 arg3, intype4, const char *arg5, arg6) diff --git a/test/atomic.py b/test/atomic.py index dc4896d..fd565cc 100644 --- a/test/atomic.py +++ b/test/atomic.py @@ -89,16 +89,19 @@ class TestAtomic(unittest.TestCase): for ordering in test_these_orderings: loaded = bldr.atomic_load(ptr, ordering) self.assertIn('load atomic', str(loaded)) - self.assertEqual(ordering, str(loaded).strip().split(' ')[-1]) + self.assertEqual(ordering, + str(loaded).strip().split(' ')[-3].rstrip(',')) + self.assertIn('align 1', str(loaded)) stored = bldr.atomic_store(loaded, ptr, ordering) self.assertIn('store atomic', str(stored)) - self.assertEqual(ordering, str(stored).strip().split(' ')[-1]) + self.assertEqual(ordering, + str(stored).strip().split(' ')[-3].rstrip(',')) + self.assertIn('align 1', str(stored)) fenced = bldr.fence(ordering) self.assertEqual(['fence', ordering], str(fenced).strip().split(' ')) - if __name__ == '__main__': unittest.main()