[pypy-svn] pypy default: merge heads
arigo
commits-noreply at bitbucket.org
Mon Apr 4 19:07:44 CEST 2011
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r43158:7cfdee10b79d
Date: 2011-04-04 17:07 +0000
http://bitbucket.org/pypy/pypy/changeset/7cfdee10b79d/
Log: merge heads
diff --git a/pypy/translator/backendopt/test/test_malloc.py b/pypy/translator/backendopt/test/test_malloc.py
--- a/pypy/translator/backendopt/test/test_malloc.py
+++ b/pypy/translator/backendopt/test/test_malloc.py
@@ -46,7 +46,7 @@
auto_inline_graphs(t, t.graphs, inline)
if option.view:
t.view()
- # to detect missing keepalives and broken intermediate graphs,
+ # to detect broken intermediate graphs,
# we do the loop ourselves instead of calling remove_simple_mallocs()
while True:
progress = remover.remove_mallocs_once(graph)
@@ -157,18 +157,6 @@
type_system = 'lltype'
MallocRemover = LLTypeMallocRemover
- def test_with_keepalive(self):
- from pypy.rlib.objectmodel import keepalive_until_here
- def fn1(x, y):
- if x > 0:
- t = x+y, x-y
- else:
- t = x-y, x+y
- s, d = t
- keepalive_until_here(t)
- return s*d
- self.check(fn1, [int, int], [15, 10], 125)
-
def test_dont_remove_with__del__(self):
import os
delcalls = [0]
@@ -198,50 +186,6 @@
op = graph.startblock.exits[0].target.exits[1].target.operations[0]
assert op.opname == "malloc"
- def test_add_keepalives(self):
- class A:
- pass
- SMALL = lltype.Struct('SMALL', ('x', lltype.Signed))
- BIG = lltype.GcStruct('BIG', ('z', lltype.Signed), ('s', SMALL))
- def fn7(i):
- big = lltype.malloc(BIG)
- a = A()
- a.big = big
- a.small = big.s
- a.small.x = 0
- while i > 0:
- a.small.x += i
- i -= 1
- return a.small.x
- self.check(fn7, [int], [10], 55, must_be_removed=False)
-
- def test_getsubstruct(self):
- py.test.skip("fails because of the interior structure changes")
- SMALL = lltype.Struct('SMALL', ('x', lltype.Signed))
- BIG = lltype.GcStruct('BIG', ('z', lltype.Signed), ('s', SMALL))
-
- def fn(n1, n2):
- b = lltype.malloc(BIG)
- b.z = n1
- b.s.x = n2
- return b.z - b.s.x
-
- self.check(fn, [int, int], [100, 58], 42)
-
- def test_fixedsizearray(self):
- py.test.skip("fails because of the interior structure changes")
- A = lltype.FixedSizeArray(lltype.Signed, 3)
- S = lltype.GcStruct('S', ('a', A))
-
- def fn(n1, n2):
- s = lltype.malloc(S)
- a = s.a
- a[0] = n1
- a[2] = n2
- return a[0]-a[2]
-
- self.check(fn, [int, int], [100, 42], 58)
-
def test_wrapper_cannot_be_removed(self):
SMALL = lltype.OpaqueType('SMALL')
BIG = lltype.GcStruct('BIG', ('z', lltype.Signed), ('s', SMALL))
diff --git a/pypy/rpython/memory/test/test_transformed_gc.py b/pypy/rpython/memory/test/test_transformed_gc.py
--- a/pypy/rpython/memory/test/test_transformed_gc.py
+++ b/pypy/rpython/memory/test/test_transformed_gc.py
@@ -13,7 +13,6 @@
from pypy.rlib import rgc
from pypy import conftest
from pypy.rlib.rstring import StringBuilder
-from pypy.rlib.objectmodel import keepalive_until_here
from pypy.rlib.rarithmetic import LONG_BIT
WORD = LONG_BIT // 8
diff --git a/pypy/translator/backendopt/test/test_support.py b/pypy/translator/backendopt/test/test_support.py
--- a/pypy/translator/backendopt/test/test_support.py
+++ b/pypy/translator/backendopt/test/test_support.py
@@ -1,94 +1,7 @@
-from pypy.translator.unsimplify import varoftype
from pypy.translator.translator import TranslationContext, graphof
from pypy.translator.backendopt.support import \
- needs_conservative_livevar_calculation, split_block_with_keepalive, \
find_loop_blocks, find_backedges, compute_reachability
-from pypy.rpython.rtyper import LowLevelOpList
-from pypy.rpython.lltypesystem import lltype
-from pypy.objspace.flow import model
-
-NonGcB = lltype.Struct("B", ('x', lltype.Signed))
-GcA = lltype.GcStruct("A", ('b', NonGcB), ('c', lltype.Ptr(lltype.FuncType([], lltype.Void))))
-
-def test_nclc_should_be_true():
- # this is testing a block like:
- # +--- inputargs: pointer_to_gc
- # | v0 <- op_getsubstruct pointer_to_gc 'b'
- # +--- exitargs: v0 (i.e. pointer to non-gc)
- llops = LowLevelOpList()
- ptr_a = varoftype(lltype.Ptr(GcA))
- v_res = llops.genop("getsubstruct", [ptr_a, model.Constant('b', lltype.Void)],
- resulttype=lltype.Ptr(NonGcB))
- block = model.Block([ptr_a])
- block.operations.extend(llops)
- block.closeblock(model.Link([v_res], None))
- assert needs_conservative_livevar_calculation(block)
-
-def test_nclc_nongc_not_passed_on():
- # +--- inputargs: pointer_to_gc
- # | v0 <- op_getsubstruct pointer_to_gc 'b'
- # +--- exitargs: pointer_to_gc (i.e. the pointer to non-gc doesn't leave the block)
- llops = LowLevelOpList()
- ptr_a = varoftype(lltype.Ptr(GcA))
- v_res = llops.genop("getsubstruct", [ptr_a, model.Constant('b', lltype.Void)],
- resulttype=lltype.Ptr(NonGcB))
- block = model.Block([ptr_a])
- block.operations.extend(llops)
- block.closeblock(model.Link([ptr_a], None))
- assert not needs_conservative_livevar_calculation(block)
-
-def test_nclc_ignore_functype():
- # +--- inputargs: pointer_to_gc
- # | v0 <- op_getfield pointer_to_gc 'c'
- # +--- exitargs: v0 (i.e. a pointer to function)
- # pointers to functions are 'not gc' but functions are also
- # immortal so you don't need to muck around inserting keepalives
- # so *they* don't die!
- llops = LowLevelOpList()
- ptr_a = varoftype(lltype.Ptr(GcA))
- v_res = llops.genop("getfield", [ptr_a, model.Constant('c', lltype.Void)],
- resulttype=GcA.c)
- block = model.Block([ptr_a])
- block.operations.extend(llops)
- block.closeblock(model.Link([v_res], None))
- assert not needs_conservative_livevar_calculation(block)
-
-def test_sbwk_should_insert_keepalives():
- # this is testing something like:
- # v0 <- op_producing_non_gc
- # v1 <- op_using_v0 <- split here
- llops = LowLevelOpList()
- ptr_a = varoftype(lltype.Ptr(GcA))
- v_res = llops.genop("getfield", [ptr_a, model.Constant('b', lltype.Void)],
- resulttype=lltype.Ptr(NonGcB))
- llops.genop("direct_call", [model.Constant(None, lltype.Void), v_res],
- resulttype=lltype.Void)
- block = model.Block([ptr_a])
- block.operations.extend(llops)
- block.closeblock(model.Link([], None))
- link = split_block_with_keepalive(block, 1)
- assert 'keepalive' in [op.opname for op in link.target.operations]
-
-def test_sbwk_should_insert_keepalives_2():
- # this is testing something like:
- # v0 <- op_producing_non_gc
- # v1 <- op_not_using_v0 <- split here
- # v2 <- op_using_v0
- llops = LowLevelOpList()
- ptr_a = varoftype(lltype.Ptr(GcA))
- v_res = llops.genop("getfield", [ptr_a, model.Constant('b', lltype.Void)],
- resulttype=lltype.Ptr(NonGcB))
- llops.genop("direct_call", [model.Constant(None, lltype.Void)],
- resulttype=lltype.Void)
- llops.genop("direct_call", [model.Constant(None, lltype.Void), v_res],
- resulttype=lltype.Void)
- block = model.Block([ptr_a])
- block.operations.extend(llops)
- block.closeblock(model.Link([], None))
- link = split_block_with_keepalive(block, 1)
- assert 'keepalive' in [op.opname for op in link.target.operations]
-
#__________________________________________________________
# test compute_reachability
diff --git a/pypy/translator/backendopt/test/test_constfold.py b/pypy/translator/backendopt/test/test_constfold.py
--- a/pypy/translator/backendopt/test/test_constfold.py
+++ b/pypy/translator/backendopt/test/test_constfold.py
@@ -185,27 +185,6 @@
check_graph(graph, [0], 61, t)
-def test_keepalive_const_substruct():
- py.test.skip("do we want partial folding of getinteriorfield?")
- S2 = lltype.Struct('S2', ('x', lltype.Signed))
- S1 = lltype.GcStruct('S1', ('sub', S2))
- s1 = lltype.malloc(S1)
- s1.sub.x = 1234
- def fn():
- return s1.sub.x
- graph, t = get_graph(fn, [])
- assert summary(graph) == {'getinteriorfield': 1}
- constant_fold_graph(graph)
-
- # kill all references to 's1'
- s1 = fn = None
- del graph.func
- import gc; gc.collect()
-
- assert summary(graph) == {'getfield': 1}
- check_graph(graph, [], 1234, t)
-
-
def test_keepalive_const_fieldptr():
S1 = lltype.GcStruct('S1', ('x', lltype.Signed))
s1 = lltype.malloc(S1)
diff --git a/pypy/rpython/memory/test/test_gc.py b/pypy/rpython/memory/test/test_gc.py
--- a/pypy/rpython/memory/test/test_gc.py
+++ b/pypy/rpython/memory/test/test_gc.py
@@ -8,7 +8,7 @@
from pypy.rpython.lltypesystem.rstr import STR
from pypy.rpython.lltypesystem.lloperation import llop
from pypy.rlib.objectmodel import we_are_translated
-from pypy.rlib.objectmodel import compute_unique_id, keepalive_until_here
+from pypy.rlib.objectmodel import compute_unique_id
from pypy.rlib import rgc
from pypy.rlib.rstring import StringBuilder
from pypy.rlib.rarithmetic import LONG_BIT
diff --git a/pypy/translator/backendopt/mallocprediction.py b/pypy/translator/backendopt/mallocprediction.py
--- a/pypy/translator/backendopt/mallocprediction.py
+++ b/pypy/translator/backendopt/mallocprediction.py
@@ -176,7 +176,6 @@
break
count += newcount
for graph in graphs:
- removenoops.remove_superfluous_keep_alive(graph)
removenoops.remove_duplicate_casts(graph, translator)
return count
diff --git a/pypy/translator/backendopt/inline.py b/pypy/translator/backendopt/inline.py
--- a/pypy/translator/backendopt/inline.py
+++ b/pypy/translator/backendopt/inline.py
@@ -13,7 +13,7 @@
from pypy.rpython import rmodel
from pypy.tool.algo import sparsemat
from pypy.translator.backendopt import removenoops
-from pypy.translator.backendopt.support import log, split_block_with_keepalive
+from pypy.translator.backendopt.support import log
from pypy.translator.unsimplify import split_block
from pypy.translator.backendopt.support import find_backedges, find_loop_blocks
from pypy.translator.backendopt.canraise import RaiseAnalyzer
@@ -280,13 +280,6 @@
self.varmap[var] = copyvar(None, var)
return self.varmap[var]
- def generate_keepalive(self, *args):
- from pypy.translator.backendopt.support import generate_keepalive
- if self.translator.rtyper.type_system.name == 'lltypesystem':
- return generate_keepalive(*args)
- else:
- return []
-
def passon_vars(self, cache_key):
if cache_key in self._passon_vars:
return self._passon_vars[cache_key]
@@ -397,7 +390,6 @@
for exceptionlink in afterblock.exits[1:]:
if exc_match(vtable, exceptionlink.llexitcase):
passon_vars = self.passon_vars(link.prevblock)
- copiedblock.operations += self.generate_keepalive(passon_vars)
copiedlink.target = exceptionlink.target
linkargs = self.find_args_in_exceptional_case(
exceptionlink, link.prevblock, var_etype, var_evalue, afterblock, passon_vars)
@@ -445,7 +437,6 @@
del blocks[-1].exits[0].llexitcase
linkargs = copiedexceptblock.inputargs
copiedexceptblock.recloseblock(Link(linkargs, blocks[0]))
- copiedexceptblock.operations += self.generate_keepalive(linkargs)
def do_inline(self, block, index_operation):
splitlink = split_block(None, block, index_operation)
@@ -457,11 +448,8 @@
# this copy is created with the method passon_vars
self.original_passon_vars = [arg for arg in block.exits[0].args
if isinstance(arg, Variable)]
- n = 0
- while afterblock.operations[n].opname == 'keepalive':
- n += 1
- assert afterblock.operations[n].opname == self.op.opname
- self.op = afterblock.operations.pop(n)
+ assert afterblock.operations[0].opname == self.op.opname
+ self.op = afterblock.operations.pop(0)
#vars that need to be passed through the blocks of the inlined function
linktoinlined = splitlink
copiedstartblock = self.copy_block(self.graph_to_inline.startblock)
@@ -551,7 +539,6 @@
OP_WEIGHTS = {'same_as': 0,
'cast_pointer': 0,
- 'keepalive': 0,
'malloc': 2,
'yield_current_frame_to_caller': sys.maxint, # XXX bit extreme
'resume_point': sys.maxint, # XXX bit extreme
@@ -784,5 +771,4 @@
call_count_pred=call_count_pred)
log.inlining('inlined %d callsites.'% (count,))
for graph in graphs:
- removenoops.remove_superfluous_keep_alive(graph)
removenoops.remove_duplicate_casts(graph, translator)
diff --git a/pypy/translator/backendopt/test/test_mallocv.py b/pypy/translator/backendopt/test/test_mallocv.py
--- a/pypy/translator/backendopt/test/test_mallocv.py
+++ b/pypy/translator/backendopt/test/test_mallocv.py
@@ -53,7 +53,7 @@
if option.view:
t.view()
self.original_graph_count = len(t.graphs)
- # to detect missing keepalives and broken intermediate graphs,
+ # to detect broken intermediate graphs,
# we do the loop ourselves instead of calling remove_simple_mallocs()
maxiter = 100
mallocv = MallocVirtualizer(t.graphs, t.rtyper, verbose=True)
@@ -556,36 +556,6 @@
type_system = 'lltype'
#MallocRemover = LLTypeMallocRemover
- def test_with_keepalive(self):
- from pypy.rlib.objectmodel import keepalive_until_here
- def fn1(x, y):
- if x > 0:
- t = x+y, x-y
- else:
- t = x-y, x+y
- s, d = t
- keepalive_until_here(t)
- return s*d
- self.check(fn1, [int, int], [15, 10], 125)
-
- def test_add_keepalives(self):
- class A:
- pass
- SMALL = lltype.Struct('SMALL', ('x', lltype.Signed))
- BIG = lltype.GcStruct('BIG', ('z', lltype.Signed), ('s', SMALL))
- def fn7(i):
- big = lltype.malloc(BIG)
- a = A()
- a.big = big
- a.small = big.s
- a.small.x = 0
- while i > 0:
- a.small.x += i
- i -= 1
- return a.small.x
- self.check(fn7, [int], [10], 55,
- expected_mallocs=1) # no support for interior structs
-
def test_getsubstruct(self):
SMALL = lltype.Struct('SMALL', ('x', lltype.Signed))
BIG = lltype.GcStruct('BIG', ('z', lltype.Signed), ('s', SMALL))
@@ -769,39 +739,6 @@
return x.u1.b * x.u2.a
self.check(fn, [], [], DONT_CHECK_RESULT)
- def test_keep_all_keepalives(self):
- SIZE = llmemory.sizeof(lltype.Signed)
- PARRAY = lltype.Ptr(lltype.FixedSizeArray(lltype.Signed, 1))
- class A:
- def __init__(self):
- self.addr = llmemory.raw_malloc(SIZE)
- def __del__(self):
- llmemory.raw_free(self.addr)
- class B:
- pass
- def myfunc():
- b = B()
- b.keep = A()
- b.data = llmemory.cast_adr_to_ptr(b.keep.addr, PARRAY)
- b.data[0] = 42
- ptr = b.data
- # normally 'b' could go away as early as here, which would free
- # the memory held by the instance of A in b.keep...
- res = ptr[0]
- # ...so we explicitly keep 'b' alive until here
- objectmodel.keepalive_until_here(b)
- return res
- graph = self.check(myfunc, [], [], 42,
- expected_mallocs=1, # 'A' instance left
- expected_calls=1) # to A.__init__()
-
- # there is a getarrayitem near the end of the graph of myfunc.
- # However, the memory it accesses must still be protected by the
- # following keepalive, even after malloc removal
- entrymap = mkentrymap(graph)
- [link] = entrymap[graph.returnblock]
- assert link.prevblock.operations[-1].opname == 'keepalive'
-
def test_nested_struct(self):
S = lltype.GcStruct("S", ('x', lltype.Signed))
T = lltype.GcStruct("T", ('s', S))
diff --git a/pypy/rpython/lltypesystem/rlist.py b/pypy/rpython/lltypesystem/rlist.py
--- a/pypy/rpython/lltypesystem/rlist.py
+++ b/pypy/rpython/lltypesystem/rlist.py
@@ -16,7 +16,6 @@
from pypy.rlib.debug import ll_assert
from pypy.rlib.rarithmetic import ovfcheck
from pypy.rpython.lltypesystem import rffi
-from pypy.rlib.objectmodel import keepalive_until_here
from pypy.rpython.lltypesystem.lloperation import llop
from pypy.rlib import rgc
diff --git a/pypy/translator/backendopt/mallocv.py b/pypy/translator/backendopt/mallocv.py
--- a/pypy/translator/backendopt/mallocv.py
+++ b/pypy/translator/backendopt/mallocv.py
@@ -846,22 +846,6 @@
else:
return self.handle_default(op)
- def handle_op_keepalive(self, op):
- node = self.getnode(op.args[0])
- if isinstance(node, VirtualSpecNode):
- rtnodes, vtnodes = find_all_nodes([node])
- newops = []
- for rtnode in rtnodes:
- v = self.renamings[rtnode]
- if isinstance(v, Variable):
- T = v.concretetype
- if isinstance(T, lltype.Ptr) and T._needsgc():
- v0 = varoftype(lltype.Void)
- newops.append(SpaceOperation('keepalive', [v], v0))
- return newops
- else:
- return self.handle_default(op)
-
def handle_op_ptr_nonzero(self, op):
node = self.getnode(op.args[0])
if isinstance(node, VirtualSpecNode):
diff --git a/pypy/translator/backendopt/support.py b/pypy/translator/backendopt/support.py
--- a/pypy/translator/backendopt/support.py
+++ b/pypy/translator/backendopt/support.py
@@ -39,74 +39,6 @@
# assume PyObjPtr
return True
-def needs_conservative_livevar_calculation(block):
- from pypy.rpython.lltypesystem import rclass
- vars = block.getvariables()
- assert len(block.exits) == 1
- exitingvars = block.exits[0].args
- for var in vars:
- TYPE = getattr(var, "concretetype", lltype.Ptr(lltype.PyObject))
- if isinstance(TYPE, lltype.Ptr) and not var_needsgc(var):
- if isinstance(TYPE.TO, lltype.FuncType):
- continue
- try:
- lltype.castable(TYPE, rclass.CLASSTYPE)
- except lltype.InvalidCast:
- if var in exitingvars:
- return True
- else:
- return False
-
-def generate_keepalive(vars, annotator=None):
- keepalive_ops = []
- for v in vars:
- if isinstance(v, Constant):
- continue
- if v.concretetype._is_atomic():
- continue
- v_keepalive = Variable()
- v_keepalive.concretetype = lltype.Void
- if annotator is not None:
- annotator.setbinding(v_keepalive, s_ImpossibleValue)
- keepalive_ops.append(SpaceOperation('keepalive', [v], v_keepalive))
- return keepalive_ops
-
-def split_block_with_keepalive(block, index_operation,
- keep_alive_op_args=True,
- annotator=None):
- splitlink = split_block(annotator, block, index_operation)
- afterblock = splitlink.target
- conservative_keepalives = needs_conservative_livevar_calculation(block)
- if conservative_keepalives:
- keep_alive_vars = [var for var in block.getvariables()
- if var_needsgc(var)]
- # XXX you could maybe remove more, if the variables are kept
- # alive by something else. but this is sometimes hard to know
- for i, var in enumerate(keep_alive_vars):
- try:
- index = splitlink.args.index(var)
- newvar = afterblock.inputargs[index]
- except ValueError:
- splitlink.args.append(var)
- newvar = copyvar(annotator, var)
- afterblock.inputargs.append(newvar)
- keep_alive_vars[i] = newvar
- elif keep_alive_op_args and afterblock.operations:
- keep_alive_vars = [var for var in afterblock.operations[0].args
- if isinstance(var, Variable) and var_needsgc(var)]
- if len(afterblock.operations) > 1 or afterblock.exitswitch != c_last_exception:
- afterblock.operations[1:1] = generate_keepalive(keep_alive_vars,
- annotator=annotator)
- keep_alive_vars = []
- else:
- keep_alive_vars = []
- pos = len(afterblock.operations)
- if afterblock.exitswitch == c_last_exception:
- pos -= 1 # insert the keepalives just before the last operation
- # in case of exception-catching
- afterblock.operations[pos:pos] = generate_keepalive(keep_alive_vars)
- return splitlink
-
def find_calls_from(translator, graph, memo=None):
if memo and graph in memo:
return memo[graph]
diff --git a/pypy/translator/backendopt/malloc.py b/pypy/translator/backendopt/malloc.py
--- a/pypy/translator/backendopt/malloc.py
+++ b/pypy/translator/backendopt/malloc.py
@@ -67,7 +67,6 @@
# in this 'block', follow where the 'var' goes to and replace
# it by a flattened-out family of variables. This family is given
# by newvarsmap, whose keys are the 'flatnames'.
- self.last_removed_access = None
def list_newvars():
return [newvarsmap[key] for key in self.flatnames]
@@ -115,7 +114,6 @@
newargs.append(arg)
link.args[:] = newargs
- self.insert_keepalives(list_newvars())
block.operations[:] = self.newops
def compute_lifetimes(self, graph):
@@ -211,7 +209,7 @@
STRUCT = self.get_STRUCT(lltypes.keys()[0])
# must be only ever accessed via getfield/setfield/getsubstruct/
- # direct_fieldptr, or touched by keepalive or ptr_iszero/ptr_nonzero.
+ # direct_fieldptr, or touched by ptr_iszero/ptr_nonzero.
# Note that same_as and cast_pointer are not recorded in usepoints.
self.accessed_substructs = {}
@@ -331,7 +329,6 @@
MALLOC_OP = "malloc"
FIELD_ACCESS = dict.fromkeys(["getfield",
"setfield",
- "keepalive",
"ptr_iszero",
"ptr_nonzero",
"getarrayitem",
@@ -482,7 +479,6 @@
[newvarsmap[key]],
op.result)
self.newops.append(newop)
- self.last_removed_access = len(self.newops)
elif op.opname in ("setfield", "setarrayitem"):
S = op.args[0].concretetype.TO
fldname = op.args[1].value
@@ -498,15 +494,12 @@
self.newops.append(newop)
else:
newvarsmap[key] = op.args[2]
- self.last_removed_access = len(self.newops)
elif op.opname in ("same_as", "cast_pointer"):
vars[op.result] = True
# Consider the two pointers (input and result) as
# equivalent. We can, and indeed must, use the same
# flattened list of variables for both, as a "setfield"
# via one pointer must be reflected in the other.
- elif op.opname == 'keepalive':
- self.last_removed_access = len(self.newops)
elif op.opname in ("getsubstruct", "getarraysubstruct",
"direct_fieldptr"):
S = op.args[0].concretetype.TO
@@ -544,18 +537,6 @@
else:
raise AssertionError, op.opname
-
- def insert_keepalives(self, newvars):
- if self.last_removed_access is not None:
- keepalives = []
- for v in newvars:
- T = v.concretetype
- if isinstance(T, lltype.Ptr) and T._needsgc():
- v0 = Variable()
- v0.concretetype = lltype.Void
- newop = SpaceOperation('keepalive', [v], v0)
- keepalives.append(newop)
- self.newops[self.last_removed_access:self.last_removed_access] = keepalives
class OOTypeMallocRemover(BaseMallocRemover):
@@ -614,14 +595,12 @@
[newvarsmap[key]],
op.result)
self.newops.append(newop)
- last_removed_access = len(self.newops)
elif op.opname == "oosetfield":
S = op.args[0].concretetype
fldname = op.args[1].value
key = self.key_for_field_access(S, fldname)
assert key in newvarsmap
newvarsmap[key] = op.args[2]
- last_removed_access = len(self.newops)
elif op.opname in ("same_as", "oodowncast", "ooupcast"):
vars[op.result] = True
# Consider the two pointers (input and result) as
@@ -637,8 +616,6 @@
else:
raise AssertionError, op.opname
- def insert_keepalives(self, newvars):
- pass
def remove_simple_mallocs(graph, type_system='lltypesystem', verbose=True):
if type_system == 'lltypesystem':
diff --git a/pypy/translator/backendopt/constfold.py b/pypy/translator/backendopt/constfold.py
--- a/pypy/translator/backendopt/constfold.py
+++ b/pypy/translator/backendopt/constfold.py
@@ -1,19 +1,16 @@
from pypy.objspace.flow.model import Constant, Variable, SpaceOperation
from pypy.objspace.flow.model import c_last_exception
from pypy.objspace.flow.model import mkentrymap
-from pypy.translator.backendopt.support import split_block_with_keepalive
from pypy.translator.backendopt.support import log
from pypy.translator.simplify import eliminate_empty_blocks
-from pypy.translator.unsimplify import insert_empty_block
+from pypy.translator.unsimplify import insert_empty_block, split_block
from pypy.rpython.lltypesystem.lloperation import llop
from pypy.rpython.lltypesystem import lltype
def fold_op_list(operations, constants, exit_early=False, exc_catch=False):
newops = []
- keepalives = []
folded_count = 0
- first_sideeffect_index = None
for spaceop in operations:
vargsmodif = False
vargs = []
@@ -29,10 +26,9 @@
try:
op = getattr(llop, spaceop.opname)
except AttributeError:
- sideeffects = True
+ pass
else:
- sideeffects = op.sideeffects
- if not sideeffects and len(args) == len(vargs):
+ if not op.sideeffects and len(args) == len(vargs):
RESTYPE = spaceop.result.concretetype
try:
result = op(RESTYPE, *args)
@@ -53,10 +49,6 @@
# failed to fold an operation, exit early if requested
if exit_early:
return folded_count
- if spaceop.opname == 'keepalive' and first_sideeffect_index is None:
- if vargsmodif:
- continue # keepalive(constant) is not useful
- keepalives.append(spaceop)
else:
if vargsmodif:
if (spaceop.opname == 'indirect_call'
@@ -66,20 +58,11 @@
else:
spaceop = SpaceOperation(spaceop.opname, vargs,
spaceop.result)
- if sideeffects and first_sideeffect_index is None:
- first_sideeffect_index = len(newops)
newops.append(spaceop)
# end
if exit_early:
return folded_count
else:
- # move the keepalives to the end of the block, which makes the life
- # of prepare_constant_fold_link() easier. Don't put them past the
- # exception-raising operation, though. There is also no point in
- # moving them past the first sideeffect-ing operation.
- if first_sideeffect_index is None:
- first_sideeffect_index = len(newops) - exc_catch
- newops[first_sideeffect_index:first_sideeffect_index] = keepalives
return newops
def constant_fold_block(block):
@@ -177,33 +160,23 @@
if block.exitswitch == c_last_exception:
n -= 1
# is the next, non-folded operation an indirect_call?
- m = folded_count
- while m < n and block.operations[m].opname == 'keepalive':
- m += 1
- if m < n:
- nextop = block.operations[m]
+ if folded_count < n:
+ nextop = block.operations[folded_count]
if nextop.opname == 'indirect_call' and nextop.args[0] in constants:
# indirect_call -> direct_call
callargs = [constants[nextop.args[0]]]
constants1 = constants.copy()
complete_constants(link, constants1)
- newkeepalives = []
- for i in range(folded_count, m):
- [v] = block.operations[i].args
- v = constants1.get(v, v)
- v_void = Variable()
- v_void.concretetype = lltype.Void
- newkeepalives.append(SpaceOperation('keepalive', [v], v_void))
for v in nextop.args[1:-1]:
callargs.append(constants1.get(v, v))
v_result = Variable(nextop.result)
v_result.concretetype = nextop.result.concretetype
constants[nextop.result] = v_result
callop = SpaceOperation('direct_call', callargs, v_result)
- newblock = insert_empty_block(None, link, newkeepalives + [callop])
+ newblock = insert_empty_block(None, link, [callop])
[link] = newblock.exits
assert link.target is block
- folded_count = m+1
+ folded_count += 1
if folded_count > 0:
splits = splitblocks.setdefault(block, [])
@@ -226,7 +199,7 @@
splitlink = block.exits[0]
else:
# split the block at the given position
- splitlink = split_block_with_keepalive(block, position)
+ splitlink = split_block(None, block, position)
assert list(block.exits) == [splitlink]
assert link.target is block
assert splitlink.prevblock is block
diff --git a/pypy/translator/test/test_simplify.py b/pypy/translator/test/test_simplify.py
--- a/pypy/translator/test/test_simplify.py
+++ b/pypy/translator/test/test_simplify.py
@@ -156,36 +156,6 @@
assert graph.startblock.operations[-1].opname == 'direct_call'
-def test_remove_pointless_keepalive():
- from pypy.rlib import objectmodel
- class C:
- y = None
- z1 = None
- z2 = None
-
- def g():
- return C()
-
- def f(i):
- c = g()
- c.y
- if i:
- n = c.z1
- else:
- n = c.z2
- objectmodel.keepalive_until_here(c, n)
-
- graph, t = translate(f, [bool])
-
- #t.view()
-
- for block in graph.iterblocks():
- for op in block.operations:
- assert op.opname != 'getfield'
- if op.opname == 'keepalive':
- assert op.args[0] in graph.getargs()
-
-
def test_remove_identical_variables():
def g(code):
pc = 0
diff --git a/pypy/translator/stackless/transform.py b/pypy/translator/stackless/transform.py
--- a/pypy/translator/stackless/transform.py
+++ b/pypy/translator/stackless/transform.py
@@ -2,7 +2,7 @@
from pypy.rpython.lltypesystem.lloperation import LL_OPERATIONS
from pypy.rlib import rarithmetic
from pypy.rpython import rclass, rmodel
-from pypy.translator.backendopt import support
+from pypy.translator.unsimplify import split_block
from pypy.objspace.flow import model
from pypy.translator import unsimplify, simplify
from pypy.translator.unsimplify import varoftype
@@ -598,7 +598,7 @@
link = block.exits[0]
nextblock = None
else:
- link = support.split_block_with_keepalive(block, i+1)
+ link = split_block(None, block, i+1)
i = 0
nextblock = link.target
@@ -765,7 +765,7 @@
exitcases = dict.fromkeys([l.exitcase for l in block.exits])
nextblock = None
else:
- link = support.split_block_with_keepalive(block, i+1)
+ link = split_block(None, block, i+1)
nextblock = link.target
block.exitswitch = model.c_last_exception
link.llexitcase = None
diff --git a/pypy/rpython/module/ll_os.py b/pypy/rpython/module/ll_os.py
--- a/pypy/rpython/module/ll_os.py
+++ b/pypy/rpython/module/ll_os.py
@@ -29,7 +29,7 @@
from pypy.rpython.lltypesystem.rstr import STR
from pypy.rpython.annlowlevel import llstr
from pypy.rlib import rgc
-from pypy.rlib.objectmodel import keepalive_until_here, specialize
+from pypy.rlib.objectmodel import specialize
def monkeypatch_rposix(posixfunc, unicodefunc, signature):
func_name = posixfunc.__name__
diff --git a/pypy/translator/unsimplify.py b/pypy/translator/unsimplify.py
--- a/pypy/translator/unsimplify.py
+++ b/pypy/translator/unsimplify.py
@@ -54,8 +54,7 @@
def split_block(annotator, block, index, _forcelink=None):
"""return a link where prevblock is the block leading up but excluding the
index'th operation and target is a new block with the neccessary variables
- passed on. NOTE: if you call this after rtyping, you WILL need to worry
- about keepalives, you may use backendopt.support.split_block_with_keepalive.
+ passed on.
"""
assert 0 <= index <= len(block.operations)
if block.exitswitch == c_last_exception:
diff --git a/pypy/jit/codewriter/test/test_regalloc.py b/pypy/jit/codewriter/test/test_regalloc.py
--- a/pypy/jit/codewriter/test/test_regalloc.py
+++ b/pypy/jit/codewriter/test/test_regalloc.py
@@ -9,7 +9,6 @@
from pypy.objspace.flow.model import c_last_exception
from pypy.rpython.lltypesystem import lltype, llmemory, rclass
from pypy.rlib.rarithmetic import ovfcheck
-from pypy.rlib.objectmodel import keepalive_until_here
class TestRegAlloc:
diff --git a/pypy/translator/backendopt/test/test_removenoops.py b/pypy/translator/backendopt/test/test_removenoops.py
--- a/pypy/translator/backendopt/test/test_removenoops.py
+++ b/pypy/translator/backendopt/test/test_removenoops.py
@@ -1,5 +1,5 @@
from pypy.translator.backendopt.removenoops import remove_same_as, \
- remove_unaryops, remove_duplicate_casts, remove_superfluous_keep_alive
+ remove_unaryops, remove_duplicate_casts
from pypy.translator.backendopt.inline import simple_inline_function
from pypy.translator.translator import TranslationContext, graphof
from pypy.rpython.memory.gctransform.test.test_transform import getops
@@ -115,20 +115,6 @@
result = interp.eval_graph(f_graph, [-2])
assert result == -1
-def test_remove_keepalive():
- S = lltype.GcStruct("s", ("f", lltype.Signed))
- def f():
- s1 = lltype.malloc(S)
- llop.keepalive(lltype.Void, s1)
- s2 = lltype.malloc(S)
- llop.keepalive(lltype.Void, s1)
- llop.keepalive(lltype.Void, s2)
- return lltype.cast_ptr_to_int(s1) + lltype.cast_ptr_to_int(s2)
- graph, t = get_graph(f, [])
- remove_superfluous_keep_alive(graph)
- ops = getops(graph)
- assert len(ops['keepalive']) == 2
-
def test_remove_duplicate_casts():
class A(object):
def __init__(self, x, y):
diff --git a/pypy/translator/exceptiontransform.py b/pypy/translator/exceptiontransform.py
--- a/pypy/translator/exceptiontransform.py
+++ b/pypy/translator/exceptiontransform.py
@@ -229,7 +229,6 @@
n_need_exc_matching_blocks += need_exc_matching
n_gen_exc_checks += gen_exc_checks
cleanup_graph(graph)
- removenoops.remove_superfluous_keep_alive(graph)
return n_need_exc_matching_blocks, n_gen_exc_checks
def replace_stack_unwind(self, block):
diff --git a/pypy/translator/backendopt/removenoops.py b/pypy/translator/backendopt/removenoops.py
--- a/pypy/translator/backendopt/removenoops.py
+++ b/pypy/translator/backendopt/removenoops.py
@@ -108,15 +108,3 @@
for i, op in list(enumerate(block.operations))[::-1]:
if op.opname == "debug_assert":
del block.operations[i]
-
-def remove_superfluous_keep_alive(graph):
- for block in graph.iterblocks():
- used = {}
- for i, op in list(enumerate(block.operations))[::-1]:
- if op.opname == "keepalive":
- if op.args[0] in used:
- del block.operations[i]
- else:
- used[op.args[0]] = True
-
-
More information about the Pypy-commit
mailing list