Added atomic cmpxchg.
This commit is contained in:
parent
9d068fd582
commit
acad5c9d8b
6 changed files with 127 additions and 0 deletions
|
|
@ -740,6 +740,10 @@ _wrap_objobjobjstr2obj(LLVMBuildBitCast, LLVMBuilderRef, LLVMValueRef, LLVMTypeR
|
|||
_wrap_objenumobjobjstr2obj(LLVMBuildICmp, LLVMBuilderRef, LLVMIntPredicate, LLVMValueRef, LLVMValueRef, LLVMValueRef)
|
||||
_wrap_objenumobjobjstr2obj(LLVMBuildFCmp, LLVMBuilderRef, LLVMRealPredicate, LLVMValueRef, LLVMValueRef, LLVMValueRef)
|
||||
|
||||
|
||||
/* Atomics */
|
||||
_wrap_objobjobjobjstrint2obj(LLVMBuildAtomicCmpXchg, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef, LLVMValueRef)
|
||||
|
||||
/* Miscellaneous instructions */
|
||||
|
||||
_wrap_objobjintstr2obj(LLVMBuildGetResult, LLVMBuilderRef, LLVMValueRef, LLVMValueRef)
|
||||
|
|
@ -1647,6 +1651,9 @@ static PyMethodDef core_methods[] = {
|
|||
_method( LLVMBuildICmp )
|
||||
_method( LLVMBuildFCmp )
|
||||
|
||||
/* Atomics */
|
||||
_method( LLVMBuildAtomicCmpXchg )
|
||||
|
||||
/* Miscellaneous instructions */
|
||||
_method( LLVMBuildGetResult )
|
||||
_method( LLVMBuildPhi )
|
||||
|
|
|
|||
|
|
@ -1996,6 +1996,15 @@ class Builder(object):
|
|||
_core.LLVMBuildShuffleVector(self.ptr,
|
||||
vecA.ptr, vecB.ptr, mask.ptr, name))
|
||||
|
||||
# atomics
|
||||
|
||||
def atomic_cmpxchg(self, ptr, old, new, ordering, crossthread=True):
|
||||
check_is_value(ptr)
|
||||
check_is_value(old)
|
||||
check_is_value(new)
|
||||
inst = _core.LLVMBuildAtomicCmpXchg(self.ptr, ptr.ptr, old.ptr, new.ptr,
|
||||
ordering.lower(), int(bool(crossthread)))
|
||||
return _make_value(inst)
|
||||
|
||||
#===----------------------------------------------------------------------===
|
||||
# Memory buffer
|
||||
|
|
|
|||
|
|
@ -111,6 +111,45 @@ char *do_print(W obj)
|
|||
return strdup(buf.str().c_str());
|
||||
}
|
||||
|
||||
LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef builder, LLVMValueRef ptr,
|
||||
LLVMValueRef cmp, LLVMValueRef val,
|
||||
const char* ordering, int crossthread)
|
||||
{
|
||||
using namespace llvm;
|
||||
|
||||
AtomicOrdering ordering_enum;
|
||||
|
||||
if ( strcmp(ordering, "unordered") == 0 )
|
||||
ordering_enum = Unordered;
|
||||
else if ( strcmp(ordering, "monotonic") == 0 )
|
||||
ordering_enum = Monotonic;
|
||||
else if ( strcmp(ordering, "acquire") == 0 )
|
||||
ordering_enum = Acquire;
|
||||
else if ( strcmp(ordering, "release") == 0 )
|
||||
ordering_enum = Release;
|
||||
else if ( strcmp(ordering, "acq_rel") == 0 )
|
||||
ordering_enum = AcquireRelease;
|
||||
else if ( strcmp(ordering, "seq_cst") == 0 )
|
||||
ordering_enum = SequentiallyConsistent;
|
||||
else
|
||||
ordering_enum = NotAtomic;
|
||||
|
||||
SynchronizationScope crossthread_enum;
|
||||
switch( crossthread ){
|
||||
case 0:
|
||||
crossthread_enum = SingleThread;
|
||||
break;
|
||||
default:
|
||||
crossthread_enum = CrossThread;
|
||||
}
|
||||
|
||||
|
||||
Value * inst = unwrap(builder)->CreateAtomicCmpXchg(
|
||||
unwrap(ptr), unwrap(cmp), unwrap(val),
|
||||
ordering_enum, crossthread_enum);
|
||||
return wrap(inst);
|
||||
}
|
||||
|
||||
LLVMEngineBuilderRef LLVMCreateEngineBuilder(LLVMModuleRef mod)
|
||||
{
|
||||
using namespace llvm;
|
||||
|
|
|
|||
|
|
@ -45,6 +45,14 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Wraps IRBuilder::CreateAtomicCmpXchg
|
||||
*/
|
||||
LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef builder, LLVMValueRef ptr,
|
||||
LLVMValueRef cmp, LLVMValueRef val,
|
||||
const char* ordering, int crossthread);
|
||||
|
||||
/*
|
||||
* Wraps new EngineBuilder
|
||||
*/
|
||||
|
|
|
|||
28
llvm/wrap.h
28
llvm/wrap.h
|
|
@ -671,6 +671,34 @@ _w ## func (PyObject *self, PyObject *args) \
|
|||
return ctor_ ## outtype ( func (arg1, arg2, arg3, arg4)); \
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Wrap LLVM functions of the type
|
||||
* outtype func(intype1 arg1, intype2 arg2, intype3 arg3, intype4, const char *arg5, <unsigned/signed int> arg6)
|
||||
*/
|
||||
#define _wrap_objobjobjobjstrint2obj(func, intype1, intype2, intype3, intype4, outtype)\
|
||||
static PyObject * \
|
||||
_w ## func (PyObject *self, PyObject *args) \
|
||||
{ \
|
||||
PyObject *obj1, *obj2, *obj3, *obj4; \
|
||||
intype1 arg1; \
|
||||
intype2 arg2; \
|
||||
intype3 arg3; \
|
||||
intype4 arg4; \
|
||||
const char *arg5; \
|
||||
int arg6; \
|
||||
\
|
||||
if (!PyArg_ParseTuple(args, "OOOOsi", &obj1, &obj2, &obj3, &obj4, &arg5, &arg6)) \
|
||||
return NULL; \
|
||||
\
|
||||
arg1 = ( intype1 ) PyCapsule_GetPointer(obj1, NULL); \
|
||||
arg2 = ( intype2 ) PyCapsule_GetPointer(obj2, NULL); \
|
||||
arg3 = ( intype3 ) PyCapsule_GetPointer(obj3, NULL); \
|
||||
arg4 = ( intype4 ) PyCapsule_GetPointer(obj4, 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, <unsigned/signed int> arg4)
|
||||
|
|
|
|||
36
test/atomic.py
Normal file
36
test/atomic.py
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
from llvm.core import *
|
||||
import unittest
|
||||
|
||||
test_these_orderings = filter(bool, map(lambda s:s.strip(),
|
||||
'''
|
||||
unordered
|
||||
monotonic
|
||||
acquire
|
||||
release
|
||||
acq_rel
|
||||
seq_cst
|
||||
'''.splitlines()))
|
||||
|
||||
class TestAtomic(unittest.TestCase):
|
||||
def test_atomic(self):
|
||||
mod = Module.new('mod')
|
||||
functype = Type.function(Type.void(), [])
|
||||
func = mod.add_function(functype, name='foo')
|
||||
bb = func.append_basic_block('entry')
|
||||
bldr = Builder.new(bb)
|
||||
ptr = bldr.alloca(Type.int())
|
||||
|
||||
old = bldr.load(ptr)
|
||||
new = Constant.int(Type.int(), 1234)
|
||||
|
||||
|
||||
for ordering in test_these_orderings:
|
||||
inst = bldr.atomic_cmpxchg(ptr, old, new, ordering)
|
||||
self.assertEqual(ordering, str(inst).split(' ')[-1])
|
||||
|
||||
|
||||
inst = bldr.atomic_cmpxchg(ptr, old, new, ordering, crossthread=False)
|
||||
self.assertEqual('singlethread', str(inst).split(' ')[-2])
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue