Author: Maciej Fijalkowski <fij...@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 _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit