[pypy-commit] pypy backend-vector-ops: enough to run vector ops on the simplest thing in numpy

fijal noreply at buildbot.pypy.org
Thu Feb 9 16:47:44 CET 2012


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: backend-vector-ops
Changeset: r52307:922b890924eb
Date: 2012-02-09 17:47 +0200
http://bitbucket.org/pypy/pypy/changeset/922b890924eb/

Log:	enough to run vector ops on the simplest thing in numpy

diff --git a/pypy/jit/codewriter/test/test_jtransform.py b/pypy/jit/codewriter/test/test_jtransform.py
--- a/pypy/jit/codewriter/test/test_jtransform.py
+++ b/pypy/jit/codewriter/test/test_jtransform.py
@@ -139,12 +139,15 @@
              EI.OS_UNIEQ_NONNULL_CHAR:   ([PUNICODE, UNICHAR], INT),
              EI.OS_UNIEQ_CHECKNULL_CHAR: ([PUNICODE, UNICHAR], INT),
              EI.OS_UNIEQ_LENGTHOK:       ([PUNICODE, PUNICODE], INT),
+             EI.OS_ASSERT_ALIGNED:       ([INT], lltype.Void),
             }
             argtypes = argtypes[oopspecindex]
             assert argtypes[0] == [v.concretetype for v in op.args[1:]]
             assert argtypes[1] == op.result.concretetype
             if oopspecindex == EI.OS_STR2UNICODE:
                 assert extraeffect == EI.EF_ELIDABLE_CAN_RAISE
+            elif oopspecindex == EI.OS_ASSERT_ALIGNED:
+                assert extraeffect == EI.EF_CANNOT_RAISE
             else:
                 assert extraeffect == EI.EF_ELIDABLE_CANNOT_RAISE
         return 'calldescr-%d' % oopspecindex
@@ -1079,6 +1082,18 @@
     assert op1.args[2] == ListOfKind('ref', [v1])
     assert op1.result == v2
 
+def test_assert_aligned():
+    from pypy.rlib import jit
+    
+    v = varoftype(lltype.Signed) # does not matter
+    FUNC = lltype.FuncType([lltype.Signed], lltype.Void)
+    func = lltype.functionptr(FUNC, 'assert_aligned',
+                              _callable=jit.assert_aligned)
+    op = SpaceOperation('direct_call', [const(func), v], varoftype(lltype.Void))
+    tr = Transformer(FakeCPU(), FakeBuiltinCallControl())
+    op1 = tr.rewrite_operation(op)
+    assert op1.args[1] == 'calldescr-%d' % effectinfo.EffectInfo.OS_ASSERT_ALIGNED
+
 def test_unicode_eq_checknull_char():
     # test that the oopspec is present and correctly transformed
     PUNICODE = lltype.Ptr(rstr.UNICODE)
diff --git a/pypy/jit/metainterp/optimizeopt/__init__.py b/pypy/jit/metainterp/optimizeopt/__init__.py
--- a/pypy/jit/metainterp/optimizeopt/__init__.py
+++ b/pypy/jit/metainterp/optimizeopt/__init__.py
@@ -22,9 +22,10 @@
             ('earlyforce', OptEarlyForce),
             ('pure', OptPure),
             ('heap', OptHeap),
+            ('ffi', None),
             ('vectorize', OptVectorize), # XXX check if CPU supports that maybe
-            ('ffi', None),
-            ('unroll', None)]
+            ('unroll', None),
+            ]
 # no direct instantiation of unroll
 unroll_all_opts = unrolling_iterable(ALL_OPTS)
 
diff --git a/pypy/jit/metainterp/optimizeopt/vectorize.py b/pypy/jit/metainterp/optimizeopt/vectorize.py
--- a/pypy/jit/metainterp/optimizeopt/vectorize.py
+++ b/pypy/jit/metainterp/optimizeopt/vectorize.py
@@ -116,6 +116,8 @@
             self.ops_so_far.append(op)
             self.track[self.getvalue(op.result)] = Read(arr, track, op)
 
+    optimize_GETINTERIORFIELD_RAW = optimize_GETARRAYITEM_RAW
+
     def optimize_INT_ADD(self, op):
         # only for += 1
         one = self.getvalue(op.getarg(0))
@@ -159,6 +161,8 @@
             self.full[arr] = [None] * VECTOR_SIZE
         self.full[arr][ti.index] = Write(arr, index, v, op)
 
+    optimize_SETINTERIORFIELD_RAW = optimize_SETARRAYITEM_RAW
+
     def emit_vector_ops(self, forbidden_boxes):
         for arg in forbidden_boxes:
             if arg in self.track:
@@ -184,7 +188,10 @@
         if op.opnum in [rop.JUMP, rop.FINISH, rop.LABEL]:
             self.emit_vector_ops(op.getarglist())
         elif op.is_guard():
-            self.emit_vector_ops(op.getarglist() + op.getfailargs())
+            lst = op.getarglist()
+            if op.getfailargs() is not None:
+                lst = lst + op.getfailargs()
+            self.emit_vector_ops(lst)
         elif op.is_always_pure():
             # in theory no side effect ops, but stuff like malloc
             # can go in the way
diff --git a/pypy/module/micronumpy/loop.py b/pypy/module/micronumpy/loop.py
--- a/pypy/module/micronumpy/loop.py
+++ b/pypy/module/micronumpy/loop.py
@@ -8,7 +8,7 @@
 
 class NumpyEvalFrame(object):
     _virtualizable2_ = ['iterators[*]', 'final_iter', 'arraylist[*]',
-                        'value', 'identity', 'cur_value']
+                        'value', 'identity', 'cur_value', 'first_iteration']
 
     @unroll_safe
     def __init__(self, iterators, arrays):
@@ -24,6 +24,7 @@
             self.final_iter = -1
         self.cur_value = None
         self.identity = None
+        self.first_iteration = False
 
     def done(self):
         final_iter = promote(self.final_iter)
@@ -76,6 +77,10 @@
             numpy_driver.jit_merge_point(sig=sig,
                                          shapelen=shapelen,
                                          frame=frame, arr=arr)
+            frame.first_iteration = True # vectorization hint
+            sig.eval(frame, arr)
+            frame.first_iteration = False
+            frame.next(shapelen)
             sig.eval(frame, arr)
             frame.next(shapelen)
         return frame.cur_value
diff --git a/pypy/module/micronumpy/signature.py b/pypy/module/micronumpy/signature.py
--- a/pypy/module/micronumpy/signature.py
+++ b/pypy/module/micronumpy/signature.py
@@ -4,6 +4,7 @@
      ViewTransform, BroadcastTransform
 from pypy.tool.pairtype import extendabletype
 from pypy.module.micronumpy.loop import ComputationDone
+from pypy.rlib import jit
 
 """ Signature specifies both the numpy expression that has been constructed
 and the assembler to be compiled. This is a very important observation -
@@ -150,7 +151,10 @@
 
     def eval(self, frame, arr):
         iter = frame.iterators[self.iter_no]
-        return self.dtype.getitem(frame.arrays[self.array_no], iter.offset)
+        offset = iter.offset
+        if frame.first_iteration:
+            jit.assert_aligned(offset)
+        return self.dtype.getitem(frame.arrays[self.array_no], offset)
 
 class ScalarSignature(ConcreteSignature):
     def debug_repr(self):
diff --git a/pypy/rlib/jit.py b/pypy/rlib/jit.py
--- a/pypy/rlib/jit.py
+++ b/pypy/rlib/jit.py
@@ -874,4 +874,4 @@
 
 @oopspec('assert_aligned(arg)')
 def assert_aligned(arg):
-    pass
+    keepalive_until_here(arg)


More information about the pypy-commit mailing list