[pypy-svn] r68020 - in pypy/branch/kill-jumptarget/pypy/jit/metainterp: . test
arigo at codespeak.net
arigo at codespeak.net
Wed Sep 30 13:15:24 CEST 2009
Author: arigo
Date: Wed Sep 30 13:15:23 2009
New Revision: 68020
Modified:
pypy/branch/kill-jumptarget/pypy/jit/metainterp/compile.py
pypy/branch/kill-jumptarget/pypy/jit/metainterp/graphpage.py
pypy/branch/kill-jumptarget/pypy/jit/metainterp/history.py
pypy/branch/kill-jumptarget/pypy/jit/metainterp/optimize.py
pypy/branch/kill-jumptarget/pypy/jit/metainterp/optimizefindnode.py
pypy/branch/kill-jumptarget/pypy/jit/metainterp/optimizeopt.py
pypy/branch/kill-jumptarget/pypy/jit/metainterp/pyjitpl.py
pypy/branch/kill-jumptarget/pypy/jit/metainterp/resume.py
pypy/branch/kill-jumptarget/pypy/jit/metainterp/test/test_compile.py
pypy/branch/kill-jumptarget/pypy/jit/metainterp/test/test_optimizefindnode.py
pypy/branch/kill-jumptarget/pypy/jit/metainterp/test/test_optimizeopt.py
pypy/branch/kill-jumptarget/pypy/jit/metainterp/test/test_send.py
pypy/branch/kill-jumptarget/pypy/jit/metainterp/warmspot.py
Log:
Progress.
Modified: pypy/branch/kill-jumptarget/pypy/jit/metainterp/compile.py
==============================================================================
--- pypy/branch/kill-jumptarget/pypy/jit/metainterp/compile.py (original)
+++ pypy/branch/kill-jumptarget/pypy/jit/metainterp/compile.py Wed Sep 30 13:15:23 2009
@@ -33,6 +33,11 @@
name = metainterp.staticdata.stats.name_for_new_loop()
return TreeLoop(name)
+def make_loop_token(nb_args):
+ loop_token = LoopToken()
+ loop_token.specnodes = [prebuiltNotSpecNode] * nb_args
+ return loop_token
+
# ____________________________________________________________
def compile_new_loop(metainterp, old_loop_tokens, greenkey, start):
@@ -50,7 +55,9 @@
loop.operations = history.operations[start:]
else:
loop.operations = history.operations
- loop.operations[-1].jump_target = None
+ loop_token = make_loop_token(len(loop.inputargs))
+ loop.token = loop_token
+ loop.operations[-1].descr = loop_token # patch the target of the JUMP
metainterp_sd = metainterp.staticdata
try:
old_loop_token = metainterp_sd.state.optimize_loop(
@@ -61,12 +68,7 @@
if DEBUG > 0:
debug_print("reusing old loop")
return old_loop_token
- executable_token = send_loop_to_backend(metainterp_sd, loop, "loop")
- loop_token = LoopToken()
- loop_token.specnodes = loop.specnodes
- loop_token.executable_token = executable_token
- if not we_are_translated():
- loop.token = loop_token
+ send_loop_to_backend(metainterp_sd, loop, "loop")
insert_loop_token(old_loop_tokens, loop_token)
return loop_token
@@ -89,8 +91,7 @@
if not we_are_translated():
show_loop(metainterp_sd, loop)
loop.check_consistency()
- executable_token = metainterp_sd.cpu.compile_loop(loop.inputargs,
- loop.operations)
+ metainterp_sd.cpu.compile_loop(loop.inputargs, loop.operations, loop.token)
metainterp_sd.profiler.end_backend()
metainterp_sd.stats.add_new_loop(loop)
if not we_are_translated():
@@ -103,7 +104,6 @@
from pypy.jit.metainterp.pyjitpl import DEBUG
if DEBUG > 0:
debug_print("compiled new " + type)
- return executable_token
def send_bridge_to_backend(metainterp_sd, faildescr, inputargs, operations):
metainterp_sd.options.logger_ops.log_loop(inputargs, operations)
@@ -226,21 +226,19 @@
# with completely unoptimized arguments, as in the interpreter.
metainterp_sd = metainterp.staticdata
metainterp.history.inputargs = self.redkey
+ new_loop_token = make_loop_token(len(self.redkey))
new_loop.greenkey = self.original_greenkey
new_loop.inputargs = self.redkey
- executable_token = send_loop_to_backend(metainterp_sd, new_loop,
- "entry bridge")
+ new_loop.token = new_loop_token
+ send_loop_to_backend(metainterp_sd, new_loop, "entry bridge")
# send the new_loop to warmspot.py, to be called directly the next time
metainterp_sd.state.attach_unoptimized_bridge_from_interp(
self.original_greenkey,
- executable_token)
+ new_loop_token)
# store the new loop in compiled_merge_points too
glob = metainterp_sd.globaldata
greenargs = glob.unpack_greenkey(self.original_greenkey)
old_loop_tokens = glob.compiled_merge_points.setdefault(greenargs, [])
- new_loop_token = LoopToken()
- new_loop_token.specnodes = [prebuiltNotSpecNode] * len(self.redkey)
- new_loop_token.executable_token = executable_token
# it always goes at the end of the list, as it is the most
# general loop token
old_loop_tokens.append(new_loop_token)
@@ -280,11 +278,11 @@
op = new_loop.operations[-1]
if not isinstance(target_loop_token, TerminatingLoopToken):
# normal case
- op.jump_target = target_loop_token
+ op.descr = target_loop_token # patch the jump target
else:
# The target_loop_token is a pseudo loop token,
# e.g. loop_tokens_done_with_this_frame_void[0]
- # Replace the operation with the real operation we want, i.e. a FAIL.
+ # Replace the operation with the real operation we want, i.e. a FINISH
descr = target_loop_token.finishdescr
new_op = ResOperation(rop.FINISH, op.args, None, descr=descr)
new_loop.operations[-1] = new_op
Modified: pypy/branch/kill-jumptarget/pypy/jit/metainterp/graphpage.py
==============================================================================
--- pypy/branch/kill-jumptarget/pypy/jit/metainterp/graphpage.py (original)
+++ pypy/branch/kill-jumptarget/pypy/jit/metainterp/graphpage.py Wed Sep 30 13:15:23 2009
@@ -168,7 +168,7 @@
(graphindex, opindex))
break
if op.opnum == rop.JUMP:
- tgt = op.jump_target
+ tgt = op.descr
tgt_g = -1
if tgt is None:
tgt_g = graphindex
Modified: pypy/branch/kill-jumptarget/pypy/jit/metainterp/history.py
==============================================================================
--- pypy/branch/kill-jumptarget/pypy/jit/metainterp/history.py (original)
+++ pypy/branch/kill-jumptarget/pypy/jit/metainterp/history.py Wed Sep 30 13:15:23 2009
@@ -652,13 +652,14 @@
generated assembler.
"""
terminating = False # see TerminatingLoopToken in compile.py
- # specnodes
- # executable_token
+ # specnodes = ...
+ # and more data specified by the backend when the loop is compiled
class TreeLoop(object):
inputargs = None
- specnodes = None
operations = None
+ token = None
+ specnodes = property(lambda x: crash, lambda x, y: crash) # XXX temp
def __init__(self, name):
self.name = name
@@ -729,7 +730,7 @@
seen[box] = True
assert operations[-1].is_final()
if operations[-1].opnum == rop.JUMP:
- target = operations[-1].jump_target
+ target = operations[-1].descr
if target is not None:
assert isinstance(target, LoopToken)
@@ -802,6 +803,9 @@
def add_new_loop(self, loop):
pass
+ def view(self, **kwds):
+ pass
+
class Stats(object):
"""For tests."""
Modified: pypy/branch/kill-jumptarget/pypy/jit/metainterp/optimize.py
==============================================================================
--- pypy/branch/kill-jumptarget/pypy/jit/metainterp/optimize.py (original)
+++ pypy/branch/kill-jumptarget/pypy/jit/metainterp/optimize.py Wed Sep 30 13:15:23 2009
@@ -9,7 +9,7 @@
finder = PerfectSpecializationFinder(cpu)
finder.find_nodes_loop(loop)
for old_loop_token in old_loop_tokens:
- if equals_specnodes(old_loop_token.specnodes, loop.specnodes):
+ if equals_specnodes(old_loop_token.specnodes, loop.token.specnodes):
return old_loop_token
optimize_loop_1(cpu, loop)
return None
@@ -25,7 +25,7 @@
finder.find_nodes_bridge(bridge)
for old_loop_token in old_loop_tokens:
if finder.bridge_matches(old_loop_token.specnodes):
- bridge.operations[-1].jump_target = old_loop_token
+ bridge.operations[-1].descr = old_loop_token # patch jump target
optimize_bridge_1(cpu, bridge)
return old_loop_token
return None
Modified: pypy/branch/kill-jumptarget/pypy/jit/metainterp/optimizefindnode.py
==============================================================================
--- pypy/branch/kill-jumptarget/pypy/jit/metainterp/optimizefindnode.py (original)
+++ pypy/branch/kill-jumptarget/pypy/jit/metainterp/optimizefindnode.py Wed Sep 30 13:15:23 2009
@@ -299,7 +299,7 @@
for box in op.args:
self.getnode(box).set_unique_nodes()
- def find_nodes_FAIL(self, op):
+ def find_nodes_FINISH(self, op):
# only for bridges, and only for the ones that end in a 'return'
# or 'raise'; all other cases end with a JUMP.
for box in op.args:
@@ -337,7 +337,7 @@
inputnode = self.inputnodes[i]
exitnode = self.getnode(op.args[i])
specnodes.append(self.intersect(inputnode, exitnode))
- loop.specnodes = specnodes
+ loop.token.specnodes = specnodes
def intersect(self, inputnode, exitnode):
assert inputnode.fromstart
Modified: pypy/branch/kill-jumptarget/pypy/jit/metainterp/optimizeopt.py
==============================================================================
--- pypy/branch/kill-jumptarget/pypy/jit/metainterp/optimizeopt.py (original)
+++ pypy/branch/kill-jumptarget/pypy/jit/metainterp/optimizeopt.py Wed Sep 30 13:15:23 2009
@@ -458,7 +458,7 @@
def setup_virtuals_and_constants(self):
inputargs = self.loop.inputargs
- specnodes = self.loop.specnodes
+ specnodes = self.loop.token.specnodes
assert len(inputargs) == len(specnodes)
newinputargs = []
for i in range(len(inputargs)):
Modified: pypy/branch/kill-jumptarget/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/kill-jumptarget/pypy/jit/metainterp/pyjitpl.py (original)
+++ pypy/branch/kill-jumptarget/pypy/jit/metainterp/pyjitpl.py Wed Sep 30 13:15:23 2009
@@ -1428,7 +1428,7 @@
residual_args = self.get_residual_args(loop_token.specnodes,
gmp.argboxes[num_green_args:])
history.set_future_values(self.cpu, residual_args)
- return loop_token.executable_token
+ return loop_token
def prepare_resume_from_failure(self, opnum):
if opnum == rop.GUARD_TRUE: # a goto_if_not that jumps only now
Modified: pypy/branch/kill-jumptarget/pypy/jit/metainterp/resume.py
==============================================================================
--- pypy/branch/kill-jumptarget/pypy/jit/metainterp/resume.py (original)
+++ pypy/branch/kill-jumptarget/pypy/jit/metainterp/resume.py Wed Sep 30 13:15:23 2009
@@ -3,7 +3,7 @@
from pypy.jit.metainterp.resoperation import rop
# Logic to encode the chain of frames and the state of the boxes at a
-# FAIL operation, and to decode it again. This is a bit advanced,
+# guard operation, and to decode it again. This is a bit advanced,
# because it needs to support optimize.py which encodes virtuals with
# arbitrary cycles.
Modified: pypy/branch/kill-jumptarget/pypy/jit/metainterp/test/test_compile.py
==============================================================================
--- pypy/branch/kill-jumptarget/pypy/jit/metainterp/test/test_compile.py (original)
+++ pypy/branch/kill-jumptarget/pypy/jit/metainterp/test/test_compile.py Wed Sep 30 13:15:23 2009
@@ -1,6 +1,9 @@
-from pypy.jit.metainterp.history import LoopToken, ConstInt
+from pypy.jit.metainterp.history import LoopToken, ConstInt, History, Stats
from pypy.jit.metainterp.specnode import NotSpecNode, ConstantSpecNode
-from pypy.jit.metainterp.compile import insert_loop_token
+from pypy.jit.metainterp.compile import insert_loop_token, compile_new_loop
+from pypy.jit.metainterp import optimize, jitprof
+from pypy.jit.metainterp.test.oparser import parse
+from pypy.jit.metainterp.test.test_optimizefindnode import LLtypeMixin
def test_insert_loop_token():
@@ -20,3 +23,71 @@
tok3.specnodes = [ConstantSpecNode(ConstInt(-13))]
insert_loop_token(lst, tok3)
assert lst == [tok2, tok3, tok1]
+
+
+class FakeCPU:
+ def __init__(self):
+ self.seen = []
+ def compile_loop(self, inputargs, operations, token):
+ self.seen.append((inputargs, operations, token))
+
+class FakeLogger:
+ def log_loop(self, inputargs, operations):
+ pass
+
+class FakeOptions:
+ logger_noopt = FakeLogger()
+ logger_ops = FakeLogger()
+
+class FakeState:
+ optimize_loop = staticmethod(optimize.optimize_loop)
+
+class FakeMetaInterpStaticData:
+ options = FakeOptions()
+ state = FakeState()
+ stats = Stats()
+ profiler = jitprof.EmptyProfiler()
+
+class FakeMetaInterp:
+ pass
+
+def test_compile_new_loop():
+ cpu = FakeCPU()
+ staticdata = FakeMetaInterpStaticData()
+ staticdata.cpu = cpu
+ #
+ loop = parse('''
+ [p1]
+ i1 = getfield_gc(p1, descr=valuedescr)
+ i2 = int_add(i1, 1)
+ p2 = new_with_vtable(ConstClass(node_vtable))
+ setfield_gc(p2, i2, descr=valuedescr)
+ jump(p2)
+ ''', namespace=LLtypeMixin.__dict__.copy())
+ #
+ metainterp = FakeMetaInterp()
+ metainterp.staticdata = staticdata
+ metainterp.cpu = cpu
+ metainterp.history = History(metainterp.cpu)
+ metainterp.history.operations = loop.operations[:]
+ metainterp.history.inputargs = loop.inputargs[:]
+ #
+ loop_tokens = []
+ loop_token = compile_new_loop(metainterp, loop_tokens, [], 0)
+ assert loop_tokens == [loop_token]
+ #
+ assert len(cpu.seen) == 1
+ assert cpu.seen[0][2] == loop_token
+ #
+ del cpu.seen[:]
+ metainterp = FakeMetaInterp()
+ metainterp.staticdata = staticdata
+ metainterp.cpu = cpu
+ metainterp.history = History(metainterp.cpu)
+ metainterp.history.operations = loop.operations[:]
+ metainterp.history.inputargs = loop.inputargs[:]
+ #
+ loop_token_2 = compile_new_loop(metainterp, loop_tokens, [], 0)
+ assert loop_token_2 is loop_token
+ assert loop_tokens == [loop_token]
+ assert len(cpu.seen) == 0
Modified: pypy/branch/kill-jumptarget/pypy/jit/metainterp/test/test_optimizefindnode.py
==============================================================================
--- pypy/branch/kill-jumptarget/pypy/jit/metainterp/test/test_optimizefindnode.py (original)
+++ pypy/branch/kill-jumptarget/pypy/jit/metainterp/test/test_optimizefindnode.py Wed Sep 30 13:15:23 2009
@@ -224,7 +224,7 @@
loop = self.parse(ops, boxkinds=boxkinds)
perfect_specialization_finder = PerfectSpecializationFinder(self.cpu)
perfect_specialization_finder.find_nodes_loop(loop)
- self.check_specnodes(loop.specnodes, spectext)
+ self.check_specnodes(loop.token.specnodes, spectext)
return (loop.getboxes(), perfect_specialization_finder.getnode)
def test_find_nodes_simple(self):
@@ -1062,6 +1062,9 @@
finish(p1)
"""
self.find_bridge(ops, 'Not', 'Not')
+ self.find_bridge(ops, 'Not',
+ 'Virtual(node_vtable, valuedescr=Not)',
+ mismatch=True)
def test_bridge_array_virtual_1(self):
ops = """
Modified: pypy/branch/kill-jumptarget/pypy/jit/metainterp/test/test_optimizeopt.py
==============================================================================
--- pypy/branch/kill-jumptarget/pypy/jit/metainterp/test/test_optimizeopt.py (original)
+++ pypy/branch/kill-jumptarget/pypy/jit/metainterp/test/test_optimizeopt.py Wed Sep 30 13:15:23 2009
@@ -147,12 +147,11 @@
cpu = self.cpu
perfect_specialization_finder = PerfectSpecializationFinder(cpu)
perfect_specialization_finder.find_nodes_loop(loop)
- self.check_specnodes(loop.specnodes, spectext)
+ self.check_specnodes(loop.token.specnodes, spectext)
else:
# for cases where we want to see how optimizeopt behaves with
# combinations different from the one computed by optimizefindnode
- loop.specnodes = self.unpack_specnodes(spectext)
- loop.token.specnodes = loop.specnodes
+ loop.token.specnodes = self.unpack_specnodes(spectext)
#
optimize_loop_1(self.cpu, loop)
#
Modified: pypy/branch/kill-jumptarget/pypy/jit/metainterp/test/test_send.py
==============================================================================
--- pypy/branch/kill-jumptarget/pypy/jit/metainterp/test/test_send.py (original)
+++ pypy/branch/kill-jumptarget/pypy/jit/metainterp/test/test_send.py Wed Sep 30 13:15:23 2009
@@ -586,7 +586,27 @@
self.check_loops(oosend=0)
else:
self.check_loops(call=0)
-
+
+ def test_generalize_loop(self):
+ myjitdriver = JitDriver(greens=[], reds = ['i', 'obj'])
+ class A:
+ def __init__(self, n):
+ self.n = n
+ def extern(obj):
+ pass
+ def fn(i):
+ obj = A(1)
+ while i > 0:
+ myjitdriver.can_enter_jit(i=i, obj=obj)
+ myjitdriver.jit_merge_point(i=i, obj=obj)
+ obj = A(obj.n + 1)
+ if i < 10:
+ extern(obj)
+ i -= 1
+ return obj.n
+ res = self.meta_interp(fn, [20], policy=StopAtXPolicy(extern))
+ assert res == 21
+
class TestOOtype(SendTests, OOJitMixin):
pass
Modified: pypy/branch/kill-jumptarget/pypy/jit/metainterp/warmspot.py
==============================================================================
--- pypy/branch/kill-jumptarget/pypy/jit/metainterp/warmspot.py (original)
+++ pypy/branch/kill-jumptarget/pypy/jit/metainterp/warmspot.py Wed Sep 30 13:15:23 2009
@@ -696,8 +696,8 @@
#
class MachineCodeEntryPoint(object):
next = None # linked list
- def __init__(self, entry_executable_token, *greenargs):
- self.entry_executable_token = entry_executable_token
+ def __init__(self, entry_loop_token, *greenargs):
+ self.entry_loop_token = entry_loop_token
i = 0
for name in green_args_names:
setattr(self, 'green_' + name, greenargs[i])
@@ -825,7 +825,7 @@
return
metainterp = MetaInterp(metainterp_sd)
try:
- executable_token = metainterp.compile_and_run_once(*args)
+ loop_token = metainterp.compile_and_run_once(*args)
except warmrunnerdesc.ContinueRunningNormally:
# the trace got too long, reset the counter
self.mccounters[argshash] = 0
@@ -837,21 +837,20 @@
cell = self.mcentrypoints[argshash]
if not cell.equalkey(*greenargs):
# hash collision
- executable_token = self.handle_hash_collision(cell,
- argshash,
- *args)
- if executable_token is None:
+ loop_token = self.handle_hash_collision(cell, argshash,
+ *args)
+ if loop_token is None:
return
else:
# get the assembler and fill in the boxes
cell.set_future_values(*args[num_green_args:])
- executable_token = cell.entry_executable_token
+ loop_token = cell.entry_loop_token
# ---------- execute assembler ----------
while True: # until interrupted by an exception
metainterp_sd.profiler.start_running()
- fail_descr = metainterp_sd.cpu.execute_token(executable_token)
+ fail_descr = metainterp_sd.cpu.execute_token(loop_token)
metainterp_sd.profiler.end_running()
- executable_token = fail_descr.handle_fail(metainterp_sd)
+ loop_token = fail_descr.handle_fail(metainterp_sd)
maybe_compile_and_run._dont_inline_ = True
@@ -867,7 +866,7 @@
nextcell.next = firstcell
self.mcentrypoints[argshash] = nextcell
nextcell.set_future_values(*args[num_green_args:])
- return nextcell.entry_executable_token
+ return nextcell.entry_loop_token
cell = nextcell
# not found at all, do profiling
counter = self.mccounters[argshash]
@@ -927,9 +926,9 @@
key.counter = 0
def attach_unoptimized_bridge_from_interp(self, greenkey,
- entry_executable_token):
+ entry_loop_token):
greenargs = self.unwrap_greenkey(greenkey)
- newcell = MachineCodeEntryPoint(entry_executable_token, *greenargs)
+ newcell = MachineCodeEntryPoint(entry_loop_token, *greenargs)
argshash = self.getkeyhash(*greenargs) & self.hashtablemask
oldcell = self.mcentrypoints[argshash]
newcell.next = oldcell # link
More information about the Pypy-commit
mailing list