Author: Armin Rigo <[email protected]>
Branch: stm
Changeset: r48551:3a174d94e902
Date: 2011-10-27 22:36 +0200
http://bitbucket.org/pypy/pypy/changeset/3a174d94e902/
Log: Transform and compile to C code: first early version.
diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py
--- a/pypy/config/translationoption.py
+++ b/pypy/config/translationoption.py
@@ -102,6 +102,8 @@
# other noticeable options
BoolOption("thread", "enable use of threading primitives",
default=False, cmdline="--thread"),
+ BoolOption("stm", "enable use of Software Transactional Memory",
+ default=False, cmdline="--stm"),
BoolOption("sandbox", "Produce a fully-sandboxed executable",
default=False, cmdline="--sandbox",
requires=[("translation.thread", False)],
diff --git a/pypy/translator/c/funcgen.py b/pypy/translator/c/funcgen.py
--- a/pypy/translator/c/funcgen.py
+++ b/pypy/translator/c/funcgen.py
@@ -596,6 +596,8 @@
return self.op_stm(op)
OP_STM_GETFIELD = _OP_STM
OP_STM_SETFIELD = _OP_STM
+ OP_STM_BEGIN_TRANSACTION = _OP_STM
+ OP_STM_COMMIT_TRANSACTION = _OP_STM
def OP_PTR_NONZERO(self, op):
diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py
--- a/pypy/translator/c/genc.py
+++ b/pypy/translator/c/genc.py
@@ -131,6 +131,12 @@
def build_database(self):
translator = self.translator
+ if self.config.translation.stm:
+ from pypy.translator.stm import transform
+ transformer = transform.STMTransformer(self.translator)
+ transformer.transform()
+ log.info("Software Transactional Memory transformation applied")
+
gcpolicyclass = self.get_gcpolicyclass()
if self.config.translation.gcrootfinder == "asmgcc":
@@ -179,6 +185,10 @@
# we need a concrete gcpolicy to do this
self.merge_eci(db.gcpolicy.compilation_info())
+ if self.config.translation.stm:
+ from pypy.translator.stm._rffi_stm import eci
+ self.merge_eci(eci)
+
all = []
for node in self.db.globalcontainers():
eci = node.compilation_info()
diff --git a/pypy/translator/stm/_rffi_stm.py b/pypy/translator/stm/_rffi_stm.py
--- a/pypy/translator/stm/_rffi_stm.py
+++ b/pypy/translator/stm/_rffi_stm.py
@@ -3,14 +3,15 @@
from pypy.tool.autopath import pypydir
from pypy.rpython.lltypesystem import lltype, rffi
from pypy.translator.tool.cbuild import ExternalCompilationInfo
+from pypy.rlib.rarithmetic import LONG_BIT
cdir = py.path.local(pypydir) / 'translator' / 'stm'
-
eci = ExternalCompilationInfo(
include_dirs = [cdir],
includes = ['src_stm/et.h'],
+ pre_include_bits = ['#define PYPY_LONG_BIT %d' % LONG_BIT],
separate_module_sources = ['#include "src_stm/et.c"\n'],
)
@@ -24,8 +25,8 @@
descriptor_init = llexternal('stm_descriptor_init', [], lltype.Void)
descriptor_done = llexternal('stm_descriptor_done', [], lltype.Void)
-begin_transaction = llexternal('STM_begin_transaction', [], lltype.Void)
-commit_transaction = llexternal('stm_commit_transaction', [], lltype.Signed)
+#begin_transaction = llexternal('STM_begin_transaction', [], lltype.Void)
+#commit_transaction = llexternal('stm_commit_transaction', [], lltype.Signed)
stm_read_word = llexternal('stm_read_word', [SignedP], lltype.Signed)
stm_write_word = llexternal('stm_write_word', [SignedP, lltype.Signed],
diff --git a/pypy/translator/stm/funcgen.py b/pypy/translator/stm/funcgen.py
--- a/pypy/translator/stm/funcgen.py
+++ b/pypy/translator/stm/funcgen.py
@@ -84,7 +84,14 @@
cdecl(funcgen.db.gettype(STRUCT), ''),
structdef.c_struct_field_name(fieldname), newvalue))
+def stm_begin_transaction(funcgen, op):
+ return 'STM_begin_transaction();'
+
+def stm_commit_transaction(funcgen, op):
+ return 'stm_commit_transaction();'
+
def op_stm(funcgen, op):
+ assert funcgen.db.translator.stm_transformation_applied
func = globals()[op.opname]
return func(funcgen, op)
diff --git a/pypy/translator/stm/src_stm/et.c b/pypy/translator/stm/src_stm/et.c
--- a/pypy/translator/stm/src_stm/et.c
+++ b/pypy/translator/stm/src_stm/et.c
@@ -775,6 +775,7 @@
stm_write_word(p, val);
}
+#if PYPY_LONG_BIT == 32
long long stm_read_doubleword(long *addr)
{
/* 32-bit only */
@@ -789,15 +790,17 @@
stm_write_word(addr, (long)val);
stm_write_word(addr + 1, (long)(val >> 32));
}
+#endif
double stm_read_double(long *addr)
{
long long x;
double dd;
- if (sizeof(double) > sizeof(long))
- x = stm_read_doubleword(addr); /* 32 bits */
- else
- x = stm_read_word(addr); /* 64 bits */
+#if PYPY_LONG_BIT == 32
+ x = stm_read_doubleword(addr); /* 32 bits */
+#else
+ x = stm_read_word(addr); /* 64 bits */
+#endif
assert(sizeof(double) == 8 && sizeof(long long) == 8);
memcpy(&dd, &x, 8);
return dd;
@@ -808,24 +811,27 @@
long long ll;
assert(sizeof(double) == 8 && sizeof(long long) == 8);
memcpy(&ll, &val, 8);
- if (sizeof(double) > sizeof(long))
- stm_write_doubleword(addr, ll); /* 32 bits */
- else
- stm_write_word(addr, ll); /* 64 bits */
+#if PYPY_LONG_BIT == 32
+ stm_write_doubleword(addr, ll); /* 32 bits */
+#else
+ stm_write_word(addr, ll); /* 64 bits */
+#endif
}
float stm_read_float(long *addr)
{
unsigned int x;
float ff;
- if (sizeof(float) == sizeof(long))
- x = stm_read_word(addr); /* 32 bits */
- else if (((long)(char*)addr) & 7) {
+#if PYPY_LONG_BIT == 32
+ x = stm_read_word(addr); /* 32 bits */
+#else
+ if (((long)(char*)addr) & 7) {
addr = (long *)(((char *)addr) - 4);
x = (unsigned int)(stm_read_word(addr) >> 32); /* 64 bits, unaligned */
}
else
x = (unsigned int)stm_read_word(addr); /* 64 bits, aligned */
+#endif
assert(sizeof(float) == 4 && sizeof(unsigned int) == 4);
memcpy(&ff, &x, 4);
return ff;
@@ -836,11 +842,13 @@
unsigned int ii;
assert(sizeof(float) == 4 && sizeof(unsigned int) == 4);
memcpy(&ii, &val, 4);
- if (sizeof(float) == sizeof(long))
- stm_write_word(addr, ii); /* 32 bits */
- else if (((long)(char*)addr) & 7)
+#if PYPY_LONG_BIT == 32
+ stm_write_word(addr, ii); /* 32 bits */
+#else
+ if (((long)(char*)addr) & 7)
stm_write_partial_word(4, (((char *)addr) - 4),
4, ii); /* 64 bits, unaligned */
else
stm_write_partial_word(4, (char *)addr, 0, ii); /* 64 bits, aligned */
+#endif
}
diff --git a/pypy/translator/stm/src_stm/et.h b/pypy/translator/stm/src_stm/et.h
--- a/pypy/translator/stm/src_stm/et.h
+++ b/pypy/translator/stm/src_stm/et.h
@@ -9,6 +9,7 @@
#define _ET_H
#include <setjmp.h>
+#include "src/commondefs.h"
void stm_descriptor_init(void);
@@ -40,8 +41,10 @@
void stm_write_double(long *addr, double val);
float stm_read_float(long *addr);
void stm_write_float(long *addr, float val);
+#if PYPY_LONG_BIT == 32
long long stm_read_doubleword(long *addr);
void stm_write_doubleword(long *addr, long long val);
+#endif
#endif /* _ET_H */
diff --git a/pypy/translator/stm/test/test_rstm.py
b/pypy/translator/stm/test/test_rstm.py
--- a/pypy/translator/stm/test/test_rstm.py
+++ b/pypy/translator/stm/test/test_rstm.py
@@ -161,6 +161,7 @@
t.config.translation.gc = 'boehm'
t.buildannotator().build_types(entry_point, [s_list_of_strings])
t.buildrtyper().specialize()
+ t.stm_transformation_applied = True # not really, but for these tests
cbuilder = CStandaloneBuilder(t, entry_point, t.config)
force_debug = ExternalCompilationInfo(pre_include_bits=[
"#define RPY_ASSERT 1\n"
diff --git a/pypy/translator/stm/test/test_transform.py
b/pypy/translator/stm/test/test_transform.py
--- a/pypy/translator/stm/test/test_transform.py
+++ b/pypy/translator/stm/test/test_transform.py
@@ -3,6 +3,9 @@
from pypy.objspace.flow.model import summary
from pypy.translator.stm.llstminterp import eval_stm_graph
from pypy.translator.stm.transform import transform_graph
+from pypy.translator.stm import rstm
+from pypy.translator.c.test.test_standalone import StandaloneTests
+from pypy.rlib.debug import debug_print
def test_simple():
@@ -28,3 +31,26 @@
assert summary(graph) == {'getfield': 1}
res = eval_stm_graph(interp, graph, [p], stm_mode="regular_transaction")
assert res == 42
+
+
+class TestTransformSingleThread(StandaloneTests):
+
+ def compile(self, entry_point):
+ from pypy.config.pypyoption import get_pypy_config
+ self.config = get_pypy_config(translating=True)
+ self.config.translation.stm = True
+ return StandaloneTests.compile(self, entry_point)
+
+ def test_no_pointer_operations(self):
+ def simplefunc(argv):
+ rstm.begin_transaction()
+ i = 0
+ while i < 100:
+ i += 3
+ rstm.commit_transaction()
+ debug_print(i)
+ return 0
+ t, cbuilder = self.compile(simplefunc)
+ dataout, dataerr = cbuilder.cmdexec('', err=True)
+ assert dataout == ''
+ assert '102' in dataerr.splitlines()
diff --git a/pypy/translator/stm/transform.py b/pypy/translator/stm/transform.py
--- a/pypy/translator/stm/transform.py
+++ b/pypy/translator/stm/transform.py
@@ -1,8 +1,18 @@
from pypy.objspace.flow.model import SpaceOperation
+from pypy.translator.stm import _rffi_stm
class STMTransformer(object):
+ def __init__(self, translator=None):
+ self.translator = translator
+
+ def transform(self):
+ self.add_descriptor_init_stuff()
+ for graph in self.translator.graphs:
+ self.transform_graph(graph)
+ self.translator.stm_transformation_applied = True
+
def transform_block(self, block):
if block.operations == ():
return
@@ -16,6 +26,18 @@
for block in graph.iterblocks():
self.transform_block(block)
+ def add_descriptor_init_stuff(self):
+ from pypy.translator.unsimplify import call_initial_function
+ from pypy.translator.unsimplify import call_final_function
+ def descriptor_init():
+ _rffi_stm.descriptor_init()
+ def descriptor_done():
+ _rffi_stm.descriptor_done()
+ call_initial_function(self.translator, descriptor_init)
+ call_final_function(self.translator, descriptor_done)
+
+ # ----------
+
def stt_getfield(self, newoperations, op):
STRUCT = op.args[0].concretetype.TO
if STRUCT._immutable_field(op.args[1].value):
@@ -30,4 +52,5 @@
def transform_graph(graph):
+ # for tests: only transforms one graph
STMTransformer().transform_graph(graph)
diff --git a/pypy/translator/unsimplify.py b/pypy/translator/unsimplify.py
--- a/pypy/translator/unsimplify.py
+++ b/pypy/translator/unsimplify.py
@@ -144,7 +144,8 @@
if own_annhelper:
annhelper.finish()
- entry_point = translator.entry_point_graph
+ entry_point = getattr(translator, 'entry_point_graph',
+ translator.graphs[0])
args = [copyvar(translator.annotator, v) for v in entry_point.getargs()]
extrablock = Block(args)
v_none = varoftype(lltype.Void)
@@ -169,7 +170,8 @@
if own_annhelper:
annhelper.finish()
- entry_point = translator.entry_point_graph
+ entry_point = getattr(translator, 'entry_point_graph',
+ translator.graphs[0])
v = copyvar(translator.annotator, entry_point.getreturnvar())
extrablock = Block([v])
v_none = varoftype(lltype.Void)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit