[pypy-svn] r77270 - in pypy/branch/jit-str/pypy/jit/codewriter: . test

arigo at codespeak.net arigo at codespeak.net
Wed Sep 22 15:23:33 CEST 2010


Author: arigo
Date: Wed Sep 22 15:23:31 2010
New Revision: 77270

Modified:
   pypy/branch/jit-str/pypy/jit/codewriter/call.py
   pypy/branch/jit-str/pypy/jit/codewriter/effectinfo.py
   pypy/branch/jit-str/pypy/jit/codewriter/jtransform.py
   pypy/branch/jit-str/pypy/jit/codewriter/support.py
   pypy/branch/jit-str/pypy/jit/codewriter/test/test_jtransform.py
   pypy/branch/jit-str/pypy/jit/codewriter/test/test_list.py
Log:
Start refactoring ARRAYCOPY and the string operations.  The idea is
to reach a point in which we can cleanly have a call operation
remain as a call, unless some special case applies in optimizeopt.


Modified: pypy/branch/jit-str/pypy/jit/codewriter/call.py
==============================================================================
--- pypy/branch/jit-str/pypy/jit/codewriter/call.py	(original)
+++ pypy/branch/jit-str/pypy/jit/codewriter/call.py	Wed Sep 22 15:23:31 2010
@@ -185,7 +185,7 @@
                                          FUNC.RESULT)
         return (fnaddr, calldescr)
 
-    def getcalldescr(self, op):
+    def getcalldescr(self, op, oopspecindex=EffectInfo.OS_NONE):
         """Return the calldescr that describes all calls done by 'op'.
         This returns a calldescr that we can put in the corresponding
         call operation in the calling jitcode.  It gets an effectinfo
@@ -226,7 +226,8 @@
             extraeffect = EffectInfo.EF_CANNOT_RAISE
         #
         effectinfo = effectinfo_from_writeanalyze(
-            self.readwrite_analyzer.analyze(op), self.cpu, extraeffect)
+            self.readwrite_analyzer.analyze(op), self.cpu, extraeffect,
+            oopspecindex)
         #
         if pure or loopinvariant:
             assert effectinfo is not None

Modified: pypy/branch/jit-str/pypy/jit/codewriter/effectinfo.py
==============================================================================
--- pypy/branch/jit-str/pypy/jit/codewriter/effectinfo.py	(original)
+++ pypy/branch/jit-str/pypy/jit/codewriter/effectinfo.py	Wed Sep 22 15:23:31 2010
@@ -15,13 +15,27 @@
     EF_LOOPINVARIANT                   = 3 #special: call it only once per loop
     EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE = 4 #can raise and force virtualizables
 
+    # the 'oopspecindex' field is one of the following values:
+    OS_NONE                     = 0    # normal case, no oopspec
+    OS_ARRAYCOPY                = 1    # "list.ll_arraycopy"
+    OS_STR_CONCAT               = 2    # "stroruni.concat"
+    OS_STR_SLICE_STARTONLY      = 3    # "stroruni.slice_startonly"
+    OS_STR_SLICE_STARTSTOP      = 4    # "stroruni.slice_startstop"
+    OS_STR_SLICE_MINUSONE       = 5    # "stroruni.slice_minusone"
+    OS_UNI_CONCAT               = 82   # "stroruni.concat" (+80)
+    OS_UNI_SLICE_STARTONLY      = 83   # "stroruni.slice_startonly" (+80)
+    OS_UNI_SLICE_STARTSTOP      = 84   # "stroruni.slice_startstop" (+80)
+    OS_UNI_SLICE_MINUSONE       = 85   # "stroruni.slice_minusone" (+80)
+
     def __new__(cls, readonly_descrs_fields,
                 write_descrs_fields, write_descrs_arrays,
-                extraeffect=EF_CAN_RAISE):
+                extraeffect=EF_CAN_RAISE,
+                oopspecindex=OS_NONE):
         key = (frozenset(readonly_descrs_fields),
                frozenset(write_descrs_fields),
                frozenset(write_descrs_arrays),
-               extraeffect)
+               extraeffect,
+               oopspecindex)
         if key in cls._cache:
             return cls._cache[key]
         result = object.__new__(cls)
@@ -29,6 +43,7 @@
         result.write_descrs_fields = write_descrs_fields
         result.write_descrs_arrays = write_descrs_arrays
         result.extraeffect = extraeffect
+        result.oopspecindex = oopspecindex
         cls._cache[key] = result
         return result
 
@@ -36,7 +51,8 @@
         return self.extraeffect >= self.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE
 
 def effectinfo_from_writeanalyze(effects, cpu,
-                                 extraeffect=EffectInfo.EF_CAN_RAISE):
+                                 extraeffect=EffectInfo.EF_CAN_RAISE,
+                                 oopspecindex=EffectInfo.OS_NONE):
     from pypy.translator.backendopt.writeanalyze import top_set
     if effects is top_set:
         return None

Modified: pypy/branch/jit-str/pypy/jit/codewriter/jtransform.py
==============================================================================
--- pypy/branch/jit-str/pypy/jit/codewriter/jtransform.py	(original)
+++ pypy/branch/jit-str/pypy/jit/codewriter/jtransform.py	Wed Sep 22 15:23:31 2010
@@ -6,6 +6,7 @@
 from pypy.objspace.flow.model import Block, Link, c_last_exception
 from pypy.jit.codewriter.flatten import ListOfKind, IndirectCallTargets
 from pypy.jit.codewriter import support, heaptracker
+from pypy.jit.codewriter.effectinfo import EffectInfo
 from pypy.jit.codewriter.policy import log
 from pypy.jit.metainterp.typesystem import deref, arrayItem
 from pypy.rlib import objectmodel
@@ -310,6 +311,8 @@
         # dispatch to various implementations depending on the oopspec_name
         if oopspec_name.startswith('list.') or oopspec_name == 'newlist':
             prepare = self._handle_list_call
+        elif oopspec_name.startswith('stroruni.'):
+            prepare = self._handle_stroruni_call
         elif oopspec_name.startswith('virtual_ref'):
             prepare = self._handle_virtual_ref_call
         else:
@@ -982,10 +985,7 @@
         return extraop + [op]
 
     def do_fixed_list_ll_arraycopy(self, op, args, arraydescr):
-        calldescr = self.callcontrol.getcalldescr(op)
-        return SpaceOperation('arraycopy',
-                              [calldescr, op.args[0]] + args + [arraydescr],
-                              op.result)
+        return self._handle_oopspec_call(op, args, EffectInfo.OS_ARRAYCOPY)
 
     # ---------- resizable lists ----------
 
@@ -1023,6 +1023,30 @@
                               [args[0], lengthdescr], op.result)
 
     # ----------
+    # Strings and Unicodes.
+
+    def _handle_oopspec_call(self, op, args, oopspecindex):
+        cc = self.callcontrol
+        calldescr = cc.getcalldescr(op, oopspecindex=oopspecindex)
+        return SpaceOperation('oopspec_call',
+                              [calldescr, op.args[0]] + args,
+                              op.result)
+
+    def _handle_stroruni_call(self, op, oopspec_name, args):
+        dict = {"stroruni.concat":          EffectInfo.OS_STR_CONCAT,
+                "stroruni.slice_startonly": EffectInfo.OS_STR_SLICE_STARTONLY,
+                "stroruni.slice_startstop": EffectInfo.OS_STR_SLICE_STARTSTOP,
+                "stroruni.slice_minusone":  EffectInfo.OS_STR_SLICE_MINUSONE}
+        base = dict[oopspec_name]
+        if args[0].concretetype.TO == rstr.STR:
+            offset = 0
+        elif args[0].concretetype.TO == rstr.UNICODE:
+            offset = 80
+        else:
+            assert 0, "args[0].concretetype must be STR or UNICODE"
+        return self._handle_oopspec_call(op, args, base + offset)
+
+    # ----------
     # VirtualRefs.
 
     def _handle_virtual_ref_call(self, op, oopspec_name, args):

Modified: pypy/branch/jit-str/pypy/jit/codewriter/support.py
==============================================================================
--- pypy/branch/jit-str/pypy/jit/codewriter/support.py	(original)
+++ pypy/branch/jit-str/pypy/jit/codewriter/support.py	Wed Sep 22 15:23:31 2010
@@ -277,11 +277,6 @@
 
     _ll_1_str_str2unicode = ll_rstr.LLHelpers.ll_str2unicode
 
-    _ll_2_stroruni_concat          = ll_rstr.LLHelpers.ll_strconcat
-    _ll_2_stroruni_slice_startonly = ll_rstr.LLHelpers.ll_stringslice_startonly
-    _ll_3_stroruni_slice_startstop = ll_rstr.LLHelpers.ll_stringslice_startstop
-    _ll_1_stroruni_slice_minusone  = ll_rstr.LLHelpers.ll_stringslice_minusone
-
     # ---------- malloc with del ----------
 
     def _ll_2_raw_malloc(TP, size):

Modified: pypy/branch/jit-str/pypy/jit/codewriter/test/test_jtransform.py
==============================================================================
--- pypy/branch/jit-str/pypy/jit/codewriter/test/test_jtransform.py	(original)
+++ pypy/branch/jit-str/pypy/jit/codewriter/test/test_jtransform.py	Wed Sep 22 15:23:31 2010
@@ -4,9 +4,9 @@
 from pypy.objspace.flow.model import SpaceOperation, Variable, Constant
 from pypy.jit.codewriter.jtransform import Transformer
 from pypy.jit.metainterp.history import getkind
-from pypy.rpython.lltypesystem import lltype, llmemory, rclass, rstr
+from pypy.rpython.lltypesystem import lltype, llmemory, rclass, rstr, rlist
 from pypy.translator.unsimplify import varoftype
-from pypy.jit.codewriter import heaptracker
+from pypy.jit.codewriter import heaptracker, effectinfo
 
 def const(x):
     return Constant(x, lltype.typeOf(x))
@@ -21,6 +21,8 @@
         return ('calldescr', FUNC, ARGS, RESULT)
     def fielddescrof(self, STRUCT, name):
         return ('fielddescr', STRUCT, name)
+    def arraydescrof(self, ARRAY):
+        return FakeDescr(('arraydescr', ARRAY))
     def sizeof(self, STRUCT):
         return FakeDescr(('sizedescr', STRUCT))
 
@@ -74,8 +76,8 @@
 class FakeBuiltinCallControl:
     def guess_call_kind(self, op):
         return 'builtin'
-    def getcalldescr(self, op):
-        return 'calldescr'
+    def getcalldescr(self, op, oopspecindex):
+        return 'calldescr-%d' % oopspecindex
     def calldescr_canraise(self, calldescr):
         return False
 
@@ -681,7 +683,6 @@
     assert op1.result == v2
 
 def test_str_concat():
-    py.test.xfail('later')
     # test that the oopspec is present and correctly transformed
     PSTR = lltype.Ptr(rstr.STR)
     FUNC = lltype.FuncType([PSTR, PSTR], PSTR)
@@ -693,8 +694,28 @@
     op = SpaceOperation('direct_call', [const(func), v1, v2], v3)
     tr = Transformer(FakeCPU(), FakeBuiltinCallControl())
     op1 = tr.rewrite_operation(op)
-    assert op1.opname == 'residual_call_r_r'
-    assert list(op1.args[2]) == [v1, v2]
+    assert op1.opname == 'oopspec_call'
+    assert op1.args[0] == 'calldescr-%d' % effectinfo.EffectInfo.OS_STR_CONCAT
+    assert op1.args[1].value == func
+    assert op1.args[2:] == [v1, v2]
+    assert op1.result == v3
+
+def test_unicode_concat():
+    # test that the oopspec is present and correctly transformed
+    PSTR = lltype.Ptr(rstr.UNICODE)
+    FUNC = lltype.FuncType([PSTR, PSTR], PSTR)
+    func = lltype.functionptr(FUNC, 'll_strconcat',
+                              _callable=rstr.LLHelpers.ll_strconcat)
+    v1 = varoftype(PSTR)
+    v2 = varoftype(PSTR)
+    v3 = varoftype(PSTR)
+    op = SpaceOperation('direct_call', [const(func), v1, v2], v3)
+    tr = Transformer(FakeCPU(), FakeBuiltinCallControl())
+    op1 = tr.rewrite_operation(op)
+    assert op1.opname == 'oopspec_call'
+    assert op1.args[0] == 'calldescr-%d' % effectinfo.EffectInfo.OS_UNI_CONCAT
+    assert op1.args[1].value == func
+    assert op1.args[2:] == [v1, v2]
     assert op1.result == v3
 
 def test_str_stringslice_startonly():
@@ -710,9 +731,11 @@
     op = SpaceOperation('direct_call', [const(func), v1, v2], v3)
     tr = Transformer(FakeCPU(), FakeBuiltinCallControl())
     op1 = tr.rewrite_operation(op)
-    assert op1.opname == 'residual_call_ir_r'
-    assert list(op1.args[2]) == [v2]
-    assert list(op1.args[3]) == [v1]
+    assert op1.opname == 'oopspec_call'
+    assert op1.args[0] == 'calldescr-%d' % (
+        effectinfo.EffectInfo.OS_STR_SLICE_STARTONLY)
+    assert op1.args[1].value == func
+    assert op1.args[2:] == [v1, v2]
     assert op1.result == v3
 
 def test_str_stringslice_startstop():
@@ -720,8 +743,8 @@
     PSTR = lltype.Ptr(rstr.STR)
     INT = lltype.Signed
     FUNC = lltype.FuncType([PSTR, INT, INT], PSTR)
-    func = lltype.functionptr(FUNC, 'll_stringslice_startstop',
-                             _callable=rstr.LLHelpers.ll_stringslice_startstop)
+    func = lltype.functionptr(FUNC, '_ll_stringslice_startstop',
+                            _callable=rstr.LLHelpers._ll_stringslice_startstop)
     v1 = varoftype(PSTR)
     v2 = varoftype(INT)
     v3 = varoftype(INT)
@@ -729,9 +752,11 @@
     op = SpaceOperation('direct_call', [const(func), v1, v2, v3], v4)
     tr = Transformer(FakeCPU(), FakeBuiltinCallControl())
     op1 = tr.rewrite_operation(op)
-    assert op1.opname == 'residual_call_ir_r'
-    assert list(op1.args[2]) == [v2, v3]
-    assert list(op1.args[3]) == [v1]
+    assert op1.opname == 'oopspec_call'
+    assert op1.args[0] == 'calldescr-%d' % (
+        effectinfo.EffectInfo.OS_STR_SLICE_STARTSTOP)
+    assert op1.args[1].value == func
+    assert op1.args[2:] == [v1, v2, v3]
     assert op1.result == v4
 
 def test_str_stringslice_minusone():
@@ -745,6 +770,31 @@
     op = SpaceOperation('direct_call', [const(func), v1], v2)
     tr = Transformer(FakeCPU(), FakeBuiltinCallControl())
     op1 = tr.rewrite_operation(op)
-    assert op1.opname == 'residual_call_r_r'
-    assert list(op1.args[2]) == [v1]
+    assert op1.opname == 'oopspec_call'
+    assert op1.args[0] == 'calldescr-%d' % (
+        effectinfo.EffectInfo.OS_STR_SLICE_MINUSONE)
+    assert op1.args[1].value == func
+    assert op1.args[2:] == [v1]
     assert op1.result == v2
+
+def test_list_ll_arraycopy():
+    from pypy.rlib.rgc import ll_arraycopy
+    LIST = lltype.GcArray(lltype.Signed)
+    PLIST = lltype.Ptr(LIST)
+    INT = lltype.Signed
+    FUNC = lltype.FuncType([PLIST]*2+[INT]*3, lltype.Void)
+    func = lltype.functionptr(FUNC, 'll_arraycopy', _callable=ll_arraycopy)
+    v1 = varoftype(PLIST)
+    v2 = varoftype(PLIST)
+    v3 = varoftype(INT)
+    v4 = varoftype(INT)
+    v5 = varoftype(INT)
+    v6 = varoftype(lltype.Void)
+    op = SpaceOperation('direct_call', [const(func), v1, v2, v3, v4, v5], v6)
+    tr = Transformer(FakeCPU(), FakeBuiltinCallControl())
+    op1 = tr.rewrite_operation(op)
+    assert op1.opname == 'oopspec_call'
+    assert op1.args[0] == 'calldescr-%d' % effectinfo.EffectInfo.OS_ARRAYCOPY
+    assert op1.args[1].value == func
+    assert op1.args[2:] == [v1, v2, v3, v4, v5]
+    assert op1.result == v6

Modified: pypy/branch/jit-str/pypy/jit/codewriter/test/test_list.py
==============================================================================
--- pypy/branch/jit-str/pypy/jit/codewriter/test/test_list.py	(original)
+++ pypy/branch/jit-str/pypy/jit/codewriter/test/test_list.py	Wed Sep 22 15:23:31 2010
@@ -36,10 +36,14 @@
 
 class FakeCallControl:
     class getcalldescr(AbstractDescr):
-        def __init__(self, op):
+        def __init__(self, op, oopspecindex=0):
             self.op = op
+            self.oopspecindex = oopspecindex
         def __repr__(self):
-            return '<CallDescr>'
+            if self.oopspecindex == 0:
+                return '<CallDescr>'
+            else:
+                return '<CallDescrOS%d>' % self.oopspecindex
 
 def builtin_test(oopspec_name, args, RESTYPE, expected):
     v_result = varoftype(RESTYPE)
@@ -99,7 +103,7 @@
                   varoftype(lltype.Signed), 
                   varoftype(lltype.Signed)],
                  lltype.Void, """
-                     arraycopy <CallDescr>, $'myfunc', %r0, %r1, %i0, %i1, %i2, <ArrayDescr>
+                     oopspec_call <CallDescrOS1>, $'myfunc', %r0, %r1, %i0, %i1, %i2
                  """)
 
 def test_fixed_getitem():



More information about the Pypy-commit mailing list