[pypy-commit] pypy inline-dict-ops: start working on inlining of simple (non-looping) dict ops into assembler

fijal noreply at buildbot.pypy.org
Wed Jun 22 15:28:51 CEST 2011


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: inline-dict-ops
Changeset: r45053:04c0bfcc0891
Date: 2011-06-22 15:06 +0200
http://bitbucket.org/pypy/pypy/changeset/04c0bfcc0891/

Log:	start working on inlining of simple (non-looping) dict ops into
	assembler

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
@@ -698,14 +698,16 @@
     def rewrite_op_getinteriorfield(self, op):
         # only supports strings and unicodes
         assert len(op.args) == 3
-        assert op.args[1].value == 'chars'
-        optype = op.args[0].concretetype
-        if optype == lltype.Ptr(rstr.STR):
-            opname = "strgetitem"
+        if isinstance(op.args[1], Constant) and op.args[1].value == 'chars':
+            optype = op.args[0].concretetype
+            if optype == lltype.Ptr(rstr.STR):
+                opname = "strgetitem"
+            else:
+                assert optype == lltype.Ptr(rstr.UNICODE)
+                opname = "unicodegetitem"
+            return SpaceOperation(opname, [op.args[0], op.args[2]], op.result)
         else:
-            assert optype == lltype.Ptr(rstr.UNICODE)
-            opname = "unicodegetitem"
-        return SpaceOperation(opname, [op.args[0], op.args[2]], op.result)
+            return SpaceOperation('getinteriorfield', op.args[:], op.result)
 
     def rewrite_op_setinteriorfield(self, op):
         # only supports strings and unicodes
diff --git a/pypy/jit/codewriter/test/test_jtransform.py b/pypy/jit/codewriter/test/test_jtransform.py
--- a/pypy/jit/codewriter/test/test_jtransform.py
+++ b/pypy/jit/codewriter/test/test_jtransform.py
@@ -2,13 +2,13 @@
 import random
 from pypy.objspace.flow.model import FunctionGraph, Block, Link
 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, rlist
 from pypy.rpython.lltypesystem.module import ll_math
 from pypy.translator.unsimplify import varoftype
 from pypy.jit.codewriter import heaptracker, effectinfo
 from pypy.jit.codewriter.flatten import ListOfKind
+from pypy.jit.codewriter.jtransform import Transformer
+from pypy.jit.metainterp.history import getkind
 
 def const(x):
     return Constant(x, lltype.typeOf(x))
@@ -646,6 +646,17 @@
     assert op1.args == [v, v_index]
     assert op1.result == v_result
 
+def test_dict_getinteriorfield():
+    DICT = lltype.GcArray(lltype.Struct('ENTRY', ('v', lltype.Signed),
+                                        ('k', lltype.Signed)))
+    v = varoftype(DICT)
+    i = varoftype(lltype.Signed)
+    v_result = varoftype(lltype.Signed)
+    op = SpaceOperation('getinteriorfield', [v, i, Constant('v', lltype.Void)],
+                        v_result)
+    op1 = Transformer().rewrite_operation(op)
+    assert op1.opname == 'getinteriorfield'
+
 def test_str_setinteriorfield():
     v = varoftype(lltype.Ptr(rstr.STR))
     v_index = varoftype(lltype.Signed)
diff --git a/pypy/rpython/lltypesystem/rdict.py b/pypy/rpython/lltypesystem/rdict.py
--- a/pypy/rpython/lltypesystem/rdict.py
+++ b/pypy/rpython/lltypesystem/rdict.py
@@ -7,7 +7,7 @@
 from pypy.rlib.rarithmetic import r_uint, intmask, LONG_BIT
 from pypy.rlib.objectmodel import hlinvoke
 from pypy.rpython import robject
-from pypy.rlib import objectmodel, jit
+from pypy.rlib import objectmodel
 from pypy.rpython import rmodel
 
 HIGHEST_BIT = intmask(1 << (LONG_BIT - 1))
@@ -408,7 +408,6 @@
     ENTRIES = lltype.typeOf(entries).TO
     return ENTRIES.fasthashfn(entries[i].key)
 
- at jit.dont_look_inside
 def ll_get_value(d, i):
     return d.entries[i].value
 
@@ -439,7 +438,6 @@
     i = ll_dict_lookup(d, key, hash)
     return _ll_dict_setitem_lookup_done(d, key, value, hash, i)
 
- at jit.dont_look_inside
 def _ll_dict_setitem_lookup_done(d, key, value, hash, i):
     valid = (i & HIGHEST_BIT) == 0
     i = i & MASK
@@ -553,10 +551,17 @@
         freeslot = i
     else:
         return i | HIGHEST_BIT # pristine entry -- lookup failed
+    return _ll_dict_lookup_slowpath(d, key, hash, freeslot)
 
+def _ll_dict_lookup_slowpath(d, key, hash, freeslot):
     # In the loop, a deleted entry (everused and not valid) is by far
     # (factor of 100s) the least likely outcome, so test for that last.
     perturb = r_uint(hash) 
+    entries = d.entries
+    ENTRIES = lltype.typeOf(entries).TO
+    direct_compare = not hasattr(ENTRIES, 'no_direct_compare')
+    mask = len(entries) - 1
+    i = hash & mask
     while 1: 
         # compute the next index using unsigned arithmetic
         i = r_uint(i)


More information about the pypy-commit mailing list