Author: Antonio Cuni <[email protected]>
Branch: faster-rstruct-2
Changeset: r91376:1e87cd8c5f6c
Date: 2017-05-22 18:59 +0200
http://bitbucket.org/pypy/pypy/changeset/1e87cd8c5f6c/

Log:    implement the analyzer for gc_store_indexed

diff --git a/rpython/translator/backendopt/test/test_writeanalyze.py 
b/rpython/translator/backendopt/test/test_writeanalyze.py
--- a/rpython/translator/backendopt/test/test_writeanalyze.py
+++ b/rpython/translator/backendopt/test/test_writeanalyze.py
@@ -418,6 +418,10 @@
         result = wa.analyze(graph.startblock.operations[-1])
         return result
 
+    def _filter_reads(self, effects):
+        result = [item for item in effects if not item[0].startswith('read')]
+        return frozenset(result)
+
     def test_gc_load_indexed_str(self):
         from rpython.rlib.buffer import StringBuffer
 
@@ -476,3 +480,28 @@
             ('readarray', LIST.items),
         ])
         assert expected.issubset(typed_effects)
+
+    def test_gc_store_indexed_str(self):
+        from rpython.rlib.mutbuffer import MutableStringBuffer
+
+        def typed_write(buf):
+            return buf.typed_write(lltype.Signed, 0, 42)
+
+        def direct_write(buf):
+            return buf.setitem(0, 'A')
+
+        def f(x):
+            buf = MutableStringBuffer(8)
+            return direct_write(buf), typed_write(buf)
+
+        t, wa = self.translate(f, [str])
+        # check that the effect of direct_write
+        direct_effects = self._analyze_graph(t, wa, direct_write)
+        direct_effects = self._filter_reads(direct_effects)
+        assert direct_effects == frozenset([
+            ('interiorfield', lltype.Ptr(STR), 'chars')
+        ])
+        #
+        typed_effects = self._analyze_graph(t, wa, typed_write)
+        typed_effects = self._filter_reads(typed_effects)
+        assert typed_effects == direct_effects
diff --git a/rpython/translator/backendopt/writeanalyze.py 
b/rpython/translator/backendopt/writeanalyze.py
--- a/rpython/translator/backendopt/writeanalyze.py
+++ b/rpython/translator/backendopt/writeanalyze.py
@@ -63,7 +63,8 @@
                 name = self._getinteriorname(op)
                 return self._interiorfield_result(op.args[0].concretetype, 
name)
         elif op.opname == "gc_store_indexed":
-            assert False, 'implement me'
+            if graphinfo is None or not graphinfo.is_fresh_malloc(op.args[0]):
+                return self._gc_store_indexed_result(op)
         return empty_set
 
     def _array_result(self, TYPE):
@@ -72,6 +73,39 @@
     def _interiorfield_result(self, TYPE, fieldname):
         return frozenset([("interiorfield", TYPE, fieldname)])
 
+    def _gc_store_indexed_result(self, op):
+        base_ofs = op.args[4].value
+        effect = self._get_effect_for_offset(base_ofs)
+        return frozenset([effect])
+
+    def _get_effect_for_offset(self, ofs, prefix=''):
+        # gc_{load,store}_indexed are generic operation which operate on
+        # various data types: depending on the symbolic offset, they can be
+        # equivalent as reading/writing an array, and interiorfield, etc. The
+        # following logic tries to catch all the known usages. If you see an
+        # 'implement me', please update the logic accordingly
+        if isinstance(ofs, llmemory.CompositeOffset):
+            # get the effect for the first component and modify it if
+            # necessary
+            sub_offsets = ofs.offsets
+            effect = self._get_effect_for_offset(sub_offsets[0])
+            for sub_ofs in sub_offsets[1:]:
+                if isinstance(sub_ofs, llmemory.ArrayItemsOffset):
+                    # reading from the middle of an array is the same as
+                    # reading from the beginning, so we don't need to change
+                    # the effect
+                    pass
+                else:
+                    assert False, 'implement me'
+            return effect
+        elif isinstance(ofs, llmemory.FieldOffset):
+            T = ofs.TYPE
+            return (prefix + 'interiorfield', lltype.Ptr(T), ofs.fldname)
+        elif isinstance(ofs, llmemory.ArrayItemsOffset):
+            return (prefix + 'array', lltype.Ptr(ofs.TYPE))
+        else:
+            assert False, 'implement me'
+
     def compute_graph_info(self, graph):
         return FreshMallocs(graph)
 
@@ -129,35 +163,8 @@
             return self._gc_load_store_result(op)
         return WriteAnalyzer.analyze_simple_operation(self, op, graphinfo)
 
-    def _gc_load_store_result(self, op):
+    def _gc_load_indexed_result(self, op):
         base_offset = op.args[3].value
-        effect = self._get_effect_for_offset(base_offset)
+        effect = self._get_effect_for_offset(base_offset, prefix='read')
         return frozenset([effect])
 
-    def _get_effect_for_offset(self, ofs):
-        # gc_{load,store}_indexed are generic operation which operate on
-        # various data types: depending on the symbolic offset, they can be
-        # equivalent as reading/writing an array, and interiorfield, etc. The
-        # following logic tries to catch all the known usages. If you see an
-        # 'implement me', please update the logic accordingly
-        if isinstance(ofs, llmemory.CompositeOffset):
-            # get the effect for the first component and modify it if
-            # necessary
-            sub_offsets = ofs.offsets
-            effect = self._get_effect_for_offset(sub_offsets[0])
-            for sub_ofs in sub_offsets[1:]:
-                if isinstance(sub_ofs, llmemory.ArrayItemsOffset):
-                    # reading from the middle of an array is the same as
-                    # reading from the beginning, so we don't need to change
-                    # the effect
-                    pass
-                else:
-                    assert False, 'implement me'
-            return effect
-        elif isinstance(ofs, llmemory.FieldOffset):
-            T = ofs.TYPE
-            return ('readinteriorfield', lltype.Ptr(T), ofs.fldname)
-        elif isinstance(ofs, llmemory.ArrayItemsOffset):
-            return ('readarray', lltype.Ptr(ofs.TYPE))
-        else:
-            assert False, 'implement me'
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to