[pypy-svn] r22000 - in pypy/dist/pypy/translator/backendopt: . test
cfbolz at codespeak.net
cfbolz at codespeak.net
Thu Jan 12 00:04:03 CET 2006
Author: cfbolz
Date: Thu Jan 12 00:04:01 2006
New Revision: 22000
Modified:
pypy/dist/pypy/translator/backendopt/escape.py
pypy/dist/pypy/translator/backendopt/test/test_escape.py
Log:
some small fixes to the adi. is now able to treat the whole rpystone - not sure
whether it produces useful info.
Modified: pypy/dist/pypy/translator/backendopt/escape.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/escape.py (original)
+++ pypy/dist/pypy/translator/backendopt/escape.py Thu Jan 12 00:04:01 2006
@@ -77,6 +77,7 @@
self.constant_cps = {} # const: creationpoint
self.dependencies = {} # creationpoint: {block: graph containing it}
self.functionargs = {} # graph: list of state of args
+ self.flown_blocks = {} # block: True
def getstate(self, var_or_const):
if not isonheap(var_or_const):
@@ -129,6 +130,7 @@
def flow_block(self, block, graph):
print "flowing in block %s of function %s" % (block, graph.name)
+ self.flown_blocks[block] = True
if block is graph.returnblock:
if isonheap(block.inputargs[0]):
changed = self.getstate(block.inputargs[0]).setescapes()
@@ -139,7 +141,7 @@
changed = self.getstate(block.inputargs[0]).setescapes()
self.handle_changed(changed)
if isonheap(block.inputargs[0]):
- changed = self.gestate(block.inputargs[1]).setescapes()
+ changed = self.getstate(block.inputargs[1]).setescapes()
self.handle_changed(changed)
return
self.curr_block = block
@@ -154,7 +156,9 @@
targetargs = self.getstates(exit.target.inputargs)
print " newargs", args
print " targetargs", targetargs
- if multicontains(targetargs, args):
+ # flow every block at least once:
+ if (multicontains(targetargs, args) and
+ exit.target in self.flown_blocks):
print " not necessary"
continue
else:
@@ -203,6 +207,7 @@
def register_state_dependency(self, state1, state2):
"state1 depends on state2: if state2 does escape/change, so does state1"
+ # change state1 according to how state2 is now
escapes = state2.does_escape()
if escapes and not state1.does_escape():
changed = state1.setescapes()
@@ -211,19 +216,26 @@
if changes and not state1:
changed = state1.setchanges()
self.handle_changed(changed)
+ # register a dependency of the current block on state2:
+ # that means that if state2 changes the current block will be reflown
+ # triggering this function again and thus updating state1
self.register_block_dependency(state2)
# _____________________________________________________________________
# operation implementations
- def malloc(self, op, type):
+ def malloc(self, op, typestate):
return VarState(self.get_creationpoint(op.result, "malloc"))
+ def malloc_varsize(self, op, typestate, lengthstate):
+ return VarState(self.get_creationpoint(op.result, "malloc_varsize"))
+
def cast_pointer(self, op, state):
return state
def setfield(self, op, objstate, fieldname, valuestate):
changed = objstate.setchanges()
+ self.handle_changed(changed)
if valuestate is not None:
# be pessimistic for now:
# everything that gets stored into a structure escapes and changes
@@ -233,15 +245,46 @@
changed = valuestate.setescapes()
self.handle_changed(changed)
return None
+
+ def setarrayitem(self, op, objstate, indexstate, valuestate):
+ changed = objstate.setchanges()
+ self.handle_changed(changed)
+ if valuestate is not None:
+ # everything that gets stored into a structure escapes and changes
+ self.handle_changed(changed)
+ changed = valuestate.setchanges()
+ self.handle_changed(changed)
+ changed = valuestate.setescapes()
+ self.handle_changed(changed)
+ return None
+
+ def getarrayitem(self, op, objstate, indexstate):
+ if isonheap(op.result):
+ return VarState(self.get_creationpoint(op.result, "getarrayitem"))
def getfield(self, op, objstate, fieldname):
if isonheap(op.result):
# assume that getfield creates a new value
return VarState(self.get_creationpoint(op.result, "getfield"))
+ def getsubstruct(self, op, objstate, fieldname):
+ # since this is really an embedded struct, it has the same
+ # state, the same creationpoints, etc.
+ return objstate
+
+ def getarraysize(self, op, arraystate):
+ pass
+
def direct_call(self, op, function, *args):
graph = get_graph(op.args[0], self.translation_context)
- result, funcargs = self.schedule_function(graph)
+ if graph is None:
+ if len(filter(None, args)):
+ raise NotImplementedError, "can't handle call %s" % (op, )
+ else:
+ result = None
+ funcargs = [None] * len(args)
+ else:
+ result, funcargs = self.schedule_function(graph)
assert len(args) == len(funcargs)
for localarg, funcarg in zip(args, funcargs):
if localarg is None:
@@ -267,8 +310,15 @@
# assume that a call creates a new value
return VarState(self.get_creationpoint(op.result, "indirect_call"))
- def ptr_iszero(self, op, ptr):
+ def ptr_iszero(self, op, ptrstate):
return None
+
+ cast_ptr_to_int = ptr_iszero
+
+ def same_as(self, op, objstate):
+ return objstate
+
+
def isonheap(var_or_const):
return isinstance(var_or_const.concretetype, lltype.Ptr)
Modified: pypy/dist/pypy/translator/backendopt/test/test_escape.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_escape.py (original)
+++ pypy/dist/pypy/translator/backendopt/test/test_escape.py Thu Jan 12 00:04:01 2006
@@ -245,3 +245,55 @@
a2crep = a2state.creation_points.keys()[0]
assert a1crep.changes and a2crep.changes
assert not a1crep.escapes and a2crep.escapes
+
+def test_getarray():
+ class A(object):
+ pass
+ def f():
+ a = A()
+ l = [None]
+ l[0] = a
+ t, adi, graph = build_adi(f, [])
+ avar = graph.startblock.operations[0].result
+ state = adi.getstate(avar)
+ assert len(state.creation_points) == 1
+ crep = state.creation_points.keys()[0]
+ assert crep.changes
+ assert crep.escapes
+
+def test_flow_blocksonce():
+ class A(object):
+ pass
+ def f():
+ a = 0
+ for i in range(10):
+ a += i
+ b = A()
+ b.x = 1
+ return b.x + 2
+ t, adi, graph = build_adi(f, [])
+ avar = graph.startblock.exits[0].target.exits[1].target.operations[0].result
+ state = adi.getstate(avar)
+ assert not state.does_escape()
+
+def test_call_external():
+ import time
+ def f():
+ return time.time()
+ #does not crash
+ t, adi, graph = build_adi(f, [])
+
+def test_getsubstruct():
+ def f(i):
+ s = "hello"
+ return s[i]
+ # does not crash
+ t, adi, graph = build_adi(f, [int])
+
+def test_big():
+ from pypy.translator.goal.targetrpystonex import make_target_definition
+ entrypoint, _, _ = make_target_definition(10)
+ # does not crash
+ t, adi, graph = build_adi(entrypoint, [int])
+
+
More information about the Pypy-commit
mailing list