Author: Richard Plangger <r...@pasra.at> 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 pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit