Author: Carl Friedrich Bolz <cfb...@gmx.de>
Branch: better-storesink
Changeset: r87164:d2cc6120b553
Date: 2016-09-09 18:54 +0200
http://bitbucket.org/pypy/pypy/changeset/d2cc6120b553/

Log:    constant-fold reads from immutable fields of constants

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
@@ -2,7 +2,7 @@
 
 from rpython.translator.backendopt import support
 from rpython.rtyper.lltypesystem.lloperation import llop
-from rpython.flowspace.model import mkentrymap, Variable
+from rpython.flowspace.model import mkentrymap, Variable, Constant
 from rpython.translator.backendopt import removenoops
 from rpython.translator import simplify
 from rpython.translator.backendopt import ssa
@@ -212,8 +212,19 @@
         for op in block.operations:
             # heap operations
             if op.opname == 'getfield':
-                tup = (representative_arg(op.args[0]), op.args[1].value)
-                res = self.heapcache.get(tup, None)
+                fieldname = op.args[1].value
+                arg0 = representative_arg(op.args[0])
+                res = None
+                if isinstance(arg0, Constant):
+                    PTRTYPE = arg0.concretetype.TO
+                    if PTRTYPE._immutable_field(fieldname).is_immutable:
+                        # can constant-fold:
+                        FIELDTYPE = getattr(PTRTYPE, fieldname)
+                        value = getattr(arg0.value, fieldname)
+                        res = Constant(value, FIELDTYPE)
+                if res is None:
+                    tup = (arg0, fieldname)
+                    res = self.heapcache.get(tup, None)
                 if res is not None:
                     op.opname = 'same_as'
                     op.args = [res]
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
@@ -374,6 +374,21 @@
             return res
         self.check(read, [int, int])
 
+    def test_immutable_getfield(self):
+        class A(object):
+            _immutable_fields_ = ['a']
+            def __init__(self, a):
+                self.a = a
+        a1 = A(5)
+        a2 = A(8)
+
+        def read(i):
+            if i:
+                return a1.a
+            return a2.a
+        self.check(read, [int], getfield=0)
+
+
 def fakevar(name='v'):
     var = Variable(name)
     var.concretetype = "fake concrete type"
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to