[pypy-commit] pypy faster-rstruct-2: backout 85d3ab6fe80b, which was broken, and start to rewrite the logic in a more generic way. Also, write tests in such a way that we can check that gc_{load, store}_indexed produce effects corresponding to their equivalent
antocuni
pypy.commits at gmail.com
Mon May 22 13:03:49 EDT 2017
Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: faster-rstruct-2
Changeset: r91374:356dacc477eb
Date: 2017-05-22 18:30 +0200
http://bitbucket.org/pypy/pypy/changeset/356dacc477eb/
Log: backout 85d3ab6fe80b, which was broken, and start to rewrite the
logic in a more generic way. Also, write tests in such a way that we
can check that gc_{load,store}_indexed produce effects corresponding
to their equivalent
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
@@ -1,5 +1,7 @@
import py
-from rpython.rtyper.lltypesystem import lltype
+from rpython.rtyper.lltypesystem import lltype, llmemory
+from rpython.rtyper.lltypesystem.lloperation import llop
+from rpython.rtyper.lltypesystem.rstr import STR
from rpython.translator.translator import TranslationContext, graphof
from rpython.translator.backendopt.writeanalyze import WriteAnalyzer, top_set
from rpython.translator.backendopt.writeanalyze import ReadWriteAnalyzer
@@ -269,34 +271,6 @@
assert struct == "struct"
assert name.endswith("foobar")
- def test_gc_store_indexed(self):
- from rpython.rtyper.lltypesystem import lltype, llmemory
- from rpython.rtyper.lltypesystem.lloperation import llop
- from rpython.rlib.rgc import (resizable_list_supporting_raw_ptr,
- ll_for_resizable_list)
-
- def write_item(lst, byte_offset, value):
- ll_data = ll_for_resizable_list(lst)
- ll_items = ll_data.items
- LIST = lltype.typeOf(ll_data).TO # rlist.LIST_OF(lltype.Char)
- base_ofs = llmemory.itemoffsetof(LIST.items.TO, 0)
- scale_factor = llmemory.sizeof(lltype.Char)
- llop.gc_store_indexed(lltype.Void, ll_items, byte_offset, value,
- scale_factor, base_ofs)
-
- def f(x):
- lst = resizable_list_supporting_raw_ptr(['A', 'B', 'C', 'D'])
- write_item(lst, 0, 'E')
- t, wa = self.translate(f, [int])
- fgraph = graphof(t, f)
- result = wa.analyze(fgraph.startblock.operations[-1])
- #
- assert len(result) == 1
- array, A = list(result)[0]
- assert array == "array"
- assert A.TO.OF == lltype.Char
-
-
class TestLLtypeReadWriteAnalyze(BaseTest):
Analyzer = ReadWriteAnalyzer
@@ -433,3 +407,42 @@
res = list(result)
assert ('readinteriorfield', lltype.Ptr(A), 'y') in res
assert ('interiorfield', lltype.Ptr(A), 'x') in res
+
+
+class TestGcLoadStoreIndexed(BaseTest):
+ Analyzer = ReadWriteAnalyzer
+
+ def _analyze_graph_single(self, t, wa, fn):
+ graph = graphof(t, fn)
+ result = wa.analyze(graph.startblock.operations[-1])
+ result = list(result)
+ return result
+
+ def test_gc_load_indexed_str(self):
+ from rpython.rlib.buffer import StringBuffer
+
+ def typed_read(buf):
+ return buf.typed_read(lltype.Signed, 0)
+
+ def direct_read(buf):
+ return buf.value[0]
+
+ def f(x):
+ buf = StringBuffer(x)
+ return direct_read(buf), typed_read(buf)
+
+ t, wa = self.translate(f, [str])
+ # check that the effect of direct_read
+ direct_effects = self._analyze_graph_single(t, wa, direct_read)
+ assert len(direct_effects) == 1
+ effect = direct_effects[0]
+ what, T, field = effect
+ assert what == 'readinteriorfield'
+ assert T == lltype.Ptr(STR)
+ assert field == 'chars'
+ #
+ # typed_read contains many effects because it reads the vtable etc.,
+ # but we want to check that it contains also the same effect as
+ # direct_read
+ typed_effects = self._analyze_graph_single(t, wa, typed_read)
+ assert effect in typed_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
@@ -1,5 +1,6 @@
from rpython.flowspace.model import Variable, Constant
from rpython.translator.backendopt import graphanalyze
+from rpython.rtyper.lltypesystem import lltype, llmemory
top_set = object()
empty_set = frozenset()
@@ -62,8 +63,7 @@
name = self._getinteriorname(op)
return self._interiorfield_result(op.args[0].concretetype, name)
elif op.opname == "gc_store_indexed":
- if graphinfo is None or not graphinfo.is_fresh_malloc(op.args[0]):
- return self._array_result(op.args[0].concretetype)
+ assert False, 'implement me'
return empty_set
def _array_result(self, TYPE):
@@ -125,4 +125,37 @@
name = self._getinteriorname(op)
return frozenset([("readinteriorfield", op.args[0].concretetype,
name)])
+ elif op.opname == "gc_load_indexed":
+ return self._gc_load_store_result(op)
return WriteAnalyzer.analyze_simple_operation(self, op, graphinfo)
+
+ def _gc_load_store_result(self, op):
+ base_offset = op.args[3].value
+ effect = self._get_effect_for_offset(base_offset)
+ 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)
+ else:
+ assert False, 'implement me'
More information about the pypy-commit
mailing list