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

Reply via email to