[pypy-svn] r69331 - in pypy/trunk/pypy/rpython/memory/gctransform: . test
fijal at codespeak.net
fijal at codespeak.net
Tue Nov 17 08:59:19 CET 2009
Author: fijal
Date: Tue Nov 17 08:59:18 2009
New Revision: 69331
Modified:
pypy/trunk/pypy/rpython/memory/gctransform/framework.py
pypy/trunk/pypy/rpython/memory/gctransform/test/test_framework.py
Log:
Implement write barrier shortcut for the case:
x = l[i]
l[j] = x
In which case we don't need a write barrier. To work correctly
with lists (as opposed to just GcArrays), it requires storesinking
on.
Modified: pypy/trunk/pypy/rpython/memory/gctransform/framework.py
==============================================================================
--- pypy/trunk/pypy/rpython/memory/gctransform/framework.py (original)
+++ pypy/trunk/pypy/rpython/memory/gctransform/framework.py Tue Nov 17 08:59:18 2009
@@ -52,7 +52,7 @@
# a bit of a hackish analysis: if a block contains a malloc and check that
# the result is not zero, then the block following the True link will
# usually initialize the newly allocated object
- result = {}
+ result = set()
def find_in_block(block, mallocvars):
for i, op in enumerate(block.operations):
if op.opname in ("cast_pointer", "same_as"):
@@ -63,7 +63,7 @@
if (op.args[0] in mallocvars and
isinstance(TYPE, lltype.Ptr) and
TYPE.TO._gckind == "gc"):
- result[op] = True
+ result.add(op)
else:
if collect_analyzer.analyze(op):
return
@@ -110,6 +110,20 @@
# print "found %s initializing stores in %s" % (len(result), graph.name)
return result
+def find_clean_setarrayitems(collect_analyzer, graph):
+ result = set()
+ for block in graph.iterblocks():
+ cache = set()
+ for op in block.operations:
+ if op.opname == 'getarrayitem':
+ cache.add((op.args[0], op.result))
+ elif op.opname == 'setarrayitem':
+ if (op.args[0], op.args[2]) in cache:
+ result.add(op)
+ elif collect_analyzer.analyze(op):
+ cache = set()
+ return result
+
class FrameworkGCTransformer(GCTransformer):
use_stackless = False
root_stack_depth = 163840
@@ -544,11 +558,12 @@
def transform_graph(self, graph):
if self.write_barrier_ptr:
- self.initializing_stores = find_initializing_stores(
- self.collect_analyzer, graph)
+ self.clean_sets = (
+ find_clean_setarrayitems(self.collect_analyzer, graph).union(
+ find_initializing_stores(self.collect_analyzer, graph)))
super(FrameworkGCTransformer, self).transform_graph(graph)
if self.write_barrier_ptr:
- self.initializing_stores = None
+ self.clean_sets = None
def gct_direct_call(self, hop):
if self.collect_analyzer.analyze(hop.spaceop):
@@ -879,7 +894,7 @@
if (self.write_barrier_ptr is not None
and not isinstance(v_newvalue, Constant)
and v_struct.concretetype.TO._gckind == "gc"
- and hop.spaceop not in self.initializing_stores):
+ and hop.spaceop not in self.clean_sets):
self.write_barrier_calls += 1
v_newvalue = hop.genop("cast_ptr_to_adr", [v_newvalue],
resulttype = llmemory.Address)
Modified: pypy/trunk/pypy/rpython/memory/gctransform/test/test_framework.py
==============================================================================
--- pypy/trunk/pypy/rpython/memory/gctransform/test/test_framework.py (original)
+++ pypy/trunk/pypy/rpython/memory/gctransform/test/test_framework.py Tue Nov 17 08:59:18 2009
@@ -5,13 +5,14 @@
rtype_and_transform
from pypy.rpython.memory.gctransform.transform import GcHighLevelOp
from pypy.rpython.memory.gctransform.framework import FrameworkGCTransformer, \
- CollectAnalyzer, find_initializing_stores
+ CollectAnalyzer, find_initializing_stores, find_clean_setarrayitems
from pypy.rpython.lltypesystem import lltype
from pypy.rpython.rtyper import LowLevelOpList
from pypy.translator.c.gc import FrameworkGcPolicy
from pypy.translator.translator import TranslationContext, graphof
from pypy.translator.unsimplify import varoftype
from pypy.translator.exceptiontransform import ExceptionTransformer
+from pypy.translator.backendopt.all import backend_optimizations
from pypy import conftest
import py
@@ -87,7 +88,7 @@
assert can_collect
class WriteBarrierTransformer(FrameworkGCTransformer):
- initializing_stores = {}
+ clean_sets = {}
GC_PARAMS = {}
class GCClass(MarkSweepGC):
needs_write_barrier = True
@@ -188,3 +189,88 @@
collect_analyzer = CollectAnalyzer(t)
init_stores = find_initializing_stores(collect_analyzer, t.graphs[0])
assert len(init_stores) == 5
+
+def test_find_clean_setarrayitems():
+ S = lltype.GcStruct('S')
+ A = lltype.GcArray(lltype.Ptr(S))
+
+ def f():
+ l = lltype.malloc(A, 3)
+ l[0] = lltype.malloc(S)
+ l[1] = lltype.malloc(S)
+ l[2] = lltype.malloc(S)
+ x = l[1]
+ l[0] = x
+ return len(l)
+
+ t = rtype(f, [])
+ etrafo = ExceptionTransformer(t)
+ graph = etrafo.transform_completely()
+ collect_analyzer = CollectAnalyzer(t)
+ clean_setarrayitems = find_clean_setarrayitems(collect_analyzer,
+ t.graphs[0])
+ assert len(clean_setarrayitems) == 1
+
+def test_find_clean_setarrayitems_2():
+ S = lltype.GcStruct('S')
+ A = lltype.GcArray(lltype.Ptr(S))
+
+ def f():
+ l = lltype.malloc(A, 3)
+ l[0] = lltype.malloc(S)
+ l[1] = lltype.malloc(S)
+ l[2] = lltype.malloc(S)
+ x = l[1]
+ l[2] = lltype.malloc(S) # <- this can possibly collect
+ l[0] = x
+ return len(l)
+
+ t = rtype(f, [])
+ etrafo = ExceptionTransformer(t)
+ graph = etrafo.transform_completely()
+ collect_analyzer = CollectAnalyzer(t)
+ clean_setarrayitems = find_clean_setarrayitems(collect_analyzer,
+ t.graphs[0])
+ assert len(clean_setarrayitems) == 0
+
+def test_find_clean_setarrayitems_3():
+ S = lltype.GcStruct('S')
+ A = lltype.GcArray(lltype.Ptr(S))
+
+ def f():
+ l = lltype.malloc(A, 3)
+ l[0] = lltype.malloc(S)
+ l[1] = lltype.malloc(S)
+ l[2] = lltype.malloc(S)
+ l2 = lltype.malloc(A, 4)
+ x = l[1]
+ l2[0] = x # <- different list
+ return len(l)
+
+ t = rtype(f, [])
+ etrafo = ExceptionTransformer(t)
+ graph = etrafo.transform_completely()
+ collect_analyzer = CollectAnalyzer(t)
+ clean_setarrayitems = find_clean_setarrayitems(collect_analyzer,
+ t.graphs[0])
+ assert len(clean_setarrayitems) == 0
+
+def test_list_operations():
+
+ class A(object):
+ pass
+
+ def f():
+ l = [A(), A()]
+ l.append(A())
+ l[1] = l[0]
+ return len(l)
+
+ t = rtype(f, [])
+ backend_optimizations(t, clever_malloc_removal=False, storesink=True)
+ etrafo = ExceptionTransformer(t)
+ graph = etrafo.transform_completely()
+ collect_analyzer = CollectAnalyzer(t)
+ clean_setarrayitems = find_clean_setarrayitems(collect_analyzer,
+ t.graphs[0])
+ assert len(clean_setarrayitems) == 1
More information about the Pypy-commit
mailing list