[pypy-commit] pypy disable_merge_different_int_types: merge default

bivab noreply at buildbot.pypy.org
Tue Nov 29 12:59:29 CET 2011


Author: David Schneider <david.schneider at picle.org>
Branch: disable_merge_different_int_types
Changeset: r49954:89efc1956c94
Date: 2011-11-29 12:50 +0100
http://bitbucket.org/pypy/pypy/changeset/89efc1956c94/

Log:	merge default

diff --git a/pypy/jit/backend/llsupport/gc.py b/pypy/jit/backend/llsupport/gc.py
--- a/pypy/jit/backend/llsupport/gc.py
+++ b/pypy/jit/backend/llsupport/gc.py
@@ -648,14 +648,10 @@
         # make a malloc function, with two arguments
         def malloc_basic(size, tid):
             type_id = llop.extract_ushort(llgroup.HALFWORD, tid)
-            has_finalizer = bool(tid & (1<<llgroup.HALFSHIFT))
-            has_light_finalizer = bool(tid & (1<<(llgroup.HALFSHIFT + 1)))
             check_typeid(type_id)
             res = llop1.do_malloc_fixedsize_clear(llmemory.GCREF,
                                                   type_id, size,
-                                                  has_finalizer,
-                                                  has_light_finalizer,
-                                                  False)
+                                                  False, False, False)
             # In case the operation above failed, we are returning NULL
             # from this function to assembler.  There is also an RPython
             # exception set, typically MemoryError; but it's easier and
@@ -749,11 +745,8 @@
     def init_size_descr(self, S, descr):
         type_id = self.layoutbuilder.get_type_id(S)
         assert not self.layoutbuilder.is_weakref_type(S)
-        has_finalizer = bool(self.layoutbuilder.has_finalizer(S))
-        has_light_finalizer = bool(self.layoutbuilder.has_light_finalizer(S))
-        flags = (int(has_finalizer) << llgroup.HALFSHIFT |
-                 int(has_light_finalizer) << (llgroup.HALFSHIFT + 1))
-        descr.tid = llop.combine_ushort(lltype.Signed, type_id, flags)
+        assert not self.layoutbuilder.has_finalizer(S)
+        descr.tid = llop.combine_ushort(lltype.Signed, type_id, 0)
 
     def init_array_descr(self, A, descr):
         type_id = self.layoutbuilder.get_type_id(A)
diff --git a/pypy/jit/metainterp/history.py b/pypy/jit/metainterp/history.py
--- a/pypy/jit/metainterp/history.py
+++ b/pypy/jit/metainterp/history.py
@@ -1003,6 +1003,9 @@
         insns = {}
         for loop in self.loops:
             insns = loop.summary(adding_insns=insns)
+        return self._check_insns(insns, expected, check)
+
+    def _check_insns(self, insns, expected, check):
         if expected is not None:
             insns.pop('debug_merge_point', None)
             assert insns == expected
@@ -1012,6 +1015,25 @@
             assert found == expected_count, (
                 "found %d %r, expected %d" % (found, insn, expected_count))
         return insns
+
+    def check_simple_loop(self, expected=None, **check):
+        # Usefull in the simplest case when we have only one trace ending with
+        # a jump back to itself and possibly a few bridges ending with finnish.
+        # Only the operations within the loop formed by that single jump will
+        # be counted.
+
+        # XXX hacked version, ignore and remove me when jit-targets is merged.
+        loops = self.get_all_loops()
+        loops = [loop for loop in loops if 'Preamble' not in repr(loop)] #XXX
+        assert len(loops) == 1
+        loop, = loops
+        jumpop = loop.operations[-1]
+        assert jumpop.getopnum() == rop.JUMP
+        insns = {}
+        for op in loop.operations:
+            opname = op.getopname()
+            insns[opname] = insns.get(opname, 0) + 1
+        return self._check_insns(insns, expected, check)
         
     def check_consistency(self):
         "NOT_RPYTHON"
diff --git a/pypy/jit/metainterp/test/support.py b/pypy/jit/metainterp/test/support.py
--- a/pypy/jit/metainterp/test/support.py
+++ b/pypy/jit/metainterp/test/support.py
@@ -157,6 +157,8 @@
     basic = True
     def check_resops(self, expected=None, **check):
         get_stats().check_resops(expected=expected, **check)
+    def check_simple_loop(self, expected=None, **check):
+        get_stats().check_simple_loop(expected=expected, **check)
 
     def check_loop_count(self, count):
         """NB. This is a hack; use check_tree_loop_count() or
diff --git a/pypy/jit/metainterp/test/test_ajit.py b/pypy/jit/metainterp/test/test_ajit.py
--- a/pypy/jit/metainterp/test/test_ajit.py
+++ b/pypy/jit/metainterp/test/test_ajit.py
@@ -107,7 +107,7 @@
         res = self.meta_interp(f, [6, 7])
         assert res == 1323
         self.check_loop_count(1)
-        self.check_resops(int_mul=3)
+        self.check_simple_loop(int_mul=1)
 
     def test_loop_variant_mul_ovf(self):
         myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x'])
@@ -124,7 +124,7 @@
         res = self.meta_interp(f, [6, 7])
         assert res == 1323
         self.check_loop_count(1)
-        self.check_resops(int_mul_ovf=3)
+        self.check_simple_loop(int_mul_ovf=1)
 
     def test_loop_invariant_mul1(self):
         myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x'])
@@ -139,6 +139,7 @@
         res = self.meta_interp(f, [6, 7])
         assert res == 252
         self.check_loop_count(1)
+        self.check_simple_loop(int_mul=0)
         self.check_resops({'jump': 2, 'int_gt': 2, 'int_add': 2,
                            'int_mul': 1, 'guard_true': 2, 'int_sub': 2})
 
@@ -157,6 +158,7 @@
         res = self.meta_interp(f, [6, 7])
         assert res == 308
         self.check_loop_count(1)
+        self.check_simple_loop(int_mul_ovf=0)
         self.check_resops({'jump': 2, 'int_lshift': 2, 'int_gt': 2,
                            'int_mul_ovf': 1, 'int_add': 4,
                            'guard_true': 2, 'guard_no_overflow': 1,
diff --git a/pypy/module/micronumpy/compile.py b/pypy/module/micronumpy/compile.py
--- a/pypy/module/micronumpy/compile.py
+++ b/pypy/module/micronumpy/compile.py
@@ -69,8 +69,12 @@
             if start < 0:
                 start += size
             if stop < 0:
-                stop += size
-            return (start, stop, step, size//step)
+                stop += size + 1
+            if step < 0:
+                lgt = (stop - start + 1) / step + 1
+            else:
+                lgt = (stop - start - 1) / step + 1
+            return (start, stop, step, lgt)
 
     @specialize.argtype(1)
     def wrap(self, obj):
@@ -97,7 +101,7 @@
         return w_obj
 
     def float_w(self, w_obj):
-        assert isinstance(w_obj, FloatObject)        
+        assert isinstance(w_obj, FloatObject)
         return w_obj.floatval
 
     def int_w(self, w_obj):
@@ -208,11 +212,12 @@
 
     def execute(self, interp):
         arr = interp.variables[self.name]
-        w_index = self.index.execute(interp).eval(arr.start_iter()).wrap(interp.space)
+        w_index = self.index.execute(interp)
         # cast to int
         if isinstance(w_index, FloatObject):
             w_index = IntObject(int(w_index.floatval))
-        w_val = self.expr.execute(interp).eval(arr.start_iter()).wrap(interp.space)
+        w_val = self.expr.execute(interp)
+        assert isinstance(arr, BaseArray)
         arr.descr_setitem(interp.space, w_index, w_val)
 
     def __repr__(self):
@@ -240,18 +245,22 @@
             w_rhs = self.rhs.wrap(interp.space)
         else:
             w_rhs = self.rhs.execute(interp)
+        if not isinstance(w_lhs, BaseArray):
+            # scalar
+            dtype = interp.space.fromcache(W_Float64Dtype)
+            w_lhs = scalar_w(interp.space, dtype, w_lhs)
         assert isinstance(w_lhs, BaseArray)
         if self.name == '+':
             w_res = w_lhs.descr_add(interp.space, w_rhs)
         elif self.name == '*':
             w_res = w_lhs.descr_mul(interp.space, w_rhs)
         elif self.name == '-':
-            w_res = w_lhs.descr_sub(interp.space, w_rhs)            
+            w_res = w_lhs.descr_sub(interp.space, w_rhs)
         elif self.name == '->':
-            if isinstance(w_rhs, Scalar):
-                w_rhs = w_rhs.eval(w_rhs.start_iter()).wrap(interp.space)
-                assert isinstance(w_rhs, FloatObject)
+            assert not isinstance(w_rhs, Scalar)
+            if isinstance(w_rhs, FloatObject):
                 w_rhs = IntObject(int(w_rhs.floatval))
+            assert isinstance(w_lhs, BaseArray)
             w_res = w_lhs.descr_getitem(interp.space, w_rhs)
         else:
             raise NotImplementedError
@@ -274,9 +283,7 @@
         return space.wrap(self.v)
 
     def execute(self, interp):
-        dtype = interp.space.fromcache(W_Float64Dtype)
-        assert isinstance(dtype, W_Float64Dtype)
-        return Scalar(dtype, dtype.box(self.v))
+        return FloatObject(self.v)
 
 class RangeConstant(Node):
     def __init__(self, v):
@@ -325,6 +332,9 @@
     def wrap(self, space):
         return SliceObject(self.start, self.stop, self.step)
 
+    def execute(self, interp):
+        return SliceObject(self.start, self.stop, self.step)
+
     def __repr__(self):
         return 'slice(%s,%s,%s)' % (self.start, self.stop, self.step)
 
@@ -477,8 +487,8 @@
                 else:
                     step = 1
         return SliceConstant(start, stop, step)
-            
-        
+
+
     def parse_expression(self, tokens):
         stack = []
         while tokens.remaining():
@@ -532,7 +542,7 @@
             if token.name == 'array_right':
                 return elems
             assert token.name == 'coma'
-        
+
     def parse_statement(self, tokens):
         if (tokens.get(0).name == 'identifier' and
             tokens.get(1).name == 'assign'):
diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py
--- a/pypy/module/micronumpy/interp_dtype.py
+++ b/pypy/module/micronumpy/interp_dtype.py
@@ -131,6 +131,7 @@
 
 
 def binop(func):
+    func._annspecialcase_ = "specialize:call_location"
     @functools.wraps(func)
     def impl(self, v1, v2):
         return self.adapt_val(func(self,
@@ -320,6 +321,18 @@
     @binop
     def mod(self, v1, v2):
         return v1 % v2
+    @binop
+    def pow(self, v1, v2):
+        res = 1
+        while v2 > 0:
+            if v2 & 1:
+                res *= v1
+            v2 >>= 1
+            if v2 == 0:
+                break
+            v1 *= v1
+        return res
+
 
 class SignedIntegerArithmeticDtype(IntegerArithmeticDtype):
     _mixin_ = True
diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py
--- a/pypy/module/micronumpy/interp_numarray.py
+++ b/pypy/module/micronumpy/interp_numarray.py
@@ -102,11 +102,12 @@
                     w_order=NoneNotWrapped):
     # find scalar
     if not space.issequence_w(w_item_or_iterable):
-        w_dtype = interp_ufuncs.find_dtype_for_scalar(space,
-                                                      w_item_or_iterable,
-                                                      w_dtype)
+        if space.is_w(w_dtype, space.w_None):
+            w_dtype = interp_ufuncs.find_dtype_for_scalar(space,
+                                                          w_item_or_iterable)
         dtype = space.interp_w(interp_dtype.W_Dtype,
-           space.call_function(space.gettypefor(interp_dtype.W_Dtype), w_dtype))
+            space.call_function(space.gettypefor(interp_dtype.W_Dtype), w_dtype)
+        )
         return scalar_w(space, dtype, w_item_or_iterable)
     if w_order is None:
         order = 'C'
@@ -179,10 +180,10 @@
         return self.offset
 
 class OneDimIterator(BaseIterator):
-    def __init__(self, start, step, size):
+    def __init__(self, start, step, stop):
         self.offset = start
         self.step = step
-        self.size = size
+        self.size = stop * step + start
 
     def next(self, shapelen):
         arr = instantiate(OneDimIterator)
@@ -192,7 +193,7 @@
         return arr
 
     def done(self):
-        return self.offset >= self.size
+        return self.offset == self.size
 
     def get_offset(self):
         return self.offset
@@ -717,21 +718,15 @@
 
     def descr_setitem(self, space, w_idx, w_value):
         self.invalidated()
-        concrete = self.get_concrete()
         if self._single_item_result(space, w_idx):
+            concrete = self.get_concrete()
             if len(concrete.shape) < 1:
                 raise OperationError(space.w_IndexError, space.wrap(
                         "0-d arrays can't be indexed"))
             item = concrete._index_of_single_item(space, w_idx)
             concrete.setitem_w(space, item, w_value)
             return
-        if isinstance(w_value, BaseArray):
-            # for now we just copy if setting part of an array from part of
-            # itself. can be improved.
-            if (concrete.get_root_storage() ==
-                w_value.get_concrete().get_root_storage()):
-                w_value = w_value.descr_copy(space)
-        else:
+        if not isinstance(w_value, BaseArray):
             w_value = convert_to_array(space, w_value)
         chunks = self._prepare_slice_args(space, w_idx)
         view = self.create_slice(space, chunks)
@@ -968,9 +963,9 @@
         call_sig = sig.components[0]
         assert isinstance(call_sig, signature.Call1)
         if self.forced_result is not None:
-            return 'Call1(%s, forced=%s)' % (call_sig.func.func_name,
+            return 'Call1(%s, forced=%s)' % (call_sig.name,
                                              self.forced_result.debug_repr())
-        return 'Call1(%s, %s)' % (call_sig.func.func_name,
+        return 'Call1(%s, %s)' % (call_sig.name,
                                   self.values.debug_repr())
 
 class Call2(VirtualArray):
@@ -1018,9 +1013,9 @@
         call_sig = sig.components[0]
         assert isinstance(call_sig, signature.Call2)
         if self.forced_result is not None:
-            return 'Call2(%s, forced=%s)' % (call_sig.func.func_name,
+            return 'Call2(%s, forced=%s)' % (call_sig.name,
                 self.forced_result.debug_repr())
-        return 'Call2(%s, %s, %s)' % (call_sig.func.func_name,
+        return 'Call2(%s, %s, %s)' % (call_sig.name,
             self.left.debug_repr(),
             self.right.debug_repr())
 
@@ -1108,8 +1103,8 @@
     def start_iter(self, res_shape=None):
         if res_shape is not None and res_shape != self.shape:
             return BroadcastIterator(self, res_shape)
-        # XXX there is a possible optimization here with SingleDimViewIterator
-        #     ignore for now
+        if len(self.shape) == 1:
+            return OneDimIterator(self.start, self.strides[0], self.shape[0])
         return ViewIterator(self)
 
     def setitem(self, item, value):
diff --git a/pypy/module/micronumpy/signature.py b/pypy/module/micronumpy/signature.py
--- a/pypy/module/micronumpy/signature.py
+++ b/pypy/module/micronumpy/signature.py
@@ -40,13 +40,15 @@
         return Signature._known_sigs.setdefault(components, Signature(components))
 
 class Call1(BaseSignature):
-    _immutable_fields_ = ["func"]
+    _immutable_fields_ = ["func", "name"]
 
     def __init__(self, func):
         self.func = func
+        self.name = func.func_name
 
 class Call2(BaseSignature):
-    _immutable_fields_ = ["func"]
+    _immutable_fields_ = ["func", "name"]
 
     def __init__(self, func):
         self.func = func
+        self.name = func.func_name
diff --git a/pypy/module/micronumpy/test/test_compile.py b/pypy/module/micronumpy/test/test_compile.py
--- a/pypy/module/micronumpy/test/test_compile.py
+++ b/pypy/module/micronumpy/test/test_compile.py
@@ -177,6 +177,27 @@
         """)
         assert interp.results[0].value.val == 6
 
+    def test_setslice(self):
+        interp = self.run("""
+        a = |30|
+        b = |10|
+        b[1] = 5
+        a[::3] = b
+        a -> 3
+        """)
+        assert interp.results[0].value.val == 5
+
+
+    def test_slice2(self):
+        interp = self.run("""
+        a = |30|
+        s1 = a -> 0:20:2
+        s2 = a -> 0:30:3
+        b = s1 + s2
+        b -> 3
+        """)
+        assert interp.results[0].value.val == 15
+
     def test_multidim_getitem(self):
         interp = self.run("""
         a = [[1,2]]
@@ -191,3 +212,23 @@
         b -> 1 -> 1
         """)
         assert interp.results[0].value.val == 8
+
+    def test_set_slice(self):
+        interp = self.run("""
+        a = |30|
+        b = |30|
+        b[:] = a + a
+        b -> 3
+        """)
+        assert interp.results[0].value.val == 6
+
+    def test_set_slice2(self):
+        interp = self.run("""
+        a = |30|
+        b = |10|
+        b[1] = 5.5
+        c = b + b
+        a[0:30:3] = c
+        a -> 3
+        """)
+        assert interp.results[0].value.val == 11        
diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py
--- a/pypy/module/micronumpy/test/test_numarray.py
+++ b/pypy/module/micronumpy/test/test_numarray.py
@@ -176,8 +176,7 @@
 
     def test_size(self):
         from numpypy import array
-        # XXX fixed on multidim branch
-        #assert array(3).size == 1
+        assert array(3).size == 1
         a = array([1, 2, 3])
         assert a.size == 3
         assert (a + a).size == 3
@@ -302,12 +301,13 @@
         assert a[3] == 0.
 
     def test_scalar(self):
-        from numpypy import array
+        from numpypy import array, dtype
         a = array(3)
         #assert a[0] == 3
         raises(IndexError, "a[0]")
         assert a.size == 1
         assert a.shape == ()
+        assert a.dtype is dtype(int)
 
     def test_len(self):
         from numpypy import array
@@ -750,6 +750,12 @@
         assert bool(array([1]))
         assert not bool(array([0]))
 
+    def test_slice_assignment(self):
+        from numpypy import arange
+        a = arange(5)
+        a[::-1] = a
+        assert (a == [0, 1, 2, 1, 0]).all()
+
 
 class AppTestMultiDim(BaseNumpyAppTest):
     def test_init(self):
diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py
--- a/pypy/module/micronumpy/test/test_ufuncs.py
+++ b/pypy/module/micronumpy/test/test_ufuncs.py
@@ -111,6 +111,8 @@
         for i in range(3):
             assert c[i] == a[i] / b[i]
 
+        assert (divide(array([-10]), array([2])) == array([-5])).all()
+
     def test_fabs(self):
         from numpypy import array, fabs
         from math import fabs as math_fabs
diff --git a/pypy/module/micronumpy/test/test_zjit.py b/pypy/module/micronumpy/test/test_zjit.py
--- a/pypy/module/micronumpy/test/test_zjit.py
+++ b/pypy/module/micronumpy/test/test_zjit.py
@@ -11,7 +11,8 @@
 from pypy.module.micronumpy import interp_ufuncs, signature
 from pypy.module.micronumpy.compile import (numpy_compile, FakeSpace,
     FloatObject, IntObject, BoolObject, Parser, InterpreterState)
-from pypy.module.micronumpy.interp_numarray import NDimArray, NDimSlice
+from pypy.module.micronumpy.interp_numarray import NDimArray, NDimSlice,\
+     BaseArray
 from pypy.rlib.nonconst import NonConstant
 from pypy.rpython.annlowlevel import llstr, hlstr
 
@@ -48,6 +49,7 @@
             interp = InterpreterState(codes[i])
             interp.run(space)
             res = interp.results[-1]
+            assert isinstance(res, BaseArray)
             w_res = res.eval(res.start_iter()).wrap(interp.space)
             if isinstance(w_res, BoolObject):
                 return float(w_res.boolval)
@@ -78,10 +80,9 @@
 
     def test_add(self):
         result = self.run("add")
-        self.check_resops({'setarrayitem_raw': 2, 'getfield_gc': 19, 'guard_class': 11,
-                           'int_add': 6, 'guard_isnull': 1, 'jump': 2, 'int_ge': 2,
-                           'getarrayitem_raw': 4, 'float_add': 2, 'guard_false': 2,
-                           'guard_value': 1})
+        self.check_simple_loop({'getarrayitem_raw': 2, 'float_add': 1,
+                          'setarrayitem_raw': 1, 'int_add': 3,
+                          'int_ge': 1, 'guard_false': 1, 'jump': 1})
         assert result == 3 + 3
 
     def define_float_add():
@@ -93,10 +94,9 @@
     def test_floatadd(self):
         result = self.run("float_add")
         assert result == 3 + 3
-        self.check_resops({'setarrayitem_raw': 2, 'getfield_gc': 17, 'guard_class': 11,
-                           'int_add': 4, 'guard_isnull': 1, 'jump': 2, 'int_ge': 2,
-                           'getarrayitem_raw': 2, 'float_add': 2, 'guard_false': 2,
-                           'guard_value': 1})
+        self.check_simple_loop({"getarrayitem_raw": 1, "float_add": 1,
+                          "setarrayitem_raw": 1, "int_add": 2,
+                          "int_ge": 1, "guard_false": 1, "jump": 1})
 
     def define_sum():
         return """
@@ -108,9 +108,9 @@
     def test_sum(self):
         result = self.run("sum")
         assert result == 2 * sum(range(30))
-        self.check_resops({'guard_class': 10, 'getfield_gc': 17, 'jump': 2,
-                           'getarrayitem_raw': 4, 'guard_value': 2, 'int_add': 4,
-                           'guard_isnull': 1, 'int_ge': 2, 'float_add': 4, 'guard_false': 2})
+        self.check_simple_loop({"getarrayitem_raw": 2, "float_add": 2,
+                          "int_add": 2,
+                          "int_ge": 1, "guard_false": 1, "jump": 1})
 
     def define_prod():
         return """
@@ -125,11 +125,9 @@
         for i in range(30):
             expected *= i * 2
         assert result == expected
-        self.check_resops({'guard_class': 10, 'getfield_gc': 17, 'int_add': 4,
-                           'float_mul': 2, 'guard_isnull': 1, 'jump': 2, 'int_ge': 2,
-                           'getarrayitem_raw': 4, 'float_add': 2, 'guard_false': 2,
-                           'guard_value': 2})
-
+        self.check_simple_loop({"getarrayitem_raw": 2, "float_add": 1,
+                          "float_mul": 1, "int_add": 2,
+                          "int_ge": 1, "guard_false": 1, "jump": 1})
 
     def test_max(self):
         py.test.skip("broken, investigate")
@@ -140,7 +138,7 @@
         max(b)
         """)
         assert result == 256
-        self.check_loops({"getarrayitem_raw": 2, "float_add": 1,
+        self.check_simple_loop({"getarrayitem_raw": 2, "float_add": 1,
                           "float_mul": 1, "int_add": 1,
                           "int_lt": 1, "guard_true": 1, "jump": 1})
 
@@ -153,10 +151,9 @@
         min(b)
         """)
         assert result == -24
-        self.check_resops({'guard_class': 10, 'getfield_gc': 15, 'guard_value': 1,
-                           'int_add': 4, 'guard_isnull': 1, 'jump': 2, 'int_ge': 2,
-                           'getarrayitem_raw': 4, 'float_add': 2, 'guard_false': 4,
-                           'float_ne': 2})
+        self.check_simple_loop({"getarrayitem_raw": 2, "float_add": 1,
+                          "float_mul": 1, "int_add": 1,
+                          "int_lt": 1, "guard_true": 1, "jump": 1})
 
     def define_any():
         return """
@@ -169,10 +166,10 @@
     def test_any(self):
         result = self.run("any")
         assert result == 1
-        self.check_resops({'guard_class': 10, 'getfield_gc': 15, 'guard_value': 1,
-                           'int_add': 4, 'guard_isnull': 1, 'jump': 2, 'int_ge': 2,
-                           'getarrayitem_raw': 4, 'float_add': 2, 'guard_false': 4,
-                           'float_ne': 2})
+        self.check_simple_loop({"getarrayitem_raw": 2, "float_add": 1,
+                          "float_ne": 1, "int_add": 2,
+                          "int_ge": 1, "jump": 1,
+                          "guard_false": 2})
 
     def define_already_forced():
         return """
@@ -189,13 +186,14 @@
         # This is the sum of the ops for both loops, however if you remove the
         # optimization then you end up with 2 float_adds, so we can still be
         # sure it was optimized correctly.
+        # XXX the comment above is wrong now.  We need preferrably a way to
+        # count the two loops separately
         self.check_resops({'setarrayitem_raw': 4, 'guard_nonnull': 1, 'getfield_gc': 35,
                            'guard_class': 22, 'int_add': 8, 'float_mul': 2,
                            'guard_isnull': 2, 'jump': 4, 'int_ge': 4,
                            'getarrayitem_raw': 4, 'float_add': 2, 'guard_false': 4,
                            'guard_value': 2})
 
-
     def define_ufunc():
         return """
         a = |30|
@@ -207,11 +205,10 @@
     def test_ufunc(self):
         result = self.run("ufunc")
         assert result == -6
-        self.check_resops({'setarrayitem_raw': 2, 'getfield_gc': 24, 'guard_class': 14,
-                           'int_add': 6, 'float_neg': 2, 'guard_isnull': 2, 'jump': 2,
-                           'int_ge': 2, 'getarrayitem_raw': 4, 'float_add': 2,
-                           'guard_false': 2, 'guard_value': 2})
-
+        self.check_simple_loop({"getarrayitem_raw": 2, "float_add": 1, "float_neg": 1,
+                          "setarrayitem_raw": 1, "int_add": 3,
+                          "int_ge": 1, "guard_false": 1, "jump": 1,
+        })
 
     def define_specialization():
         return """
@@ -249,10 +246,28 @@
     def test_slice(self):
         result = self.run("slice")
         assert result == 18
-        py.test.skip("Few remaining arraylen_gc left")
-        self.check_loops({'int_mul': 2, 'getarrayitem_raw': 2, 'float_add': 1,
-                          'setarrayitem_raw': 1, 'int_add': 3,
-                          'int_lt': 1, 'guard_true': 1, 'jump': 1})
+        self.check_simple_loop({'getarrayitem_raw': 2,
+                                'float_add': 1,
+                                'setarrayitem_raw': 1,
+                                'int_add': 3,
+                                'int_ge': 1, 'guard_false': 1,
+                                'jump': 1})
+
+    def define_slice2():
+        return """
+        a = |30|
+        s1 = a -> :20:2
+        s2 = a -> :30:3
+        b = s1 + s2
+        b -> 3
+        """
+
+    def test_slice2(self):
+        result = self.run("slice2")
+        assert result == 15
+        self.check_simple_loop({'getarrayitem_raw': 2, 'float_add': 1,
+                                'setarrayitem_raw': 1, 'int_add': 3,
+                                'int_ge': 1, 'guard_false': 1, 'jump': 1})
 
     def define_multidim():
         return """
@@ -264,10 +279,9 @@
     def test_multidim(self):
         result = self.run('multidim')
         assert result == 8
-        self.check_resops({'setarrayitem_raw': 2, 'getfield_gc': 19, 'guard_class': 11,
-                           'int_add': 6, 'guard_isnull': 1, 'jump': 2, 'int_ge': 2,
-                           'getarrayitem_raw': 4, 'float_add': 2, 'guard_false': 2,
-                           'guard_value': 1})
+        self.check_simple_loop({'float_add': 1, 'getarrayitem_raw': 2,
+                          'guard_false': 1, 'int_add': 3, 'int_ge': 1,
+                          'jump': 1, 'setarrayitem_raw': 1})
         # int_add might be 1 here if we try slightly harder with
         # reusing indexes or some optimization
 
@@ -285,7 +299,7 @@
         py.test.skip("improve")
         # XXX the bridge here is scary. Hopefully jit-targets will fix that,
         #     otherwise it looks kind of good
-        self.check_loops({})
+        self.check_simple_loop({})
 
     def define_broadcast():
         return """
@@ -299,7 +313,25 @@
         result = self.run("broadcast")
         assert result == 10
         py.test.skip("improve")
-        self.check_loops({})
+        self.check_simple_loop({})
+
+    def define_setslice():
+        return """
+        a = |30|
+        b = |10|
+        b[1] = 5.5
+        c = b + b
+        a[0:30:3] = c
+        a -> 3
+        """
+
+    def test_setslice(self):
+        result = self.run("setslice")
+        assert result == 11.0
+        self.check_loop_count(1)
+        self.check_simple_loop({'getarrayitem_raw': 2, 'float_add' : 1,
+                                'setarrayitem_raw': 1, 'int_add': 3,
+                                'int_eq': 1, 'guard_false': 1, 'jump': 1})
 
 class TestNumpyOld(LLJitMixin):
     def setup_class(cls):
@@ -310,48 +342,6 @@
         cls.space = FakeSpace()
         cls.float64_dtype = cls.space.fromcache(W_Float64Dtype)
 
-    def test_slice2(self):
-        def f(i):
-            step1 = 2
-            step2 = 3
-            ar = NDimArray(step2*i, dtype=self.float64_dtype)
-            new_sig = signature.Signature.find_sig([
-                NDimSlice.signature, ar.signature
-            ])
-            s1 = NDimSlice(0, step1*i, step1, i, ar, new_sig)
-            new_sig = signature.Signature.find_sig([
-                NDimSlice.signature, s1.signature
-            ])
-            s2 = NDimSlice(0, step2*i, step2, i, ar, new_sig)
-            v = interp_ufuncs.get(self.space).add.call(self.space, [s1, s2])
-            return v.get_concrete().eval(3).val
-
-        result = self.meta_interp(f, [5], listops=True, backendopt=True)
-        self.check_loops({'int_mul': 2, 'getarrayitem_raw': 2, 'float_add': 1,
-                          'setarrayitem_raw': 1, 'int_add': 1,
-                          'int_lt': 1, 'guard_true': 1, 'jump': 1})
-        assert result == f(5)
-
-    def test_setslice(self):
-        space = self.space
-        float64_dtype = self.float64_dtype
-
-        def f(i):
-            step = NonConstant(3)
-            ar = NDimArray(step*i, dtype=float64_dtype)
-            ar2 = NDimArray(i, dtype=float64_dtype)
-            ar2.get_concrete().setitem(1, float64_dtype.box(5.5))
-            arg = ar2.descr_add(space, ar2)
-            ar.setslice(space, 0, step*i, step, i, arg)
-            return ar.get_concrete().eval(3).val
-
-        result = self.meta_interp(f, [5], listops=True, backendopt=True)
-        self.check_loops({'getarrayitem_raw': 2,
-                          'float_add' : 1,
-                          'setarrayitem_raw': 1, 'int_add': 2,
-                          'int_lt': 1, 'guard_true': 1, 'jump': 1})
-        assert result == 11.0
-
     def test_int32_sum(self):
         py.test.skip("pypy/jit/backend/llimpl.py needs to be changed to "
                      "deal correctly with int dtypes for this test to "


More information about the pypy-commit mailing list