[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