Author: Richard Plangger <[email protected]>
Branch: vecopt-merge-iterator-sharing
Changeset: r79000:40eb3eef0bac
Date: 2015-08-17 09:55 +0200
http://bitbucket.org/pypy/pypy/changeset/40eb3eef0bac/
Log: activated get/setarrayitem_gc if their descriptor uses primitive
data (int/float) added test to ensure this is working properly,
modified some tests that assumed the old behaviour
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
@@ -38,6 +38,10 @@
states = [out_state,left_state,right_state]
left_index = 1
right_index = 2
+ # 1) get rid of scalar cases
+ # 2) switch through cases
+ # 3) you dont need states
+ # 4) no left_right_index
# left == right == out
# left == right
# left == out
diff --git a/rpython/jit/backend/llgraph/runner.py
b/rpython/jit/backend/llgraph/runner.py
--- a/rpython/jit/backend/llgraph/runner.py
+++ b/rpython/jit/backend/llgraph/runner.py
@@ -155,6 +155,13 @@
def __repr__(self):
return 'ArrayDescr(%r)' % (self.OUTERA,)
+ def is_array_of_primitives(self):
+ kind = getkind(self.A.OF)
+ return kind == 'float' or \
+ kind == 'int' or \
+ kind == ''
+
+
def is_array_of_pointers(self):
return getkind(self.A.OF) == 'ref'
diff --git a/rpython/jit/backend/llsupport/descr.py
b/rpython/jit/backend/llsupport/descr.py
--- a/rpython/jit/backend/llsupport/descr.py
+++ b/rpython/jit/backend/llsupport/descr.py
@@ -203,6 +203,11 @@
def getconcrete_type(self):
return self.concrete_type
+ def is_array_of_primitives(self):
+ return self.flag == FLAG_FLOAT or \
+ self.flag == FLAG_SIGNED or \
+ self.flag == FLAG_UNSIGNED
+
def is_array_of_pointers(self):
return self.flag == FLAG_POINTER
diff --git a/rpython/jit/metainterp/executor.py
b/rpython/jit/metainterp/executor.py
--- a/rpython/jit/metainterp/executor.py
+++ b/rpython/jit/metainterp/executor.py
@@ -344,6 +344,8 @@
rop.VEC_RAW_STORE,
rop.VEC_GETARRAYITEM_RAW,
rop.VEC_SETARRAYITEM_RAW,
+ rop.VEC_GETARRAYITEM_GC,
+ rop.VEC_SETARRAYITEM_GC,
): # list of opcodes never executed by pyjitpl
continue
if rop._VEC_PURE_FIRST <= value <= rop._VEC_PURE_LAST:
diff --git a/rpython/jit/metainterp/optimizeopt/dependency.py
b/rpython/jit/metainterp/optimizeopt/dependency.py
--- a/rpython/jit/metainterp/optimizeopt/dependency.py
+++ b/rpython/jit/metainterp/optimizeopt/dependency.py
@@ -805,8 +805,9 @@
def operation_{name}(self, op, node):
descr = op.getdescr()
idx_ref = self.get_or_create(op.getarg(1))
- node.memory_ref = MemoryRef(op, idx_ref, {raw_access})
- self.memory_refs[node] = node.memory_ref
+ if descr.is_array_of_primitives():
+ node.memory_ref = MemoryRef(op, idx_ref, {raw_access})
+ self.memory_refs[node] = node.memory_ref
"""
exec py.code.Source(array_access_source
.format(name='RAW_LOAD',raw_access=True)).compile()
@@ -816,6 +817,10 @@
.format(name='GETARRAYITEM_RAW',raw_access=False)).compile()
exec py.code.Source(array_access_source
.format(name='SETARRAYITEM_RAW',raw_access=False)).compile()
+ exec py.code.Source(array_access_source
+ .format(name='GETARRAYITEM_GC',raw_access=False)).compile()
+ exec py.code.Source(array_access_source
+ .format(name='SETARRAYITEM_GC',raw_access=False)).compile()
del array_access_source
integral_dispatch_opt = make_dispatcher_method(IntegralForwardModification,
'operation_')
IntegralForwardModification.inspect_operation = integral_dispatch_opt
diff --git a/rpython/jit/metainterp/optimizeopt/schedule.py
b/rpython/jit/metainterp/optimizeopt/schedule.py
--- a/rpython/jit/metainterp/optimizeopt/schedule.py
+++ b/rpython/jit/metainterp/optimizeopt/schedule.py
@@ -698,8 +698,10 @@
rop.VEC_RAW_LOAD: LOAD_TRANS,
rop.VEC_GETARRAYITEM_RAW: LOAD_TRANS,
+ rop.VEC_GETARRAYITEM_GC: LOAD_TRANS,
rop.VEC_RAW_STORE: STORE_TRANS,
rop.VEC_SETARRAYITEM_RAW: STORE_TRANS,
+ rop.VEC_SETARRAYITEM_GC: STORE_TRANS,
rop.VEC_CAST_FLOAT_TO_SINGLEFLOAT: OpToVectorOpConv(PT_DOUBLE_2,
PT_FLOAT_2),
rop.VEC_CAST_SINGLEFLOAT_TO_FLOAT: OpToVectorOpConv(PT_FLOAT_2,
PT_DOUBLE_2),
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_vectorize.py
b/rpython/jit/metainterp/optimizeopt/test/test_vectorize.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_vectorize.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_vectorize.py
@@ -212,21 +212,6 @@
"""
self.assert_vectorize(self.parse_loop(ops), self.parse_loop(ops))
- def test_vectorize_skip_impossible_2(self):
- ops = """
- [p0,i0]
- i1 = int_add(i0,1)
- i2 = int_le(i1, 10)
- guard_true(i2) []
- i3 = getarrayitem_gc(p0,i0,descr=intarraydescr)
- jump(p0,i1)
- """
- try:
- self.vectorize(self.parse_loop(ops))
- py.test.fail("should not happend")
- except NotAVectorizeableLoop:
- pass
-
def test_unroll_empty_stays_empty(self):
""" has no operations in this trace, thus it stays empty
after unrolling it 2 times """
@@ -264,6 +249,26 @@
"""
self.assert_vectorize(self.parse_loop(ops), self.parse_loop(ops))
+ def test_load_primitive_python_list(self):
+ """ it currently rejects pointer arrays """
+ ops = """
+ [p0,i0]
+ i2 = getarrayitem_gc(p0,i0,descr=floatarraydescr)
+ i1 = int_add(i0,1)
+ i3 = getarrayitem_gc(p0,i1,descr=floatarraydescr)
+ i4 = int_add(i1,1)
+ jump(p0,i4)
+ """
+ opt = """
+ [p0,i0]
+ i1 = int_add(i0,1)
+ i2 = int_add(i0,2)
+ i3 = vec_getarrayitem_gc(p0,i0,2,descr=floatarraydescr)
+ jump(p0,i2)
+ """
+ vopt = self.vectorize(self.parse_loop(ops),0)
+ self.assert_equal(vopt.loop, self.parse_loop(opt))
+
def test_vect_unroll_char(self):
""" a 16 byte vector register can hold 16 bytes thus
it is unrolled 16 times. (it is the smallest type in the trace) """
@@ -316,7 +321,7 @@
def test_estimate_unroll_factor_smallest_byte_zero(self):
ops = """
[p0,i0]
- raw_load(p0,i0,descr=arraydescr2)
+ raw_load(p0,i0,descr=arraydescr)
jump(p0,i0)
"""
vopt = self.vectoroptimizer(self.parse_loop(ops))
@@ -326,7 +331,7 @@
def test_array_operation_indices_not_unrolled(self):
ops = """
[p0,i0]
- raw_load(p0,i0,descr=arraydescr2)
+ raw_load(p0,i0,descr=arraydescr)
jump(p0,i0)
"""
vopt = self.vectoroptimizer_unrolled(self.parse_loop(ops),0)
diff --git a/rpython/jit/metainterp/optimizeopt/vectorize.py
b/rpython/jit/metainterp/optimizeopt/vectorize.py
--- a/rpython/jit/metainterp/optimizeopt/vectorize.py
+++ b/rpython/jit/metainterp/optimizeopt/vectorize.py
@@ -253,13 +253,12 @@
def linear_find_smallest_type(self, loop):
# O(#operations)
for i,op in enumerate(loop.operations):
- if op.is_raw_array_access():
+ if op.is_primitive_array_access():
descr = op.getdescr()
- if not descr.is_array_of_pointers():
- byte_count = descr.get_item_size_in_bytes()
- if self.smallest_type_bytes == 0 \
- or byte_count < self.smallest_type_bytes:
- self.smallest_type_bytes = byte_count
+ byte_count = descr.get_item_size_in_bytes()
+ if self.smallest_type_bytes == 0 \
+ or byte_count < self.smallest_type_bytes:
+ self.smallest_type_bytes = byte_count
def get_unroll_count(self, simd_vec_reg_bytes):
""" This is an estimated number of further unrolls """
@@ -714,7 +713,7 @@
if origin_pack is None:
descr = lnode.getoperation().getdescr()
ptype = PackType.by_descr(descr, self.vec_reg_size)
- if lnode.getoperation().is_raw_load():
+ if lnode.getoperation().is_primitive_load():
# load outputs value, no input
return Pair(lnode, rnode, None, ptype)
else:
@@ -757,7 +756,7 @@
""" Blocks the packing of some operations """
if inquestion.vector == -1:
return True
- if packed.is_raw_array_access():
+ if packed.is_primitive_array_access():
if packed.getarg(1) == inquestion.result:
return True
if not forward and inquestion.getopnum() == rop.INT_SIGNEXT:
diff --git a/rpython/jit/metainterp/resoperation.py
b/rpython/jit/metainterp/resoperation.py
--- a/rpython/jit/metainterp/resoperation.py
+++ b/rpython/jit/metainterp/resoperation.py
@@ -174,10 +174,19 @@
def is_raw_array_access(self):
return self.is_raw_load() or self.is_raw_store()
- def is_raw_load(self):
+ def is_primitive_array_access(self):
+ """ Indicates that this operations loads/stores a
+ primitive type (int,float) """
+ if self.is_primitive_load() or self.is_primitive_store():
+ descr = self.getdescr()
+ if descr.is_array_of_primitives():
+ return True
+ return False
+
+ def is_primitive_load(self):
return rop._RAW_LOAD_FIRST < self.getopnum() < rop._RAW_LOAD_LAST
- def is_raw_store(self):
+ def is_primitive_store(self):
return rop._RAW_STORE_FIRST < self.getopnum() < rop._RAW_STORE_LAST
def is_comparison(self):
@@ -568,13 +577,13 @@
#
'_ALWAYS_PURE_LAST', # ----- end of always_pure operations -----
+ '_RAW_LOAD_FIRST',
'GETARRAYITEM_GC/2d',
-
- '_RAW_LOAD_FIRST',
'GETARRAYITEM_RAW/2d',
'VEC_GETARRAYITEM_RAW/3d',
'RAW_LOAD/2d',
'VEC_RAW_LOAD/3d',
+ 'VEC_GETARRAYITEM_GC/3d',
'_RAW_LOAD_LAST',
'GETINTERIORFIELD_GC/2d',
@@ -596,13 +605,14 @@
'_NOSIDEEFFECT_LAST', # ----- end of no_side_effect operations -----
'INCREMENT_DEBUG_COUNTER/1',
- 'SETARRAYITEM_GC/3d',
'_RAW_STORE_FIRST',
+ 'SETARRAYITEM_GC/3d',
'SETARRAYITEM_RAW/3d',
'VEC_SETARRAYITEM_RAW/3d',
'RAW_STORE/3d',
'VEC_RAW_STORE/3d',
+ 'VEC_SETARRAYITEM_GC/3d',
'_RAW_STORE_LAST',
'SETINTERIORFIELD_GC/3d',
@@ -796,8 +806,10 @@
_opvector = {
rop.RAW_LOAD: rop.VEC_RAW_LOAD,
rop.GETARRAYITEM_RAW: rop.VEC_GETARRAYITEM_RAW,
+ rop.GETARRAYITEM_GC: rop.VEC_GETARRAYITEM_GC,
rop.RAW_STORE: rop.VEC_RAW_STORE,
rop.SETARRAYITEM_RAW: rop.VEC_SETARRAYITEM_RAW,
+ rop.SETARRAYITEM_GC: rop.VEC_SETARRAYITEM_GC,
rop.INT_ADD: rop.VEC_INT_ADD,
rop.INT_SUB: rop.VEC_INT_SUB,
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit