Add memory fence

This commit is contained in:
Siu Kwan Lam 2012-08-03 12:30:01 -07:00
commit f479f85676
6 changed files with 54 additions and 2 deletions

View file

@ -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 )

View file

@ -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
#===----------------------------------------------------------------------===

View file

@ -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)

View file

@ -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,

View file

@ -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, <unsigned/signed int> 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, <unsigned/signed int> arg5)

View file

@ -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()