[pypy-svn] r63257 - in pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp: . test
arigo at codespeak.net
arigo at codespeak.net
Mon Mar 23 21:22:58 CET 2009
Author: arigo
Date: Mon Mar 23 21:22:55 2009
New Revision: 63257
Modified:
pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/compile.py
pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/history.py
pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/optimize.py
pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/pyjitpl.py
pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_basic.py
pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_loop.py
Log:
Make optimize.py pass again (first step).
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/compile.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/compile.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/compile.py Mon Mar 23 21:22:55 2009
@@ -5,7 +5,7 @@
from pypy.conftest import option
from pypy.jit.metainterp.resoperation import ResOperation, rop
-from pypy.jit.metainterp.history import Loop, log, Box
+from pypy.jit.metainterp.history import TreeLoop, log, Box
from pypy.jit.metainterp import optimize
@@ -101,7 +101,7 @@
name = 'Loop'
else:
name = 'Loop #%d' % len(metainterp.stats.loops)
- return Loop(name)
+ return TreeLoop(name)
# ____________________________________________________________
@@ -114,13 +114,14 @@
loop.inputargs = history.inputargs
loop.operations = history.operations
close_loop(loop, endliveboxes)
- #old_loop = optimize.optimize_loop(metainterp.options, old_loops, loop,
- # metainterp.cpu)
- #if old_loop is not None:
- # return old_loop
+ old_loop = optimize.optimize_loop(metainterp.options, old_loops, loop,
+ metainterp.cpu)
+ if old_loop is not None:
+ return old_loop
mark_keys_in_loop(loop, loop.operations)
send_loop_to_backend(metainterp, loop)
metainterp.stats.loops.append(loop)
+ metainterp.stats.compiled_count += 1
old_loops.append(loop)
return loop
@@ -164,4 +165,5 @@
guard_op.suboperations = history.operations
mark_keys_in_loop(source_loop, guard_op.suboperations)
send_loop_to_backend(metainterp, source_loop)
+ metainterp.stats.compiled_count += 1
return target_loop
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/history.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/history.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/history.py Mon Mar 23 21:22:55 2009
@@ -324,11 +324,11 @@
# ____________________________________________________________
-# The Loop class contains a loop or a generalized loop, i.e. a tree
+# The TreeLoop class contains a loop or a generalized loop, i.e. a tree
# of operations. Each branch ends in a jump which can go either to
-# the top of the same loop, or to another loop.
+# the top of the same loop, or to another TreeLoop.
-class Loop(object):
+class TreeLoop(object):
inputargs = None
specnodes = None
operations = None
@@ -340,18 +340,16 @@
# ops of the kind 'guard_xxx' contain a further list of operations,
# which may itself contain 'guard_xxx' and so on, making a tree.
- def _all_operations(self):
+ def _all_operations(self, omit_fails=False):
"NOT_RPYTHON"
- oplist = list(self.operations)
- for op in oplist:
- if op.is_guard():
- oplist += op.suboperations
- return oplist
+ result = []
+ _list_all_operations(result, self.operations, omit_fails)
+ return result
def summary(self, adding_insns={}): # for debugging
"NOT_RPYTHON"
insns = adding_insns.copy()
- for op in self._all_operations():
+ for op in self._all_operations(omit_fails=True):
opname = op.getopname()
insns[opname] = insns.get(opname, 0) + 1
return insns
@@ -392,11 +390,19 @@
seen[box] = True
assert operations[-1].is_final()
if operations[-1].opnum == rop.JUMP:
- assert isinstance(operations[-1].jump_target, Loop)
+ assert isinstance(operations[-1].jump_target, TreeLoop)
def __repr__(self):
return '<%s>' % (self.name,)
+def _list_all_operations(result, operations, omit_fails=True):
+ if omit_fails and operations[-1].opnum == rop.FAIL:
+ return
+ result.extend(operations)
+ for op in operations:
+ if op.is_guard():
+ _list_all_operations(result, op.suboperations, omit_fails)
+
# ____________________________________________________________
@@ -442,6 +448,7 @@
def __init__(self):
self.loops = []
+ self.compiled_count = 0
def get_all_loops(self):
return self.loops
@@ -452,9 +459,6 @@
opname = op.getopname()
insns[opname] = insns.get(opname, 0) + 1
if expected is not None:
- # 'fail' operations may be omitted from 'expected'
- if 'fail' in insns:
- expected.setdefault('fail', insns['fail'])
assert insns == expected
for insn, expected_count in check.items():
assert insns.get(insn, 0) == expected_count
@@ -465,9 +469,6 @@
for loop in self.loops:
insns = loop.summary(adding_insns=insns)
if expected is not None:
- # 'fail' operations may be omitted from 'expected'
- if 'fail' in insns:
- expected.setdefault('fail', insns['fail'])
assert insns == expected
for insn, expected_count in check.items():
assert insns.get(insn, 0) == expected_count
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/optimize.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/optimize.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/optimize.py Mon Mar 23 21:22:55 2009
@@ -279,17 +279,13 @@
def find_nodes(self):
# Steps (1) and (2)
self.first_escaping_op = True
- # only catch can have consts
- for box in self.loop.operations[0].args:
- self.nodes[box] = InstanceNode(box, escaped=False, startbox=True,
- const=isinstance(box, Const))
+ for box in self.loop.inputargs:
+ self.nodes[box] = InstanceNode(box, escaped=False, startbox=True)
for op in self.loop.operations:
#print '| ' + op.repr()
opnum = op.opnum
- if (opnum == rop.MERGE_POINT or
- opnum == rop.CATCH or
- opnum == rop.JUMP):
- continue
+ if opnum == rop.JUMP:
+ break
elif opnum == rop.NEW_WITH_VTABLE:
box = op.result
instnode = InstanceNode(box, escaped=False)
@@ -392,15 +388,15 @@
self.nodes[box] = InstanceNode(box, escaped=True)
def recursively_find_escaping_values(self):
- assert self.loop.operations[0].opnum == rop.MERGE_POINT
end_args = self.loop.operations[-1].args
+ assert len(self.loop.inputargs) == len(end_args)
memo = {}
for i in range(len(end_args)):
end_box = end_args[i]
if isinstance(end_box, Box):
self.nodes[end_box].escape_if_startbox(memo)
for i in range(len(end_args)):
- box = self.loop.operations[0].args[i]
+ box = self.loop.inputargs[i]
other_box = end_args[i]
if isinstance(other_box, Box):
self.nodes[box].add_to_dependency_graph(self.nodes[other_box],
@@ -418,13 +414,11 @@
def intersect_input_and_output(self):
# Step (3)
self.recursively_find_escaping_values()
- mp = self.loop.operations[0]
jump = self.loop.operations[-1]
- assert mp.opnum == rop.MERGE_POINT
assert jump.opnum == rop.JUMP
specnodes = []
- for i in range(len(mp.args)):
- enternode = self.nodes[mp.args[i]]
+ for i in range(len(self.loop.inputargs)):
+ enternode = self.nodes[self.loop.inputargs[i]]
leavenode = self.getnode(jump.args[i])
specnodes.append(enternode.intersect(leavenode, self.nodes))
self.specnodes = specnodes
@@ -439,7 +433,7 @@
specnode.expand_boxlist(self.nodes[box], newboxlist, oplist)
return newboxlist
- def prepare_rebuild_ops(self, instnode, liveboxes, rebuild_ops, memo):
+ def prepare_rebuild_ops(self, instnode, rebuild_ops, memo):
box = instnode.source
if not isinstance(box, Box):
return box
@@ -465,8 +459,7 @@
rebuild_ops.append(op)
memo[box] = newbox
for ofs, node in instnode.curfields.items():
- fieldbox = self.prepare_rebuild_ops(node, liveboxes,
- rebuild_ops, memo)
+ fieldbox = self.prepare_rebuild_ops(node, rebuild_ops, memo)
if isinstance(ld, FixedList):
op = ResOperation(rop.SETARRAYITEM_GC,
[newbox, ofs, fieldbox],
@@ -477,12 +470,10 @@
None, descr=ofs)
rebuild_ops.append(op)
return newbox
- liveboxes.append(box)
memo[box] = box
if instnode.virtualized:
for ofs, node in instnode.curfields.items():
- fieldbox = self.prepare_rebuild_ops(node, liveboxes,
- rebuild_ops, memo)
+ fieldbox = self.prepare_rebuild_ops(node, rebuild_ops, memo)
if instnode.cls and isinstance(instnode.cls.source, FixedList):
ld = instnode.cls.source
assert isinstance(ld, FixedList)
@@ -498,36 +489,33 @@
def optimize_guard(self, op):
# Make a list of operations to run to rebuild the unoptimized objects.
- # The ops assume that the Boxes in 'liveboxes' have been reloaded.
- liveboxes = []
rebuild_ops = []
memo = {}
- old_boxes = op.liveboxes
- op = op.clone()
+ assert len(op.suboperations) == 1
+ op_fail = op.suboperations[0]
+ assert op_fail.opnum == rop.FAIL
+ old_boxes = op.suboperations[0].args
unoptboxes = []
for box in old_boxes:
if isinstance(box, Const):
unoptboxes.append(box)
continue
unoptboxes.append(self.prepare_rebuild_ops(self.nodes[box],
- liveboxes, rebuild_ops,
- memo))
+ rebuild_ops, memo))
# XXX sloooooow!
for node in self.nodes.values():
if node.virtualized:
- self.prepare_rebuild_ops(node, liveboxes, rebuild_ops, memo)
+ self.prepare_rebuild_ops(node, rebuild_ops, memo)
# start of code for dirtyfields support
for node in self.nodes.values():
for ofs, subnode in node.dirtyfields.items():
box = node.source
if box not in memo and isinstance(box, Box):
- liveboxes.append(box)
memo[box] = box
#index = (rev_boxes[box] << FLAG_SHIFT) | FLAG_BOXES_FROM_FRAME
fieldbox = subnode.source
if fieldbox not in memo and isinstance(fieldbox, Box):
- liveboxes.append(fieldbox)
memo[fieldbox] = fieldbox
#fieldindex = ((rev_boxes[fieldbox] << FLAG_SHIFT) |
# FLAG_BOXES_FROM_FRAME)
@@ -546,15 +534,9 @@
rebuild_ops.append(op1)
# end of code for dirtyfields support
- if not we_are_translated():
- for box in liveboxes:
- assert isinstance(box, Box)
- assert len(dict.fromkeys(liveboxes)) == len(liveboxes)
-
- op.args = self.new_arguments(op)
- op.liveboxes = liveboxes
- op.rebuild_ops = rebuild_ops
- op.unoptboxes = unoptboxes
+ op_fail.args = unoptboxes
+ rebuild_ops.append(op_fail)
+ op.suboperations = rebuild_ops
return op
def new_arguments(self, op):
@@ -567,11 +549,6 @@
newboxes.append(box)
return newboxes
- def replace_arguments(self, op):
- op = op.clone()
- op.args = self.new_arguments(op)
- return op
-
def optimize_getfield(self, instnode, ofs, box):
assert isinstance(ofs, AbstractValue)
if instnode.virtual:
@@ -604,32 +581,26 @@
def optimize_loop(self):
newoperations = []
exception_might_have_happened = False
- mp = self.loop.operations[0]
- if mp.opnum == rop.MERGE_POINT:
- assert len(mp.args) == len(self.specnodes)
- for i in range(len(self.specnodes)):
- box = mp.args[i]
- self.specnodes[i].mutate_nodes(self.nodes[box])
- else:
- assert mp.opnum == rop.CATCH
- for box in mp.args:
- self.nodes[box].cls = None
- assert not self.nodes[box].virtual
+ assert len(self.loop.inputargs) == len(self.specnodes)
+ for i in range(len(self.specnodes)):
+ box = self.loop.inputargs[i]
+ self.specnodes[i].mutate_nodes(self.nodes[box])
+ newinputargs = self.expanded_version_of(self.loop.inputargs, None)
+
+## assert mp.opnum == rop.CATCH
+## for box in mp.args:
+## self.nodes[box].cls = None
+## assert not self.nodes[box].virtual
for op in self.loop.operations:
opnum = op.opnum
- if opnum == rop.MERGE_POINT:
- args = self.expanded_version_of(op.args, None)
- op = ResOperation(rop.MERGE_POINT, args, None)
- newoperations.append(op)
- continue
- elif opnum == rop.JUMP:
+ if opnum == rop.JUMP:
args = self.expanded_version_of(op.args, newoperations)
for arg in args:
if arg in self.nodes:
assert not self.nodes[arg].virtual
self.cleanup_field_caches(newoperations)
- op = ResOperation(rop.JUMP, args, None)
+ op.args = args
newoperations.append(op)
continue
elif opnum == rop.GUARD_NO_EXCEPTION:
@@ -753,7 +724,7 @@
self.nodes[box] = instnode
continue
# default handling of arguments and return value
- op = self.replace_arguments(op)
+ op.args = self.new_arguments(op)
if op.is_always_pure():
for box in op.args:
if isinstance(box, Box):
@@ -779,7 +750,8 @@
self.nodes[box] = instnode
newoperations.append(op)
- newoperations[0].specnodes = self.specnodes
+ self.loop.specnodes = self.specnodes
+ self.loop.inputargs = newinputargs
self.loop.operations = newoperations
def cleanup_field_caches(self, newoperations):
@@ -817,6 +789,7 @@
def match(self, old_operations):
old_mp = old_operations[0]
jump_op = self.loop.operations[-1]
+ assert old_op.opnum == rop.MERGE_POINT
assert jump_op.opnum == rop.JUMP
assert len(old_mp.specnodes) == len(jump_op.args)
for i in range(len(old_mp.specnodes)):
@@ -829,6 +802,8 @@
def adapt_for_match(self, old_operations):
old_mp = old_operations[0]
jump_op = self.loop.operations[-1]
+ assert old_op.opnum == rop.MERGE_POINT
+ assert jump_op.opnum == rop.JUMP
self.specnodes = old_mp.specnodes
for i in range(len(old_mp.specnodes)):
old_specnode = old_mp.specnodes[i]
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/pyjitpl.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/pyjitpl.py Mon Mar 23 21:22:55 2009
@@ -887,12 +887,10 @@
def get_residual_args(self, loop, args):
if loop.specnodes is None: # it is None only for tests
return args
- assert 0, "XXX fix me"
- # ---
- assert len(mp.specnodes) == len(args)
+ assert len(loop.specnodes) == len(args)
expanded_args = []
- for i in range(len(mp.specnodes)):
- specnode = mp.specnodes[i]
+ for i in range(len(loop.specnodes)):
+ specnode = loop.specnodes[i]
specnode.extract_runtime_data(self.cpu, args[i], expanded_args)
return expanded_args
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_basic.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_basic.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_basic.py Mon Mar 23 21:22:55 2009
@@ -29,9 +29,11 @@
def check_loops(self, expected=None, **check):
get_stats().check_loops(expected=expected, **check)
def check_loop_count(self, count):
+ assert get_stats().compiled_count == count
+ def check_tree_loop_count(self, count):
assert len(get_stats().loops) == count
def check_loop_count_at_most(self, count):
- assert len(get_stats().loops) <= count
+ assert get_stats().compiled_count <= count
def check_jumps(self, maxcount):
assert get_stats().exec_jumps <= maxcount
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_loop.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_loop.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_loop.py Mon Mar 23 21:22:55 2009
@@ -321,10 +321,9 @@
expected = f(100, 5)
res = self.meta_interp(f, [100, 5], policy=StopAtXPolicy(externfn))
assert res == expected
-
- loops = get_stats().loops
- assert loops[0].operations[0].opnum == rop.MERGE_POINT
- assert loops[1].operations[0].opnum == rop.CATCH
+
+ self.check_loop_count(2)
+ self.check_tree_loop_count(1)
def test_example(self):
myjitdriver = JitDriver(greens = ['i'],
More information about the Pypy-commit
mailing list