Author: Maciej Fijalkowski <[email protected]>
Branch: improve-consecutive-dict-lookups
Changeset: r70006:f6665773ece4
Date: 2014-03-14 17:33 +0200
http://bitbucket.org/pypy/pypy/changeset/f6665773ece4/
Log: start working on optimizing consecutive dict lookups
diff --git a/rpython/jit/codewriter/effectinfo.py
b/rpython/jit/codewriter/effectinfo.py
--- a/rpython/jit/codewriter/effectinfo.py
+++ b/rpython/jit/codewriter/effectinfo.py
@@ -21,6 +21,7 @@
OS_ARRAYCOPY = 1 # "list.ll_arraycopy"
OS_STR2UNICODE = 2 # "str.str2unicode"
OS_SHRINK_ARRAY = 3 # rgc.ll_shrink_array
+ OS_DICT_LOOKUP = 4 # ll_dict_lookup
#
OS_STR_CONCAT = 22 # "stroruni.concat"
OS_STR_SLICE = 23 # "stroruni.slice"
@@ -88,7 +89,7 @@
# for debugging:
_OS_CANRAISE = set([
OS_NONE, OS_STR2UNICODE, OS_LIBFFI_CALL, OS_RAW_MALLOC_VARSIZE_CHAR,
- OS_JIT_FORCE_VIRTUAL, OS_SHRINK_ARRAY,
+ OS_JIT_FORCE_VIRTUAL, OS_SHRINK_ARRAY, OS_DICT_LOOKUP,
])
def __new__(cls, readonly_descrs_fields, readonly_descrs_arrays,
diff --git a/rpython/jit/codewriter/jtransform.py
b/rpython/jit/codewriter/jtransform.py
--- a/rpython/jit/codewriter/jtransform.py
+++ b/rpython/jit/codewriter/jtransform.py
@@ -403,6 +403,8 @@
prepare = self._handle_math_sqrt_call
elif oopspec_name.startswith('rgc.'):
prepare = self._handle_rgc_call
+ elif oopspec_name == 'dict.lookup':
+ prepare = self._handle_dict_lookup_call
else:
prepare = self.prepare_builtin_call
try:
@@ -1848,6 +1850,10 @@
return self._handle_oopspec_call(op, args, EffectInfo.OS_MATH_SQRT,
EffectInfo.EF_ELIDABLE_CANNOT_RAISE)
+ def _handle_dict_lookup_call(self, op, oopspec_name, args):
+ return self._handle_oopspec_call(op, args, EffectInfo.OS_DICT_LOOKUP,
+ EffectInfo.EF_CAN_RAISE)
+
def _handle_rgc_call(self, op, oopspec_name, args):
if oopspec_name == 'rgc.ll_shrink_array':
return self._handle_oopspec_call(op, args,
EffectInfo.OS_SHRINK_ARRAY, EffectInfo.EF_CAN_RAISE)
diff --git a/rpython/jit/metainterp/optimizeopt/heap.py
b/rpython/jit/metainterp/optimizeopt/heap.py
--- a/rpython/jit/metainterp/optimizeopt/heap.py
+++ b/rpython/jit/metainterp/optimizeopt/heap.py
@@ -1,5 +1,6 @@
import os
+from rpython.jit.codewriter.effectinfo import EffectInfo
from rpython.jit.metainterp.history import Const
from rpython.jit.metainterp.jitexc import JitException
from rpython.jit.metainterp.optimizeopt.optimizer import Optimization,
MODE_ARRAY, LEVEL_KNOWNCLASS
@@ -168,6 +169,7 @@
self.cached_fields = {}
# cached array items: {array descr: {index: CachedField}}
self.cached_arrayitems = {}
+ self.cached_dict_reads = {}
#
self._lazy_setfields_and_arrayitems = []
self._remove_guard_not_invalidated = False
@@ -277,6 +279,20 @@
self.force_all_lazy_setfields_and_arrayitems()
self.clean_caches()
+ def optimize_CALL(self, op):
+ # dispatch based on 'oopspecindex' to a method that handles
+ # specifically the given oopspec call. For non-oopspec calls,
+ # oopspecindex is just zero.
+ effectinfo = op.getdescr().get_extra_info()
+ oopspecindex = effectinfo.oopspecindex
+ if oopspecindex == EffectInfo.OS_DICT_LOOKUP:
+ if self._optimize_CALL_DICT_LOOKUP(op):
+ return
+ self.emit_operation(op)
+
+ def _optimize_CALL_DICT_LOOKUP(self, op):
+ xxx
+
def force_from_effectinfo(self, effectinfo):
# XXX we can get the wrong complexity here, if the lists
# XXX stored on effectinfo are large
diff --git a/rpython/jit/metainterp/test/test_dict.py
b/rpython/jit/metainterp/test/test_dict.py
--- a/rpython/jit/metainterp/test/test_dict.py
+++ b/rpython/jit/metainterp/test/test_dict.py
@@ -193,6 +193,21 @@
self.check_simple_loop({'int_sub': 1, 'int_gt': 1, 'guard_true': 1,
'jump': 1})
+ def test_dict_two_lookups(self):
+ driver = JitDriver(greens = [], reds = 'auto')
+ d = {'a': 3, 'b': 4}
+ indexes = ['a', 'b']
+
+ def f(n):
+ s = 0
+ while n > 0:
+ driver.jit_merge_point()
+ s += d[indexes[n & 1]]
+ s += d[indexes[n & 1]]
+ n -= 1
+ return s
+
+ self.meta_interp(f, [10])
class TestLLtype(DictTests, LLJitMixin):
pass
diff --git a/rpython/rtyper/lltypesystem/rdict.py
b/rpython/rtyper/lltypesystem/rdict.py
--- a/rpython/rtyper/lltypesystem/rdict.py
+++ b/rpython/rtyper/lltypesystem/rdict.py
@@ -569,6 +569,7 @@
PERTURB_SHIFT = 5
@jit.look_inside_iff(lambda d, key, hash: jit.isvirtual(d) and
jit.isconstant(key))
[email protected]('dict.lookup(d, key, hash)')
def ll_dict_lookup(d, key, hash):
entries = d.entries
ENTRIES = lltype.typeOf(entries).TO
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit