[pypy-commit] pypy vecopt2: working on packing instructions

plan_rich noreply at buildbot.pypy.org
Tue May 5 09:45:20 CEST 2015


Author: Richard Plangger <rich at 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:


More information about the pypy-commit mailing list