[pypy-svn] r9675 - in pypy/dist/pypy/objspace/flow: . test
arigo at codespeak.net
arigo at codespeak.net
Sun Mar 6 19:31:35 CET 2005
Author: arigo
Date: Sun Mar 6 19:31:35 2005
New Revision: 9675
Modified:
pypy/dist/pypy/objspace/flow/flowcontext.py
pypy/dist/pypy/objspace/flow/test/test_model.py
pypy/dist/pypy/objspace/flow/test/test_objspace.py
Log:
Removed a case where the flow objspace would repeat some operations: near the
beginning of the function.
Cleaned up the tests, which were too precise about the shape and generally not
precise enough about what's really in the graph.
Modified: pypy/dist/pypy/objspace/flow/flowcontext.py
==============================================================================
--- pypy/dist/pypy/objspace/flow/flowcontext.py (original)
+++ pypy/dist/pypy/objspace/flow/flowcontext.py Sun Mar 6 19:31:35 2005
@@ -71,32 +71,33 @@
self.crnt_block = block
# saved state at the join point most recently seen
self.last_join_point = None
- self.progress = False
+ self.enterspamblock = isinstance(block, SpamBlock)
def append(self, operation):
if self.last_join_point is not None:
- # don't add more operations if we already crossed a join point
+ # only add operations corresponding to the first bytecode
raise MergeBlock(self.crnt_block, self.last_join_point)
self.crnt_block.operations.append(operation)
def bytecode_trace(self, ec, frame):
assert frame is ec.crnt_frame, "seeing an unexpected frame!"
- next_instr = frame.next_instr
- if self.crnt_block.operations or isinstance(self.crnt_block, EggBlock):
- # if we have already produced at least one operation or a branch,
- # make a join point as early as possible (but not before we
- # actually try to generate more operations)
- self.last_join_point = FrameState(frame)
- else:
- ec.crnt_offset = next_instr # save offset for opcode
+ ec.crnt_offset = frame.next_instr # save offset for opcode
+ if self.enterspamblock:
+ # If we have a SpamBlock, the first call to bytecode_trace()
+ # occurs as soon as frame.resume() starts, before interpretation
+ # really begins.
varnames = frame.code.getvarnames()
for name, w_value in zip(varnames, frame.getfastscope()):
if isinstance(w_value, Variable):
w_value.rename(name)
- # record passage over already-existing join points
- if self.progress and next_instr in ec.joinpoints:
- self.last_join_point = FrameState(frame)
- self.progress = True
+ self.enterspamblock = False
+ else:
+ # At this point, we progress to the next bytecode. When this
+ # occurs, we no longer allow any more operations to be recorded in
+ # the same block. We will continue, to figure out where the next
+ # such operation *would* appear, and we make a join point just
+ # before.
+ self.last_join_point = FrameState(frame)
def guessbool(self, ec, w_condition, cases=[False,True],
replace_last_variable_except_in_first_case = None):
@@ -259,14 +260,27 @@
# EggBlocks reuse the variables of their previous block,
# which is deemed not acceptable for simplicity of the operations
# that will be performed later on the flow graph.
- def fixegg(node):
- if isinstance(node, EggBlock):
- mapping = {}
- for a in node.inputargs:
- mapping[a] = Variable(a)
- node.renamevariables(mapping)
- elif isinstance(node, SpamBlock):
- del node.framestate # memory saver
+ def fixegg(link):
+ if isinstance(link, Link):
+ block = link.target
+ if isinstance(block, EggBlock):
+ if (not block.operations and len(block.exits) == 1 and
+ link.args == block.inputargs): # not renamed
+ # if the variables are not renamed across this link
+ # (common case for EggBlocks) then it's easy enough to
+ # get rid of the empty EggBlock.
+ link2 = block.exits[0]
+ link.args = list(link2.args)
+ link.target = link2.target
+ assert link2.exitcase is None
+ fixegg(link)
+ else:
+ mapping = {}
+ for a in block.inputargs:
+ mapping[a] = Variable(a)
+ block.renamevariables(mapping)
+ elif isinstance(link, SpamBlock):
+ del link.framestate # memory saver
traverse(fixegg, self.graph)
def mergeblock(self, currentblock, currentstate):
Modified: pypy/dist/pypy/objspace/flow/test/test_model.py
==============================================================================
--- pypy/dist/pypy/objspace/flow/test/test_model.py (original)
+++ pypy/dist/pypy/objspace/flow/test/test_model.py Sun Mar 6 19:31:35 2005
@@ -24,9 +24,7 @@
def test_simplefunc(self):
graph = self.getflow(self.simplefunc)
- l = flatten(graph)
- #print l
- assert len(l) == 4
+ assert all_operations(graph) == {'add': 1}
def test_class(self):
graph = self.getflow(self.simplefunc)
@@ -45,32 +43,32 @@
v = MyVisitor()
traverse(v, graph)
- assert len(v.blocks) == 2
- assert len(v.links) == 1
+ #assert len(v.blocks) == 2
+ #assert len(v.links) == 1
assert v.graph == graph
assert v.links[0] == graph.startblock.exits[0]
- def test_partial_class(self):
- graph = self.getflow(self.simplefunc)
+## def test_partial_class(self):
+## graph = self.getflow(self.simplefunc)
- class MyVisitor:
- def __init__(self):
- self.blocks = []
- self.links = []
-
- def visit_FunctionGraph(self, graph):
- self.graph = graph
- def visit_Block(self, block):
- self.blocks.append(block)
- def visit(self, link):
- self.links.append(link)
-
- v = MyVisitor()
- traverse(v, graph)
- assert len(v.blocks) == 2
- assert len(v.links) == 1
- assert v.graph == graph
- assert v.links[0] == graph.startblock.exits[0]
+## class MyVisitor:
+## def __init__(self):
+## self.blocks = []
+## self.links = []
+
+## def visit_FunctionGraph(self, graph):
+## self.graph = graph
+## def visit_Block(self, block):
+## self.blocks.append(block)
+## def visit(self, link):
+## self.links.append(link)
+
+## v = MyVisitor()
+## traverse(v, graph)
+## assert len(v.blocks) == 2
+## assert len(v.links) == 1
+## assert v.graph == graph
+## assert v.links[0] == graph.startblock.exits[0]
def loop(x):
x = abs(x)
@@ -78,6 +76,18 @@
x = x - 1
def test_loop(self):
- graph = self.getflow(self.simplefunc)
- l = flatten(graph)
- assert len(l) == 4
+ graph = self.getflow(self.loop)
+ assert all_operations(graph) == {'simple_call': 1,
+ 'is_true': 1,
+ 'sub': 1}
+
+
+def all_operations(graph):
+ result = {}
+ def visit(node):
+ if isinstance(node, Block):
+ for op in node.operations:
+ result.setdefault(op.opname, 0)
+ result[op.opname] += 1
+ traverse(visit, graph)
+ return result
Modified: pypy/dist/pypy/objspace/flow/test/test_objspace.py
==============================================================================
--- pypy/dist/pypy/objspace/flow/test/test_objspace.py (original)
+++ pypy/dist/pypy/objspace/flow/test/test_objspace.py Sun Mar 6 19:31:35 2005
@@ -1,6 +1,7 @@
import autopath
from pypy.objspace.flow.model import Constant, Block, traverse
from pypy.interpreter.argument import Arguments
+from pypy.translator.simplify import simplify_graph
objspacename = 'flow'
@@ -256,6 +257,7 @@
def test_raise3(self):
x = self.codetest(self.raise3)
self.show(x)
+ simplify_graph(x)
assert len(x.startblock.operations) == 1
assert x.startblock.operations[0].opname == 'simple_call'
assert list(x.startblock.operations[0].args) == [
More information about the Pypy-commit
mailing list