[pypy-commit] pypy recent-pure-ops: (fijal, arigo) in-progress
arigo
noreply at buildbot.pypy.org
Sat Feb 28 12:14:26 CET 2015
Author: Armin Rigo <arigo at tunes.org>
Branch: recent-pure-ops
Changeset: r76192:5954b774370c
Date: 2015-02-28 12:14 +0100
http://bitbucket.org/pypy/pypy/changeset/5954b774370c/
Log: (fijal, arigo) in-progress
diff --git a/rpython/jit/metainterp/optimizeopt/optimizer.py b/rpython/jit/metainterp/optimizeopt/optimizer.py
--- a/rpython/jit/metainterp/optimizeopt/optimizer.py
+++ b/rpython/jit/metainterp/optimizeopt/optimizer.py
@@ -721,6 +721,7 @@
if clear:
self.clear_newoperations()
for op in self.loop.operations:
+ self._really_emitted_operation = None
self.first_optimization.propagate_forward(op)
self.loop.operations = self.get_newoperations()
self.loop.quasi_immutable_deps = self.quasi_immutable_deps
@@ -773,9 +774,12 @@
op = self.store_final_boxes_in_guard(guard_op, pendingfields)
elif op.can_raise():
self.exception_might_have_happened = True
- self._last_emitted_op = orig_op
+ self._really_emitted_operation = op
self._newoperations.append(op)
+ def getlastop(self):
+ return self._really_emitted_operation
+
def get_op_replacement(self, op):
changed = False
for i, arg in enumerate(op.getarglist()):
diff --git a/rpython/jit/metainterp/optimizeopt/pure.py b/rpython/jit/metainterp/optimizeopt/pure.py
--- a/rpython/jit/metainterp/optimizeopt/pure.py
+++ b/rpython/jit/metainterp/optimizeopt/pure.py
@@ -1,12 +1,54 @@
from rpython.jit.metainterp.optimizeopt.optimizer import Optimization, REMOVED
from rpython.jit.metainterp.resoperation import rop, ResOperation
-from rpython.jit.metainterp.optimizeopt.util import (make_dispatcher_method,
- args_dict)
+from rpython.jit.metainterp.optimizeopt.util import make_dispatcher_method
+
+
+class RecentPureOps(object):
+ REMEMBER_LIMIT = 16
+
+ def __init__(self):
+ self.lst = [None] * self.REMEMBER_LIMIT
+ self.next_index = 0
+
+ def add(self, op):
+ next_index = self.next_index
+ self.next_index = (next_index + 1) % self.REMEMBER_LIMIT
+ self.lst[next_index] = op
+
+ def lookup1(self, box0):
+ for i in range(self.REMEMBER_LIMIT):
+ op = self.lst[i]
+ if op is None:
+ break
+ if op.getarg(0).same_box(box0):
+ return op
+ return None
+
+ def lookup2(self, box0, box1):
+ for i in range(self.REMEMBER_LIMIT):
+ op = self.lst[i]
+ if op is None:
+ break
+ if op.getarg(0).same_box(box0) and op.getarg(1).same_box(box1):
+ return op
+ return None
+
+ def lookup(self, optimizer, op):
+ numargs = op.numargs()
+ if numargs == 1:
+ return self.lookup1(optimizer.get_box_replacement(op.getarg(0)))
+ elif numargs == 2:
+ return self.lookup2(optimizer.get_box_replacement(op.getarg(0)),
+ optimizer.get_box_replacement(op.getarg(1)))
+ else:
+ assert False
+
class OptPure(Optimization):
def __init__(self):
self.postponed_op = None
- self.pure_operations = args_dict()
+ self._pure_operations = [None] * (rop._ALWAYS_PURE_LAST -
+ rop._ALWAYS_PURE_FIRST)
self.call_pure_positions = []
def propagate_forward(self, op):
@@ -39,20 +81,31 @@
return
# did we do the exact same operation already?
- args = self.optimizer.make_args_key(op)
- oldvalue = self.pure_operations.get(args, None)
- if oldvalue is not None:
- self.optimizer.make_equal_to(op.result, oldvalue, True)
+ recentops = self.getrecentops(op.getopnum())
+ oldop = recentops.lookup(self.optimizer, op)
+ if oldop is not None:
+ self.optimizer.make_equal_to(op.result, oldop.result, True)
return
# otherwise, the operation remains
self.emit_operation(op)
if op.returns_bool_result():
self.optimizer.bool_boxes[self.getvalue(op.result)] = None
+ if canfold:
+ realop = self.optimizer.getlastop()
+ if realop is not None:
+ recentops = self.getrecentops(realop.getopnum())
+ recentops.add(realop)
if nextop:
self.emit_operation(nextop)
- if args is not None:
- self.pure_operations[args] = self.getvalue(op.result)
+
+ def getrecentops(self, opnum):
+ opnum = opnum - rop._ALWAYS_PURE_FIRST
+ assert 0 <= opnum < len(self._pure_operations)
+ recentops = self._pure_operations[opnum]
+ if recentops is None:
+ self._pure_operations[opnum] = recentops = RecentPureOps()
+ return recentops
def optimize_CALL_PURE(self, op):
# Step 1: check if all arguments are constant
More information about the pypy-commit
mailing list