[pypy-commit] pypy optresult: an experiment in specialization
fijal
noreply at buildbot.pypy.org
Fri Jun 5 13:56:34 CEST 2015
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: optresult
Changeset: r77905:96d560350883
Date: 2015-06-05 13:56 +0200
http://bitbucket.org/pypy/pypy/changeset/96d560350883/
Log: an experiment in specialization
diff --git a/rpython/jit/backend/llsupport/rewrite.py b/rpython/jit/backend/llsupport/rewrite.py
--- a/rpython/jit/backend/llsupport/rewrite.py
+++ b/rpython/jit/backend/llsupport/rewrite.py
@@ -86,25 +86,12 @@
return op
def emit_op(self, op):
- op = self.get_box_replacement(op)
- orig_op = op
- # XXX specialize on number of args
- replaced = False
- for i in range(op.numargs()):
- orig_arg = op.getarg(i)
- arg = self.get_box_replacement(orig_arg)
- if orig_arg is not arg:
- if not replaced:
- op = op.copy_and_change(op.getopnum())
- orig_op.set_forwarded(op)
- replaced = True
- op.setarg(i, arg)
if op.is_guard():
- if not replaced:
- op = op.copy_and_change(op.getopnum())
- orig_op.set_forwarded(op)
- op.setfailargs([self.get_box_replacement(a, True)
- for a in op.getfailargs()])
+ op = op.copy_and_change(op.getopnum())
+ op = op.get_replacement_for_rewrite()
+ op.setfailargs([arg.get_replacement_for_rewrite() for arg in op.getfailargs()])
+ else:
+ op = op.get_replacement_for_rewrite()
self._newops.append(op)
def replace_op_with(self, op, newop):
diff --git a/rpython/jit/metainterp/history.py b/rpython/jit/metainterp/history.py
--- a/rpython/jit/metainterp/history.py
+++ b/rpython/jit/metainterp/history.py
@@ -204,6 +204,9 @@
def constbox(self):
return self
+ def get_replacement_for_rewrite(self):
+ return self
+
def same_box(self, other):
return self.same_constant(other)
diff --git a/rpython/jit/metainterp/resoperation.py b/rpython/jit/metainterp/resoperation.py
--- a/rpython/jit/metainterp/resoperation.py
+++ b/rpython/jit/metainterp/resoperation.py
@@ -24,6 +24,9 @@
def get_forwarded(self):
return None
+ def get_replacement(self):
+ return self
+
def set_forwarded(self, forwarded_to):
raise Exception("oups")
@@ -74,6 +77,11 @@
def get_forwarded(self):
return self._forwarded
+ def get_replacement(self):
+ if self._forwarded:
+ return self._forwarded
+ return self
+
def set_forwarded(self, forwarded_to):
self._forwarded = forwarded_to
@@ -419,6 +427,12 @@
def get_forwarded(self):
return self._forwarded
+ # this is for rewrite.py, we can have several versions depending on
+ # invariants
+ def get_replacement_for_rewrite(self):
+ assert self._forwarded is None
+ return self
+
def set_forwarded(self, forwarded_to):
self._forwarded = forwarded_to
@@ -464,6 +478,11 @@
def initarglist(self, args):
assert len(args) == 0
+ def get_replacement_for_rewrite(self):
+ if self._forwarded:
+ return self._forwarded
+ return self
+
def getarglist(self):
return []
@@ -485,6 +504,18 @@
assert len(args) == 1
self._arg0, = args
+ def get_replacement_for_rewrite(self):
+ if self._forwarded:
+ return self._forwarded.get_replacement_for_rewrite()
+ arg0 = self._arg0.get_replacement()
+ if arg0 is not self._arg0:
+ op = self.__class__()
+ if isinstance(self, ResOpWithDescr):
+ op.setdescr(self.getdescr())
+ op._arg0 = arg0
+ return op
+ return self
+
def getarglist(self):
return [self._arg0]
@@ -532,6 +563,20 @@
else:
raise IndexError
+ def get_replacement_for_rewrite(self):
+ if self._forwarded:
+ return self._forwarded.get_replacement_for_rewrite()
+ arg0 = self._arg0.get_replacement()
+ arg1 = self._arg1.get_replacement()
+ if arg0 is not self._arg0 or arg1 is not self._arg1:
+ op = self.__class__()
+ if isinstance(self, ResOpWithDescr):
+ op.setdescr(self.getdescr())
+ op._arg0 = arg0
+ op._arg1 = arg1
+ return op
+ return self
+
def getarglist(self):
return [self._arg0, self._arg1]
@@ -562,6 +607,23 @@
else:
raise IndexError
+ def get_replacement_for_rewrite(self):
+ if self._forwarded:
+ return self._forwarded.get_replacement_for_rewrite()
+ arg0 = self._arg0.get_replacement()
+ arg1 = self._arg1.get_replacement()
+ arg2 = self._arg2.get_replacement()
+ if (arg0 is not self._arg0 or arg1 is not self._arg1 or
+ arg2 is not self._arg2):
+ op = self.__class__()
+ if isinstance(self, ResOpWithDescr):
+ op.setdescr(self.getdescr())
+ op._arg0 = arg0
+ op._arg1 = arg1
+ op._arg2 = arg2
+ return op
+ return self
+
def setarg(self, i, box):
if i == 0:
self._arg0 = box
@@ -583,6 +645,20 @@
self.__class__.__name__.startswith('FINISH'): # XXX remove me
assert len(args) <= 1 # FINISH operations take 0 or 1 arg now
+ def get_replacement_for_rewrite(self):
+ if self._forwarded:
+ return self._forwarded.get_replacement_for_rewrite()
+ for arg in self._args:
+ if arg is not arg.get_replacement():
+ break
+ else:
+ return self
+ op = self.__class__()
+ op._args = [arg.get_replacement() for arg in self._args]
+ if isinstance(self, ResOpWithDescr):
+ op.setdescr(self.getdescr())
+ return op
+
def getarglist(self):
return self._args
More information about the pypy-commit
mailing list