Author: Richard Plangger <r...@pasra.at> Branch: vecopt2 Changeset: r77073:1047edfb7de1 Date: 2015-03-12 10:19 +0100 http://bitbucket.org/pypy/pypy/changeset/1047edfb7de1/
Log: working on packing instructions 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 @@ -42,15 +42,23 @@ self._do_optimize_loop(loop, call_pure_results, export_state=True) self.assert_equal(loop, expected_loop) - def assert_unroll_loop_equals(self, loop, expected_loop, \ - unroll_factor = -1, call_pure_results=None): + def vec_optimizer(self, loop): metainterp_sd = FakeMetaInterpStaticData(self.cpu) jitdriver_sd = FakeJitDriverStaticData() opt = OptVectorize(metainterp_sd, jitdriver_sd, loop, []) + return opt + + def vec_optimizer_unrolled(self, loop, unroll_factor = -1): + opt = self.vec_optimizer(loop) + opt._gather_trace_information(loop) if unroll_factor == -1: - opt._gather_trace_information(loop) unroll_factor = opt.get_estimated_unroll_factor() opt.unroll_loop_iterations(loop, unroll_factor) + return opt + + def assert_unroll_loop_equals(self, loop, expected_loop, \ + unroll_factor = -1): + vec_optimizer = self.vec_optimizer(loop, unroll_factor) self.assert_equal(loop, expected_loop) def assert_def_use(self, graph, from_instr_index, to_instr_index): @@ -171,49 +179,36 @@ """ self.assert_unroll_loop_equals(self.parse_loop(ops), self.parse_loop(opt_ops), 2) + def test_estimate_unroll_factor_smallest_byte_zero(self): + ops = """ + [p0,i0] + raw_load(p0,i0,descr=arraydescr2) + jump(p0,i0) + """ + vopt = self.vec_optimizer(self.parse_loop(ops)) + assert 0 == vopt.vec_info.smallest_type_bytes + assert 0 == vopt.get_estimated_unroll_factor() + + def test_array_operation_indices_not_unrolled(self): + ops = """ + [p0,i0] + raw_load(p0,i0,descr=arraydescr2) + jump(p0,i0) + """ + vopt = self.vec_optimizer_unrolled(self.parse_loop(ops)) + assert 1 in vopt.vec_info.array_ops + assert len(vopt.vec_info.array_ops) == 1 + + def test_array_operation_indices_unrolled_1(self): + ops = """ + [p0,i0] + raw_load(p0,i0,descr=chararraydescr) + jump(p0,i0) + """ + vopt = self.vec_optimizer_unrolled(self.parse_loop(ops),2) + assert 1 in vopt.vec_info.array_ops + assert 2 in vopt.vec_info.array_ops + assert len(vopt.vec_info.array_ops) == 2 + class TestLLtype(BaseTestDependencyGraph, LLtypeMixin): pass - -#class BaseTestVectorize(BaseTest): -# -# # vector instructions are not produced by the interpreter -# # the optimization vectorize produces them -# # load from from aligned memory example: -# # vec = vec_aligned_raw_load(dst, index, sizeinbytes, descr) -# # 'VEC_ALIGNED_RAW_LOAD/3d', -# # store to aligned memory. example: -# # vec_aligned_raw_store(dst, index, vector, sizeinbytes, descr) -# # 'VEC_ALIGNED_RAW_STORE/4d', -# # a list of operations on vectors -# # add a vector: vec_int_add(v1, v2, 16) -# # 'VEC_INT_ADD/3', -# -#class TestVectorize(BaseTestVectorize): -# -# def test_simple(self): -# ops = """ -# [ia,ib,ic,i0] -# ibi = raw_load(ib, i0, descr=arraydescr) -# ici = raw_load(ic, i0, descr=arraydescr) -# iai = int_add(ibi, ici) -# raw_store(ia, i0, iai, descr=arraydescr) -# i1 = int_add(i0,1) -# ie = int_ge(i1,8) -# guard_false(ie) [ia,ib,ic,i1] -# jump(ia,ib,ic,i1) -# """ -# expected = """ -# [ia,ib,ic,i0] -# ibv = vec_raw_load(ib, i0, 16, descr=arraydescr) -# icv = vec_raw_load(ic, i0, 16, descr=arraydescr) -# iav = vec_int_add(ibi, ici, 16) -# vec_raw_store(ia, i0, iai, 16, descr=arraydescr) -# i1 = int_add(i0,4) -# ie = int_ge(i1,8) -# guard_false(ie) [ia,ib,ic,i1] -# jump(ia,ib,ic,i1) -# """ -# self.optimize_loop(ops, expected) -# -#class TestLLtype(TestVectorize, LLtypeMixin): -# pass 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 @@ -25,7 +25,8 @@ def __init__(self, metainterp_sd, jitdriver_sd, loop, optimizations): self.optimizer = VectorizeOptimizer(metainterp_sd, jitdriver_sd, loop, optimizations) - self.loop_vectorizer_checker = LoopVectorizeChecker() + self.vec_info = LoopVectorizeInfo() + self.memory_refs = [] self.vectorized = False def _rename_arguments_ssa(self, rename_map, label_args, jump_args): @@ -42,10 +43,12 @@ def unroll_loop_iterations(self, loop, unroll_factor): label_op = loop.operations[0] jump_op = loop.operations[-1] - operations = [loop.operations[i] for i in range(1,len(loop.operations)-1)] + operations = [loop.operations[i].clone() for i in range(1,len(loop.operations)-1)] loop.operations = [] - iterations = [[op.clone() for op in operations]] + op_index = len(operations) + 1 + + iterations = [operations] label_op_args = [self.getvalue(box).get_key_box() for box in label_op.getarglist()] values = [self.getvalue(box) for box in label_op.getarglist()] #values[0].make_nonnull(self.optimizer) @@ -75,7 +78,10 @@ except KeyError: pass + self._op_index = op_index iteration_ops.append(copied_op) + self.vec_info.inspect_operation(copied_op) + op_index += 1 # the jump arguments have been changed # if label(iX) ... jump(i(X+1)) is called, at the next unrolled loop @@ -102,13 +108,15 @@ def _gather_trace_information(self, loop): for i,op in enumerate(loop.operations): - self.loop_vectorizer_checker._op_index = i - self.loop_vectorizer_checker.inspect_operation(op) + self.vec_info._op_index = i + self.vec_info.inspect_operation(op) def get_estimated_unroll_factor(self, force_reg_bytes = -1): """ force_reg_bytes used for testing """ # this optimization is not opaque, and needs info about the CPU - byte_count = self.loop_vectorizer_checker.smallest_type_bytes + byte_count = self.vec_info.smallest_type_bytes + if byte_count == 0: + return 0 simd_vec_reg_bytes = 16 # TODO get from cpu if force_reg_bytes > 0: simd_vec_reg_bytes = force_reg_bytes @@ -122,10 +130,7 @@ self._gather_trace_information(loop) - for op in loop.operations: - self.loop_vectorizer_checker.inspect_operation(op) - - byte_count = self.loop_vectorizer_checker.smallest_type_bytes + byte_count = self.vec_info.smallest_type_bytes if byte_count == 0: # stop, there is no chance to vectorize this trace return loop @@ -143,37 +148,37 @@ for more details. """ + for i,operation in enumerate(loop.operations): + + if operation.getopnum() == rop.RAW_LOAD: + # TODO while the loop is unrolled, build memory accesses + pass + # was not able to vectorize return False - - -class LoopVectorizeChecker(object): +class LoopVectorizeInfo(object): def __init__(self): self.smallest_type_bytes = 0 self._op_index = 0 - self.mem_ref_indices = [] + self.array_ops = [] - def add_memory_ref(self, i): - self.mem_ref_indices.append(i) - - def count_RAW_LOAD(self, op): - self.add_memory_ref(self._op_index) + def operation_RAW_LOAD(self, op): descr = op.getdescr() + self.array_ops.append(self._op_index) 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 - def default_count(self, operation): + def default_operation(self, operation): pass -dispatch_opt = make_dispatcher_method(LoopVectorizeChecker, 'count_', - default=LoopVectorizeChecker.default_count) -LoopVectorizeChecker.inspect_operation = dispatch_opt - +dispatch_opt = make_dispatcher_method(LoopVectorizeInfo, 'operation_', + default=LoopVectorizeInfo.default_operation) +LoopVectorizeInfo.inspect_operation = dispatch_opt class Pack(object): """ A pack is a set of n statements that are: @@ -194,11 +199,11 @@ Pack.__init__(self, [left_op, right_op]) -class MemoryAccess(object): - def __init__(self, array, origin, offset): +class MemoryRef(object): + def __init__(self, array, origin): self.array = array self.origin = origin - self.offset = offset + self.offset = None def is_adjacent_to(self, mem_acc): if self.array == mem_acc.array: _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit