[pypy-commit] pypy unroll-if-const: improve the situation where we do "%d" % num in RPython

fijal noreply at buildbot.pypy.org
Mon Jul 25 20:35:20 CEST 2011


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: unroll-if-const
Changeset: r45980:5b64d3250a30
Date: 2011-07-25 20:35 +0200
http://bitbucket.org/pypy/pypy/changeset/5b64d3250a30/

Log:	improve the situation where we do "%d" % num in RPython

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
@@ -920,21 +920,9 @@
         return string_repr.convert_const(s)
     ll_constant._annspecialcase_ = 'specialize:memo'
 
-    def do_stringformat(cls, hop, sourcevarsrepr):
-        s_str = hop.args_s[0]
-        assert s_str.is_constant()
-        s = s_str.const
-        things = cls.parse_fmt_string(s)
-        size = inputconst(Signed, len(things)) # could be unsigned?
-        cTEMP = inputconst(Void, TEMP)
-        cflags = inputconst(Void, {'flavor': 'gc'})
-        vtemp = hop.genop("malloc_varsize", [cTEMP, cflags, size],
-                          resulttype=Ptr(TEMP))
-
-        argsiter = iter(sourcevarsrepr)
-
+    @classmethod
+    def _stringformat_one_elem(cls, thing, argsiter, hop):
         InstanceRepr = hop.rtyper.type_system.rclass.InstanceRepr
-        for i, thing in enumerate(things):
             if isinstance(thing, tuple):
                 code = thing[0]
                 vitem, r_arg = argsiter.next()
@@ -962,12 +950,31 @@
             else:
                 from pypy.rpython.lltypesystem.rstr import string_repr
                 vchunk = inputconst(string_repr, thing)
+        return vchunk
+
+    @classmethod
+    def do_stringformat(cls, hop, sourcevarsrepr):
+        s_str = hop.args_s[0]
+        assert s_str.is_constant()
+        s = s_str.const
+        things = cls.parse_fmt_string(s)
+        size = inputconst(Signed, len(things)) # could be unsigned?
+        cTEMP = inputconst(Void, TEMP)
+        cflags = inputconst(Void, {'flavor': 'gc'})
+        argsiter = iter(sourcevarsrepr)
+
+        if len(things) == 1:
+            return cls._stringformat_one_elem(things[0], argsiter, hop)
+        vtemp = hop.genop("malloc_varsize", [cTEMP, cflags, size],
+                          resulttype=Ptr(TEMP))
+
+        for i, thing in enumerate(things):
             i = inputconst(Signed, i)
+            vchunk = cls._stringformat_one_elem(thing, argsiter, hop)
             hop.genop('setarrayitem', [vtemp, i, vchunk])
 
         hop.exception_cannot_occur()   # to ignore the ZeroDivisionError of '%'
         return hop.gendirectcall(cls.ll_join_strs, size, vtemp)
-    do_stringformat = classmethod(do_stringformat)
 
 TEMP = GcArray(Ptr(STR))
 
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
@@ -502,6 +502,11 @@
         res = self.interpret(moreThanOne, list(args))
         assert self.ll_to_string(res) == moreThanOne(*args)
 
+        def onething(a):
+            return const("%x" % a)
+        res = self.interpret(onething, [10])
+        assert self.ll_to_string(res) == onething(10)
+
     def test_strformat_nontuple(self):
         const = self.const
         def percentD(i):


More information about the pypy-commit mailing list