Author: Richard Plangger <r...@pasra.at>
Branch: vecopt
Changeset: r77989:2982e1a68dcf
Date: 2015-06-09 13:36 +0200
http://bitbucket.org/pypy/pypy/changeset/2982e1a68dcf/

Log:    moving the type determination from the scheduling transformation to
        the find pack routines, this helps to better determine the costs of
        unpacking and is needed for accumulation (vector type,size,count)
        must be known before scheduling begins

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
@@ -184,7 +184,9 @@
     def is_valid(self):
         return self.type != PackType.UNKNOWN_TYPE and self.size > 0
 
-    def new_vector_box(self, count):
+    def new_vector_box(self, count = -1):
+        if count == -1:
+            count = self.count
         return BoxVector(self.type, count, self.size, self.signed)
 
     def __repr__(self):
@@ -262,7 +264,7 @@
                 off += 1
                 continue
             ops = pack.operations[off:off+stride]
-            self.pack = Pack(ops)
+            self.pack = Pack(ops, pack.input_type, pack.output_type)
             self.transform_pack(ops, off, stride)
             off += stride
             left -= stride
@@ -671,13 +673,15 @@
         * isomorphic
         * independent
     """
-    def __init__(self, ops):
+    def __init__(self, ops, input_type, output_type):
         self.operations = ops
         for i,node in enumerate(self.operations):
             node.pack = self
             node.pack_position = i
         self.accum_variable = None
         self.accum_position = -1
+        self.input_type = input_type
+        self.output_type = output_type
 
     def opcount(self):
         return len(self.operations)
@@ -719,12 +723,12 @@
 
 class Pair(Pack):
     """ A special Pack object with only two statements. """
-    def __init__(self, left, right):
+    def __init__(self, left, right, input_type, output_type):
         assert isinstance(left, Node)
         assert isinstance(right, Node)
         self.left = left
         self.right = right
-        Pack.__init__(self, [left, right])
+        Pack.__init__(self, [left, right], input_type, output_type)
 
     def __eq__(self, other):
         if isinstance(other, Pair):
@@ -732,10 +736,10 @@
                    self.right is other.right
 
 class AccumPair(Pair):
-    def __init__(self, left, right, accum_var, accum_pos):
+    def __init__(self, left, right, input_type, output_type, accum_var, 
accum_pos):
         assert isinstance(left, Node)
         assert isinstance(right, Node)
-        Pair.__init__(self, left, right)
+        Pair.__init__(self, left, right, input_type, output_type)
         self.left = left
         self.right = right
         self.accum_variable = accum_var
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
@@ -11,7 +11,8 @@
 from rpython.jit.metainterp.optimizeopt.dependency import (DependencyGraph,
         MemoryRef, Node, IndexVar)
 from rpython.jit.metainterp.optimizeopt.schedule import (VecScheduleData,
-        Scheduler, Pack, Pair, AccumPair, vectorbox_outof_box, getpackopnum)
+        Scheduler, Pack, Pair, AccumPair, vectorbox_outof_box, getpackopnum,
+        getunpackopnum, PackType)
 from rpython.jit.metainterp.optimizeopt.guard import GuardStrengthenOpt
 from rpython.jit.metainterp.resoperation import (rop, ResOperation, GuardResOp)
 from rpython.rlib.objectmodel import we_are_translated
@@ -275,9 +276,10 @@
         loop = self.loop
         operations = loop.operations
 
+        vsize = self.metainterp_sd.cpu.vector_register_size
         self.packset = PackSet(self.dependency_graph, operations,
-                               self.unroll_count,
-                               self.smallest_type_bytes)
+                               self.unroll_count, self.smallest_type_bytes,
+                               vsize)
         graph = self.dependency_graph
         memory_refs = graph.memory_refs.items()
         # initialize the pack set
@@ -380,7 +382,7 @@
                 if vector:
                     self.unpack_from_vector(op, sched_data, renamer)
                 self.emit_operation(op)
-
+        #
         if not we_are_translated():
             for node in self.dependency_graph.nodes:
                 assert node.emitted
@@ -411,9 +413,7 @@
             renamer.start_renaming(arg, arg_cloned)
             cj = ConstInt(j)
             ci = ConstInt(1)
-            opnum = rop.VEC_FLOAT_UNPACK
-            if vbox.item_type == INT:
-                opnum = rop.VEC_INT_UNPACK
+            opnum = getunpackopnum(vbox.item_type)
             unpack_op = ResOperation(opnum, [vbox, cj, ci], arg_cloned)
             self.emit_operation(unpack_op)
             return arg_cloned
@@ -526,12 +526,13 @@
 class PackSet(object):
 
     def __init__(self, dependency_graph, operations, unroll_count,
-                 smallest_type_bytes):
+                 smallest_type_bytes, vec_reg_size):
         self.packs = []
         self.dependency_graph = dependency_graph
         self.operations = operations
         self.unroll_count = unroll_count
         self.smallest_type_bytes = smallest_type_bytes
+        self.vec_reg_size = vec_reg_size
 
     def pack_count(self):
         return len(self.packs)
@@ -545,9 +546,12 @@
                 if self.contains_pair(lnode, rnode):
                     return None
                 if origin_pack is None:
-                    return Pair(lnode, rnode)
+                    descr = lnode.getoperation().getdescr()
+                    input_type = PackType.by_descr(descr, self.vec_reg_size)
+                    return Pair(lnode, rnode, input_type, None)
                 if self.profitable_pack(lnode, rnode, origin_pack):
-                    return Pair(lnode, rnode)
+                    ptype = origin_pack.output_type
+                    return Pair(lnode, rnode, ptype, ptype)
             else:
                 if self.contains_pair(lnode, rnode):
                     return None
@@ -590,7 +594,8 @@
         operations = pack_i.operations
         for op in pack_j.operations[1:]:
             operations.append(op)
-        self.packs[i] = pack = Pack(operations)
+        pack = Pack(operations, pack_i.input_type, pack_i.output_type)
+        self.packs[i] = pack
         # preserve the accum variable (if present) of the
         # left most pack, that is the pack with the earliest
         # operation at index 0 in the trace
@@ -640,7 +645,8 @@
                 return None
 
             # this can be handled by accumulation
-            return AccumPair(lnode, rnode, accum, accum_pos)
+            ptype = origin_pack.output_type
+            return AccumPair(lnode, rnode, ptype, ptype, accum, accum_pos)
 
         return None
 
@@ -659,7 +665,7 @@
             var = pack.accum_variable
             pos = pack.accum_position
             # create a new vector box for the parameters
-            box = vectorbox_outof_box(var)
+            box = pack.input_type.new_vector_box(0)
             op = ResOperation(rop.VEC_BOX, [ConstInt(0)], box)
             sched_data.invariant_oplist.append(op)
             result = box.clonebox()
@@ -675,4 +681,3 @@
             # rename the variable with the box
             renamer.start_renaming(var, result)
 
-
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to