Author: Maciej Fijalkowski <[email protected]>
Branch: string-char-concat
Changeset: r59562:f95aaab180eb
Date: 2012-12-26 14:50 +0200
http://bitbucket.org/pypy/pypy/changeset/f95aaab180eb/

Log:    IN-PROGRESS string-char concat not upgrading char to string. Give up
        for now

diff --git a/pypy/jit/codewriter/effectinfo.py 
b/pypy/jit/codewriter/effectinfo.py
--- a/pypy/jit/codewriter/effectinfo.py
+++ b/pypy/jit/codewriter/effectinfo.py
@@ -23,26 +23,28 @@
     OS_STR2UNICODE              = 2    # "str.str2unicode"
     #
     OS_STR_CONCAT               = 22   # "stroruni.concat"
-    OS_STR_SLICE                = 23   # "stroruni.slice"
-    OS_STR_EQUAL                = 24   # "stroruni.equal"
-    OS_STREQ_SLICE_CHECKNULL    = 25   # s2!=NULL and s1[x:x+length]==s2
-    OS_STREQ_SLICE_NONNULL      = 26   # s1[x:x+length]==s2   (assert s2!=NULL)
-    OS_STREQ_SLICE_CHAR         = 27   # s1[x:x+length]==char
-    OS_STREQ_NONNULL            = 28   # s1 == s2    (assert s1!=NULL,s2!=NULL)
-    OS_STREQ_NONNULL_CHAR       = 29   # s1 == char  (assert s1!=NULL)
-    OS_STREQ_CHECKNULL_CHAR     = 30   # s1!=NULL and s1==char
-    OS_STREQ_LENGTHOK           = 31   # s1 == s2    (assert len(s1)==len(s2))
+    OS_STR_CONCAT_CHAR          = 23   # "stroruni.concatchar"
+    OS_STR_SLICE                = 24   # "stroruni.slice"
+    OS_STR_EQUAL                = 25   # "stroruni.equal"
+    OS_STREQ_SLICE_CHECKNULL    = 26   # s2!=NULL and s1[x:x+length]==s2
+    OS_STREQ_SLICE_NONNULL      = 27   # s1[x:x+length]==s2   (assert s2!=NULL)
+    OS_STREQ_SLICE_CHAR         = 28   # s1[x:x+length]==char
+    OS_STREQ_NONNULL            = 29   # s1 == s2    (assert s1!=NULL,s2!=NULL)
+    OS_STREQ_NONNULL_CHAR       = 30   # s1 == char  (assert s1!=NULL)
+    OS_STREQ_CHECKNULL_CHAR     = 31   # s1!=NULL and s1==char
+    OS_STREQ_LENGTHOK           = 32   # s1 == s2    (assert len(s1)==len(s2))
     #
     OS_UNI_CONCAT               = 42   #
-    OS_UNI_SLICE                = 43   #
-    OS_UNI_EQUAL                = 44   #
-    OS_UNIEQ_SLICE_CHECKNULL    = 45   #
-    OS_UNIEQ_SLICE_NONNULL      = 46   #
-    OS_UNIEQ_SLICE_CHAR         = 47   #
-    OS_UNIEQ_NONNULL            = 48   #   the same for unicode
-    OS_UNIEQ_NONNULL_CHAR       = 49   #   (must be the same amount as for
-    OS_UNIEQ_CHECKNULL_CHAR     = 50   #   STR, in the same order)
-    OS_UNIEQ_LENGTHOK           = 51   #
+    OS_UNI_CONCAT_CHAR          = 43   #
+    OS_UNI_SLICE                = 44   #
+    OS_UNI_EQUAL                = 45   #
+    OS_UNIEQ_SLICE_CHECKNULL    = 46   #
+    OS_UNIEQ_SLICE_NONNULL      = 47   #
+    OS_UNIEQ_SLICE_CHAR         = 48   #
+    OS_UNIEQ_NONNULL            = 49   #   the same for unicode
+    OS_UNIEQ_NONNULL_CHAR       = 50   #   (must be the same amount as for
+    OS_UNIEQ_CHECKNULL_CHAR     = 51   #   STR, in the same order)
+    OS_UNIEQ_LENGTHOK           = 52   #
     _OS_offset_uni              = OS_UNI_CONCAT - OS_STR_CONCAT
     #
     OS_LIBFFI_CALL              = 62
diff --git a/pypy/jit/codewriter/jtransform.py 
b/pypy/jit/codewriter/jtransform.py
--- a/pypy/jit/codewriter/jtransform.py
+++ b/pypy/jit/codewriter/jtransform.py
@@ -1651,6 +1651,7 @@
         SoU = args[0].concretetype     # Ptr(STR) or Ptr(UNICODE)
         if SoU.TO == rstr.STR:
             dict = {"stroruni.concat": EffectInfo.OS_STR_CONCAT,
+                    "stroruni.concatchar": EffectInfo.OS_STR_CONCAT_CHAR,
                     "stroruni.slice":  EffectInfo.OS_STR_SLICE,
                     "stroruni.equal":  EffectInfo.OS_STR_EQUAL,
                     }
diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py 
b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py
--- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py
+++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py
@@ -4099,6 +4099,23 @@
         """
         self.optimize_strunicode_loop(ops, expected)
 
+    def test_str_concat_char(self):
+        ops = """
+        [p1, i2]
+        p3 = call(0, p1, i2, descr=strconcatchardescr)
+        jump(p3, i2)
+        """
+        expected = """
+        [p1, i0]
+        i1 = strlen(p1)
+        i3 = int_add(i1, 1)
+        p3 = newstr(i3)
+        copystrcontent(p1, p3, 0, 0, i1)
+        strsetitem(p1, i1, i0)
+        jump(p3, i0)
+        """
+        self.optimize_strunicode_loop(ops, expected)
+
     def test_str_concat_vstr2_str(self):
         ops = """
         [i0, i1, p2]
diff --git a/pypy/jit/metainterp/optimizeopt/test/test_util.py 
b/pypy/jit/metainterp/optimizeopt/test/test_util.py
--- a/pypy/jit/metainterp/optimizeopt/test/test_util.py
+++ b/pypy/jit/metainterp/optimizeopt/test/test_util.py
@@ -210,6 +210,7 @@
 
     for _name, _os in [
         ('strconcatdescr',               'OS_STR_CONCAT'),
+        ('strconcatchardescr',           'OS_STR_CONCAT_CHAR'),
         ('strslicedescr',                'OS_STR_SLICE'),
         ('strequaldescr',                'OS_STR_EQUAL'),
         ('streq_slice_checknull_descr',  'OS_STREQ_SLICE_CHECKNULL'),
diff --git a/pypy/jit/metainterp/optimizeopt/vstring.py 
b/pypy/jit/metainterp/optimizeopt/vstring.py
--- a/pypy/jit/metainterp/optimizeopt/vstring.py
+++ b/pypy/jit/metainterp/optimizeopt/vstring.py
@@ -264,7 +264,6 @@
     def _make_virtual(self, modifier):
         return modifier.make_vstrconcat(self.mode is mode_unicode)
 
-
 class VStringSliceValue(VAbstractStringValue):
     """A slice."""
     _attrs_ = ('vstr', 'vstart', 'vlength')
diff --git a/pypy/rpython/lltypesystem/rstr.py 
b/pypy/rpython/lltypesystem/rstr.py
--- a/pypy/rpython/lltypesystem/rstr.py
+++ b/pypy/rpython/lltypesystem/rstr.py
@@ -316,6 +316,17 @@
     ll_strconcat.oopspec = 'stroruni.concat(s1, s2)'
 
     @jit.elidable
+    def ll_strconcat_char(s1, c2):
+        len1 = len(s1.chars)
+        # a single '+' like this is allowed to overflow: it gets
+        # a negative result, and the gc will complain
+        newstr = s1.malloc(len1 + 1)
+        newstr.copy_contents(s1, newstr, 0, 0, len1)
+        newstr.chars[len1] = c2
+        return newstr
+    ll_strconcat_char.oopspec = 'stroruni.concatchar(s1, c2)'
+
+    @jit.elidable
     def ll_strip(s, ch, left, right):
         s_len = len(s.chars)
         if s_len == 0:
diff --git a/pypy/rpython/rstr.py b/pypy/rpython/rstr.py
--- a/pypy/rpython/rstr.py
+++ b/pypy/rpython/rstr.py
@@ -542,6 +542,13 @@
         hop.exception_cannot_occur()
         return hop.gendirectcall(r_str.ll.ll_contains, v_str, v_chr)
 
+    def rtype_add((r_str, r_chr), hop):
+        string_repr = r_str.repr
+        char_repr = r_chr.char_repr
+        v_str, v_chr = hop.inputargs(string_repr, char_repr)
+        hop.exception_is_here()
+        return hop.gendirectcall(r_str.ll.ll_strconcat_char, v_str, v_chr)
+
 class __extend__(pairtype(AbstractStringRepr, AbstractTupleRepr)):
     def rtype_mod((r_str, r_tuple), hop):
         r_tuple = hop.args_r[1]
diff --git a/pypy/rpython/test/test_rstr.py b/pypy/rpython/test/test_rstr.py
--- a/pypy/rpython/test/test_rstr.py
+++ b/pypy/rpython/test/test_rstr.py
@@ -8,6 +8,7 @@
 from pypy.rpython.rstr import AbstractLLHelpers
 from pypy.rpython.rtyper import TyperError
 from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin
+from pypy.rpython.test.test_llinterp import get_interpreter
 
 
 def test_parse_fmt():
@@ -1098,6 +1099,17 @@
         res = self.interpret(f, [5])
         assert res == 0
 
+    def test_char_addition_does_not_promote(self):
+        const = self.const
+        constchar = self.constchar
+        
+        def f(n):
+            return const("abc") + constchar(n)
+
+        interp, graph = get_interpreter(f, [ord('a')])
+        opnames = [op.opname for op in graph.iterblocks().next().operations]
+        assert opnames.count('direct_call') == 1
+        assert self.ll_to_string(interp.eval_graph(graph, [ord('a')])) == 
"abca"
 
 class TestOOtype(BaseTestRstr, OORtypeMixin):
     pass
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to