[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