Author: Richard Plangger <r...@pasra.at>
Branch: vecopt-merge
Changeset: r79252:fc31b6dcacc8
Date: 2015-08-27 13:10 +0200
http://bitbucket.org/pypy/pypy/changeset/fc31b6dcacc8/

Log:    extending test cases for memory references

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
@@ -934,11 +934,11 @@
     """ IndexVar is an AbstractValue only to ensure that a box can be assigned
         to the same variable as an index var.
     """
-    def __init__(self, var):
+    def __init__(self, var, coeff_mul=1, coeff_div=1, constant=0):
         self.var = var
-        self.coefficient_mul = 1
-        self.coefficient_div = 1
-        self.constant = 0
+        self.coefficient_mul = coeff_mul
+        self.coefficient_div = coeff_div
+        self.constant = constant
         # saves the next modification that uses a variable
         self.next_nonconst = None
         self.current_end = None
@@ -990,7 +990,7 @@
 
     def same_variable(self, other):
         assert isinstance(other, IndexVar)
-        return other.var == self.var
+        return other.var is self.var
 
     def diff(self, other):
         """ calculates the difference as a second parameter """
@@ -1060,9 +1060,8 @@
         if self.is_identity():
             return 'IndexVar(%s+%s)' % (self.var, repr(self.next_nonconst))
 
-        return 'IndexVar((%s*(%s/%s)+%s) + %s)' % (self.var, 
self.coefficient_mul,
-                                            self.coefficient_div, 
self.constant,
-                                            repr(self.next_nonconst))
+        return 'IndexVar((%s*(%s/%s)+%s))' % (self.var, self.coefficient_mul,
+                                            self.coefficient_div, 
self.constant)
 
 class MemoryRef(object):
     """ a memory reference to an array object. IntegralForwardModification is 
able
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_dependency.py 
b/rpython/jit/metainterp/optimizeopt/test/test_dependency.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_dependency.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_dependency.py
@@ -7,20 +7,11 @@
 from rpython.jit.metainterp.optimizeopt.dependency import (DependencyGraph, 
Dependency,
         IndexVar, MemoryRef, Node)
 from rpython.jit.metainterp.resoperation import rop, ResOperation
+from rpython.jit.backend.llgraph.runner import ArrayDescr
+from rpython.rtyper.lltypesystem import rffi
+from rpython.rtyper.lltypesystem import lltype
 from rpython.conftest import option
 
-class FakeNode(Node):
-    def __init__(self, i):
-        Node.__init__(self, None, i)
-        pass
-
-    def __repr__(self):
-        return "n%d" % self.opidx
-
-class FakeDependencyGraph(DependencyGraph):
-    def __init__(self):
-        pass
-
 class DependencyBaseTest(BaseTest):
 
     def setup_method(self, method):
@@ -138,6 +129,48 @@
         return self.last_graph.memory_refs[node]
 
 class BaseTestDependencyGraph(DependencyBaseTest):
+
+    def test_index_var_basic(self):
+        b = FakeBox()
+        i = IndexVar(b,1,1,0)
+        j = IndexVar(b,1,1,0)
+        assert i.is_identity()
+        assert not i.less(j)
+        assert i.same_variable(j)
+        assert i.diff(j) == 0
+
+    def test_index_var_diff(self):
+        b = FakeBox()
+        i = IndexVar(b,4,2,0)
+        j = IndexVar(b,1,1,1)
+        assert not i.is_identity()
+        assert not j.is_identity()
+        assert i.diff(j) == 1
+
+    def test_memoryref_basic(self):
+        i = FakeBox()
+        a = FakeBox()
+        m1 = memoryref(a, i, (1,1,0))
+        m2 = memoryref(a, i, (1,1,0))
+        assert m1.match(m2)
+
+    @py.test.mark.parametrize('coeff1,coeff2,adja,alias',
+            [((1,1,0), (1,1,0), False, True),
+             ((4,2,0), (8,4,0), False, True),
+             ((4,2,0), (8,2,0), False, True),
+             ((4,2,1), (8,4,0), True, False),
+            ])
+    def test_memoryref_adjacent_alias(self, coeff1,
+                                      coeff2, adja,
+                                      alias):
+        i = FakeBox()
+        a = FakeBox()
+        m1 = memoryref(a, i, coeff1)
+        m2 = memoryref(a, i, coeff2)
+        assert m1.is_adjacent_after(m2) == adja
+        assert m2.is_adjacent_after(m1) == adja
+        assert m1.indices_can_alias(m2) == alias
+
     def test_dependency_empty(self):
         ops = """
         [] # 0: 1
@@ -511,6 +544,49 @@
         assert cycle is not None
         assert cycle == [n1,n3,n4]
 
+class FakeMemoryRefResOp(object):
+    def __init__(self, array, descr):
+        self.array = array
+        self.descr = descr
+    def getarg(self, index):
+        return self.array
+    def getdescr(self):
+        return self.descr
+
+FLOAT = ArrayDescr(lltype.Float)
+SFLOAT = ArrayDescr(lltype.SingleFloat)
+CHAR = ArrayDescr(rffi.r_signedchar)
+UCHAR = ArrayDescr(rffi.r_uchar)
+SHORT = ArrayDescr(rffi.r_short)
+USHORT = ArrayDescr(rffi.r_ushort)
+INT = ArrayDescr(rffi.r_int)
+UINT = ArrayDescr(rffi.r_uint)
+LONG = ArrayDescr(rffi.r_longlong)
+ULONG = ArrayDescr(rffi.r_ulonglong)
+
+def memoryref(array, var, mod=(1,1,0), descr=None, raw=False):
+    if descr is None:
+        descr = FLOAT
+    mul, div, off = mod
+    op = FakeMemoryRefResOp(array, descr)
+    return MemoryRef(op,
+                     IndexVar(var, mul, div, off),
+                     raw)
+
+class FakeBox(object):
+    pass
+
+class FakeNode(Node):
+    def __init__(self, i):
+        Node.__init__(self, None, i)
+        pass
+
+    def __repr__(self):
+        return "n%d" % self.opidx
+
+class FakeDependencyGraph(DependencyGraph):
+    def __init__(self):
+        pass
 
 
 class TestLLtype(BaseTestDependencyGraph, LLtypeMixin):
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
@@ -326,6 +326,8 @@
                     if memref_a.is_adjacent_to(memref_b):
                         pair = self.packset.can_be_packed(node_a, node_b, 
None, False)
                         if pair:
+                            if node_a.op.getopnum() == rop.GETARRAYITEM_RAW:
+                                print "found", memref_a.index_var, 
memref_b.index_var
                             self.packset.add_pack(pair)
 
     def extend_packset(self):
diff --git a/rpython/jit/metainterp/test/test_vectorize.py 
b/rpython/jit/metainterp/test/test_vectorize.py
--- a/rpython/jit/metainterp/test/test_vectorize.py
+++ b/rpython/jit/metainterp/test/test_vectorize.py
@@ -13,6 +13,11 @@
 from rpython.rlib.rawstorage import (alloc_raw_storage, raw_storage_setitem,
                                      free_raw_storage, raw_storage_getitem)
 
+def malloc(T,n):
+    return lltype.malloc(T, n, flavor='raw', zero=True)
+def free(mem):
+    lltype.free(mem, flavor='raw')
+
 class VectorizeTests:
     enable_opts = 
'intbounds:rewrite:virtualize:string:earlyforce:pure:heap:unroll'
 
@@ -289,8 +294,8 @@
         myjitdriver = JitDriver(greens = [],
                                 reds = 'auto')
         def f(d, v1, v2):
-            a = [v1] * d
-            b = [v2] * d
+            a = [v1] * i
+            b = [v2] * i
             i = 0
             while i < len(a):
                 myjitdriver.jit_merge_point()
@@ -305,6 +310,31 @@
         # return 69.999 ... instead of 70, (v1+v2)*i == 70.0
         assert res == f(i,v1,v2) == sum([v1+v2]*i)
 
+    @py.test.mark.parametrize('size',[12])
+    def test_body_multiple_accesses(self, size):
+        myjitdriver = JitDriver(greens = [], reds = 'auto')
+        T = lltype.Array(rffi.CHAR, hints={'nolength': True})
+        def f(size):
+            vector_a = malloc(T, size)
+            vector_b = malloc(T, size)
+            i = 0
+            while i < size:
+                myjitdriver.jit_merge_point()
+                # should unroll and group them correctly
+                c1 = vector_a[i]
+                c2 = vector_a[i+1]
+                c3 = vector_a[i+2]
+                #
+                vector_b[i] = c1
+                vector_b[i+1] = c2
+                vector_b[i+2] = c3
+                i += 3
+            free(vector_a)
+            free(vector_b)
+            return 0
+        res = self.meta_interp(f, [size], vec_all=True)
+        assert res == f(size)
+
 class VectorizeLLtypeTests(VectorizeTests):
     pass
 
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to