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