[pypy-svn] r77331 - in pypy/branch/jit-str/pypy/jit/metainterp: . optimizeopt test

arigo at codespeak.net arigo at codespeak.net
Fri Sep 24 12:07:00 CEST 2010


Author: arigo
Date: Fri Sep 24 12:06:58 2010
New Revision: 77331

Modified:
   pypy/branch/jit-str/pypy/jit/metainterp/history.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/oparser.py
   pypy/branch/jit-str/pypy/jit/metainterp/test/test_optimizefindnode.py
   pypy/branch/jit-str/pypy/jit/metainterp/test/test_optimizeopt.py
Log:
Use prebuilt constant strings instead of generating
NEWSTR and a sequence of operations to build a constant
string at runtime.


Modified: pypy/branch/jit-str/pypy/jit/metainterp/history.py
==============================================================================
--- pypy/branch/jit-str/pypy/jit/metainterp/history.py	(original)
+++ pypy/branch/jit-str/pypy/jit/metainterp/history.py	Fri Sep 24 12:06:58 2010
@@ -685,6 +685,19 @@
         return llmemory.cast_adr_to_int(adr, "emulated")
     return i
 
+def get_const_ptr_for_string(s):
+    from pypy.rpython.annlowlevel import llstr
+    if not we_are_translated():
+        try:
+            return _const_ptr_for_string[s]
+        except KeyError:
+            pass
+    result = ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, llstr(s)))
+    if not we_are_translated():
+        _const_ptr_for_string[s] = result
+    return result
+_const_ptr_for_string = {}
+
 # ____________________________________________________________
 
 # The TreeLoop class contains a loop or a generalized loop, i.e. a tree

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 12:06:58 2010
@@ -12,6 +12,7 @@
 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
+from pypy.rpython import annlowlevel
 
 LEVEL_UNKNOWN    = '\x00'
 LEVEL_NONNULL    = '\x01'
@@ -127,10 +128,9 @@
         raise NotImplementedError
 
     def getstrlen(self, newoperations):
-        if self.is_constant():
-            s = self.box.getref(lltype.Ptr(rstr.STR))
-            length = len(s.chars)
-            return ConstInt(length)
+        s = self.get_constant_string()
+        if s is not None:
+            return ConstInt(len(s))
         else:
             self.ensure_nonnull()
             box = self.force_box()
@@ -138,6 +138,13 @@
             newoperations.append(ResOperation(rop.STRLEN, [box], lengthbox))
             return lengthbox
 
+    def get_constant_string(self):
+        if self.is_constant():
+            s = self.box.getref(lltype.Ptr(rstr.STR))
+            return annlowlevel.hlstr(s)
+        else:
+            return None
+
     def string_copy_parts(self, *args):
         from pypy.jit.metainterp.optimizeopt import virtualize
         return virtualize.default_string_copy_parts(self, *args)
@@ -150,6 +157,7 @@
 CONST_1      = ConstInt(1)
 CVAL_ZERO    = ConstantValue(CONST_0)
 CVAL_ZERO_FLOAT = ConstantValue(ConstFloat(0.0))
+CVAL_UNINITIALIZED_ZERO = ConstantValue(CONST_0)
 llhelper.CVAL_NULLREF = ConstantValue(llhelper.CONST_NULL)
 oohelper.CVAL_NULLREF = ConstantValue(oohelper.CONST_NULL)
 

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 12:06:58 2010
@@ -5,6 +5,7 @@
 from pypy.jit.metainterp.specnode import VirtualStructSpecNode
 from pypy.jit.metainterp.resoperation import rop, ResOperation
 from pypy.jit.metainterp.optimizeutil import _findall
+from pypy.jit.metainterp.history import get_const_ptr_for_string
 from pypy.rlib.objectmodel import we_are_translated
 from pypy.jit.metainterp.optimizeopt.optimizer import *
 from pypy.jit.codewriter.effectinfo import EffectInfo
@@ -199,6 +200,11 @@
 class VAbstractStringValue(AbstractVirtualValue):
 
     def _really_force(self):
+        s = self.get_constant_string()
+        if s is not None:
+            c_s = get_const_ptr_for_string(s)
+            self.make_constant(c_s)
+            return
         assert self.source_op is not None
         self.box = box = self.source_op.result
         newoperations = self.optimizer.newoperations
@@ -212,7 +218,7 @@
     _lengthbox = None     # cache only
 
     def setup(self, size):
-        self._chars = [CVAL_ZERO] * size
+        self._chars = [CVAL_UNINITIALIZED_ZERO] * size
 
     def getstrlen(self, _):
         if self._lengthbox is None:
@@ -226,6 +232,12 @@
         assert isinstance(charvalue, OptValue)
         self._chars[index] = charvalue
 
+    def get_constant_string(self):
+        for c in self._chars:
+            if c is CVAL_UNINITIALIZED_ZERO or not c.is_constant():
+                return None
+        return ''.join([chr(c.box.getint()) for c in self._chars])
+
     def string_copy_parts(self, newoperations, targetbox, offsetbox):
         for i in range(len(self._chars)):
             charbox = self._chars[i].force_box()
@@ -257,6 +269,15 @@
     def getstrlen(self, _):
         return self.lengthbox
 
+    def get_constant_string(self):
+        s1 = self.left.get_constant_string()
+        if s1 is None:
+            return None
+        s2 = self.right.get_constant_string()
+        if s2 is None:
+            return None
+        return s1 + s2
+
     def string_copy_parts(self, newoperations, targetbox, offsetbox):
         offsetbox = self.left.string_copy_parts(newoperations, targetbox,
                                                 offsetbox)
@@ -289,6 +310,16 @@
     def getstrlen(self, newoperations):
         return self.vlength.force_box()
 
+    def get_constant_string(self):
+        if self.vstart.is_constant() and self.vlength.is_constant():
+            s1 = self.vstr.get_constant_string()
+            if s1 is None:
+                return None
+            start = self.vstart.box.getint()
+            length = self.vlength.box.getint()
+            return s1[start : start + length]
+        return None
+
     def string_copy_parts(self, newoperations, targetbox, offsetbox):
         lengthbox = self.getstrlen(newoperations)
         return copy_str_content(newoperations,

Modified: pypy/branch/jit-str/pypy/jit/metainterp/test/oparser.py
==============================================================================
--- pypy/branch/jit-str/pypy/jit/metainterp/test/oparser.py	(original)
+++ pypy/branch/jit-str/pypy/jit/metainterp/test/oparser.py	Fri Sep 24 12:06:58 2010
@@ -5,13 +5,12 @@
 
 from pypy.jit.metainterp.history import TreeLoop, BoxInt, ConstInt,\
      ConstObj, ConstPtr, Box, BasicFailDescr, BoxFloat, ConstFloat,\
-     LoopToken
+     LoopToken, get_const_ptr_for_string
 from pypy.jit.metainterp.resoperation import rop, ResOperation
 from pypy.jit.metainterp.typesystem import llhelper
 from pypy.jit.codewriter.heaptracker import adr2int
 from pypy.rpython.lltypesystem import lltype, llmemory
 from pypy.rpython.ootypesystem import ootype
-from pypy.rpython.annlowlevel import llstr
 
 class ParseError(Exception):
     pass
@@ -145,8 +144,7 @@
             if arg.startswith('"') or arg.startswith("'"):
                 # XXX ootype
                 info = arg.strip("'\"")
-                return ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF,
-                                                       llstr(info)))
+                return get_const_ptr_for_string(info)
             if arg.startswith('ConstClass('):
                 name = arg[len('ConstClass('):-1]
                 return self.get_const(name, 'class')

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 12:06:58 2010
@@ -124,9 +124,6 @@
     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
     asmdescr = LoopToken() # it can be whatever, it's not a descr though

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 12:06:58 2010
@@ -4019,7 +4019,7 @@
     def test_str_concat_str_cstr1(self):
         ops = """
         [p2]
-        p3 = call(0, p2, ConstPtr(mystr1), descr=strconcatdescr)
+        p3 = call(0, p2, "x", descr=strconcatdescr)
         jump(p3)
         """
         expected = """
@@ -4029,12 +4029,28 @@
         p3 = newstr(i3)
         i4 = strlen(p2)
         copystrcontent(p2, p3, 0, 0, i4)
-        strsetitem(p3, i4, 120)     # == ord('x') == ord(mystr1)
+        strsetitem(p3, i4, 120)     # == ord('x')
         i5 = int_add(i4, 1)      # will be killed by the backend
         jump(p3)
         """
         self.optimize_loop(ops, 'Not', expected)
 
+    def test_str_concat_consts(self):
+        ops = """
+        []
+        p1 = same_as("ab")
+        p2 = same_as("cde")
+        p3 = call(0, p1, p2, descr=strconcatdescr)
+        escape(p3)
+        jump()
+        """
+        expected = """
+        []
+        escape("abcde")
+        jump()
+        """
+        self.optimize_loop(ops, '', expected)
+
     def test_str_slice_1(self):
         ops = """
         [p1, i1, i2]



More information about the Pypy-commit mailing list