[pypy-svn] r77328 - in pypy/branch/jit-str/pypy/jit: backend/llgraph metainterp/optimizeopt metainterp/test

arigo at codespeak.net arigo at codespeak.net
Fri Sep 24 11:04:14 CEST 2010


Author: arigo
Date: Fri Sep 24 11:04:11 2010
New Revision: 77328

Modified:
   pypy/branch/jit-str/pypy/jit/backend/llgraph/llimpl.py
   pypy/branch/jit-str/pypy/jit/metainterp/optimizeopt/optimizer.py
   pypy/branch/jit-str/pypy/jit/metainterp/optimizeopt/virtualize.py
   pypy/branch/jit-str/pypy/jit/metainterp/test/test_optimizefindnode.py
   pypy/branch/jit-str/pypy/jit/metainterp/test/test_optimizeopt.py
Log:
Try to recognize that constant strings of length 1 are actually characters.


Modified: pypy/branch/jit-str/pypy/jit/backend/llgraph/llimpl.py
==============================================================================
--- pypy/branch/jit-str/pypy/jit/backend/llgraph/llimpl.py	(original)
+++ pypy/branch/jit-str/pypy/jit/backend/llgraph/llimpl.py	Fri Sep 24 11:04:11 2010
@@ -1385,11 +1385,15 @@
 def do_copystrcontent(src, dst, srcstart, dststart, length):
     src = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), src)
     dst = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), dst)
+    assert 0 <= srcstart <= srcstart + length <= len(src.chars)
+    assert 0 <= dststart <= dststart + length <= len(dst.chars)
     rstr.copy_string_contents(src, dst, srcstart, dststart, length)
 
 def do_copyunicodecontent(src, dst, srcstart, dststart, length):
     src = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), src)
     dst = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), dst)
+    assert 0 <= srcstart <= srcstart + length <= len(src.chars)
+    assert 0 <= dststart <= dststart + length <= len(dst.chars)
     rstr.copy_unicode_contents(src, dst, srcstart, dststart, length)
 
 # ---------- call ----------

Modified: pypy/branch/jit-str/pypy/jit/metainterp/optimizeopt/optimizer.py
==============================================================================
--- pypy/branch/jit-str/pypy/jit/metainterp/optimizeopt/optimizer.py	(original)
+++ pypy/branch/jit-str/pypy/jit/metainterp/optimizeopt/optimizer.py	Fri Sep 24 11:04:11 2010
@@ -9,7 +9,7 @@
 from pypy.jit.metainterp.optimizeutil import InvalidLoop, args_dict
 from pypy.jit.metainterp import resume, compile
 from pypy.jit.metainterp.typesystem import llhelper, oohelper
-from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.lltypesystem import lltype, rstr
 from pypy.jit.metainterp.history import AbstractDescr, make_hashable_int
 from pypy.jit.metainterp.optimizeopt.intutils import IntBound, IntUnbounded
 
@@ -127,10 +127,16 @@
         raise NotImplementedError
 
     def getstrlen(self, newoperations):
-        box = self.force_box()
-        lengthbox = BoxInt()
-        newoperations.append(ResOperation(rop.STRLEN, [box], lengthbox))
-        return lengthbox
+        if self.is_constant():
+            s = self.box.getref(lltype.Ptr(rstr.STR))
+            length = len(s.chars)
+            return ConstInt(length)
+        else:
+            self.ensure_nonnull()
+            box = self.force_box()
+            lengthbox = BoxInt()
+            newoperations.append(ResOperation(rop.STRLEN, [box], lengthbox))
+            return lengthbox
 
     def string_copy_parts(self, *args):
         from pypy.jit.metainterp.optimizeopt import virtualize

Modified: pypy/branch/jit-str/pypy/jit/metainterp/optimizeopt/virtualize.py
==============================================================================
--- pypy/branch/jit-str/pypy/jit/metainterp/optimizeopt/virtualize.py	(original)
+++ pypy/branch/jit-str/pypy/jit/metainterp/optimizeopt/virtualize.py	Fri Sep 24 11:04:11 2010
@@ -314,20 +314,35 @@
     # Copies the pointer-to-string 'srcvalue' into the target string
     # given by 'targetbox', at the specified offset.  Returns the offset
     # at the end of the copy.
+    lengthbox = srcvalue.getstrlen(newoperations)
     srcbox = srcvalue.force_box()
-    lengthbox = BoxInt()
-    newoperations.append(ResOperation(rop.STRLEN, [srcbox], lengthbox))
     return copy_str_content(newoperations, srcbox, targetbox,
                             CONST_0, offsetbox, lengthbox)
 
 def copy_str_content(newoperations, srcbox, targetbox,
                      srcoffsetbox, offsetbox, lengthbox):
-    nextoffsetbox = _int_add(newoperations, offsetbox, lengthbox)
-    newoperations.append(ResOperation(rop.COPYSTRCONTENT, [srcbox, targetbox,
-                                                           srcoffsetbox,
-                                                           offsetbox,
-                                                           lengthbox], None))
-    return nextoffsetbox
+    if isinstance(srcbox, ConstPtr) and isinstance(srcoffsetbox, Const):
+        M = 5
+    else:
+        M = 2
+    if isinstance(lengthbox, ConstInt) and lengthbox.value <= M:
+        # up to M characters are done "inline", i.e. with STRGETITEM/STRSETITEM
+        # instead of just a COPYSTRCONTENT.
+        for i in range(lengthbox.value):
+            charbox = _strgetitem(newoperations, srcbox, srcoffsetbox)
+            srcoffsetbox = _int_add(newoperations, srcoffsetbox, CONST_1)
+            newoperations.append(ResOperation(rop.STRSETITEM, [targetbox,
+                                                               offsetbox,
+                                                               charbox], None))
+            offsetbox = _int_add(newoperations, offsetbox, CONST_1)
+    else:
+        nextoffsetbox = _int_add(newoperations, offsetbox, lengthbox)
+        op = ResOperation(rop.COPYSTRCONTENT, [srcbox, targetbox,
+                                               srcoffsetbox, offsetbox,
+                                               lengthbox], None)
+        newoperations.append(op)
+        offsetbox = nextoffsetbox
+    return offsetbox
 
 def _int_add(newoperations, box1, box2):
     if isinstance(box1, ConstInt):
@@ -351,6 +366,16 @@
     newoperations.append(ResOperation(rop.INT_SUB, [box1, box2], resbox))
     return resbox
 
+def _strgetitem(newoperations, strbox, indexbox):
+    # hum, this repetition of the operations is not quite right
+    if isinstance(strbox, ConstPtr) and isinstance(indexbox, ConstInt):
+        s = strbox.getref(lltype.Ptr(rstr.STR))
+        return ConstInt(ord(s.chars[indexbox.getint()]))
+    resbox = BoxInt()
+    newoperations.append(ResOperation(rop.STRGETITEM, [strbox, indexbox],
+                                      resbox))
+    return resbox
+
 
 class __extend__(SpecNode):
     def setup_virtual_node(self, optimizer, box, newinputargs):
@@ -661,12 +686,8 @@
 
     def optimize_STRLEN(self, op):
         value = self.getvalue(op.args[0])
-        if isinstance(value, VStringPlainValue):  # even if no longer virtual
-            lengthbox = value.getstrlen(self.optimizer.newoperations)
-            self.make_equal_to(op.result, self.getvalue(lengthbox))
-        else:
-            value.ensure_nonnull()
-            self.emit_operation(op)
+        lengthbox = value.getstrlen(self.optimizer.newoperations)
+        self.make_equal_to(op.result, self.getvalue(lengthbox))
 
     def opt_call_oopspec_STR_CONCAT(self, op):
         vleft = self.getvalue(op.args[1])

Modified: pypy/branch/jit-str/pypy/jit/metainterp/test/test_optimizefindnode.py
==============================================================================
--- pypy/branch/jit-str/pypy/jit/metainterp/test/test_optimizefindnode.py	(original)
+++ pypy/branch/jit-str/pypy/jit/metainterp/test/test_optimizefindnode.py	Fri Sep 24 11:04:11 2010
@@ -1,6 +1,6 @@
 import py, random
 
-from pypy.rpython.lltypesystem import lltype, llmemory, rclass
+from pypy.rpython.lltypesystem import lltype, llmemory, rclass, rstr
 from pypy.rpython.ootypesystem import ootype
 from pypy.rpython.lltypesystem.rclass import OBJECT, OBJECT_VTABLE
 
@@ -121,6 +121,11 @@
                  EffectInfo([], [], [], oopspecindex=EffectInfo.OS_STR_CONCAT))
     slicedescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
                  EffectInfo([], [], [], oopspecindex=EffectInfo.OS_STR_SLICE))
+    strequaldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
+                 EffectInfo([], [], [], oopspecindex=EffectInfo.OS_STR_EQUAL))
+
+    mystr1 = lltype.cast_opaque_ptr(llmemory.GCREF,
+                                    rstr.string_repr.convert_const("x"))
 
     class LoopToken(AbstractDescr):
         pass

Modified: pypy/branch/jit-str/pypy/jit/metainterp/test/test_optimizeopt.py
==============================================================================
--- pypy/branch/jit-str/pypy/jit/metainterp/test/test_optimizeopt.py	(original)
+++ pypy/branch/jit-str/pypy/jit/metainterp/test/test_optimizeopt.py	Fri Sep 24 11:04:11 2010
@@ -4016,6 +4016,25 @@
         """
         self.optimize_loop(ops, 'Not, Not, Not', expected)
 
+    def test_str_concat_str_cstr1(self):
+        ops = """
+        [p2]
+        p3 = call(0, p2, ConstPtr(mystr1), descr=strconcatdescr)
+        jump(p3)
+        """
+        expected = """
+        [p2]
+        i2 = strlen(p2)
+        i3 = int_add(i2, 1)
+        p3 = newstr(i3)
+        i4 = strlen(p2)
+        copystrcontent(p2, p3, 0, 0, i4)
+        strsetitem(p3, i4, 120)     # == ord('x') == ord(mystr1)
+        i5 = int_add(i4, 1)      # will be killed by the backend
+        jump(p3)
+        """
+        self.optimize_loop(ops, 'Not', expected)
+
     def test_str_slice_1(self):
         ops = """
         [p1, i1, i2]



More information about the Pypy-commit mailing list