[pypy-commit] pypy result-in-resops: improve hashing, a bit tricky
fijal
noreply at buildbot.pypy.org
Wed Sep 26 14:37:02 CEST 2012
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: result-in-resops
Changeset: r57606:d60b8107bede
Date: 2012-09-26 13:38 +0200
http://bitbucket.org/pypy/pypy/changeset/d60b8107bede/
Log: improve hashing, a bit tricky
diff --git a/pypy/jit/metainterp/optimizeopt/pure.py b/pypy/jit/metainterp/optimizeopt/pure.py
--- a/pypy/jit/metainterp/optimizeopt/pure.py
+++ b/pypy/jit/metainterp/optimizeopt/pure.py
@@ -40,14 +40,13 @@
return
# did we do the exact same operation already?
- import pdb
- pdb.set_trace()
- oldop = self.pure_operations.get(op)
+ key_op = op.get_key_op(self.optimizer)
+ oldop = self.pure_operations.get(key_op)
if oldop is not None:
self.replace(op, oldop)
return
else:
- self.pure_operations.set(op, op)
+ self.pure_operations.set(key_op, op)
self.remember_emitting_pure(op)
# otherwise, the operation remains
@@ -68,7 +67,8 @@
self.last_emitted_operation = REMOVED
return
else:
- self.pure_operations.set(op, op)
+ new_op = op.copy_if_modified_by_optimization(self.optimizer)
+ self.pure_operations.set(new_op, op)
self.remember_emitting_pure(op)
# replace CALL_PURE with just CALL
@@ -98,6 +98,9 @@
@specialize.arg(2)
def pure(self, oldop, opnum, arg0, arg1=None):
+ arg0 = arg0.get_key_op(self.optimizer)
+ if arg1 is not None:
+ arg1 = arg1.get_key_op(self.optimizer)
result = example_for_opnum(opnum)
if arg1 is None:
op = create_resop_1(opnum, result, arg0)
diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py
--- a/pypy/jit/metainterp/optimizeopt/rewrite.py
+++ b/pypy/jit/metainterp/optimizeopt/rewrite.py
@@ -93,6 +93,7 @@
else:
self.emit_operation(op)
# Synthesize the reverse ops for optimize_default to reuse
+ self.pure(op.getarg(0), rop.INT_ADD, op.getarg(1), op)
self.pure(op.getarg(0), rop.INT_ADD, op, op.getarg(1))
self.pure(op.getarg(1), rop.INT_SUB, op.getarg(0), op)
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
@@ -3638,7 +3638,7 @@
def test_framestackdepth_overhead(self):
ops = """
[p0, i22]
- i1 = getfield_gc(p0, descr=valuedescr)
+ i1 = getfield_gc_i(p0, descr=valuedescr)
i2 = int_gt(i1, i22)
guard_false(i2) []
i3 = int_add(i1, 1)
@@ -3655,7 +3655,7 @@
"""
expected = """
[p0, i22]
- i1 = getfield_gc(p0, descr=valuedescr)
+ i1 = getfield_gc_i(p0, descr=valuedescr)
i2 = int_gt(i1, i22)
guard_false(i2) []
i3 = int_add(i1, 1)
diff --git a/pypy/jit/metainterp/optimizeopt/util.py b/pypy/jit/metainterp/optimizeopt/util.py
--- a/pypy/jit/metainterp/optimizeopt/util.py
+++ b/pypy/jit/metainterp/optimizeopt/util.py
@@ -94,7 +94,7 @@
# ____________________________________________________________
-BUCKET_SIZE = 1024
+BUCKET_SIZE = 8192
def new_args_set(has_value=False):
class ArgsSet(object):
@@ -124,6 +124,9 @@
if has_value:
def set(self, op, v):
hash = op._get_hash_() & self.bucket_size
+ if self.buckets[hash] is not None and not self.buckets[hash].eq(op):
+ import pdb
+ pdb.set_trace()
self.buckets[hash] = op # don't care about collisions
self.values[hash] = v
else:
@@ -148,6 +151,9 @@
def __repr__(self):
return 'ArgsSet(%s)' % ([item for item in self.buckets
if item is not None],)
+
+ def __len__(self):
+ return len([item for item in self.buckets if item is not None])
return ArgsSet
ArgsSet = new_args_set()
ArgsDict = new_args_set(True)
diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py
--- a/pypy/jit/metainterp/resoperation.py
+++ b/pypy/jit/metainterp/resoperation.py
@@ -244,6 +244,9 @@
def get_extra(self, key):
raise KeyError
+ def get_key_op(self, optimizer):
+ return self
+
def getkind(TYPE, supports_floats=True,
supports_longlong=True,
supports_singlefloats=True):
@@ -711,7 +714,7 @@
hash = (self.getopnum() ^
intmask(self.get_result_hash() << 4) ^
self.get_descr_hash() ^
- self.get_arg_hash())
+ intmask(self.get_arg_hash() << 1))
if hash == 0:
hash = -1
self._hash = hash
@@ -1089,6 +1092,9 @@
def copy_if_modified_by_optimization(self, opt):
return self
+ def get_key_op(self, opt):
+ return self
+
def get_arg_hash(self):
return 0
@@ -1129,6 +1135,14 @@
res.set_rd_snapshot(self.get_rd_snapshot())
return res
+ def get_key_op(self, opt):
+ new_arg = opt.getvalue(self._arg0).get_key_box()
+ if new_arg is self._arg0:
+ return self
+ res = create_resop_1(self.opnum, self.getresult(), new_arg,
+ self.getdescr())
+ return res
+
@specialize.arg(1)
def copy_and_change(self, newopnum=-1, arg0=None, descr=None):
if newopnum == -1:
@@ -1188,6 +1202,15 @@
res.set_rd_snapshot(self.get_rd_snapshot())
return res
+ @specialize.argtype(1)
+ def get_key_op(self, opt):
+ new_arg0 = opt.getvalue(self._arg0).get_key_box()
+ new_arg1 = opt.getvalue(self._arg1).get_key_box()
+ if new_arg0 is self._arg0 and new_arg1 is self._arg0:
+ return self
+ return create_resop_2(self.opnum, self.getresult(),
+ new_arg0, new_arg1, self.getdescr())
+
@specialize.arg(1)
def copy_and_change(self, newopnum=-1, arg0=None, arg1=None, descr=None):
if newopnum == -1:
@@ -1201,7 +1224,7 @@
return res
def get_arg_hash(self):
- return (intmask(self._arg0._get_hash_() << 1) ^
+ return (intmask(self._arg0._get_hash_() << 3) ^
self._arg1._get_hash_())
def args_eq(self, other):
@@ -1252,6 +1275,17 @@
new_arg2 or self._arg2,
self.getdescr())
+ @specialize.argtype(1)
+ def get_key_op(self, opt):
+ new_arg0 = opt.getvalue(self._arg0).get_key_box()
+ new_arg1 = opt.getvalue(self._arg1).get_key_box()
+ new_arg2 = opt.getvalue(self._arg2).get_key_box()
+ if (new_arg0 is self._arg0 and new_arg1 is self._arg1 and
+ new_arg2 is self._arg2):
+ return self
+ return create_resop_3(self.opnum, self.getresult(),
+ new_arg0, new_arg1, new_arg2, self.getdescr())
+
@specialize.arg(1)
def copy_and_change(self, newopnum=-1, arg0=None, arg1=None, arg2=None,
descr=None):
@@ -1264,8 +1298,8 @@
return r
def get_arg_hash(self):
- return (intmask(self._arg0._get_hash_() << 2) ^
- intmask(self._arg1._get_hash_() << 1) ^
+ return (intmask(self._arg0._get_hash_() << 5) ^
+ intmask(self._arg1._get_hash_() << 2) ^
self._arg2._get_hash_())
def args_eq(self, other):
@@ -1303,7 +1337,6 @@
newargs = newlist_hint(len(self._args))
for k in range(i):
newargs.append(self._args[k])
- self._args[:i]
newargs.append(new_arg)
elif newargs is not None:
newargs.append(arg)
@@ -1312,6 +1345,24 @@
return create_resop(self.opnum, self.getresult(),
newargs, self.getdescr())
+ @specialize.argtype(1)
+ def get_key_op(self, opt):
+ newargs = None
+ for i, arg in enumerate(self._args):
+ new_arg = opt.getvalue(arg).get_key_box()
+ if new_arg is not arg:
+ if newargs is None:
+ newargs = newlist_hint(len(self._args))
+ for k in range(i):
+ newargs.append(self._args[k])
+ newargs.append(new_arg)
+ elif newargs is not None:
+ newargs.append(arg)
+ if newargs is None:
+ return self
+ return create_resop(self.opnum, self.getresult(),
+ newargs, self.getdescr())
+
@specialize.arg(1)
def copy_and_change(self, newopnum=-1, newargs=None, descr=None):
if newopnum == -1:
@@ -1325,7 +1376,7 @@
def get_arg_hash(self):
hash = 0
for i, arg in enumerate(self._args):
- hash += intmask(arg._get_hash_() << (i & 15))
+ hash ^= intmask(arg._get_hash_() << (i & 15))
return hash
def args_eq(self, other):
More information about the pypy-commit
mailing list