Author: Richard Plangger <r...@pasra.at>
Branch: vecopt
Changeset: r77956:ac80f41576c2
Date: 2015-06-08 15:03 +0200
http://bitbucket.org/pypy/pypy/changeset/ac80f41576c2/

Log:    finding reduceables works, scheduling needs to be adapted next

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
@@ -1065,6 +1065,8 @@
         jump(p0, i1, v3[f64|2])
         """
         opt = self.vectorize(self.parse_loop(trace))
+        assert len(opt.packset.accum_vars) == 1
+        assert opt.loop.inputargs[2] in opt.packset.accum_vars
         self.debug_print_operations(opt.loop)
 
 
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
@@ -292,7 +292,7 @@
                     if memref_a.is_adjacent_to(memref_b):
                         pair = self.packset.can_be_packed(node_a, node_b, None)
                         if pair:
-                            self.packset.packs.append(pair)
+                            self.packset.add_pack(pair)
 
     def extend_packset(self):
         pack_count = self.packset.pack_count()
@@ -314,7 +314,7 @@
                 if isomorph and lnode.is_before(rnode):
                     pair = self.packset.can_be_packed(lnode, rnode, pack)
                     if pair:
-                        self.packset.packs.append(pair)
+                        self.packset.add_pack(pair)
 
     def follow_def_uses(self, pack):
         assert isinstance(pack, Pair)
@@ -324,8 +324,9 @@
                 rnode = rdep.to
                 isomorph = isomorphic(lnode.getoperation(), 
rnode.getoperation())
                 if isomorph and lnode.is_before(rnode):
-                    if self.packset.can_be_packed(lnode, rnode, pack):
-                        self.packset.add_pair(lnode, rnode)
+                    pair = self.packset.can_be_packed(lnode, rnode, pack)
+                    if pair:
+                        self.packset.add_pack(pair)
 
     def combine_packset(self):
         if len(self.packset.packs) == 0:
@@ -1312,23 +1313,27 @@
         self.operations = operations
         self.unroll_count = unroll_count
         self.smallest_type_bytes = smallest_type_bytes
+        self.accum_vars = {}
 
     def pack_count(self):
         return len(self.packs)
 
-    def add_pair(self, l, r):
-        p = Pair(l,r)
-        self.packs.append(p)
+    def add_pack(self, pack):
+        if pack.is_accumulating():
+            # remember the variable and the position in this map
+            self.accum_vars[pack.accum_variable] = pack.accum_variable
+        self.packs.append(pack)
 
     def accumulates_pair(self, lnode, rnode, origin_pack):
         # lnode and rnode are isomorphic and dependent
+        assert isinstance(origin_pack, Pair)
         lop = lnode.getoperation()
         opnum = lop.getopnum()
-        rop = rnode.getoperation()
 
         if opnum in (rop.FLOAT_ADD, rop.INT_ADD):
+            roper = rnode.getoperation()
             assert lop.numargs() == 2 and lop.result is not None
-            accum, accum_pos = self.getaccumulator_variable(lop, rop, 
origin_pack)
+            accum, accum_pos = self.getaccumulator_variable(lop, roper, 
origin_pack)
             if not accum:
                 return None
             # the dependency exists only because of the result of lnode
@@ -1337,6 +1342,17 @@
                     if not dep.because_of(accum):
                         # not quite ... this is not handlable
                         return None
+
+            # in either of the two cases the arguments are mixed,
+            # which is not handled currently
+            var_pos = (accum_pos + 1) % 2
+            plop = origin_pack.left.getoperation()
+            if lop.getarg(var_pos) is not plop.result:
+                return None
+            prop = origin_pack.right.getoperation()
+            if roper.getarg(var_pos) is not prop.result:
+                return None
+
             # this can be handled by accumulation
             return AccumPair(lnode, rnode, accum, accum_pos)
 
@@ -1344,10 +1360,11 @@
 
     def getaccumulator_variable(self, lop, rop, origin_pack):
         args = rop.getarglist()
-        for arg, i in enumerate(args):
+        for i, arg in enumerate(args):
+            print arg, "is", lop.result
             if arg is lop.result:
                 return arg, i
-
+        #
         return None, -1
 
     def can_be_packed(self, lnode, rnode, origin_pack):
@@ -1357,10 +1374,12 @@
                     return None
                 if origin_pack is None:
                     return Pair(lnode, rnode)
-                if self.profitable_pack(lnode, rnode, origin_pack)
+                if self.profitable_pack(lnode, rnode, origin_pack):
                     return Pair(lnode, rnode)
             else:
-                return self.accumulates_pair(lnode, rnode, origin_pack):
+                if self.contains_pair(lnode, rnode):
+                    return None
+                return self.accumulates_pair(lnode, rnode, origin_pack)
         return None
 
     def contains_pair(self, lnode, rnode):
@@ -1399,6 +1418,8 @@
         for op in pack_j.operations[1:]:
             operations.append(op)
         self.packs[i] = pack = Pack(operations)
+        pack.accum_variable = pack_i.accum_variable
+        pack.accum_position = pack_i.accum_position
 
         # instead of deleting an item in the center of pack array,
         # the last element is assigned to position j and
@@ -1411,13 +1432,6 @@
             del self.packs[last_pos]
         return last_pos
 
-    def pack_for_operation(self, node):
-        for pack in self.packs:
-            for node2 in pack.operations:
-                if node == node2:
-                    return pack
-        return None
-
 class Pack(object):
     """ A pack is a set of n statements that are:
         * isomorphic
@@ -1447,14 +1461,15 @@
         assert isinstance(other, Pack)
         rightmost = self.operations[-1]
         leftmost = other.operations[0]
-        both_same_type = self.is_accumulating() == other.is_accumulating()
-        return rightmost == leftmost and both_same_type
+        return rightmost == leftmost and \
+               self.accum_variable == other.accum_variable and \
+               self.accum_position == other.accum_position
 
     def __repr__(self):
         return "Pack(%r)" % self.operations
 
     def is_accumulating(self):
-        return accum_position != -1
+        return self.accum_variable is not None
 
 class Pair(Pack):
     """ A special Pack object with only two statements. """
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to