[pypy-commit] pypy better-storesink: don't redo identical writes

cfbolz pypy.commits at gmail.com
Wed Oct 12 11:46:35 EDT 2016


Author: Carl Friedrich Bolz <cfbolz at gmx.de>
Branch: better-storesink
Changeset: r87726:323b0d19038a
Date: 2016-09-19 22:32 +0200
http://bitbucket.org/pypy/pypy/changeset/323b0d19038a/

Log:	don't redo identical writes

diff --git a/rpython/translator/backendopt/cse.py b/rpython/translator/backendopt/cse.py
--- a/rpython/translator/backendopt/cse.py
+++ b/rpython/translator/backendopt/cse.py
@@ -239,19 +239,28 @@
                 fieldname = op.args[1].value
                 concretetype = op.args[0].concretetype
                 arg0 = representative_arg(op.args[0])
-                tup = (arg0, op.args[0].concretetype, fieldname)
-                res = self.heapcache.get(tup, None)
+                key = (arg0, op.args[0].concretetype, fieldname)
+                res = self.heapcache.get(key, None)
                 if res is not None:
                     self._replace_with_result(op, res)
                     added_same_as += 1
                 else:
-                    self.heapcache[tup] = op.result
+                    self.heapcache[key] = op.result
                 continue
             if op.opname == 'setfield':
-                # XXX check whether value is the same already
                 concretetype = op.args[0].concretetype
                 target = representative_arg(op.args[0])
                 fieldname = op.args[1].value
+                key = (target, concretetype, fieldname)
+                res = self.heapcache.get(key, None)
+                if (res is not None and
+                        representative_arg(res) ==
+                                representative_arg(op.args[2])):
+                    # writing the same value that's already there
+                    op.opname = "same_as"
+                    op.args = [Constant("not needed setfield", lltype.Void)]
+                    added_same_as += 1
+                    continue
                 self._clear_heapcache_for(concretetype, fieldname)
                 self.heapcache[target, concretetype, fieldname] = op.args[2]
                 continue
diff --git a/rpython/translator/backendopt/test/test_cse.py b/rpython/translator/backendopt/test/test_cse.py
--- a/rpython/translator/backendopt/test/test_cse.py
+++ b/rpython/translator/backendopt/test/test_cse.py
@@ -531,6 +531,22 @@
             return res
         self.check(f, [int], getfield=3)
 
+    def test_remove_unnecessary_setfield(self):
+        class A(object):
+            pass
+        def f(i):
+            res = 0
+            x = i
+            a = A()
+            if i == 0:
+                a.x = 1
+                a.x = 1
+            else:
+                a.x = i
+                a.x = a.x
+                a.x = i
+        self.check(f, [int], setfield=3)
+
     def test_malloc_varsize_getarraysize(self):
         def f(i):
             if i == 1:


More information about the pypy-commit mailing list